Include 2008 in the copyright years.
[rsync/rsync.git] / xattrs.c
index 24a01c1..a436572 100644 (file)
--- a/xattrs.c
+++ b/xattrs.c
@@ -3,7 +3,7 @@
  * 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
@@ -47,7 +47,6 @@ extern int checksum_seed;
 #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)
@@ -112,6 +111,7 @@ static int rsync_xal_compare_names(const void *x1, const void *x2)
 static ssize_t get_xattr_names(const char *fname)
 {
        ssize_t list_len;
+       double arg;
 
        if (!namebuf) {
                namebuf_len = 1024;
@@ -120,39 +120,36 @@ static ssize_t get_xattr_names(const char *fname)
                        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
@@ -472,9 +469,11 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
                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;
@@ -508,27 +507,6 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
        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
@@ -751,8 +729,6 @@ static int rsync_xal_set(const char *fname, item_list *xalp,
                                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;
                        }