Adds user extended attribute copying support to libkio. See tdeio/tdeio/README.xattr for more info.

Signed-off-by: Alexander Hajnal <trinitydesktop@alephnull.net>
feat/tdeio-xattr-support
Alexander Hajnal 2 years ago
parent 8d96e85f7d
commit c383a347ea
No known key found for this signature in database
GPG Key ID: 5050665AA3F08058

@ -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

@ -2,6 +2,8 @@
Copyright (C) 2000 Stephan Kulow <coolo@kde.org> Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
David Faure <faure@kde.org> David Faure <faure@kde.org>
Waldo Bastian <bastian@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 This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public modify it under the terms of the GNU Library General Public
@ -78,6 +80,88 @@ extern "C" {
#include <fixx11h.h> #include <fixx11h.h>
#endif #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; using namespace TDEIO;
template class TQPtrList<TDEIO::Job>; template class TQPtrList<TDEIO::Job>;
@ -1958,6 +2042,14 @@ void FileCopyJob::slotResult( TDEIO::Job *job)
if (job == m_copyJob) if (job == m_copyJob)
{ {
m_copyJob = 0; 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) if (m_move)
{ {
d->m_delJob = file_delete( m_src, false/*no GUI*/ ); // Delete source d->m_delJob = file_delete( m_src, false/*no GUI*/ ); // Delete source

Loading…
Cancel
Save