Refer to the right lsetxattr() caller in a error message.
[rsync/rsync.git] / xattrs.c
index b903475..e6a7156 100644 (file)
--- a/xattrs.c
+++ b/xattrs.c
@@ -284,6 +284,20 @@ int get_xattr(const char *fname, stat_x *sxp)
 {
        sxp->xattr = new(item_list);
        *sxp->xattr = empty_xattr;
+
+#ifdef NO_SPECIAL_XATTRS
+       if (IS_SPECIAL(sxp->st.st_mode))
+               return 0;
+#endif
+#ifdef NO_DEVICE_XATTRS
+       if (IS_DEVICE(sxp->st.st_mode))
+               return 0;
+#endif
+#ifdef NO_SYMLINK_XATTRS
+       if (S_ISLNK(sxp->st.st_mode))
+               return 0;
+#endif
+
        if (rsync_xal_get(fname, sxp->xattr) < 0) {
                free_xattr(sxp);
                return -1;
@@ -322,7 +336,7 @@ int copy_xattrs(const char *source, const char *dest)
                if (sys_lsetxattr(dest, name, ptr, datum_len) < 0) {
                        int save_errno = errno ? errno : EINVAL;
                        rsyserr(FERROR_XFER, errno,
-                               "rsync_xal_set: lsetxattr(\"%s\",\"%s\") failed",
+                               "copy_xattrs: lsetxattr(\"%s\",\"%s\") failed",
                                dest, name);
                        errno = save_errno;
                        return -1;
@@ -384,7 +398,7 @@ static void rsync_xal_store(item_list *xalp)
 }
 
 /* Send the make_xattr()-generated xattr list for this flist entry. */
-int send_xattr(stat_x *sxp, int f)
+int send_xattr(int f, stat_x *sxp)
 {
        int ndx = find_matching_xattr(sxp->xattr);
 
@@ -575,7 +589,7 @@ int recv_xattr_request(struct file_struct *file, int f_in)
 
        if (F_XATTR(file) < 0) {
                rprintf(FERROR, "recv_xattr_request: internal data error!\n");
-               exit_cleanup(RERR_STREAMIO);
+               exit_cleanup(RERR_PROTOCOL);
        }
        lst += F_XATTR(file);
 
@@ -591,12 +605,12 @@ int recv_xattr_request(struct file_struct *file, int f_in)
                if (!cnt || rxa->num != num) {
                        rprintf(FERROR, "[%s] could not find xattr #%d for %s\n",
                                who_am_i(), num, f_name(file, NULL));
-                       exit_cleanup(RERR_STREAMIO);
+                       exit_cleanup(RERR_PROTOCOL);
                }
                if (!XATTR_ABBREV(*rxa) || rxa->datum[0] != XSTATE_ABBREV) {
                        rprintf(FERROR, "[%s] internal abbrev error on %s (%s, len=%ld)!\n",
                                who_am_i(), f_name(file, NULL), rxa->name, (long)rxa->datum_len);
-                       exit_cleanup(RERR_STREAMIO);
+                       exit_cleanup(RERR_PROTOCOL);
                }
 
                if (am_sender) {
@@ -626,7 +640,7 @@ int recv_xattr_request(struct file_struct *file, int f_in)
 /* ------------------------------------------------------------------------- */
 
 /* receive and build the rsync_xattr_lists */
-void receive_xattr(struct file_struct *file, int f)
+void receive_xattr(int f, struct file_struct *file)
 {
        static item_list temp_xattr = EMPTY_ITEM_LIST;
        int count, num;
@@ -647,7 +661,7 @@ void receive_xattr(struct file_struct *file, int f)
                F_XATTR(file) = ndx - 1;
                return;
        }
-       
+
        if ((count = read_varint(f)) != 0) {
                (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
                temp_xattr.count = 0;
@@ -752,7 +766,7 @@ void uncache_tmp_xattrs(void)
                rsync_xal_l.count = prior_xattr_count;
                while (xattr_item-- > xattr_start) {
                        rsync_xal_free(xattr_item);
-                       free(xattr_item);
+                       free(xattr_item->items);
                }
                prior_xattr_count = (size_t)-1;
        }
@@ -884,6 +898,25 @@ int set_xattr(const char *fname, const struct file_struct *file,
                return -1;
        }
 
+#ifdef NO_SPECIAL_XATTRS
+       if (IS_SPECIAL(sxp->st.st_mode)) {
+               errno = ENOTSUP;
+               return -1;
+       }
+#endif
+#ifdef NO_DEVICE_XATTRS
+       if (IS_DEVICE(sxp->st.st_mode)) {
+               errno = ENOTSUP;
+               return -1;
+       }
+#endif
+#ifdef NO_SYMLINK_XATTRS
+       if (S_ISLNK(sxp->st.st_mode)) {
+               errno = ENOTSUP;
+               return -1;
+       }
+#endif
+
        ndx = F_XATTR(file);
        return rsync_xal_set(fname, lst + ndx, fnamecmp, sxp);
 }
@@ -990,7 +1023,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
        fst.st_mode &= (_S_IFMT | CHMOD_BITS);
        fmode = new_mode & (_S_IFMT | CHMOD_BITS);
 
-       if (IS_DEVICE(fmode) || IS_SPECIAL(fmode)) {
+       if (IS_DEVICE(fmode)) {
                uint32 *devp = F_RDEV_P(file);
                rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
        } else
@@ -1001,7 +1034,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
             | (S_ISDIR(fst.st_mode) ? 0700 : 0600);
        if (fst.st_mode != mode)
                do_chmod(fname, mode);
-       if (!IS_DEVICE(fst.st_mode) && !IS_SPECIAL(fst.st_mode))
+       if (!IS_DEVICE(fst.st_mode))
                fst.st_rdev = 0; /* just in case */
 
        if (mode == fmode && fst.st_rdev == rdev