Add --omit-link-times and use CAN_SET_SYMLINK_TIMES less.
authorWayne Davison <wayned@samba.org>
Thu, 26 Aug 2010 15:50:05 +0000 (08:50 -0700)
committerWayne Davison <wayned@samba.org>
Thu, 26 Aug 2010 18:12:58 +0000 (11:12 -0700)
generator.c
options.c
rsync.c
rsync.h
rsync.yo
t_stub.c
util.c

index b12087f..be36e63 100644 (file)
@@ -390,12 +390,9 @@ static void do_delete_pass(void)
 
 int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
 {
 
 int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
 {
-#ifndef CAN_SET_SYMLINK_TIMES
-       if (S_ISLNK(file->mode)) {
+       if (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(file->mode)) {
                ;
                ;
-       } else
-#endif
-       if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0)
+       } else if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0)
                return 0;
 
        if (preserve_perms) {
                return 0;
 
        if (preserve_perms) {
@@ -437,12 +434,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
 {
        if (statret >= 0) { /* A from-dest-dir statret can == 1! */
                int keep_time = !preserve_times ? 0
 {
        if (statret >= 0) { /* A from-dest-dir statret can == 1! */
                int keep_time = !preserve_times ? 0
-                   : S_ISDIR(file->mode) ? preserve_times > 1 :
-#ifdef CAN_SET_SYMLINK_TIMES
-                   1;
-#else
-                   !S_ISLNK(file->mode);
-#endif
+                   : S_ISDIR(file->mode) ? preserve_times & PRESERVE_DIR_TIMES
+                   : S_ISLNK(file->mode) ? preserve_times & PRESERVE_LINK_TIMES
+                   : 1;
 
                if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
                        iflags |= ITEM_REPORT_SIZE;
 
                if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
                        iflags |= ITEM_REPORT_SIZE;
@@ -2056,7 +2050,7 @@ void generate_files(int f_out, const char *local_name)
        }
        solo_file = local_name;
        dir_tweaking = !(list_only || solo_file || dry_run);
        }
        solo_file = local_name;
        dir_tweaking = !(list_only || solo_file || dry_run);
-       need_retouch_dir_times = preserve_times > 1;
+       need_retouch_dir_times = preserve_times & PRESERVE_DIR_TIMES;
        loopchk_limit = allowed_lull ? allowed_lull * 5 : 200;
        symlink_timeset_failed_flags = ITEM_REPORT_TIME
            | (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0);
        loopchk_limit = allowed_lull ? allowed_lull * 5 : 200;
        symlink_timeset_failed_flags = ITEM_REPORT_TIME
            | (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0);
index dbde289..2529fe2 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 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;
 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," -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");
   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 },
   {"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 },
   {"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 },
   {"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 },
@@ -1452,7 +1457,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        preserve_links = 1;
 #endif
                        preserve_perms = 1;
                        preserve_links = 1;
 #endif
                        preserve_perms = 1;
-                       preserve_times = 2;
+                       preserve_times = 1;
                        preserve_gid = 1;
                        preserve_uid = 1;
                        preserve_devices = 1;
                        preserve_gid = 1;
                        preserve_uid = 1;
                        preserve_devices = 1;
@@ -2072,13 +2077,19 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                parse_filter_str(&filter_list, backup_dir_buf, rule_template(0), 0);
        }
 
                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 (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) {
        }
 
        if (stdout_format) {
@@ -2315,6 +2326,8 @@ void server_options(char **args, int *argc_p)
                        argstr[x++] = 'm';
                if (omit_dir_times)
                        argstr[x++] = 'O';
                        argstr[x++] = 'm';
                if (omit_dir_times)
                        argstr[x++] = 'O';
+               if (omit_link_times)
+                       argstr[x++] = 'J';
        } else {
                if (copy_links)
                        argstr[x++] = 'L';
        } else {
                if (copy_links)
                        argstr[x++] = 'L';
diff --git a/rsync.c b/rsync.c
index c9be424..91fb9e3 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -489,11 +489,13 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                set_xattr(fname, file, fnamecmp, sxp);
 #endif
 
                set_xattr(fname, file, fnamecmp, sxp);
 #endif
 
-       if (!preserve_times || (S_ISDIR(sxp->st.st_mode) && preserve_times == 1))
+       if (!preserve_times
+        || (!(preserve_times & PRESERVE_DIR_TIMES) && S_ISDIR(sxp->st.st_mode))
+        || (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(sxp->st.st_mode)))
                flags |= ATTRS_SKIP_MTIME;
        if (!(flags & ATTRS_SKIP_MTIME)
            && cmp_time(sxp->st.st_mtime, file->modtime) != 0) {
                flags |= ATTRS_SKIP_MTIME;
        if (!(flags & ATTRS_SKIP_MTIME)
            && cmp_time(sxp->st.st_mtime, file->modtime) != 0) {
-               int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode);
+               int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), file->mode);
                if (ret < 0) {
                        rsyserr(FERROR_XFER, errno, "failed to set times on %s",
                                full_fname(fname));
                if (ret < 0) {
                        rsyserr(FERROR_XFER, errno, "failed to set times on %s",
                                full_fname(fname));
diff --git a/rsync.h b/rsync.h
index efa42c8..4a5313e 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -1117,6 +1117,10 @@ extern int errno;
 #define IS_SPECIAL(mode) (S_ISSOCK(mode) || S_ISFIFO(mode))
 #define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode))
 
 #define IS_SPECIAL(mode) (S_ISSOCK(mode) || S_ISFIFO(mode))
 #define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode))
 
+#define PRESERVE_FILE_TIMES    (1<<0)
+#define PRESERVE_DIR_TIMES     (1<<1)
+#define PRESERVE_LINK_TIMES    (1<<2)
+
 /* Initial mask on permissions given to temporary files.  Mask off setuid
      bits and group access because of potential race-condition security
      holes, and mask other access because mode 707 is bizarre */
 /* Initial mask on permissions given to temporary files.  Mask off setuid
      bits and group access because of potential race-condition security
      holes, and mask other access because mode 707 is bizarre */
index 9ec60a5..5f5365a 100644 (file)
--- a/rsync.yo
+++ b/rsync.yo
@@ -356,6 +356,7 @@ to the detailed description below for a complete description.  verb(
  -D                          same as --devices --specials
  -t, --times                 preserve modification times
  -O, --omit-dir-times        omit directories from --times
  -D                          same as --devices --specials
  -t, --times                 preserve modification times
  -O, --omit-dir-times        omit directories from --times
+ -J, --omit-link-times       omit symlinks from --times
      --super                 receiver attempts super-user activities
      --fake-super            store/recover privileged attrs using xattrs
  -S, --sparse                handle sparse files efficiently
      --super                 receiver attempts super-user activities
      --fake-super            store/recover privileged attrs using xattrs
  -S, --sparse                handle sparse files efficiently
@@ -1114,6 +1115,9 @@ it is preserving modification times (see bf(--times)).  If NFS is sharing
 the directories on the receiving side, it is a good idea to use bf(-O).
 This option is inferred if you use bf(--backup) without bf(--backup-dir).
 
 the directories on the receiving side, it is a good idea to use bf(-O).
 This option is inferred if you use bf(--backup) without bf(--backup-dir).
 
+dit(bf(-J, --omit-link-times)) This tells rsync to omit symlinks when
+it is preserving modification times (see bf(--times)).
+
 dit(bf(--super)) This tells the receiving side to attempt super-user
 activities even if the receiving rsync wasn't run by the super-user.  These
 activities include: preserving users via the bf(--owner) option, preserving
 dit(bf(--super)) This tells the receiving side to attempt super-user
 activities even if the receiving rsync wasn't run by the super-user.  These
 activities include: preserving users via the bf(--owner) option, preserving
index 4459308..3bfa699 100644 (file)
--- a/t_stub.c
+++ b/t_stub.c
@@ -25,6 +25,7 @@ int modify_window = 0;
 int module_id = -1;
 int relative_paths = 0;
 int module_dirlen = 0;
 int module_id = -1;
 int relative_paths = 0;
 int module_dirlen = 0;
+int preserve_times = 0;
 int preserve_xattrs = 0;
 char number_separator = ',';
 char *partial_dir;
 int preserve_xattrs = 0;
 char number_separator = ',';
 char *partial_dir;
diff --git a/util.c b/util.c
index 9d5f180..ee65f54 100644 (file)
--- a/util.c
+++ b/util.c
@@ -29,6 +29,7 @@ extern int dry_run;
 extern int module_id;
 extern int modify_window;
 extern int relative_paths;
 extern int module_id;
 extern int modify_window;
 extern int relative_paths;
+extern int preserve_times;
 extern int preserve_xattrs;
 extern char *module_dir;
 extern unsigned int module_dirlen;
 extern int preserve_xattrs;
 extern char *module_dir;
 extern unsigned int module_dirlen;
@@ -124,10 +125,8 @@ NORETURN void overflow_exit(const char *str)
 
 int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
 {
 
 int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
 {
-#ifndef CAN_SET_SYMLINK_TIMES
-       if (S_ISLNK(mode))
+       if (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(mode))
                return 1;
                return 1;
-#endif
 
        if (DEBUG_GTE(TIME, 1)) {
                rprintf(FINFO, "set modtime of %s to (%ld) %s",
 
        if (DEBUG_GTE(TIME, 1)) {
                rprintf(FINFO, "set modtime of %s to (%ld) %s",
@@ -145,9 +144,7 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
                t[0].tv_nsec = UTIME_NOW;
                t[1].tv_sec = modtime;
                t[1].tv_nsec = mod_nsec;
                t[0].tv_nsec = UTIME_NOW;
                t[1].tv_sec = modtime;
                t[1].tv_nsec = mod_nsec;
-               if (utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW) < 0)
-                       return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1;
-               return 0;
+               return utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW);
 #elif defined HAVE_UTIMES || defined HAVE_LUTIMES
                struct timeval t[2];
                t[0].tv_sec = time(NULL);
 #elif defined HAVE_UTIMES || defined HAVE_LUTIMES
                struct timeval t[2];
                t[0].tv_sec = time(NULL);
@@ -155,9 +152,7 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
                t[1].tv_sec = modtime;
                t[1].tv_usec = mod_nsec / 1000;
 # ifdef HAVE_LUTIMES
                t[1].tv_sec = modtime;
                t[1].tv_usec = mod_nsec / 1000;
 # ifdef HAVE_LUTIMES
-               if (lutimes(fname, t) < 0)
-                       return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1;
-               return 0;
+               return lutimes(fname, t);
 # else
                return utimes(fname, t);
 # endif
 # else
                return utimes(fname, t);
 # endif