From: Leo C. Date: Sun, 21 Jul 2024 08:19:21 +0000 (+0200) Subject: add fat commands: rm, mkdir X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/commitdiff_plain/465090d410f8fd09085a54b0fbee5bf33ae99cc1 add fat commands: rm, mkdir --- diff --git a/avr/cmd_fat.c b/avr/cmd_fat.c index 063ebfb..c4d17b3 100644 --- a/avr/cmd_fat.c +++ b/avr/cmd_fat.c @@ -21,10 +21,11 @@ uint32_t fat_time(const struct tm * timeptr); #include "timer.h" #include "debug.h" #include "env.h" +#include "getopt-min.h" #define DEBUG_FA 0 /* set to 1 to debug */ #define DEBUG_LS 1 /* set to 1 to debug */ -#define DEBUG_RM 1 /* set to 1 to debug */ +#define DEBUG_RM 0 /* set to 1 to debug */ #define debug_fa(fmt, args...) \ debug_cond(DEBUG_FA, fmt, ##args) @@ -202,6 +203,23 @@ char *path_split(char *p) return ps; } +command_ret_t do_mkdir(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[]) +{ + int ret = CMD_RET_SUCCESS; + FRESULT res; + + if (argc < 1) + return CMD_RET_USAGE; + + for (uint8_t i = 1; i < argc; i++) { + if ((res = f_mkdir(argv[i])) != FR_OK) { + ret = CMD_RET_FAILURE; + cmd_error(0, res, PSTR("cannot create directory '%s'"), argv[i]); + } + } + return ret; +} + /* * ls path - Directory listing * @@ -275,6 +293,137 @@ command_ret_t do_ls(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, return CMD_RET_SUCCESS; } +typedef FRESULT (*fatfunc_t)(const TCHAR* path_old, const TCHAR* path_new); + +uint8_t cmd_flags; +#define I_FLAG (1<<1) // prompt before overwrite (overrides a previous -n option) +#define N_FLAG (1<<2) // do not overwrite an existing file (overrides a previous -i option) +#define F_FLAG (1<<3) // overwrite existing file ignoring write protection +#define P_FLAG (1<<4) // preserve attributes and timestamps +#define V_FLAG (1<<5) // explain what is being done + +char* splitpath(const char* path) +{ + char* fs = strrchr(path, '/'); + char* bs = strrchr(path, '\\'); + if (fs > bs) { + *fs = '\0'; + return fs + 1; + } else if (bs != NULL) { + *bs = '\0'; + return bs + 1; + } + return NULL; +} + +FRESULT ff_remove(const TCHAR *file, const TCHAR *dest UNUSED) +{ + FRESULT res = FR_OK; + + debug_rm("==== ff_remove: '%s'\n", file); + + if (!(cmd_flags & N_FLAG)) { + if ((res = f_unlink(file)) == FR_OK) { + if (cmd_flags & V_FLAG) + printf_P(PSTR("removed '%s'\n"), file); + } else { + cmd_error(0, res, PSTR("cannot remove '%s'"), file); + } + } else { + printf_P(PSTR("not removed '%s'\n"), file); + } + + return res; +} + +void ff_iterate(fatfunc_t fatfunc, int count, char* const file[], char* dest) +{ + FRESULT res = 0; + DIR dir; + FILINFO finfo; + char srcpath[PATH_MAX], destpath[PATH_MAX]; + + uint8_t dest_is_dir = dest != NULL && f_stat(dest, &finfo) == FR_OK && finfo.fattrib & AM_DIR; + for (uint8_t i = 0; i < count; i++) { + char* pattern = NULL; + strcpy(srcpath, file[i]); + char* p1 = path_split(srcpath); + + if (p1 != NULL) { + pattern = (char *) malloc(strlen(p1)+1); + strcpy(pattern, p1); + } + + debug_rm("### iter1 srcpath, pattern: '%s', '%s'\n", srcpath, pattern ? pattern : ""); + + if (pattern != NULL) { + res = f_findfirst(&dir, &finfo, srcpath, pattern); + p1 = srcpath+strlen(srcpath)-1; + if (*p1++ != '/') + *(p1++) = '/'; + } else { + res = f_findfirst(&dir, &finfo, ".", file[i]); + p1 = srcpath; + } + if (finfo.fname[0] == 0) + cmd_error(0, res, PSTR("cannot remove '%s': no such file or directory"), file[i]); + + + while (res == FR_OK && finfo.fname[0] != 0) { + strcpy(p1, finfo.fname); + + debug_rm("### iter3 srcpath: '%s'\n", srcpath); + + if (dest != NULL) { + strcpy(destpath, dest); + if (dest_is_dir) { + strcat_P(destpath, PSTR("/")); + strcat(destpath, finfo.fname); + } + } + fatfunc(srcpath, destpath); + res = f_findnext(&dir, &finfo); + debug_rm("### iter4 res, .fname: %d, '%s'\n", res, finfo.fname); + + } + res = f_closedir(&dir); + free(pattern); + } + if (res != FR_OK) + cmd_error(CMD_RET_FAILURE, res, PSTR("error enumerating files")); + //printf_P(PSTR("error enumerating files: %S\n"), ffw_error(res)); +} + +command_ret_t do_rm(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[]) +{ + + cmd_flags = 0; + int opt; + while ((opt = getopt(argc, argv, PSTR("nv"))) != -1) { + switch (opt) { + case 'n': + cmd_flags |= N_FLAG; + break; + case 'v': + cmd_flags |= V_FLAG; + break; + default: + return CMD_RET_USAGE; + break; + } + } + argc -= optind; + argv += optind; + + debug_rm("==== do_rm: argc, argv[0]: %d, '%s'\n", argc, argv[0]); + + if (argc < 1) + return CMD_RET_USAGE; + + ff_iterate(ff_remove, argc, argv, NULL); + + return CMD_RET_SUCCESS; +} /* * tst path - for debugging: test access with different functions @@ -583,6 +732,11 @@ CMD_TBL_ITEM( "Change the current/working directory.", "path" ), +CMD_TBL_ITEM( + mkdir, CONFIG_SYS_MAXARGS, 0, do_mkdir, + "Create the DIRECTORY(ies), if they do not already exist.", + "DIRECTORY..." +), CMD_TBL_ITEM( ls, 2, CTBL_RPT|CTBL_SUBCMDAUTO, do_ls, "Directory listing", @@ -593,6 +747,15 @@ CMD_TBL_ITEM( "FatFS test function", "[path [pattern]]" ), +CMD_TBL_ITEM( + rm, CONFIG_SYS_MAXARGS, 0, do_rm, + "Remove FILE(s)", + "[OPTION]... [FILE]...\n" + //" -i prompt before removal\n" + " -v explain what is being done\n" + "\n" + "rm removes directories, if they are empty." +), CMD_TBL_ITEM( load, 5, 0, do_rw, "load binary file from a dos filesystem",