1717#include " common/asserts.h"
1818#include " common/utility.h"
1919#include " libsync/discoveryinfo.h"
20+ #include " libsync/xattr.h"
2021
2122#include < QCoreApplication>
2223#include < QDirIterator>
2829
2930#include < sys/stat.h>
3031
31- #if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
32- #include < sys/xattr.h>
33- #endif
34-
3532#ifdef Q_OS_WIN32
3633#include " common/utility_win.h"
3734#include < winsock2.h>
@@ -250,52 +247,25 @@ std::optional<uint64_t> FileSystem::getInode(const std::filesystem::path &filena
250247 return info.inode ();
251248}
252249
253- namespace {
254-
255- #ifdef Q_OS_LINUX
256- Q_ALWAYS_INLINE ssize_t getxattr (const char *path, const char *name, void *value, size_t size, u_int32_t , int )
257- {
258- return ::getxattr (path, name, value, size);
259- }
260-
261- Q_ALWAYS_INLINE int setxattr (const char *path, const char *name, const void *value, size_t size, u_int32_t , int )
262- {
263- return ::setxattr (path, name, value, size, 0 );
264- }
265-
266- Q_ALWAYS_INLINE int removexattr (const char *path, const char *name, int )
267- {
268- return ::removexattr (path, name);
269- }
270- #endif // Q_OS_LINUX
271-
272- } // anonymous namespace
273-
274- std::optional<QByteArray> FileSystem::Tags::get (const QString &path, const QString &key)
250+ std::optional<QString> FileSystem::Tags::get (const QString &path, const QString &key)
275251{
276252#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
277253 QString platformKey = key;
278254 if (Utility::isLinux ()) {
279255 platformKey = QStringLiteral (" user." ) + platformKey;
280256 }
281-
282- QByteArray value (MaxValueSize + 1 , ' \0 ' ); // Add a NUL character to terminate a string
283- auto size = getxattr (path.toUtf8 ().constData (), platformKey.toUtf8 ().constData (), value.data (), MaxValueSize, 0 , 0 );
284- if (size != -1 ) {
285- value.truncate (size);
286- return value;
287- }
257+ return Xattr::getxattr (toFilesystemPath (path), platformKey);
288258#elif defined(Q_OS_WIN)
289259 QFile file (QStringLiteral (" %1:%2" ).arg (path, key));
290260 if (file.open (QIODevice::ReadOnly)) {
291- return file.readAll ();
261+ return QString::fromUtf8 ( file.readAll () );
292262 }
293263#endif // Q_OS_MAC || Q_OS_LINUX
294264
295265 return {};
296266}
297267
298- OCC::Result<void , QString> FileSystem::Tags::set (const QString &path, const QString &key, const QByteArray &value)
268+ OCC::Result<void , QString> FileSystem::Tags::set (const QString &path, const QString &key, const QString &value)
299269{
300270 OC_ASSERT (value.size () < MaxValueSize)
301271
@@ -304,62 +274,44 @@ OCC::Result<void, QString> FileSystem::Tags::set(const QString &path, const QStr
304274 if (Utility::isLinux ()) {
305275 platformKey = QStringLiteral (" user." ) + platformKey;
306276 }
307-
308- auto result = setxattr (path.toUtf8 ().constData (), platformKey.toUtf8 ().constData (), value.constData (), value.size (), 0 , 0 );
309- if (result != 0 ) {
310- return QString::fromUtf8 (strerror (errno));
311- }
312-
313- return {};
277+ return Xattr::setxattr (toFilesystemPath (path), platformKey, value);
314278#elif defined(Q_OS_WIN)
315279 QFile file (QStringLiteral (" %1:%2" ).arg (path, key));
316280 if (!file.open (QIODevice::WriteOnly)) {
317281 return file.errorString ();
318282 }
319- auto bytesWritten = file.write (value);
320- if (bytesWritten != value.size ()) {
321- return QStringLiteral (" wrote %1 out of %2 bytes" ).arg (QString::number (bytesWritten), QString::number (value.size ()));
283+ const auto data = value.toUtf8 ();
284+ auto bytesWritten = file.write (data);
285+ if (bytesWritten != data.size ()) {
286+ return QStringLiteral (" wrote %1 out of %2 bytes" ).arg (QString::number (bytesWritten), QString::number (data.size ()));
322287 }
323288
324289 return {};
325290#else
326- return QStringLiteral ( " function not implemented" ) ;
291+ return u" Not implemented" _s ;
327292#endif // Q_OS_MAC || Q_OS_LINUX
328293}
329294
330- bool FileSystem::Tags::remove (const QString &path, const QString &key)
295+ OCC::Result< void , QString> FileSystem::Tags::remove (const QString &path, const QString &key)
331296{
332297#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
333298 QString platformKey = key;
334299 if (Utility::isLinux ()) {
335300 platformKey = QStringLiteral (" user.%1" ).arg (platformKey);
336301 }
337302
338- auto result = removexattr (path.toUtf8 ().constData (), platformKey.toUtf8 ().constData (), 0 );
339- if (result == 0 ) {
340- return true ;
341- }
342- #ifdef Q_OS_MAC
343- if (errno == ENOATTR) {
344- #else
345- if (errno == ENODATA) {
346- #endif
347- qCWarning (lcFileSystem) << u" Failed to remove tag" << key << u" from" << path << u" tag doesn't exist" ;
348- return true ;
349- }
350- qCWarning (lcFileSystem) << u" Failed to remove tag" << key << u" from" << path << u" :" << strerror (errno);
351- return false ;
303+ return Xattr::removexattr (toFilesystemPath (path), platformKey);
352304#elif defined(Q_OS_WIN)
353305 const auto fsPath = toFilesystemPath (u" %1:%2" _s.arg (path, key));
354306 std::error_code fileError;
355307 std::filesystem::remove (fsPath, fileError);
356308 if (fileError) {
357309 qCWarning (lcFileSystem) << u" Failed to remove tag" << key << u" from" << path << u" :" << fsPath << u" error:" << fileError.message ();
358- return false ;
310+ return QString::fromStdString (fileError. message ()) ;
359311 }
360- return true ;
312+ return {} ;
361313#else
362- return false ;
314+ return u" Not implemented " _s ;
363315#endif // Q_OS_MAC || Q_OS_LINUX
364316}
365317} // namespace OCC
0 commit comments