Fixed the itemizing of perms with -E.
[rsync/rsync.git] / generator.c
index 4ebc5e5..9e24f56 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2007 Wayne Davison
+ * Copyright (C) 2003-2008 Wayne Davison
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -582,10 +582,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
        if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0)
                return 0;
 
-       if (preserve_perms && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
-               return 0;
-
-       if (preserve_executability && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
+       if (preserve_perms) {
+               if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
+                       return 0;
+       } else if (preserve_executability
+        && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
                return 0;
 
        if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file))
@@ -638,8 +639,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
                        ;
                } else
 #endif
-               if ((preserve_perms || preserve_executability)
-                && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
+               if (preserve_perms) {
+                       if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
+                               iflags |= ITEM_REPORT_PERMS;
+               } else if (preserve_executability
+                && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
                        iflags |= ITEM_REPORT_PERMS;
                if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid)
                        iflags |= ITEM_REPORT_OWNER;
@@ -1949,8 +1953,12 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
                fname = f_name(file, NULL);
                if (!(file->mode & S_IWUSR))
                        do_chmod(fname, file->mode);
-               if (need_retouch_dir_times)
-                       set_modtime(fname, file->modtime, file->mode);
+               if (need_retouch_dir_times) {
+                       STRUCT_STAT st;
+                       if (link_stat(fname, &st, 0) == 0
+                        && cmp_time(st.st_mtime, file->modtime) != 0)
+                               set_modtime(fname, file->modtime, file->mode);
+               }
                if (allowed_lull && !(counter % lull_mod))
                        maybe_send_keepalive();
                else if (!(counter & 0xFF))