Discovery: Filter 'M' out of permissions for non root storage
authorOlivier Goffart <ogoffart@woboq.com>
Tue, 24 Jan 2017 12:25:03 +0000 (13:25 +0100)
committerMarkus Goetz <markus@woboq.com>
Fri, 27 Jan 2017 14:59:59 +0000 (15:59 +0100)
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
src/libsync/discoveryphase.h

index 5e3a6bbdbd87b2a70e46ef2bc82b9632a62483dc..79b476d098cc5cd522384b2ca86472c96157da12 100644 (file)
@@ -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('/'));
index 7c352c2f181573647207703b50323976e3d260e2..e521c1fabe2bb52ac85e0a777ec297cbc78cccc5 100644 (file)
@@ -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> _lsColJob;
 
 public: