From f89bc09fd16105d1003e0edd54d9f9f980b1004d Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 24 Jan 2017 13:25:03 +0100 Subject: [PATCH] Discovery: Filter 'M' out of permissions for non root storage The sync engine rely on the 'M' in premission to ask for confirmation (As requested in issue #5340) But we only want to ask the premission for the 'root' of the mounting point and not for every subfolders within it. So we change the discovery phase in a way that it does not keep the 'M' for children within the external storage. --- src/libsync/discoveryphase.cpp | 16 +++++++++++++--- src/libsync/discoveryphase.h | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index 5e3a6bbdb..79b476d09 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -90,14 +90,15 @@ bool DiscoveryJob::checkSelectiveSyncNewFolder(const QString& path, const char * if (_syncOptions._confirmExternalStorage && std::strchr(remotePerm, 'M')) { // 'M' in the permission means external storage. + /* Note: DiscoverySingleDirectoryJob::directoryListingIteratedSlot make sure that only the + * root of a mounted storage has 'M', all sub entries have 'm' */ + // Only allow it if the white list contains exactly this path (not parents) // We want to ask confirmation for external storage even if the parents where selected if (_selectiveSyncWhiteList.contains(path + QLatin1Char('/'))) { return false; } - // FIXME! if the parent folder has 'M': return false - emit newBigFolder(path); return true; } @@ -340,7 +341,9 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file, con // The first entry is for the folder itself, we should process it differently. _ignoredFirst = true; if (map.contains("permissions")) { - emit firstDirectoryPermissions(map.value("permissions")); + auto perm = map.value("permissions"); + emit firstDirectoryPermissions(perm); + _isExternalStorage = perm.contains(QLatin1Char('M')); } if (map.contains("data-fingerprint")) { _dataFingerprint = map.value("data-fingerprint").toUtf8(); @@ -363,6 +366,13 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file, con if (!file_stat->etag || strlen(file_stat->etag) == 0) { qDebug() << "WARNING: etag of" << file_stat->name << "is" << file_stat->etag << " This must not happen."; } + if (_isExternalStorage) { + /* All the entries in a external storage have 'M' in their permission. However, for all + purposes in the desktop client, we only need to know about the mount points. + So replace the 'M' by a 'm' for every sub entries in an external storage */ + std::replace(std::begin(file_stat->remotePerm), std::end(file_stat->remotePerm), + 'M', 'm'); + } QStringRef fileRef(&file); int slashPos = file.lastIndexOf(QLatin1Char('/')); diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h index 7c352c2f1..e521c1fab 100644 --- a/src/libsync/discoveryphase.h +++ b/src/libsync/discoveryphase.h @@ -116,6 +116,8 @@ private: bool _ignoredFirst; // Set to true if this is the root path and we need to check the data-fingerprint bool _isRootPath; + // If this directory is an external storage (The first item has 'M' in its permission) + bool _isExternalStorage = false; QPointer _lsColJob; public: -- 2.30.2