diff --git a/subsys/fs/shell.c b/subsys/fs/shell.c index e3957b8caf8..1ea75cedb50 100644 --- a/subsys/fs/shell.c +++ b/subsys/fs/shell.c @@ -12,8 +12,16 @@ #include #include #include +#include +#include +#include +#include + +#define BUF_CNT 64 #define MAX_PATH_LEN 128 +#define MAX_FILENAME_LEN 128 +#define MAX_INPUT_LEN 20 static char cwd[MAX_PATH_LEN] = "/"; @@ -52,6 +60,185 @@ static int cmd_mkdir(int argc, char *argv[]) return 0; } +static int cmd_rm(int argc, char *argv[]) +{ + int err; + char path[MAX_PATH_LEN]; + + if (argc < 2) { + printk("Missing argument\n"); + return 0; + } + + create_abs_path(argv[1], path, sizeof(path)); + + err = fs_unlink(path); + if (err) { + printk("Failed to remove %s (%d)\n", path, err); + return err; + } + + return 0; +} + +static int cmd_read(int argc, char *argv[]) +{ + char path[MAX_PATH_LEN]; + struct fs_dirent dirent; + fs_file_t file; + int count; + off_t offset; + int err; + + if (argc < 2) { + printk("Missing argument\n"); + return 0; + } + + create_abs_path(argv[1], path, sizeof(path)); + + if (argc > 2) { + count = strtol(argv[2], NULL, 0); + if (count <= 0) { + count = INT_MAX; + } + } else { + count = INT_MAX; + } + + if (argc > 3) { + offset = strtol(argv[3], NULL, 0); + } else { + offset = 0; + } + + err = fs_stat(path, &dirent); + if (err) { + printk("Failed to stat %s (%d)\n", path, err); + return err; + } + + if (dirent.type != FS_DIR_ENTRY_FILE) { + return -EINVAL; + } + + printk("File size: %zd\n", dirent.size); + + err = fs_open(&file, path); + if (err) { + printk("Failed to open %s (%d)\n", path, err); + return err; + } + + if (offset > 0) { + fs_seek(&file, offset, FS_SEEK_SET); + } + + while (count > 0) { + ssize_t read; + u8_t buf[16]; + int i; + + read = fs_read(&file, buf, min(count, sizeof(buf))); + if (read <= 0) { + break; + } + + printk("%08X ", (unsigned) offset); + + for (i = 0; i < read; i++) { + printk("%02X ", buf[i]); + } + for (; i < sizeof(buf); i++) { + printk(" "); + } + + printk(" "); + + for (i = 0; i < read; i++) { + printk("%c", buf[i] < 32 || + buf[i] > 127 ? '.' : buf[i]); + } + + printk("\n"); + + offset += read; + count -= read; + } + + fs_close(&file); + + return 0; +} + +static int cmd_write(int argc, char *argv[]) +{ + char path[MAX_PATH_LEN]; + u8_t buf[BUF_CNT]; + u8_t buf_len; + int arg_offset; + fs_file_t file; + off_t offset = -1; + int err; + + if (argc < 3) { + printk("Missing argument\n"); + return 0; + } + + create_abs_path(argv[1], path, sizeof(path)); + + if (!strcmp(argv[2], "-o")) { + if (argc < 4) { + printk("Missing argument\n"); + return 0; + } + + offset = strtol(argv[3], NULL, 0); + + arg_offset = 4; + } else { + arg_offset = 2; + } + + err = fs_open(&file, path); + if (err) { + printk("Failed to open %s (%d)\n", path, err); + return err; + } + + if (offset < 0) { + err = fs_seek(&file, 0, FS_SEEK_END); + } else { + err = fs_seek(&file, offset, FS_SEEK_SET); + } + if (err) { + printk("Failed to seek %s (%d)\n", path, err); + fs_close(&file); + return err; + } + + buf_len = 0; + while (arg_offset < argc) { + buf[buf_len++] = strtol(argv[arg_offset++], NULL, 16); + + if ((buf_len == BUF_CNT) || (arg_offset == argc)) { + err = fs_write(&file, buf, buf_len); + if (err < 0) { + printk("Failed to write %s (%d)\n", path, err); + fs_close(&file); + return err; + } + + buf_len = 0; + } + } + + fs_close(&file); + + return 0; +} + static int cmd_ls(int argc, char *argv[]) { char path[MAX_PATH_LEN]; @@ -144,11 +331,62 @@ static int cmd_cd(int argc, char *argv[]) return 0; } +static int cmd_trunc(int argc, char *argv[]) +{ + char path[MAX_PATH_LEN]; + fs_file_t file; + int length; + int err; + + if (argc < 2) { + printk("Missing argument\n"); + return 0; + } + + if (argv[1][0] == '/') { + strncpy(path, argv[1], sizeof(path) - 1); + path[MAX_PATH_LEN - 1] = '\0'; + } else { + if (strcmp(cwd, "/") == 0) { + snprintf(path, sizeof(path), "/%s", argv[1]); + } else { + snprintf(path, sizeof(path), "%s/%s", cwd, argv[1]); + } + } + + if (argc > 2) { + length = strtol(argv[2], NULL, 0); + } else { + length = 0; + } + + err = fs_open(&file, path); + if (err) { + printk("Failed to open %s (%d)\n", path, err); + return err; + } + + err = fs_truncate(&file, length); + if (err) { + printk("Failed to truncate %s (%d)\n", path, err); + fs_close(&file); + return err; + } + + fs_close(&file); + + return 0; +} + struct shell_cmd fs_commands[] = { { "ls", cmd_ls, "List files in current directory" }, { "cd", cmd_cd, "Change working directory" }, { "pwd", cmd_pwd, "Print current working directory" }, { "mkdir", cmd_mkdir, "Create directory" }, + { "rm", cmd_rm, "Remove file"}, + { "read", cmd_read, "Read from file" }, + { "write", cmd_write, "Write to file" }, + { "trunc", cmd_trunc, "Truncate file" }, { NULL, NULL } };