void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account, bool backwardsCompatible)
{
- foreach (const auto& folderAlias, settings.childGroups()) {
+ 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());
// Fire event for the path that was changed.
if (event->len > 0 && event->wd > -1) {
QByteArray fileName(event->name);
- if (fileName.startsWith("._sync_") || fileName.startsWith(".csync_journal.db") || fileName.startsWith(".owncloudsync.log")) {
- // qDebug() << Q_FUNC_INFO << event->name;
- if (fileName.startsWith("._sync_") ||
- fileName.startsWith(".csync_journal.db") ||
- fileName.startsWith(".owncloudsync.log") ||
- fileName.startsWith(".sync_")) {
- // qDebug() << "ignore journal";
++ if (fileName.startsWith("._sync_")
++ || fileName.startsWith(".csync_journal.db")
++ || fileName.startsWith(".owncloudsync.log")
++ || fileName.startsWith(".sync_")) {
} else {
const QString p = _watches[event->wd] + '/' + fileName;
- //qDebug() << "found a change in " << p;
_parent->changeDetected(p);
}
}
ConfigFile cfgFile;
readOnlyTooltip = tr("This entry is provided by the system at '%1' "
"and cannot be modified in this view.")
- .arg(QDir::toNativeSeparators(cfgFile.excludeFile(ConfigFile::SystemScope)));
+ .arg(QDir::toNativeSeparators(cfgFile.excludeFile(ConfigFile::SystemScope)));
+ addPattern(".csync_journal.db*", /*deletable=*/false, /*readonly=*/true);
+ addPattern("._sync_*.db*", /*deletable=*/false, /*readonly=*/true);
+ addPattern(".sync_*.db*", /*deletable=*/false, /*readonly=*/true);
readIgnoreFile(cfgFile.excludeFile(ConfigFile::SystemScope), true);
readIgnoreFile(cfgFile.excludeFile(ConfigFile::UserScope), false);
*/
#include <QFile>
+#include <QLoggingCategory>
#include <QStringList>
-#include <QDebug>
#include <QElapsedTimer>
#include <QUrl>
+ #include <QDir>
#include "ownsql.h"
namespace OCC {
-SyncJournalDb::SyncJournalDb(const QString& dbFilePath, QObject *parent) :
- QObject(parent),
- _dbFile(dbFilePath),
- _transaction(0)
-{
+Q_LOGGING_CATEGORY(lcDb, "sync.database", QtInfoMsg)
+SyncJournalDb::SyncJournalDb(const QString &dbFilePath, QObject *parent)
+ : QObject(parent)
+ , _dbFile(dbFilePath)
+ , _transaction(0)
+{
}
- QString SyncJournalDb::makeDbName(const QUrl &remoteUrl,
-QString SyncJournalDb::makeDbName(const QString& localPath,
- const QUrl& remoteUrl,
- const QString& remotePath,
- const QString& user)
++QString SyncJournalDb::makeDbName(const QString &localPath,
++ const QUrl &remoteUrl,
+ const QString &remotePath,
+ const QString &user)
{
QString journalPath = QLatin1String("._sync_");
- QString key = QString::fromUtf8("%1@%2:%3").arg(
- user,
- remoteUrl.toString(),
- remotePath);
+ QString key = QString::fromUtf8("%1@%2:%3").arg(user, remoteUrl.toString(), remotePath);
QByteArray ba = QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Md5);
- journalPath.append( ba.left(6).toHex() );
+ journalPath.append(ba.left(6).toHex());
journalPath.append(".db");
- qDebug() << "Using alternate database path" << alternateJournalPath;
+ // 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() << "Could not find a writable database path" << file.fileName();
++ qCInfo(lcDb) << "Using alternate database path" << alternateJournalPath;
+ file2.close();
+ file2.remove();
+ return alternateJournalPath;
+ }
+
+ // Neither worked, just keep the original and throw errors later
++ qCWarning(lcDb) << "Could not find a writable database path" << file.fileName();
return journalPath;
}
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);
++ static QString makeDbName(const QString &localPath,
++ const QUrl &remoteUrl,
+ const QString &remotePath,
+ const QString &user);
/// Migrate a csync_journal to the new path, if necessary. Returns false on error
- static bool maybeMigrateDb(const QString& localPath, const QString& absoluteJournalPath);
+ static bool maybeMigrateDb(const QString &localPath, const QString &absoluteJournalPath);
// to verify that the record could be queried successfully check
// with SyncJournalFileRecord::isValid()