Skip to content

Commit

Permalink
Merge pull request #68 from Infomaniak/KDESKTOP-774-Implementation-of…
Browse files Browse the repository at this point in the history
…-setRights-method

Kdesktop 774 implementation of set rights method.
  • Loading branch information
herve-er authored May 1, 2024
2 parents 3b47458 + 14d6bde commit b07e33f
Show file tree
Hide file tree
Showing 15 changed files with 680 additions and 222 deletions.
32 changes: 32 additions & 0 deletions src/libcommonserver/io/iohelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,4 +507,36 @@ bool IoHelper::createSymlink(const SyncPath &targetPath, const SyncPath &path, I

return ioError == IoErrorSuccess;
}

#ifndef _WIN32
//See iohelper_win.cpp for the Windows implementation
bool IoHelper::setRights(const SyncPath &path, bool read, bool write, bool exec, IoError &ioError) noexcept {
return _setRightsStd(path, read, write, exec, ioError);
}
#endif

bool IoHelper::_setRightsStd(const SyncPath &path, bool read, bool write, bool exec, IoError &ioError) noexcept {
ioError = IoErrorSuccess;
std::filesystem::perms perms = std::filesystem::perms::none;
if (read) {
perms |= std::filesystem::perms::owner_read;
}
if (write) {
perms |= std::filesystem::perms::owner_write;
}
if (exec) {
perms |= std::filesystem::perms::owner_exec;
}

std::error_code ec;
std::filesystem::permissions(path, perms, ec);
if (ec) {
ioError = posixError2ioError(ec.value());
return _isExpectedError(ioError);
}

return true;
}


} // namespace KDC
32 changes: 28 additions & 4 deletions src/libcommonserver/io/iohelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

#include "libcommon/utility/types.h"
#include "libcommonserver/log/log.h"
#ifdef _WIN32
#include <AccCtrl.h>
#endif

