From: Olivier Goffart Date: Mon, 16 Jul 2018 16:35:35 +0000 (+0200) Subject: New Discovery algorithm X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~553 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=d54e00488ac4fd01c5199ec4300ad451c5a20537;p=nextcloud-desktop.git New Discovery algorithm Some error handling. In particular for the case where there is a conflict between files and directories. SyncEngineTest and SyncMoveTest passes --- diff --git a/src/csync/csync_update.cpp b/src/csync/csync_update.cpp index f440dcdc7..eb1395a67 100644 --- a/src/csync/csync_update.cpp +++ b/src/csync/csync_update.cpp @@ -547,17 +547,10 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn, } /* permission denied */ ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR); - if (errno == EACCES) { - qCWarning(lcUpdate, "Permission denied."); - if (mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_PERMISSION_DENIED)) { - return 0; - } - } else if(errno == ENOENT) { - ctx->error_string = QString::fromUtf8(uri); - } + // 403 Forbidden can be sent by the server if the file firewall is active. // A file or directory should be ignored and sync must continue. See #3490 - else if(errno == ERRNO_FORBIDDEN) { + if (errno == ERRNO_FORBIDDEN) { qCWarning(lcUpdate, "Directory access Forbidden (File Firewall?)"); if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_FORBIDDEN) ) { return 0; diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 726ac9379..4387826b6 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -64,8 +64,9 @@ void ProcessDirectoryJob::start() { qCInfo(lcDisco) << "STARTING" << _currentFolder._server << _queryServer << _currentFolder._local << _queryLocal; + DiscoverServerJob *serverJob = nullptr; if (_queryServer == NormalQuery) { - auto serverJob = new DiscoverServerJob(_discoveryData->_account, _discoveryData->_remoteFolder + _currentFolder._server, this); + serverJob = new DiscoverServerJob(_discoveryData->_account, _discoveryData->_remoteFolder + _currentFolder._server, this); connect(serverJob, &DiscoverServerJob::finished, this, [this](const auto &results) { if (results) { _serverEntries = *results; @@ -92,9 +93,36 @@ void ProcessDirectoryJob::start() }*/ auto dh = csync_vio_local_opendir((_discoveryData->_localDir + _currentFolder._local).toUtf8()); if (!dh) { - qDebug() << "COULD NOT OPEN" << (_discoveryData->_localDir + _currentFolder._local); - qFatal("TODO: ERROR HANDLING"); - // should be the same as in csync_update; + qCInfo(lcDisco) << "Error while opening directory" << (_discoveryData->_localDir + _currentFolder._local) << errno; + serverJob->abort(); + QString errorString = tr("Error while opening directory %1").arg(_discoveryData->_localDir + _currentFolder._local); + if (errno == EACCES) { + errorString = tr("Directory not accessible on client, permission denied"); + if (_dirItem) { + _dirItem->_instruction = CSYNC_INSTRUCTION_IGNORE; + _dirItem->_errorString = errorString; + emit finished(); + return; + } + } else if (errno == ENOENT) { + errorString = tr("Directory not found: %1").arg(_discoveryData->_localDir + _currentFolder._local); + if (_dirItem) { + _dirItem->_instruction = CSYNC_INSTRUCTION_IGNORE; + _dirItem->_errorString = errorString; + emit finished(); + return; + } + } else if (errno == ENOTDIR) { + // Not a directory.. + // Just consider it is empty + _hasLocalEntries = true; + if (_hasServerEntries) + process(); + return; + } + emit _discoveryData->fatalError(errorString); + emit finished(); + return; } while (auto dirent = csync_vio_local_readdir(dh)) { LocalInfo i; @@ -434,12 +462,12 @@ void ProcessDirectoryJob::processFile(PathTuple path, qCInfo(lcDisco) << "Local file does not exist anymore." << originalPath; return; } - if (buf.modtime != base._modtime || buf.size != base._fileSize) { + if (buf.modtime != base._modtime || buf.size != base._fileSize || buf.type != ItemTypeFile) { qCInfo(lcDisco) << "File has changed locally, not a rename." << originalPath; return; } } else { - if (!QFile::exists(_discoveryData->_localDir + originalPath)) { + if (!QFileInfo(_discoveryData->_localDir + originalPath).isDir()) { qCInfo(lcDisco) << "Local directory does not exist anymore." << originalPath; return; } diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h index 51b2fc16f..4b09f6fc6 100644 --- a/src/libsync/discoveryphase.h +++ b/src/libsync/discoveryphase.h @@ -123,7 +123,7 @@ public: QString adjustRenamedPath(const QString &original) const; signals: - void finished(int result); + void fatalError(const QString &errorString); void folderDiscovered(bool local, QString folderUrl); // A new folder was discovered and was not synced because of the confirmation feature diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 2d9ae138f..56130442e 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -558,10 +558,6 @@ int SyncEngine::treewalkFile(csync_file_stat_t * /*file*/, csync_file_stat_t * / item->_status = SyncFileItem::SoftError; _temporarilyUnavailablePaths.insert(item->_file); break; - case CSYNC_STATUS_PERMISSION_DENIED: - item->_errorString = QLatin1String("Directory not accessible on client, permission denied."); - item->_status = SyncFileItem::SoftError; - break; } @@ -920,7 +916,10 @@ void SyncEngine::slotStartDiscovery() connect(_discoveryPhase.data(), &DiscoveryPhase::folderDiscovered, this, &SyncEngine::slotFolderDiscovered); connect(_discoveryPhase.data(), &DiscoveryPhase::newBigFolder, this, &SyncEngine::newBigFolder); - + connect(_discoveryPhase.data(), &DiscoveryPhase::fatalError, this, [this](const QString &errorString) { + csyncError(errorString); + finalize(false); + }); _discoveryJob = new ProcessDirectoryJob(SyncFileItemPtr(), ProcessDirectoryJob::NormalQuery, ProcessDirectoryJob::NormalQuery, _discoveryPhase.data(), this);