Protect a remote filename that starts with a dash.
[rsync/rsync.git] / options.c
index e97507c..dc13592 100644 (file)
--- a/options.c
+++ b/options.c
@@ -293,6 +293,7 @@ static int do_stats = 0;
 static int do_progress = 0;
 static int daemon_opt;   /* sets am_daemon after option error-reporting */
 static int omit_dir_times = 0;
+static int omit_link_times = 0;
 static int F_option_cnt = 0;
 static int modify_window_set;
 static int itemize_changes = 0;
@@ -699,6 +700,7 @@ void usage(enum logcode F)
   rprintf(F," -D                          same as --devices --specials\n");
   rprintf(F," -t, --times                 preserve modification times\n");
   rprintf(F," -O, --omit-dir-times        omit directories from --times\n");
+  rprintf(F," -J, --omit-link-times       omit symlinks from --times\n");
   rprintf(F,"     --super                 receiver attempts super-user activities\n");
 #ifdef SUPPORT_XATTRS
   rprintf(F,"     --fake-super            store/recover privileged attrs using xattrs\n");
@@ -843,12 +845,15 @@ static struct poptOption long_options[] = {
   {"xattrs",          'X', POPT_ARG_NONE,   0, 'X', 0, 0 },
   {"no-xattrs",        0,  POPT_ARG_VAL,    &preserve_xattrs, 0, 0, 0 },
   {"no-X",             0,  POPT_ARG_VAL,    &preserve_xattrs, 0, 0, 0 },
-  {"times",           't', POPT_ARG_VAL,    &preserve_times, 2, 0, 0 },
+  {"times",           't', POPT_ARG_VAL,    &preserve_times, 1, 0, 0 },
   {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
   {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
   {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 1, 0, 0 },
   {"no-omit-dir-times",0,  POPT_ARG_VAL,    &omit_dir_times, 0, 0, 0 },
   {"no-O",             0,  POPT_ARG_VAL,    &omit_dir_times, 0, 0, 0 },
+  {"omit-link-times", 'J', POPT_ARG_VAL,    &omit_link_times, 1, 0, 0 },
+  {"no-omit-link-times",0, POPT_ARG_VAL,    &omit_link_times, 0, 0, 0 },
+  {"no-J",             0,  POPT_ARG_VAL,    &omit_link_times, 0, 0, 0 },
   {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
   {"super",            0,  POPT_ARG_VAL,    &am_root, 2, 0, 0 },
   {"no-super",         0,  POPT_ARG_VAL,    &am_root, 0, 0, 0 },
@@ -889,8 +894,8 @@ static struct poptOption long_options[] = {
   {"ignore-times",    'I', POPT_ARG_NONE,   &ignore_times, 0, 0, 0 },
   {"size-only",        0,  POPT_ARG_NONE,   &size_only, 0, 0, 0 },
   {"one-file-system", 'x', POPT_ARG_NONE,   0, 'x', 0, 0 },
-  {"no-one-file-system",'x',POPT_ARG_VAL,   &one_file_system, 0, 0, 0 },
-  {"no-x",            'x', POPT_ARG_VAL,    &one_file_system, 0, 0, 0 },
+  {"no-one-file-system",0, POPT_ARG_VAL,    &one_file_system, 0, 0, 0 },
+  {"no-x",             0,  POPT_ARG_VAL,    &one_file_system, 0, 0, 0 },
   {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
   {"existing",         0,  POPT_ARG_NONE,   &ignore_non_existing, 0, 0, 0 },
   {"ignore-non-existing",0,POPT_ARG_NONE,   &ignore_non_existing, 0, 0, 0 },
@@ -1452,7 +1457,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        preserve_links = 1;
 #endif
                        preserve_perms = 1;
-                       preserve_times = 2;
+                       preserve_times = 1;
                        preserve_gid = 1;
                        preserve_uid = 1;
                        preserve_devices = 1;
@@ -2039,17 +2044,18 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                return 0;
        }
        if (backup_dir) {
+               size_t len;
                while (*backup_dir == '.' && backup_dir[1] == '/')
                        backup_dir += 2;
                if (*backup_dir == '.' && backup_dir[1] == '\0')
                        backup_dir++;
-               backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
-               backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
-               if (backup_dir_remainder < 128) {
+               len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
+               if (len > sizeof backup_dir_buf - 128) {
                        snprintf(err_buf, sizeof err_buf,
                                "the --backup-dir path is WAY too long.\n");
                        return 0;
                }
+               backup_dir_len = (int)len;
                if (!backup_dir_len) {
                        backup_dir_len = -1;
                        backup_dir = NULL;
@@ -2057,6 +2063,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        backup_dir_buf[backup_dir_len++] = '/';
                        backup_dir_buf[backup_dir_len] = '\0';
                }
+               backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
        }
        if (backup_dir) {
                /* No need for a suffix or a protect rule. */
@@ -2072,13 +2079,19 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                parse_filter_str(&filter_list, backup_dir_buf, rule_template(0), 0);
        }
 
+       if (preserve_times) {
+               preserve_times = PRESERVE_FILE_TIMES;
+               if (!omit_dir_times)
+                       preserve_times |= PRESERVE_DIR_TIMES;
+#ifdef CAN_SET_SYMLINK_TIMES
+               if (!omit_link_times)
+                       preserve_times |= PRESERVE_LINK_TIMES;
+#endif
+       }
+
        if (make_backups && !backup_dir) {
                omit_dir_times = 0; /* Implied, so avoid -O to sender. */
-               if (preserve_times > 1)
-                       preserve_times = 1;
-       } else if (omit_dir_times) {
-               if (preserve_times > 1)
-                       preserve_times = 1;
+               preserve_times &= ~PRESERVE_DIR_TIMES;
        }
 
        if (stdout_format) {
@@ -2315,6 +2328,8 @@ void server_options(char **args, int *argc_p)
                        argstr[x++] = 'm';
                if (omit_dir_times)
                        argstr[x++] = 'O';
+               if (omit_link_times)
+                       argstr[x++] = 'J';
        } else {
                if (copy_links)
                        argstr[x++] = 'L';