[Pkg-owncloud-commits] [owncloud-client] 45/135: Journal: Don't use a ._ path if it won't work #5633

Sandro Knauß hefee at debian.org
Sat Sep 9 14:28:34 UTC 2017


This is an automated email from the git hooks/post-receive script.

hefee pushed a commit to branch master
in repository owncloud-client.

commit 4291ea47f77752848e31341019e9be98f59526df
Author: Christian Kamm <mail at ckamm.de>
Date:   Fri Jun 16 15:43:21 2017 +0200

    Journal: Don't use a ._ path if it won't work #5633
    
    When synchronizing a folder on a samba share, creating files that begin
    with ._ is often forbidden. This prevented the client from creating
    its ._sync_abcdef.db file.
    
    Now, it'll check whether the preferred filename is creatable, and if
    it isn't it'll use .sync_abcdef.db instead.
    
    The disadvantage is that this alternative path won't be ignored by
    older clients - that was the reason for the ._ prefix.
---
 csync/src/csync_exclude.c                     |  5 ++++
 csync/tests/csync_tests/check_csync_exclude.c | 11 +++++++-
 src/cmd/cmd.cpp                               |  2 +-
 src/gui/folder.cpp                            |  2 +-
 src/gui/folderman.cpp                         | 15 ++++++++--
 src/gui/folderwatcher_linux.cpp               |  3 +-
 src/libsync/syncjournaldb.cpp                 | 40 ++++++++++++++++++++++++++-
 src/libsync/syncjournaldb.h                   |  3 +-
 8 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/csync/src/csync_exclude.c b/csync/src/csync_exclude.c
index e125b33..88dd61e 100644
--- a/csync/src/csync_exclude.c
+++ b/csync/src/csync_exclude.c
@@ -235,6 +235,11 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
         match = CSYNC_FILE_SILENTLY_EXCLUDED;
         goto out;
     }
