--- a/generator.c +++ b/generator.c @@ -584,29 +584,54 @@ static void do_delete_pass(void) int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) { -#if !defined HAVE_LUTIMES || !defined HAVE_UTIMES + int skip_times = 0, skip_perms = 0, skip_ownership = 0; +#ifdef SUPPORT_ACLS + int skip_acls = 0; +#endif +#ifdef SUPPORT_XATTRS + int skip_xattrs = 0; +#endif + if (S_ISLNK(file->mode)) { - ; - } else +#ifndef CAN_SET_SYMLINK_TIMES + skip_times = 1; #endif - if (preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0) +#ifndef CAN_CHMOD_SYMLINK + skip_perms = 1; +#endif +#ifndef CAN_CHOWN_SYMLINK + skip_ownership = 1; +#endif +#ifdef SUPPORT_ACLS + skip_acls = 1; +#endif +#if defined SUPPORT_XATTRS && defined NO_SYMLINK_XATTRS + skip_xattrs = 1; +#endif + } + + if (!skip_times && preserve_times && cmp_time(sxp->st.st_mtime, file->modtime) != 0) return 0; - if (preserve_perms) { - if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS)) + if (!skip_perms) { + 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; - } 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)) - return 0; + if (!skip_ownership) { + if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file)) + return 0; - if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file)) - return 0; + if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file)) + return 0; + } #ifdef SUPPORT_ACLS - if (preserve_acls && !S_ISLNK(file->mode)) { + if (!skip_acls && preserve_acls) { if (!ACL_READY(*sxp)) get_acl(fname, sxp); if (set_acl(NULL, file, sxp) == 0) @@ -614,7 +639,7 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) } #endif #ifdef SUPPORT_XATTRS - if (preserve_xattrs) { + if (!skip_xattrs && preserve_xattrs) { if (!XATTR_READY(*sxp)) get_xattr(fname, sxp); if (xattr_diff(file, sxp, 0)) --- a/rsync.c +++ b/rsync.c @@ -444,7 +444,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file); change_gid = gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file); -#if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK +#ifndef CAN_CHOWN_SYMLINK if (S_ISLNK(sxp->st.st_mode)) { ; } else --- a/rsync.h +++ b/rsync.h @@ -335,6 +335,14 @@ enum msgcode { #include #endif +#if defined HAVE_LCHOWN || defined CHOWN_MODIFIES_SYMLINK +#define CAN_CHOWN_SYMLINK 1 +#endif + +#if defined HAVE_LCHMOD || defined HAVE_SETATTRLIST +#define CAN_CHMOD_SYMLINK 1 +#endif + #ifdef HAVE_SYS_SELECT_H #include #endif