Skip to content

Commit b619ba5

Browse files
committed
gui/config: Add symlink synchronization as sync option
This commit reverts the effects of commit 47be8fd.
1 parent 9ac0358 commit b619ba5

File tree

9 files changed

+53
-10
lines changed

9 files changed

+53
-10
lines changed

src/gui/folder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,7 @@ SyncOptions Folder::initializeSyncOptions() const
10961096
auto newFolderLimit = cfgFile.newBigFolderSizeLimit();
10971097
opt._newBigFolderSizeLimit = newFolderLimit.first ? newFolderLimit.second * 1000LL * 1000LL : -1; // convert from MB to B
10981098
opt._confirmExternalStorage = cfgFile.confirmExternalStorage();
1099+
opt._synchronizeSymlinks = cfgFile.synchronizeSymlinks();
10991100
opt._moveFilesToTrash = cfgFile.moveToTrash();
11001101
opt._vfs = _vfs;
11011102
opt._parallelNetworkJobs = _accountState->account()->isHttp2Supported() ? 20 : 6;

src/gui/generalsettings.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ GeneralSettings::GeneralSettings(QWidget *parent)
191191
connect(_ui->existingFolderLimitCheckBox, &QAbstractButton::toggled, this, &GeneralSettings::saveMiscSettings);
192192
connect(_ui->stopExistingFolderNowBigSyncCheckBox, &QAbstractButton::toggled, this, &GeneralSettings::saveMiscSettings);
193193
connect(_ui->newExternalStorage, &QAbstractButton::toggled, this, &GeneralSettings::saveMiscSettings);
194+
connect(_ui->synchronizeSymlinks, &QAbstractButton::toggled, this, &GeneralSettings::saveMiscSettings);
194195
connect(_ui->moveFilesToTrashCheckBox, &QAbstractButton::toggled, this, &GeneralSettings::saveMiscSettings);
195196

196197
#ifndef WITH_CRASHREPORTER
@@ -259,6 +260,7 @@ void GeneralSettings::loadMiscSettings()
259260
_ui->showInExplorerNavigationPaneCheckBox->setChecked(cfgFile.showInExplorerNavigationPane());
260261
_ui->crashreporterCheckBox->setChecked(cfgFile.crashReporter());
261262
_ui->newExternalStorage->setChecked(cfgFile.confirmExternalStorage());
263+
_ui->synchronizeSymlinks->setChecked(cfgFile.synchronizeSymlinks());
262264
_ui->monoIconsCheckBox->setChecked(cfgFile.monoIcons());
263265
_ui->moveFilesToTrashCheckBox->setChecked(cfgFile.moveToTrash());
264266

@@ -270,6 +272,7 @@ void GeneralSettings::loadMiscSettings()
270272
_ui->stopExistingFolderNowBigSyncCheckBox->setEnabled(_ui->existingFolderLimitCheckBox->isChecked());
271273
_ui->stopExistingFolderNowBigSyncCheckBox->setChecked(_ui->existingFolderLimitCheckBox->isChecked() && cfgFile.stopSyncingExistingFoldersOverLimit());
272274
_ui->newExternalStorage->setChecked(cfgFile.confirmExternalStorage());
275+
_ui->synchronizeSymlinks->setChecked(cfgFile.synchronizeSymlinks());
273276
_ui->monoIconsCheckBox->setChecked(cfgFile.monoIcons());
274277
}
275278

@@ -447,6 +450,7 @@ void GeneralSettings::saveMiscSettings()
447450
cfgFile.setMoveToTrash(_ui->moveFilesToTrashCheckBox->isChecked());
448451
cfgFile.setNewBigFolderSizeLimit(newFolderLimitEnabled, _ui->newFolderLimitSpinBox->value());
449452
cfgFile.setConfirmExternalStorage(_ui->newExternalStorage->isChecked());
453+
cfgFile.setSynchronizeSymlinks(_ui->synchronizeSymlinks->isChecked());
450454
cfgFile.setNotifyExistingFoldersOverLimit(existingFolderLimitEnabled);
451455
cfgFile.setStopSyncingExistingFoldersOverLimit(stopSyncingExistingFoldersOverLimit);
452456

src/gui/generalsettings.ui

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,17 @@
139139
</item>
140140
</layout>
141141
</item>
142+
<item>
143+
<layout class="QHBoxLayout" name="horizontalLayout_11">
144+
<item>
145+
<widget class="QCheckBox" name="synchronizeSymlinks">
146+
<property name="text">
147+
<string>[experimental] Synchronize symlinks</string>
148+
</property>
149+
</widget>
150+
</item>
151+
</layout>
152+
</item>
142153
<item>
143154
<layout class="QHBoxLayout" name="horizontalLayout">
144155
<item>

src/libsync/configfile.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ static constexpr char useNewBigFolderSizeLimitC[] = "useNewBigFolderSizeLimit";
102102
static constexpr char notifyExistingFoldersOverLimitC[] = "notifyExistingFoldersOverLimit";
103103
static constexpr char stopSyncingExistingFoldersOverLimitC[] = "stopSyncingExistingFoldersOverLimit";
104104
static constexpr char confirmExternalStorageC[] = "confirmExternalStorage";
105+
static constexpr char synchronizeSymlinksC[] = "synchronizeSymlinks";
105106
static constexpr char moveToTrashC[] = "moveToTrash";
106107

