diff --git a/include/mega/sync.h b/include/mega/sync.h index d2f8377fd1..e7801570a9 100644 --- a/include/mega/sync.h +++ b/include/mega/sync.h @@ -1233,6 +1233,7 @@ struct Syncs string exportSyncConfigs(const SyncConfigVector configs) const; string exportSyncConfigs() const; + error createMegaignoreFromLegacyExclusions(const LocalPath& targetPath); void importSyncConfigs(const char* data, std::function completion); diff --git a/include/megaapi.h b/include/megaapi.h index 2d703008f7..ea8d09ffb9 100644 --- a/include/megaapi.h +++ b/include/megaapi.h @@ -16990,6 +16990,30 @@ class MegaApi */ void setLegacyExclusionUpperSizeLimit(unsigned long long limit); + /** + * @brief Create a .megaignore file using legacy exclusion rules. + * + * Absolute paths included in the legacy rules will only be included + * if they are contained in the absolute path passed to the function. + * + * Ex: + * 1. Legacy excluded path: "/home/user/someSync/folder1*" + * 2. Param absolutePath: "/home/user/someSync" + * 3. Path "folder1*" will be included in the .megaignore created at "someSync". + * + * Possible return values for this function are: + * - MegaError::API_OK if the megaignore file was successfuly written. + * - MegaError::API_EARGS if absolutePath is empty or invalid. + * - MegaError::API_EACCESS if there was a problem writing the megaignore file. + * - MegaError::API_EEXIST if the megaignore file already exists. + * + * The caller takes ownership of the returned value. + * + * @param absolutePath Absolute path where the .megaignore file is going to be created. + * @return MegaError::API_OK if the file was created, otherwise it returns an error. + */ + MegaError* exportLegacyExclusionRules(const char* absolutePath); + /** * @brief Check if it's possible to start synchronizing a folder node. * diff --git a/include/megaapi_impl.h b/include/megaapi_impl.h index 5453ccb7c5..a7fba7adaa 100644 --- a/include/megaapi_impl.h +++ b/include/megaapi_impl.h @@ -3470,6 +3470,7 @@ class MegaApiImpl : public MegaApp void setLegacyExcludedPaths(vector *excludedPaths); void setLegacyExclusionLowerSizeLimit(unsigned long long limit); void setLegacyExclusionUpperSizeLimit(unsigned long long limit); + MegaError* exportLegacyExclusionRules(const char* absolutePath); long long getNumLocalNodes(); int isNodeSyncable(MegaNode *megaNode); MegaError *isNodeSyncableWithError(MegaNode* node); diff --git a/src/megaapi.cpp b/src/megaapi.cpp index c87681dc71..9d9763ab0e 100644 --- a/src/megaapi.cpp +++ b/src/megaapi.cpp @@ -3896,6 +3896,11 @@ void MegaApi::setLegacyExclusionUpperSizeLimit(unsigned long long limit) { pImpl->setLegacyExclusionUpperSizeLimit(limit); } + +MegaError* MegaApi::exportLegacyExclusionRules(const char* absolutePath) +{ + return pImpl->exportLegacyExclusionRules(absolutePath); +} #endif diff --git a/src/megaapi_impl.cpp b/src/megaapi_impl.cpp index 72c818c071..8c47043356 100644 --- a/src/megaapi_impl.cpp +++ b/src/megaapi_impl.cpp @@ -9883,6 +9883,20 @@ void MegaApiImpl::setLegacyExclusionUpperSizeLimit(unsigned long long limit) client->syncs.mLegacyUpgradeFilterChain.upperLimit(limit); } +MegaError* MegaApiImpl::exportLegacyExclusionRules(const char* absolutePath) +{ + SdkMutexGuard guard(sdkMutex); + + if (!absolutePath || !*absolutePath) + { + return new MegaErrorPrivate(API_EARGS); + } + + auto lp = LocalPath::fromAbsolutePath(absolutePath); + auto result = client->syncs.createMegaignoreFromLegacyExclusions(lp); + return new MegaErrorPrivate(result); +} + long long MegaApiImpl::getNumLocalNodes() { return client->syncs.totalLocalNodes; diff --git a/src/sync.cpp b/src/sync.cpp index 80ef734831..35819a4b1e 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -3753,6 +3753,33 @@ void Syncs::confirmOrCreateDefaultMegaignore(bool transitionToMegaignore, unique } } +error Syncs::createMegaignoreFromLegacyExclusions(const LocalPath& targetPath) +{ + LOG_info << "Writing .megaignore with legacy exclusion rules at " << targetPath; + + // Check whether the file already exists + auto targetPathWithFileName = targetPath; + targetPathWithFileName.appendWithSeparator(IGNORE_FILE_NAME, false); + if (fsaccess->fileExistsAt(targetPathWithFileName)) + { + LOG_err << "Failed to write " << targetPathWithFileName + << " because the file already exists"; + return API_EEXIST; + } + + // Safely copy the legacy filter chain + auto legacyFilterChain = std::make_unique(mLegacyUpgradeFilterChain); + + // Write the file + if (!legacyFilterChain->create(targetPath, true, *fsaccess, false)) + { + LOG_err << "Failed to write " << targetPath; + return API_EACCESS; + } + + return API_OK; +} + void Syncs::enableSyncByBackupId(handle backupId, bool setOriginalPath, std::function completion, bool completionInClient, const string& logname) { assert(!onSyncThread());