diff options
author | Kamil Dudka <kdudka@redhat.com> | 2009-01-23 12:17:53 +0100 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2009-01-29 13:26:07 +0100 |
commit | 0889381cbfdbb4895e6b8693d14c0f5c77bc85bc (patch) | |
tree | 1c93168a0d0c7e5ff72df37c4b34607b0eb3aaea /src/copy.c | |
parent | 1bdf77ad523fca6f3781f5614706246f20394a62 (diff) | |
download | coreutils-0889381cbfdbb4895e6b8693d14c0f5c77bc85bc.tar.xz |
cp/mv: add xattr support
This patch was originally written by Andreas Grünbacher, nowadays
available at
http://www.suse.de/~agruen/coreutils/5.91/coreutils-xattr.diff
* bootstrap.conf: Add gnulib module verror.
* po/POTFILES.in: Add lib/verror.c.
* m4/xattr.m4: Check for libattr availability, new configure option
--disable-xattr.
* m4/prereq.m4: Require gl_FUNC_XATTR.
* src/Makefile.am: Link cp, mv and ginstall with libattr.
* src/copy.h: Add preserve_xattr and require_preserve_xattr to
cp_options.
* src/copy.c (copy_attr_error): New function to handle errors during
xattr copying.
(copy_attr_quote): New function to quote file name in error messages
printed by libattr.
(copy_attr_free): Empty function requested by libattr to free quoted
string.
(copy_attr_by_fd): New fd-oriented function to copy xattr.
(copy_attr_by_name): New name-oriented function to copy xattr.
(copy_reg, copy_internal): Call copy_extended_attributes function.
* src/cp.c (usage): Mention new --preserve=xattr option.
(decode_preserve_arg): Handle new --preserve=xattr option.
* src/mv.c: Always attempt to preserve xattr.
* src/install.c: Never attempt to preserve xattr.
* tests/misc/xattr: New test for xattr support in cp, mv and install.
* tests/Makefile.am: Add the new test to list.
* doc/coreutils.texi: Mention xattr support, new --preserve=xattr
option.
* NEWS: Mention the change.
Diffstat (limited to 'src/copy.c')
-rw-r--r-- | src/copy.c | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/src/copy.c b/src/copy.c index c9c79a1b1..85d1fea13 100644 --- a/src/copy.c +++ b/src/copy.c @@ -1,5 +1,5 @@ /* copy.c -- core functions for copying files and directories - Copyright (C) 89, 90, 91, 1995-2008 Free Software Foundation, Inc. + Copyright (C) 89, 90, 91, 1995-2009 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 @@ -54,6 +54,13 @@ #include "areadlink.h" #include "yesno.h" +#if USE_XATTR +# include <attr/error_context.h> +# include <attr/libattr.h> +# include <stdarg.h> +# include "verror.h" +#endif + #ifndef HAVE_FCHOWN # define HAVE_FCHOWN false # define fchown(fd, uid, gid) (-1) @@ -123,6 +130,72 @@ is_ancestor (const struct stat *sb, const struct dir_list *ancestors) return false; } +#if USE_XATTR +static void +copy_attr_error (struct error_context *ctx ATTRIBUTE_UNUSED, + char const *fmt, ...) +{ + int err = errno; + va_list ap; + + /* use verror module to print error message */ + va_start (ap, fmt); + verror (0, err, fmt, ap); + va_end (ap); +} + +static char const * +copy_attr_quote (struct error_context *ctx ATTRIBUTE_UNUSED, char const *str) +{ + return quote (str); +} + +static void +copy_attr_free (struct error_context *ctx ATTRIBUTE_UNUSED, + char const *str ATTRIBUTE_UNUSED) +{ +} + +static bool +copy_attr_by_fd (char const *src_path, int src_fd, + char const *dst_path, int dst_fd) +{ + struct error_context ctx = + { + .error = copy_attr_error, + .quote = copy_attr_quote, + .quote_free = copy_attr_free + }; + return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0, &ctx); +} + +static bool +copy_attr_by_name (char const *src_path, char const *dst_path) +{ + struct error_context ctx = + { + .error = copy_attr_error, + .quote = copy_attr_quote, + .quote_free = copy_attr_free + }; + return 0 == attr_copy_file (src_path, dst_path, 0, &ctx); +} +#else /* USE_XATTR */ + +static bool +copy_attr_by_fd (char const *src_path, int src_fd, + char const *dst_path, int dst_fd) +{ + return true; +} + +static bool +copy_attr_by_name (char const *src_path, char const *dst_path) +{ + 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 @@ -681,6 +754,11 @@ copy_reg (char const *src_name, char const *dst_name, set_author (dst_name, dest_desc, src_sb); + if (x->preserve_xattr && ! copy_attr_by_fd (src_name, source_desc, + dst_name, dest_desc) + && x->require_preserve_xattr) + return false; + if (x->preserve_mode || x->move_mode) { if (copy_acl (src_name, source_desc, dst_name, dest_desc, src_mode) != 0 @@ -1985,6 +2063,10 @@ copy_internal (char const *src_name, char const *dst_name, set_author (dst_name, -1, &src_sb); + if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name) + && x->require_preserve_xattr) + return false; + if (x->preserve_mode || x->move_mode) { if (copy_acl (src_name, -1, dst_name, -1, src_mode) != 0 |