]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
add fat commands: rm, mkdir
authorLeo C. <erbl259-lmu@yahoo.de>
Sun, 21 Jul 2024 08:19:21 +0000 (10:19 +0200)
committerLeo C. <erbl259-lmu@yahoo.de>
Sun, 21 Jul 2024 08:19:21 +0000 (10:19 +0200)
avr/cmd_fat.c

index 063ebfb1fecba86cc4e4e466792fc87d1c27d675..c4d17b3661159ec83696f451fc8673c210ed7645 100644 (file)
@@ -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 : "<NULL>");
+
+        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",