Index: attr-2.4.28/libattr/Makefile =================================================================== --- attr-2.4.28.orig/libattr/Makefile +++ attr-2.4.28/libattr/Makefile @@ -13,7 +13,7 @@ LT_CURRENT = 2 LT_REVISION = 0 LT_AGE = 1 -CFILES = libattr.c syscalls.c attr_copy_fd.c attr_copy_file.c attr_copy_check.c +CFILES = libattr.c syscalls.c attr_copy_fd.c attr_copy_file.c attr_copy_check.c attr_copy_action.c HFILES = libattr.h LCFLAGS = -include libattr.h Index: attr-2.4.28/libattr/attr_copy_action.c =================================================================== --- /dev/null +++ attr-2.4.28/libattr/attr_copy_action.c @@ -0,0 +1,163 @@ +/* Copyright (C) 2006 Andreas Gruenbacher , SuSE Linux AG. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "attr/libattr.h" +#define ERROR_CONTEXT_MACROS +#include "error_context.h" + +#define ATTR_CONF "/etc/xattr.conf" + +struct attr_action { + struct attr_action *next; + char *pattern; + int action; +}; + +static struct attr_action *attr_actions; + +static void +free_attr_actions(void) +{ + struct attr_action *tmp; + + while (attr_actions) { + tmp = attr_actions->next; + free(attr_actions->pattern); + free(attr_actions); + attr_actions = tmp; + } +} + +static int +attr_parse_attr_conf(struct error_context *ctx) +{ + char *text, *t; + size_t size_guess = 4096, len; + FILE *file; + char *pattern = NULL; + struct attr_action *new; + int action; + + if (attr_actions) + return 0; + +repeat: + text = malloc(size_guess + 1); + if (!text) + goto fail; + + if ((file = fopen(ATTR_CONF, "r")) == NULL) { + if (errno == ENOENT) + return 0; + goto fail; + } + len = fread(text, 1, size_guess, file); + if (ferror(file)) + goto fail; + if (!feof(file)) { + fclose(file); + file = NULL; + free(text); + size_guess *= 2; + goto repeat; + } + fclose(file); + file = NULL; + + text[len] = 0; + t = text; + for (;;) { + t += strspn(t, " \t\n"); + len = strcspn(t, " \t\n#"); + if (t[len] == '#') { + if (len) + goto parse_error; + t += strcspn(t, "\n"); + continue; + } else if (t[len] == 0) + break; + else if (t[len] == '\n') + goto parse_error; + pattern = strndup(t, len); + if (!pattern) + goto fail; + t += len; + + t += strspn(t, " \t"); + len = strcspn(t, " \t\n#"); + if (len == 4 && !strncmp(t, "skip", 4)) + action = ATTR_ACTION_SKIP; + else if (len == 11 && !strncmp(t, "permissions", 11)) + action = ATTR_ACTION_PERMISSIONS; + else + goto parse_error; + t += len; + t += strspn(t, " \t"); + if (*t != '#' && *t != '\n') + goto parse_error; + + new = malloc(sizeof(struct attr_action)); + if (!new) + goto parse_error; + new->next = attr_actions; + new->pattern = pattern; + new->action = action; + attr_actions = new; + + t += strcspn(t, "\n"); + } + return 0; + +parse_error: + errno = EINVAL; + +fail: + { + const char *q = quote (ctx, ATTR_CONF); + error (ctx, "%s", q); + quote_free (ctx, q); + } + + free(pattern); + if (file) + fclose(file); + free(text); + free_attr_actions(); + return -1; +} + +int +attr_copy_action(const char *name, struct error_context *ctx) +{ + struct attr_action *action = attr_actions; + + if (!attr_parse_attr_conf(ctx)) { + for (action = attr_actions; action; action = action->next) { + if (!fnmatch(action->pattern, name, 0)) + return action->action; + } + } + return 0; +} Index: attr-2.4.28/libattr/attr_copy_fd.c =================================================================== --- attr-2.4.28.orig/libattr/attr_copy_fd.c +++ attr-2.4.28/libattr/attr_copy_fd.c @@ -120,7 +120,7 @@ attr_copy_fd(const char *src_path, int s quote_free (ctx, qname); quote_free (ctx, qpath); ret = -1; - continue; /* may not have permission to access */ + continue; } value = (char *) realloc (old_value = value, size); if (size != 0 && value == NULL) { @@ -137,6 +137,7 @@ attr_copy_fd(const char *src_path, int s quote_free (ctx, qname); quote_free (ctx, qpath); ret = -1; + continue; } if (fsetxattr (dst_fd, name, value, size, 0) != 0) { if (errno == ENOTSUP) Index: attr-2.4.28/libattr/attr_copy_file.c =================================================================== --- attr-2.4.28.orig/libattr/attr_copy_file.c +++ attr-2.4.28/libattr/attr_copy_file.c @@ -118,7 +118,7 @@ attr_copy_file(const char *src_path, con quote_free (ctx, qname); quote_free (ctx, qpath); ret = -1; - continue; /* may not have permission to access */ + continue; } value = (char *) realloc (old_value = value, size); if (size != 0 && value == NULL) { @@ -135,6 +135,7 @@ attr_copy_file(const char *src_path, con quote_free (ctx, qname); quote_free (ctx, qpath); ret = -1; + continue; } if (lsetxattr (dst_path, name, value, size, 0) != 0) { if (errno == ENOTSUP) Index: attr-2.4.28/libattr/attr_copy_check.c =================================================================== --- attr-2.4.28.orig/libattr/attr_copy_check.c +++ attr-2.4.28/libattr/attr_copy_check.c @@ -23,32 +23,6 @@ int attr_copy_check_permissions(const char *name, struct error_context *ctx) { - /* Skip POSIX ACLs. */ - if (strncmp(name, "system.posix_acl_", 17) == 0 && - (strcmp(name+17, "access") == 0 || - strcmp(name+17, "default") == 0)) - return 0; - - /* Skip permissions attributes which are used on IRIX, and - hence are part of the XFS ondisk format (incl. ACLs). - Also skip SGI DMF attributes as they are inappropriate - targets for copying over as well. */ - if (strncmp(name, "trusted.SGI_", 12) == 0 && - (strcmp(name+12, "ACL_DEFAULT") == 0 || - strcmp(name+12, "ACL_FILE") == 0 || - strcmp(name+12, "CAP_FILE") == 0 || - strcmp(name+12, "MAC_FILE") == 0 || - strncmp(name+12, "DMI_", 4) == 0)) - return 0; - - /* The xfsroot namespace mirrored attributes, some of which - are also also available via the system.* and trusted.* - namespaces. To avoid the problems this would cause, - we skip xfsroot altogether. - Note: xfsroot namespace has now been removed from XFS. */ - if (strncmp(name, "xfsroot.", 8) == 0) - return 0; - - return 1; + return attr_copy_action(name, ctx) == 0; } Index: attr-2.4.28/include/libattr.h =================================================================== --- attr-2.4.28.orig/include/libattr.h +++ attr-2.4.28/include/libattr.h @@ -14,9 +14,14 @@ extern int attr_copy_fd (const char *, i int (*) (const char *, struct error_context *), struct error_context *); -/* The default check function used by attr_copy_{fd,file}. */ +/* Keep this function for backwards compatibility. */ extern int attr_copy_check_permissions(const char *, struct error_context *); +#define ATTR_ACTION_SKIP 1 +#define ATTR_ACTION_PERMISSIONS 2 + +extern int attr_copy_action(const char *, struct error_context *); + #ifdef __cplusplus } #endif