* src/xattrs.c (xattrs_xattrs_get): apply exclude/include mask when fetching extended attributes
This makes archive create behavior consistent with the documentation. Without this change xattr include/exclude options are accepted when creating an archive but are silently ignored. --- src/xattrs.c | 103 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/src/xattrs.c b/src/xattrs.c index 8e56168..a272af7 100644 --- a/src/xattrs.c +++ b/src/xattrs.c @@ -434,8 +434,55 @@ xattrs_clear_setup (void) clear_mask_map (&xattrs_setup.excl); } -/* get all xattrs from file given by FILE_NAME or FD (when non-zero). This - includes all the user.*, security.*, system.*, etc. available domains */ +static bool +xattrs_matches_mask (const char *kw, struct xattrs_mask_map *mm) +{ + int i; + + if (!mm->size) + return false; + + for (i = 0; i < mm->used; i++) + if (fnmatch (mm->masks[i], kw, 0) == 0) + return true; + + return false; +} + +#define USER_DOT_PFX "user." + +static bool +xattrs_kw_included (const char *kw, bool archiving) +{ + if (xattrs_setup.incl.size) + return xattrs_matches_mask (kw, &xattrs_setup.incl); + else if (archiving) + return true; + else + return strncmp (kw, USER_DOT_PFX, sizeof (USER_DOT_PFX) - 1) == 0; +} + +static bool +xattrs_kw_excluded (const char *kw, bool archiving) +{ + return xattrs_setup.excl.size ? + xattrs_matches_mask (kw, &xattrs_setup.excl) : false; +} + +/* Check whether the xattr with keyword KW should be discarded from list of + attributes that are going to be archived/excluded (set ARCHIVING=true for + archiving, false for excluding) */ +static bool +xattrs_masked_out (const char *kw, bool archiving) +{ + return xattrs_kw_included (kw, archiving) ? + xattrs_kw_excluded (kw, archiving) : true; +} + +/* get xattrs from file given by FILE_NAME or FD (when non-zero) + xattrs are checked against the user supplied include/exclude mask + if no mask is given this includes all the user.*, security.*, system.*, + etc. available domains */ void xattrs_xattrs_get (int parentfd, char const *file_name, struct tar_stat_info *st, int fd) @@ -480,8 +527,6 @@ xattrs_xattrs_get (int parentfd, char const *file_name, size_t len = strlen (attr); ssize_t aret = 0; - /* Archive all xattrs during creation, decide at extraction time - * which ones are of interest/use for the target filesystem. */ while (((fd == 0) ? ((aret = lgetxattrat (parentfd, file_name, attr, val, asz)) == -1) @@ -492,7 +537,10 @@ xattrs_xattrs_get (int parentfd, char const *file_name, } if (aret != -1) - xheader_xattr_add (st, attr, val, aret); + { + if (!xattrs_masked_out(attr, true)) + xheader_xattr_add (st, attr, val, aret); + } else if (errno != ENOATTR) call_arg_warn ((fd == 0) ? "lgetxattrat" : "fgetxattr", file_name); @@ -595,51 +643,6 @@ xattrs_selinux_set (struct tar_stat_info const *st, } } -static bool -xattrs_matches_mask (const char *kw, struct xattrs_mask_map *mm) -{ - int i; - - if (!mm->size) - return false; - - for (i = 0; i < mm->used; i++) - if (fnmatch (mm->masks[i], kw, 0) == 0) - return true; - - return false; -} - -#define USER_DOT_PFX "user." - -static bool -xattrs_kw_included (const char *kw, bool archiving) -{ - if (xattrs_setup.incl.size) - return xattrs_matches_mask (kw, &xattrs_setup.incl); - else if (archiving) - return true; - else - return strncmp (kw, USER_DOT_PFX, sizeof (USER_DOT_PFX) - 1) == 0; -} - -static bool -xattrs_kw_excluded (const char *kw, bool archiving) -{ - return xattrs_setup.excl.size ? - xattrs_matches_mask (kw, &xattrs_setup.excl) : false; -} - -/* Check whether the xattr with keyword KW should be discarded from list of - attributes that are going to be archived/excluded (set ARCHIVING=true for - archiving, false for excluding) */ -static bool -xattrs_masked_out (const char *kw, bool archiving) -{ - return xattrs_kw_included (kw, archiving) ? - xattrs_kw_excluded (kw, archiving) : true; -} - void xattrs_xattrs_set (struct tar_stat_info const *st, char const *file_name, char typeflag, int later_run) -- 2.5.5