[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: cp and mv with -p preserve xattrs
From: Dmitry Falko <dfalko () digiflak ! com>
Date: 2014-09-29 9:31:30
Message-ID: 542926F2.7020304 () digiflak ! com
[Download RAW message or body]
Hello to all!
On the work required to copy files with extended attributes, busybox
cp(and mv), unfortunately, unlike the older brother did not know how to
copy extended attributes, so I wrote a patch copying extended attributes
(if the call command with the option -p), maybe it will be useful.
Perhaps the quality of the patch is not entirely satisfactory, so
waiting for the critics.
From 5782979527f9498b7d39f4a63dbf05483fe66c5d Mon Sep 17 00:00:00 2001
From: Dmitry Falko <dfalko@digiflak.com>
Date: Mon, 29 Sep 2014 11:38:15 +0400
Subject: [PATCH] add feature copy xattrs of file if set flag preserve status
to mv, cp
---
include/libbb.h | 5 +-
libbb/Config.src | 6 +++
libbb/Kbuild.src | 1 +
libbb/copy_file.c | 7 +++
libbb/copy_file_attr.c | 118
++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 136 insertions(+), 1 deletion(-)
create mode 100644 libbb/copy_file_attr.c
diff --git a/include/libbb.h b/include/libbb.h
index e520060..4a16542 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -343,6 +343,10 @@ extern int remove_file(const char *path, int flags)
FAST_FUNC;
* work coreutils-compatibly. */
extern int copy_file(const char *source, const char *dest, int flags)
FAST_FUNC;
+#if ENABLE_XATTR
+extern int copy_file_attr(const char *src_path, int src_fd, const char
*dst_path, int dst_fd) FAST_FUNC;
+#endif
+
enum {
ACTION_RECURSE = (1 << 0),
ACTION_FOLLOWLINKS = (1 << 1),
@@ -1262,7 +1266,6 @@ extern void selinux_preserve_fcontext(int fdesc)
FAST_FUNC;
#endif
extern void selinux_or_die(void) FAST_FUNC;
-
/* systemd support */
#define SD_LISTEN_FDS_START 3
int sd_listen_fds(void);
diff --git a/libbb/Config.src b/libbb/Config.src
index 19021fe..8615cb2 100644
--- a/libbb/Config.src
+++ b/libbb/Config.src
@@ -232,4 +232,10 @@ config FEATURE_HWIB
Support for printing infiniband addresses in
network applets.
+config XATTR
+ bool "Support preserve extended attributes for cp command"
+ default y
+ help
+ Support preserve extended attributes for cp and mv command.
+
endmenu
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 61eec26..ec13b96 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -172,6 +172,7 @@ lib-$(CONFIG_TRACEROUTE6) += inet_cksum.o
lib-$(CONFIG_UDHCPC) += inet_cksum.o
lib-$(CONFIG_UDHCPC6) += inet_cksum.o
lib-$(CONFIG_UDHCPD) += inet_cksum.o
+lib-$(CONFIG_XATTR) += copy_file_attr.o
# We shouldn't build xregcomp.c if we don't need it - this ensures we
don't
# require regex.h to be in the include dir even if we don't need it
thereby
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index 9333a8d..6904e2b 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -314,6 +314,13 @@ int FAST_FUNC copy_file(const char *source, const
char *dest, int flags)
}
}
#endif
+#if ENABLE_XATTR
+ /* Preserve extended attributes */
+ if(flags & FILEUTILS_PRESERVE_STATUS &&
+ copy_file_attr(source, src_fd, dest, dst_fd) == -1) {
+ return -1;
+ }
+#endif
if (bb_copyfd_eof(src_fd, dst_fd) == -1)
retval = -1;
/* Careful with writing... */
diff --git a/libbb/copy_file_attr.c b/libbb/copy_file_attr.c
new file mode 100644
index 0000000..2e0c295
--- /dev/null
+++ b/libbb/copy_file_attr.c
@@ -0,0 +1,118 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copy extended attributes between files
+ *
+ * Copyright (C) 2014 Dmitry Falko <dfalko@digiflak.com>, digiFLAK
+ *
+ * based on libattr code, original copyright:
+ * Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#include "libbb.h"
+
+#if !defined(ENOTSUP)
+# define ENOTSUP (-1)
+#endif
+
+#if defined(HAVE_ALLOCA)
+# define bb_alloc(size) alloca (size)
+# define bb_free(ptr) do { } while(0)
+#else
+# define bb_alloc(size) xmalloc (size)
+# define bb_free(ptr) free (ptr)
+#endif
+
+/* Copy extended attributes from src_path to dst_path. If the file
+ has an extended Access ACL (system.posix_acl_access) and that is
+ copied successfully, the file mode permission bits are copied as
+ a side effect. This may not always the case, so the file mode
+ and/or ownership must be copied separately. */
+int FAST_FUNC copy_file_attr(const char *src_path, int src_fd,
+ const char *dst_path, int dst_fd)
+{
+ int ret = 0;
+ ssize_t size;
+ char *names = NULL, *end_names, *name, *value = NULL;
+ unsigned int setxattr_ENOTSUP = 0;
+
+ size = flistxattr (src_fd, NULL, 0);
+ if (size < 0) {
+ if (errno != ENOSYS && errno != ENOTSUP) {
+ bb_perror_msg("listing attributes of %s", src_path);
+ ret = -1;
+ }
+ goto getout;
+ }
+ names = (char *) bb_alloc (size+1);
+ if (names == NULL) {
+ bb_error_msg("cannot allocate buffer");
+ ret = -1;
+ goto getout;
+ }
+ size = flistxattr (src_fd, names, size);
+ if (size < 0) {
+ bb_error_msg("listing attributes of %s", src_path);
+ ret = -1;
+ goto getout;
+ } else {
+ names[size] = '\0';
+ end_names = names + size;
+ }
+
+ for (name = names; name != end_names; name = strchr(name, '\0') + 1) {
+ void *old_value;
+
+ if (!*name)
+ continue;
+
+ size = fgetxattr (src_fd, name, NULL, 0);
+ if (size < 0) {
+ bb_error_msg("getting attribute %s of %s",
+ src_path, name);
+ ret = -1;
+ continue;
+ }
+ value = (char *) xrealloc (old_value = value, size);
+ if (size != 0 && value == NULL) {
+ free(old_value);
+ bb_error_msg(" failed to realloc ");
+ ret = -1;
+ }
+ size = fgetxattr (src_fd, name, value, size);
+ if (size < 0) {
+ bb_error_msg("getting attribute %s of %s",
+ src_path, name);
+ ret = -1;
+ continue;
+ }
+ if (fsetxattr (dst_fd, name, value, size, 0) != 0) {
+ if (errno == ENOTSUP)
+ setxattr_ENOTSUP++;
+ else {
+ if (errno == ENOSYS) {
+ bb_error_msg("setting attributes for "
+ "%s", dst_path);
+ ret = -1;
+ break; /* no hope of getting any further */
+ } else {
+ bb_error_msg("setting attribute %s for %s",
+ name, dst_path);
+ ret = -1;
+ }
+ }
+ }
+ }
+ if (setxattr_ENOTSUP) {
+ errno = ENOTSUP;
+ /* ignore this error */
+ bb_error_msg("setting attributes for %s", dst_path);
+ ret = 0;
+ }
+getout:
+ free (value);
+ bb_free (names);
+ return ret;
+}
+
--
1.7.9.5
--
Best Regards, Dmitry!
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic