X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/0d5ebab1d6df5169c5834c02c978fd5bb67421ca..HEAD:/xattrs.c diff --git a/xattrs.c b/xattrs.c index 7df67848..009da9b2 100644 --- a/xattrs.c +++ b/xattrs.c @@ -33,6 +33,9 @@ extern int am_generator; extern int read_only; extern int list_only; extern int preserve_xattrs; +extern int preserve_links; +extern int preserve_devices; +extern int preserve_specials; extern int checksum_seed; #define RSYNC_XAL_INITIAL 5 @@ -139,7 +142,7 @@ static ssize_t get_xattr_names(const char *fname) got_error: rsyserr(FERROR_XFER, errno, "get_xattr_names: llistxattr(\"%s\",%s) failed", - fname, big_num(arg)); + full_fname(fname), big_num(arg)); return -1; } list_len = sys_llistxattr(fname, NULL, 0); @@ -175,7 +178,7 @@ static char *get_xattr_data(const char *fname, const char *name, size_t *len_ptr return NULL; rsyserr(FERROR_XFER, errno, "get_xattr_data: lgetxattr(\"%s\",\"%s\",0) failed", - fname, name); + full_fname(fname), name); return NULL; } @@ -192,11 +195,11 @@ static char *get_xattr_data(const char *fname, const char *name, size_t *len_ptr if (len == (size_t)-1) { rsyserr(FERROR_XFER, errno, "get_xattr_data: lgetxattr(\"%s\",\"%s\",%ld)" - " failed", fname, name, (long)datum_len); + " failed", full_fname(fname), name, (long)datum_len); } else { rprintf(FERROR_XFER, "get_xattr_data: lgetxattr(\"%s\",\"%s\",%ld)" - " returned %ld\n", fname, name, + " returned %ld\n", full_fname(fname), name, (long)datum_len, (long)len); } free(ptr); @@ -285,18 +288,24 @@ 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; + if (S_ISREG(sxp->st.st_mode) || S_ISDIR(sxp->st.st_mode)) { + /* Everyone supports this. */ + } else if (S_ISLNK(sxp->st.st_mode)) { +#ifndef NO_SYMLINK_XATTRS + if (!preserve_links) #endif -#ifdef NO_DEVICE_XATTRS - if (IS_DEVICE(sxp->st.st_mode)) - return 0; + return 0; + } else if (IS_SPECIAL(sxp->st.st_mode)) { +#ifndef NO_SPECIAL_XATTRS + if (!preserve_specials) #endif -#ifdef NO_SYMLINK_XATTRS - if (S_ISLNK(sxp->st.st_mode)) - return 0; + return 0; + } else if (IS_DEVICE(sxp->st.st_mode)) { +#ifndef NO_DEVICE_XATTRS + if (!preserve_devices) #endif + return 0; + } if (rsync_xal_get(fname, sxp->xattr) < 0) { free_xattr(sxp); @@ -336,8 +345,8 @@ 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", - dest, name); + "copy_xattrs: lsetxattr(\"%s\",\"%s\") failed", + full_fname(dest), name); errno = save_errno; return -1; } @@ -398,7 +407,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); @@ -449,9 +458,9 @@ int send_xattr(stat_x *sxp, int f) } /* Return a flag indicating if we need to change a file's xattrs. If - * "find_all" is specified, also mark any abbreviated xattrs that we + * "mark_needed" is specified, also mark any abbreviated xattrs that we * need so that send_xattr_request() can tell the sender about them. */ -int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all) +int xattr_diff(struct file_struct *file, stat_x *sxp, BOOL mark_needed) { item_list *lst = rsync_xal_l.items; rsync_xa *snd_rxa, *rec_rxa; @@ -477,7 +486,8 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all) /* If the count of the sender's xattrs is different from our * (receiver's) xattrs, the lists are not the same. */ if (snd_cnt != rec_cnt) { - if (!find_all) + if (!mark_needed) + /* We can return as soon as we find a difference. */ return 1; xattrs_equal = 0; } @@ -491,7 +501,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all) && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1, MAX_DIGEST_LEN) == 0; /* Flag unrequested items that we need. */ - if (!same && find_all && snd_rxa->datum[0] == XSTATE_ABBREV) + if (!same && mark_needed && snd_rxa->datum[0] == XSTATE_ABBREV) snd_rxa->datum[0] = XSTATE_TODO; } else { same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len @@ -499,7 +509,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all) snd_rxa->datum_len) == 0; } if (!same) { - if (!find_all) + if (!mark_needed) return 1; xattrs_equal = 0; } @@ -589,7 +599,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); @@ -605,12 +615,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) { @@ -640,7 +650,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; @@ -661,7 +671,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; @@ -766,7 +776,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; } @@ -822,7 +832,7 @@ static int rsync_xal_set(const char *fname, item_list *xalp, else if (sys_lsetxattr(fname, name, ptr, len) < 0) { rsyserr(FERROR_XFER, errno, "rsync_xal_set: lsetxattr(\"%s\",\"%s\") failed", - fname, name); + full_fname(fname), name); ret = -1; } else /* make sure caller sets mtime */ sxp->st.st_mtime = (time_t)-1; @@ -843,7 +853,7 @@ static int rsync_xal_set(const char *fname, item_list *xalp, if (sys_lsetxattr(fname, name, rxas[i].datum, rxas[i].datum_len) < 0) { rsyserr(FERROR_XFER, errno, "rsync_xal_set: lsetxattr(\"%s\",\"%s\") failed", - fname, name); + full_fname(fname), name); ret = -1; } else /* make sure caller sets mtime */ sxp->st.st_mtime = (time_t)-1; @@ -872,8 +882,8 @@ static int rsync_xal_set(const char *fname, item_list *xalp, if (i == xalp->count) { if (sys_lremovexattr(fname, name) < 0) { rsyserr(FERROR_XFER, errno, - "rsync_xal_clear: lremovexattr(\"%s\",\"%s\") failed", - fname, name); + "rsync_xal_set: lremovexattr(\"%s\",\"%s\") failed", + full_fname(fname), name); ret = -1; } else /* make sure caller sets mtime */ sxp->st.st_mtime = (time_t)-1; @@ -935,7 +945,7 @@ int set_xattr_acl(const char *fname, int is_access_acl, const char *buf, size_t if (sys_lsetxattr(fname, name, buf, buf_len) < 0) { rsyserr(FERROR_XFER, errno, "set_xattr_acl: lsetxattr(\"%s\",\"%s\") failed", - fname, name); + full_fname(fname), name); return -1; } return 0;