Skip to content
Permalink
Browse files

Reflect read-only permissions in filesystem owncloud#3244

  • Loading branch information...
ckamm committed Oct 29, 2015
1 parent 5189690 commit 175ad6fb77fbb80a7372f52355c5c8da493063dc
Showing with 65 additions and 5 deletions.
  1. +32 −0 src/libsync/filesystem.cpp
  2. +8 −0 src/libsync/filesystem.h
  3. +4 −0 src/libsync/propagatedownload.cpp
  4. +21 −5 src/libsync/syncengine.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();
@@ -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 );

@@ -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.
@@ -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) {

0 comments on commit 175ad6f

Please sign in to comment.
You can’t perform that action at this time.