summaryrefslogtreecommitdiff
path: root/xattrs.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2007-11-25 13:48:54 -0800
committerWayne Davison <wayned@samba.org>2007-11-25 13:48:54 -0800
commita685271de33c6d9d39fb1a8855fe214911c774e6 (patch)
treeac2c4c28f84e448a91e2ecf36dc53b9f08a9de09 /xattrs.c
parent613c2d44317e9e1aacba22a3af9ce31078893339 (diff)
downloadrsync-a685271de33c6d9d39fb1a8855fe214911c774e6.tar.gz
Various xattr fixes:
- Fake-super mode no longer strips the RSYNC_PREFIX from a "%name" item. - Make various places skip the fake-super xattr when --fake-super is enabled. - If we fail to re-read the xattr value of an xattr we are trying to un- abbreviate, send a zero for its length (avoiding a protocol problem).
Diffstat (limited to 'xattrs.c')
-rw-r--r--xattrs.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/xattrs.c b/xattrs.c
index 5e808297..6ab9698b 100644
--- a/xattrs.c
+++ b/xattrs.c
@@ -216,7 +216,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
return -1;
for (name = namebuf; list_len > 0; name += name_len) {
- rsync_xa *rxas;
+ rsync_xa *rxa;
name_len = strlen(name) + 1;
list_len -= name_len;
@@ -230,9 +230,12 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
#endif
/* No rsync.%FOO attributes are copied w/o 2 -X options. */
- if (am_sender && preserve_xattrs < 2 && name_len > RPRE_LEN
- && name[RPRE_LEN] == '%' && HAS_PREFIX(name, RSYNC_PREFIX))
- continue;
+ if (name_len > RPRE_LEN && name[RPRE_LEN] == '%'
+ && HAS_PREFIX(name, RSYNC_PREFIX)) {
+ if ((am_sender && preserve_xattrs < 2)
+ || (am_root < 0 && strcmp(name, XSTAT_ATTR) == 0))
+ continue;
+ }
datum_len = name_len; /* Pass extra size to get_xattr_data() */
if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
@@ -253,19 +256,19 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
name_offset = datum_len;
#ifdef HAVE_LINUX_XATTRS
- if (am_root < 0 && name_len > RPRE_LEN
+ if (am_root < 0 && name_len > RPRE_LEN && name[RPRE_LEN] != '%'
&& HAS_PREFIX(name, RSYNC_PREFIX)) {
name += RPRE_LEN;
name_len -= RPRE_LEN;
}
#endif
- rxas = EXPAND_ITEM_LIST(xalp, rsync_xa, RSYNC_XAL_INITIAL);
- rxas->name = ptr + name_offset;
- memcpy(rxas->name, name, name_len);
- rxas->datum = ptr;
- rxas->name_len = name_len;
- rxas->datum_len = datum_len;
+ rxa = EXPAND_ITEM_LIST(xalp, rsync_xa, RSYNC_XAL_INITIAL);
+ rxa->name = ptr + name_offset;
+ memcpy(rxa->name, name, name_len);
+ rxa->datum = ptr;
+ rxa->name_len = name_len;
+ rxa->datum_len = datum_len;
}
if (xalp->count > 1)
qsort(xalp->items, xalp->count, sizeof (rsync_xa), rsync_xal_compare_names);
@@ -486,8 +489,11 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
char *ptr;
/* Re-read the long datum. */
- if (!(ptr = get_xattr_data(fname, rxa->name, &len, 0)))
+ if (!(ptr = get_xattr_data(fname, rxa->name, &len, 0))) {
+ rprintf(FERROR_XFER, "failed to re-read xattr %s for %s\n", rxa->name, fname);
+ write_varint(f_out, 0);
continue;
+ }
write_varint(f_out, len); /* length might have changed! */
write_buf(f_out, ptr, len);