coreutils/coreutils-xattr.diff

309 lines
9.6 KiB
Diff

Index: coreutils-6.2/configure.ac
================================================================================
--- coreutils-6.9.89.48-96961/configure.ac
+++ coreutils-6.9.89.48-96961/configure.ac
@@ -325,6 +325,9 @@ CONFIG_STATUS_DEPENDENCIES='$(top_srcdir
AC_SUBST([CONFIG_STATUS_DEPENDENCIES])
############################################################################
+# Extended attribute copying.
+AC_FUNC_XATTR
+
AM_GNU_GETTEXT([external], [need-formatstring-macros])
AM_GNU_GETTEXT_VERSION([0.15])
--- coreutils-6.9.89.48-96961/doc/coreutils.texi
+++ coreutils-6.9.89.48-96961/doc/coreutils.texi
@@ -7087,6 +7087,8 @@ Preserve in the destination files
any links between corresponding source files.
@c Give examples illustrating how hard links are preserved.
@c Also, show how soft links map to hard links with -L and -H.
+@itemx xattrs
+Preserve extended attributes. (See /etc/xattr.conf.)
@itemx all
Preserve all file attributes.
Equivalent to specifying all of the above.
--- coreutils-6.9.89.48-96961/m4/xattr.m4
+++ coreutils-6.9.89.48-96961/m4/xattr.m4
@@ -0,0 +1,38 @@
+# xattr.m4 - check for Extended Attributes (Linux)
+
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# 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.
+
+# 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.
+
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+# Written by Andreas Gruenbacher.
+
+AC_DEFUN([AC_FUNC_XATTR],
+[
+ AC_CHECK_HEADERS(attr/error_context.h attr/libattr.h)
+ if test "$ac_cv_header_attr_libattr_h" = yes \
+ && test "$ac_cv_header_attr_error_context_h" = yes; then
+ use_xattr=1
+ else
+ use_xattr=0
+ fi
+ AC_DEFINE_UNQUOTED(USE_XATTR, $use_xattr,
+ [Define if you want extended attribute support.])
+ xattr_saved_LIBS=$LIBS
+ AC_SEARCH_LIBS(attr_copy_file, attr,
+ [test "$ac_cv_search_attr_copy_file" = "none required" || LIB_XATTR=$ac_cv_search_attr_copy_file])
+ AC_SUBST(LIB_XATTR)
+ AC_CHECK_FUNCS(attr_copy_file)
+ LIBS=$xattr_saved_LIBS
+])
--- coreutils-6.9.89.48-96961/src/Makefile.am
+++ coreutils-6.9.89.48-96961/src/Makefile.am
@@ -135,6 +135,10 @@ ginstall_LDADD += $(LIB_ACL)
stat_LDADD = $(LDADD) $(LIB_SELINUX)
+cp_LDADD += $(LIB_XATTR)
+mv_LDADD += $(LIB_XATTR)
+ginstall_LDADD += $(LIB_XATTR)
+
$(PROGRAMS): ../lib/libcoreutils.a
# Get the release year from ../lib/version-etc.c.
--- coreutils-6.9.89.48-96961/src/copy.c
+++ coreutils-6.9.89.48-96961/src/copy.c
@@ -56,6 +56,12 @@
#include "areadlink.h"
#include "yesno.h"
+#if USE_XATTR
+# include <stdarg.h>
+# include <attr/error_context.h>
+# include <attr/libattr.h>
+#endif
+
#ifndef HAVE_FCHOWN
# define HAVE_FCHOWN false
# define fchown(fd, uid, gid) (-1)
@@ -113,6 +119,98 @@ is_ancestor (const struct stat *sb, cons
return false;
}
+#if USE_XATTR
+static void
+copy_xattr_error (struct error_context *ctx, const char *fmt, ...)
+{
+ int err = errno;
+ va_list ap;
+ int len;
+ char *buffer;
+
+ /* There is no error function that takes a va_list argument,
+ so we print the message in a buffer first. */
+
+ va_start (ap, fmt);
+ len = vsnprintf (NULL, 0, fmt, ap);
+ va_end (ap);
+ if (len > 0)
+ {
+ buffer = xmalloc (len + 1);
+ va_start (ap, fmt);
+ vsnprintf (buffer, len + 1, fmt, ap);
+ va_end (ap);
+ error (0, err, "%s", buffer);
+ free (buffer);
+ }
+}
+
+static const char *
+copy_xattr_quote (struct error_context *ctx, const char *str)
+{
+ return xstrdup (quote (str));
+}
+
+static void
+copy_xattr_free (struct error_context *ctx, const char *str)
+{
+ free ((void *) str);
+}
+
+struct copy_xattr_context {
+ struct error_context ctx;
+ struct cp_options *x;
+};
+
+static int
+copy_xattr_filter (const char *name, struct error_context *ctx)
+{
+ struct copy_xattr_context *copy_ctx = (struct copy_xattr_context *) ctx;
+ int action;
+
+ /* We handle POSIX ACLs separately. */
+ if (!strcmp(name, "system.posix_acl_access")
+ || !strcmp(name, "system.posix_acl_default"))
+ return 0;
+
+ action = attr_copy_action(name, ctx);
+ return (action != ATTR_ACTION_SKIP &&
+ (!copy_ctx->x->preserve_mode
+ || action != ATTR_ACTION_PERMISSIONS));
+}
+#endif /* USE_XATTR */
+
+static bool
+copy_xattrs (const char *src_path, int source_desc, const char *dst_path,
+ int dest_desc, const struct cp_options *x)
+{
+ struct copy_xattr_context copy_xattr_ctx = {
+ { copy_xattr_error,
+ copy_xattr_quote,
+ copy_xattr_free },
+ x
+ };
+
+#if USE_XATTR
+ if (x->preserve_xattrs)
+ {
+ int ret;
+
+ if (source_desc != -1 && dest_desc != -1)
+ ret = attr_copy_fd(src_path, source_desc, dst_path, dest_desc,
+ copy_xattr_filter, &copy_xattr_ctx.ctx);
+ else
+ ret = attr_copy_file (src_path, dst_path,
+ copy_xattr_filter, &copy_xattr_ctx.ctx);
+ return ret == 0 || !x->require_preserve;
+ }
+ else
+ return true;
+#else /* USE_XATTR */
+ return true;
+#endif /* USE_XATTR */
+}
+
/* Read the contents of the directory SRC_NAME_IN, and recursively
copy the contents to DST_NAME_IN. NEW_DST is true if
DST_NAME_IN is a directory that was created previously in the
@@ -640,6 +738,9 @@ copy_reg (char const *src_name, char con
}
}
+ if (!copy_xattrs (src_name, source_desc, dst_name, dest_desc, x))
+ return_val = false;
+
set_author (dst_name, dest_desc, src_sb);
if (x->preserve_mode || x->move_mode)
@@ -1939,6 +2040,9 @@ copy_internal (char const *src_name, cha
}
}
+ if (!copy_xattrs (src_name, -1, dst_name, -1, x))
+ delayed_ok = false;
+
set_author (dst_name, -1, &src_sb);
if (x->preserve_mode || x->move_mode)
--- coreutils-6.9.89.48-96961/src/copy.h
+++ coreutils-6.9.89.48-96961/src/copy.h
@@ -134,6 +134,9 @@ struct cp_options
bool preserve_mode;
bool preserve_timestamps;
+ /* If true, attempt to copy extended attributes. */
+ bool preserve_xattrs;
+
/* Enabled for mv, and for cp by the --preserve=links option.
If true, attempt to preserve in the destination files any
logical hard links between the source files. If used with cp's
--- coreutils-6.9.89.48-96961/src/cp.c
+++ coreutils-6.9.89.48-96961/src/cp.c
@@ -197,7 +197,8 @@ Mandatory arguments to long options are
-p same as --preserve=mode,ownership,timestamps\n\
--preserve[=ATTR_LIST] preserve the specified attributes (default:\n\
mode,ownership,timestamps), if possible\n\
- additional attributes: context, links, all\n\
+ additional attributes: context, links,\n\
+ xattrs, all\n\
"), stdout);
fputs (_("\
--no-preserve=ATTR_LIST don't preserve the specified attributes\n\
@@ -751,6 +752,7 @@ cp_option_init (struct cp_options *x)
x->preserve_links = false;
x->preserve_mode = false;
x->preserve_timestamps = false;
+ x->preserve_xattrs = false;
x->preserve_security_context = false;
x->require_preserve_context = false;
@@ -788,19 +790,21 @@ decode_preserve_arg (char const *arg, st
PRESERVE_TIMESTAMPS,
PRESERVE_OWNERSHIP,
PRESERVE_LINK,
+ PRESERVE_XATTRS,
PRESERVE_CONTEXT,
PRESERVE_ALL
};
static enum File_attribute const preserve_vals[] =
{
PRESERVE_MODE, PRESERVE_TIMESTAMPS,
- PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_ALL
+ PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_XATTRS, PRESERVE_CONTEXT,
+ PRESERVE_ALL
};
/* Valid arguments to the `--preserve' option. */
static char const* const preserve_args[] =
{
"mode", "timestamps",
- "ownership", "links", "context", "all", NULL
+ "ownership", "links", "xattrs", "context", "all", NULL
};
ARGMATCH_VERIFY (preserve_args, preserve_vals);
@@ -836,6 +840,10 @@ decode_preserve_arg (char const *arg, st
x->preserve_links = on_off;
break;
+ case PRESERVE_XATTRS:
+ x->preserve_xattrs = on_off;
+ break;
+
case PRESERVE_CONTEXT:
x->preserve_security_context = on_off;
x->require_preserve_context = on_off;
@@ -846,6 +854,7 @@ decode_preserve_arg (char const *arg, st
x->preserve_timestamps = on_off;
x->preserve_ownership = on_off;
x->preserve_links = on_off;
+ x->preserve_xattrs = on_off;
if (selinux_enabled)
x->preserve_security_context = on_off;
break;
--- coreutils-6.9.89.48-96961/src/install.c
+++ coreutils-6.9.89.48-96961/src/install.c
@@ -176,6 +176,7 @@ cp_option_init (struct cp_options *x)
x->preserve_links = false;
x->preserve_mode = false;
x->preserve_timestamps = false;
+ x->preserve_xattrs = false;
x->require_preserve = false;
x->require_preserve_context = false;
x->recursive = false;
--- coreutils-6.9.89.48-96961/src/mv.c
+++ coreutils-6.9.89.48-96961/src/mv.c
@@ -136,6 +136,7 @@ cp_option_init (struct cp_options *x)
x->preserve_links = true;
x->preserve_mode = true;
x->preserve_timestamps = true;
+ x->preserve_xattrs = true;
x->preserve_security_context = selinux_enabled;
x->require_preserve = false; /* FIXME: maybe make this an option */
x->require_preserve_context = false;