From e107b6b122812d88d531f3826e1a510abe916006 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sat, 24 Nov 2007 10:50:45 -0800 Subject: [PATCH] Fixed a problem with --fake-super not getting the fully tweaked new_mode value. Also fixed the removal of rsync-internal xattr values on the destination files when we aren't copying rsync-internal xattr values. --- rsync.c | 8 ++++---- xattrs.c | 16 +++++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/rsync.c b/rsync.c index c5bcbb5a..ca122561 100644 --- a/rsync.c +++ b/rsync.c @@ -371,6 +371,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, new_mode |= S_ISGID; } + if (daemon_chmod_modes && !S_ISLNK(new_mode)) + new_mode = tweak_mode(new_mode, daemon_chmod_modes); + #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode) && !ACL_READY(*sxp)) get_acl(fname, sxp); @@ -380,7 +383,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, if (preserve_xattrs && fnamecmp) set_xattr(fname, file, fnamecmp, sxp); if (am_root < 0) - set_stat_xattr(fname, file); + set_stat_xattr(fname, file, new_mode); #endif if (!preserve_times || (S_ISDIR(sxp->st.st_mode) && preserve_times == 1)) @@ -440,9 +443,6 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, updated = 1; } - if (daemon_chmod_modes && !S_ISLNK(new_mode)) - new_mode = tweak_mode(new_mode, daemon_chmod_modes); - #ifdef SUPPORT_ACLS /* It's OK to call set_acl() now, even for a dir, as the generator * will enable owner-writability using chmod, if necessary. diff --git a/xattrs.c b/xattrs.c index 21e30499..5e808297 100644 --- a/xattrs.c +++ b/xattrs.c @@ -230,7 +230,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp) #endif /* No rsync.%FOO attributes are copied w/o 2 -X options. */ - if (preserve_xattrs < 2 && name_len > RPRE_LEN + if (am_sender && preserve_xattrs < 2 && name_len > RPRE_LEN && name[RPRE_LEN] == '%' && HAS_PREFIX(name, RSYNC_PREFIX)) continue; @@ -523,12 +523,12 @@ void xattr_clear_locals(struct file_struct *file) * any needed xattrs with a flag that lets us know they need to be sent to * the receiver. When called by the receiver, reads the sent data and * stores it in place of its checksum. */ -void recv_xattr_request(struct file_struct *file, int f_in) +int recv_xattr_request(struct file_struct *file, int f_in) { item_list *lst = rsync_xal_l.items; char *old_datum, *name; rsync_xa *rxa; - int rel_pos, cnt; + int rel_pos, cnt, got_xattr_data = 0; if (F_XATTR(file) < 0) { rprintf(FERROR, "recv_xattr_request: internal data error!\n"); @@ -566,7 +566,10 @@ void recv_xattr_request(struct file_struct *file, int f_in) rxa->name = name; free(old_datum); read_buf(f_in, rxa->datum, rxa->datum_len); + got_xattr_data = 1; } + + return got_xattr_data; } /* ------------------------------------------------------------------------- */ @@ -765,6 +768,9 @@ static int rsync_xal_set(const char *fname, item_list *xalp, : !HAS_PREFIX(name, USER_PREFIX)) continue; #endif + if (am_root < 0 && name_len > RPRE_LEN + && name[RPRE_LEN] == '%' && strcmp(name, XSTAT_ATTR) == 0) + continue; for (i = 0; i < xalp->count; i++) { if (strcmp(name, rxas[i].name) == 0) @@ -881,7 +887,7 @@ int get_stat_xattr(const char *fname, int fd, STRUCT_STAT *fst, STRUCT_STAT *xst return 0; } -int set_stat_xattr(const char *fname, struct file_struct *file) +int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) { STRUCT_STAT fst, xst; dev_t rdev; @@ -903,7 +909,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file) } fst.st_mode &= (_S_IFMT | CHMOD_BITS); - fmode = file->mode & (_S_IFMT | CHMOD_BITS); + fmode = new_mode & (_S_IFMT | CHMOD_BITS); if (IS_DEVICE(fmode) || IS_SPECIAL(fmode)) { uint32 *devp = F_RDEV_P(file); -- 2.34.1