107108
static constexpr char certPath[] = "http_certificatePath";
@@ -947,6 +948,12 @@ bool ConfigFile::confirmExternalStorage() const
947948
return getPolicySetting(QLatin1String(confirmExternalStorageC), fallback).toBool();
948949
}
949950

951+
bool ConfigFile::synchronizeSymlinks() const
952+
{
953+
const auto fallback = getValue(synchronizeSymlinksC, QString(), false);
954+
return getPolicySetting(QLatin1String(synchronizeSymlinksC), fallback).toBool();
955+
}
956+
950957
bool ConfigFile::useNewBigFolderSizeLimit() const
951958
{
952959
const auto fallback = getValue(useNewBigFolderSizeLimitC, QString(), true);
@@ -981,6 +988,11 @@ void ConfigFile::setConfirmExternalStorage(bool isChecked)
981988
setValue(confirmExternalStorageC, isChecked);
982989
}
983990

991+
void ConfigFile::setSynchronizeSymlinks(bool isChecked)
992+
{
993+
setValue(synchronizeSymlinksC, isChecked);
994+
}
995+
984996
bool ConfigFile::moveToTrash() const
985997
{
986998
return getValue(moveToTrashC, QString(), false).toBool();

src/libsync/configfile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ class OWNCLOUDSYNC_EXPORT ConfigFile
149149
[[nodiscard]] bool confirmExternalStorage() const;
150150
void setConfirmExternalStorage(bool);
151151

152+
[[nodiscard]] bool synchronizeSymlinks() const;
153+
void setSynchronizeSymlinks(bool);
154+
152155
/** If we should move the files deleted on the server in the trash */
153156
[[nodiscard]] bool moveToTrash() const;
154157
void setMoveToTrash(bool);

src/libsync/discovery.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,35 +39,38 @@ namespace OCC {
3939

4040
Q_LOGGING_CATEGORY(lcDisco, "nextcloud.sync.discovery", QtInfoMsg)
4141

42-
ProcessDirectoryJob::ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState, qint64 lastSyncTimestamp, QObject *parent)
42+
ProcessDirectoryJob::ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState, qint64 lastSyncTimestamp, bool synchronizeSymlinks, QObject *parent)
4343
: QObject(parent)
4444
, _lastSyncTimestamp(lastSyncTimestamp)
4545
, _discoveryData(data)
46+
, _synchronizeSymlinks(synchronizeSymlinks)
4647
{
4748
qCDebug(lcDisco) << data;
4849
computePinState(basePinState);
4950
}
5051

51-
ProcessDirectoryJob::ProcessDirectoryJob(const PathTuple &path, const SyncFileItemPtr &dirItem, QueryMode queryLocal, QueryMode queryServer, qint64 lastSyncTimestamp, ProcessDirectoryJob *parent)
52+
ProcessDirectoryJob::ProcessDirectoryJob(const PathTuple &path, const SyncFileItemPtr &dirItem, QueryMode queryLocal, QueryMode queryServer, qint64 lastSyncTimestamp, bool synchronizeSymlinks, ProcessDirectoryJob *parent)
5253
: QObject(parent)
5354
, _dirItem(dirItem)
5455
, _lastSyncTimestamp(lastSyncTimestamp)
5556
, _queryServer(queryServer)
5657
, _queryLocal(queryLocal)
5758
, _discoveryData(parent->_discoveryData)
5859
, _currentFolder(path)
60+
, _synchronizeSymlinks(synchronizeSymlinks)
5961
{
6062
qCDebug(lcDisco) << path._server << queryServer << path._local << queryLocal << lastSyncTimestamp;
6163
computePinState(parent->_pinState);
6264
}
6365

64-
ProcessDirectoryJob::ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState, const PathTuple &path, const SyncFileItemPtr &dirItem, QueryMode queryLocal, qint64 lastSyncTimestamp, QObject *parent)
66+
ProcessDirectoryJob::ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState, const PathTuple &path, const SyncFileItemPtr &dirItem, QueryMode queryLocal, qint64 lastSyncTimestamp, bool synchronizeSymlinks, QObject *parent)
6567
: QObject(parent)
6668
, _dirItem(dirItem)
6769
, _lastSyncTimestamp(lastSyncTimestamp)
6870
, _queryLocal(queryLocal)
6971
, _discoveryData(data)
7072
, _currentFolder(path)
73+
, _synchronizeSymlinks(synchronizeSymlinks)
7174
{
7275
computePinState(basePinState);
7376
}
@@ -306,7 +309,9 @@ bool ProcessDirectoryJob::handleExcluded(const QString &path, const Entries &ent
306309
}
307310
}
308311