+    rc = csync_fnmatch(".sync_*.db*", bname, 0);
+    if (rc == 0) {
+        match = CSYNC_FILE_SILENTLY_EXCLUDED;
+        goto out;
+    }
     rc = csync_fnmatch(".csync_journal.db*", bname, 0);
     if (rc == 0) {
         match = CSYNC_FILE_SILENTLY_EXCLUDED;
diff --git a/csync/tests/csync_tests/check_csync_exclude.c b/csync/tests/csync_tests/check_csync_exclude.c
index e7af73c..bd4813c 100644
--- a/csync/tests/csync_tests/check_csync_exclude.c
+++ b/csync/tests/csync_tests/check_csync_exclude.c
@@ -157,7 +157,16 @@ static void check_csync_excluded(void **state)
     assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
     rc = csync_excluded_no_ctx(csync->excludes, "subdir/._sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
     assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
-    
+
+    rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
+    rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db.ctmp", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
+    rc = csync_excluded_no_ctx(csync->excludes, ".sync_5bdd60bdfcfa.db-shm", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
+    rc = csync_excluded_no_ctx(csync->excludes, "subdir/.sync_5bdd60bdfcfa.db", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
+
 
     /* pattern ]*.directory - ignore and remove */
     rc = csync_excluded_no_ctx(csync->excludes, "my.~directory", CSYNC_FTW_TYPE_FILE);
diff --git a/src/cmd/cmd.cpp b/src/cmd/cmd.cpp
index 5421b23..152f249 100644
--- a/src/cmd/cmd.cpp
+++ b/src/cmd/cmd.cpp
@@ -469,7 +469,7 @@ restart_sync:
     }
 
     Cmd cmd;
-    QString dbPath = options.source_dir + SyncJournalDb::makeDbName(credentialFreeUrl, folder, user);
+    QString dbPath = options.source_dir + SyncJournalDb::makeDbName(options.source_dir, credentialFreeUrl, folder, user);
     SyncJournalDb db(dbPath);
 
     if (!selectiveSyncList.empty()) {
diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp
index 83ed5c5..7e2d12b 100644
--- a/src/gui/folder.cpp
+++ b/src/gui/folder.cpp
@@ -1003,7 +1003,7 @@ QString FolderDefinition::absoluteJournalPath() const
 
 QString FolderDefinition::defaultJournalPath(AccountPtr account)
 {
-    return SyncJournalDb::makeDbName(account->url(), targetPath, account->credentials()->user());
+    return SyncJournalDb::makeDbName(localPath, account->url(), targetPath, account->credentials()->user());
 }
 
 } // namespace OCC
diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp
index 1a230a2..cb0fa90 100644
--- a/src/gui/folderman.cpp
+++ b/src/gui/folderman.cpp
@@ -235,11 +235,22 @@ void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account,
     foreach (const auto& folderAlias, settings.childGroups()) {
         FolderDefinition folderDefinition;
         if (FolderDefinition::load(settings, folderAlias, &folderDefinition)) {
+            auto defaultJournalPath = folderDefinition.defaultJournalPath(account->account());
+
             // Migration: Old settings don't have journalPath
             if (folderDefinition.journalPath.isEmpty()) {
-                folderDefinition.journalPath = folderDefinition.defaultJournalPath(account->account());
+                folderDefinition.journalPath = defaultJournalPath;
+            }
+
+            // Migration: ._ files sometimes don't work
+            // So if the configured journalPath is the default one ("._sync_*.db")
+            // but the current default doesn't have the underscore, switch to the
+            // new default. See SyncJournalDb::makeDbName().
+            if (folderDefinition.journalPath.startsWith("._sync_")
+                && defaultJournalPath.startsWith(".sync_")) {
+                folderDefinition.journalPath = defaultJournalPath;
             }
-            folderDefinition.defaultJournalPath(account->account());
+
             // Migration: If an old db is found, move it to the new name.
             if (backwardsCompatible) {
                 SyncJournalDb::maybeMigrateDb(folderDefinition.localPath, folderDefinition.absoluteJournalPath());
diff --git a/src/gui/folderwatcher_linux.cpp b/src/gui/folderwatcher_linux.cpp
index c8024c0..d647f65 100644
--- a/src/gui/folderwatcher_linux.cpp
+++ b/src/gui/folderwatcher_linux.cpp
@@ -171,7 +171,8 @@ void FolderWatcherPrivate::slotReceivedNotification(int fd)
             // qDebug() << Q_FUNC_INFO << event->name;
             if (fileName.startsWith("._sync_") ||
                     fileName.startsWith(".csync_journal.db") ||
-                    fileName.startsWith(".owncloudsync.log")) {
+                    fileName.startsWith(".owncloudsync.log") ||
+                    fileName.startsWith(".sync_")) {
                 // qDebug() << "ignore journal";
             } else {
                 const QString p = _watches[event->wd] + '/' + fileName;
diff --git a/src/libsync/syncjournaldb.cpp b/src/libsync/syncjournaldb.cpp
index 43ef9b3..c6c4a9c 100644
--- a/src/libsync/syncjournaldb.cpp
+++ b/src/libsync/syncjournaldb.cpp
@@ -17,6 +17,7 @@
 #include <QDebug>
 #include <QElapsedTimer>
 #include <QUrl>
+#include <QDir>
 
 #include "ownsql.h"
 
@@ -41,7 +42,8 @@ SyncJournalDb::SyncJournalDb(const QString& dbFilePath, QObject *parent) :
 
 }
 
-QString SyncJournalDb::makeDbName(const QUrl& remoteUrl,
+QString SyncJournalDb::makeDbName(const QString& localPath,
+                                  const QUrl& remoteUrl,
                                   const QString& remotePath,
                                   const QString& user)
 {
@@ -56,6 +58,42 @@ QString SyncJournalDb::makeDbName(const QUrl& remoteUrl,
     journalPath.append( ba.left(6).toHex() );
     journalPath.append(".db");
 
+    // If the journal doesn't exist and we can't create a file
+    // at that location, try again with a journal name that doesn't
+    // have the ._ prefix.
+    //
+    // The disadvantage of that filename is that it will only be ignored
+    // by client versions >2.3.2.
+    //
+    // See #5633: "._*" is often forbidden on samba shared folders.
+
+    // If it exists already, the path is clearly usable
+    QFile file(QDir(localPath).filePath(journalPath));
+    if (file.exists()) {
+        return journalPath;
+    }
+
+    // Try to create a file there
+    if (file.open(QIODevice::ReadWrite)) {
+        // Ok, all good.
+        file.close();
+        file.remove();
+        return journalPath;
+    }
+
+    // Can we create it if we drop the underscore?
+    QString alternateJournalPath = journalPath.mid(2).prepend(".");
+    QFile file2(QDir(localPath).filePath(alternateJournalPath));
+    if (file2.open(QIODevice::ReadWrite)) {
+        // The alternative worked, use it
+        qDebug() << "Using alternate database path" << alternateJournalPath;
+        file2.close();
+        file2.remove();
+        return alternateJournalPath;
+    }
+
+    // Neither worked, just keep the original and throw errors later
+    qDebug() << "Could not find a writable database path" << file.fileName();
     return journalPath;
 }
 
diff --git a/src/libsync/syncjournaldb.h b/src/libsync/syncjournaldb.h
index 72db1c4..37df8c8 100644
--- a/src/libsync/syncjournaldb.h
+++ b/src/libsync/syncjournaldb.h
@@ -41,7 +41,8 @@ public:
     virtual ~SyncJournalDb();
 
     /// Create a journal path for a specific configuration
-    static QString makeDbName(const QUrl& remoteUrl,
+    static QString makeDbName(const QString& localPath,
+                              const QUrl& remoteUrl,
                               const QString& remotePath,
                               const QString& user);
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list