]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - avr/cmd_fat.c
fat cp: flags
[z180-stamp.git] / avr / cmd_fat.c
index 7717d6ec9a3dec2da8478393371054eabc405eef..29d96dec13becbd934fb999ae0525d3a7ef5bb24 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "cmd_fat.h"
+#include <util/delay.h>
 
 #include "ff.h"
 #include "z80-if.h"
@@ -138,6 +139,7 @@ void err(const char *fmt, ...)
        (void)vfprintf_P(stdout, fmt, ap);
        va_end(ap);
        (void)printf_P(PSTR("\n"));
+       _delay_ms(20);
        command_ret = CMD_RET_FAILURE;
 }
 
@@ -446,7 +448,7 @@ int
 path_set(PATH_T *p, char *string)
 {
        if (strlen(string) > MAX_PATHLEN) {
-               err(PSTR("%s: name too long"), string);
+               err(PSTR("set: '%s': name too long"), string);
                return 0;
        }
 
@@ -477,7 +479,7 @@ path_append(PATH_T *p, char *name, int len)
 
        /* The "+ 1" accounts for the '/' between old path and name. */
        if ((len + p->p_end - p->p_path + 1) > MAX_PATHLEN) {
-               err(PSTR("%s/%s: name too long"), p->p_path, name);
+               err(PSTR("append: '%s/%s': name too long"), p->p_path, name);
                return(0);
        }
 
@@ -487,35 +489,31 @@ path_append(PATH_T *p, char *name, int len)
         */
        if (p->p_end[-1] != '/') {
                *p->p_end++ = '/';
-               *p->p_end = 0;
+               *p->p_end = '\0';
        }
 
        (void)strncat(p->p_end, name, len);
        p->p_end += len;
-       *p->p_end = 0;
+       *p->p_end = '\0';
 
        strip_trailing_slash(p);
-       return(old);
+       return old;
 }
 
 /*
  * Restore path to previous value.  (As returned by path_append.)
  */
 void
-path_restore(p, old)
-       PATH_T *p;
-       char *old;
+path_restore(PATH_T *p, char *old)
 {
        p->p_end = old;
-       *p->p_end = 0;
+       *p->p_end = '\0';
 }
 
 /*
  * Return basename of path.
  */
-char *
-path_basename(p)
-       PATH_T *p;
+char *path_basename(PATH_T *p)
 {
        char *basename;
 
@@ -524,16 +522,16 @@ path_basename(p)
 }
 
 
-uint8_t flags = 0;
+static uint8_t flags;
 PATH_T *from;
 PATH_T *to;
 
-#define R_FLAG (1<<0)
-#define I_FLAG (1<<1)
-#define N_FLAG (1<<2)
-#define F_FLAG (1<<3)
-#define P_FLAG (1<<4)
-#define V_FLAG (1<<5)
+#define R_FLAG (1<<0)  // copy directories recursively
+#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)  // if an existing destination file cannot be opened, remove it and try again (this option is ignored when the -n option is also used)
+#define P_FLAG (1<<4)  // preserve attributes and timestamps
+#define V_FLAG (1<<5)  // explain what is being done
 
 static void
 setfile(FILINFO *fs, FIL *fd)
@@ -561,7 +559,7 @@ void copy_file(FILINFO *fs, uint_fast8_t dne)
        FRESULT fr;
 
 debug("==== copy_file(): dne: %u\n", dne);