309-
if (excluded == CSYNC_NOT_EXCLUDED) {
312+
bool isSymlink = entries.localEntry.isSymLink || entries.serverEntry.isSymLink;
313+
// All not excluded files and additionally all symlinks if symlink synchronization is disabled
314+
if (excluded == CSYNC_NOT_EXCLUDED && !(_synchronizeSymlinks && isSymlink)) {
310315
return false;
311316
} else if (excluded == CSYNC_FILE_SILENTLY_EXCLUDED || excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
312317
emit _discoveryData->silentlyExcluded(path);
@@ -326,7 +331,8 @@ bool ProcessDirectoryJob::handleExcluded(const QString &path, const Entries &ent
326331
return true;
327332
}
328333

329-
if (entries.localEntry.isSymLink) {
334+
if (entries.localEntry.isSymLink && !_synchronizeSymlinks) {
335+
item->_errorString = tr("Symbolic links are not supported in syncing.");
330336
} else {
331337
switch (excluded) {
332338
case CSYNC_NOT_EXCLUDED:
@@ -1649,7 +1655,7 @@ void ProcessDirectoryJob::processFileFinalize(
16491655
}
16501656
if (recurse) {
16511657
auto job = new ProcessDirectoryJob(path, item, recurseQueryLocal, recurseQueryServer,
1652-
_lastSyncTimestamp, this);
1658+
_lastSyncTimestamp, _synchronizeSymlinks, this);
16531659
job->setInsideEncryptedTree(isInsideEncryptedTree() || item->isEncrypted());
16541660
if (removed) {
16551661
job->setParent(_discoveryData);
@@ -1693,7 +1699,7 @@ void ProcessDirectoryJob::processBlacklisted(const PathTuple &path, const OCC::L
16931699
qCInfo(lcDisco) << "Discovered (blacklisted) " << item->_file << item->_instruction << item->_direction << item->isDirectory();
16941700

16951701
if (item->isDirectory() && item->_instruction != CSYNC_INSTRUCTION_IGNORE) {
1696-
auto job = new ProcessDirectoryJob(path, item, NormalQuery, InBlackList, _lastSyncTimestamp, this);
1702+
auto job = new ProcessDirectoryJob(path, item, NormalQuery, InBlackList, _lastSyncTimestamp, _synchronizeSymlinks, this);
16971703
connect(job, &ProcessDirectoryJob::finished, this, &ProcessDirectoryJob::subJobFinished);
16981704
_queuedJobs.push_back(job);
16991705
} else {

src/libsync/discovery.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,15 @@ class ProcessDirectoryJob : public QObject
101101
* The base pin state is used if the root dir's pin state can't be retrieved.
102102
*/
103103
explicit ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState,
104-
qint64 lastSyncTimestamp, QObject *parent);
104+
qint64 lastSyncTimestamp, bool synchronizeSymlinks, QObject *parent);
105105

106106
/// For creating subjobs
107107
explicit ProcessDirectoryJob(const PathTuple &path, const SyncFileItemPtr &dirItem,
108-
QueryMode queryLocal, QueryMode queryServer, qint64 lastSyncTimestamp,
108+
QueryMode queryLocal, QueryMode queryServer, qint64 lastSyncTimestamp, bool synchronizeSymlinks,
109109
ProcessDirectoryJob *parent);
110110

111111
explicit ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState, const PathTuple &path, const SyncFileItemPtr &dirItem,
112-
QueryMode queryLocal, qint64 lastSyncTimestamp, QObject *parent);
112+
QueryMode queryLocal, qint64 lastSyncTimestamp, bool synchronizeSymlinks, QObject *parent);
113113

114114
void start();
115115
/** Start up to nbJobs, return the number of job started; emit finished() when done */
@@ -296,6 +296,7 @@ class ProcessDirectoryJob : public QObject
296296
bool _childIgnored = false; // The directory contains ignored item that would prevent deletion
297297
PinState _pinState = PinState::Unspecified; // The directory's pin-state, see computePinState()
298298
bool _isInsideEncryptedTree = false; // this directory is encrypted or is within the tree of directories with root directory encrypted
299+
const bool _synchronizeSymlinks = false;
299300

300301
signals:
301302
void finished();

src/libsync/syncengine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,13 +715,15 @@ void SyncEngine::startSync()
715715
singleItemDiscoveryOptions().discoveryDirItem,
716716
localQueryMode,
717717
_journal->keyValueStoreGetInt("last_sync", 0),
718+
_syncOptions._synchronizeSymlinks,
718719
_discoveryPhase.data()
719720
);
720721
} else {
721722
discoveryJob = new ProcessDirectoryJob(
722723
_discoveryPhase.data(),
723724
PinState::AlwaysLocal,
724725
_journal->keyValueStoreGetInt("last_sync", 0),
726+
_syncOptions._synchronizeSymlinks,
725727
_discoveryPhase.data()
726728
);
727729
}

src/libsync/syncoptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class OWNCLOUDSYNC_EXPORT SyncOptions
4242
/** If a confirmation should be asked for external storages */
4343
bool _confirmExternalStorage = false;
4444

45+
/** If symlinks should be synchronized to the server as symlinks */
46+
bool _synchronizeSymlinks = false;
47+
4548
/** If remotely deleted files are needed to move to trash */
4649
bool _moveFilesToTrash = false;
4750

0 commit comments

Comments
 (0)