namespace KDC {

Expand All @@ -32,9 +35,9 @@ struct IoHelper {
inline static void setLogger(log4cplus::Logger logger) { _logger = logger; }

#ifdef _WIN32
static int _getRightsMethod;
static int _getAndSetRightsMethod;
#endif

static IoError stdError2ioError(int error) noexcept;
static IoError stdError2ioError(const std::error_code &ec) noexcept;
static IoError posixError2ioError(int error) noexcept;
Expand Down Expand Up @@ -255,8 +258,27 @@ struct IoHelper {
*/
static bool checkIfFileIsDehydrated(const SyncPath &path, bool &isDehydrated, IoError &ioError) noexcept;

// TODO: docstring and unit tests
static bool getRights(const SyncPath &path, bool &read, bool &write, bool &exec, bool &exists) noexcept;
//! Get the rights of the item indicated by `path`.
/*!
\param path is the file system path of the item.
\param read is a boolean indicating whether the item is readable.
\param write is a boolean indicating whether the item is writable.
\param exec is a boolean indicating whether the item is executable.
\param exists is a boolean indicating whether the item exists.
\return true if no unexpected error occurred, false otherwise.
*/
static bool getRights(const SyncPath &path, bool &read, bool &write, bool &exec, IoError &ioError) noexcept;

//! Set the rights of the item indicated by `path`.
/*!
\param path is the file system path of the item.
\param read is a boolean indicating whether the item should be readable.
\param write is a boolean indicating whether the item should be writable.
\param exec is a boolean indicating whether the item should be executable.
\param ioError holds the error returned when an underlying OS API call fails.
\return true if no unexpected error occurred, false otherwise.
*/
static bool setRights(const SyncPath &path, bool read, bool write, bool exec, IoError &ioError) noexcept;

protected:
// These functions default to the std::filesystem functions.
Expand All @@ -283,6 +305,8 @@ struct IoHelper {
#endif
static bool _setTargetType(ItemType &itemType) noexcept;
static bool _checkIfIsHiddenFile(const SyncPath &path, bool &isHidden, IoError &ioError) noexcept;

static bool _setRightsStd(const SyncPath &path, bool read, bool write, bool exec, IoError &ioError) noexcept;
};

} // namespace KDC
16 changes: 6 additions & 10 deletions src/libcommonserver/io/iohelper_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,30 +116,26 @@ bool IoHelper::checkIfFileIsDehydrated(const SyncPath &itemPath, bool &isDehydra
return true;
}

bool IoHelper::getRights(const SyncPath &path, bool &read, bool &write, bool &exec, bool &exists) noexcept {
bool IoHelper::getRights(const SyncPath &path, bool &read, bool &write, bool &exec, IoError &ioError) noexcept {
read = false;
write = false;
exec = false;
exists = false;

std::error_code ec;
std::filesystem::perms perms = std::filesystem::status(path, ec).permissions();
if (ec.value() != 0) {
exists = (ec.value() != static_cast<int>(std::errc::no_such_file_or_directory));
if (ec) {
const bool exists = (ec.value() != static_cast<int>(std::errc::no_such_file_or_directory));
ioError = stdError2ioError(ec);
if (!exists) {
// Path doesn't exist
return true;
ioError = IoErrorNoSuchFileOrDirectory;
}

return false;
return _isExpectedError(ioError);
}

exists = true;
read = ((perms & std::filesystem::perms::owner_read) != std::filesystem::perms::none);
write = ((perms & std::filesystem::perms::owner_write) != std::filesystem::perms::none);
exec = ((perms & std::filesystem::perms::owner_exec) != std::filesystem::perms::none);
return true;
}


} // namespace KDC
28 changes: 12 additions & 16 deletions src/libcommonserver/io/iohelper_mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,40 +213,36 @@ bool IoHelper::checkIfFileIsDehydrated(const SyncPath &itemPath, bool &isDehydra
return true;
}

bool IoHelper::getRights(const SyncPath &path, bool &read, bool &write, bool &exec, bool &exists) noexcept {
bool IoHelper::getRights(const SyncPath &path, bool &read, bool &write, bool &exec, IoError &ioError) noexcept {
read = false;
write = false;
exec = false;
exists = false;

ItemType itemType;
const bool success = getItemType(path, itemType);
if (!success) {
LOGW_WARN(logger(),
L"Failed to check if the item is a symlink: " << Utility::formatIoError(path, itemType.ioError).c_str());
LOGW_WARN(logger(), L"Failed to get item type: " << Utility::formatIoError(path, itemType.ioError).c_str());
return false;
}
exists = itemType.ioError != IoErrorNoSuchFileOrDirectory;
if (!exists) {
return true;
ioError = itemType.ioError;
if (ioError != IoErrorSuccess) {
return _isExpectedError(ioError);
}
const bool isSymlink = itemType.linkType = LinkTypeSymlink;
const bool isSymlink = itemType.linkType == LinkTypeSymlink;

std::error_code ec;
std::filesystem::perms perms =
isSymlink ? std::filesystem::symlink_status(path, ec).permissions() : std::filesystem::status(path, ec).permissions();
if (ec.value() != 0) {
exists = (ec.value() != static_cast<int>(std::errc::no_such_file_or_directory));
if (ec) {
const bool exists = (ec.value() != static_cast<int>(std::errc::no_such_file_or_directory));
ioError = stdError2ioError(ec);
if (!exists) {
// Path doesn't exist
return true;
ioError = IoErrorNoSuchFileOrDirectory;
}

LOGW_WARN(logger(), L"Failed to get permissions - " << Utility::formatStdError(path, ec).c_str());
return false;
LOGW_WARN(logger(), L"Failed to get permissions: " << Utility::formatStdError(path, ec).c_str());
return _isExpectedError(ioError);
}

exists = true;
read = ((perms & std::filesystem::perms::owner_read) != std::filesystem::perms::none);
write = isLocked(path) ? false : ((perms & std::filesystem::perms::owner_write) != std::filesystem::perms::none);
exec = ((perms & std::filesystem::perms::owner_exec) != std::filesystem::perms::none);
Expand Down
Loading

0 comments on commit b07e33f

Please sign in to comment.