X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/f20e6902af6c77aef51f6c7050af641852de5283..aeaab98e5a4b148444f6aab7913c70d9eb75a34f:/avr/cmd_fat.c diff --git a/avr/cmd_fat.c b/avr/cmd_fat.c index 55d6ceb..039ec90 100644 --- a/avr/cmd_fat.c +++ b/avr/cmd_fat.c @@ -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 : "", pattern ? pattern : ""); + 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.",