As reported in
http://lists.gnu.org/archive/html/bug-coreutils/2009-08/msg00342.html by
Ernest N. Mamikonyan, cp/mv fails to preserve extended attributes for
read-only source files.
Following patch fixes the issue for me, although maybe it's not perfect
solution. But I don't know about better one at the moment.
Test included...

Greetings,
         Ondřej Vašík
From cae691907fe50e2ab05198a7c647fe4140e3669e Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= <[email protected]>
Date: Thu, 3 Sep 2009 16:10:21 +0200
Subject: [PATCH] cp,mv: do preserve extended attributes even for read-only source files

* src/copy.c (copy_reg): Set mode on file descriptor to 0600 for copying
 extended attributes to prevent failures when source file doesn't have
 write access rights (reported by Ernest N. Mamikonyan)
* tests/misc/xattr: test that change
* NEWS: mention that change
---
 NEWS             |    4 ++++
 src/copy.c       |   24 ++++++++++++++++++++----
 tests/misc/xattr |    7 +++++++
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index 59270eb..8c511c6 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   cp --preserve=xattr no longer leaks resources on each preservation failure.
   [bug introduced in coreutils-7.1]
 
+  cp --preserve=xattr and --archive now preserves extended attributes even
+  when the source file doesn't have write access rights
+  [bug introduced in coreutils-7.1]
+
   dd now returns non-zero status if it encountered a write error while
   printing a summary to stderr.
   [bug introduced in coreutils-6.11]
diff --git a/src/copy.c b/src/copy.c
index e604ec5..b645a9a 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -850,10 +850,26 @@ 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)
-      && x->require_preserve_xattr)
-    return_val = false;
+  /* to allow copying extended attributes on read-only files, change
+     destination file descriptor access rights to 0600 for a while. */
+  if (x->preserve_xattr)
+   {
+     if (! fchmod_or_lchmod (dest_desc, dst_name, 0600))
+       {
+         if (! copy_attr_by_fd (src_name, source_desc, dst_name, dest_desc, x)
+            && x->require_preserve_xattr)
+           return_val = false;
+       }
+     else
+       {
+          if (!x->reduce_diagnostics || x->require_preserve_xattr)
+            error (0, errno, _("can't write extended attributes to %s"),
+                   quote (dst_name));
+          if (x->require_preserve_xattr)
+            return_val = false;
+       }
+    }
+
 
   if (x->preserve_mode || x->move_mode)
     {
diff --git a/tests/misc/xattr b/tests/misc/xattr
index a27e1f6..828e871 100755
--- a/tests/misc/xattr
+++ b/tests/misc/xattr
@@ -77,6 +77,13 @@ cp -a a d 2>err && test -s err && fail=1
 getfattr -d d >out_d || skip_test_ "failed to get xattr of file"
 grep -F "$xattr_pair" out_d >/dev/null || fail=1
 
+#test if --preserve=xattr works even for files without write rights
+chmod a-w a || framework_failure
+cp --preserve=xattr a e || fail=1
+getfattr -d e >out_e || skip_test_ "failed to get xattr of file"
+grep -F  "$xattr_pair" out_e >/dev/null || fail=1
+chmod a+w a || framework_failure
+
 rm b || framework_failure
 
 # install should never preserve xattr
-- 
1.5.6.1.156.ge903b

Attachment: signature.asc
Description: Toto je digitálně podepsaná část zprávy

Reply via email to