Minor change.

* src/xattrs.c: Fix indentation. Fix copyleft statement, promote to GPLv3+.
* src/xattrs.h: Likewise
This commit is contained in:
Sergey Poznyakoff
2012-11-18 23:05:00 +02:00
parent 085cace180
commit 4ac671c49b
2 changed files with 241 additions and 202 deletions

View File

@@ -7,7 +7,7 @@
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any later Free Software Foundation; either version 3, or (at your option) any later
version. version.
This program is distributed in the hope that it will be useful, but This program is distributed in the hope that it will be useful, but
@@ -100,58 +100,70 @@ int file_has_acl_at (int dirfd, char const *, struct stat const *);
#undef AT_FUNC_POST_FILE_ARGS #undef AT_FUNC_POST_FILE_ARGS
/* convert unix permissions into an ACL ... needed due to "default" ACLs */ /* convert unix permissions into an ACL ... needed due to "default" ACLs */
static acl_t perms2acl (int perms) static acl_t
perms2acl (int perms)
{ {
char val[] = "user::---,group::---,other::---"; char val[] = "user::---,group::---,other::---";
/* 0123456789 123456789 123456789 123456789 */ /* 0123456789 123456789 123456789 123456789 */
/* user */ /* user */
if (perms & 0400) val[ 6] = 'r'; if (perms & 0400)
if (perms & 0200) val[ 7] = 'w'; val[6] = 'r';
if (perms & 0100) val[ 8] = 'x'; if (perms & 0200)
val[7] = 'w';
if (perms & 0100)
val[8] = 'x';
/* group */ /* group */
if (perms & 0040) val[17] = 'r'; if (perms & 0040)
if (perms & 0020) val[18] = 'w'; val[17] = 'r';
if (perms & 0010) val[19] = 'x'; if (perms & 0020)
val[18] = 'w';
if (perms & 0010)
val[19] = 'x';
/* other */ /* other */
if (perms & 0004) val[28] = 'r'; if (perms & 0004)
if (perms & 0002) val[29] = 'w'; val[28] = 'r';
if (perms & 0001) val[30] = 'x'; if (perms & 0002)
val[29] = 'w';
if (perms & 0001)
val[30] = 'x';
return (acl_from_text (val)); return acl_from_text (val);
} }
static char *skip_to_ext_fields (char *ptr) static char *
skip_to_ext_fields (char *ptr)
{ {
ptr += strcspn (ptr, ":,\n"); /* skip tag name. Ie. user/group/default/mask */ ptr += strcspn (ptr, ":,\n"); /* skip tag name. Ie. user/group/default/mask */
if (*ptr != ':') if (*ptr != ':')
return (ptr); /* error? no user/group field */ return ptr; /* error? no user/group field */
++ptr; ++ptr;
ptr += strcspn (ptr, ":,\n"); /* skip user/group name */ ptr += strcspn (ptr, ":,\n"); /* skip user/group name */
if (*ptr != ':') if (*ptr != ':')
return (ptr); /* error? no perms field */ return ptr; /* error? no perms field */
++ptr; ++ptr;
ptr += strcspn (ptr, ":,\n"); /* skip perms */ ptr += strcspn (ptr, ":,\n"); /* skip perms */
if (*ptr != ':') if (*ptr != ':')
return (ptr); /* no extra fields */ return ptr; /* no extra fields */
return (ptr); return ptr;
} }
/* The POSIX draft allows extra fields after the three main ones. Star /* The POSIX draft allows extra fields after the three main ones. Star
uses this to add a fourth field for user/group which is the numeric ID. uses this to add a fourth field for user/group which is the numeric ID.
We just skip all extra fields atm. */ We just skip all extra fields atm. */
static const char *fixup_extra_acl_fields (const char *ptr) static const char *
fixup_extra_acl_fields (const char *ptr)
{ {
char *src = (char *)ptr; char *src = (char *) ptr;
char *dst = (char *)ptr; char *dst = (char *) ptr;
while (*src) while (*src)
{ {
@@ -160,14 +172,15 @@ static const char *fixup_extra_acl_fields (const char *ptr)
src = skip_to_ext_fields (src); src = skip_to_ext_fields (src);
len = src - old; len = src - old;
if (old != dst) memmove (dst, old, len); if (old != dst)
memmove (dst, old, len);
dst += len; dst += len;
if (*src == ':') /* We have extra fields, skip them all */ if (*src == ':') /* We have extra fields, skip them all */
src += strcspn (src, "\n,"); src += strcspn (src, "\n,");
if ((*src == '\n') || (*src == ',')) if ((*src == '\n') || (*src == ','))
*dst++ = *src++; /* also done when dst == src, but that's ok */ *dst++ = *src++; /* also done when dst == src, but that's ok */
} }
if (src != dst) if (src != dst)
*dst = 0; *dst = 0;
@@ -175,10 +188,11 @@ static const char *fixup_extra_acl_fields (const char *ptr)
return ptr; return ptr;
} }
static void xattrs__acls_set (struct tar_stat_info const *st, static void
char const *file_name, int type, xattrs__acls_set (struct tar_stat_info const *st,
const char *ptr, size_t len, bool def) char const *file_name, int type,
{ /* "system.posix_acl_access" */ const char *ptr, size_t len, bool def)
{ /* "system.posix_acl_access" */
acl_t acl; acl_t acl;
if (ptr) if (ptr)
@@ -192,10 +206,10 @@ static void xattrs__acls_set (struct tar_stat_info const *st,
else if (acls_option > 0) else if (acls_option > 0)
acl = perms2acl (st->stat.st_mode); acl = perms2acl (st->stat.st_mode);
else else
return; /* don't call acl functions unless we first hit an ACL, or return; /* don't call acl functions unless we first hit an ACL, or
--acls was passed explicitly */ --acls was passed explicitly */
if (acl == (acl_t)NULL) if (acl == (acl_t) NULL)
{ {
call_arg_warn ("acl_from_text", file_name); call_arg_warn ("acl_from_text", file_name);
return; return;
@@ -203,25 +217,28 @@ static void xattrs__acls_set (struct tar_stat_info const *st,
if (acl_set_file_at (chdir_fd, file_name, type, acl) == -1) if (acl_set_file_at (chdir_fd, file_name, type, acl) == -1)
/* warn even if filesystem does not support acls */ /* warn even if filesystem does not support acls */
WARNOPT (WARN_XATTR_WRITE, (0, errno, WARNOPT (WARN_XATTR_WRITE,
_("acl_set_file_at: Cannot set POSIX ACLs for file '%s'"), file_name)); (0, errno,
_("acl_set_file_at: Cannot set POSIX ACLs for file '%s'"),
file_name));
acl_free (acl); acl_free (acl);
} }
static void xattrs__acls_get_a (int parentfd, const char *file_name, static void
struct tar_stat_info *st, xattrs__acls_get_a (int parentfd, const char *file_name,
char **ret_ptr, size_t *ret_len) struct tar_stat_info *st,
char **ret_ptr, size_t * ret_len)
{ /* "system.posix_acl_access" */ { /* "system.posix_acl_access" */
char *val = NULL; char *val = NULL;
ssize_t len; ssize_t len;
acl_t acl; acl_t acl;
if ((acl = acl_get_file_at (parentfd, file_name, ACL_TYPE_ACCESS)) if ((acl = acl_get_file_at (parentfd, file_name, ACL_TYPE_ACCESS))
== (acl_t)NULL) == (acl_t) NULL)
{ {
if (errno != ENOTSUP) if (errno != ENOTSUP)
call_arg_warn ("acl_get_file_at", file_name); call_arg_warn ("acl_get_file_at", file_name);
return; return;
} }
@@ -240,19 +257,20 @@ static void xattrs__acls_get_a (int parentfd, const char *file_name,
acl_free (val); acl_free (val);
} }
static void xattrs__acls_get_d (int parentfd, char const *file_name, static void
struct tar_stat_info *st, xattrs__acls_get_d (int parentfd, char const *file_name,
char **ret_ptr, size_t *ret_len) struct tar_stat_info *st,
{ /* "system.posix_acl_default" */ char **ret_ptr, size_t * ret_len)
{ /* "system.posix_acl_default" */
char *val = NULL; char *val = NULL;
ssize_t len; ssize_t len;
acl_t acl; acl_t acl;
if ((acl = acl_get_file_at (parentfd, file_name, ACL_TYPE_DEFAULT)) if ((acl = acl_get_file_at (parentfd, file_name, ACL_TYPE_DEFAULT))
== (acl_t)NULL) == (acl_t) NULL)
{ {
if (errno != ENOTSUP) if (errno != ENOTSUP)
call_arg_warn ("acl_get_file_at", file_name); call_arg_warn ("acl_get_file_at", file_name);
return; return;
} }
@@ -272,8 +290,9 @@ static void xattrs__acls_get_d (int parentfd, char const *file_name,
} }
#endif /* HAVE_POSIX_ACLS */ #endif /* HAVE_POSIX_ACLS */
static void acls_one_line (const char *prefix, char delim, static void
const char *aclstring, size_t len) acls_one_line (const char *prefix, char delim,
const char *aclstring, size_t len)
{ {
/* support both long and short text representation of posix acls */ /* support both long and short text representation of posix acls */
struct obstack stk; struct obstack stk;
@@ -289,10 +308,10 @@ static void acls_one_line (const char *prefix, char delim,
{ {
int move = strcspn (aclstring, ",\n"); int move = strcspn (aclstring, ",\n");
if (!move) if (!move)
break; break;
if (oldstring != aclstring) if (oldstring != aclstring)
obstack_1grow (&stk, delim); obstack_1grow (&stk, delim);
obstack_grow (&stk, prefix, pref_len); obstack_grow (&stk, prefix, pref_len);
obstack_grow (&stk, aclstring, move); obstack_grow (&stk, aclstring, move);
@@ -308,56 +327,59 @@ static void acls_one_line (const char *prefix, char delim,
obstack_free (&stk, NULL); obstack_free (&stk, NULL);
} }
void xattrs_acls_get (int parentfd, char const *file_name, void
struct tar_stat_info *st, int fd, int xisfile) xattrs_acls_get (int parentfd, char const *file_name,
struct tar_stat_info *st, int fd, int xisfile)
{ {
if (acls_option > 0) if (acls_option > 0)
{ {
#ifndef HAVE_POSIX_ACLS #ifndef HAVE_POSIX_ACLS
static int done = 0; static int done = 0;
if (!done) if (!done)
WARN ((0, 0, _("POSIX ACL support is not available"))); WARN ((0, 0, _("POSIX ACL support is not available")));
done = 1; done = 1;
#else #else
int err = file_has_acl_at (parentfd, file_name, &st->stat); int err = file_has_acl_at (parentfd, file_name, &st->stat);
if (err == 0) if (err == 0)
return; return;
if (err == -1) if (err == -1)
{ {
call_arg_warn ("file_has_acl_at", file_name); call_arg_warn ("file_has_acl_at", file_name);
return; return;
} }
xattrs__acls_get_a (parentfd, file_name, st, xattrs__acls_get_a (parentfd, file_name, st,
&st->acls_a_ptr, &st->acls_a_len); &st->acls_a_ptr, &st->acls_a_len);
if (!xisfile) if (!xisfile)
xattrs__acls_get_d (parentfd, file_name, st, xattrs__acls_get_d (parentfd, file_name, st,
&st->acls_d_ptr, &st->acls_d_len); &st->acls_d_ptr, &st->acls_d_len);
#endif #endif
} }
} }
void xattrs_acls_set (struct tar_stat_info const *st, void
char const *file_name, char typeflag) xattrs_acls_set (struct tar_stat_info const *st,
char const *file_name, char typeflag)
{ {
if ((acls_option > 0) && (typeflag != SYMTYPE)) if ((acls_option > 0) && (typeflag != SYMTYPE))
{ {
#ifndef HAVE_POSIX_ACLS #ifndef HAVE_POSIX_ACLS
static int done = 0; static int done = 0;
if (!done) if (!done)
WARN ((0, 0, _("POSIX ACL support is not available"))); WARN ((0, 0, _("POSIX ACL support is not available")));
done = 1; done = 1;
#else #else
xattrs__acls_set (st, file_name, ACL_TYPE_ACCESS, xattrs__acls_set (st, file_name, ACL_TYPE_ACCESS,
st->acls_a_ptr, st->acls_a_len, false); st->acls_a_ptr, st->acls_a_len, false);
if ((typeflag == DIRTYPE) || (typeflag == GNUTYPE_DUMPDIR)) if ((typeflag == DIRTYPE) || (typeflag == GNUTYPE_DUMPDIR))
xattrs__acls_set (st, file_name, ACL_TYPE_DEFAULT, xattrs__acls_set (st, file_name, ACL_TYPE_DEFAULT,
st->acls_d_ptr, st->acls_d_len, true); st->acls_d_ptr, st->acls_d_len, true);
#endif #endif
} }
} }
static void mask_map_realloc (struct xattrs_mask_map *map) static void
mask_map_realloc (struct xattrs_mask_map *map)
{ {
if (map->size == 0) if (map->size == 0)
{ {
@@ -374,10 +396,11 @@ static void mask_map_realloc (struct xattrs_mask_map *map)
} }
} }
void xattrs_mask_add (const char *mask, bool incl) void
xattrs_mask_add (const char *mask, bool incl)
{ {
struct xattrs_mask_map *mask_map = incl ? &xattrs_setup.incl struct xattrs_mask_map *mask_map = incl ? &xattrs_setup.incl
: &xattrs_setup.excl; : &xattrs_setup.excl;
/* ensure there is enough space */ /* ensure there is enough space */
mask_map_realloc (mask_map); mask_map_realloc (mask_map);
/* just assign pointers -- we silently expect that pointer "mask" is valid /* just assign pointers -- we silently expect that pointer "mask" is valid
@@ -385,13 +408,15 @@ void xattrs_mask_add (const char *mask, bool incl)
mask_map->masks[mask_map->used++] = mask; mask_map->masks[mask_map->used++] = mask;
} }
static void clear_mask_map (struct xattrs_mask_map *mask_map) static void
clear_mask_map (struct xattrs_mask_map *mask_map)
{ {
if (mask_map->size) if (mask_map->size)
free (mask_map->masks); free (mask_map->masks);
} }
void xattrs_clear_setup () void
xattrs_clear_setup ()
{ {
clear_mask_map (&xattrs_setup.incl); clear_mask_map (&xattrs_setup.incl);
clear_mask_map (&xattrs_setup.excl); clear_mask_map (&xattrs_setup.excl);
@@ -399,77 +424,81 @@ void xattrs_clear_setup ()
/* get all xattrs from file given by FILE_NAME or FD (when non-zero). This /* get all xattrs from file given by FILE_NAME or FD (when non-zero). This
includes all the user.*, security.*, system.*, etc. available domains */ includes all the user.*, security.*, system.*, etc. available domains */
void xattrs_xattrs_get (int parentfd, char const *file_name, void
struct tar_stat_info *st, int fd) xattrs_xattrs_get (int parentfd, char const *file_name,
struct tar_stat_info *st, int fd)
{ {
if (xattrs_option > 0) if (xattrs_option > 0)
{ {
#ifndef HAVE_XATTRS #ifndef HAVE_XATTRS
static int done = 0; static int done = 0;
if (!done) if (!done)
WARN ((0, 0, _("XATTR support is not available"))); WARN ((0, 0, _("XATTR support is not available")));
done = 1; done = 1;
#else #else
static ssize_t xsz = 1024; static ssize_t xsz = 1024;
static char *xatrs = NULL; static char *xatrs = NULL;
ssize_t xret = -1; ssize_t xret = -1;
if (!xatrs) xatrs = xmalloc (xsz); if (!xatrs)
xatrs = xmalloc (xsz);
while (((fd == 0) ? while (((fd == 0) ?
((xret = llistxattrat (parentfd, file_name, xatrs, xsz)) == -1) : ((xret =
((xret = flistxattr (fd, xatrs, xsz)) == -1)) && llistxattrat (parentfd, file_name, xatrs, xsz)) == -1) :
(errno == ERANGE)) ((xret = flistxattr (fd, xatrs, xsz)) == -1))
{ && (errno == ERANGE))
xsz <<= 1; {
xatrs = xrealloc (xatrs, xsz); xsz <<= 1;
} xatrs = xrealloc (xatrs, xsz);
}
if (xret == -1) if (xret == -1)
call_arg_warn ((fd == 0) ? "llistxattrat" : "flistxattr", file_name); call_arg_warn ((fd == 0) ? "llistxattrat" : "flistxattr", file_name);
else else
{ {
const char *attr = xatrs; const char *attr = xatrs;
static ssize_t asz = 1024; static ssize_t asz = 1024;
static char *val = NULL; static char *val = NULL;
if (!val) val = xmalloc (asz); if (!val)
val = xmalloc (asz);
while (xret > 0) while (xret > 0)
{ {
size_t len = strlen (attr); size_t len = strlen (attr);
ssize_t aret = 0; ssize_t aret = 0;
/* Archive all xattrs during creation, decide at extraction time /* Archive all xattrs during creation, decide at extraction time
* which ones are of interest/use for the target filesystem. */ * which ones are of interest/use for the target filesystem. */
while (((fd == 0) while (((fd == 0)
? ((aret = lgetxattrat (parentfd, file_name, attr, ? ((aret = lgetxattrat (parentfd, file_name, attr,
val, asz)) == -1) val, asz)) == -1)
: ((aret = fgetxattr (fd, attr, val, asz)) == -1)) : ((aret = fgetxattr (fd, attr, val, asz)) == -1))
&& (errno == ERANGE)) && (errno == ERANGE))
{ {
asz <<= 1; asz <<= 1;
val = xrealloc (val, asz); val = xrealloc (val, asz);
} }
if (aret != -1) if (aret != -1)
xheader_xattr_add (st, attr, val, aret); xheader_xattr_add (st, attr, val, aret);
else if (errno != ENOATTR) else if (errno != ENOATTR)
call_arg_warn ((fd == 0) ? "lgetxattrat" call_arg_warn ((fd == 0) ? "lgetxattrat"
: "fgetxattr", file_name); : "fgetxattr", file_name);
attr += len + 1; attr += len + 1;
xret -= len + 1; xret -= len + 1;
} }
} }
#endif #endif
} }
} }
static void xattrs__fd_set (struct tar_stat_info const *st, static void
char const *file_name, char typeflag, xattrs__fd_set (struct tar_stat_info const *st,
const char *attr, char const *file_name, char typeflag,
const char *ptr, size_t len) const char *attr, const char *ptr, size_t len)
{ {
if (ptr) if (ptr)
{ {
@@ -477,79 +506,84 @@ static void xattrs__fd_set (struct tar_stat_info const *st,
int ret = -1; int ret = -1;
if (typeflag != SYMTYPE) if (typeflag != SYMTYPE)
ret = setxattrat (chdir_fd, file_name, attr, ptr, len, 0); ret = setxattrat (chdir_fd, file_name, attr, ptr, len, 0);
else else
{ {
sysname = "lsetxattr"; sysname = "lsetxattr";
ret = lsetxattrat (chdir_fd, file_name, attr, ptr, len, 0); ret = lsetxattrat (chdir_fd, file_name, attr, ptr, len, 0);
} }
if (ret == -1) if (ret == -1)
WARNOPT (WARN_XATTR_WRITE, (0, errno, WARNOPT (WARN_XATTR_WRITE,
_("%s: Cannot set '%s' extended attribute for file '%s'"), (0, errno,
sysname, attr, file_name)); _("%s: Cannot set '%s' extended attribute for file '%s'"),
sysname, attr, file_name));
} }
} }
/* lgetfileconat is called against FILE_NAME iff the FD parameter is set to /* lgetfileconat is called against FILE_NAME iff the FD parameter is set to
zero, otherwise the fgetfileconat is used against correct file descriptor */ zero, otherwise the fgetfileconat is used against correct file descriptor */
void xattrs_selinux_get (int parentfd, char const *file_name, void
struct tar_stat_info *st, int fd) xattrs_selinux_get (int parentfd, char const *file_name,
struct tar_stat_info *st, int fd)
{ {
if (selinux_context_option > 0) if (selinux_context_option > 0)
{ {
#if HAVE_SELINUX_SELINUX_H != 1 #if HAVE_SELINUX_SELINUX_H != 1
static int done = 0; static int done = 0;
if (!done) if (!done)
WARN ((0, 0, _("SELinux support is not available"))); WARN ((0, 0, _("SELinux support is not available")));
done = 1; done = 1;
#else #else
int result = (fd ? fgetfilecon (fd, &st->cntx_name) int result = (fd ? fgetfilecon (fd, &st->cntx_name)
: lgetfileconat (parentfd, file_name, &st->cntx_name)); : lgetfileconat (parentfd, file_name, &st->cntx_name));
if (result == -1 && errno != ENODATA && errno != ENOTSUP) if (result == -1 && errno != ENODATA && errno != ENOTSUP)
call_arg_warn (fd ? "fgetfilecon" : "lgetfileconat", file_name); call_arg_warn (fd ? "fgetfilecon" : "lgetfileconat", file_name);
#endif #endif
} }
} }
void xattrs_selinux_set (struct tar_stat_info const *st, void
char const *file_name, char typeflag) xattrs_selinux_set (struct tar_stat_info const *st,
char const *file_name, char typeflag)
{ {
if (selinux_context_option > 0) if (selinux_context_option > 0)
{ {
#if HAVE_SELINUX_SELINUX_H != 1 #if HAVE_SELINUX_SELINUX_H != 1
static int done = 0; static int done = 0;
if (!done) if (!done)
WARN ((0, 0, _("SELinux support is not available"))); WARN ((0, 0, _("SELinux support is not available")));
done = 1; done = 1;
#else #else
const char *sysname = "setfilecon"; const char *sysname = "setfilecon";
int ret; int ret;
if (!st->cntx_name) if (!st->cntx_name)
return; return;
if (typeflag != SYMTYPE) if (typeflag != SYMTYPE)
{ {
ret = setfileconat (chdir_fd, file_name, st->cntx_name); ret = setfileconat (chdir_fd, file_name, st->cntx_name);
sysname = "setfileconat"; sysname = "setfileconat";
} }
else else
{ {
ret = lsetfileconat (chdir_fd, file_name, st->cntx_name); ret = lsetfileconat (chdir_fd, file_name, st->cntx_name);
sysname = "lsetfileconat"; sysname = "lsetfileconat";
} }
if (ret == -1) if (ret == -1)
WARNOPT (WARN_XATTR_WRITE, (0, errno, WARNOPT (WARN_XATTR_WRITE,
_("%s: Cannot set SELinux context for file '%s'"), sysname, (0, errno,
file_name)); _("%s: Cannot set SELinux context for file '%s'"),
sysname, file_name));
#endif #endif
} }
} }
static bool xattrs_matches_mask (const char *kw, struct xattrs_mask_map *mm) static bool
xattrs_matches_mask (const char *kw, struct xattrs_mask_map *mm)
{ {
int i; int i;
@@ -563,20 +597,22 @@ static bool xattrs_matches_mask (const char *kw, struct xattrs_mask_map *mm)
return false; return false;
} }
static bool xattrs_kw_included (const char *kw, bool archiving) static bool
xattrs_kw_included (const char *kw, bool archiving)
{ {
if (xattrs_setup.incl.size) if (xattrs_setup.incl.size)
return xattrs_matches_mask (kw, &xattrs_setup.incl); return xattrs_matches_mask (kw, &xattrs_setup.incl);
else else
{ {
if (archiving) if (archiving)
return true; return true;
else else
return strncmp (kw, "user.", strlen ("user.")) == 0; return strncmp (kw, "user.", strlen ("user.")) == 0;
} }
} }
static bool xattrs_kw_excluded (const char *kw, bool archiving) static bool
xattrs_kw_excluded (const char *kw, bool archiving)
{ {
if (!xattrs_setup.excl.size) if (!xattrs_setup.excl.size)
return false; return false;
@@ -587,7 +623,8 @@ static bool xattrs_kw_excluded (const char *kw, bool archiving)
/* Check whether the xattr with keyword KW should be discarded from list of /* 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 attributes that are going to be archived/excluded (set ARCHIVING=true for
archiving, false for excluding) */ archiving, false for excluding) */
static bool xattrs_masked_out (const char *kw, bool archiving) static bool
xattrs_masked_out (const char *kw, bool archiving)
{ {
if (!xattrs_kw_included (kw, archiving)) if (!xattrs_kw_included (kw, archiving))
return true; return true;
@@ -595,60 +632,62 @@ static bool xattrs_masked_out (const char *kw, bool archiving)
return xattrs_kw_excluded (kw, archiving); return xattrs_kw_excluded (kw, archiving);
} }
void xattrs_xattrs_set (struct tar_stat_info const *st, void
char const *file_name, char typeflag, xattrs_xattrs_set (struct tar_stat_info const *st,
int later_run) char const *file_name, char typeflag, int later_run)
{ {
if (xattrs_option > 0) if (xattrs_option > 0)
{ {
#ifndef HAVE_XATTRS #ifndef HAVE_XATTRS
static int done = 0; static int done = 0;
if (!done) if (!done)
WARN ((0, 0, _("XATTR support is not available"))); WARN ((0, 0, _("XATTR support is not available")));
done = 1; done = 1;
#else #else
size_t scan = 0; size_t scan = 0;
if (!st->xattr_map_size) if (!st->xattr_map_size)
return; return;
for (; scan < st->xattr_map_size; ++scan) for (; scan < st->xattr_map_size; ++scan)
{ {
char *keyword = st->xattr_map[scan].xkey; char *keyword = st->xattr_map[scan].xkey;
keyword += strlen ("SCHILY.xattr."); keyword += strlen ("SCHILY.xattr.");
/* TODO: this 'later_run' workaround is temporary solution -> once /* TODO: this 'later_run' workaround is temporary solution -> once
capabilities should become fully supported by it's API and there capabilities should become fully supported by it's API and there
should exist something like xattrs_capabilities_set() call. should exist something like xattrs_capabilities_set() call.
For a regular files: all extended attributes are restored during For a regular files: all extended attributes are restored during
the first run except 'security.capability' which is restored in the first run except 'security.capability' which is restored in
'later_run == 1'. */ 'later_run == 1'. */
if (typeflag == REGTYPE if (typeflag == REGTYPE
&& later_run == !!strcmp (keyword, "security.capability")) && later_run == !!strcmp (keyword, "security.capability"))
continue; continue;
if (xattrs_masked_out (keyword, false /* extracting */ )) if (xattrs_masked_out (keyword, false /* extracting */ ))
/* we don't want to restore this keyword */ /* we don't want to restore this keyword */
continue; continue;
xattrs__fd_set (st, file_name, typeflag, keyword, xattrs__fd_set (st, file_name, typeflag, keyword,
st->xattr_map[scan].xval_ptr, st->xattr_map[scan].xval_ptr,
st->xattr_map[scan].xval_len); st->xattr_map[scan].xval_len);
} }
#endif #endif
} }
} }
void xattrs_print_char (struct tar_stat_info const *st, char *output) void
xattrs_print_char (struct tar_stat_info const *st, char *output)
{ {
int i; int i;
if (verbose_option < 2) if (verbose_option < 2)
{ {
*output = 0; *output = 0;
return; return;
} }
if (xattrs_option > 0 || selinux_context_option > 0 || acls_option > 0) if (xattrs_option > 0 || selinux_context_option > 0 || acls_option > 0)
{ {
/* placeholders */ /* placeholders */
*output = ' '; *output = ' ';
@@ -658,11 +697,11 @@ void xattrs_print_char (struct tar_stat_info const *st, char *output)
if (xattrs_option > 0 && st->xattr_map_size) if (xattrs_option > 0 && st->xattr_map_size)
for (i = 0; i < st->xattr_map_size; ++i) for (i = 0; i < st->xattr_map_size; ++i)
{ {
char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr."); char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr.");
if (xattrs_masked_out (keyword, false /* like extracting */ )) if (xattrs_masked_out (keyword, false /* like extracting */ ))
continue; continue;
*output = '*'; *output = '*';
break; break;
} }
if (selinux_context_option > 0 && st->cntx_name) if (selinux_context_option > 0 && st->cntx_name)
@@ -672,7 +711,8 @@ void xattrs_print_char (struct tar_stat_info const *st, char *output)
*output = '+'; *output = '+';
} }
void xattrs_print (struct tar_stat_info const *st) void
xattrs_print (struct tar_stat_info const *st)
{ {
if (verbose_option < 3) if (verbose_option < 3)
return; return;
@@ -695,12 +735,12 @@ void xattrs_print (struct tar_stat_info const *st)
{ {
int i; int i;
for (i = 0; i < st->xattr_map_size; ++i) for (i = 0; i < st->xattr_map_size; ++i)
{ {
char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr."); char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr.");
if (xattrs_masked_out (keyword, false /* like extracting */ )) if (xattrs_masked_out (keyword, false /* like extracting */ ))
continue; continue;
fprintf (stdlis, " x: %lu %s\n", fprintf (stdlis, " x: %lu %s\n",
(unsigned long) st->xattr_map[i].xval_len, keyword); (unsigned long) st->xattr_map[i].xval_len, keyword);
} }
} }
} }

View File

@@ -1,6 +1,3 @@
#ifndef GUARD_XATTTRS_H
#define GUARD_XATTTRS_H
/* Support for extended attributes. /* Support for extended attributes.
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software
@@ -10,7 +7,7 @@
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any later Free Software Foundation; either version 3, or (at your option) any later
version. version.
This program is distributed in the hope that it will be useful, but This program is distributed in the hope that it will be useful, but
@@ -23,6 +20,8 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#ifndef GUARD_XATTTRS_H
#define GUARD_XATTTRS_H
/* Add include/exclude fnmatch pattern for xattr key domain. Set INCL parameter /* Add include/exclude fnmatch pattern for xattr key domain. Set INCL parameter
to true/false if you want to add include/exclude pattern */ to true/false if you want to add include/exclude pattern */