+++ /dev/null
-This patch adds backward-compatibility support for the --acls option.
-Since the main release has never had ACL support, the trunk doesn't
-need this code. If you want to make rsync 3.0.x communicate with an
-older (patched) release, use this.
-
-To use this patch, run these commands for a successful build:
-
- patch -p1 <patches/acls.diff
- ./configure (optional if already run)
- make
-
-based-on: 194cee671d5e178f20c4494f41911fa8db942935
-diff --git a/acls.c b/acls.c
---- a/acls.c
-+++ b/acls.c
-@@ -31,6 +31,7 @@ extern int list_only;
- extern int orig_umask;
- extern int numeric_ids;
- extern int inc_recurse;
-+extern int protocol_version;
- extern int preserve_devices;
- extern int preserve_specials;
-
-@@ -112,6 +113,18 @@ static const char *str_acl_type(SMB_ACL_TYPE_T type)
- return "unknown ACL type!";
- }
-
-+#define OTHER_TYPE(t) (SMB_ACL_TYPE_ACCESS+SMB_ACL_TYPE_DEFAULT-(t))
-+#define BUMP_TYPE(t) ((t = OTHER_TYPE(t)) == SMB_ACL_TYPE_DEFAULT)
-+
-+static int old_count_racl_entries(const rsync_acl *racl)
-+{
-+ return racl->names.count
-+ + (racl->user_obj != NO_ENTRY)
-+ + (racl->group_obj != NO_ENTRY)
-+ + (racl->mask_obj != NO_ENTRY)
-+ + (racl->other_obj != NO_ENTRY);
-+}
-+
- static int calc_sacl_entries(const rsync_acl *racl)
- {
- /* A System ACL always gets user/group/other permission entries. */
-@@ -574,6 +587,94 @@ int get_acl(const char *fname, stat_x *sxp)
- return 0;
- }
-
-+/* === OLD Send functions === */
-+
-+/* Send the ida list over the file descriptor. */
-+static void old_send_ida_entries(int f, const ida_entries *idal, char tag_char)
-+{
-+ id_access *ida;
-+ size_t count = idal->count;
-+ for (ida = idal->idas; count--; ida++) {
-+ if (tag_char == 'U') {
-+ if (!(ida->access & NAME_IS_USER))
-+ continue;
-+ add_uid(ida->id);
-+ } else {
-+ if (ida->access & NAME_IS_USER)
-+ continue;
-+ add_gid(ida->id);
-+ }
-+ write_byte(f, tag_char);
-+ write_byte(f, ida->access);
-+ write_int(f, ida->id);
-+ }
-+}
-+
-+/* Send an rsync ACL over the file descriptor. */
-+static void old_send_rsync_acl(int f, const rsync_acl *racl)
-+{
-+ size_t count = old_count_racl_entries(racl);
-+ write_int(f, count);
-+ if (racl->user_obj != NO_ENTRY) {
-+ write_byte(f, 'u');
-+ write_byte(f, racl->user_obj);
-+ }
-+ old_send_ida_entries(f, &racl->names, 'U');
-+ if (racl->group_obj != NO_ENTRY) {
-+ write_byte(f, 'g');
-+ write_byte(f, racl->group_obj);
-+ }
-+ old_send_ida_entries(f, &racl->names, 'G');
-+ if (racl->mask_obj != NO_ENTRY) {
-+ write_byte(f, 'm');
-+ write_byte(f, racl->mask_obj);
-+ }
-+ if (racl->other_obj != NO_ENTRY) {
-+ write_byte(f, 'o');
-+ write_byte(f, racl->other_obj);
-+ }
-+}
-+
-+/* Send the ACL from the stat_x structure down the indicated file descriptor.
-+ * This also frees the ACL data. */
-+void old_send_acl(stat_x *sxp, int f)
-+{
-+ SMB_ACL_TYPE_T type;
-+ rsync_acl *racl, *new_racl;
-+ item_list *racl_list;
-+ int ndx;
-+
-+ type = SMB_ACL_TYPE_ACCESS;
-+ racl = sxp->acc_acl;
-+ racl_list = &access_acl_list;
-+ do {
-+ if (!racl) {
-+ racl = new(rsync_acl);
-+ *racl = empty_rsync_acl;
-+ if (type == SMB_ACL_TYPE_ACCESS) {
-+ rsync_acl_fake_perms(racl, sxp->st.st_mode);
-+ sxp->acc_acl = racl;
-+ } else
-+ sxp->def_acl = racl;
-+ }
-+
-+ if ((ndx = find_matching_rsync_acl(racl, type, racl_list)) != -1) {
-+ write_byte(f, type == SMB_ACL_TYPE_ACCESS ? 'a' : 'd');
-+ write_int(f, ndx);
-+ } else {
-+ new_racl = EXPAND_ITEM_LIST(racl_list, rsync_acl, 1000);
-+ write_byte(f, type == SMB_ACL_TYPE_ACCESS ? 'A' : 'D');
-+ old_send_rsync_acl(f, racl);
-+ *new_racl = *racl;
-+ *racl = empty_rsync_acl;
-+ }
-+ racl = sxp->def_acl;
-+ racl_list = &default_acl_list;
-+ } while (BUMP_TYPE(type) && S_ISDIR(sxp->st.st_mode));
-+
-+ free_acl(sxp);
-+}
-+
- /* === Send functions === */
-
- /* Send the ida list over the file descriptor. */
-@@ -649,6 +750,11 @@ static void send_rsync_acl(int f, rsync_acl *racl, SMB_ACL_TYPE_T type,
- * This also frees the ACL data. */
- void send_acl(int f, stat_x *sxp)
- {
-+ if (protocol_version < 30) {
-+ old_send_acl(sxp, f);
-+ return;
-+ }
-+
- if (!sxp->acc_acl) {
- sxp->acc_acl = create_racl();
- rsync_acl_fake_perms(sxp->acc_acl, sxp->st.st_mode);
-@@ -666,6 +772,159 @@ void send_acl(int f, stat_x *sxp)
- }
- }
-
-+/* === OLD Receive functions */
-+
-+static void old_recv_rsync_acl(rsync_acl *racl, int f)
-+{
-+ static item_list temp_ida_list = EMPTY_ITEM_LIST;
-+ SMB_ACL_TAG_T tag_type = 0;
-+ uchar computed_mask_bits = 0;
-+ id_access *ida;
-+ size_t count;
-+
-+ if (!(count = read_int(f)))
-+ return;
-+
-+ while (count--) {
-+ char tag = read_byte(f);
-+ uchar access = read_byte(f);
-+ if (access & ~ (4 | 2 | 1)) {
-+ rprintf(FERROR, "old_recv_rsync_acl: bogus permset %o\n",
-+ access);
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ switch (tag) {
-+ case 'u':
-+ if (racl->user_obj != NO_ENTRY) {
-+ rprintf(FERROR, "old_recv_rsync_acl: error: duplicate USER_OBJ entry\n");
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ racl->user_obj = access;
-+ continue;
-+ case 'U':
-+ tag_type = SMB_ACL_USER;
-+ break;
-+ case 'g':
-+ if (racl->group_obj != NO_ENTRY) {
-+ rprintf(FERROR, "old_recv_rsync_acl: error: duplicate GROUP_OBJ entry\n");
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ racl->group_obj = access;
-+ continue;
-+ case 'G':
-+ tag_type = SMB_ACL_GROUP;
-+ break;
-+ case 'm':
-+ if (racl->mask_obj != NO_ENTRY) {
-+ rprintf(FERROR, "old_recv_rsync_acl: error: duplicate MASK entry\n");
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ racl->mask_obj = access;
-+ continue;
-+ case 'o':
-+ if (racl->other_obj != NO_ENTRY) {
-+ rprintf(FERROR, "old_recv_rsync_acl: error: duplicate OTHER entry\n");
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ racl->other_obj = access;
-+ continue;
-+ default:
-+ rprintf(FERROR, "old_recv_rsync_acl: unknown tag %c\n",
-+ tag);
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ ida = EXPAND_ITEM_LIST(&temp_ida_list, id_access, -10);
-+ ida->access = access | (tag_type == SMB_ACL_USER ? NAME_IS_USER : 0);
-+ ida->id = read_int(f);
-+ computed_mask_bits |= access;
-+ }
-+
-+ /* Transfer the count id_access items out of the temp_ida_list
-+ * into the names ida_entries list in racl. */
-+ if (temp_ida_list.count) {
-+#ifdef SMB_ACL_NEED_SORT
-+ if (temp_ida_list.count > 1) {
-+ qsort(temp_ida_list.items, temp_ida_list.count,
-+ sizeof (id_access), id_access_sorter);
-+ }
-+#endif
-+ racl->names.idas = new_array(id_access, temp_ida_list.count);
-+ memcpy(racl->names.idas, temp_ida_list.items,
-+ temp_ida_list.count * sizeof (id_access));
-+ } else
-+ racl->names.idas = NULL;
-+
-+ racl->names.count = temp_ida_list.count;
-+
-+ /* Truncate the temporary list now that its idas have been saved. */
-+ temp_ida_list.count = 0;
-+
-+ if (!racl->names.count) {
-+ /* If we received a superfluous mask, throw it away. */
-+ if (racl->mask_obj != NO_ENTRY) {
-+ /* Mask off the group perms with it first. */
-+ racl->group_obj &= racl->mask_obj | NO_ENTRY;
-+ racl->mask_obj = NO_ENTRY;
-+ }
-+ } else if (racl->mask_obj == NO_ENTRY) /* Must be non-empty with lists. */
-+ racl->mask_obj = (computed_mask_bits | racl->group_obj) & 7;
-+}
-+
-+/* Receive the ACL info the sender has included for this file-list entry. */
-+void old_recv_acl(struct file_struct *file, int f)
-+{
-+ SMB_ACL_TYPE_T type;
-+ item_list *racl_list;
-+
-+ if (S_ISLNK(file->mode))
-+ return;
-+
-+ type = SMB_ACL_TYPE_ACCESS;
-+ racl_list = &access_acl_list;
-+ do {
-+ char tag = read_byte(f);
-+ int ndx;
-+
-+ if (tag == 'A' || tag == 'a') {
-+ if (type != SMB_ACL_TYPE_ACCESS) {
-+ rprintf(FERROR, "receive_acl %s: duplicate access ACL\n",
-+ f_name(file, NULL));
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ } else if (tag == 'D' || tag == 'd') {
-+ if (type == SMB_ACL_TYPE_ACCESS) {
-+ rprintf(FERROR, "receive_acl %s: expecting access ACL; got default\n",
-+ f_name(file, NULL));
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ } else {
-+ rprintf(FERROR, "receive_acl %s: unknown ACL type tag: %c\n",
-+ f_name(file, NULL), tag);
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ if (tag == 'A' || tag == 'D') {
-+ acl_duo *duo_item;
-+ ndx = racl_list->count;
-+ duo_item = EXPAND_ITEM_LIST(racl_list, acl_duo, 1000);
-+ duo_item->racl = empty_rsync_acl;
-+ old_recv_rsync_acl(&duo_item->racl, f);
-+ duo_item->sacl = NULL;
-+ } else {
-+ ndx = read_int(f);
-+ if (ndx < 0 || (size_t)ndx >= racl_list->count) {
-+ rprintf(FERROR, "receive_acl %s: %s ACL index %d out of range\n",
-+ f_name(file, NULL), str_acl_type(type), ndx);
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ }
-+ if (type == SMB_ACL_TYPE_ACCESS)
-+ F_ACL(file) = ndx;
-+ else
-+ F_DIR_DEFACL(file) = ndx;
-+ racl_list = &default_acl_list;
-+ } while (BUMP_TYPE(type) && S_ISDIR(file->mode));
-+}
-+
- /* === Receive functions === */
-
- static uint32 recv_acl_access(int f, uchar *name_follows_ptr)
-@@ -782,6 +1041,11 @@ static int recv_rsync_acl(int f, item_list *racl_list, SMB_ACL_TYPE_T type, mode
- /* Receive the ACL info the sender has included for this file-list entry. */
- void receive_acl(int f, struct file_struct *file)
- {
-+ if (protocol_version < 30) {
-+ old_recv_acl(file, f);
-+ return;
-+ }
-+
- F_ACL(file) = recv_rsync_acl(f, &access_acl_list, SMB_ACL_TYPE_ACCESS, file->mode);
-
- if (S_ISDIR(file->mode))
-diff --git a/compat.c b/compat.c
---- a/compat.c
-+++ b/compat.c
-@@ -629,6 +629,13 @@ void setup_protocol(int f_out,int f_in)
- protocol_version);
- exit_cleanup(RERR_PROTOCOL);
- }
-+ if (preserve_acls && !local_server) {
-+ rprintf(FERROR,
-+ "--acls requires protocol 30 or higher"
-+ " (negotiated %d).\n",
-+ protocol_version);
-+ exit_cleanup(RERR_PROTOCOL);
-+ }
- if (preserve_xattrs && !local_server) {
- rprintf(FERROR,
- "--xattrs requires protocol 30 or higher"
+++ /dev/null
-To use this patch, run these commands for a successful build:
-
- patch -p1 <patches/adaptec_acl_mods.diff
- ./prepare-source
- ./configure --enable-acl-support
- make
-
-Philip Lowman wrote:
-> Attached is a small patch which allows the preservation of the delete,
-> chmod, and chown bits which Adaptec has added to XFS on their SnapOS NAS
-> units. This is nice for backing up files between different NAS units
-> and preserving all of the Samba ACLs.
->
-> I'm not sure how useful this patch will be because I'm not sure if any
-> other NAS vendors have standardized on their extensions to POSIX ACLs to
-> support Samba in the same manner that Adaptec has. FWIW, though, this
-> will allow you to preserve acls when copying between different Adaptec
-> based NAS units running SnapOS.
-
-I (Wayne) tweaked the patch to work with the latest source.
-
-Todo:
-
-Fix a bug that could lose some bits when stripping some (supposedly)
-superfluous ACL info.
-
-based-on: 194cee671d5e178f20c4494f41911fa8db942935
-diff --git a/lib/sysacls.c b/lib/sysacls.c
---- a/lib/sysacls.c
-+++ b/lib/sysacls.c
-@@ -31,6 +31,18 @@
- #endif
- #define DEBUG(x,y)
-
-+/* These are custom ACL bits used by Adaptec's modifications
-+ * to XFS on their SnapOS units. */
-+#ifndef ACL_DELETE
-+#define ACL_DELETE 8
-+#endif
-+#ifndef ACL_CHMOD
-+#define ACL_CHMOD 16
-+#endif
-+#ifndef ACL_CHOWN
-+#define ACL_CHOWN 32
-+#endif
-+
- void SAFE_FREE(void *mem)
- {
- if (mem)
-@@ -100,6 +112,9 @@ int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *b
- return -1;
-
- *bits_p = (acl_get_perm(permset, ACL_READ) ? 4 : 0)
-+ | (acl_get_perm(permset, ACL_CHOWN) ? 32 : 0)
-+ | (acl_get_perm(permset, ACL_CHMOD) ? 16 : 0)
-+ | (acl_get_perm(permset, ACL_DELETE) ? 8 : 0)
- | (acl_get_perm(permset, ACL_WRITE) ? 2 : 0)
- | (acl_get_perm(permset, ACL_EXECUTE) ? 1 : 0);
-
-@@ -144,6 +159,12 @@ int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits)
- if ((rc = acl_get_permset(entry, &permset)) != 0)
- return rc;
- acl_clear_perms(permset);
-+ if (bits & 32)
-+ acl_add_perm(permset, ACL_CHOWN);
-+ if (bits & 16)
-+ acl_add_perm(permset, ACL_CHMOD);
-+ if (bits & 8)
-+ acl_add_perm(permset, ACL_DELETE);
- if (bits & 4)
- acl_add_perm(permset, ACL_READ);
- if (bits & 2)
-diff --git a/lib/sysacls.h b/lib/sysacls.h
---- a/lib/sysacls.h
-+++ b/lib/sysacls.h
-@@ -59,8 +59,8 @@
- #define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS
- #define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
-
--#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
--#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
-+#define SMB_ACL_VALID_NAME_BITS (32 | 16 | 8 | 4 | 2 | 1)
-+#define SMB_ACL_VALID_OBJ_BITS (32 | 16 | 8 | 4 | 2 | 1)
-
- #define SMB_ACL_NEED_SORT
-
+++ /dev/null
-This patch causes the --cvs-exclude option to prefix the names listed
-in each dir's CVS/Entries file as per-dir includes before the dir's list
-of excludes taken from the .cvsignore file.
-
-To use this patch, run these commands for a successful build:
-
- patch -p1 <patches/cvs-entries.diff
- ./configure (optional if already run)
- make
-
-based-on: 194cee671d5e178f20c4494f41911fa8db942935
-diff --git a/exclude.c b/exclude.c
---- a/exclude.c
-+++ b/exclude.c
-@@ -263,6 +263,8 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
- }
-
- lp = new_array0(filter_rule_list, 1);
-+ if (rule->rflags & FILTRULE_CVS_IGNORE)
-+ cp = "CVS";
- if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0)
- out_of_memory("add_rule");
- rule->u.mergelist = lp;
-@@ -526,6 +528,14 @@ void *push_local_filters(const char *dir, unsigned int dirlen)
- set_filter_dir(dir, dirlen);
- }
-
-+ if (ex->rflags & FILTRULE_CVS_IGNORE
-+ && strlcpy(dirbuf + dirbuf_len, "CVS/Entries",
-+ MAXPATHLEN - dirbuf_len) < MAXPATHLEN - dirbuf_len) {
-+ /* Start by adding include rules for all the names in CVS/Entries. */
-+ parse_filter_file(lp, dirbuf,
-+ rule_template(FILTRULE_NO_PREFIXES | FILTRULE_INCLUDE),
-+ XFLG_CVS_ENTRIES);
-+ }
- if (strlcpy(dirbuf + dirbuf_len, ex->pattern,
- MAXPATHLEN - dirbuf_len) < MAXPATHLEN - dirbuf_len) {
- parse_filter_file(lp, dirbuf, ex,
-@@ -1157,6 +1167,7 @@ void parse_filter_file(filter_rule_list *listp, const char *fname, const filter_
- char line[BIGPATHBUFLEN];
- char *eob = line + sizeof line - 1;
- BOOL word_split = (template->rflags & FILTRULE_WORD_SPLIT) != 0;
-+ int slash_parse = xflags & XFLG_CVS_ENTRIES ? 1 : 0;
-
- if (!fname || !*fname)
- return;
-@@ -1203,6 +1214,24 @@ void parse_filter_file(filter_rule_list *listp, const char *fname, const filter_
- }
- break;
- }
-+ switch (slash_parse) { /* CVS/Entries parsing: */
-+ case 1: /* Ignore starting chars until first slash. */
-+ if (ch == '/')
-+ slash_parse = 2;
-+ continue;
-+ case 2: /* Name ends at 2nd slash on the line. */
-+ if (ch == '/') {
-+ slash_parse = 3;
-+ continue;
-+ }
-+ break;
-+ case 3: /* Ignore trailing chars until EOL. */
-+ if (ch == '\n' || ch == '\r') {
-+ slash_parse = 1;
-+ goto end_the_line;
-+ }
-+ continue;
-+ }
- if (word_split && isspace(ch))
- break;
- if (eol_nulls? !ch : (ch == '\n' || ch == '\r'))
-@@ -1212,13 +1241,14 @@ void parse_filter_file(filter_rule_list *listp, const char *fname, const filter_
- else
- overflow = 1;
- }
-+ end_the_line:
- if (overflow) {
- rprintf(FERROR, "discarding over-long filter: %s...\n", line);
- s = line;
- }
- *s = '\0';
- /* Skip an empty token and (when line parsing) comments. */
-- if (*line && (word_split || (*line != ';' && *line != '#')))
-+ if (*line && (word_split || slash_parse || (*line != ';' && *line != '#')))
- parse_filter_str(listp, line, template, xflags);
- if (ch == EOF)
- break;
-diff --git a/rsync.h b/rsync.h
---- a/rsync.h
-+++ b/rsync.h
-@@ -177,6 +177,7 @@
- #define XFLG_ANCHORED2ABS (1<<2) /* leading slash indicates absolute */
- #define XFLG_ABS_IF_SLASH (1<<3) /* leading or interior slash is absolute */
- #define XFLG_DIR2WILD3 (1<<4) /* dir/ match gets trailing *** added */
-+#define XFLG_CVS_ENTRIES (1<<5)
-
- #define ATTRS_REPORT (1<<0)
- #define ATTRS_SKIP_MTIME (1<<1)
-diff --git a/testsuite/exclude.test b/testsuite/exclude.test
---- a/testsuite/exclude.test
-+++ b/testsuite/exclude.test
-@@ -22,6 +22,7 @@ export CVSIGNORE
-
- makepath "$fromdir/foo/down/to/you"
- makepath "$fromdir/foo/sub"
-+makepath "$fromdir/bar/down/to/CVS"
- makepath "$fromdir/bar/down/to/foo/too"
- makepath "$fromdir/bar/down/to/bar/baz"
- makepath "$fromdir/mid/for/foo/and/that/is/who"
-@@ -60,6 +61,9 @@ echo cvsout >"$fromdir/bar/down/to/foo/file1.bak"
- echo gone >"$fromdir/bar/down/to/foo/file3"
- echo lost >"$fromdir/bar/down/to/foo/file4"
- echo weird >"$fromdir/bar/down/to/foo/+ file3"
-+echo cvsin >"$fromdir/bar/down/to/not.junk"
-+echo cvsout >"$fromdir/bar/down/to/not.good"
-+echo cvsout >"$fromdir/bar/down/to/D"
- echo cvsout-but-filtin >"$fromdir/bar/down/to/foo/file4.junk"
- echo smashed >"$fromdir/bar/down/to/foo/to"
- cat >"$fromdir/bar/down/to/bar/.filt2" <<EOF
-@@ -105,7 +109,18 @@ cat >"$excl" <<EOF
- EOF
-
- cat >"$scratchdir/.cvsignore" <<EOF
--home-cvs-exclude
-+home-cvs-exclude D
-+EOF
-+cat >"$fromdir/bar/down/to/CVS/Entries" <<EOF
-+/not.junk/1.1/Mon Jan 1 11:11:11 2001//
-+filt2
-+/another.file/1.1/Tue Jan 1 22:22:22 2002//
-+invalid lines should just be ignored...
-+D/directory////
-+D
-+EOF
-+cat >"$fromdir/bar/down/to/.cvsignore" <<EOF
-+not.good
- EOF
-
- # Start with a check of --prune-empty-dirs:
-@@ -147,6 +162,10 @@ checkit "$RSYNC -avv --exclude-from='$excl' \
- # Modify the chk dir by removing cvs-ignored files and then tweaking the dir times.
-
- rm "$chkdir"/foo/*.old
-+rm "$chkdir"/bar/down/to/D
-+rm "$chkdir"/bar/down/to/CVS/Entries
-+rmdir "$chkdir"/bar/down/to/CVS
-+rm "$chkdir"/bar/down/to/not.good
- rm "$chkdir"/bar/down/to/foo/*.bak
- rm "$chkdir"/bar/down/to/foo/*.junk
- rm "$chkdir"/bar/down/to/home-cvs-exclude
-@@ -162,8 +181,12 @@ checkit "$RSYNC -avvC --filter='merge $excl' --delete-excluded \
-
- # Modify the chk dir for our merge-exclude test and then tweak the dir times.
-
-+makepath "$chkdir/bar/down/to/CVS"
- rm "$chkdir"/foo/file1
- rm "$chkdir"/bar/down/to/bar/baz/*.deep
-+cp_touch "$fromdir"/bar/down/to/D "$chkdir"/bar/down/to/D
-+cp_touch "$fromdir"/bar/down/to/not.good "$chkdir"/bar/down/to/not.good
-+cp_touch "$fromdir"/bar/down/to/CVS/Entries "$chkdir"/bar/down/to/CVS/Entries
- cp_touch "$fromdir"/bar/down/to/foo/*.junk "$chkdir"/bar/down/to/foo
- cp_touch "$fromdir"/bar/down/to/foo/to "$chkdir"/bar/down/to/foo
-
+++ /dev/null
-This is an adapted version of the original by Zoong Pham.
-
-To use this patch, run these commands for a successful build:
-
- patch -p1 <patches/tru64.diff
- ./configure (optional if already run)
- make
-
-based-on: 194cee671d5e178f20c4494f41911fa8db942935
-diff --git a/syscall.c b/syscall.c
---- a/syscall.c
-+++ b/syscall.c
-@@ -23,6 +23,7 @@
- #include "rsync.h"
-
- #if !defined MKNOD_CREATES_SOCKETS && defined HAVE_SYS_UN_H
-+#define _SOCKADDR_LEN
- #include <sys/un.h>
- #endif
- #ifdef HAVE_SYS_ATTR_H
+++ /dev/null
-This patch adds backward-compatibility support for the --xattrs option.
-Since the main release has never had xattr support, the trunk doesn't
-need this code. If you want to make rsync 3.0.x communicate with an
-older (patched) release, use this.
-
-To use this patch, run these commands for a successful build:
-
- patch -p1 <patches/acls.diff
- patch -p1 <patches/xattrs.diff
- ./configure (optional if already run)
- make
-
-based-on: patch/master/acls
-diff --git a/compat.c b/compat.c
---- a/compat.c
-+++ b/compat.c
-@@ -636,13 +636,6 @@ void setup_protocol(int f_out,int f_in)
- protocol_version);
- exit_cleanup(RERR_PROTOCOL);
- }
-- if (preserve_xattrs && !local_server) {
-- rprintf(FERROR,
-- "--xattrs requires protocol 30 or higher"
-- " (negotiated %d).\n",
-- protocol_version);
-- exit_cleanup(RERR_PROTOCOL);
-- }
- }
-
- if (delete_mode && !(delete_before+delete_during+delete_after)) {
-diff --git a/xattrs.c b/xattrs.c
---- a/xattrs.c
-+++ b/xattrs.c
-@@ -22,6 +22,7 @@
- #include "rsync.h"
- #include "ifuncs.h"
- #include "inums.h"
-+#include "io.h"
- #include "lib/sysxattrs.h"
-
- #ifdef SUPPORT_XATTRS
-@@ -38,6 +39,7 @@ extern int preserve_devices;
- extern int preserve_specials;
- extern int checksum_seed;
- extern int saw_xattr_filter;
-+extern int protocol_version;
-
- #define RSYNC_XAL_INITIAL 5
- #define RSYNC_XAL_LIST_INITIAL 100
-@@ -267,7 +269,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
- if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
- return -1;
-
-- if (datum_len > MAX_FULL_DATUM) {
-+ if (datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
- /* For large datums, we store a flag and a checksum. */
- name_offset = 1 + MAX_DIGEST_LEN;
- sum_init(-1, checksum_seed);
-@@ -432,7 +434,7 @@ static int find_matching_xattr(const item_list *xalp)
- || rxas1[j].datum_len != rxas2[j].datum_len
- || strcmp(rxas1[j].name, rxas2[j].name))
- break;
-- if (rxas1[j].datum_len > MAX_FULL_DATUM) {
-+ if (rxas1[j].datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
- if (memcmp(rxas1[j].datum + 1,
- rxas2[j].datum + 1,
- MAX_DIGEST_LEN) != 0)
-@@ -500,13 +502,22 @@ int send_xattr(int f, stat_x *sxp)
- {
- int ndx = find_matching_xattr(sxp->xattr);
-
-- /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
-- write_varint(f, ndx + 1);
-+ if (protocol_version < 30) {
-+ if (ndx < 0)
-+ write_byte(f, 'X');
-+ else {
-+ write_byte(f, 'x');
-+ write_int(f, ndx);
-+ }
-+ } else {
-+ /* Send 0 (-1 + 1) to indicate that literal xattr data follows. */
-+ write_varint(f, ndx + 1);
-+ }
-
- if (ndx < 0) {
- rsync_xa *rxa;
- int count = sxp->xattr->count;
-- write_varint(f, count);
-+ write_varint30(f, count);
- for (rxa = sxp->xattr->items; count--; rxa++) {
- size_t name_len = rxa->name_len;
- const char *name = rxa->name;
-@@ -525,8 +536,8 @@ int send_xattr(int f, stat_x *sxp)
- name_len += UPRE_LEN;
- }
- #endif
-- write_varint(f, name_len);
-- write_varint(f, rxa->datum_len);
-+ write_varint30(f, name_len);
-+ write_varint30(f, rxa->datum_len);
- #ifndef HAVE_LINUX_XATTRS
- if (name_len > rxa->name_len) {
- write_buf(f, USER_PREFIX, UPRE_LEN);
-@@ -534,7 +545,7 @@ int send_xattr(int f, stat_x *sxp)
- }
- #endif
- write_buf(f, name, name_len);
-- if (rxa->datum_len > MAX_FULL_DATUM)
-+ if (rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30)
- write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
- else
- write_bigbuf(f, rxa->datum, rxa->datum_len);
-@@ -585,7 +596,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
- cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
- if (cmp > 0)
- same = 0;
-- else if (snd_rxa->datum_len > MAX_FULL_DATUM) {
-+ else if (snd_rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30) {
- same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
- && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
- MAX_DIGEST_LEN) == 0;
-@@ -631,6 +642,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
- int cnt, prior_req = 0;
- rsync_xa *rxa;
-
-+ if (protocol_version < 30)
-+ return;
-+
- glst += F_XATTR(file);
- lst = &glst->xa_items;
-
-@@ -690,6 +704,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
- rsync_xa *rxa;
- int rel_pos, cnt, num, got_xattr_data = 0;
-
-+ if (protocol_version < 30)
-+ return 0;
-+
- if (F_XATTR(file) < 0) {
- rprintf(FERROR, "recv_xattr_request: internal data error!\n");
- exit_cleanup(RERR_PROTOCOL);
-@@ -774,7 +791,22 @@ void receive_xattr(int f, struct file_struct *file)
- #else
- int need_sort = 1;
- #endif
-- int ndx = read_varint(f);
-+ int ndx;
-+
-+ if (protocol_version >= 30)
-+ ndx = read_varint(f);
-+ else {
-+ int tag = read_byte(f);
-+ if (tag == 'x')
-+ ndx = read_int(f) + 1;
-+ else if (tag == 'X')
-+ ndx = 0;
-+ else {
-+ rprintf(FERROR, "receive_xattr: unknown extended attribute"
-+ " type tag (%02x) for %s\n", tag, f_name(file, NULL));
-+ exit_cleanup(RERR_STREAMIO);
-+ }
-+ }
-
- if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
- rprintf(FERROR, "receive_xattr: xa index %d out of"
-@@ -787,7 +819,7 @@ void receive_xattr(int f, struct file_struct *file)
- return;
- }
-
-- if ((count = read_varint(f)) != 0) {
-+ if ((count = read_varint30(f)) != 0) {
- (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
- temp_xattr.count = 0;
- }
-@@ -795,9 +827,10 @@ void receive_xattr(int f, struct file_struct *file)
- for (num = 1; num <= count; num++) {
- char *ptr, *name;
- rsync_xa *rxa;
-- size_t name_len = read_varint(f);
-- size_t datum_len = read_varint(f);
-- size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
-+ size_t name_len = read_varint30(f);
-+ size_t datum_len = read_varint30(f);
-+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
-+ ? 1 + MAX_DIGEST_LEN : datum_len;
- size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
- if ((dget_len + extra_len < dget_len)
- || (dget_len + extra_len + name_len < dget_len + extra_len))