forked from pool/coreutils
322 lines
9.7 KiB
Diff
322 lines
9.7 KiB
Diff
|
Index: coreutils-6.2/configure.ac
|
||
|
===================================================================
|
||
|
--- coreutils-6.2.orig/configure.ac
|
||
|
+++ coreutils-6.2/configure.ac
|
||
|
@@ -246,6 +246,9 @@ AC_CHECK_DECLS([strtoimax, strtoumax])
|
||
|
|
||
|
cu_LIB_CHECK
|
||
|
|
||
|
+# Extended attribute copying.
|
||
|
+AC_FUNC_XATTR
|
||
|
+
|
||
|
AM_GNU_GETTEXT([external], [need-formatstring-macros])
|
||
|
AM_GNU_GETTEXT_VERSION([0.15])
|
||
|
|
||
|
Index: coreutils-6.2/m4/xattr.m4
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ coreutils-6.2/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
|
||
|
+])
|
||
|
Index: coreutils-6.2/src/Makefile.am
|
||
|
===================================================================
|
||
|
--- coreutils-6.2.orig/src/Makefile.am
|
||
|
+++ coreutils-6.2/src/Makefile.am
|
||
|
@@ -112,6 +112,10 @@ cp_LDADD += $(LIB_ACL)
|
||
|
mv_LDADD += $(LIB_ACL)
|
||
|
ginstall_LDADD += $(LIB_ACL)
|
||
|
|
||
|
+cp_LDADD += $(LIB_XATTR)
|
||
|
+mv_LDADD += $(LIB_XATTR)
|
||
|
+ginstall_LDADD += $(LIB_XATTR)
|
||
|
+
|
||
|
$(PROGRAMS): ../lib/libcoreutils.a
|
||
|
|
||
|
SUFFIXES = .sh
|
||
|
Index: coreutils-6.2/src/copy.c
|
||
|
===================================================================
|
||
|
--- coreutils-6.2.orig/src/copy.c
|
||
|
+++ coreutils-6.2/src/copy.c
|
||
|
@@ -53,6 +53,12 @@
|
||
|
#include "xreadlink.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)
|
||
|
@@ -118,6 +124,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, ©_xattr_ctx.ctx);
|
||
|
+ else
|
||
|
+ ret = attr_copy_file (src_path, dst_path,
|
||
|
+ copy_xattr_filter, ©_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
|
||
|
@@ -509,6 +607,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)
|
||
|
@@ -1755,6 +1856,9 @@ copy_internal (char const *src_name, cha
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
+ 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)
|
||
|
Index: coreutils-6.2/src/copy.h
|
||
|
===================================================================
|
||
|
--- coreutils-6.2.orig/src/copy.h
|
||
|
+++ coreutils-6.2/src/copy.h
|
||
|
@@ -128,6 +128,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
|
||
|
Index: coreutils-6.2/src/cp.c
|
||
|
===================================================================
|
||
|
--- coreutils-6.2.orig/src/cp.c
|
||
|
+++ coreutils-6.2/src/cp.c
|
||
|
@@ -191,7 +191,7 @@ 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: links, all\n\
|
||
|
+ additional attributes: links, xattrs, all\n\
|
||
|
"), stdout);
|
||
|
fputs (_("\
|
||
|
--no-preserve=ATTR_LIST don't preserve the specified attributes\n\
|
||
|
@@ -724,6 +724,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->recursive = false;
|
||
|
@@ -752,18 +753,21 @@ decode_preserve_arg (char const *arg, st
|
||
|
PRESERVE_TIMESTAMPS,
|
||
|
PRESERVE_OWNERSHIP,
|
||
|
PRESERVE_LINK,
|
||
|
+ PRESERVE_XATTRS,
|
||
|
PRESERVE_ALL
|
||
|
};
|
||
|
static enum File_attribute const preserve_vals[] =
|
||
|
{
|
||
|
PRESERVE_MODE, PRESERVE_TIMESTAMPS,
|
||
|
- PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_ALL
|
||
|
+ PRESERVE_OWNERSHIP, PRESERVE_LINK,
|
||
|
+ PRESERVE_XATTRS, PRESERVE_ALL
|
||
|
};
|
||
|
/* Valid arguments to the `--preserve' option. */
|
||
|
static char const* const preserve_args[] =
|
||
|
{
|
||
|
"mode", "timestamps",
|
||
|
- "ownership", "links", "all", NULL
|
||
|
+ "ownership", "links",
|
||
|
+ "xattrs", "all", NULL
|
||
|
};
|
||
|
ARGMATCH_VERIFY (preserve_args, preserve_vals);
|
||
|
|
||
|
@@ -799,11 +803,16 @@ decode_preserve_arg (char const *arg, st
|
||
|
x->preserve_links = on_off;
|
||
|
break;
|
||
|
|
||
|
+ case PRESERVE_XATTRS:
|
||
|
+ x->preserve_xattrs = on_off;
|
||
|
+ break;
|
||
|
+
|
||
|
case PRESERVE_ALL:
|
||
|
x->preserve_mode = on_off;
|
||
|
x->preserve_timestamps = on_off;
|
||
|
x->preserve_ownership = on_off;
|
||
|
x->preserve_links = on_off;
|
||
|
+ x->preserve_xattrs = on_off;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
Index: coreutils-6.2/src/install.c
|
||
|
===================================================================
|
||
|
--- coreutils-6.2.orig/src/install.c
|
||
|
+++ coreutils-6.2/src/install.c
|
||
|
@@ -154,6 +154,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->recursive = false;
|
||
|
x->sparse_mode = SPARSE_AUTO;
|
||
|
Index: coreutils-6.2/src/mv.c
|
||
|
===================================================================
|
||
|
--- coreutils-6.2.orig/src/mv.c
|
||
|
+++ coreutils-6.2/src/mv.c
|
||
|
@@ -125,6 +125,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->require_preserve = false; /* FIXME: maybe make this an option */
|
||
|
x->recursive = true;
|
||
|
x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */
|
||
|
Index: coreutils-6.2/doc/coreutils.texi
|
||
|
===================================================================
|
||
|
--- coreutils-6.2.orig/doc/coreutils.texi
|
||
|
+++ coreutils-6.2/doc/coreutils.texi
|
||
|
@@ -6948,6 +6948,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.
|