diff --git a/subsys/fs/Kconfig b/subsys/fs/Kconfig index 3723f042227d..c91039c8c236 100644 --- a/subsys/fs/Kconfig +++ b/subsys/fs/Kconfig @@ -55,7 +55,7 @@ config FILE_SYSTEM_NFFS config FILE_SYSTEM_SHELL bool "Enable file system shell" - depends on CONSOLE_SHELL + depends on SHELL help This shell provides basic browsing of the contents of the file system. diff --git a/subsys/fs/shell.c b/subsys/fs/shell.c index c4a01a7043b9..a1ad56f16e3c 100644 --- a/subsys/fs/shell.c +++ b/subsys/fs/shell.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -17,7 +17,6 @@ #include #include - /* FAT */ #ifdef CONFIG_FAT_FILESYSTEM_ELM #include @@ -30,15 +29,12 @@ static struct fs_mount_t fatfs_mnt = { .fs_data = &fat_fs, }; #endif - /* NFFS */ #ifdef CONFIG_FILE_SYSTEM_NFFS #include #define NFFS_MNTP "/nffs" - /* NFFS work area strcut */ static struct nffs_flash_desc flash_desc; - /* mounting info */ static struct fs_mount_t nffs_mnt = { .type = FS_NFFS, @@ -52,12 +48,9 @@ static struct fs_mount_t nffs_mnt = { #define MAX_FILENAME_LEN 128 #define MAX_INPUT_LEN 20 - #define SHELL_FS "fs" - static char cwd[MAX_PATH_LEN] = "/"; - static void create_abs_path(const char *name, char *path, size_t len) { if (name[0] == '/') { @@ -72,34 +65,174 @@ static void create_abs_path(const char *name, char *path, size_t len) } } -static int cmd_mkdir(int argc, char *argv[]) +static int cmd_cd(const struct shell *shell, size_t argc, char **argv) { - int res; char path[MAX_PATH_LEN]; + struct fs_dirent entry; + int err; if (argc < 2) { - printk("Missing argument\n"); + strcpy(cwd, "/"); + return 0; + } + + if (strcmp(argv[1], "..") == 0) { + char *prev = strrchr(cwd, '/'); + + if (!prev || prev == cwd) { + strcpy(cwd, "/"); + } else { + *prev = '\0'; + } + + /* No need to test that a parent exists */ return 0; } create_abs_path(argv[1], path, sizeof(path)); - res = fs_mkdir(path); - if (res) { - printk("Error creating dir[%d]\n", res); - return res; + err = fs_stat(path, &entry); + if (err) { + shell_fprintf(shell, SHELL_ERROR, "%s doesn't exist\r\n", path); + return -ENOEXEC; + } + + if (entry.type != FS_DIR_ENTRY_DIR) { + shell_fprintf(shell, SHELL_ERROR, + "%s is not a directory\r\n", path); + return -ENOEXEC; } + strcpy(cwd, path); + return 0; } -static int cmd_rm(int argc, char *argv[]) +static int cmd_ls(const struct shell *shell, size_t argc, char **argv) { - int err; char path[MAX_PATH_LEN]; + struct fs_dir_t dir; + int err; if (argc < 2) { - printk("Missing argument\n"); + strcpy(path, cwd); + } else { + create_abs_path(argv[1], path, sizeof(path)); + } + + err = fs_opendir(&dir, path); + if (err) { + shell_fprintf(shell, SHELL_ERROR, + "Unable to open %s (err %d)\r\n", path, err); + return -ENOEXEC; + } + + while (1) { + struct fs_dirent entry; + + err = fs_readdir(&dir, &entry); + if (err) { + shell_fprintf(shell, SHELL_ERROR, + "Unable to read directory\r\n"); + break; + } + + /* Check for end of directory listing */ + if (entry.name[0] == '\0') { + break; + } + + shell_fprintf(shell, SHELL_NORMAL, "%s%s\r\n", + entry.name, + (entry.type == FS_DIR_ENTRY_DIR) ? "/" : ""); + } + + fs_closedir(&dir); + + return 0; +} + +static int cmd_pwd(const struct shell *shell, size_t argc, char **argv) +{ + shell_fprintf(shell, SHELL_NORMAL, "%s\r\n", cwd); + + return 0; +} + +static int cmd_trunc(const struct shell *shell, size_t argc, char **argv) +{ + char path[MAX_PATH_LEN]; + struct fs_file_t file; + int length; + int err; + + if (!shell_cmd_precheck(shell, (argc >= 2), NULL, 0)) { + 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) { + shell_fprintf(shell, SHELL_ERROR, + "Failed to open %s (%d)\r\n", path, err); + return -ENOEXEC;; + } + + err = fs_truncate(&file, length); + if (err) { + shell_fprintf(shell, SHELL_ERROR, + "Failed to truncate %s (%d)\r\n", path, err); + err = -ENOEXEC; + } + + fs_close(&file); + + return err; +} + +static int cmd_mkdir(const struct shell *shell, size_t argc, char **argv) +{ + int err; + char path[MAX_PATH_LEN]; + + if (!shell_cmd_precheck(shell, (argc == 2), NULL, 0)) { + return 0; + } + + create_abs_path(argv[1], path, sizeof(path)); + + err = fs_mkdir(path); + if (err) { + shell_fprintf(shell, SHELL_ERROR, + "Error creating dir[%d]\r\n", err); + err = -ENOEXEC; + } + + return err; +} + +static int cmd_rm(const struct shell *shell, size_t argc, char **argv) +{ + int err; + char path[MAX_PATH_LEN]; + + if (!shell_cmd_precheck(shell, (argc == 2), NULL, 0)) { return 0; } @@ -107,14 +240,15 @@ static int cmd_rm(int argc, char *argv[]) err = fs_unlink(path); if (err) { - printk("Failed to remove %s (%d)\n", path, err); - return err; + shell_fprintf(shell, SHELL_ERROR, + "Failed to remove %s (%d)\r\n", path, err); + err = -ENOEXEC; } - return 0; + return err; } -static int cmd_read(int argc, char *argv[]) +static int cmd_read(const struct shell *shell, size_t argc, char **argv) { char path[MAX_PATH_LEN]; struct fs_dirent dirent; @@ -123,8 +257,7 @@ static int cmd_read(int argc, char *argv[]) off_t offset; int err; - if (argc < 2) { - printk("Missing argument\n"); + if (!shell_cmd_precheck(shell, (argc >= 2), NULL, 0)) { return 0; } @@ -147,20 +280,25 @@ static int cmd_read(int argc, char *argv[]) err = fs_stat(path, &dirent); if (err) { - printk("Failed to stat %s (%d)\n", path, err); - return err; + shell_fprintf(shell, SHELL_ERROR, + "Failed to obtain file %s (err: %d)\r\n", + path, err); + return -ENOEXEC; } if (dirent.type != FS_DIR_ENTRY_FILE) { - return -EINVAL; + shell_fprintf(shell, SHELL_ERROR, "Note a file %s\r\n", + path); + return -ENOEXEC; } - printk("File size: %zd\n", dirent.size); + shell_fprintf(shell, SHELL_NORMAL, "File size: %zd\r\n", dirent.size); err = fs_open(&file, path); if (err) { - printk("Failed to open %s (%d)\n", path, err); - return err; + shell_fprintf(shell, SHELL_ERROR, "Failed to open %s (%d)\r\n", + path, err); + return -ENOEXEC; } if (offset > 0) { @@ -177,23 +315,23 @@ static int cmd_read(int argc, char *argv[]) break; } - printk("%08X ", (unsigned) offset); + shell_fprintf(shell, SHELL_NORMAL, "%08X ", offset); for (i = 0; i < read; i++) { - printk("%02X ", buf[i]); + shell_fprintf(shell, SHELL_NORMAL, "%02X ", buf[i]); } for (; i < sizeof(buf); i++) { - printk(" "); + shell_fprintf(shell, SHELL_NORMAL, " "); } - printk(" "); + shell_fprintf(shell, SHELL_NORMAL, " "); for (i = 0; i < read; i++) { - printk("%c", buf[i] < 32 || + shell_fprintf(shell, SHELL_NORMAL, "%c", buf[i] < 32 || buf[i] > 127 ? '.' : buf[i]); } - printk("\n"); + shell_fprintf(shell, SHELL_NORMAL, "\r\n"); offset += read; count -= read; @@ -204,7 +342,7 @@ static int cmd_read(int argc, char *argv[]) return 0; } -static int cmd_write(int argc, char *argv[]) +static int cmd_write(const struct shell *shell, size_t argc, char **argv) { char path[MAX_PATH_LEN]; u8_t buf[BUF_CNT]; @@ -214,8 +352,7 @@ static int cmd_write(int argc, char *argv[]) off_t offset = -1; int err; - if (argc < 3) { - printk("Missing argument\n"); + if (!shell_cmd_precheck(shell, (argc >= 3), NULL, 0)) { return 0; } @@ -223,8 +360,9 @@ static int cmd_write(int argc, char *argv[]) if (!strcmp(argv[2], "-o")) { if (argc < 4) { - printk("Missing argument\n"); - return 0; + shell_fprintf(shell, SHELL_ERROR, + "Missing argument\r\n"); + return -ENOEXEC; } offset = strtol(argv[3], NULL, 0); @@ -236,8 +374,9 @@ static int cmd_write(int argc, char *argv[]) err = fs_open(&file, path); if (err) { - printk("Failed to open %s (%d)\n", path, err); - return err; + shell_fprintf(shell, SHELL_ERROR, "Failed to open %s (%d)\r\n", + path, err); + return -ENOEXEC; } if (offset < 0) { @@ -246,9 +385,10 @@ static int cmd_write(int argc, char *argv[]) err = fs_seek(&file, offset, FS_SEEK_SET); } if (err) { - printk("Failed to seek %s (%d)\n", path, err); + shell_fprintf(shell, SHELL_ERROR, + "Failed to seek %s (%d)\r\n", path, err); fs_close(&file); - return err; + return -ENOEXEC; } buf_len = 0; @@ -258,9 +398,11 @@ static int cmd_write(int argc, char *argv[]) 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); + shell_fprintf(shell, SHELL_ERROR, + "Failed to write %s (%d)\r\n", + path, err); fs_close(&file); - return err; + return -ENOEXEC; } buf_len = 0; @@ -272,230 +414,126 @@ static int cmd_write(int argc, char *argv[]) return 0; } -static int cmd_ls(int argc, char *argv[]) +#if defined(CONFIG_FILE_SYSTEM_NFFS) || defined(CONFIG_FAT_FILESYSTEM_ELM) +static char *mntpt_prepare(char *mntpt) { - char path[MAX_PATH_LEN]; - struct fs_dir_t dir; - int err; - - if (argc < 2) { - strcpy(path, cwd); - } else { - create_abs_path(argv[1], path, sizeof(path)); - } - - err = fs_opendir(&dir, path); - if (err) { - printk("Unable to open %s (err %d)\n", path, err); - return 0; - } + char *cpy_mntpt; - while (1) { - struct fs_dirent entry; - - err = fs_readdir(&dir, &entry); - if (err) { - printk("Unable to read directory\n"); - break; - } - - /* Check for end of directory listing */ - if (entry.name[0] == '\0') { - break; - } - - if (entry.type == FS_DIR_ENTRY_DIR) { - printk("%s/\n", entry.name); - } else { - printk("%s\n", entry.name); - } + cpy_mntpt = k_malloc(strlen(mntpt) + 1); + if (cpy_mntpt) { + ((u8_t *)mntpt)[strlen(mntpt)] = '\0'; + memcpy(cpy_mntpt, mntpt, strlen(mntpt)); } - - fs_closedir(&dir); - - return 0; -} - -static int cmd_pwd(int argc, char *argv[]) -{ - printk("%s\n", cwd); - return 0; + return cpy_mntpt; } +#endif -static int cmd_cd(int argc, char *argv[]) +#if defined(CONFIG_FAT_FILESYSTEM_ELM) +static int cmd_mount_fat(const struct shell *shell, size_t argc, char **argv) { - char path[MAX_PATH_LEN]; - struct fs_dirent entry; - int err; - - if (argc < 2) { - strcpy(cwd, "/"); - return 0; - } - - if (strcmp(argv[1], "..") == 0) { - char *prev = strrchr(cwd, '/'); - - if (!prev || prev == cwd) { - strcpy(cwd, "/"); - } else { - *prev = '\0'; - } + char *mntpt; + int res; - /* No need to test that a parent exists */ + if (!shell_cmd_precheck(shell, (argc == 2), NULL, 0)) { return 0; } - create_abs_path(argv[1], path, sizeof(path)); - - err = fs_stat(path, &entry); - if (err) { - printk("%s doesn't exist\n", path); - return 0; + mntpt = mntpt_prepare(argv[1]); + if (!mntpt) { + shell_fprintf(shell, SHELL_ERROR, + "Failed to allocate buffer for mount point\r\n"); + return -ENOEXEC; } - if (entry.type != FS_DIR_ENTRY_DIR) { - printk("%s is not a directory\n", path); - return 0; + fatfs_mnt.mnt_point = (const char *)mntpt; + res = fs_mount(&fatfs_mnt); + if (res != 0) { + shell_fprintf(shell, SHELL_ERROR, + "Error mounting fat fs.Error Code [%d]\r\n", res); + return -ENOEXEC; } - strcpy(cwd, path); + shell_fprintf(shell, SHELL_NORMAL, "Successfully mounted fat fs:%s\r\n", + fatfs_mnt.mnt_point); return 0; } +#endif -static int cmd_trunc(int argc, char *argv[]) +#if defined(CONFIG_FILE_SYSTEM_NFFS) +static int cmd_mount_nffs(const struct shell *shell, size_t argc, char **argv) { - char path[MAX_PATH_LEN]; - struct fs_file_t file; - int length; - int err; + struct device *flash_dev; + char *mntpt; + int res; - if (argc < 2) { - printk("Missing argument\n"); + if (!shell_cmd_precheck(shell, (argc == 2), NULL, 0)) { 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]); - } + mntpt = mntpt_prepare(argv[1]); + if (!mntpt) { + shell_fprintf(shell, SHELL_ERROR, + "Failed to allocate buffer for mount point\r\n"); + return -ENOEXEC; } - 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; + nffs_mnt.mnt_point = (const char *)mntpt; + flash_dev = device_get_binding(FLASH_DEV_NAME); + if (!flash_dev) { + printk("Error in device_get_binding, while mounting nffs fs\n"); + return -ENOEXEC; } - err = fs_truncate(&file, length); - if (err) { - printk("Failed to truncate %s (%d)\n", path, err); - fs_close(&file); - return err; + nffs_mnt.storage_dev = flash_dev; + res = fs_mount(&nffs_mnt); + if (res != 0) { + shell_fprintf(shell, SHELL_ERROR, + "Error mounting fat fs.Error Code [%d]\r\n", res); + return -ENOEXEC; } - fs_close(&file); + shell_fprintf(shell, SHELL_NORMAL, + "Successfully mounted fs:%s\r\n", nffs_mnt.mnt_point); return 0; } - +#endif #if defined(CONFIG_FILE_SYSTEM_NFFS) || defined(CONFIG_FAT_FILESYSTEM_ELM) -static int cmd_mount(int argc, char *argv[]) +SHELL_CREATE_STATIC_SUBCMD_SET(sub_fs_mount) { - int type, res; - char *mntpt; - - if (argc != 3) { - return -EINVAL; - } - - if (!strcmp(argv[1], "fat")) { - type = FS_FATFS; - } else if (!strcmp(argv[1], "nffs")) { - type = FS_NFFS; - } else { - return -EINVAL; - } - if (argv[2] != NULL) { - if (type == FS_FATFS) { -#ifdef CONFIG_FAT_FILESYSTEM_ELM - mntpt = k_malloc(strlen(argv[2]) + 1); - if (mntpt == NULL) { - return -ENOMEM; - } - ((u8_t *)mntpt)[strlen(argv[2])] = '\0'; - memcpy(mntpt, argv[2], strlen(argv[2])); - fatfs_mnt.mnt_point = (const char *)mntpt; - - res = fs_mount(&fatfs_mnt); - if (res < 0) { - printk("Error mounting fat fs.Error Code [%d]\n", res); - return res; - } - printk("Successfully mounted fat fs:%s\n", fatfs_mnt.mnt_point); +#if defined(CONFIG_FAT_FILESYSTEM_ELM) + SHELL_CMD(fat, NULL, + "Mount fatfs. fs mount fat ", cmd_mount_fat), #endif - } else if (type == FS_NFFS) { -#ifdef CONFIG_FILE_SYSTEM_NFFS - mntpt = k_malloc(strlen(argv[2]) + 1); - if (mntpt == NULL) { - return -ENOMEM; - } - ((u8_t *)mntpt)[strlen(argv[2])] = '\0'; - memcpy(mntpt, argv[2], strlen(argv[2])); - nffs_mnt.mnt_point = (const char *)mntpt; - - struct device *flash_dev; - - flash_dev = device_get_binding(CONFIG_FS_NFFS_FLASH_DEV_NAME); - if (!flash_dev) { - printk("Error in device_get_binding, while mounting nffs fs\n"); - return -ENODEV; - } - nffs_mnt.storage_dev = flash_dev; - - res = fs_mount(&nffs_mnt); - if (res < 0) { - printk("Error mounting nffs fs.Error code [%d]\n", res); - return res; - } - printk("Successfully mounted nffs:%s\n", nffs_mnt.mnt_point); -#endif - } - } - return 0; -} +#if defined(CONFIG_FILE_SYSTEM_NFFS) + SHELL_CMD(nffs, NULL, + "Mount nffs. fs mount nffs ", cmd_mount_nffs), #endif + SHELL_SUBCMD_SET_END +}; +#endif -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" }, +SHELL_CREATE_STATIC_SUBCMD_SET(sub_fs) +{ + SHELL_CMD(cd, NULL, + "Change working directory", cmd_cd), + SHELL_CMD(ls, NULL, "List files in current directory", cmd_ls), + SHELL_CMD(mkdir, NULL, "Create directory", cmd_mkdir), #if defined(CONFIG_FILE_SYSTEM_NFFS) || defined(CONFIG_FAT_FILESYSTEM_ELM) - { "mount", cmd_mount, " " }, + SHELL_CMD(mount, &sub_fs_mount, + " ", NULL), #endif - { NULL, NULL } + SHELL_CMD(pwd, NULL, "Print current working directory", cmd_pwd), + SHELL_CMD(read, NULL, "Read from file", cmd_read), + SHELL_CMD(rm, NULL, "Remove file", cmd_rm), + SHELL_CMD(trunc, NULL, "Truncate file", cmd_trunc), + SHELL_CMD(write, NULL, "Write file", cmd_write), + SHELL_SUBCMD_SET_END }; - -SHELL_REGISTER(SHELL_FS, fs_commands); +SHELL_CMD_REGISTER(fs, &sub_fs, "File system commands", NULL);