From 526184b9143ed4fc73f1b197e6aca065b47d1124 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Thu, 8 Mar 2007 01:37:38 +0000 Subject: [PATCH] We now remove any extraneous xattr values from a file that isn't being updated. --- xattrs.diff | 111 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 38 deletions(-) diff --git a/xattrs.diff b/xattrs.diff index cf46b67..e8a53f7 100644 --- a/xattrs.diff +++ b/xattrs.diff @@ -18,9 +18,6 @@ TODO: - This patch needs to more efficiently handle large xattrs, especially when they're unchanged. - - Extraneous xattr values need to be removed from files that are not being - recreated. - - We need to affect the itemized output to know when xattrs are being updated. - We need to affect the --link-dest option to avoid hard-linking two files @@ -46,7 +43,7 @@ TODO: popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \ --- old/backup.c +++ new/backup.c -@@ -24,6 +24,7 @@ +@@ -23,6 +23,7 @@ extern int verbose; extern int am_root; extern int preserve_acls; @@ -54,7 +51,7 @@ TODO: extern int preserve_devices; extern int preserve_specials; extern int preserve_links; -@@ -135,6 +136,9 @@ static int make_bak_dir(char *fullpath) +@@ -134,6 +135,9 @@ static int make_bak_dir(char *fullpath) #ifdef SUPPORT_ACLS sx.acc_acl = sx.def_acl = NULL; #endif @@ -64,7 +61,7 @@ TODO: if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS))) continue; #ifdef SUPPORT_ACLS -@@ -143,6 +147,12 @@ static int make_bak_dir(char *fullpath) +@@ -142,6 +146,12 @@ static int make_bak_dir(char *fullpath) cache_acl(file, &sx); } #endif @@ -77,7 +74,7 @@ TODO: set_file_attrs(fullpath, file, NULL, 0); free(file); } -@@ -194,6 +204,9 @@ static int keep_backup(const char *fname +@@ -193,6 +203,9 @@ static int keep_backup(const char *fname #ifdef SUPPORT_ACLS sx.acc_acl = sx.def_acl = NULL; #endif @@ -87,7 +84,7 @@ TODO: if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) return 1; /* the file could have disappeared */ -@@ -209,6 +222,12 @@ static int keep_backup(const char *fname +@@ -208,6 +221,12 @@ static int keep_backup(const char *fname cache_acl(file, &sx); } #endif @@ -102,7 +99,7 @@ TODO: if ((am_root && preserve_devices && IS_DEVICE(file->mode)) --- old/compat.c +++ new/compat.c -@@ -58,6 +58,8 @@ void setup_protocol(int f_out,int f_in) +@@ -64,6 +64,8 @@ void setup_protocol(int f_out,int f_in) preserve_gid = ++file_extra_cnt; if (preserve_acls && !am_sender) preserve_acls = ++file_extra_cnt; @@ -156,7 +153,7 @@ TODO: --- old/flist.c +++ new/flist.c -@@ -43,6 +43,7 @@ extern int one_file_system; +@@ -42,6 +42,7 @@ extern int one_file_system; extern int copy_dirlinks; extern int keep_dirlinks; extern int preserve_acls; @@ -164,7 +161,7 @@ TODO: extern int preserve_links; extern int preserve_hard_links; extern int preserve_devices; -@@ -865,6 +866,10 @@ static struct file_struct *recv_file_ent +@@ -864,6 +865,10 @@ static struct file_struct *recv_file_ent if (preserve_acls) receive_acl(file, f); #endif @@ -175,7 +172,7 @@ TODO: if (S_ISREG(mode) || S_ISLNK(mode)) stats.total_size += file_length; -@@ -1137,7 +1142,7 @@ static struct file_struct *send_file_nam +@@ -1136,7 +1141,7 @@ static struct file_struct *send_file_nam int flags, int filter_flags) { struct file_struct *file; @@ -184,7 +181,7 @@ TODO: statx sx; #endif -@@ -1156,6 +1161,13 @@ static struct file_struct *send_file_nam +@@ -1155,6 +1160,13 @@ static struct file_struct *send_file_nam return NULL; } #endif @@ -198,7 +195,7 @@ TODO: maybe_emit_filelist_progress(flist->count + flist_count_offset); -@@ -1167,6 +1179,10 @@ static struct file_struct *send_file_nam +@@ -1166,6 +1178,10 @@ static struct file_struct *send_file_nam if (preserve_acls) send_acl(&sx, f); #endif @@ -378,7 +375,7 @@ TODO: +#endif --- old/options.c +++ new/options.c -@@ -48,6 +48,7 @@ int copy_links = 0; +@@ -47,6 +47,7 @@ int copy_links = 0; int preserve_links = 0; int preserve_hard_links = 0; int preserve_acls = 0; @@ -386,7 +383,7 @@ TODO: int preserve_perms = 0; int preserve_executability = 0; int preserve_devices = 0; -@@ -201,6 +202,7 @@ static void print_rsync_version(enum log +@@ -200,6 +201,7 @@ static void print_rsync_version(enum log char const *have_inplace = "no "; char const *hardlinks = "no "; char const *acls = "no "; @@ -394,7 +391,7 @@ TODO: char const *links = "no "; char const *ipv6 = "no "; STRUCT_STAT *dumstat; -@@ -220,7 +222,9 @@ static void print_rsync_version(enum log +@@ -219,7 +221,9 @@ static void print_rsync_version(enum log #ifdef SUPPORT_ACLS acls = ""; #endif @@ -405,7 +402,7 @@ TODO: #ifdef SUPPORT_LINKS links = ""; #endif -@@ -239,8 +243,8 @@ static void print_rsync_version(enum log +@@ -238,8 +242,8 @@ static void print_rsync_version(enum log (int)(sizeof (int64) * 8)); rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n", got_socketpair, hardlinks, links, ipv6, have_inplace); @@ -416,7 +413,7 @@ TODO: #ifdef MAINTAINER_MODE rprintf(f, "Panic Action: \"%s\"\n", get_panic_action()); -@@ -286,7 +290,7 @@ void usage(enum logcode F) +@@ -285,7 +289,7 @@ void usage(enum logcode F) rprintf(F," -q, --quiet suppress non-error messages\n"); rprintf(F," --no-motd suppress daemon-mode MOTD (see manpage caveat)\n"); rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n"); @@ -425,7 +422,7 @@ TODO: rprintf(F," --no-OPTION turn off an implied OPTION (e.g. --no-D)\n"); rprintf(F," -r, --recursive recurse into directories\n"); rprintf(F," -R, --relative use relative path names\n"); -@@ -311,6 +315,9 @@ void usage(enum logcode F) +@@ -310,6 +314,9 @@ void usage(enum logcode F) #ifdef SUPPORT_ACLS rprintf(F," -A, --acls preserve ACLs (implies --perms)\n"); #endif @@ -435,7 +432,7 @@ TODO: rprintf(F," -o, --owner preserve owner (super-user only)\n"); rprintf(F," -g, --group preserve group\n"); rprintf(F," --devices preserve device files (super-user only)\n"); -@@ -434,6 +441,9 @@ static struct poptOption long_options[] +@@ -433,6 +440,9 @@ static struct poptOption long_options[] {"acls", 'A', POPT_ARG_NONE, 0, 'A', 0, 0 }, {"no-acls", 0, POPT_ARG_VAL, &preserve_acls, 0, 0, 0 }, {"no-A", 0, POPT_ARG_VAL, &preserve_acls, 0, 0, 0 }, @@ -445,7 +442,7 @@ TODO: {"times", 't', POPT_ARG_VAL, &preserve_times, 1, 0, 0 }, {"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, {"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, -@@ -1122,6 +1132,17 @@ int parse_arguments(int *argc, const cha +@@ -1121,6 +1131,17 @@ int parse_arguments(int *argc, const cha return 0; #endif @@ -463,7 +460,7 @@ TODO: default: /* A large opt value means that set_refuse_options() -@@ -1590,6 +1611,10 @@ void server_options(char **args,int *arg +@@ -1585,6 +1606,10 @@ void server_options(char **args,int *arg if (preserve_acls) argstr[x++] = 'A'; #endif @@ -476,7 +473,7 @@ TODO: if (always_checksum) --- old/rsync.c +++ new/rsync.c -@@ -33,6 +33,7 @@ +@@ -32,6 +32,7 @@ extern int verbose; extern int dry_run; extern int preserve_acls; @@ -497,7 +494,7 @@ TODO: * will enable owner-writability using chmod, if necessary. --- old/rsync.h +++ new/rsync.h -@@ -554,6 +554,10 @@ struct idev_node { +@@ -555,6 +555,10 @@ struct idev_node { #define ACLS_NEED_MASK 1 #endif @@ -508,7 +505,7 @@ TODO: #define GID_NONE ((gid_t)-1) union file_extras { -@@ -574,6 +578,7 @@ extern int file_extra_cnt; +@@ -575,6 +579,7 @@ extern int file_extra_cnt; extern int preserve_uid; extern int preserve_gid; extern int preserve_acls; @@ -516,7 +513,7 @@ TODO: #define FILE_STRUCT_LEN (offsetof(struct file_struct, basename)) #define EXTRA_LEN (sizeof (union file_extras)) -@@ -607,6 +612,7 @@ extern int preserve_acls; +@@ -608,6 +613,7 @@ extern int preserve_acls; #define F_OWNER(f) REQ_EXTRA(f, preserve_uid)->unum #define F_GROUP(f) REQ_EXTRA(f, preserve_gid)->unum #define F_ACL(f) REQ_EXTRA(f, preserve_acls)->unum @@ -524,7 +521,7 @@ TODO: /* These items are per-entry optional and mutally exclusive: */ #define F_HL_GNUM(f) OPT_EXTRA(f, LEN64_BUMP(f))->num -@@ -798,6 +804,9 @@ typedef struct { +@@ -799,6 +805,9 @@ typedef struct { struct rsync_acl *acc_acl; /* access ACL */ struct rsync_acl *def_acl; /* default ACL */ #endif @@ -567,7 +564,7 @@ TODO: transfer. The resulting value is treated as though it was the permissions --- old/xattr.c +++ new/xattr.c -@@ -0,0 +1,413 @@ +@@ -0,0 +1,451 @@ +/* + * Extended Attribute support for rsync. + * Written by Jay Fenlason, vaguely based on the ACLs patch. @@ -657,16 +654,15 @@ TODO: + return strcmp(xa1->name, xa2->name); +} + -+static int rsync_xal_get(const char *fname, item_list *xalp) ++static ssize_t rsync_xal_list(const char *fname) +{ -+ ssize_t list_len, name_len, datum_len; -+ char *name, *ptr; ++ ssize_t list_len; + + if (!namebuf) { + namebuf_len = 1024; + namebuf = new_array(char, namebuf_len); + if (!namebuf) -+ out_of_memory("rsync_xal_get"); ++ out_of_memory("rsync_xal_list"); + } + + /* The length returned includes all the '\0' terminators. */ @@ -682,29 +678,41 @@ TODO: + list_len = sys_llistxattr(fname, NULL, 0); + if (list_len < 0) { + rsyserr(FERROR, errno, -+ "rsync_xal_get: llistxattr(\"%s\",0) failed", ++ "rsync_xal_list: llistxattr(\"%s\",0) failed", + fname); + return -1; + } + namebuf = realloc_array(namebuf, char, list_len + 1024); + if (!namebuf) -+ out_of_memory("rsync_xal_get"); ++ out_of_memory("rsync_xal_list"); + namebuf_len = list_len + 1024; + list_len = sys_llistxattr(fname, namebuf, namebuf_len); + if (list_len < 0) { + rsyserr(FERROR, errno, -+ "rsync_xal_get: llistxattr(\"%s\",%ld) failed", ++ "rsync_xal_list: llistxattr(\"%s\",%ld) failed", + fname, (long)namebuf_len); + return -1; + } + } else { + rsyserr(FERROR, errno, -+ "rsync_xal_get: llistxattr(\"%s\",%ld) failed", ++ "rsync_xal_list: llistxattr(\"%s\",%ld) failed", + fname, (long)namebuf_len); + return -1; + } + } + ++ return list_len; ++} ++ ++static int rsync_xal_get(const char *fname, item_list *xalp) ++{ ++ ssize_t list_len, name_len, datum_len; ++ char *name, *ptr; ++ ++ /* This puts the name list into the "namebuf" buffer. */ ++ if ((list_len = rsync_xal_list(fname)) < 0) ++ return -1; ++ + for (name = namebuf; list_len > 0; name += name_len) { + rsync_xa *rxas; + @@ -947,8 +955,14 @@ TODO: +static int rsync_xal_set(const char *fname, item_list *xalp) +{ + rsync_xa *rxas = xalp->items; ++ ssize_t list_len; + size_t i; -+ int ret = 0; ++ char *name; ++ int name_len, ret = 0; ++ ++ /* This puts the current name list into the "namebuf" buffer. */ ++ if ((list_len = rsync_xal_list(fname)) < 0) ++ return -1; + + for (i = 0; i < xalp->count; i++) { + int status = sys_lsetxattr(fname, rxas[i].name, rxas[i].datum, rxas[i].datum_len); @@ -959,6 +973,27 @@ TODO: + ret = -1; + } + } ++ ++ /* Remove any extraneous names. */ ++ for (name = namebuf; list_len > 0; name += name_len) { ++ name_len = strlen(name) + 1; ++ list_len -= name_len; ++ ++ for (i = 0; i < xalp->count; i++) { ++ if (strcmp(name, rxas[i].name) == 0) ++ break; ++ } ++ if (i == xalp->count) { ++ int status = sys_lremovexattr(fname, name); ++ if (status < 0) { ++ rsyserr(FERROR, errno, ++ "rsync_xal_clear: lremovexattr(\"%s\",\"%s\") failed", ++ fname, name); ++ ret = -1; ++ } ++ } ++ } ++ + return ret; +} + -- 2.34.1