* Written by Jay Fenlason, vaguely based on the ACLs patch.
*
* Copyright (C) 2004 Red Hat, Inc.
- * Copyright (C) 2006, 2007 Wayne Davison
+ * Copyright (C) 2006-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
#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;
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;
}
} 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);
int count = sxp->xattr->count;
write_varint(f, count);
for (rxa = sxp->xattr->items; count--; rxa++) {
+ size_t name_len = rxa->name_len;
+ const char *name = rxa->name;
+ /* Strip the rsync prefix from disguised namespaces. */
+ if (name_len > RPRE_LEN
#ifdef HAVE_LINUX_XATTRS
- write_varint(f, rxa->name_len);
+ && am_root < 0
+#endif
+ && 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
{
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) {
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
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 */
ssize_t list_len;
size_t i, len;
char *name, *ptr, sum[MAX_DIGEST_LEN];
- int name_len, ret = 0;
+ size_t name_len;
+ int ret = 0;
/* This puts the current name list into the "namebuf" buffer. */
if ((list_len = get_xattr_names(fname)) < 0)