summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Hajnal <trinitydesktop@alephnull.net>2022-12-21 21:17:36 -0500
committerAlexander Hajnal <trinitydesktop@alephnull.net>2022-12-21 21:17:36 -0500
commitc383a347ea1ca630aabaf15242f7bcdaf10632c9 (patch)
treedd6ed4fab349164e1b597f53feae694f96976c79
parent8d96e85f7d273da88361260f125db04f60971a9a (diff)
downloadtdelibs-c383a347ea1ca630aabaf15242f7bcdaf10632c9.tar.gz
tdelibs-c383a347ea1ca630aabaf15242f7bcdaf10632c9.zip
Adds user extended attribute copying support to libkio. See tdeio/tdeio/README.xattr for more info.
Signed-off-by: Alexander Hajnal <trinitydesktop@alephnull.net>
-rw-r--r--tdeio/tdeio/README.xattr86
-rw-r--r--tdeio/tdeio/job.cpp92
2 files changed, 178 insertions, 0 deletions
diff --git a/tdeio/tdeio/README.xattr b/tdeio/tdeio/README.xattr
new file mode 100644
index 000000000..8e18f529a
--- /dev/null
+++ b/tdeio/tdeio/README.xattr
@@ -0,0 +1,86 @@
+This is a small patch adding user extended attribute support[1] for local files
+to tdeio. With the patch in place user xattrs are preserved when copying or
+moving files on the local system[2]. It relies on libattr[3] to do the heavy
+lifting.
+
+The code adds a call to attr_copy_file in libattr that copies the user xattrs
+from the source file to the destination file. The call is made after the
+source file has been closed and immediately before the source file is deleted
+(in the case that a move is being done). This code is based on the sample
+code[4] provided with libattr (examples/copyattr.c).
+
+This code has been in daily use by the author of this patch for just over five
+years without any issues. What's missing though is the addition of tests for
+xattr and libattr support at configuration/compile time. The code I've added
+is enclosed by '#ifdef USE_XATTR' statements so a test should be added that
+sets this macro[5] if configure-time tests show that xattrs/libattr are working.
+I don't know how to go about adding such tests though so I've simply included a
+'#define USE_XATTR 1' statement to the top of the code. This should obviously
+be fixed before general release.
+
+This code has been tested on select Ubuntu Linux releases (natty, precise,
+xenial, and jammy) using x86_64 Linux kernels 3.14.1, 4.18.3, and 5.15.0.
+Tested filesystems are ext4 and squashfs.
+
+As far as cross-platform availability goes this code is only known to work on
+Linux[6][7]. That said, this code adds functionality that (as far as I'm aware)
+isn't currently present in TDE on any of the platforms it runs on. In other
+words, even if it only runs on Linux in its current state there is no loss of
+functionality on any other platforms (just a lack of a gaining a feature). In
+addition, determining the proper location to insert the library call was the
+hard part with the actual implementation being quite straightforward. Adding
+additional backends for other platforms should be pretty easy.
+
+To test the code build and install it[8] then run the following from the
+commandline in e.g. Konsole:
+
+ $ cd PATH_SUPPORTING_USER_XATTRS_AT_THE_FILESYSTEM_LEVEL
+ $ touch test
+ $ setfattr -n "user.AttributeName" -v "Attribute value" attr_test
+ $ kfmclient copy attr_test attr_test.copy
+ $ getfattr -d attr_test*
+
+The final command should output (minus the indents):
+
+ # file: attr_test
+ user.AttributeName="Attribute value"
+
+ # file: attr_test.copy
+ user.AttributeName="Attribute value"
+
+Enjoy!
+
+
+ - Alex Kent Hajnal (AKH) 2022-12-21
+
+
+
+[1] This includeds all attributes residing (on Linux) in the "user" namespace.
+ ACLs, etc. are not copied.
+
+ See the xattr(7) and e.g. the getfattr(1) manpages for more info.
+
+[2] The underlying filesytems must, of course, have xattr support enabled.
+ This should be the case by default on modern systems that support xattrs.
+
+[3] This is libattr1 and libattr1-dev on Ubuntu.
+
+ See http://savannah.nongnu.org/projects/attr for more info.
+ See also https://github.com/philips/attr
+
+[4] The code that this patch is based on is licensed GPL v2 (or later).
+
+[5] One has to use '#define USE_XATTR 1'; specifying '#define USE_XATTR'
+ doesn't enable the code (at least on my system).
+
+[6] I'm not sure which non-Linux platforms (if any) libattr runs on.
+
+
+[7] Another known issue is namespaces. Linux, FreeBSD, and NetBSD support
+ xattrs using the 'user' namespace. Solaris and OSX support user xattrs
+ but do not support namespaces.
+ (source: File::ExtAttr(3pm), personal testing)
+
+[8] Instead of doing a full install one can simply copy the updated library:
+
+ cp -va "BUILD_DIR/tdeio/libtdeio.so.14.0.0" /opt/trinity/lib/ && ldconfig
diff --git a/tdeio/tdeio/job.cpp b/tdeio/tdeio/job.cpp
index f6156a966..6f90bd213 100644
--- a/tdeio/tdeio/job.cpp
+++ b/tdeio/tdeio/job.cpp
@@ -2,6 +2,8 @@
Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
David Faure <faure@kde.org>
Waldo Bastian <bastian@kde.org>
+ Copyright (C) 2009 Andreas Gruenbacher <agruen@suse.de>
+ Copyright (C) 2022 Alexander Hajnal <trinitydesktop@alephnull.net>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -78,6 +80,88 @@ extern "C" {
#include <fixx11h.h>
#endif
+
+
+// Set this macro if libattr is installed and working
+#define USE_XATTR 1
+
+// Extended attribute support (added AKH 2017-11-26, updated AKH 2022-12-16)
+// Based on copyattr.c by Andreas Gruenbacher (included with libattr)
+// This does NOT also copy Access Control Lists!
+
+#ifdef USE_XATTR
+
+//#include <errno.h> // For errno (already included above)
+//#include <stdlib.h> // For free (already included above)
+//#include <string.h> // For errno, strdup, and strcmp (already implictly included above)
+#include <stdarg.h> // For va_start and va_end
+
+extern "C" {
+# include <attr/error_context.h>
+# include <attr/libattr.h>
+}
+
+/*
+ * Optional error handler for attr_copy_file(). CTX is the error
+ * context passed to attr_copy_file(), ERR is the errno value
+ * that occurred. FMT and the rest are printf style arguments.
+ */
+static void
+error(struct error_context *ctx, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (vfprintf(stderr, fmt, ap))
+ fprintf(stderr, ": ");
+ fprintf(stderr, "%s\n", strerror(errno));
+ va_end(ap);
+}
+
+/*
+ * Optional handler for quoting path names in error messages.
+ * (This is a very stupid example!)
+ */
+static const char *
+quote(struct error_context *ctx, const char *pathname)
+{
+ char *pn = strdup(pathname), *p;
+ pathname = strdup(pathname);
+ for (p = pn; *p != '\0'; p++)
+ if (*p & 0x80)
+ *p='?';
+ return pn;
+}
+
+static void
+quote_free(struct error_context *ctx, const char *name)
+{
+ free((void *)name);
+}
+
+/*
+ * The error context we pass to attr_copy_file().
+ */
+struct error_context ctx = { error, quote, quote_free };
+
+/*
+ * Optional attribute filter for attr_copy_file(). This example
+ * excludes all attributes other than extended user attributes.
+ *
+ * This function isn't used by the current code.
+ */
+static int is_user_attr(const char *name, struct error_context *ctx)
+{
+ // Note that non-Linux systems (including Solaris and Darwin/OSX) may
+ // use a different naming scheme for user attributes. AFAIK FreeBSD
+ // and NetBSD do support the "user" namespace.
+ return strcmp(name, "user.") == 0;
+}
+
+#endif /* USE_XATTR */
+
+
+
using namespace TDEIO;
template class TQPtrList<TDEIO::Job>;
@@ -1958,6 +2042,14 @@ void FileCopyJob::slotResult( TDEIO::Job *job)
if (job == m_copyJob)
{
m_copyJob = 0;
+
+#ifdef USE_XATTR
+ {
+ // Copy extended attributes (added AKH 2017-11-26)
+ attr_copy_file(TQFile::encodeName(m_src.path()), TQFile::encodeName(m_dest.path()), NULL, &ctx);
+ }
+#endif
+
if (m_move)
{
d->m_delJob = file_delete( m_src, false/*no GUI*/ ); // Delete source