summaryrefslogtreecommitdiff
path: root/xattrs.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2008-03-07 16:16:29 -0800
committerWayne Davison <wayned@samba.org>2008-03-07 16:23:21 -0800
commitd724dd186ed6a2d66fa13a9357ce91e459d39e8c (patch)
treeb84c732cf840c1b32ce0b27731f6448b8cc3a673 /xattrs.c
parentcbbd8e2e8bf72aa46c84c7de43e19da40f040fa7 (diff)
downloadrsync-d724dd186ed6a2d66fa13a9357ce91e459d39e8c.tar.gz
Fixed the interaction of --fake-super with --link-dest & --xattrs.
Fixed the munging of non-user namespace xattrs w/--fake-super. Fixed the sorting of received xattrs when name-munging occurs. Added xattr tests to verify that these things stay fixed.
Diffstat (limited to 'xattrs.c')
-rw-r--r--xattrs.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/xattrs.c b/xattrs.c
index a436572b..53363bde 100644
--- a/xattrs.c
+++ b/xattrs.c
@@ -62,9 +62,12 @@ extern int checksum_seed;
#endif
#define RPRE_LEN ((int)sizeof RSYNC_PREFIX - 1)
-#define XSTAT_ATTR RSYNC_PREFIX "%stat"
-#define XACC_ACL_ATTR RSYNC_PREFIX "%aacl"
-#define XDEF_ACL_ATTR RSYNC_PREFIX "%dacl"
+#define XSTAT_SUFFIX "stat"
+#define XSTAT_ATTR RSYNC_PREFIX "%" XSTAT_SUFFIX
+#define XACC_ACL_SUFFIX "aacl"
+#define XACC_ACL_ATTR RSYNC_PREFIX "%" XACC_ACL_SUFFIX
+#define XDEF_ACL_SUFFIX "dacl"
+#define XDEF_ACL_ATTR RSYNC_PREFIX "%" XDEF_ACL_SUFFIX
typedef struct {
char *datum, *name;
@@ -231,7 +234,10 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
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))
+ || (am_root < 0
+ && (strcmp(name+RPRE_LEN+1, XSTAT_SUFFIX) == 0
+ || strcmp(name+RPRE_LEN+1, XACC_ACL_SUFFIX) == 0
+ || strcmp(name+RPRE_LEN+1, XDEF_ACL_SUFFIX) == 0)))
continue;
}
@@ -253,14 +259,6 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
} else
name_offset = datum_len;
-#ifdef HAVE_LINUX_XATTRS
- if (am_root < 0 && name_len > RPRE_LEN && name[RPRE_LEN] != '%'
- && HAS_PREFIX(name, RSYNC_PREFIX)) {
- name += RPRE_LEN;
- name_len -= RPRE_LEN;
- }
-#endif
-
rxa = EXPAND_ITEM_LIST(xalp, rsync_xa, RSYNC_XAL_INITIAL);
rxa->name = ptr + name_offset;
memcpy(rxa->name, name, name_len);
@@ -352,25 +350,33 @@ int send_xattr(stat_x *sxp, int f)
int count = sxp->xattr->count;
write_varint(f, count);
for (rxa = sxp->xattr->items; count--; rxa++) {
+ int name_len = rxa->name_len;
+ const char *name = rxa->name;
+ /* Strip the rsync prefix from disguised namespaces. */
+ if (
#ifdef HAVE_LINUX_XATTRS
- write_varint(f, rxa->name_len);
+ am_root < 0
+#endif
+ && name_len > RPRE_LEN && name[RPRE_LEN] != '%'
+ && HAS_PREFIX(name, RSYNC_PREFIX)) {
+ name += RPRE_LEN;
+ name_len -= RPRE_LEN;
+ }
+#ifndef HAVE_LINUX_XATTRS
+ else {
+ /* Put everything else in the user namespace. */
+ name_len += UPRE_LEN;
+ }
+#endif
+ write_varint(f, name_len);
write_varint(f, rxa->datum_len);
- write_buf(f, rxa->name, rxa->name_len);
-#else
- /* We strip the rsync prefix from disguised namespaces
- * and put everything else in the user namespace. */
- if (HAS_PREFIX(rxa->name, RSYNC_PREFIX)
- && rxa->name[RPRE_LEN] != '%') {
- write_varint(f, rxa->name_len - RPRE_LEN);
- write_varint(f, rxa->datum_len);
- write_buf(f, rxa->name + RPRE_LEN, rxa->name_len - RPRE_LEN);
- } else {
- write_varint(f, rxa->name_len + UPRE_LEN);
- write_varint(f, rxa->datum_len);
+#ifndef HAVE_LINUX_XATTRS
+ if (name_len > rxa->name_len) {
write_buf(f, USER_PREFIX, UPRE_LEN);
- write_buf(f, rxa->name, rxa->name_len);
+ name_len -= UPRE_LEN;
}
#endif
+ write_buf(f, name, name_len);
if (rxa->datum_len > MAX_FULL_DATUM)
write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
else
@@ -574,6 +580,11 @@ void receive_xattr(struct file_struct *file, int f)
{
static item_list temp_xattr = EMPTY_ITEM_LIST;
int count, num;
+#ifdef HAVE_LINUX_XATTRS
+ int need_sort = 0;
+#else
+ int need_sort = 1;
+#endif
int ndx = read_varint(f);
if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
@@ -624,6 +635,7 @@ void receive_xattr(struct file_struct *file, int f)
name -= RPRE_LEN;
name_len += RPRE_LEN;
memcpy(name, RSYNC_PREFIX, RPRE_LEN);
+ need_sort = 1;
}
#else
/* This OS only has a user namespace, so we either
@@ -655,6 +667,9 @@ void receive_xattr(struct file_struct *file, int f)
rxa->num = num;
}
+ if (need_sort && count > 1)
+ qsort(temp_xattr.items, count, sizeof (rsync_xa), rsync_xal_compare_names);
+
ndx = rsync_xal_l.count; /* pre-incremented count */
rsync_xal_store(&temp_xattr); /* adds item to rsync_xal_l */