X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fxattrs.c;h=307ee380fab183f8b02915f1d585ba80b1d0684b;hb=fe3b106cb3b0bc4d50230ed263bf5ccbc8bf1ea7;hp=5a4bf7215b7ca97f78fcba0e0d8dbdf267f23aa0;hpb=3c4e51fad6dbd595a2fb1e34f11e5a804b9b33ab;p=chaz%2Ftar
diff --git a/src/xattrs.c b/src/xattrs.c
index 5a4bf72..307ee38 100644
--- a/src/xattrs.c
+++ b/src/xattrs.c
@@ -1,23 +1,23 @@
/* Support for extended attributes.
- Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software
- Foundation, Inc.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
- Written by James Antill, on 2006-07-27.
+ This file is part of GNU tar.
- 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
- Free Software Foundation; either version 2, or (at your option) any later
- version.
+ GNU tar is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- Public License for more details.
+ GNU tar is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ Written by James Antill, on 2006-07-27. */
#include
#include
@@ -58,9 +58,10 @@ static struct
#ifdef HAVE_POSIX_ACLS
/* acl-at wrappers, TODO: move to gnulib in future? */
-acl_t acl_get_file_at (int dirfd, const char *file, acl_type_t type);
-int acl_set_file_at (int dirfd, const char *file, acl_type_t type, acl_t acl);
-int file_has_acl_at (int dirfd, char const *, struct stat const *);
+static acl_t acl_get_file_at (int, const char *, acl_type_t);
+static int acl_set_file_at (int, const char *, acl_type_t, acl_t);
+static int file_has_acl_at (int, char const *, struct stat const *);
+static int acl_delete_def_file_at (int, char const *);
/* acl_get_file_at */
#define AT_FUNC_NAME acl_get_file_at
@@ -88,6 +89,17 @@ int file_has_acl_at (int dirfd, char const *, struct stat const *);
#undef AT_FUNC_POST_FILE_PARAM_DECLS
#undef AT_FUNC_POST_FILE_ARGS
+/* acl_delete_def_file_at */
+#define AT_FUNC_NAME acl_delete_def_file_at
+#define AT_FUNC_F1 acl_delete_def_file
+#define AT_FUNC_POST_FILE_PARAM_DECLS
+#define AT_FUNC_POST_FILE_ARGS
+#include "at-func.c"
+#undef AT_FUNC_NAME
+#undef AT_FUNC_F1
+#undef AT_FUNC_POST_FILE_PARAM_DECLS
+#undef AT_FUNC_POST_FILE_ARGS
+
/* gnulib file_has_acl_at */
#define AT_FUNC_NAME file_has_acl_at
#define AT_FUNC_F1 file_has_acl
@@ -137,7 +149,7 @@ static char *
skip_to_ext_fields (char *ptr)
{
/* skip tag name (user/group/default/mask) */
- ptr += strcspn (ptr, ":,\n");
+ ptr += strcspn (ptr, ":,\n");
if (*ptr != ':')
return ptr;
@@ -187,27 +199,36 @@ fixup_extra_acl_fields (char *ptr)
return ptr;
}
-/* "system.posix_acl_access" */
+/* Set the "system.posix_acl_access/system.posix_acl_default" extended
+ attribute. Called only when acls_option > 0. */
static void
xattrs__acls_set (struct tar_stat_info const *st,
char const *file_name, int type,
char *ptr, size_t len, bool def)
-{
+{
acl_t acl;
if (ptr)
{
/* assert (strlen (ptr) == len); */
ptr = fixup_extra_acl_fields (ptr);
-
acl = acl_from_text (ptr);
- acls_option = 1;
}
- else if (acls_option > 0)
- acl = perms2acl (st->stat.st_mode);
+ else if (def)
+ {
+ /* No "default" IEEE 1003.1e ACL set for directory. At this moment,
+ FILE_NAME may already have inherited default acls from parent
+ directory; clean them up. */
+ if (acl_delete_def_file_at (chdir_fd, file_name))
+ WARNOPT (WARN_XATTR_WRITE,
+ (0, errno,
+ _("acl_delete_def_file_at: Cannot drop default POSIX ACLs "
+ "for file '%s'"),
+ file_name));
+ return;
+ }
else
- return; /* don't call acl functions unless we first hit an ACL, or
- --acls was passed explicitly */
+ acl = perms2acl (st->stat.st_mode);
if (!acl)
{
@@ -229,7 +250,7 @@ static void
xattrs__acls_get_a (int parentfd, const char *file_name,
struct tar_stat_info *st,
char **ret_ptr, size_t * ret_len)
-{
+{
char *val = NULL;
ssize_t len;
acl_t acl;
@@ -261,7 +282,7 @@ static void
xattrs__acls_get_d (int parentfd, char const *file_name,
struct tar_stat_info *st,
char **ret_ptr, size_t * ret_len)
-{
+{
char *val = NULL;
ssize_t len;
acl_t acl;
@@ -407,7 +428,7 @@ clear_mask_map (struct xattrs_mask_map *mask_map)
}
void
-xattrs_clear_setup ()
+xattrs_clear_setup (void)
{
clear_mask_map (&xattrs_setup.incl);
clear_mask_map (&xattrs_setup.excl);
@@ -484,6 +505,7 @@ xattrs_xattrs_get (int parentfd, char const *file_name,
}
}
+#ifdef HAVE_XATTRS
static void
xattrs__fd_set (struct tar_stat_info const *st,
char const *file_name, char typeflag,
@@ -509,6 +531,7 @@ xattrs__fd_set (struct tar_stat_info const *st,
sysname, attr, file_name));
}
}
+#endif
/* lgetfileconat is called against FILE_NAME iff the FD parameter is set to
zero, otherwise the fgetfileconat is used against correct file descriptor */
@@ -614,7 +637,7 @@ static bool
xattrs_masked_out (const char *kw, bool archiving)
{
return xattrs_kw_included (kw, archiving) ?
- xattrs_kw_excluded (kw, archiving) : true;
+ xattrs_kw_excluded (kw, archiving) : true;
}
void
@@ -693,7 +716,7 @@ xattrs_print_char (struct tar_stat_info const *st, char *output)
if (selinux_context_option > 0 && st->cntx_name)
*output = '.';
- if (acls_option && (st->acls_a_len || st->acls_d_len))
+ if (acls_option > 0 && (st->acls_a_len || st->acls_d_len))
*output = '+';
}
@@ -704,11 +727,11 @@ xattrs_print (struct tar_stat_info const *st)
return;
/* selinux */
- if (selinux_context_option && st->cntx_name)
+ if (selinux_context_option > 0 && st->cntx_name)
fprintf (stdlis, " s: %s\n", st->cntx_name);
/* acls */
- if (acls_option && (st->acls_a_len || st->acls_d_len))
+ if (acls_option > 0 && (st->acls_a_len || st->acls_d_len))
{
fprintf (stdlis, " a: ");
acls_one_line ("", ',', st->acls_a_ptr, st->acls_a_len);
@@ -717,10 +740,10 @@ xattrs_print (struct tar_stat_info const *st)
}
/* xattrs */
- if (xattrs_option && st->xattr_map_size)
+ if (xattrs_option > 0 && st->xattr_map_size)
{
int i;
-
+
for (i = 0; i < st->xattr_map_size; ++i)
{
char *keyword = st->xattr_map[i].xkey + strlen ("SCHILY.xattr.");