]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
New command: fat attrib
authorLeo C <erbl259-lmu@yahoo.de>
Sun, 27 May 2018 01:01:46 +0000 (03:01 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Sun, 27 May 2018 01:01:46 +0000 (03:01 +0200)
avr/cmd_fat.c

index 55d6ceb8a51eee13bdc68f60c999fb67e37a0e3f..039ec9039d753deb63cefc9c3bc7b2eb942f093f 100644 (file)
@@ -26,6 +26,7 @@
 #define DEBUG_CP               1       /* 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_FA               1       /* set to 1 to debug */
 
 #define debug_cp(fmt, args...)                                                        \
        debug_cond(DEBUG_CP, fmt, ##args)
@@ -33,6 +34,8 @@
        debug_cond(DEBUG_LS, fmt, ##args)
 #define debug_rm(fmt, args...)                                                        \
        debug_cond(DEBUG_RM, fmt, ##args)
+#define debug_fa(fmt, args...)                                                        \
+       debug_cond(DEBUG_FA, fmt, ##args)
 
 
 
@@ -430,6 +433,109 @@ command_ret_t do_cd(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc,
 }
 
 
+static int decode_arg(const char *arg)
+{
+       BYTE attr = 0;
+       char c;
+
+       while ((c = *++arg) != '\0') {
+               switch (c) {
+                       case 'a':
+                               attr |= AM_ARC;         /* Archive   */
+                               break;
+                       case 'h':
+                               attr |= AM_HID;         /* Hidden    */
+                               break;
+                       case 'r':
+                               attr |= AM_RDO;         /* Read only */
+                               break;
+                       case 's':
+                               attr |= AM_SYS;         /* System    */
+                               break;
+                       default:
+                               err(PSTR("unknown attribute: '%c'"), c);
+                               return -1;
+               }
+       }
+       return attr;
+}
+
+static void print_attrib(char *path, FILINFO *f)
+{
+       printf_P(PSTR("%c%c%c%c%c %s%s\n"),
+                               (f->fattrib & AM_DIR) ? 'D' : '-',
+                               (f->fattrib & AM_RDO) ? 'R' : '-',
+                               (f->fattrib & AM_HID) ? 'H' : '-',
+                               (f->fattrib & AM_SYS) ? 'S' : '-',
+                               (f->fattrib & AM_ARC) ? 'A' : '-',
+                               path, f->fname);
+}
+
+command_ret_t do_attrib(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, UNUSED char * const argv[])
+{
+       DIR Dir;                                        /* Directory object */
+       FILINFO Finfo;
+       FRESULT res;
+       BYTE set_mask = 0;
+       BYTE clear_mask = 0;
+
+       cmdname = argv[0];
+       command_ret = CMD_RET_SUCCESS;
+
+
+       for (;;) {
+               int attr;
+               char *arg = *++argv;
+
+               if (!arg)
+                       return CMD_RET_USAGE;
+               if (arg[0] != '-' && arg[0] != '+')
+                       break;
+               attr = decode_arg(arg);
+               if (attr < 0)
+                       return CMD_RET_FAILURE;
+               if (arg[0] == '+')
+                       set_mask |= attr;
+               else
+                       clear_mask |= attr;
+       }
+
+       do {
+               if (!path_set(&from, *argv)) {
+                       /* TODO: error out*/
+               }
+               char *pattern = path_split_pattern(&from);
+               if (*pattern == '\0')
+                       pattern = "*";
+               debug_fa("==== path: '%s', pattern: '%s'\n", from.p_path ? from.p_path : "<NULL>", pattern ? pattern : "<NULL>");
+               res = f_findfirst(&Dir, &Finfo, from.p_path, pattern);
+               debug_fa("==== findfirst %d\n", res);
+               if (res != FR_OK || !Finfo.fname[0]) {
+                       path_fix(&from);
+                       err(PSTR("'%s%s': No such file or directory"), from.p_path, pattern);
+               } else {
+                       do {
+                               if (set_mask | clear_mask) {
+                                       if ((res = f_chmod(Finfo.fname, set_mask, set_mask | clear_mask)) != FR_OK) {
+                                               path_fix(&from);
+                                               err(PSTR("'%s%s': %S"), from.p_path, Finfo.fname, rctostr(res));
+                                               path_unfix(&from);
+                                       }
+                               } else {
+                                       path_fix(&from);
+                                       print_attrib(from.p_path, &Finfo);
+                                       path_unfix(&from);
+                               }
+
+                               res = f_findnext(&Dir, &Finfo);
+                               //debug_fa("==== findnext %d\n", res);
+                       } while (res == FR_OK && Finfo.fname[0]);
+               }
+               f_closedir(&Dir);
+       } while (*++argv);
+
+       return command_ret;
+}
 
 command_ret_t do_rm(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
 {
@@ -1266,6 +1372,21 @@ CMD_TBL_ITEM(
        "Print name of current/working directory",
        ""
 ),
+CMD_TBL_ITEM(
+       attrib, CONFIG_SYS_MAXARGS,     0,                      do_attrib,
+    "Display or change attributes on a FAT filesystem",
+    "[+-ahrs] files...\n"
+    "\n"
+    "    -    Clear attributes\n"
+    "    +    Set attributes\n"
+    "    a    Archive\n"
+    "    h    Hidden\n"
+    "    r    Read only\n"
+    "    s    System\n"
+    "Display only:\n"
+    "    v    Volume label\n"
+    "    d    Directory\n"
+),
 CMD_TBL_ITEM(
        cd,             2,      0,                      do_cd,
        "Change the current/working directory.",