[Pkg-owncloud-commits] [owncloud-client] 286/484: Reflect read-only permissions in filesystem #3244

Sandro Knauß hefee-guest at moszumanska.debian.org
Wed Dec 16 00:37:54 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 175ad6fb77fbb80a7372f52355c5c8da493063dc
Author: Christian Kamm <mail at ckamm.de>
Date:   Thu Oct 29 14:10:11 2015 +0100

    Reflect read-only permissions in filesystem #3244
---
 src/libsync/filesystem.cpp        | 32 ++++++++++++++++++++++++++++++++
 src/libsync/filesystem.h          |  8 ++++++++
 src/libsync/propagatedownload.cpp |  4 ++++
 src/libsync/syncengine.cpp        | 26 +++++++++++++++++++++-----
 4 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/src/libsync/filesystem.cpp b/src/libsync/filesystem.cpp
index 5420fd5..9179926 100644
--- a/src/libsync/filesystem.cpp
+++ b/src/libsync/filesystem.cpp
@@ -111,6 +111,38 @@ void FileSystem::setFileHidden(const QString& filename, bool hidden)
 #endif
 }
 
+static QFile::Permissions getDefaultWritePermissions()
+{
+    QFile::Permissions result = QFile::WriteUser;
+#ifndef Q_OS_WIN
+    __mode_t mask = umask(0);
+    umask(mask);
+    if (!(mask & S_IWGRP)) {
+        result |= QFile::WriteGroup;
+    }
+    if (!(mask & S_IWOTH)) {
+        result |= QFile::WriteOther;
+    }
+#endif
+    return result;
+}
+
+void FileSystem::setFileReadOnly(const QString& filename, bool readonly)
+{
+    QFile file(filename);
+    QFile::Permissions permissions = file.permissions();
+
+    QFile::Permissions allWritePermissions =
+            QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther | QFile::WriteOwner;
+    static QFile::Permissions defaultWritePermissions = getDefaultWritePermissions();
+
+    permissions &= ~allWritePermissions;
+    if (!readonly) {
+        permissions |= defaultWritePermissions;
+    }
+    file.setPermissions(permissions);
+}
+
 time_t FileSystem::getModTime(const QString &filename)
 {
     csync_vio_file_stat_t* stat = csync_vio_file_stat_new();
diff --git a/src/libsync/filesystem.h b/src/libsync/filesystem.h
index 8a101cc..e6a760a 100644
--- a/src/libsync/filesystem.h
+++ b/src/libsync/filesystem.h
@@ -47,6 +47,14 @@ bool fileEquals(const QString &fn1, const QString &fn2);
  */
 void OWNCLOUDSYNC_EXPORT setFileHidden(const QString& filename, bool hidden);
 
+/**
+ * @brief Marks the file as read-only.
+ *
+ * On linux this either revokes all 'w' permissions or restores permissions
+ * according to the umask.
+ */
+void OWNCLOUDSYNC_EXPORT setFileReadOnly(const QString& filename, bool readonly);
+
 /** convert a "normal" windows path into a path that can be 32k chars long. */
 QString OWNCLOUDSYNC_EXPORT longWinPath( const QString& inpath );
 
diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp
index 0de8a21..a0fde8a 100644
--- a/src/libsync/propagatedownload.cpp
+++ b/src/libsync/propagatedownload.cpp
@@ -678,6 +678,10 @@ void PropagateDownloadFileQNAM::downloadFinished(const QByteArray& checksumType,
         }
     }
 
+    // Apply the remote permissions
+    FileSystem::setFileReadOnly(_tmpFile.fileName(),
+                                 !_item->_remotePerm.contains('W'));
+
     QString error;
     _propagator->addTouchedFile(fn);
     // The fileChanged() check is done above to generate better error messages.
diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp
index 77c4cab..54ced86 100644
--- a/src/libsync/syncengine.cpp
+++ b/src/libsync/syncengine.cpp
@@ -22,6 +22,7 @@
 #include "creds/abstractcredentials.h"
 #include "syncfilestatus.h"
 #include "csync_private.h"
+#include "filesystem.h"
 
 #ifdef Q_OS_WIN
 #include <windows.h>
@@ -459,16 +460,31 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
         if (remote && item->_should_update_metadata && !item->_isDirectory && item->_instruction == CSYNC_INSTRUCTION_NONE) {
             // Update the database now already:  New fileid or Etag or RemotePerm
             // Or for files that were detected as "resolved conflict".
-            // They should have been a conflict because they both were new, or both
-            // had their local mtime or remote etag modified, but the size and mtime
-            // is the same on the server.  This typically happens when the database is removed.
-            // Nothing will be done for those files, but we still need to update the database.
+
+            // In case of "resolved conflict": there should have been a conflict because they
+            // both were new, or both had their local mtime or remote etag modified, but the
+            // size and mtime is the same on the server.  This typically happens when the
+            // database is removed. Nothing will be done for those files, but we still need
+            // to update the database.
+
+            // This metadata update *could* be a propagation job of its own, but since it's
+            // quick to do and we don't want to create a potentially large number of
+            // mini-jobs later on, we just update metadata right now.
+
+            QString filePath = _localPath + item->_file;
 
             // Even if the mtime is different on the server, we always want to keep the mtime from
             // the file system in the DB, this is to avoid spurious upload on the next sync
             item->_modtime = file->other.modtime;
 
-            _journal->updateFileRecordMetadata(SyncJournalFileRecord(*item, _localPath + item->_file));
+            // If the 'W' remote permission changed, update the local filesystem
+            SyncJournalFileRecord prev = _journal->getFileRecord(item->_file);
+            if (prev._remotePerm.contains('W') != item->_remotePerm.contains('W')) {
+                const bool isReadOnly = !item->_remotePerm.contains('W');
+                FileSystem::setFileReadOnly(filePath, isReadOnly);
+            }
+
+            _journal->updateFileRecordMetadata(SyncJournalFileRecord(*item, filePath));
             item->_should_update_metadata = false;
         }
         if (item->_isDirectory && file->should_update_metadata) {

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