[Pkg-owncloud-commits] [owncloud-client] 122/164: Lnk: Work around QFile::rename() #2792

Sandro Knauß hefee-guest at moszumanska.debian.org
Sun Mar 22 11:57:01 UTC 2015


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

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

commit efe9f1b442ea6aba13de5118dbcb2aa1874b6d8b
Author: Christian Kamm <kamm at incasoftware.de>
Date:   Wed Mar 11 10:51:36 2015 +0100

    Lnk: Work around QFile::rename() #2792
    
    QFile::rename() fails if the source file is a shortcut to a file
    or directory that does not exist.
---
 src/gui/folderman.cpp               |  6 ++--
 src/libsync/filesystem.cpp          | 58 ++++++++++++++++++++++++++++++-------
 src/libsync/filesystem.h            |  8 +++++
 src/libsync/propagatedownload.cpp   |  6 ++--
 src/libsync/propagateremotemove.cpp |  4 ++-
 src/libsync/propagator_legacy.cpp   |  6 ++--
 src/libsync/propagatorjobs.cpp      |  6 ++--
 7 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp
index 89f4613..91c5c4e 100644
--- a/src/gui/folderman.cpp
+++ b/src/gui/folderman.cpp
@@ -21,6 +21,7 @@
 #include "account.h"
 #include "accountmigrator.h"
 #include "accountstate.h"
+#include "filesystem.h"
 
 #ifdef Q_OS_MAC
 #include <CoreServices/CoreServices.h>
@@ -852,9 +853,10 @@ bool FolderMan::startFromScratch( const QString& localFolder )
 
         // Make a backup of the folder/file.
         QString newName = getBackupName( parentDir.absoluteFilePath( folderName ) );
-        if( !parentDir.rename( fi.absoluteFilePath(), newName ) ) {
+        QString renameError;
+        if( !FileSystem::rename( fi.absoluteFilePath(), newName, &renameError ) ) {
             qDebug() << "startFromScratch: Could not rename" << fi.absoluteFilePath()
-                     << "to" << newName;
+                     << "to" << newName << "error:" << renameError;
             return false;
         }
     }
diff --git a/src/libsync/filesystem.cpp b/src/libsync/filesystem.cpp
index 5e014f7..ba94db0 100644
--- a/src/libsync/filesystem.cpp
+++ b/src/libsync/filesystem.cpp
@@ -107,6 +107,54 @@ bool FileSystem::setModTime(const QString& filename, time_t modTime)
     return true;
 }
 
+#ifdef Q_OS_WIN
+static bool isLnkFile(const QString& filename)
+{
+    return filename.endsWith(".lnk");
+}
+#endif
+
+bool FileSystem::rename(const QString &originFileName,
+                        const QString &destinationFileName,
+                        QString *errorString)
+{
+    bool success = false;
+    QString error;
+#ifdef Q_OS_WIN
+    if (isLnkFile(originFileName) || isLnkFile(destinationFileName)) {
+        success = MoveFileEx((wchar_t*)originFileName.utf16(),
+                             (wchar_t*)destinationFileName.utf16(),
+                             MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH);
+        if (!success) {
+            wchar_t *string = 0;
+            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                          NULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                          (LPWSTR)&string, 0, NULL);
+
+            error = QString::fromWCharArray(string);
+            LocalFree((HLOCAL)string);
+        }
+    } else
+#endif
+    {
+        QFile orig(originFileName);
+        success = orig.rename(destinationFileName);
+        if (!success) {
+            error = orig.errorString();
+        }
+    }
+
+    if (!success) {
+        qDebug() << "FAIL: renaming file" << originFileName
+                 << "to" << destinationFileName
+                 << "failed: " << error;
+        if (errorString) {
+            *errorString = error;
+        }
+    }
+    return success;
+}
+
 bool FileSystem::renameReplace(const QString& originFileName, const QString& destinationFileName, QString* errorString)
 {
 #ifndef Q_OS_WIN
@@ -215,16 +263,6 @@ bool FileSystem::openFileSharedRead(QFile* file, QString* error)
 }
 
 #ifdef Q_OS_WIN
