diff --git a/src/csync/csync_update.cpp b/src/csync/csync_update.cpp index 6edfa0b46..4c121503b 100644 --- a/src/csync/csync_update.cpp +++ b/src/csync/csync_update.cpp @@ -784,15 +784,6 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn, continue; } - /* if the filename starts with a . we consider it a hidden file - * For windows, the hidden state is also discovered within the vio - * local stat function. - */ - if( filename[0] == '.' ) { - if (filename != ".sys.admin#recall#") { /* recall file shall not be ignored (#4420) */ - dirent->is_hidden = true; - } - } #if 0 // Now process to have a relative path to the sync root for the local replica, or to the data root on the remote. diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 03d97dbb5..2dec6fdac 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -102,6 +102,7 @@ void ProcessDirectoryJob::start() i.size = dirent->size; i.inode = dirent->inode; i.isDirectory = dirent->type == ItemTypeDirectory; + i.isHidden = dirent->is_hidden; if (dirent->type != ItemTypeDirectory && dirent->type != ItemTypeFile) qFatal("FIXME: NEED TO CARE ABOUT THE OTHER STUFF "); _localEntries.push_back(i); @@ -150,7 +151,15 @@ void ProcessDirectoryJob::process() for (const auto &f : entriesNames) { QString path = _currentFolder + f; - if (handleExcluded(path, (localEntriesHash.value(f).isDirectory || serverEntriesHash.value(f).isDirectory))) + auto localEntry = localEntriesHash.value(f); + auto serverEntry = serverEntriesHash.value(f); + + // If the filename starts with a . we consider it a hidden file + // For windows, the hidden state is also discovered within the vio + // local stat function. + // Recall file shall not be ignored (#4420) + bool isHidden = localEntry.isHidden || (f[0] == '.' && f != QLatin1String(".sys.admin#recall#")); + if (handleExcluded(path, localEntry.isDirectory || serverEntry.isDirectory, isHidden)) continue; SyncJournalFileRecord record; @@ -158,16 +167,16 @@ void ProcessDirectoryJob::process() qFatal("TODO: DB ERROR HANDLING"); } if (_queryServer == InBlackList || _discoveryData->isInSelectiveSyncBlackList(path)) { - processBlacklisted(path, localEntriesHash.value(f), record); + processBlacklisted(path, localEntry, record); continue; } - processFile(path, localEntriesHash.value(f), serverEntriesHash.value(f), record); + processFile(path, localEntry, serverEntry, record); } progress(); } -bool ProcessDirectoryJob::handleExcluded(const QString &path, bool isDirectory) +bool ProcessDirectoryJob::handleExcluded(const QString &path, bool isDirectory, bool isHidden) { // FIXME! call directly, without char* conversion auto excluded = _discoveryData->_excludes->csyncTraversalMatchFun()(path.toUtf8(), isDirectory ? ItemTypeDirectory : ItemTypeFile); @@ -181,6 +190,9 @@ bool ProcessDirectoryJob::handleExcluded(const QString &path, bool isDirectory) isInvalidPattern = true; } } + if (excluded == CSYNC_NOT_EXCLUDED && _discoveryData->_ignoreHiddenFiles && isHidden) { + excluded = CSYNC_FILE_EXCLUDE_HIDDEN; + } if (excluded == CSYNC_NOT_EXCLUDED /* FIXME && item->_type != ItemTypeSoftLink */) { return false; diff --git a/src/libsync/discovery.h b/src/libsync/discovery.h index 3ba55155f..8c7b729eb 100644 --- a/src/libsync/discovery.h +++ b/src/libsync/discovery.h @@ -89,6 +89,7 @@ struct LocalInfo int64_t size = 0; uint64_t inode = 0; bool isDirectory = false; + bool isHidden = false; bool isValid() const { return !name.isNull(); } }; @@ -129,7 +130,7 @@ public: private: void process(); // return true if the file is excluded - bool handleExcluded(const QString &path, bool isDirectory); + bool handleExcluded(const QString &path, bool isDirectory, bool isHidden); void processFile(const QString &, const LocalInfo &, const RemoteInfo &, const SyncJournalFileRecord &); void processBlacklisted(const QString &path, const LocalInfo &, const SyncJournalFileRecord &); void subJobFinished(); diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h index 35973378f..0058e846e 100644 --- a/src/libsync/discoveryphase.h +++ b/src/libsync/discoveryphase.h @@ -110,6 +110,7 @@ public: QStringList _selectiveSyncWhiteList; ExcludedFiles *_excludes; QString _invalidFilenamePattern; // FIXME: maybe move in ExcludedFiles + bool _ignoreHiddenFiles = false; bool isInSelectiveSyncBlackList(const QString &path) const; bool checkSelectiveSyncNewFolder(const QString &path, RemotePermissions rp); diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index e564f769e..31a12dac6 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -882,6 +882,7 @@ void SyncEngine::slotStartDiscovery() invalidFilenamePattern = "[\\\\:?*\"<>|]"; } ddata->_invalidFilenamePattern = invalidFilenamePattern; + ddata->_ignoreHiddenFiles = ignoreHiddenFiles(); connect(ddata.data(), &DiscoveryPhase::folderDiscovered, this, &SyncEngine::slotFolderDiscovered); connect(ddata.data(), &DiscoveryPhase::newBigFolder, this, &SyncEngine::newBigFolder);