-debug("==== from:'%s'  to:'%s'\n", from->p_path, to->p_path);
+debug("     from:'%s'  to:'%s'\n", from->p_path, to->p_path);
 
        if ((fr = f_open(&from_fd, from->p_path, FA_READ)) != FR_OK) {
                err(PSTR("%s: %S"), from->p_path, rctostr(fr));
@@ -578,13 +576,8 @@ debug("==== from:'%s'  to:'%s'\n", from->p_path, to->p_path);
         */
        if (!dne) {
                if (flags & I_FLAG) {
-                       int checkch, ch;
-
                        printf_P(PSTR("overwrite %s? "), to->p_path);
-                       checkch = ch = getchar();
-                       while (ch != '\n' && ch != EOF)
-                               ch = getchar();
-                       if (checkch != 'y') {
+                       if (!confirm_yes()) {
                                f_close(&from_fd);
                                return;
                        }
@@ -621,8 +614,12 @@ debug("==== from:'%s'  to:'%s'\n", from->p_path, to->p_path);
 #if 1
 static void copy_dir(void)
 {
-       printf(PSTR("directory copy not supported, ommitting dir '%s'\n"),
+debug("==== copy_dir()");
+debug("     from:'%s'  to:'%s'\n", from->p_path, to->p_path);
+
+       printf_P(PSTR("directory copy not supported, ommitting dir '%s'\n"),
                from->p_path);
+       command_ret = CMD_RET_FAILURE;
 }
 #else
 static void copy_dir(void)
@@ -632,6 +629,9 @@ static void copy_dir(void)
        int dir_cnt, i;
        char *old_from, *old_to;
 
+debug("==== copy_file(): dne: %u\n", dne);
+debug("     from:'%s'  to:'%s'\n", from->p_path, to->p_path);
+
        dir_cnt = scandir(from->p_path, &dir_list, NULL, NULL);
        if (dir_cnt == -1) {
                (void)fprintf(stderr, "%s: can't read directory %s.\n",
@@ -712,10 +712,10 @@ static void copy()
        FRESULT fr;
 
 debug("==== copy()\n");
-debug("==== from:'%s'  to:'%s'\n", from->p_path, to->p_path);
+debug("     from:'%s'  to:'%s'\n", from->p_path, to->p_path);
 
        fr = f_stat(from->p_path, &from_stat);
-       if (fr) {
+       if (fr != FR_OK) {
                err(PSTR("%s: %S"), from->p_path, rctostr(fr));
                return;
        }
@@ -724,7 +724,7 @@ debug("==== from:'%s'  to:'%s'\n", from->p_path, to->p_path);
        if (f_stat(to->p_path, &to_stat) != FR_OK)
                dne = 1;
        else {
-               if (strcmp(to->p_path, from->p_path) !=0) {
+               if (strcmp(to->p_path, from->p_path) == 0) {
                        (void)printf_P(PSTR("%s and %s are identical (not copied).\n"),
                                        to->p_path, from->p_path);
                        command_ret = CMD_RET_FAILURE;
@@ -735,7 +735,7 @@ debug("==== from:'%s'  to:'%s'\n", from->p_path, to->p_path);
 
        if(from_stat.fattrib & AM_DIR) {
                if (!(flags & R_FLAG)) {
-                       (void)printf(PSTR("-r not specified; ommitting dir '%s'\n"),
+                       (void)printf_P(PSTR("-r not specified; ommitting dir '%s'\n"),
                            from->p_path);
                        command_ret = CMD_RET_FAILURE;
                        return;
@@ -779,36 +779,38 @@ command_ret_t do_cp(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc,
     char *old_to;
 
 
+       uint8_t tflags = 0;
        command_ret = CMD_RET_SUCCESS;
 
        /* reset getopt() */
        optind = 0;
 
        int opt;
-       while ((opt = getopt(argc, argv, PSTR("Rrfip"))) != -1) {
+       while ((opt = getopt(argc, argv, PSTR("rfipv"))) != -1) {
                switch (opt) {
                        case 'f':
-                               flags &= I_FLAG;
+                               tflags &= ~I_FLAG;
+                               tflags |=  F_FLAG;
                                break;
                        case 'i':
-                               flags |= I_FLAG;
-                               flags &= F_FLAG;
+                               tflags &= ~F_FLAG;
+                               tflags |=  I_FLAG;
                                break;
                        case 'p':
-                               flags |= P_FLAG;
+                               tflags |= P_FLAG;
                                break;
-                       case 'R':
                        case 'r':
-                               flags |= R_FLAG;
+                               tflags |= R_FLAG;
                                break;
                        case 'v':
-                               flags |= V_FLAG;
+                               tflags |= V_FLAG;
                                break;
                        default:
                                return CMD_RET_USAGE;
                                break;
                }
        }
+       flags = tflags;
        argc -= optind;
        argv += optind;
 
@@ -847,22 +849,27 @@ command_ret_t do_cp(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc,
         */
 
        fr = f_stat(to->p_path, &to_stat);
-       if (fr != FR_OK && fr != FR_NO_FILE) {
-               err(PSTR("%s: %S"), to->p_path, rctostr(fr));
+debug("==== main, stat to: fr: %d, attr: %02x, flags:%02x\n", fr, to_stat.fattrib, flags);
+debug("     from:'%s'  to:'%s'\n", from->p_path, to->p_path);
+
+       if (fr != FR_OK && fr != FR_NO_FILE && fr != FR_NO_PATH) {
+               err(PSTR("Test1: %s: %S"), to->p_path, rctostr(fr));
                command_ret = CMD_RET_FAILURE;
                goto cleanup;
        }
-       if (fr != FR_OK || !(to_stat.fattrib & AM_DIR)) {
+       if (!(fr == FR_OK && (to_stat.fattrib & AM_DIR))) {
                /*
                 * Case (1).  Target is not a directory.
                 */
                if (argc > 1) {
-                       command_ret = CMD_RET_USAGE;
+                       err(PSTR("target '%s' is not a directory"), to->p_path);
+                       //command_ret = CMD_RET_USAGE;
                        goto cleanup;
                }
-               if (!path_set(from, *argv))
+               if (!path_set(from, *argv)) {
                        command_ret = CMD_RET_FAILURE;
                        goto cleanup;
+               }
                copy();
        }
        else {
@@ -877,7 +884,7 @@ command_ret_t do_cp(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc,
                        copy();
                        if (!--argc)
                                break;
-                       path_restore(&to, old_to);
+                       path_restore(to, old_to);
                }
        }
 
@@ -1196,8 +1203,15 @@ CMD_TBL_ITEM(
 CMD_TBL_ITEM(
        cp,     CONFIG_SYS_MAXARGS,     CTBL_DBG,       do_cp,
        "copy files",
-       "[-R] [-f | -i | -n] [-aprv] source_file target_file\n"
-       "    - \n"
+       "[-f | -i | -n] [-prv] source_file target_file\n"
+       "cp [-f | -i | -n] [-prv] source_file ... target_dir\n"
+       "    -f overwrite existing file ignoring write protection\n"
+       "       this option is ignored when the -n option is also used\n"
+       "    -i prompt before overwrite (overrides a previous -n option)\n"
+       "    -n do not overwrite an existing file (overrides a previous -i option)\n"
+       "    -p preserve attributes and timestamps\n"
+       "    -r copy directories recursively\n"
+       "    -v explain what is being done\n"
 ),
 
 CMD_TBL_ITEM(