|
|
5ae4d2 |
diff -up rsync-3.1.2/exclude.c.orig rsync-3.1.2/exclude.c
|
|
|
5ae4d2 |
--- rsync-3.1.2/exclude.c.orig 2018-09-27 17:06:15.413701320 -0300
|
|
|
5ae4d2 |
+++ rsync-3.1.2/exclude.c 2018-09-27 17:06:19.259579122 -0300
|
|
|
5ae4d2 |
@@ -44,6 +44,8 @@ filter_rule_list filter_list = { .debug_
|
|
|
5ae4d2 |
filter_rule_list cvs_filter_list = { .debug_type = " [global CVS]" };
|
|
|
5ae4d2 |
filter_rule_list daemon_filter_list = { .debug_type = " [daemon]" };
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
+int saw_xattr_filter = 0;
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
/* Need room enough for ":MODS " prefix plus some room to grow. */
|
|
|
5ae4d2 |
#define MAX_RULE_PREFIX (16)
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
@@ -622,7 +624,7 @@ void change_local_filter_dir(const char
|
|
|
5ae4d2 |
filt_array[cur_depth] = push_local_filters(dname, dlen);
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
-static int rule_matches(const char *fname, filter_rule *ex, int name_is_dir)
|
|
|
5ae4d2 |
+static int rule_matches(const char *fname, filter_rule *ex, int name_flags)
|
|
|
5ae4d2 |
{
|
|
|
5ae4d2 |
int slash_handling, str_cnt = 0, anchored_match = 0;
|
|
|
5ae4d2 |
int ret_match = ex->rflags & FILTRULE_NEGATE ? 0 : 1;
|
|
|
5ae4d2 |
@@ -633,6 +635,9 @@ static int rule_matches(const char *fnam
|
|
|
5ae4d2 |
if (!*name)
|
|
|
5ae4d2 |
return 0;
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
+ if (!(name_flags & NAME_IS_XATTR) ^ !(ex->rflags & FILTRULE_XATTR))
|
|
|
5ae4d2 |
+ return 0;
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
if (!ex->u.slash_cnt && !(ex->rflags & FILTRULE_WILD2)) {
|
|
|
5ae4d2 |
/* If the pattern does not have any slashes AND it does
|
|
|
5ae4d2 |
* not have a "**" (which could match a slash), then we
|
|
|
5ae4d2 |
@@ -650,7 +655,7 @@ static int rule_matches(const char *fnam
|
|
|
5ae4d2 |
strings[str_cnt++] = "/";
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
strings[str_cnt++] = name;
|
|
|
5ae4d2 |
- if (name_is_dir) {
|
|
|
5ae4d2 |
+ if (name_flags & NAME_IS_DIR) {
|
|
|
5ae4d2 |
/* Allow a trailing "/"+"***" to match the directory. */
|
|
|
5ae4d2 |
if (ex->rflags & FILTRULE_WILD3_SUFFIX)
|
|
|
5ae4d2 |
strings[str_cnt++] = "/";
|
|
|
5ae4d2 |
@@ -702,7 +707,7 @@ static int rule_matches(const char *fnam
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
static void report_filter_result(enum logcode code, char const *name,
|
|
|
5ae4d2 |
filter_rule const *ent,
|
|
|
5ae4d2 |
- int name_is_dir, const char *type)
|
|
|
5ae4d2 |
+ int name_flags, const char *type)
|
|
|
5ae4d2 |
{
|
|
|
5ae4d2 |
/* If a trailing slash is present to match only directories,
|
|
|
5ae4d2 |
* then it is stripped out by add_rule(). So as a special
|
|
|
5ae4d2 |
@@ -712,17 +717,40 @@ static void report_filter_result(enum lo
|
|
|
5ae4d2 |
static char *actions[2][2]
|
|
|
5ae4d2 |
= { {"show", "hid"}, {"risk", "protect"} };
|
|
|
5ae4d2 |
const char *w = who_am_i();
|
|
|
5ae4d2 |
+ const char *t = name_flags & NAME_IS_XATTR ? "xattr"
|
|
|
5ae4d2 |
+ : name_flags & NAME_IS_DIR ? "directory"
|
|
|
5ae4d2 |
+ : "file";
|
|
|
5ae4d2 |
rprintf(code, "[%s] %sing %s %s because of pattern %s%s%s\n",
|
|
|
5ae4d2 |
w, actions[*w!='s'][!(ent->rflags & FILTRULE_INCLUDE)],
|
|
|
5ae4d2 |
- name_is_dir ? "directory" : "file", name, ent->pattern,
|
|
|
5ae4d2 |
+ t, name, ent->pattern,
|
|
|
5ae4d2 |
ent->rflags & FILTRULE_DIRECTORY ? "/" : "", type);
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
+/* This function is used to check if a file should be included/excluded
|
|
|
5ae4d2 |
+ * from the list of files based on its name and type etc. The value of
|
|
|
5ae4d2 |
+ * filter_level is set to either SERVER_FILTERS or ALL_FILTERS. */
|
|
|
5ae4d2 |
+int name_is_excluded(const char *fname, int name_flags, int filter_level)
|
|
|
5ae4d2 |
+{
|
|
|
5ae4d2 |
+ if (daemon_filter_list.head && check_filter(&daemon_filter_list, FLOG, fname, name_flags) < 0) {
|
|
|
5ae4d2 |
+ if (!(name_flags & NAME_IS_XATTR))
|
|
|
5ae4d2 |
+ errno = ENOENT;
|
|
|
5ae4d2 |
+ return 1;
|
|
|
5ae4d2 |
+ }
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+ if (filter_level != ALL_FILTERS)
|
|
|
5ae4d2 |
+ return 0;
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+ if (filter_list.head && check_filter(&filter_list, FINFO, fname, name_flags) < 0)
|
|
|
5ae4d2 |
+ return 1;
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+ return 0;
|
|
|
5ae4d2 |
+}
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
/* Return -1 if file "name" is defined to be excluded by the specified
|
|
|
5ae4d2 |
* exclude list, 1 if it is included, and 0 if it was not matched. */
|
|
|
5ae4d2 |
int check_filter(filter_rule_list *listp, enum logcode code,
|
|
|
5ae4d2 |
- const char *name, int name_is_dir)
|
|
|
5ae4d2 |
+ const char *name, int name_flags)
|
|
|
5ae4d2 |
{
|
|
|
5ae4d2 |
filter_rule *ent;
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
@@ -730,22 +758,19 @@ int check_filter(filter_rule_list *listp
|
|
|
5ae4d2 |
if (ignore_perishable && ent->rflags & FILTRULE_PERISHABLE)
|
|
|
5ae4d2 |
continue;
|
|
|
5ae4d2 |
if (ent->rflags & FILTRULE_PERDIR_MERGE) {
|
|
|
5ae4d2 |
- int rc = check_filter(ent->u.mergelist, code, name,
|
|
|
5ae4d2 |
- name_is_dir);
|
|
|
5ae4d2 |
+ int rc = check_filter(ent->u.mergelist, code, name, name_flags);
|
|
|
5ae4d2 |
if (rc)
|
|
|
5ae4d2 |
return rc;
|
|
|
5ae4d2 |
continue;
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
if (ent->rflags & FILTRULE_CVS_IGNORE) {
|
|
|
5ae4d2 |
- int rc = check_filter(&cvs_filter_list, code, name,
|
|
|
5ae4d2 |
- name_is_dir);
|
|
|
5ae4d2 |
+ int rc = check_filter(&cvs_filter_list, code, name, name_flags);
|
|
|
5ae4d2 |
if (rc)
|
|
|
5ae4d2 |
return rc;
|
|
|
5ae4d2 |
continue;
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
- if (rule_matches(name, ent, name_is_dir)) {
|
|
|
5ae4d2 |
- report_filter_result(code, name, ent, name_is_dir,
|
|
|
5ae4d2 |
- listp->debug_type);
|
|
|
5ae4d2 |
+ if (rule_matches(name, ent, name_flags)) {
|
|
|
5ae4d2 |
+ report_filter_result(code, name, ent, name_flags, listp->debug_type);
|
|
|
5ae4d2 |
return ent->rflags & FILTRULE_INCLUDE ? 1 : -1;
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
@@ -970,6 +995,10 @@ static filter_rule *parse_rule_tok(const
|
|
|
5ae4d2 |
goto invalid;
|
|
|
5ae4d2 |
rule->rflags |= FILTRULE_WORD_SPLIT;
|
|
|
5ae4d2 |
break;
|
|
|
5ae4d2 |
+ case 'x':
|
|
|
5ae4d2 |
+ rule->rflags |= FILTRULE_XATTR;
|
|
|
5ae4d2 |
+ saw_xattr_filter = 1;
|
|
|
5ae4d2 |
+ break;
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
if (*s)
|
|
|
5ae4d2 |
@@ -1286,6 +1286,8 @@ char *get_rule_prefix(filter_rule *rule, const char *pat, int for_xfer,
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
if (rule->rflags & FILTRULE_EXCLUDE_SELF)
|
|
|
5ae4d2 |
*op++ = 'e';
|
|
|
5ae4d2 |
+ if (rule->rflags & FILTRULE_XATTR)
|
|
|
5ae4d2 |
+ *op++ = 'x';
|
|
|
5ae4d2 |
if (rule->rflags & FILTRULE_SENDER_SIDE
|
|
|
5ae4d2 |
&& (!for_xfer || protocol_version >= 29))
|
|
|
5ae4d2 |
*op++ = 's';
|
|
|
5ae4d2 |
diff -up rsync-3.1.2/flist.c.orig rsync-3.1.2/flist.c
|
|
|
5ae4d2 |
--- rsync-3.1.2/flist.c.orig 2018-09-27 17:06:15.420701098 -0300
|
|
|
5ae4d2 |
+++ rsync-3.1.2/flist.c 2018-09-27 17:06:19.262579026 -0300
|
|
|
5ae4d2 |
@@ -237,16 +237,6 @@ int link_stat(const char *path, STRUCT_S
|
|
|
5ae4d2 |
#endif
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
-static inline int is_daemon_excluded(const char *fname, int is_dir)
|
|
|
5ae4d2 |
-{
|
|
|
5ae4d2 |
- if (daemon_filter_list.head
|
|
|
5ae4d2 |
- && check_filter(&daemon_filter_list, FLOG, fname, is_dir) < 0) {
|
|
|
5ae4d2 |
- errno = ENOENT;
|
|
|
5ae4d2 |
- return 1;
|
|
|
5ae4d2 |
- }
|
|
|
5ae4d2 |
- return 0;
|
|
|
5ae4d2 |
-}
|
|
|
5ae4d2 |
-
|
|
|
5ae4d2 |
static inline int path_is_daemon_excluded(char *path, int ignore_filename)
|
|
|
5ae4d2 |
{
|
|
|
5ae4d2 |
if (daemon_filter_list.head) {
|
|
|
5ae4d2 |
@@ -273,23 +263,10 @@ static inline int path_is_daemon_exclude
|
|
|
5ae4d2 |
return 0;
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
-/* This function is used to check if a file should be included/excluded
|
|
|
5ae4d2 |
- * from the list of files based on its name and type etc. The value of
|
|
|
5ae4d2 |
- * filter_level is set to either SERVER_FILTERS or ALL_FILTERS. */
|
|
|
5ae4d2 |
-static int is_excluded(const char *fname, int is_dir, int filter_level)
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+static inline int is_excluded(const char *fname, int is_dir, int filter_level)
|
|
|
5ae4d2 |
{
|
|
|
5ae4d2 |
-#if 0 /* This currently never happens, so avoid a useless compare. */
|
|
|
5ae4d2 |
- if (filter_level == NO_FILTERS)
|
|
|
5ae4d2 |
- return 0;
|
|
|
5ae4d2 |
-#endif
|
|
|
5ae4d2 |
- if (is_daemon_excluded(fname, is_dir))
|
|
|
5ae4d2 |
- return 1;
|
|
|
5ae4d2 |
- if (filter_level != ALL_FILTERS)
|
|
|
5ae4d2 |
- return 0;
|
|
|
5ae4d2 |
- if (filter_list.head
|
|
|
5ae4d2 |
- && check_filter(&filter_list, FINFO, fname, is_dir) < 0)
|
|
|
5ae4d2 |
- return 1;
|
|
|
5ae4d2 |
- return 0;
|
|
|
5ae4d2 |
+ return name_is_excluded(fname, is_dir ? NAME_IS_DIR : NAME_IS_FILE, filter_level);
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
static void send_directory(int f, struct file_list *flist,
|
|
|
5ae4d2 |
@@ -2262,7 +2239,7 @@ struct file_list *send_file_list(int f,
|
|
|
5ae4d2 |
memmove(fbuf, fn, len + 1);
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0
|
|
|
5ae4d2 |
- || (name_type != DOTDIR_NAME && is_daemon_excluded(fbuf, S_ISDIR(st.st_mode)))
|
|
|
5ae4d2 |
+ || (name_type != DOTDIR_NAME && is_excluded(fbuf, S_ISDIR(st.st_mode) != 0, SERVER_FILTERS))
|
|
|
5ae4d2 |
|| (relative_paths && path_is_daemon_excluded(fbuf, 1))) {
|
|
|
5ae4d2 |
if (errno != ENOENT || missing_args == 0) {
|
|
|
5ae4d2 |
/* This is a transfer error, but inhibit deletion
|
|
|
5ae4d2 |
diff -up rsync-3.1.2/rsync.h.orig rsync-3.1.2/rsync.h
|
|
|
5ae4d2 |
--- rsync-3.1.2/rsync.h.orig 2018-09-27 17:06:15.426700907 -0300
|
|
|
5ae4d2 |
+++ rsync-3.1.2/rsync.h 2018-09-27 17:06:19.263578995 -0300
|
|
|
5ae4d2 |
@@ -856,6 +856,10 @@ struct map_struct {
|
|
|
5ae4d2 |
int status; /* first errno from read errors */
|
|
|
5ae4d2 |
};
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
+#define NAME_IS_FILE (0) /* filter name as a file */
|
|
|
5ae4d2 |
+#define NAME_IS_DIR (1<<0) /* filter name as a dir */
|
|
|
5ae4d2 |
+#define NAME_IS_XATTR (1<<2) /* filter name as an xattr */
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
#define FILTRULE_WILD (1<<0) /* pattern has '*', '[', and/or '?' */
|
|
|
5ae4d2 |
#define FILTRULE_WILD2 (1<<1) /* pattern has '**' */
|
|
|
5ae4d2 |
#define FILTRULE_WILD2_PREFIX (1<<2) /* pattern starts with "**" */
|
|
|
5ae4d2 |
@@ -876,6 +880,7 @@ struct map_struct {
|
|
|
5ae4d2 |
#define FILTRULE_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */
|
|
|
5ae4d2 |
#define FILTRULE_CLEAR_LIST (1<<18)/* this item is the "!" token */
|
|
|
5ae4d2 |
#define FILTRULE_PERISHABLE (1<<19)/* perishable if parent dir goes away */
|
|
|
5ae4d2 |
+#define FILTRULE_XATTR (1<<20)/* rule only applies to xattr names */
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
#define FILTRULES_SIDES (FILTRULE_SENDER_SIDE | FILTRULE_RECEIVER_SIDE)
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
diff -up rsync-3.1.2/rsync.yo.orig rsync-3.1.2/rsync.yo
|
|
|
5ae4d2 |
--- rsync-3.1.2/rsync.yo.orig 2018-09-27 17:06:15.433700685 -0300
|
|
|
5ae4d2 |
+++ rsync-3.1.2/rsync.yo 2018-09-27 17:06:19.266578899 -0300
|
|
|
5ae4d2 |
@@ -1109,9 +1109,27 @@ super-user copies all namespaces except
|
|
|
5ae4d2 |
the user.* namespace. To be able to backup and restore non-user namespaces as
|
|
|
5ae4d2 |
a normal user, see the bf(--fake-super) option.
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
-Note that this option does not copy rsyncs special xattr values (e.g. those
|
|
|
5ae4d2 |
-used by bf(--fake-super)) unless you repeat the option (e.g. -XX). This
|
|
|
5ae4d2 |
-"copy all xattrs" mode cannot be used with bf(--fake-super).
|
|
|
5ae4d2 |
+The above name filtering can be overridden by using one or more filter options
|
|
|
5ae4d2 |
+with the bf(x) modifier. When you specify an xattr-affecting filter rule, rsync
|
|
|
5ae4d2 |
+requires that you do your own system/user filtering, as well as any additional
|
|
|
5ae4d2 |
+filtering for what xattr names are copied and what names are allowed to be
|
|
|
5ae4d2 |
+deleted. For example, to skip the system namespace, you could specify:
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+quote(--filter='-x system.*')
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+To skip all namespaces except the user namespace, you could specify a
|
|
|
5ae4d2 |
+negated-user match:
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+quote(--filter='-x! user.*')
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+To prevent any attributes from being deleted, you could specify a receiver-only
|
|
|
5ae4d2 |
+rule that excludes all names:
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+quote(--filter='-xr *')
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+Note that the bf(-X) option does not copy rsync's special xattr values (e.g.
|
|
|
5ae4d2 |
+those used by bf(--fake-super)) unless you repeat the option (e.g. -XX).
|
|
|
5ae4d2 |
+This "copy all xattrs" mode cannot be used with bf(--fake-super).
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
dit(bf(--chmod)) This option tells rsync to apply one or more
|
|
|
5ae4d2 |
comma-separated "chmod" modes to the permission of the files in the
|
|
|
5ae4d2 |
@@ -2890,6 +2908,10 @@ itemization(
|
|
|
5ae4d2 |
option's default rules that exclude things like "CVS" and "*.o" are
|
|
|
5ae4d2 |
marked as perishable, and will not prevent a directory that was removed
|
|
|
5ae4d2 |
on the source from being deleted on the destination.
|
|
|
5ae4d2 |
+ it() An bf(x) indicates that a rule affects xattr names in xattr copy/delete
|
|
|
5ae4d2 |
+ operations (and is thus ignored when matching file/dir names). If no
|
|
|
5ae4d2 |
+ xattr-matching rules are specified, a default xattr filtering rule is
|
|
|
5ae4d2 |
+ used (see the bf(--xattrs) option).
|
|
|
5ae4d2 |
)
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
manpagesection(MERGE-FILE FILTER RULES)
|
|
|
5ae4d2 |
diff -up rsync-3.1.2/testsuite/xattrs.test.orig rsync-3.1.2/testsuite/xattrs.test
|
|
|
5ae4d2 |
--- rsync-3.1.2/testsuite/xattrs.test.orig 2018-09-27 17:06:15.439700494 -0300
|
|
|
5ae4d2 |
+++ rsync-3.1.2/testsuite/xattrs.test 2018-09-27 17:06:19.267578867 -0300
|
|
|
5ae4d2 |
@@ -127,8 +127,10 @@ esac
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
xls $dirs $files >"$scratchdir/xattrs.txt"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
+XFILT='-f-x_system.* -f-x_security.*'
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
# OK, let's try a simple xattr copy.
|
|
|
5ae4d2 |
-checkit "$RSYNC -avX $dashH --super . '$chkdir/'" "$fromdir" "$chkdir"
|
|
|
5ae4d2 |
+checkit "$RSYNC -avX $XFILT $dashH --super . '$chkdir/'" "$fromdir" "$chkdir"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
cd "$chkdir"
|
|
|
5ae4d2 |
xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" -
|
|
|
5ae4d2 |
@@ -142,7 +144,7 @@ if [ "$dashH" ]; then
|
|
|
5ae4d2 |
done
|
|
|
5ae4d2 |
fi
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
-checkit "$RSYNC -aiX $dashH --super $altDest=../chk . ../to" "$fromdir" "$todir"
|
|
|
5ae4d2 |
+checkit "$RSYNC -aiX $XFILT $dashH --super $altDest=../chk . ../to" "$fromdir" "$todir"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
cd "$todir"
|
|
|
5ae4d2 |
xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" -
|
|
|
5ae4d2 |
@@ -156,7 +158,7 @@ xset user.nice 'this is nice, but differ
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
xls $dirs $files >"$scratchdir/xattrs.txt"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
-checkit "$RSYNC -aiX $dashH --fake-super --link-dest=../chk . ../to" "$chkdir" "$todir"
|
|
|
5ae4d2 |
+checkit "$RSYNC -aiX $XFILT $dashH --fake-super --link-dest=../chk . ../to" "$chkdir" "$todir"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
cd "$todir"
|
|
|
5ae4d2 |
xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" -
|
|
|
5ae4d2 |
@@ -186,7 +188,7 @@ cd "$fromdir"
|
|
|
5ae4d2 |
rm -rf "$todir"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
# When run by a non-root tester, this checks if no-user-perm files/dirs can be copied.
|
|
|
5ae4d2 |
-checkit "$RSYNC -aiX $dashH --fake-super --chmod=a= . ../to" "$chkdir" "$todir" # 2>"$scratchdir/errors.txt"
|
|
|
5ae4d2 |
+checkit "$RSYNC -aiX $XFILT $dashH --fake-super --chmod=a= . ../to" "$chkdir" "$todir" # 2>"$scratchdir/errors.txt"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
cd "$todir"
|
|
|
5ae4d2 |
xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" -
|
|
|
5ae4d2 |
@@ -202,7 +204,7 @@ $RSYNC -aX file1 ../lnk/
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
xls file1 file2 >"$scratchdir/xattrs.txt"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
-checkit "$RSYNC -aiiX $dashH $altDest=../lnk . ../to" "$chkdir" "$todir"
|
|
|
5ae4d2 |
+checkit "$RSYNC -aiiX $XFILT $dashH $altDest=../lnk . ../to" "$chkdir" "$todir"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
[ "$dashH" ] && rm ../lnk/extra-link
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
@@ -215,7 +217,7 @@ rm "$todir/file2"
|
|
|
5ae4d2 |
echo extra >file1
|
|
|
5ae4d2 |
$RSYNC -aX . ../chk/
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
-checkit "$RSYNC -aiiX . ../to" "$chkdir" "$todir"
|
|
|
5ae4d2 |
+checkit "$RSYNC -aiiX $XFILT . ../to" "$chkdir" "$todir"
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
cd "$todir"
|
|
|
5ae4d2 |
xls file1 file2 | diff $diffopt "$scratchdir/xattrs.txt" -
|
|
|
5ae4d2 |
diff -up rsync-3.1.2/xattrs.c.orig rsync-3.1.2/xattrs.c
|
|
|
5ae4d2 |
--- rsync-3.1.2/xattrs.c.orig 2018-09-27 17:06:15.442700399 -0300
|
|
|
5ae4d2 |
+++ rsync-3.1.2/xattrs.c 2018-09-27 17:07:50.900667319 -0300
|
|
|
5ae4d2 |
@@ -39,6 +39,7 @@ extern int preserve_devices;
|
|
|
5ae4d2 |
extern int preserve_specials;
|
|
|
5ae4d2 |
extern int checksum_seed;
|
|
|
5ae4d2 |
extern int protocol_version;
|
|
|
5ae4d2 |
+extern int saw_xattr_filter;
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
#define RSYNC_XAL_INITIAL 5
|
|
|
5ae4d2 |
#define RSYNC_XAL_LIST_INITIAL 100
|
|
|
5ae4d2 |
@@ -234,11 +235,14 @@ static int rsync_xal_get(const char *fna
|
|
|
5ae4d2 |
name_len = strlen(name) + 1;
|
|
|
5ae4d2 |
list_len -= name_len;
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
+ if (saw_xattr_filter) {
|
|
|
5ae4d2 |
+ if (name_is_excluded(name, NAME_IS_XATTR, ALL_FILTERS))
|
|
|
5ae4d2 |
+ continue;
|
|
|
5ae4d2 |
+ }
|
|
|
5ae4d2 |
#ifdef HAVE_LINUX_XATTRS
|
|
|
5ae4d2 |
/* We always ignore the system namespace, and non-root
|
|
|
5ae4d2 |
* ignores everything but the user namespace. */
|
|
|
5ae4d2 |
- if (user_only ? !HAS_PREFIX(name, USER_PREFIX)
|
|
|
5ae4d2 |
- : HAS_PREFIX(name, SYSTEM_PREFIX))
|
|
|
5ae4d2 |
+ else if (user_only ? !HAS_PREFIX(name, USER_PREFIX) : HAS_PREFIX(name, SYSTEM_PREFIX))
|
|
|
5ae4d2 |
continue;
|
|
|
5ae4d2 |
#endif
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
@@ -337,11 +341,14 @@ int copy_xattrs(const char *source, cons
|
|
|
5ae4d2 |
name_len = strlen(name) + 1;
|
|
|
5ae4d2 |
list_len -= name_len;
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
+ if (saw_xattr_filter) {
|
|
|
5ae4d2 |
+ if (name_is_excluded(name, NAME_IS_XATTR, ALL_FILTERS))
|
|
|
5ae4d2 |
+ continue;
|
|
|
5ae4d2 |
+ }
|
|
|
5ae4d2 |
#ifdef HAVE_LINUX_XATTRS
|
|
|
5ae4d2 |
/* We always ignore the system namespace, and non-root
|
|
|
5ae4d2 |
* ignores everything but the user namespace. */
|
|
|
5ae4d2 |
- if (user_only ? !HAS_PREFIX(name, USER_PREFIX)
|
|
|
5ae4d2 |
- : HAS_PREFIX(name, SYSTEM_PREFIX))
|
|
|
5ae4d2 |
+ else if (user_only ? !HAS_PREFIX(name, USER_PREFIX) : HAS_PREFIX(name, SYSTEM_PREFIX))
|
|
|
5ae4d2 |
continue;
|
|
|
5ae4d2 |
#endif
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
@@ -735,10 +742,17 @@ void receive_xattr(int f, struct file_st
|
|
|
5ae4d2 |
*ptr = XSTATE_ABBREV;
|
|
|
5ae4d2 |
read_buf(f, ptr + 1, MAX_DIGEST_LEN);
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
+
|
|
|
5ae4d2 |
+ if (saw_xattr_filter) {
|
|
|
5ae4d2 |
+ if (name_is_excluded(name, NAME_IS_XATTR, ALL_FILTERS)) {
|
|
|
5ae4d2 |
+ free(ptr);
|
|
|
5ae4d2 |
+ continue;
|
|
|
5ae4d2 |
+ }
|
|
|
5ae4d2 |
+ }
|
|
|
5ae4d2 |
#ifdef HAVE_LINUX_XATTRS
|
|
|
5ae4d2 |
/* Non-root can only save the user namespace. */
|
|
|
5ae4d2 |
if (am_root <= 0 && !HAS_PREFIX(name, USER_PREFIX)) {
|
|
|
5ae4d2 |
- if (!am_root) {
|
|
|
5ae4d2 |
+ if (!am_root && !saw_xattr_filter) {
|
|
|
5ae4d2 |
free(ptr);
|
|
|
5ae4d2 |
continue;
|
|
|
5ae4d2 |
}
|
|
|
5ae4d2 |
@@ -899,11 +913,14 @@ static int rsync_xal_set(const char *fna
|
|
|
5ae4d2 |
name_len = strlen(name) + 1;
|
|
|
5ae4d2 |
list_len -= name_len;
|
|
|
5ae4d2 |
|
|
|
5ae4d2 |
+ if (saw_xattr_filter) {
|
|
|
5ae4d2 |
+ if (name_is_excluded(name, NAME_IS_XATTR, ALL_FILTERS))
|
|
|
5ae4d2 |
+ continue;
|
|
|
5ae4d2 |
+ }
|
|
|
5ae4d2 |
#ifdef HAVE_LINUX_XATTRS
|
|
|
5ae4d2 |
/* We always ignore the system namespace, and non-root
|
|
|
5ae4d2 |
* ignores everything but the user namespace. */
|
|
|
5ae4d2 |
- if (user_only ? !HAS_PREFIX(name, USER_PREFIX)
|
|
|
5ae4d2 |
- : HAS_PREFIX(name, SYSTEM_PREFIX))
|
|
|
5ae4d2 |
+ else if (user_only ? !HAS_PREFIX(name, USER_PREFIX) : HAS_PREFIX(name, SYSTEM_PREFIX))
|
|
|
5ae4d2 |
continue;
|
|
|
5ae4d2 |
#endif
|
|
|
5ae4d2 |
if (am_root < 0 && name_len > RPRE_LEN
|