diff options
author | Philippe Mavridis <philippe.mavridis@yandex.com> | 2025-06-24 16:52:05 +0300 |
---|---|---|
committer | Philippe Mavridis <philippe.mavridis@yandex.com> | 2025-08-03 12:48:27 +0300 |
commit | 05da60e3b03b35a1f7aa537be39376350225e936 (patch) | |
tree | a54a6e6a7ade33be4156848b228447d4993f5446 /tdeioslave | |
parent | 2e76346c68e5c1db6b6058014c024bb70fec5e34 (diff) | |
download | tdelibs-feat/extended-attributes.tar.gz tdelibs-feat/extended-attributes.zip |
Add basic extended attributes supportfeat/extended-attributes
This commit adds extended attributes support to TDEIO, UDS, tdeio_file and a read-write plugin for the file properties dialog.
It also adds attribute display support to TDEFileItem, used by KDesktop and Konqueror to show file tooltips.
Signed-off-by: Philippe Mavridis <philippe.mavridis@yandex.com>
Diffstat (limited to 'tdeioslave')
-rw-r--r-- | tdeioslave/file/file.cpp | 146 | ||||
-rw-r--r-- | tdeioslave/file/file.h | 13 | ||||
-rw-r--r-- | tdeioslave/file/file.protocol | 2 |
3 files changed, 150 insertions, 11 deletions
diff --git a/tdeioslave/file/file.cpp b/tdeioslave/file/file.cpp index 162f8a848..1a2c5183c 100644 --- a/tdeioslave/file/file.cpp +++ b/tdeioslave/file/file.cpp @@ -94,6 +94,7 @@ #include <klargefile.h> #include <tdeglobal.h> #include <kmimetype.h> +#include <tdexattr.h> using namespace TDEIO; @@ -106,6 +107,7 @@ static bool isExtendedACL( acl_t p_acl ); static void appendACLAtoms( const TQCString & path, UDSEntry& entry, mode_t type, bool withACL ); #endif +static void appendAttributeAtom(const TQString& filename, const TQString& path, UDSEntry& entry); extern "C" { TDE_EXPORT int kdemain(int argc, char **argv); } @@ -360,7 +362,7 @@ write_all(int fd, const char *buf, size_t len) return 0; } -static bool +static bool same_inode(const KDE_struct_stat &src, const KDE_struct_stat &dest) { if (src.st_ino == dest.st_ino && @@ -626,7 +628,7 @@ void FileProtocol::copy( const KURL &src, const KURL &dest, return; } - if ( same_inode( buff_dest, buff_src) ) + if ( same_inode( buff_dest, buff_src) ) { error( TDEIO::ERR_IDENTICAL_FILES, dest.path() ); return; @@ -839,7 +841,7 @@ void FileProtocol::rename( const KURL &src, const KURL &dest, return; } - if ( same_inode( buff_dest, buff_src) ) + if ( same_inode( buff_dest, buff_src) ) { error( TDEIO::ERR_IDENTICAL_FILES, dest.path() ); return; @@ -955,6 +957,87 @@ void FileProtocol::del( const KURL& url, bool isfile) finished(); } +void FileProtocol::listAttr( const KURL& url, const TQCString &ns ) +{ + if (!TDEXAttr::readSupported(url, ns)) + { + error(TDEIO::ERR_ACCESS_DENIED, url.path()); + return; + } + + TQValueList<TQCString> attrs; + int result = TDEXAttr::list(url, ns, &attrs); + if (result != 0) + { + error(result, url.path()); + return; + } + TQValueList<TQCString>::iterator it; + for (it = attrs.begin(); it != attrs.end(); ++it) + { + TQByteArray d; + TQDataStream s(d, IO_WriteOnly); + s << (*it); + data(d); + } + finished(); +} + +void FileProtocol::readAttr( const KURL& url, const TQCString &ns, const TQCString& attr ) +{ + if (!TDEXAttr::readSupported(url, ns)) + { + error(TDEIO::ERR_ACCESS_DENIED, url.path()); + return; + } + + TQCString value; + int result = TDEXAttr::read(url, ns, attr, &value); + if (result != 0) + { + error(result, url.path()); + } + else + { + TQByteArray d; + TQDataStream s(d, IO_WriteOnly); + s << value; + data(d); + finished(); + } +} + +void FileProtocol::writeAttr( const KURL& url, const TQCString &ns, const TQCString& attr, const TQCString& value ) +{ + if (!TDEXAttr::writeSupported(url, ns)) + { + error(TDEIO::ERR_WRITE_ACCESS_DENIED, url.path()); + return; + } + + int result = TDEXAttr::write(url, ns, attr, value); + if (result != 0) + { + error(result, url.path()); + } + else finished(); +} + +void FileProtocol::removeAttr( const KURL& url, const TQCString &ns, const TQCString& attr ) +{ + if (!TDEXAttr::writeSupported(url, ns)) + { + error(TDEIO::ERR_WRITE_ACCESS_DENIED, url.path()); + return; + } + + int result = TDEXAttr::remove(url, ns, attr); + if (result != 0) + { + error(result, url.path()); + } + finished(); +} TQString FileProtocol::getUserName( uid_t uid ) { @@ -990,10 +1073,8 @@ TQString FileProtocol::getGroupName( gid_t gid ) return *temp; } - - -bool FileProtocol::createUDSEntry( const TQString & filename, const TQCString & path, UDSEntry & entry, - short int details, bool withACL ) +bool FileProtocol::createUDSEntry( const TQString & filename, const TQCString & path, const TQString & absPath, + UDSEntry & entry, short int details, bool withACL ) { assert(entry.count() == 0); // by contract :-) // Note: details = 0 (only "file or directory or symlink or doesn't exist") isn't implemented @@ -1071,6 +1152,8 @@ bool FileProtocol::createUDSEntry( const TQString & filename, const TQCString & appendACLAtoms( path, entry, type, withACL ); #endif + appendAttributeAtom(filename, absPath, entry); + notype: atom.m_uds = TDEIO::UDS_MODIFICATION_TIME; atom.m_long = buff.st_mtime; @@ -1120,7 +1203,7 @@ void FileProtocol::stat( const KURL & url ) kdDebug(7101) << "FileProtocol::stat details=" << details << endl; UDSEntry entry; - if ( !createUDSEntry( url.fileName(), _path, entry, details, true /*with acls*/ ) ) + if ( !createUDSEntry( url.fileName(), _path, url.upURL().path(), entry, details, true /*with acls*/ ) ) { error( TDEIO::ERR_DOES_NOT_EXIST, url.path(-1) ); return; @@ -1256,6 +1339,7 @@ void FileProtocol::listDir( const KURL& url) entry.clear(); if ( createUDSEntry( TQFile::decodeName(*it), *it /* we can use the filename as relative path*/, + _path, entry, 2, true ) ) listEntry( entry, false); //else @@ -1887,4 +1971,50 @@ static void appendACLAtoms( const TQCString & path, UDSEntry& entry, mode_t type } #endif +static void +appendAttributeAtom(const TQString& filename, const TQString& path, UDSEntry& entry) +{ + KURL url(path); + url.addPath(filename); + url.cleanPath(); + +// if (!TDEXAttr::readSupported(url, "user")) +// { +// kdWarning() << "attributes read not supported" << endl; +// return; +// } + + TQString serialized; + + TQValueList<TQCString> attrs; + int result = TDEXAttr::list(url, "user", &attrs); + if (result != 0) + { + kdWarning() << "no attributes" << endl; + return; + } + + TQValueList<TQCString>::iterator it; + TQChar us((char)31), rs((char)30); + for (it = attrs.begin(); it != attrs.end(); ++it) + { + TQCString key(*it); + TQCString value; + + int result = TDEXAttr::read(url, "user", key, &value); + if (result == 0) + { + serialized += TQString::fromLocal8Bit(key).remove(us).remove(rs); + serialized += us; + serialized += TQString::fromLocal8Bit(value).remove(us).remove(rs); + serialized += rs; + } + } + + UDSAtom atom; + atom.m_uds = TDEIO::UDS_ATTRIBUTES; + atom.m_str = serialized; + entry.append(atom); +} + #include "file.moc" diff --git a/tdeioslave/file/file.h b/tdeioslave/file/file.h index 04a6ed225..5ebde9e7c 100644 --- a/tdeioslave/file/file.h +++ b/tdeioslave/file/file.h @@ -62,6 +62,13 @@ public: virtual void mkdir( const KURL& url, int permissions ); virtual void chmod( const KURL& url, int permissions ); virtual void del( const KURL& url, bool isfile); + virtual void listAttr( const KURL& url, const TQCString &ns ); + virtual void readAttr( const KURL& url, const TQCString &ns, + const TQCString& attr ); + virtual void writeAttr( const KURL& url, const TQCString &ns, + const TQCString& attr, const TQCString& value ); + virtual void removeAttr( const KURL& url, const TQCString &ns, + const TQCString& attr ); /** * Special commands supported by this slave: @@ -81,10 +88,10 @@ protected slots: protected: - bool createUDSEntry( const TQString & filename, const TQCString & path, TDEIO::UDSEntry & entry, - short int details, bool withACL ); + bool createUDSEntry( const TQString & filename, const TQCString & path, const TQString & absPath, + TDEIO::UDSEntry & entry, short int details, bool withACL ); int setACL( const char *path, mode_t perm, bool _directoryDefault ); - + TQString getUserName( uid_t uid ); TQString getGroupName( gid_t gid ); diff --git a/tdeioslave/file/file.protocol b/tdeioslave/file/file.protocol index 14f17e033..26ed30a6e 100644 --- a/tdeioslave/file/file.protocol +++ b/tdeioslave/file/file.protocol @@ -10,6 +10,8 @@ makedir=true deleting=true linking=true moving=true +readattr=true +writeattr=true maxInstances=4 X-DocPath=tdeioslave/file/index.html Class=:local |