-static bool isLnkFile(const QString& filename)
-{
-    return filename.endsWith(".lnk");
-}
-
-static bool isLnkFile(const QFileInfo& fi)
-{
-    return fi.suffix() == "lnk";
-}
-
 static qint64 getSizeWithCsync(const QString& filename)
 {
     qint64 result = 0;
diff --git a/src/libsync/filesystem.h b/src/libsync/filesystem.h
index ea97a86..845ffc4 100644
--- a/src/libsync/filesystem.h
+++ b/src/libsync/filesystem.h
@@ -60,6 +60,14 @@ qint64 OWNCLOUDSYNC_EXPORT getSize(const QString& filename);
 bool OWNCLOUDSYNC_EXPORT fileExists(const QString& filename);
 
 /**
+ * Rename the file \a originFileName to \a destinationFileName.
+ *
+ * It behaves as QFile::rename() but handles .lnk files correctly on Windows.
+ */
+bool OWNCLOUDSYNC_EXPORT rename(const QString& originFileName,
+                                const QString& destinationFileName,
+                                QString* errorString = NULL);
+/**
  * Rename the file \a originFileName to \a destinationFileName, and overwrite the destination if it
  * already exists
  */
diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp
index 33538e1..9084d97 100644
--- a/src/libsync/propagatedownload.cpp
+++ b/src/libsync/propagatedownload.cpp
@@ -492,11 +492,11 @@ void PropagateDownloadFileQNAM::downloadFinished()
     bool isConflict = _item._instruction == CSYNC_INSTRUCTION_CONFLICT
             && !FileSystem::fileEquals(fn, _tmpFile.fileName());
     if (isConflict) {
-        QFile f(fn);
+        QString renameError;
         QString conflictFileName = makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item._modtime));
-        if (!f.rename(conflictFileName)) {
+        if (!FileSystem::rename(fn, conflictFileName, &renameError)) {
             //If the rename fails, don't replace it.
-            done(SyncFileItem::SoftError, f.errorString());
+            done(SyncFileItem::SoftError, renameError);
             return;
         }
     }
diff --git a/src/libsync/propagateremotemove.cpp b/src/libsync/propagateremotemove.cpp
index 600bbb3..c6c45f8 100644
--- a/src/libsync/propagateremotemove.cpp
+++ b/src/libsync/propagateremotemove.cpp
@@ -16,6 +16,7 @@
 #include "owncloudpropagator_p.h"
 #include "account.h"
 #include "syncjournalfilerecord.h"
+#include "filesystem.h"
 #include <QFile>
 #include <QStringList>
 
@@ -81,7 +82,8 @@ void PropagateRemoteMove::start()
             QString originalFile(_propagator->getFilePath(QLatin1String("Shared")));
             _propagator->addTouchedFile(originalFile);
             _propagator->addTouchedFile(targetFile);
-            if( QFile::rename( targetFile, originalFile) ) {
+            QString renameError;
+            if( FileSystem::rename(targetFile, originalFile, &renameError) ) {
                 done(SyncFileItem::NormalError, tr("This folder must not be renamed. It is renamed back to its original name."));
             } else {
                 done(SyncFileItem::NormalError, tr("This folder must not be renamed. Please name it back to Shared."));
diff --git a/src/libsync/propagator_legacy.cpp b/src/libsync/propagator_legacy.cpp
index 0e8561d..dc714b6 100644
--- a/src/libsync/propagator_legacy.cpp
+++ b/src/libsync/propagator_legacy.cpp
@@ -695,11 +695,11 @@ void PropagateDownloadFileLegacy::start()
         && !FileSystem::fileEquals(fn, tmpFile.fileName()); // compare the files to see if there was an actual conflict.
     //In case of conflict, make a backup of the old file
     if (isConflict) {
-        QFile f(fn);
         QString conflictFileName = makeConflictFileName(fn, Utility::qDateTimeFromTime_t(_item._modtime));
-        if (!f.rename(conflictFileName)) {
+        QString renameError;
+        if (!FileSystem::rename(fn, conflictFileName, &renameError)) {
             //If the rename fails, don't replace it.
-            done(SyncFileItem::NormalError, f.errorString());
+            done(SyncFileItem::NormalError, renameError);
             return;
         }
     }
diff --git a/src/libsync/propagatorjobs.cpp b/src/libsync/propagatorjobs.cpp
index 8c00d28..9f95257 100644
--- a/src/libsync/propagatorjobs.cpp
+++ b/src/libsync/propagatorjobs.cpp
@@ -155,9 +155,9 @@ void PropagateLocalRename::start()
 
         _propagator->addTouchedFile(existingFile);
         _propagator->addTouchedFile(targetFile);
-        QFile file(existingFile);
-        if (!file.rename(targetFile)) {
-            done(SyncFileItem::NormalError, file.errorString());
+        QString renameError;
+        if (!FileSystem::rename(existingFile, targetFile, &renameError)) {
+            done(SyncFileItem::NormalError, renameError);
             return;
         }
     }

-- 
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