* 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
#define XSTATE_ABBREV 0
#define XSTATE_DONE 1
#define XSTATE_TODO 2
-#define XSTATE_LOCAL 3
#define USER_PREFIX "user."
#define UPRE_LEN ((int)sizeof USER_PREFIX - 1)
static ssize_t get_xattr_names(const char *fname)
{
ssize_t list_len;
+ double arg;
if (!namebuf) {
namebuf_len = 1024;
out_of_memory("get_xattr_names");
}
- /* The length returned includes all the '\0' terminators. */
- list_len = sys_llistxattr(fname, namebuf, namebuf_len);
- if (list_len > (ssize_t)namebuf_len) {
- list_len = -1;
- errno = ERANGE;
- }
- if (list_len >= 0)
- return list_len;
- if (errno == ENOTSUP)
- return 0;
- if (errno == ERANGE) {
- list_len = sys_llistxattr(fname, NULL, 0);
- if (list_len < 0) {
+ while (1) {
+ /* The length returned includes all the '\0' terminators. */
+ list_len = sys_llistxattr(fname, namebuf, namebuf_len);
+ if (list_len >= 0) {
+ if ((size_t)list_len <= namebuf_len)
+ break;
+ } else if (errno == ENOTSUP)
+ return 0;
+ else if (errno != ERANGE) {
+ arg = (double)namebuf_len;
+ got_error:
rsyserr(FERROR_XFER, errno,
- "get_xattr_names: llistxattr(\"%s\",0) failed",
- fname);
+ "get_xattr_names: llistxattr(\"%s\",%.0f) failed",
+ fname, arg);
return -1;
}
+ list_len = sys_llistxattr(fname, NULL, 0);
+ if (list_len < 0) {
+ arg = 0;
+ goto got_error;
+ }
if (namebuf_len)
free(namebuf);
namebuf_len = list_len + 1024;
namebuf = new_array(char, namebuf_len);
if (!namebuf)
out_of_memory("get_xattr_names");
- list_len = sys_llistxattr(fname, namebuf, namebuf_len);
- if (list_len >= 0)
- return list_len;
}
- rsyserr(FERROR_XFER, errno,
- "get_xattr_names: llistxattr(\"%s\",%ld) failed",
- fname, (long)namebuf_len);
- return -1;
+ return list_len;
}
/* On entry, the *len_ptr parameter contains the size of the extra space we
if (rxa->datum_len <= MAX_FULL_DATUM)
continue;
switch (rxa->datum[0]) {
- case XSTATE_LOCAL:
- /* Items set locally will get cached by receiver. */
- rxa->datum[0] = XSTATE_DONE;
+ case XSTATE_ABBREV:
+ /* Items left abbreviated matched the sender's checksum, so
+ * the receiver will cache the local data for future use. */
+ if (am_generator)
+ rxa->datum[0] = XSTATE_DONE;
continue;
case XSTATE_TODO:
break;
write_byte(f_out, 0); /* end the list */
}
-/* Any items set locally by the generator that the receiver doesn't
- * get told about get changed back to XSTATE_ABBREV. */
-void xattr_clear_locals(struct file_struct *file)
-{
- item_list *lst = rsync_xal_l.items;
- rsync_xa *rxa;
- int cnt;
-
- if (F_XATTR(file) < 0)
- return;
-
- lst += F_XATTR(file);
- cnt = lst->count;
- for (rxa = lst->items; cnt--; rxa++) {
- if (rxa->datum_len <= MAX_FULL_DATUM)
- continue;
- if (rxa->datum[0] == XSTATE_LOCAL)
- rxa->datum[0] = XSTATE_ABBREV;
- }
-}
-
/* When called by the sender, read the request from the generator and mark
* 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
sxp->st.st_mtime = (time_t)-1;
if (am_generator) { /* generator items stay abbreviated */
- if (rxas[i].datum[0] == XSTATE_ABBREV)
- rxas[i].datum[0] = XSTATE_LOCAL;
free(ptr);
continue;
}