new_build_system (#18)
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good

Reviewed-on: #18
This commit is contained in:
2024-09-06 15:05:48 +00:00
parent 9d3e4b8767
commit a7239558bd
191 changed files with 10683 additions and 10598 deletions

View File

@@ -45,9 +45,6 @@ public:
[[nodiscard]] static auto
default_rpc_port(const provider_type &prov) -> std::uint16_t;
[[nodiscard]] static auto
get_provider_api_password(const provider_type &prov) -> std::string;
[[nodiscard]] static auto
get_provider_display_name(const provider_type &prov) -> std::string;

View File

@@ -26,8 +26,7 @@
#include "comm/i_http_comm.hpp"
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "utils/encrypt.hpp"
#include "utils/utils.hpp"
#include "utils/encryption.hpp"
namespace repertory {
class curl_comm final : public i_http_comm {
@@ -42,8 +41,8 @@ private:
using write_callback = size_t (*)(char *, size_t, size_t, void *);
struct read_write_info final {
repertory::data_buffer data{};
repertory::stop_type &stop_requested;
data_buffer data{};
stop_type &stop_requested;
};
static const write_callback write_data;
@@ -56,6 +55,11 @@ private:
private:
bool use_s3_path_style_{false};
public:
[[nodiscard]] static auto create_curl() -> CURL *;
[[nodiscard]] static auto reset_curl(CURL *curl_handle) -> CURL *;
public:
[[nodiscard]] static auto
construct_url(CURL *curl, const std::string &relative_path,
@@ -92,32 +96,31 @@ public:
const auto key =
utils::encryption::generate_key<utils::encryption::hash_256_t>(
request.decryption_token.value());
const auto result = utils::encryption::read_encrypted_range(
request.range.value(), key,
[&](data_buffer &ct, std::uint64_t start_offset,
std::uint64_t end_offset) -> api_error {
auto encrypted_request = request;
encrypted_request.decryption_token = std::nullopt;
encrypted_request.range = {{start_offset, end_offset}};
encrypted_request.response_handler = [&ct](const auto &encrypted_data,
long /*response_code*/) {
ct = encrypted_data;
};
encrypted_request.total_size = std::nullopt;
if (not utils::encryption::read_encrypted_range(
request.range.value(), key,
[&](data_buffer &ct, std::uint64_t start_offset,
std::uint64_t end_offset) -> bool {
auto encrypted_request = request;
encrypted_request.decryption_token = std::nullopt;
encrypted_request.range = {{start_offset, end_offset}};
encrypted_request.response_handler =
[&ct](const auto &encrypted_data, long /*response_code*/) {
ct = encrypted_data;
};
encrypted_request.total_size = std::nullopt;
if (not make_request(cfg, encrypted_request, response_code,
stop_requested)) {
return api_error::comm_error;
}
if (not make_request(cfg, encrypted_request, response_code,
stop_requested)) {
return false;
}
if (response_code != 200) {
return api_error::comm_error;
}
if (response_code != 200) {
return false;
}
return api_error::success;
},
request.total_size.value(), data);
if (result != api_error::success) {
return true;
},
request.total_size.value(), data)) {
return false;
}
@@ -140,7 +143,7 @@ public:
response_code = 0;
auto *curl = utils::create_curl();
auto *curl = create_curl();
if (not request.set_method(curl, stop_requested)) {
return false;
}

View File

@@ -23,7 +23,7 @@
#define INCLUDE_COMM_CURL_CURL_REQUESTS_HTTP_REQUEST_BASE_HPP_
#include "types/repertory.hpp"
#include "utils/native_file.hpp"
#include "utils/file.hpp"
namespace repertory::curl::requests {
using read_callback = size_t (*)(char *, size_t, size_t, void *);
@@ -33,7 +33,7 @@ using response_callback =
struct read_file_info final {
stop_type &stop_requested;
native_file::native_file_ptr nf{};
std::unique_ptr<utils::file::i_file> file{};
std::uint64_t offset{};
};
@@ -41,9 +41,9 @@ inline const auto read_file_data = static_cast<read_callback>(
[](char *buffer, size_t size, size_t nitems, void *instream) -> size_t {
auto *read_info = reinterpret_cast<read_file_info *>(instream);
std::size_t bytes_read{};
auto ret = read_info->nf->read_bytes(
reinterpret_cast<unsigned char *>(buffer), size * nitems,
read_info->offset, bytes_read);
auto ret =
read_info->file->read(reinterpret_cast<unsigned char *>(buffer),
size * nitems, read_info->offset, &bytes_read);
if (ret) {
read_info->offset += bytes_read;
}
@@ -66,7 +66,7 @@ struct http_request_base {
std::optional<std::string> decryption_token{};
http_headers headers{};
std::string path{};
query_parameters query{};
http_query_parameters query{};
std::optional<http_range> range{};
std::optional<response_callback> response_handler;
std::optional<http_headers> response_headers;

View File

@@ -61,17 +61,7 @@ inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION = 0ULL;
inline constexpr const std::string_view REPERTORY_DATA_NAME = "repertory2";
inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION = "2.0.0";
#if defined(_WIN32)
#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
#define REPERTORY_API_INVALID_HANDLE static_cast<std::uint64_t>(-1)
using native_handle = HANDLE;
#else
#define REPERTORY_INVALID_HANDLE (-1)
#define REPERTORY_API_INVALID_HANDLE REPERTORY_INVALID_HANDLE
using native_handle = int;
#endif
inline constexpr const auto NANOS_PER_SECOND = 1000000000L;
#define WINFSP_ALLOCATION_UNIT UINT64(4096U)

View File

@@ -64,15 +64,15 @@ private:
struct fuse_operations fuse_ops_ {};
private:
[[nodiscard]] auto execute_callback(
std::string_view function_name, const char *from, const char *to,
const std::function<api_error(const std::string &, const std::string &)>
&cb,
bool disable_logging = false) -> int;
[[nodiscard]] auto
execute_callback(std::string_view function_name, const char *from,
const char *to,
const std::function<api_error(std::string, std::string)> &cb,
bool disable_logging = false) -> int;
[[nodiscard]] auto
execute_callback(std::string_view function_name, const char *path,
const std::function<api_error(const std::string &)> &cb,
const std::function<api_error(std::string)> &cb,
bool disable_logging = false) -> int;
static void execute_void_callback(std::string_view function_name,
@@ -83,7 +83,7 @@ private:
const std::function<void *()> &cb) -> void *;
void raise_fuse_event(std::string_view function_name,
const std::string &api_path, int ret,
std::string_view api_path, int ret,
bool disable_logging);
private:

View File

@@ -1269,7 +1269,7 @@ public:
data_buffer buffer(write_size);
if ((ret = request->decode(buffer.data(), buffer.size())) == 0) {
buffer = macaron::Base64::Decode(
std::string{buffer.begin(), buffer.end()});
std::string(buffer.begin(), buffer.end()));
write_size = buffer.size();
remote::file_offset write_offset{};

View File

@@ -42,9 +42,9 @@ private:
private:
#if defined(_WIN32)
#define to_handle(x) (x)
#else
#else // !defined(_WIN32)
static auto to_handle(PVOID file_desc) -> native_handle;
#endif
#endif // defined(_WIN32)
public:
auto json_create_directory_snapshot(const std::string &path, json &json_data)

View File

@@ -30,7 +30,7 @@
#include "file_manager/i_upload_manager.hpp"
#include "platform/platform.hpp"
#include "types/repertory.hpp"
#include "utils/native_file.hpp"
#include "utils/file.hpp"
namespace repertory {
class app_config;
@@ -131,7 +131,7 @@ public:
std::atomic<std::chrono::system_clock::time_point> last_access_{
std::chrono::system_clock::now()};
bool modified_{false};
native_file_ptr nf_;
std::unique_ptr<utils::file::i_file> nf_;
mutable std::mutex io_thread_mtx_;
std::condition_variable io_thread_notify_;
std::deque<std::shared_ptr<io_item>> io_thread_queue_;

View File

@@ -29,6 +29,9 @@
namespace repertory {
class encrypt_provider final : public i_provider {
public:
static const constexpr auto type{provider_type::encrypt};
public:
explicit encrypt_provider(app_config &config);
@@ -70,10 +73,9 @@ private:
const std::string &source_path)>
callback) const -> api_error;
auto
process_directory_entry(const std::filesystem::directory_entry &dir_entry,
const encrypt_config &cfg,
std::string &api_path) const -> bool;
auto process_directory_entry(const utils::file::i_fs_item &dir_entry,
const encrypt_config &cfg,
std::string &api_path) const -> bool;
void remove_deleted_files();
@@ -81,74 +83,68 @@ public:
[[nodiscard]] auto create_directory(const std::string &api_path,
api_meta_map &meta) -> api_error override;
[[nodiscard]] auto
create_directory_clone_source_meta(const std::string & /*source_api_path*/,
const std::string & /*api_path*/)
-> api_error override {
return api_error::not_implemented;
}
[[nodiscard]] auto create_file(const std::string & /*api_path*/,
api_meta_map & /*meta*/)
-> api_error override {
[[nodiscard]] auto create_directory_clone_source_meta(
const std::string & /*source_api_path*/,
const std::string & /*api_path*/) -> api_error override {
return api_error::not_implemented;
}
[[nodiscard]] auto
get_api_path_from_source(const std::string & /*source_path*/,
std::string & /*api_path*/) const
-> api_error override;
create_file(const std::string & /*api_path*/,
api_meta_map & /*meta*/) -> api_error override {
return api_error::not_implemented;
}
[[nodiscard]] auto get_api_path_from_source(
const std::string & /*source_path*/,
std::string & /*api_path*/) const -> api_error override;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override;
[[nodiscard]] auto get_directory_items(const std::string &api_path,
directory_item_list &list) const
-> api_error override;
[[nodiscard]] auto
get_directory_items(const std::string &api_path,
directory_item_list &list) const -> api_error override;
[[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const
-> api_error override;
[[nodiscard]] auto get_file_list(api_file_list &list) const
-> api_error override;
[[nodiscard]] auto get_file_size(const std::string &api_path,
std::uint64_t &file_size) const
-> api_error override;
[[nodiscard]] auto get_filesystem_item(const std::string &api_path,
bool directory,
filesystem_item &fsi) const
-> api_error override;
[[nodiscard]] auto get_filesystem_item_and_file(const std::string &api_path,
api_file &file,
filesystem_item &fsi) const
-> api_error override;
[[nodiscard]] auto get_file(const std::string &api_path,
api_file &file) const -> api_error override;
[[nodiscard]] auto
get_filesystem_item_from_source_path(const std::string &source_path,
filesystem_item &fsi) const
-> api_error override;
get_file_list(api_file_list &list) const -> api_error override;
[[nodiscard]] auto get_pinned_files() const
-> std::vector<std::string> override;
[[nodiscard]] auto
get_file_size(const std::string &api_path,
std::uint64_t &file_size) const -> api_error override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
api_meta_map &meta) const
-> api_error override;
[[nodiscard]] auto
get_filesystem_item(const std::string &api_path, bool directory,
filesystem_item &fsi) const -> api_error override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
const std::string &key,
std::string &value) const
-> api_error override;
[[nodiscard]] auto get_filesystem_item_and_file(
const std::string &api_path, api_file &file,
filesystem_item &fsi) const -> api_error override;
[[nodiscard]] auto get_filesystem_item_from_source_path(
const std::string &source_path,
filesystem_item &fsi) const -> api_error override;
[[nodiscard]] auto
get_pinned_files() const -> std::vector<std::string> override;
[[nodiscard]] auto
get_item_meta(const std::string &api_path,
api_meta_map &meta) const -> api_error override;
[[nodiscard]] auto
get_item_meta(const std::string &api_path, const std::string &key,
std::string &value) const -> api_error override;
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t override;
[[nodiscard]] auto get_provider_type() const -> provider_type override {
return provider_type::encrypt;
return type;
}
[[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override;
@@ -158,54 +154,52 @@ public:
[[nodiscard]] auto is_directory(const std::string &api_path,
bool &exists) const -> api_error override;
[[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const
-> api_error override;
[[nodiscard]] auto is_file(const std::string &api_path,
bool &exists) const -> api_error override;
[[nodiscard]] auto is_file_writeable(const std::string &api_path) const
-> bool override;
[[nodiscard]] auto
is_file_writeable(const std::string &api_path) const -> bool override;
[[nodiscard]] auto is_online() const -> bool override;
[[nodiscard]] auto is_rename_supported() const -> bool override;
[[nodiscard]] auto read_file_bytes(const std::string &api_path,
std::size_t size, std::uint64_t offset,
data_buffer &data,
stop_type &stop_requested)
-> api_error override;
[[nodiscard]] auto
read_file_bytes(const std::string &api_path, std::size_t size,
std::uint64_t offset, data_buffer &data,
stop_type &stop_requested) -> api_error override;
[[nodiscard]] auto remove_directory(const std::string & /*api_path*/)
-> api_error override {
[[nodiscard]] auto
remove_directory(const std::string & /*api_path*/) -> api_error override {
return api_error::not_implemented;
}
[[nodiscard]] auto remove_file(const std::string & /*api_path*/)
-> api_error override {
[[nodiscard]] auto
remove_file(const std::string & /*api_path*/) -> api_error override {
return api_error::not_implemented;
}
[[nodiscard]] auto remove_item_meta(const std::string & /*api_path*/,
const std::string & /*key*/)
-> api_error override {
[[nodiscard]] auto
remove_item_meta(const std::string & /*api_path*/,
const std::string & /*key*/) -> api_error override {
return api_error::success;
}
[[nodiscard]] auto rename_file(const std::string & /*from_api_path*/,
const std::string & /*to_api_path*/)
-> api_error override {
[[nodiscard]] auto
rename_file(const std::string & /*from_api_path*/,
const std::string & /*to_api_path*/) -> api_error override {
return api_error::not_implemented;
}
[[nodiscard]] auto set_item_meta(const std::string & /*api_path*/,
const std::string & /*key*/,
const std::string & /*value*/)
-> api_error override {
[[nodiscard]] auto
set_item_meta(const std::string & /*api_path*/, const std::string & /*key*/,
const std::string & /*value*/) -> api_error override {
return api_error::success;
}
[[nodiscard]] auto set_item_meta(const std::string & /*api_path*/,
const api_meta_map & /*meta*/)
-> api_error override {
[[nodiscard]] auto
set_item_meta(const std::string & /*api_path*/,
const api_meta_map & /*meta*/) -> api_error override {
return api_error::success;
}
@@ -214,10 +208,10 @@ public:
void stop() override;
[[nodiscard]] auto upload_file(const std::string & /*api_path*/,
const std::string & /*source_path*/,
stop_type & /*stop_requested*/)
-> api_error override {
[[nodiscard]] auto
upload_file(const std::string & /*api_path*/,
const std::string & /*source_path*/,
stop_type & /*stop_requested*/) -> api_error override {
return api_error::not_implemented;
}
};

View File

@@ -32,6 +32,9 @@ class i_http_comm;
struct head_object_result;
class s3_provider final : public base_provider {
public:
static const constexpr auto type{provider_type::s3};
public:
s3_provider(app_config &config, i_http_comm &comm);
@@ -92,6 +95,9 @@ protected:
stop_type &stop_requested) -> api_error override;
public:
[[nodiscard]] static auto
convert_api_date(std::string_view date) -> std::uint64_t;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override;
@@ -104,7 +110,7 @@ public:
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
[[nodiscard]] auto get_provider_type() const -> provider_type override {
return provider_type::s3;
return type;
}
[[nodiscard]] auto is_direct_only() const -> bool override { return false; }

View File

@@ -31,6 +31,9 @@ class i_file_manager;
class i_http_comm;
class sia_provider : public base_provider {
public:
static const constexpr auto type{provider_type::sia};
public:
sia_provider(app_config &config, i_http_comm &comm);
@@ -50,40 +53,39 @@ private:
nlohmann::json &object_list) const -> bool;
protected:
[[nodiscard]] auto create_directory_impl(const std::string &api_path,
api_meta_map &meta)
-> api_error override;
[[nodiscard]] auto
create_directory_impl(const std::string &api_path,
api_meta_map &meta) -> api_error override;
[[nodiscard]] auto get_directory_items_impl(const std::string &api_path,
directory_item_list &list) const
-> api_error override;
[[nodiscard]] auto get_used_drive_space_impl() const
-> std::uint64_t override;
[[nodiscard]] auto
get_used_drive_space_impl() const -> std::uint64_t override;
[[nodiscard]] auto remove_directory_impl(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto
remove_directory_impl(const std::string &api_path) -> api_error override;
[[nodiscard]] auto remove_file_impl(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto
remove_file_impl(const std::string &api_path) -> api_error override;
[[nodiscard]] auto upload_file_impl(const std::string &api_path,
const std::string &source_path,
stop_type &stop_requested)
-> api_error override;
[[nodiscard]] auto
upload_file_impl(const std::string &api_path, const std::string &source_path,
stop_type &stop_requested) -> api_error override;
public:
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override;
[[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const
-> api_error override;
[[nodiscard]] auto get_file(const std::string &api_path,
api_file &file) const -> api_error override;
[[nodiscard]] auto get_file_list(api_file_list &list) const
-> api_error override;
[[nodiscard]] auto
get_file_list(api_file_list &list) const -> api_error override;
[[nodiscard]] auto get_provider_type() const -> provider_type override {
return provider_type::sia;
return type;
}
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
@@ -93,8 +95,8 @@ public:
[[nodiscard]] auto is_directory(const std::string &api_path,
bool &exists) const -> api_error override;
[[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const
-> api_error override;
[[nodiscard]] auto is_file(const std::string &api_path,
bool &exists) const -> api_error override;
[[nodiscard]] auto is_online() const -> bool override;
@@ -102,15 +104,14 @@ public:
return true;
}
[[nodiscard]] auto read_file_bytes(const std::string &api_path,
std::size_t size, std::uint64_t offset,
data_buffer &buffer,
stop_type &stop_requested)
-> api_error override;
[[nodiscard]] auto
read_file_bytes(const std::string &api_path, std::size_t size,
std::uint64_t offset, data_buffer &buffer,
stop_type &stop_requested) -> api_error override;
[[nodiscard]] auto rename_file(const std::string &from_api_path,
const std::string &to_api_path)
-> api_error override;
[[nodiscard]] auto
rename_file(const std::string &from_api_path,
const std::string &to_api_path) -> api_error override;
[[nodiscard]] auto start(api_item_added_callback api_item_added,
i_file_manager *mgr) -> bool override;

View File

@@ -22,14 +22,14 @@
#ifndef INCLUDE_TYPES_REMOTE_HPP_
#define INCLUDE_TYPES_REMOTE_HPP_
#define PACKET_SERVICE_FUSE 1U
#define PACKET_SERVICE_WINFSP 2U
inline constexpr const auto PACKET_SERVICE_FUSE{1U};
inline constexpr const auto PACKET_SERVICE_WINFSP{2U};
#if defined(_WIN32)
#define PACKET_SERVICE_FLAGS PACKET_SERVICE_WINFSP
#else
#define PACKET_SERVICE_FLAGS PACKET_SERVICE_FUSE
#endif
inline constexpr const auto PACKET_SERVICE_FLAGS{PACKET_SERVICE_WINFSP};
#else // !defined(_WIN32)
inline constexpr const auto PACKET_SERVICE_FLAGS{PACKET_SERVICE_FUSE};
#endif // defined(_WIN32)
namespace repertory::remote {
using block_count = std::uint64_t;
@@ -65,16 +65,19 @@ enum class open_flags : std::uint32_t {
dsync = 131072U,
};
inline auto operator|(const open_flags &flag_1,
const open_flags &flag_2) -> open_flags {
using t = std::underlying_type_t<open_flags>;
return static_cast<open_flags>(static_cast<t>(flag_1) |
static_cast<t>(flag_2));
#if defined(__GNUG__)
__attribute__((unused))
#endif // defined(__GNUG__)
inline auto
operator|(const open_flags &flag_1, const open_flags &flag_2) -> open_flags {
using flag_t = std::underlying_type_t<open_flags>;
return static_cast<open_flags>(static_cast<flag_t>(flag_1) |
static_cast<flag_t>(flag_2));
}
#if defined(__GNUG__)
__attribute__((unused))
#endif
#endif // defined(__GNUG__)
inline auto
operator|=(open_flags &flag_1, const open_flags &flag_2) -> open_flags & {
flag_1 = flag_1 | flag_2;
@@ -83,69 +86,69 @@ operator|=(open_flags &flag_1, const open_flags &flag_2) -> open_flags & {
#if defined(__GNUG__)
__attribute__((unused))
#endif
#endif // defined(__GNUG__)
inline auto
operator&(const open_flags &flag_1, const open_flags &flag_2) -> open_flags {
using t = std::underlying_type_t<open_flags>;
return static_cast<open_flags>(static_cast<t>(flag_1) &
static_cast<t>(flag_2));
using flag_t = std::underlying_type_t<open_flags>;
return static_cast<open_flags>(static_cast<flag_t>(flag_1) &
static_cast<flag_t>(flag_2));
}
#pragma pack(1)
struct file_info {
UINT32 FileAttributes;
UINT32 ReparseTag;
UINT64 AllocationSize;
UINT64 FileSize;
UINT64 CreationTime;
UINT64 LastAccessTime;
UINT64 LastWriteTime;
UINT64 ChangeTime;
UINT64 IndexNumber;
UINT32 HardLinks;
UINT32 EaSize;
struct file_info final {
UINT32 FileAttributes{};
UINT32 ReparseTag{};
UINT64 AllocationSize{};
UINT64 FileSize{};
UINT64 CreationTime{};
UINT64 LastAccessTime{};
UINT64 LastWriteTime{};
UINT64 ChangeTime{};
UINT64 IndexNumber{};
UINT32 HardLinks{};
UINT32 EaSize{};
};
struct setattr_x {
std::int32_t valid;
file_mode mode;
user_id uid;
group_id gid;
file_size size;
file_time acctime;
file_time modtime;
file_time crtime;
file_time chgtime;
file_time bkuptime;
std::uint32_t flags;
struct setattr_x final {
std::int32_t valid{};
file_mode mode{};
user_id uid{};
group_id gid{};
file_size size{};
file_time acctime{};
file_time modtime{};
file_time crtime{};
file_time chgtime{};
file_time bkuptime{};
std::uint32_t flags{};
};
struct stat {
file_mode st_mode;
file_nlink st_nlink;
user_id st_uid;
group_id st_gid;
file_time st_atimespec;
file_time st_mtimespec;
file_time st_ctimespec;
file_time st_birthtimespec;
file_size st_size;
block_count st_blocks;
block_size st_blksize;
std::uint32_t st_flags;
struct stat final {
file_mode st_mode{};
file_nlink st_nlink{};
user_id st_uid{};
group_id st_gid{};
file_time st_atimespec{};
file_time st_mtimespec{};
file_time st_ctimespec{};
file_time st_birthtimespec{};
file_size st_size{};
block_count st_blocks{};
block_size st_blksize{};
std::uint32_t st_flags{};
};
struct statfs {
std::uint64_t f_bavail;
std::uint64_t f_bfree;
std::uint64_t f_blocks;
std::uint64_t f_favail;
std::uint64_t f_ffree;
std::uint64_t f_files;
std::uint64_t f_bavail{};
std::uint64_t f_bfree{};
std::uint64_t f_blocks{};
std::uint64_t f_favail{};
std::uint64_t f_ffree{};
std::uint64_t f_files{};
};
struct statfs_x : public statfs {
char f_mntfromname[1024];
struct statfs_x final : public statfs {
std::array<char, 1024U> f_mntfromname{};
};
#pragma pack()
@@ -154,7 +157,7 @@ struct statfs_x : public statfs {
[[nodiscard]] auto
create_os_open_flags(const open_flags &flags) -> std::uint32_t;
#endif
#endif // !defined(_WIN32)
} // namespace repertory::remote
#endif // INCLUDE_TYPES_REMOTE_HPP_

View File

@@ -23,26 +23,26 @@
#define INCLUDE_TYPES_REPERTORY_HPP_
namespace repertory {
constexpr const auto max_time = 0xFFFFFFFFFFFFFFFFULL;
inline constexpr const auto max_time{std::numeric_limits<std::uint64_t>::max()};
const std::string META_ACCESSED = "accessed";
const std::string META_ATTRIBUTES = "attributes";
const std::string META_BACKUP = "backup";
const std::string META_CHANGED = "changed";
const std::string META_CREATION = "creation";
const std::string META_DIRECTORY = "directory";
const std::string META_GID = "gid";
const std::string META_KEY = "key";
const std::string META_MODE = "mode";
const std::string META_MODIFIED = "modified";
const std::string META_OSXFLAGS = "flags";
const std::string META_PINNED = "pinned";
const std::string META_SIZE = "size";
const std::string META_SOURCE = "source";
const std::string META_UID = "uid";
const std::string META_WRITTEN = "written";
inline constexpr const std::string META_ACCESSED{"accessed"};
inline constexpr const std::string META_ATTRIBUTES{"attributes"};
inline constexpr const std::string META_BACKUP{"backup"};
inline constexpr const std::string META_CHANGED{"changed"};
inline constexpr const std::string META_CREATION{"creation"};
inline constexpr const std::string META_DIRECTORY{"directory"};
inline constexpr const std::string META_GID{"gid"};
inline constexpr const std::string META_KEY{"key"};
inline constexpr const std::string META_MODE{"mode"};
inline constexpr const std::string META_MODIFIED{"modified"};
inline constexpr const std::string META_OSXFLAGS{"flags"};
inline constexpr const std::string META_PINNED{"pinned"};
inline constexpr const std::string META_SIZE{"size"};
inline constexpr const std::string META_SOURCE{"source"};
inline constexpr const std::string META_UID{"uid"};
inline constexpr const std::string META_WRITTEN{"written"};
const std::vector<std::string> META_USED_NAMES = {
inline constexpr const std::array<std::string, 16U> META_USED_NAMES = {
META_ACCESSED, META_ATTRIBUTES, META_BACKUP, META_CHANGED,
META_CREATION, META_DIRECTORY, META_GID, META_KEY,
META_MODE, META_MODIFIED, META_OSXFLAGS, META_PINNED,
@@ -51,8 +51,6 @@ const std::vector<std::string> META_USED_NAMES = {
using api_meta_map = std::map<std::string, std::string>;
using stop_type = std::atomic<bool>;
enum class api_error {
success = 0,
access_denied,
@@ -152,28 +150,28 @@ enum class provider_type : std::size_t {
};
#if defined(_WIN32)
struct open_file_data {
struct open_file_data final {
void *directory_buffer{};
};
#else
using open_file_data = int;
#endif
struct api_file {
std::string api_path;
std::string api_parent;
struct api_file final {
std::string api_path{};
std::string api_parent{};
std::uint64_t accessed_date{};
std::uint64_t changed_date{};
std::uint64_t creation_date{};
std::uint64_t file_size{};
std::string key;
std::string key{};
std::uint64_t modified_date{};
std::string source_path;
};
struct directory_item {
std::string api_path;
std::string api_parent;
struct directory_item final {
std::string api_path{};
std::string api_parent{};
bool directory{false};
std::uint64_t size{};
api_meta_map meta{};
@@ -190,26 +188,30 @@ struct directory_item {
}
[[nodiscard]] auto to_json() const -> json {
return {{"path", api_path},
{"parent", api_parent},
{"size", size},
{"directory", directory},
{"meta", meta}};
return {
{"path", api_path}, {"parent", api_parent}, {"size", size},
{"directory", directory}, {"meta", meta},
};
}
};
struct filesystem_item {
std::string api_path;
std::string api_parent;
bool directory{false};
std::uint64_t size{};
std::string source_path;
struct encrypt_config final {
std::string encryption_token{};
std::string path{};
};
struct host_config {
std::string agent_string;
std::string api_password;
std::string api_user;
struct filesystem_item final {
std::string api_path{};
std::string api_parent{};
bool directory{false};
std::uint64_t size{};
std::string source_path{};
};
struct host_config final {
std::string agent_string{};
std::string api_password{};
std::string api_user{};
std::uint16_t api_port{};
std::string host_name_or_ip{"localhost"};
std::string path{};
@@ -265,25 +267,15 @@ from_json(const json &j, host_config &hc) {
j.at("TimeoutMs").get_to(hc.timeout_ms);
}
struct http_range {
std::uint64_t begin;
std::uint64_t end;
};
struct encrypt_config {
std::string encryption_token;
std::string path;
};
struct s3_config {
std::string access_key;
std::string bucket;
struct s3_config final {
std::string access_key{};
std::string bucket{};
std::uint16_t cache_timeout_secs{60U};
std::string encryption_token;
std::string encryption_token{};
std::string region{"any"};
std::string secret_key;
std::string secret_key{};
std::uint32_t timeout_ms{60000U};
std::string url;
std::string url{};
bool use_path_style{false};
bool use_region_in_url{false};
};
@@ -292,11 +284,7 @@ using api_file_list = std::vector<api_file>;
using api_file_provider_callback = std::function<void(api_file &)>;
using api_item_added_callback = std::function<api_error(bool, api_file &)>;
using directory_item_list = std::vector<directory_item>;
using http_headers = std::unordered_map<std::string, std::string>;
using http_parameters = std::unordered_map<std::string, std::string>;
using http_ranges = std::vector<http_range>;
using meta_provider_callback = std::function<void(directory_item &)>;
using query_parameters = std::map<std::string, std::string>;
} // namespace repertory
#endif // INCLUDE_TYPES_REPERTORY_HPP_

View File

@@ -79,8 +79,8 @@ struct head_object_result {
#else
strptime(date.c_str(), "%a, %d %b %Y %H:%M:%S %Z", &tm1);
#endif
last_modified =
static_cast<std::uint64_t>(mktime(&tm1)) * NANOS_PER_SECOND;
last_modified = static_cast<std::uint64_t>(mktime(&tm1)) *
utils::time::NANOS_PER_SECOND;
}
return *this;
}

View File

@@ -1,49 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_UTILS_ACTION_QUEUE_HPP_
#define INCLUDE_UTILS_ACTION_QUEUE_HPP_
#include "utils/single_thread_service_base.hpp"
namespace repertory::utils::action_queue {
class action_queue final : single_thread_service_base {
explicit action_queue(const std::string &id,
std::uint8_t max_concurrent_actions = 5u);
private:
std::string id_;
std::uint8_t max_concurrent_actions_;
private:
std::deque<std::function<void()>> queue_;
mutable std::mutex queue_mtx_;
std::condition_variable queue_notify_;
protected:
void service_function() override;
public:
void push(std::function<void()> action);
};
} // namespace repertory::utils::action_queue
#endif // INCLUDE_UTILS_ACTION_QUEUE_HPP_

View File

@@ -1,46 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_UTILS_ENCRYPT_HPP_
#define INCLUDE_UTILS_ENCRYPT_HPP_
#include "types/repertory.hpp"
#include "utils/encryption.hpp"
namespace repertory::utils::encryption {
using reader_func = std::function<api_error(data_buffer &cypher_text,
std::uint64_t start_offset,
std::uint64_t end_offset)>;
// Prototypes
[[nodiscard]] auto decrypt_file_path(std::string_view encryption_token,
std::string &file_path) -> api_error;
[[nodiscard]] auto decrypt_file_name(std::string_view encryption_token,
std::string &file_name) -> api_error;
[[nodiscard]] auto
read_encrypted_range(const http_range &range,
const utils::encryption::hash_256_t &key,
reader_func reader, std::uint64_t total_size,
data_buffer &data) -> api_error;
} // namespace repertory::utils::encryption
#endif // INCLUDE_UTILS_ENCRYPT_HPP_

View File

@@ -1,140 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_UTILS_ENCRYPTING_READER_HPP_
#define INCLUDE_UTILS_ENCRYPTING_READER_HPP_
#include "types/repertory.hpp"
#include "utils/encryption.hpp"
#include "utils/native_file.hpp"
namespace repertory::utils::encryption {
class encrypting_reader final {
public:
encrypting_reader(std::string_view file_name, std::string_view source_path,
stop_type &stop_requested, std::string_view token,
std::optional<std::string_view> relative_parent_path,
std::size_t error_return = 0U);
encrypting_reader(std::string_view encrypted_file_path,
std::string_view source_path, stop_type &stop_requested,
std::string_view token, std::size_t error_return = 0U);
encrypting_reader(
std::string_view encrypted_file_path, std::string_view source_path,
stop_type &stop_requested, std::string_view token,
std::vector<std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list,
std::size_t error_return = 0U);
encrypting_reader(const encrypting_reader &reader);
encrypting_reader(encrypting_reader &&) = delete;
auto operator=(const encrypting_reader &) -> encrypting_reader & = delete;
auto operator=(encrypting_reader &&) -> encrypting_reader & = delete;
~encrypting_reader();
public:
using iostream = std::basic_iostream<char, std::char_traits<char>>;
using streambuf = std::basic_streambuf<char, std::char_traits<char>>;
private:
utils::encryption::hash_256_t key_;
stop_type &stop_requested_;
size_t error_return_;
std::unordered_map<std::size_t, data_buffer> chunk_buffers_;
std::string encrypted_file_name_;
std::string encrypted_file_path_;
std::vector<
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list_;
std::size_t last_data_chunk_{};
std::size_t last_data_chunk_size_{};
std::uint64_t read_offset_{};
native_file_ptr source_file_;
std::uint64_t total_size_{};
private:
static const std::size_t header_size_;
static const std::size_t data_chunk_size_;
static const std::size_t encrypted_chunk_size_;
private:
auto reader_function(char *buffer, size_t size, size_t nitems) -> size_t;
public:
[[nodiscard]] static auto
calculate_decrypted_size(std::uint64_t total_size) -> std::uint64_t;
[[nodiscard]] static auto
calculate_encrypted_size(std::string_view source_path) -> std::uint64_t;
[[nodiscard]] auto create_iostream() const -> std::shared_ptr<iostream>;
[[nodiscard]] static constexpr auto
get_encrypted_chunk_size() -> std::size_t {
return encrypted_chunk_size_;
}
[[nodiscard]] static constexpr auto get_data_chunk_size() -> std::size_t {
return data_chunk_size_;
}
[[nodiscard]] auto get_encrypted_file_name() const -> std::string {
return encrypted_file_name_;
}
[[nodiscard]] auto get_encrypted_file_path() const -> std::string {
return encrypted_file_path_;
}
[[nodiscard]] auto get_error_return() const -> std::size_t {
return error_return_;
}
[[nodiscard]] auto get_iv_list()
-> std::vector<std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> {
return iv_list_;
}
[[nodiscard]] auto get_stop_requested() const -> bool {
return stop_requested_;
}
[[nodiscard]] auto get_total_size() const -> std::uint64_t {
return total_size_;
}
[[nodiscard]] static auto reader_function(char *buffer, size_t size,
size_t nitems,
void *instream) -> size_t {
return reinterpret_cast<encrypting_reader *>(instream)->reader_function(
buffer, size, nitems);
}
void set_read_position(std::uint64_t position) { read_offset_ = position; }
};
} // namespace repertory::utils::encryption
#endif // INCLUDE_UTILS_ENCRYPTING_READER_HPP_

View File

@@ -22,64 +22,17 @@
#ifndef INCLUDE_UTILS_FILE_UTILS_HPP_
#define INCLUDE_UTILS_FILE_UTILS_HPP_
#include "types/repertory.hpp"
#include "utils/file.hpp"
#include "utils/native_file.hpp"
namespace repertory::utils::file {
// Prototypes
[[nodiscard]] auto calculate_used_space(std::string path,
bool recursive) -> std::uint64_t;
void change_to_process_directory();
[[nodiscard]] auto copy_directory_recursively(std::string from_path,
std::string to_path) -> bool;
[[nodiscard]] auto copy_file(std::string from_path,
std::string to_path) -> bool;
[[nodiscard]] auto create_full_directory_path(std::string path) -> bool;
[[nodiscard]] auto delete_directory(std::string path,
bool recursive = false) -> bool;
[[nodiscard]] auto delete_directory_recursively(std::string path) -> bool;
[[nodiscard]] auto delete_file(std::string path) -> bool;
[[nodiscard]] auto generate_sha256(const std::string &file_path) -> std::string;
[[nodiscard]] auto get_accessed_time(const std::string &path,
std::uint64_t &accessed) -> bool;
[[nodiscard]] auto
get_directory_files(std::string path, bool oldest_first,
get_directory_files(std::string_view path, bool oldest_first,
bool recursive = false) -> std::deque<std::string>;
[[nodiscard]] auto
get_free_drive_space(const std::string &path) -> std::uint64_t;
[[nodiscard]] auto
get_total_drive_space(const std::string &path) -> std::uint64_t;
[[nodiscard]] auto get_modified_time(const std::string &path,
std::uint64_t &modified) -> bool;
[[nodiscard]] auto
is_modified_date_older_than(const std::string &path,
const std::chrono::hours &hours) -> bool;
[[nodiscard]] auto move_file(std::string from, std::string to) -> bool;
[[nodiscard]] auto
read_file_lines(const std::string &path) -> std::vector<std::string>;
[[nodiscard]] auto reset_modified_time(const std::string &path) -> bool;
[[nodiscard]] auto retry_delete_directory(const std::string &dir) -> bool;
[[nodiscard]] auto retry_delete_file(const std::string &file) -> bool;
} // namespace repertory::utils::file
#endif // INCLUDE_UTILS_FILE_UTILS_HPP_

View File

@@ -1,117 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_UTILS_NATIVEFILE_HPP_
#define INCLUDE_UTILS_NATIVEFILE_HPP_
#include "types/repertory.hpp"
namespace repertory {
class native_file final {
public:
native_file(const native_file &) = delete;
native_file(native_file &&) = delete;
auto operator=(const native_file &) -> native_file & = delete;
auto operator=(native_file &&) -> native_file & = delete;
using native_file_ptr = std::shared_ptr<native_file>;
public:
[[nodiscard]] static auto attach(native_handle handle) -> native_file_ptr {
return std::shared_ptr<native_file>(new native_file(handle));
}
[[nodiscard]] static auto
clone(const native_file_ptr &ptr) -> native_file_ptr;
[[nodiscard]] static auto create_or_open(std::string_view source_path,
bool read_only,
native_file_ptr &ptr) -> api_error;
[[nodiscard]] static auto create_or_open(std::string_view source_path,
native_file_ptr &ptr) -> api_error;
[[nodiscard]] static auto open(std::string_view source_path,
native_file_ptr &ptr) -> api_error;
[[nodiscard]] static auto open(std::string_view source_path, bool read_only,
native_file_ptr &ptr) -> api_error;
private:
explicit native_file(const native_handle &handle) : handle_(handle) {}
public:
~native_file();
private:
native_handle handle_;
private:
bool auto_close{false};
#if defined(_WIN32)
std::recursive_mutex read_write_mutex_;
#endif
public:
[[nodiscard]] auto allocate(std::uint64_t file_size) -> bool;
void close();
[[nodiscard]] auto copy_from(const native_file_ptr &ptr) -> bool;
[[nodiscard]] auto copy_from(const std::string &path) -> bool;
void flush();
[[nodiscard]] auto get_file_size(std::uint64_t &file_size) -> bool;
[[nodiscard]] auto get_handle() -> native_handle;
#if defined(_WIN32)
[[nodiscard]] auto read_bytes(unsigned char *buffer, std::size_t read_size,
std::uint64_t read_offset,
std::size_t &bytes_read) -> bool;
#else
[[nodiscard]] auto read_bytes(unsigned char *buffer, std::size_t read_size,
std::uint64_t read_offset,
std::size_t &bytes_read) -> bool;
#endif
void set_auto_close(bool b) { auto_close = b; }
[[nodiscard]] auto truncate(std::uint64_t file_size) -> bool;
#if defined(_WIN32)
[[nodiscard]] auto write_bytes(const unsigned char *buffer,
std::size_t write_size,
std::uint64_t write_offset,
std::size_t &bytes_written) -> bool;
#else
[[nodiscard]] auto write_bytes(const unsigned char *buffer,
std::size_t write_size,
std::uint64_t write_offset,
std::size_t &bytes_written) -> bool;
#endif
};
using native_file_ptr = native_file::native_file_ptr;
} // namespace repertory
#endif // INCLUDE_UTILS_NATIVEFILE_HPP_

View File

@@ -43,15 +43,9 @@ inline const std::array<std::string, 4U> attribute_namespaces = {
[[nodiscard]] auto unix_error_to_windows(int err) -> std::uint32_t;
[[nodiscard]] auto
unix_time_to_windows_time(const remote::file_time &file_time) -> UINT64;
void windows_create_to_unix(const UINT32 &create_options,
const UINT32 &granted_access, std::uint32_t &flags,
remote::file_mode &mode);
[[nodiscard]] auto
windows_time_to_unix_time(std::uint64_t win_time) -> remote::file_time;
} // namespace repertory::utils
#endif // !_WIN32

View File

@@ -29,27 +29,10 @@ void calculate_allocation_size(bool directory, std::uint64_t file_size,
UINT64 allocation_size,
std::string &allocation_meta_size);
[[nodiscard]] auto convert_api_date(const std::string &date) -> std::uint64_t;
[[nodiscard]] auto create_curl() -> CURL *;
[[nodiscard]] auto
create_volume_label(const provider_type &prov) -> std::string;
[[nodiscard]] auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD;
[[nodiscard]] auto reset_curl(CURL *curl_handle) -> CURL *;
[[nodiscard]] auto
retryable_action(const std::function<bool()> &action) -> bool;
void spin_wait_for_mutex(std::function<bool()> complete,
std::condition_variable &cond, std::mutex &mtx,
const std::string &text = "");
void spin_wait_for_mutex(bool &complete, std::condition_variable &cond,
std::mutex &mtx, const std::string &text = "");
} // namespace repertory::utils
#endif // INCLUDE_UTILS_UTILS_HPP_

View File

@@ -100,18 +100,17 @@ app_config::app_config(const provider_type &prov,
log_directory_ = utils::path::combine(data_directory_, {"logs"});
hc_.agent_string = default_agent_name(prov_);
hc_.api_password = get_provider_api_password(prov_);
hc_.api_port = default_api_port(prov_);
if (not utils::file::create_full_directory_path(data_directory_)) {
if (not utils::file::directory(data_directory_).create_directory()) {
throw startup_exception("unable to create: " + data_directory_);
}
if (not utils::file::create_full_directory_path(cache_directory_)) {
if (not utils::file::directory(cache_directory_).create_directory()) {
throw startup_exception("unable to create: " + cache_directory_);
}
if (not utils::file::create_full_directory_path(log_directory_)) {
if (not utils::file::directory(log_directory_).create_directory()) {
throw startup_exception("unable to create: " + log_directory_);
}
@@ -318,39 +317,12 @@ auto app_config::get_json() const -> json {
}
auto app_config::get_max_cache_size_bytes() const -> std::uint64_t {
const auto max_space =
auto max_space =
std::max(static_cast<std::uint64_t>(100ULL * 1024ULL * 1024ULL),
max_cache_size_bytes_);
return std::min(utils::file::get_free_drive_space(get_cache_directory()),
max_space);
}
auto app_config::get_provider_api_password(const provider_type &prov)
-> std::string {
#if defined(_WIN32)
auto api_file = utils::path::combine(utils::get_local_app_data_directory(),
{
get_provider_display_name(prov),
"apipassword",
});
#else
#if defined(__APPLE__)
auto api_file = utils::path::combine("~", {
"/",
"Library",
"Application Support",
get_provider_display_name(prov),
"apipassword",
});
#else
auto api_file = utils::path::combine("~/.", {
get_provider_name(prov),
"apipassword",
});
#endif
#endif
auto lines = utils::file::read_file_lines(api_file);
return lines.empty() ? "" : utils::string::trim(lines[0U]);
auto free_space = utils::file::get_free_drive_space(get_cache_directory());
return free_space.has_value() ? std::min(free_space.value(), max_space)
: max_space;
}
auto app_config::get_provider_display_name(const provider_type &prov)
@@ -542,12 +514,11 @@ auto app_config::load() -> bool {
static_cast<const char *>(__FUNCTION__),
};
auto ret = false;
auto ret{false};
const auto config_file_path = get_config_file_path();
std::cout << config_file_path << std::endl;
recur_mutex_lock lock(read_write_mutex_);
if (utils::file::is_file(config_file_path)) {
if (utils::file::file(config_file_path).exists()) {
try {
std::ifstream config_file(config_file_path.data());
if (config_file.is_open()) {
@@ -606,13 +577,6 @@ auto app_config::load() -> bool {
ret = false;
}
if (hc_.api_password.empty()) {
hc_.api_password = get_provider_api_password(prov_);
if (hc_.api_password.empty()) {
ret = false;
}
}
if (json_document.find("S3Config") != json_document.end()) {
auto s3_config_json = json_document["S3Config"];
auto s3_cfg = s3_config_;
@@ -713,9 +677,9 @@ void app_config::save() {
const auto file_path = get_config_file_path();
recur_mutex_lock lock(read_write_mutex_);
if (config_changed_ || not utils::file::is_file(file_path)) {
if (not utils::file::is_directory(data_directory_)) {
if (not utils::file::create_full_directory_path(data_directory_)) {
if (config_changed_ || not utils::file::file(file_path).exists()) {
if (not utils::file::directory(data_directory_).exists()) {
if (not utils::file::directory{data_directory_}.create_directory()) {
utils::error::raise_error(
function_name, "failed to create directory|sp|" + data_directory_ +
"|err|" +

View File

@@ -92,6 +92,16 @@ auto curl_comm::construct_url(CURL *curl, const std::string &relative_path,
relative_path, url);
}
auto curl_comm::create_curl() -> CURL * { return reset_curl(curl_easy_init()); }
auto curl_comm::reset_curl(CURL *curl_handle) -> CURL * {
curl_easy_reset(curl_handle);
#if defined(__APPLE__)
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
#endif // defined(__APPLE__)
return curl_handle;
}
auto curl_comm::create_host_config(const s3_config &cfg,
bool use_s3_path_style) -> host_config {
host_config host_cfg{};

View File

@@ -24,8 +24,8 @@
#include "utils/string.hpp"
namespace repertory::curl::requests {
auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const
-> bool {
auto http_put_file::set_method(CURL *curl,
stop_type &stop_requested) const -> bool {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
@@ -46,19 +46,14 @@ auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const
read_info = std::make_shared<read_file_info>(read_file_info{
stop_requested,
utils::file::file::open_or_create_file(source_path),
});
if (native_file::create_or_open(source_path, read_info->nf) !=
api_error::success) {
if (not *read_info->file) {
return false;
}
read_info->nf->set_auto_close(true);
std::uint64_t file_size{};
if (not read_info->nf->get_file_size(file_size)) {
return false;
}
auto file_size = read_info->file->size();
curl_easy_setopt(curl, CURLOPT_READDATA, read_info.get());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_file_data);

View File

@@ -38,7 +38,7 @@ void packet::clear() {
auto packet::decode(std::string &data) -> packet::error_type {
const auto *str = reinterpret_cast<const char *>(&buffer_[decode_offset_]);
const auto length = strnlen(str, buffer_.size() - decode_offset_);
data = std::string{str, length};
data = std::string(str, length);
decode_offset_ += (length + 1);
return utils::from_api_error(api_error::success);
@@ -194,7 +194,7 @@ auto packet::decode(remote::statfs &val) -> packet::error_type {
auto packet::decode(remote::statfs_x &val) -> packet::error_type {
auto ret = decode(*dynamic_cast<remote::statfs *>(&val));
if (ret == 0) {
ret = decode(&val.f_mntfromname[0U], sizeof(val.f_mntfromname));
ret = decode(val.f_mntfromname.data(), val.f_mntfromname.size());
}
return ret;
}
@@ -372,9 +372,9 @@ void packet::encode(remote::statfs val, bool should_reserve) {
void packet::encode(remote::statfs_x val) {
buffer_.reserve(buffer_.size() + sizeof(remote::statfs) +
sizeof(val.f_mntfromname));
val.f_mntfromname.size());
encode(*dynamic_cast<remote::statfs *>(&val), false);
encode(&val.f_mntfromname[0], sizeof(val.f_mntfromname), false);
encode(val.f_mntfromname.data(), val.f_mntfromname.size(), false);
}
void packet::encode(remote::file_info val) {
@@ -501,8 +501,8 @@ void packet::encode_top(remote::statfs val, bool should_reserve) {
void packet::encode_top(remote::statfs_x val) {
buffer_.reserve(buffer_.size() + sizeof(remote::statfs) +
sizeof(val.f_mntfromname));
encode_top(&val.f_mntfromname[0], sizeof(val.f_mntfromname), false);
val.f_mntfromname.size());
encode_top(val.f_mntfromname.data(), val.f_mntfromname.size(), false);
encode_top(*dynamic_cast<remote::statfs *>(&val), false);
}

View File

@@ -85,7 +85,7 @@ void directory_cache::service_function() {
auto lookup = directory_lookup_;
directory_lock.unlock();
for (const auto &kv : lookup) {
for (auto &&kv : lookup) {
if (std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now() - kv.second.last_update) >= 120s) {
directory_lock.lock();

View File

@@ -38,37 +38,31 @@ auto eviction::check_minimum_requirements(const std::string &file_path)
static_cast<const char *>(__FUNCTION__),
};
std::uint64_t file_size{};
if (not utils::file::get_file_size(file_path, file_size)) {
auto opt_size = utils::file::file{file_path}.size();
if (not opt_size.has_value()) {
utils::error::raise_error(function_name, utils::get_last_error_code(),
file_path, "failed to get file size");
return false;
}
auto ret = false;
if (file_size != 0U) {
std::uint64_t reference_time{};
ret = config_.get_eviction_uses_accessed_time()
? utils::file::get_accessed_time(file_path, reference_time)
: utils::file::get_modified_time(file_path, reference_time);
if (ret) {
#if defined(_WIN32)
const auto now = std::chrono::system_clock::now();
const auto delay =
std::chrono::minutes(config_.get_eviction_delay_mins());
ret = ((std::chrono::system_clock::from_time_t(
static_cast<time_t>(reference_time)) +
delay) <= now);
#else
const auto now = utils::time::get_time_now();
const auto delay =
(config_.get_eviction_delay_mins() * 60L) * NANOS_PER_SECOND;
ret = ((reference_time + static_cast<std::uint64_t>(delay)) <= now);
#endif
}
auto file_size{opt_size.value()};
if (file_size == 0U) {
return false;
}
return ret;
auto reference_time = utils::file::file{file_path}.get_time(
config_.get_eviction_uses_accessed_time()
? utils::file::time_type::accessed
: utils::file::time_type::modified);
if (not reference_time.has_value()) {
return false;
}
auto delay = (config_.get_eviction_delay_mins() * 60UL) *
utils::time::NANOS_PER_SECOND;
return ((reference_time.value() + static_cast<std::uint64_t>(delay)) <=
utils::time::get_time_now());
}
auto eviction::get_filtered_cached_files() -> std::deque<std::string> {
@@ -91,7 +85,7 @@ void eviction::service_function() {
// Handle maximum cache size eviction
auto used_bytes =
utils::file::calculate_used_space(config_.get_cache_directory(), false);
utils::file::directory{config_.get_cache_directory()}.size();
if (config_.get_enable_max_cache_size()) {
should_evict = (used_bytes > config_.get_max_cache_size_bytes());
}
@@ -110,9 +104,9 @@ void eviction::service_function() {
if (provider_.get_filesystem_item_and_file(api_path, file, fsi) ==
api_error::success) {
// Only evict files that match expected size
std::uint64_t file_size{};
if (utils::file::get_file_size(cached_files_list.front(),
file_size)) {
auto opt_size = utils::file::file{cached_files_list.front()}.size();
if (opt_size.has_value()) {
auto file_size{opt_size.value()};
if (file_size == fsi.size) {
// Try to evict file
if (fm_.evict_file(fsi.api_path) &&

View File

@@ -106,8 +106,8 @@ auto fuse_base::access_(const char *path, int mask) -> int {
};
return instance().instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().access_impl(api_path, mask);
function_name, path, [&](std::string api_path) -> api_error {
return instance().access_impl(std::move(api_path), mask);
});
}
@@ -118,8 +118,8 @@ auto fuse_base::chflags_(const char *path, uint32_t flags) -> int {
};
return instance().instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chflags_impl(api_path, flags);
function_name, path, [&](std::string api_path) -> api_error {
return instance().chflags_impl(std::move(api_path), flags);
});
}
#endif // __APPLE__
@@ -132,8 +132,8 @@ auto fuse_base::chmod_(const char *path, mode_t mode,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chmod_impl(api_path, mode, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().chmod_impl(std::move(api_path), mode, fi);
});
}
#else
@@ -143,8 +143,8 @@ auto fuse_base::chmod_(const char *path, mode_t mode) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chmod_impl(api_path, mode);
function_name, path, [&](std::string api_path) -> api_error {
return instance().chmod_impl(std::move(api_path), mode);
});
}
#endif
@@ -157,8 +157,8 @@ auto fuse_base::chown_(const char *path, uid_t uid, gid_t gid,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chown_impl(api_path, uid, gid, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().chown_impl(std::move(api_path), uid, gid, fi);
});
}
#else
@@ -168,8 +168,8 @@ auto fuse_base::chown_(const char *path, uid_t uid, gid_t gid) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chown_impl(api_path, uid, gid);
function_name, path, [&](std::string api_path) -> api_error {
return instance().chown_impl(std::move(api_path), uid, gid);
});
}
#endif
@@ -181,8 +181,8 @@ auto fuse_base::create_(const char *path, mode_t mode,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().create_impl(api_path, mode, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().create_impl(std::move(api_path), mode, fi);
});
}
@@ -223,12 +223,12 @@ void fuse_base::display_version_information(std::vector<const char *> args) {
auto fuse_base::execute_callback(
std::string_view function_name, const char *from, const char *to,
const std::function<api_error(const std::string &from_api_file,
const std::string &to_api_path)> &cb,
const std::function<api_error(std::string from_api_file,
std::string to_api_path)> &cb,
bool disable_logging) -> int {
const auto from_api_file = utils::path::create_api_path(from ? from : "");
const auto to_api_file = utils::path::create_api_path(to ? to : "");
const auto res = utils::from_api_error(cb(from_api_file, to_api_file));
auto from_api_file = utils::path::create_api_path(from ? from : "");
auto to_api_file = utils::path::create_api_path(to ? to : "");
auto res = utils::from_api_error(cb(from_api_file, to_api_file));
raise_fuse_event(function_name,
"from|" + from_api_file + "|to|" + to_api_file, res,
disable_logging);
@@ -237,7 +237,7 @@ auto fuse_base::execute_callback(
auto fuse_base::execute_callback(
std::string_view function_name, const char *path,
const std::function<api_error(const std::string &api_path)> &cb,
const std::function<api_error(std::string api_path)> &cb,
bool disable_logging) -> int {
const auto api_path = utils::path::create_api_path(path ? path : "");
const auto res = utils::from_api_error(cb(api_path));
@@ -269,8 +269,9 @@ auto fuse_base::fallocate_(const char *path, int mode, off_t offset,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().fallocate_impl(api_path, mode, offset, length, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().fallocate_impl(std::move(api_path), mode, offset,
length, fi);
});
}
@@ -282,8 +283,8 @@ auto fuse_base::fgetattr_(const char *path, struct stat *st,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().fgetattr_impl(api_path, st, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().fgetattr_impl(std::move(api_path), st, fi);
});
}
#endif
@@ -296,8 +297,8 @@ auto fuse_base::fsetattr_x_(const char *path, struct setattr_x *attr,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().fsetattr_x_impl(api_path, attr, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().fsetattr_x_impl(std::move(api_path), attr, fi);
});
}
#endif // __APPLE__
@@ -309,8 +310,8 @@ auto fuse_base::fsync_(const char *path, int datasync,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().fsync_impl(api_path, datasync, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().fsync_impl(std::move(api_path), datasync, fi);
});
}
@@ -322,8 +323,8 @@ auto fuse_base::ftruncate_(const char *path, off_t size,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().ftruncate_impl(api_path, size, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().ftruncate_impl(std::move(api_path), size, fi);
});
}
#endif
@@ -336,8 +337,8 @@ auto fuse_base::getattr_(const char *path, struct stat *st,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getattr_impl(api_path, st, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().getattr_impl(std::move(api_path), st, fi);
});
}
#else
@@ -347,8 +348,8 @@ auto fuse_base::getattr_(const char *path, struct stat *st) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getattr_impl(api_path, st);
function_name, path, [&](std::string api_path) -> api_error {
return instance().getattr_impl(std::move(api_path), st);
});
}
#endif
@@ -361,8 +362,8 @@ auto fuse_base::getxtimes_(const char *path, struct timespec *bkuptime,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getxtimes_impl(api_path, bkuptime, crtime);
function_name, path, [&](std::string api_path) -> api_error {
return instance().getxtimes_impl(std::move(api_path), bkuptime, crtime);
});
}
#endif // __APPLE__
@@ -392,31 +393,34 @@ auto fuse_base::init_(struct fuse_conn_info *conn) -> void * {
#if FUSE_USE_VERSION >= 30
auto fuse_base::init_impl([[maybe_unused]] struct fuse_conn_info *conn,
struct fuse_config *cfg) -> void * {
#else
#else // FUSE_USE_VERSION < 30
auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * {
#endif
#endif // FUSE_USE_VERSION >= 30
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
utils::file::change_to_process_directory();
if (not console_enabled_) {
if (not repertory::project_initialize()) {
utils::error::raise_error(function_name,
"failed to initialize repertory");
event_system::instance().raise<unmount_requested>();
}
}
#if defined(__APPLE__)
conn->want |= FUSE_CAP_VOL_RENAME;
conn->want |= FUSE_CAP_XTIMES;
#endif // __APPLE__
#endif // defined(__APPLE__)
#if FUSE_USE_VERSION >= 30
cfg->nullpath_ok = 0;
cfg->hard_remove = 1;
#endif
#endif // FUSE_USE_VERSION >= 30
if (not utils::file::change_to_process_directory()) {
utils::error::raise_error(function_name,
"failed to change to process directory");
event_system::instance().raise<unmount_requested>();
return this;
}
if (not console_enabled_ && not repertory::project_initialize()) {
utils::error::raise_error(function_name, "failed to initialize repertory");
event_system::instance().raise<unmount_requested>();
}
return this;
}
@@ -427,8 +431,8 @@ auto fuse_base::mkdir_(const char *path, mode_t mode) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().mkdir_impl(api_path, mode);
function_name, path, [&](std::string api_path) -> api_error {
return instance().mkdir_impl(std::move(api_path), mode);
});
}
@@ -436,7 +440,7 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
auto ret = parse_args(args);
if (ret == 0) {
std::vector<const char *> fuse_argv(args.size());
for (std::size_t i = 0u; i < args.size(); i++) {
for (std::size_t i = 0u; i < args.size(); ++i) {
fuse_argv[i] = args[i].c_str();
}
@@ -486,8 +490,8 @@ auto fuse_base::open_(const char *path, struct fuse_file_info *fi) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().open_impl(api_path, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().open_impl(std::move(api_path), fi);
});
}
@@ -497,8 +501,8 @@ auto fuse_base::opendir_(const char *path, struct fuse_file_info *fi) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().opendir_impl(api_path, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().opendir_impl(std::move(api_path), fi);
});
}
@@ -511,9 +515,9 @@ auto fuse_base::read_(const char *path, char *buffer, size_t read_size,
std::size_t bytes_read{};
const auto res = instance().execute_callback(
function_name, path,
[&](const std::string &api_path) -> api_error {
return instance().read_impl(api_path, buffer, read_size, read_offset,
fi, bytes_read);
[&](std::string api_path) -> api_error {
return instance().read_impl(std::move(api_path), buffer, read_size,
read_offset, fi, bytes_read);
},
true);
return (res == 0) ? static_cast<int>(bytes_read) : res;
@@ -529,9 +533,9 @@ auto fuse_base::readdir_(const char *path, void *buf,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().readdir_impl(api_path, buf, fuse_fill_dir, offset, fi,
flags);
function_name, path, [&](std::string api_path) -> api_error {
return instance().readdir_impl(std::move(api_path), buf, fuse_fill_dir,
offset, fi, flags);
});
}
#else
@@ -543,9 +547,9 @@ auto fuse_base::readdir_(const char *path, void *buf,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().readdir_impl(api_path, buf, fuse_fill_dir, offset,
fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().readdir_impl(std::move(api_path), buf, fuse_fill_dir,
offset, fi);
});
}
#endif
@@ -556,8 +560,8 @@ auto fuse_base::release_(const char *path, struct fuse_file_info *fi) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().release_impl(api_path, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().release_impl(std::move(api_path), fi);
});
}
@@ -568,8 +572,8 @@ auto fuse_base::releasedir_(const char *path,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().releasedir_impl(api_path, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().releasedir_impl(std::move(api_path), fi);
});
}
@@ -582,9 +586,9 @@ auto fuse_base::rename_(const char *from, const char *to,
return instance().execute_callback(
function_name, from, to,
[&](const std::string &from_api_file,
const std::string &to_api_path) -> api_error {
return instance().rename_impl(from_api_file, to_api_path, flags);
[&](std::string from_api_file, std::string to_api_path) -> api_error {
return instance().rename_impl(std::move(from_api_file),
std::move(to_api_path), flags);
});
}
#else
@@ -595,9 +599,9 @@ auto fuse_base::rename_(const char *from, const char *to) -> int {
return instance().execute_callback(
function_name, from, to,
[&](const std::string &from_api_file,
const std::string &to_api_path) -> api_error {
return instance().rename_impl(from_api_file, to_api_path);
[&](std::string from_api_file, std::string to_api_path) -> api_error {
return instance().rename_impl(std::move(from_api_file),
std::move(to_api_path));
});
}
#endif
@@ -608,8 +612,8 @@ auto fuse_base::rmdir_(const char *path) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().rmdir_impl(api_path);
function_name, path, [&](std::string api_path) -> api_error {
return instance().rmdir_impl(std::move(api_path));
});
}
@@ -623,9 +627,9 @@ auto fuse_base::getxattr_(const char *path, const char *name, char *value,
int attribute_size = 0;
const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getxattr_impl(api_path, name, value, size, position,
attribute_size);
function_name, path, [&](std::string api_path) -> api_error {
return instance().getxattr_impl(std::move(api_path), name, value, size,
position, attribute_size);
});
return res == 0 ? attribute_size : res;
@@ -639,8 +643,8 @@ auto fuse_base::getxattr_(const char *path, const char *name, char *value,
int attribute_size = 0;
const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getxattr_impl(api_path, name, value, size,
function_name, path, [&](std::string api_path) -> api_error {
return instance().getxattr_impl(std::move(api_path), name, value, size,
attribute_size);
});
@@ -657,9 +661,9 @@ auto fuse_base::listxattr_(const char *path, char *buffer, size_t size) -> int {
bool return_size = false;
const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().listxattr_impl(api_path, buffer, size, required_size,
return_size);
function_name, path, [&](std::string api_path) -> api_error {
return instance().listxattr_impl(std::move(api_path), buffer, size,
required_size, return_size);
});
return return_size ? required_size : res;
@@ -676,14 +680,14 @@ void fuse_base::notify_fuse_args_parsed(const std::vector<std::string> &args) {
auto fuse_base::parse_args(std::vector<std::string> &args) -> int {
auto force_no_console = false;
for (std::size_t i = 1u; !force_no_console && (i < args.size()); i++) {
for (std::size_t i = 1u; !force_no_console && (i < args.size()); ++i) {
if (args[i] == "-nc") {
force_no_console = true;
}
}
utils::collection::remove_element(args, "-nc");
for (std::size_t i = 1u; i < args.size(); i++) {
for (std::size_t i = 1u; i < args.size(); ++i) {
if (args[i] == "-f") {
console_enabled_ = not force_no_console;
} else if (args[i].find("-o") == 0) {
@@ -697,7 +701,7 @@ auto fuse_base::parse_args(std::vector<std::string> &args) -> int {
}
const auto option_parts = utils::string::split(options, ',', true);
for (const auto &option : option_parts) {
for (auto &&option : option_parts) {
if (option.find("gid") == 0) {
const auto parts = utils::string::split(option, '=', true);
if (parts.size() == 2u) {
@@ -752,7 +756,7 @@ auto fuse_base::parse_args(std::vector<std::string> &args) -> int {
}
void fuse_base::raise_fuse_event(std::string_view function_name,
const std::string &api_path, int ret,
std::string_view api_path, int ret,
bool disable_logging) {
if ((ret >= 0) && disable_logging) {
return;
@@ -766,7 +770,7 @@ void fuse_base::raise_fuse_event(std::string_view function_name,
(config_.get_event_level() >= event_level::trace)) {
std::string func{function_name};
event_system::instance().raise<fuse_event>(
utils::string::right_trim(func, '_'), api_path, ret);
utils::string::right_trim(func, '_'), std::string{api_path}, ret);
}
}
@@ -776,8 +780,8 @@ auto fuse_base::removexattr_(const char *path, const char *name) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().removexattr_impl(api_path, name);
function_name, path, [&](std::string api_path) -> api_error {
return instance().removexattr_impl(std::move(api_path), name);
});
}
@@ -789,9 +793,9 @@ auto fuse_base::setxattr_(const char *path, const char *name, const char *value,
};
const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setxattr_impl(api_path, name, value, size, flags,
position);
function_name, path, [&](std::string api_path) -> api_error {
return instance().setxattr_impl(std::move(api_path), name, value, size,
flags, position);
});
if (res != 0) {
errno = std::abs(res);
@@ -807,8 +811,9 @@ auto fuse_base::setxattr_(const char *path, const char *name, const char *value,
};
const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setxattr_impl(api_path, name, value, size, flags);
function_name, path, [&](std::string api_path) -> api_error {
return instance().setxattr_impl(std::move(api_path), name, value, size,
flags);
});
if (res != 0) {
errno = std::abs(res);
@@ -832,8 +837,8 @@ auto fuse_base::setattr_x_(const char *path, struct setattr_x *attr) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setattr_x_impl(api_path, attr);
function_name, path, [&](std::string api_path) -> api_error {
return instance().setattr_x_impl(std::move(api_path), attr);
});
}
@@ -844,8 +849,8 @@ auto fuse_base::setbkuptime_(const char *path,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setbkuptime_impl(api_path, bkuptime);
function_name, path, [&](std::string api_path) -> api_error {
return instance().setbkuptime_impl(std::move(api_path), bkuptime);
});
}
@@ -856,8 +861,8 @@ auto fuse_base::setchgtime_(const char *path,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setchgtime_impl(api_path, chgtime);
function_name, path, [&](std::string api_path) -> api_error {
return instance().setchgtime_impl(std::move(api_path), chgtime);
});
}
@@ -868,8 +873,8 @@ auto fuse_base::setcrtime_(const char *path,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setcrtime_impl(api_path, crtime);
function_name, path, [&](std::string api_path) -> api_error {
return instance().setcrtime_impl(std::move(api_path), crtime);
});
}
@@ -879,8 +884,8 @@ auto fuse_base::setvolname_(const char *volname) -> int {
};
return instance().execute_callback(
function_name, volname, [&](const std::string &api_path) -> api_error {
return instance().setvolname_impl(volname);
function_name, volname, [&](std::string api_path) -> api_error {
return instance().setvolname_impl(std::move(volname));
});
}
@@ -890,8 +895,8 @@ auto fuse_base::statfs_x_(const char *path, struct statfs *stbuf) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().statfs_x_impl(api_path, stbuf);
function_name, path, [&](std::string api_path) -> api_error {
return instance().statfs_x_impl(std::move(api_path), stbuf);
});
}
#else // __APPLE__
@@ -901,8 +906,8 @@ auto fuse_base::statfs_(const char *path, struct statvfs *stbuf) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().statfs_impl(api_path, stbuf);
function_name, path, [&](std::string api_path) -> api_error {
return instance().statfs_impl(std::move(api_path), stbuf);
});
}
#endif // __APPLE__
@@ -915,8 +920,8 @@ auto fuse_base::truncate_(const char *path, off_t size,
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().truncate_impl(api_path, size, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().truncate_impl(std::move(api_path), size, fi);
});
}
#else
@@ -926,8 +931,8 @@ auto fuse_base::truncate_(const char *path, off_t size) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().truncate_impl(api_path, size);
function_name, path, [&](std::string api_path) -> api_error {
return instance().truncate_impl(std::move(api_path), size);
});
}
#endif
@@ -938,8 +943,8 @@ auto fuse_base::unlink_(const char *path) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().unlink_impl(api_path);
function_name, path, [&](std::string api_path) -> api_error {
return instance().unlink_impl(std::move(api_path));
});
}
@@ -965,8 +970,8 @@ auto fuse_base::utimens_(const char *path, const struct timespec tv[2],
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().utimens_impl(api_path, tv, fi);
function_name, path, [&](std::string api_path) -> api_error {
return instance().utimens_impl(std::move(api_path), tv, fi);
});
}
#else
@@ -976,8 +981,8 @@ auto fuse_base::utimens_(const char *path, const struct timespec tv[2]) -> int {
};
return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().utimens_impl(api_path, tv);
function_name, path, [&](std::string api_path) -> api_error {
return instance().utimens_impl(std::move(api_path), tv);
});
}
#endif
@@ -992,9 +997,9 @@ auto fuse_base::write_(const char *path, const char *buffer, size_t write_size,
const auto res = instance().execute_callback(
function_name, path,
[&](const std::string &api_path) -> api_error {
return instance().write_impl(api_path, buffer, write_size, write_offset,
fi, bytes_written);
[&](std::string api_path) -> api_error {
return instance().write_impl(std::move(api_path), buffer, write_size,
write_offset, fi, bytes_written);
},
true);
return (res == 0) ? static_cast<int>(bytes_written) : res;

View File

@@ -163,7 +163,7 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode,
{
std::shared_ptr<i_open_file> open_file;
if (is_create_op) {
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
#if defined(__APPLE__)
const auto osx_flags = static_cast<std::uint32_t>(file_info->flags);
#else // !defined(__APPLE__)
@@ -614,7 +614,7 @@ auto fuse_drive::mkdir_impl(std::string api_path, mode_t mode) -> api_error {
return res;
}
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(now, FILE_ATTRIBUTE_DIRECTORY, now, now,
true, get_effective_gid(), "", mode, now,
0U, 0U, 0U, "", get_effective_uid(), now);
@@ -915,7 +915,7 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
api_meta_map meta;
if ((res = provider_.get_item_meta(api_path, meta)) == api_error::success) {
for (const auto &meta_item : meta) {
for (auto &&meta_item : meta) {
if (utils::collection::excludes(META_USED_NAMES, meta_item.first)) {
auto attribute_name = meta_item.first;
#if defined(__APPLE__)
@@ -1155,8 +1155,8 @@ auto fuse_drive::setbkuptime_impl(
std::string api_path, const struct timespec *bkuptime) -> api_error {
return check_and_perform(
api_path, X_OK, [&](api_meta_map &meta) -> api_error {
const auto nanos =
bkuptime->tv_nsec + (bkuptime->tv_nsec * NANOS_PER_SECOND);
const auto nanos = bkuptime->tv_nsec +
(bkuptime->tv_nsec * utils::time::NANOS_PER_SECOND);
return provider_.set_item_meta(api_path, META_BACKUP,
std::to_string(nanos));
});
@@ -1166,8 +1166,8 @@ auto fuse_drive::setchgtime_impl(std::string api_path,
const struct timespec *chgtime) -> api_error {
return check_and_perform(
api_path, X_OK, [&](api_meta_map &meta) -> api_error {
const auto nanos =
chgtime->tv_nsec + (chgtime->tv_nsec * NANOS_PER_SECOND);
const auto nanos = chgtime->tv_nsec +
(chgtime->tv_nsec * utils::time::NANOS_PER_SECOND);
return provider_.set_item_meta(api_path, META_CHANGED,
std::to_string(nanos));
});
@@ -1178,7 +1178,7 @@ auto fuse_drive::setcrtime_impl(std::string api_path,
return check_and_perform(
api_path, X_OK, [&](api_meta_map &meta) -> api_error {
const auto nanos =
crtime->tv_nsec + (crtime->tv_nsec * NANOS_PER_SECOND);
crtime->tv_nsec + (crtime->tv_nsec * utils::time::NANOS_PER_SECOND);
return provider_.set_item_meta(api_path, META_CREATION,
std::to_string(nanos));
});
@@ -1310,19 +1310,24 @@ auto fuse_drive::utimens_impl(std::string api_path,
}
meta.clear();
if ((tv == nullptr) || (tv[0U].tv_nsec == UTIME_NOW)) {
meta[META_ACCESSED] = std::to_string(utils::time::get_file_time_now());
} else if (tv[0U].tv_nsec != UTIME_OMIT) {
const auto val = tv[0U].tv_nsec + (tv[0U].tv_sec * NANOS_PER_SECOND);
meta[META_ACCESSED] = std::to_string(val);
}
if ((tv == nullptr) || (tv[1U].tv_nsec == UTIME_NOW)) {
meta[META_MODIFIED] = std::to_string(utils::time::get_file_time_now());
} else if (tv[1U].tv_nsec != UTIME_OMIT) {
const auto val = tv[1U].tv_nsec + (tv[1U].tv_sec * NANOS_PER_SECOND);
meta[META_MODIFIED] = std::to_string(val);
}
const auto process_timespec = [&meta, &tv](const auto &src,
std::string attr) {
if ((tv == nullptr) || (src.tv_nsec == UTIME_NOW)) {
meta[attr] = std::to_string(utils::time::get_time_now());
return;
}
if (src.tv_nsec != UTIME_OMIT) {
meta[attr] = std::to_string(
src.tv_nsec +
(src.tv_sec * static_cast<std::decay_t<decltype(src.tv_sec)>>(
utils::time::NANOS_PER_SECOND)));
}
};
process_timespec(tv[0U], META_ACCESSED);
process_timespec(tv[1U], META_MODIFIED);
if (not meta.empty()) {
return provider_.set_item_meta(api_path, meta);
@@ -1369,8 +1374,7 @@ void fuse_drive::update_accessed_time(const std::string &api_path) {
if (atime_enabled_) {
auto res = provider_.set_item_meta(
api_path, META_ACCESSED,
std::to_string(utils::time::get_file_time_now()));
api_path, META_ACCESSED, std::to_string(utils::time::get_time_now()));
if (res != api_error::success) {
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to set accessed time");

View File

@@ -26,6 +26,7 @@
#include "platform/platform.hpp"
#include "providers/i_provider.hpp"
#include "utils/common.hpp"
#include "utils/time.hpp"
namespace repertory {
auto fuse_drive_base::access_impl(std::string api_path, int mask) -> api_error {
@@ -165,9 +166,9 @@ auto fuse_drive_base::check_parent_access(const std::string &api_path,
// Ignore root
if (api_path != "/") {
if ((mask & X_OK) == X_OK) {
for (auto parent = utils::path::get_parent_directory(api_path);
for (auto parent = utils::path::get_parent_path(api_path);
(ret == api_error::success) && not parent.empty();
parent = utils::path::get_parent_directory(parent)) {
parent = utils::path::get_parent_path(parent)) {
if (((ret = check_access(parent, X_OK)) == api_error::success) &&
(parent == "/")) {
break;
@@ -178,7 +179,7 @@ auto fuse_drive_base::check_parent_access(const std::string &api_path,
if (ret == api_error::success) {
mask &= (~X_OK);
if (mask != 0) {
ret = check_access(utils::path::get_parent_directory(api_path), mask);
ret = check_access(utils::path::get_parent_path(api_path), mask);
}
}
}
@@ -233,9 +234,9 @@ auto fuse_drive_base::get_mode_from_meta(const api_meta_map &meta) -> mode_t {
void fuse_drive_base::get_timespec_from_meta(const api_meta_map &meta,
const std::string &name,
struct timespec &ts) {
const auto meta_time = utils::string::to_int64(meta.at(name));
ts.tv_nsec = meta_time % NANOS_PER_SECOND;
ts.tv_sec = meta_time / NANOS_PER_SECOND;
auto meta_time = utils::string::to_uint64(meta.at(name));
ts.tv_nsec = meta_time % utils::time::NANOS_PER_SECOND;
ts.tv_sec = meta_time / utils::time::NANOS_PER_SECOND;
}
auto fuse_drive_base::get_uid_from_meta(const api_meta_map &meta) -> uid_t {
@@ -299,7 +300,7 @@ void fuse_drive_base::populate_stat(const std::string &api_path,
std::uint64_t size_or_count,
const api_meta_map &meta, bool directory,
i_provider &provider, struct stat *st) {
memset(st, 0, sizeof(struct stat));
std::memset(st, 0, sizeof(struct stat));
st->st_nlink = static_cast<nlink_t>(
directory ? 2 + (size_or_count == 0U
? provider.get_directory_item_count(api_path)
@@ -341,9 +342,9 @@ void fuse_drive_base::populate_stat(const std::string &api_path,
void fuse_drive_base::set_timespec_from_meta(const api_meta_map &meta,
const std::string &name,
struct timespec &ts) {
const auto meta_time = utils::string::to_int64(meta.at(name));
ts.tv_nsec = meta_time % NANOS_PER_SECOND;
ts.tv_sec = meta_time / NANOS_PER_SECOND;
auto meta_time = utils::string::to_uint64(meta.at(name));
ts.tv_nsec = meta_time % utils::time::NANOS_PER_SECOND;
ts.tv_sec = meta_time / utils::time::NANOS_PER_SECOND;
}
} // namespace repertory

View File

@@ -36,6 +36,7 @@
#include "utils/error_utils.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp"
#include "utils/time.hpp"
#include "utils/utils.hpp"
namespace repertory::remote_fuse {
@@ -142,16 +143,17 @@ api_error remote_fuse_drive::fsetattr_x_impl(std::string api_path,
attributes.uid = attr->uid;
attributes.gid = attr->gid;
attributes.size = attr->size;
attributes.acctime =
((attr->acctime.tv_sec * NANOS_PER_SECOND) + attr->acctime.tv_nsec);
attributes.modtime =
((attr->modtime.tv_sec * NANOS_PER_SECOND) + attr->modtime.tv_nsec);
attributes.crtime =
((attr->crtime.tv_sec * NANOS_PER_SECOND) + attr->crtime.tv_nsec);
attributes.chgtime =
((attr->chgtime.tv_sec * NANOS_PER_SECOND) + attr->chgtime.tv_nsec);
attributes.acctime = ((attr->acctime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->acctime.tv_nsec);
attributes.modtime = ((attr->modtime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->modtime.tv_nsec);
attributes.crtime = ((attr->crtime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->crtime.tv_nsec);
attributes.chgtime = ((attr->chgtime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->chgtime.tv_nsec);
attributes.bkuptime =
((attr->bkuptime.tv_sec * NANOS_PER_SECOND) + attr->bkuptime.tv_nsec);
((attr->bkuptime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->bkuptime.tv_nsec);
attributes.flags = attr->flags;
return utils::to_api_error(remote_instance_->fuse_fsetattr_x(
api_path.c_str(), attributes, f_info->fh));
@@ -208,10 +210,11 @@ api_error remote_fuse_drive::getxtimes_impl(std::string api_path,
api_path.c_str(), repertory_bkuptime, repertory_crtime);
if (res == 0) {
bkuptime->tv_nsec =
static_cast<long>(repertory_bkuptime % NANOS_PER_SECOND);
bkuptime->tv_sec = repertory_bkuptime / NANOS_PER_SECOND;
crtime->tv_nsec = static_cast<long>(repertory_crtime % NANOS_PER_SECOND);
crtime->tv_sec = repertory_crtime / NANOS_PER_SECOND;
static_cast<long>(repertory_bkuptime % utils::time::NANOS_PER_SECOND);
bkuptime->tv_sec = repertory_bkuptime / utils::time::NANOS_PER_SECOND;
crtime->tv_nsec =
static_cast<long>(repertory_crtime % utils::time::NANOS_PER_SECOND);
crtime->tv_sec = repertory_crtime / utils::time::NANOS_PER_SECOND;
}
return utils::to_api_error(res);
@@ -296,42 +299,51 @@ auto remote_fuse_drive::opendir_impl(
void remote_fuse_drive::populate_stat(const remote::stat &r_stat,
bool directory, struct stat &unix_st) {
memset(&unix_st, 0, sizeof(struct stat));
std::memset(&unix_st, 0, sizeof(struct stat));
#if defined(__APPLE__)
unix_st.st_blksize = 0;
unix_st.st_atimespec.tv_nsec = r_stat.st_atimespec % NANOS_PER_SECOND;
unix_st.st_atimespec.tv_sec = r_stat.st_atimespec / NANOS_PER_SECOND;
unix_st.st_atimespec.tv_nsec =
r_stat.st_atimespec % utils::time::NANOS_PER_SECOND;
unix_st.st_atimespec.tv_sec =
r_stat.st_atimespec / utils::time::NANOS_PER_SECOND;
unix_st.st_birthtimespec.tv_nsec = r_stat.st_birthtimespec % NANOS_PER_SECOND;
unix_st.st_birthtimespec.tv_sec = r_stat.st_birthtimespec / NANOS_PER_SECOND;
unix_st.st_birthtimespec.tv_nsec =
r_stat.st_birthtimespec % utils::time::NANOS_PER_SECOND;
unix_st.st_birthtimespec.tv_sec =
r_stat.st_birthtimespec / utils::time::NANOS_PER_SECOND;
unix_st.st_ctimespec.tv_nsec = r_stat.st_ctimespec % NANOS_PER_SECOND;
unix_st.st_ctimespec.tv_sec = r_stat.st_ctimespec / NANOS_PER_SECOND;
unix_st.st_ctimespec.tv_nsec =
r_stat.st_ctimespec % utils::time::NANOS_PER_SECOND;
unix_st.st_ctimespec.tv_sec =
r_stat.st_ctimespec / utils::time::NANOS_PER_SECOND;
unix_st.st_mtimespec.tv_nsec = r_stat.st_mtimespec % NANOS_PER_SECOND;
unix_st.st_mtimespec.tv_sec = r_stat.st_mtimespec / NANOS_PER_SECOND;
unix_st.st_mtimespec.tv_nsec =
r_stat.st_mtimespec % utils::time::NANOS_PER_SECOND;
unix_st.st_mtimespec.tv_sec =
r_stat.st_mtimespec / utils::time::NANOS_PER_SECOND;
unix_st.st_flags = r_stat.st_flags;
#else
#else // !defined(__APPLE__)
unix_st.st_blksize = 4096;
unix_st.st_atim.tv_nsec =
static_cast<suseconds_t>(r_stat.st_atimespec % NANOS_PER_SECOND);
unix_st.st_atim.tv_sec =
static_cast<suseconds_t>(r_stat.st_atimespec / NANOS_PER_SECOND);
unix_st.st_atim.tv_nsec = static_cast<suseconds_t>(
r_stat.st_atimespec % utils::time::NANOS_PER_SECOND);
unix_st.st_atim.tv_sec = static_cast<suseconds_t>(
r_stat.st_atimespec / utils::time::NANOS_PER_SECOND);
unix_st.st_ctim.tv_nsec =
static_cast<suseconds_t>(r_stat.st_ctimespec % NANOS_PER_SECOND);
unix_st.st_ctim.tv_sec =
static_cast<suseconds_t>(r_stat.st_ctimespec / NANOS_PER_SECOND);
unix_st.st_ctim.tv_nsec = static_cast<suseconds_t>(
r_stat.st_ctimespec % utils::time::NANOS_PER_SECOND);
unix_st.st_ctim.tv_sec = static_cast<suseconds_t>(
r_stat.st_ctimespec / utils::time::NANOS_PER_SECOND);
unix_st.st_mtim.tv_nsec = static_cast<suseconds_t>(
r_stat.st_mtimespec % utils::time::NANOS_PER_SECOND);
unix_st.st_mtim.tv_sec = static_cast<suseconds_t>(
r_stat.st_mtimespec / utils::time::NANOS_PER_SECOND);
#endif // defined(__APPLE__)
unix_st.st_mtim.tv_nsec =
static_cast<suseconds_t>(r_stat.st_mtimespec % NANOS_PER_SECOND);
unix_st.st_mtim.tv_sec =
static_cast<suseconds_t>(r_stat.st_mtimespec / NANOS_PER_SECOND);
#endif
if (not directory) {
const auto block_size_stat = static_cast<std::uint64_t>(512U);
const auto block_size = static_cast<std::uint64_t>(4096U);
@@ -440,16 +452,17 @@ api_error remote_fuse_drive::setattr_x_impl(std::string api_path,
attributes.uid = attr->uid;
attributes.gid = attr->gid;
attributes.size = attr->size;
attributes.acctime =
((attr->acctime.tv_sec * NANOS_PER_SECOND) + attr->acctime.tv_nsec);
attributes.modtime =
((attr->modtime.tv_sec * NANOS_PER_SECOND) + attr->modtime.tv_nsec);
attributes.crtime =
((attr->crtime.tv_sec * NANOS_PER_SECOND) + attr->crtime.tv_nsec);
attributes.chgtime =
((attr->chgtime.tv_sec * NANOS_PER_SECOND) + attr->chgtime.tv_nsec);
attributes.acctime = ((attr->acctime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->acctime.tv_nsec);
attributes.modtime = ((attr->modtime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->modtime.tv_nsec);
attributes.crtime = ((attr->crtime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->crtime.tv_nsec);
attributes.chgtime = ((attr->chgtime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->chgtime.tv_nsec);
attributes.bkuptime =
((attr->bkuptime.tv_sec * NANOS_PER_SECOND) + attr->bkuptime.tv_nsec);
((attr->bkuptime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->bkuptime.tv_nsec);
attributes.flags = attr->flags;
return utils::to_api_error(
remote_instance_->fuse_setattr_x(api_path.c_str(), attributes));
@@ -458,7 +471,7 @@ api_error remote_fuse_drive::setattr_x_impl(std::string api_path,
api_error remote_fuse_drive::setbkuptime_impl(std::string api_path,
const struct timespec *bkuptime) {
remote::file_time repertory_bkuptime =
((bkuptime->tv_sec * NANOS_PER_SECOND) + bkuptime->tv_nsec);
((bkuptime->tv_sec * utils::time::NANOS_PER_SECOND) + bkuptime->tv_nsec);
return utils::to_api_error(
remote_instance_->fuse_setbkuptime(api_path.c_str(), repertory_bkuptime));
}
@@ -466,7 +479,7 @@ api_error remote_fuse_drive::setbkuptime_impl(std::string api_path,
api_error remote_fuse_drive::setchgtime_impl(std::string api_path,
const struct timespec *chgtime) {
remote::file_time repertory_chgtime =
((chgtime->tv_sec * NANOS_PER_SECOND) + chgtime->tv_nsec);
((chgtime->tv_sec * utils::time::NANOS_PER_SECOND) + chgtime->tv_nsec);
return utils::to_api_error(
remote_instance_->fuse_setchgtime(api_path.c_str(), repertory_chgtime));
}
@@ -474,7 +487,7 @@ api_error remote_fuse_drive::setchgtime_impl(std::string api_path,
api_error remote_fuse_drive::setcrtime_impl(std::string api_path,
const struct timespec *crtime) {
remote::file_time repertory_crtime =
((crtime->tv_sec * NANOS_PER_SECOND) + crtime->tv_nsec);
((crtime->tv_sec * utils::time::NANOS_PER_SECOND) + crtime->tv_nsec);
return utils::to_api_error(
remote_instance_->fuse_setcrtime(api_path.c_str(), repertory_crtime));
}
@@ -555,10 +568,14 @@ auto remote_fuse_drive::utimens_impl(std::string api_path,
#endif
remote::file_time rtv[2U] = {0};
if (tv != nullptr) {
rtv[0U] = static_cast<remote::file_time>(
tv[0U].tv_nsec + (tv[0U].tv_sec * NANOS_PER_SECOND));
rtv[1U] = static_cast<remote::file_time>(
tv[1U].tv_nsec + (tv[1U].tv_sec * NANOS_PER_SECOND));
const auto update_timespec = [](auto &dst, const auto &src) {
dst = static_cast<remote::file_time>(
src.tv_nsec +
(src.tv_sec * static_cast<std::decay_t<decltype(src.tv_sec)>>(
utils::time::NANOS_PER_SECOND)));
};
update_timespec(rtv[0U], tv[0U]);
update_timespec(rtv[1U], tv[1U]);
}
return utils::to_api_error(remote_instance_->fuse_utimens(

View File

@@ -93,9 +93,10 @@ auto remote_server::populate_file_info(const std::string &api_path,
auto error = drive_.get_item_meta(api_path, META_ATTRIBUTES, meta_attributes);
if (error == api_error::success) {
if (meta_attributes.empty()) {
meta_attributes = utils::file::is_directory(construct_path(api_path))
? std::to_string(FILE_ATTRIBUTE_DIRECTORY)
: std::to_string(FILE_ATTRIBUTE_NORMAL);
meta_attributes =
utils::file::directory(construct_path(api_path)).exists()
? std::to_string(FILE_ATTRIBUTE_DIRECTORY)
: std::to_string(FILE_ATTRIBUTE_NORMAL);
drive_.set_item_meta(api_path, META_ATTRIBUTES, meta_attributes);
}
const auto attributes = utils::string::to_uint32(meta_attributes);
@@ -124,18 +125,18 @@ void remote_server::populate_file_info(const std::string &api_path,
file_info.AllocationSize =
utils::divide_with_ceiling(file_size, WINFSP_ALLOCATION_UNIT) *
WINFSP_ALLOCATION_UNIT;
file_info.ChangeTime = utils::unix_time_to_windows_time(
file_info.ChangeTime = utils::time::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(meta[META_MODIFIED])));
file_info.CreationTime = utils::unix_time_to_windows_time(
file_info.CreationTime = utils::time::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(meta[META_CREATION])));
file_info.EaSize = 0;
file_info.FileAttributes = attributes;
file_info.FileSize = file_size;
file_info.HardLinks = 0;
file_info.IndexNumber = 0;
file_info.LastAccessTime = utils::unix_time_to_windows_time(
file_info.LastAccessTime = utils::time::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(meta[META_ACCESSED])));
file_info.LastWriteTime = utils::unix_time_to_windows_time(
file_info.LastWriteTime = utils::time::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(meta[META_WRITTEN])));
if (meta[META_WRITTEN].empty() || (meta[META_WRITTEN] == "0") ||
(meta[META_WRITTEN] == "116444736000000000")) {
@@ -147,30 +148,45 @@ void remote_server::populate_file_info(const std::string &api_path,
void remote_server::populate_stat(const struct stat64 &unix_st,
remote::stat &r_stat) {
memset(&r_stat, 0, sizeof(r_stat));
r_stat = {};
#if defined(__APPLE__)
r_stat.st_flags = unix_st.st_flags;
r_stat.st_atimespec = unix_st.st_atimespec.tv_nsec +
(unix_st.st_atimespec.tv_sec * NANOS_PER_SECOND);
r_stat.st_atimespec =
unix_st.st_atimespec.tv_nsec +
(unix_st.st_atimespec.tv_sec * utils::time::NANOS_PER_SECOND);
r_stat.st_birthtimespec =
unix_st.st_birthtimespec.tv_nsec +
(unix_st.st_birthtimespec.tv_sec * NANOS_PER_SECOND);
r_stat.st_ctimespec = unix_st.st_ctimespec.tv_nsec +
(unix_st.st_ctimespec.tv_sec * NANOS_PER_SECOND);
r_stat.st_mtimespec = unix_st.st_mtimespec.tv_nsec +
(unix_st.st_mtimespec.tv_sec * NANOS_PER_SECOND);
(unix_st.st_birthtimespec.tv_sec * utils::time::NANOS_PER_SECOND);
r_stat.st_ctimespec =
unix_st.st_ctimespec.tv_nsec +
(unix_st.st_ctimespec.tv_sec * utils::time::NANOS_PER_SECOND);
r_stat.st_mtimespec =
unix_st.st_mtimespec.tv_nsec +
(unix_st.st_mtimespec.tv_sec * utils::time::NANOS_PER_SECOND);
#else // !defined(__APPLE__)
r_stat.st_flags = 0;
r_stat.st_atimespec = static_cast<remote::file_time>(
unix_st.st_atim.tv_nsec + (unix_st.st_atim.tv_sec * NANOS_PER_SECOND));
r_stat.st_birthtimespec = static_cast<remote::file_time>(
unix_st.st_ctim.tv_nsec + (unix_st.st_ctim.tv_sec * NANOS_PER_SECOND));
r_stat.st_ctimespec = static_cast<remote::file_time>(
unix_st.st_ctim.tv_nsec + (unix_st.st_ctim.tv_sec * NANOS_PER_SECOND));
r_stat.st_mtimespec = static_cast<remote::file_time>(
unix_st.st_mtim.tv_nsec + (unix_st.st_mtim.tv_sec * NANOS_PER_SECOND));
r_stat.st_atimespec =
static_cast<remote::file_time>(unix_st.st_atim.tv_nsec) +
(static_cast<remote::file_time>(unix_st.st_atim.tv_sec) *
utils::time::NANOS_PER_SECOND);
r_stat.st_birthtimespec =
static_cast<remote::file_time>(unix_st.st_ctim.tv_nsec) +
(static_cast<remote::file_time>(unix_st.st_ctim.tv_sec) *
utils::time::NANOS_PER_SECOND);
r_stat.st_ctimespec =
static_cast<remote::file_time>(unix_st.st_ctim.tv_nsec) +
(static_cast<remote::file_time>(unix_st.st_ctim.tv_sec) *
utils::time::NANOS_PER_SECOND);
r_stat.st_mtimespec =
static_cast<remote::file_time>(unix_st.st_mtim.tv_nsec) +
(static_cast<remote::file_time>(unix_st.st_mtim.tv_sec) *
utils::time::NANOS_PER_SECOND);
#endif // defined(__APPLE__)
r_stat.st_blksize = static_cast<remote::block_size>(unix_st.st_blksize);
r_stat.st_blocks = static_cast<remote::block_count>(unix_st.st_blocks);
@@ -319,12 +335,13 @@ auto remote_server::fuse_fgetattr(
static_cast<const char *>(__FUNCTION__),
};
r_stat = {};
const auto file_path = construct_path(path);
memset(&r_stat, 0, sizeof(remote::stat));
auto res = has_open_info(static_cast<native_handle>(handle), EBADF);
if (res == 0) {
directory = utils::file::is_directory(file_path);
directory = utils::file::directory(file_path).exists();
struct stat64 unix_st {};
res = fstat64(static_cast<native_handle>(handle), &unix_st);
if (res == 0) {
@@ -405,16 +422,18 @@ auto remote_server::fuse_fsetattr_x(
if (SETATTR_WANTS_MODTIME(&attr)) {
struct timeval val[2];
if (SETATTR_WANTS_ACCTIME(&attr)) {
val[0U].tv_sec = static_cast<time_t>(attr.acctime / NANOS_PER_SECOND);
val[0U].tv_usec =
static_cast<time_t>((attr.acctime % NANOS_PER_SECOND) / 1000);
val[0U].tv_sec =
static_cast<time_t>(attr.acctime / utils::time::NANOS_PER_SECOND);
val[0U].tv_usec = static_cast<time_t>(
(attr.acctime % utils::time::NANOS_PER_SECOND) / 1000);
} else {
gettimeofday(&val[0U], nullptr);
}
val[1U].tv_sec = static_cast<time_t>(attr.modtime / NANOS_PER_SECOND);
val[1U].tv_usec =
static_cast<time_t>((attr.modtime % NANOS_PER_SECOND) / 1000);
val[1U].tv_sec =
static_cast<time_t>(attr.modtime / utils::time::NANOS_PER_SECOND);
val[1U].tv_usec = static_cast<time_t>(
(attr.modtime % utils::time::NANOS_PER_SECOND) / 1000);
res = utimes(file_path.c_str(), &val[0U]);
}
@@ -486,9 +505,10 @@ auto remote_server::fuse_getattr(const char *path, remote::stat &r_stat,
const auto api_path = utils::path::create_api_path(path);
const auto file_path = construct_path(api_path);
const auto parent_api_path = utils::path::get_parent_api_path(api_path);
memset(&r_stat, 0, sizeof(remote::stat));
directory = utils::file::is_directory(file_path);
r_stat = {};
directory = utils::file::directory(file_path).exists();
struct stat64 unix_st {};
auto res = stat64(file_path.c_str(), &unix_st);
@@ -651,7 +671,7 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle)
auto res = -1;
errno = ENOENT;
if (utils::file::is_directory(file_path)) {
if (utils::file::directory(file_path).exists()) {
auto iter = std::make_shared<directory_iterator>(
drive_.get_directory_items(utils::path::create_api_path(path)));
@@ -949,10 +969,10 @@ auto remote_server::fuse_statfs_x(const char *path, std::uint64_t bsize,
r_stat.f_blocks ? (r_stat.f_blocks - used_blocks) : 0;
r_stat.f_ffree = r_stat.f_favail =
r_stat.f_files - drive_.get_total_item_count();
std::memset(&r_stat.f_mntfromname[0U], 0, sizeof(r_stat.f_mntfromname));
strncpy(&r_stat.f_mntfromname[0U],
std::memset(r_stat.f_mntfromname.data(), 0, r_stat.f_mntfromname.size());
strncpy(r_stat.f_mntfromname.data(),
(utils::create_volume_label(config_.get_provider_type())).c_str(),
sizeof(r_stat.f_mntfromname) - 1U);
r_stat.f_mntfromname.size() - 1U);
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0);
return 0;
@@ -993,21 +1013,19 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
const auto file_path = construct_path(path);
struct timespec tv2[2] = {{0, 0}};
if ((op0 == UTIME_NOW) || (op0 == UTIME_OMIT)) {
tv2[0U].tv_nsec = static_cast<time_t>(op0);
tv2[0U].tv_sec = 0;
} else {
tv2[0U].tv_nsec = static_cast<time_t>(tv[0U] % NANOS_PER_SECOND);
tv2[0U].tv_sec = static_cast<time_t>(tv[0U] / NANOS_PER_SECOND);
}
const auto process_timespec = [](auto op, const auto &src, auto &dst) {
if ((op == UTIME_NOW) || (op == UTIME_OMIT)) {
dst.tv_nsec = static_cast<time_t>(op);
dst.tv_sec = 0;
return;
}
if ((op1 == UTIME_NOW) || (op1 == UTIME_OMIT)) {
tv2[1U].tv_nsec = static_cast<time_t>(op1);
tv2[1U].tv_sec = 0;
} else {
tv2[1U].tv_nsec = static_cast<time_t>(tv[1U] % NANOS_PER_SECOND);
tv2[1U].tv_sec = static_cast<time_t>(tv[1U] / NANOS_PER_SECOND);
}
dst.tv_nsec = static_cast<time_t>(src % utils::time::NANOS_PER_SECOND);
dst.tv_sec = static_cast<time_t>(src / utils::time::NANOS_PER_SECOND);
};
process_timespec(op0, tv[0U], tv2[0U]);
process_timespec(op1, tv[1U], tv2[1U]);
const auto res =
utimensat(0, file_path.c_str(), &tv2[0U], AT_SYMLINK_NOFOLLOW);
@@ -1065,7 +1083,7 @@ auto remote_server::winfsp_can_delete(PVOID file_desc,
STATUS_INVALID_HANDLE));
if (ret == STATUS_SUCCESS) {
ret = static_cast<packet::error_type>(
utils::file::is_directory(file_path)
utils::file::directory(file_path).exists()
? drive_.get_directory_item_count(
utils::path::create_api_path(relative_path))
? STATUS_DIRECTORY_NOT_EMPTY
@@ -1090,7 +1108,7 @@ auto remote_server::winfsp_cleanup(PVOID /*file_desc*/, PWSTR file_name,
const auto file_path = construct_path(relative_path);
was_closed = 0;
const auto directory = utils::file::is_directory(file_path);
const auto directory = utils::file::directory(file_path).exists();
if (flags & FileSystemBase::FspCleanupDelete) {
remove_all(file_path);
was_closed = 1;
@@ -1170,7 +1188,7 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
const auto relative_path = utils::string::to_utf8(file_name);
const auto file_path = construct_path(relative_path);
exists = utils::file::is_file(file_path);
exists = utils::file::file(file_path).exists();
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
attributes |= FILE_ATTRIBUTE_DIRECTORY;
@@ -1268,8 +1286,8 @@ auto remote_server::winfsp_get_security_by_name(
auto ret = static_cast<packet::error_type>(STATUS_SUCCESS);
const auto file_path = construct_path(file_name);
if (utils::file::is_file(file_path) ||
(utils::file::is_directory(file_path))) {
if (utils::file::file(file_path).exists() ||
(utils::file::directory(file_path).exists())) {
if (attributes) {
remote::file_info file_info{};
if ((ret = populate_file_info(construct_api_path(file_path),
@@ -1318,7 +1336,7 @@ auto remote_server::winfsp_open(
const auto relative_path = utils::string::to_utf8(file_name);
const auto file_path = construct_path(relative_path);
const auto directory = utils::file::is_directory(file_path);
const auto directory = utils::file::directory(file_path).exists();
if (directory) {
create_options |= FILE_DIRECTORY_FILE;
}
@@ -1489,11 +1507,11 @@ auto remote_server::winfsp_rename(
auto res = -1;
errno = ENOENT;
if (utils::file::is_file(file_path)) {
if (utils::file::file(file_path).exists()) {
res = drive_.rename_file(construct_api_path(file_path),
construct_api_path(new_file_path),
replace_if_exists != 0U);
} else if (utils::file::is_directory(file_path)) {
} else if (utils::file::directory(file_path).exists()) {
res = drive_.rename_directory(construct_api_path(file_path),
construct_api_path(new_file_path));
}
@@ -1523,7 +1541,7 @@ auto remote_server::winfsp_set_basic_info(
if (attributes == INVALID_FILE_ATTRIBUTES) {
attributes = 0;
} else if (attributes == 0) {
attributes = utils::file::is_directory(file_path)
attributes = utils::file::directory(file_path).exists()
? FILE_ATTRIBUTE_DIRECTORY
: FILE_ATTRIBUTE_NORMAL;
}
@@ -1542,25 +1560,28 @@ auto remote_server::winfsp_set_basic_info(
if ((creation_time != 0U) && (creation_time != max_time)) {
drive_.set_item_meta(
api_path, META_CREATION,
std::to_string(utils::windows_time_to_unix_time(creation_time)));
std::to_string(
utils::time::windows_time_to_unix_time(creation_time)));
}
if ((last_access_time != 0U) && (last_access_time != max_time)) {
drive_.set_item_meta(
api_path, META_ACCESSED,
std::to_string(utils::windows_time_to_unix_time(last_access_time)));
std::to_string(
utils::time::windows_time_to_unix_time(last_access_time)));
}
if ((last_write_time != 0U) && (last_write_time != max_time)) {
drive_.set_item_meta(
api_path, META_WRITTEN,
std::to_string(utils::windows_time_to_unix_time(last_write_time)));
std::to_string(
utils::time::windows_time_to_unix_time(last_write_time)));
}
if ((change_time != 0U) && (change_time != max_time)) {
drive_.set_item_meta(
api_path, META_MODIFIED,
std::to_string(utils::windows_time_to_unix_time(change_time)));
std::to_string(utils::time::windows_time_to_unix_time(change_time)));
}
ret = populate_file_info(api_path, *file_info);
@@ -1679,7 +1700,7 @@ auto remote_server::json_create_directory_snapshot(
auto res = -1;
errno = ENOENT;
if (utils::file::is_directory(file_path)) {
if (utils::file::directory(file_path).exists()) {
auto iter = std::make_shared<directory_iterator>(
drive_.get_directory_items(api_path));
auto handle = get_next_handle();
@@ -1745,12 +1766,22 @@ auto remote_server::json_release_directory_snapshot(
auto remote_server::update_to_windows_format(json &item) -> json & {
const auto api_path = item["path"].get<std::string>();
item["meta"][META_MODIFIED] = std::to_string(utils::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(item["meta"][META_MODIFIED]))));
item["meta"][META_CREATION] = std::to_string(utils::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(item["meta"][META_CREATION]))));
item["meta"][META_ACCESSED] = std::to_string(utils::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(item["meta"][META_ACCESSED]))));
item["meta"][META_ACCESSED] = std::to_string(
utils::string::to_uint64(empty_as_zero(item["meta"][META_ACCESSED])));
item["meta"][META_CREATION] = std::to_string(
utils::string::to_uint64(empty_as_zero(item["meta"][META_CREATION])));
item["meta"][META_MODIFIED] = std::to_string(
utils::string::to_uint64(empty_as_zero(item["meta"][META_MODIFIED])));
if (item["meta"][META_WRITTEN].empty() ||
(item["meta"][META_WRITTEN].get<std::string>() == "0") ||
(item["meta"][META_WRITTEN].get<std::string>() ==
std::to_string(utils::time::WIN32_TIME_CONVERSION))) {
drive_.set_item_meta(api_path, META_WRITTEN,
item["meta"][META_MODIFIED].get<std::string>());
item["meta"][META_WRITTEN] = item["meta"][META_MODIFIED];
}
if (item["meta"][META_ATTRIBUTES].empty()) {
item["meta"][META_ATTRIBUTES] =
item["directory"].get<bool>() ? std::to_string(FILE_ATTRIBUTE_DIRECTORY)
@@ -1759,19 +1790,6 @@ auto remote_server::update_to_windows_format(json &item) -> json & {
item["meta"][META_ATTRIBUTES].get<std::string>());
}
if (item["meta"][META_WRITTEN].empty() ||
(item["meta"][META_WRITTEN].get<std::string>() == "0") ||
(item["meta"][META_WRITTEN].get<std::string>() == "116444736000000000")) {
drive_.set_item_meta(api_path, META_WRITTEN,
item["meta"][META_MODIFIED].get<std::string>());
item["meta"][META_WRITTEN] = std::to_string(
utils::unix_time_to_windows_time(utils::string::to_uint64(
empty_as_zero(item["meta"][META_MODIFIED]))));
} else {
item["meta"][META_WRITTEN] = std::to_string(
utils::unix_time_to_windows_time(utils::string::to_uint64(
empty_as_zero(item["meta"][META_WRITTEN]))));
}
return item;
}
} // namespace repertory::remote_fuse

View File

@@ -39,14 +39,14 @@ void remote_open_file_table::add_directory(const std::string &client_id,
void remote_open_file_table::close_all(const std::string &client_id) {
std::vector<remote::file_handle> compat_handles;
unique_recur_mutex_lock compat_lock(compat_mutex_);
for (auto &kv : compat_lookup_) {
for (auto &&kv : compat_lookup_) {
if (kv.second.client_id == client_id) {
compat_handles.emplace_back(kv.first);
}
}
compat_lock.unlock();
for (auto &handle : compat_handles) {
for (auto &&handle : compat_handles) {
#if defined(_WIN32)
_close(static_cast<int>(handle));
#else
@@ -57,14 +57,14 @@ void remote_open_file_table::close_all(const std::string &client_id) {
std::vector<native_handle> handles;
unique_recur_mutex_lock file_lock(file_mutex_);
for (auto &kv : file_lookup_) {
for (auto &&kv : file_lookup_) {
if (kv.second.client_id == client_id) {
handles.emplace_back(kv.first);
}
}
file_lock.unlock();
for (auto &handle : handles) {
for (auto &&handle : handles) {
#if defined(_WIN32)
::CloseHandle(handle);
#else
@@ -75,7 +75,7 @@ void remote_open_file_table::close_all(const std::string &client_id) {
std::vector<std::uint64_t> dirs;
unique_recur_mutex_lock directory_lock(directory_mutex_);
for (auto &kv : directory_lookup_) {
for (auto &&kv : directory_lookup_) {
if (kv.first == client_id) {
dirs.insert(dirs.end(), kv.second.begin(), kv.second.end());
}
@@ -183,11 +183,11 @@ void remote_open_file_table::remove_all(const std::string &file_path) {
});
file_lock.unlock();
for (auto &handle : open_list) {
for (auto &&handle : open_list) {
remove_open_info(handle);
}
for (auto &handle : compat_open_list) {
for (auto &&handle : compat_open_list) {
remove_compat_open_info(handle);
}
}

View File

@@ -65,7 +65,10 @@ auto remote_client::winfsp_can_delete(PVOID file_desc,
request.encode(file_name);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
auto ret{
packet_client_.send(function_name, request, service_flags),
};
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
function_name,
utils::path::create_api_path(utils::string::to_utf8(file_name)), ret);
@@ -83,8 +86,9 @@ auto remote_client::json_create_directory_snapshot(
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
if (ret == 0) {
ret = packet::decode_json(response, json_data);
}
@@ -107,8 +111,9 @@ auto remote_client::json_read_directory_snapshot(
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
if (ret == 0) {
ret = packet::decode_json(response, json_data);
}
@@ -129,7 +134,9 @@ auto remote_client::json_release_directory_snapshot(
request.encode(handle);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
auto ret{
packet_client_.send(function_name, request, service_flags),
};
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, path, ret);
return ret;
@@ -142,8 +149,14 @@ auto remote_client::winfsp_cleanup(PVOID file_desc, PWSTR file_name,
static_cast<const char *>(__FUNCTION__),
};
auto handle = to_handle(file_desc);
const auto file_path = get_open_file_path(handle);
auto handle{
to_handle(file_desc),
};
auto file_path{
get_open_file_path(handle),
};
was_closed = 0;
packet request;
@@ -153,8 +166,9 @@ auto remote_client::winfsp_cleanup(PVOID file_desc, PWSTR file_name,
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, was_closed);
if (was_closed != 0U) {
remove_all(file_path);
@@ -168,15 +182,21 @@ auto remote_client::winfsp_close(PVOID file_desc) -> packet::error_type {
static_cast<const char *>(__FUNCTION__),
};
auto handle = to_handle(file_desc);
auto handle{
to_handle(file_desc),
};
if (has_open_info(handle, STATUS_INVALID_HANDLE) == STATUS_SUCCESS) {
const auto file_path = get_open_file_path(handle);
auto file_path{
get_open_file_path(handle),
};
packet request;
request.encode(file_desc);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
auto ret{
packet_client_.send(function_name, request, service_flags),
};
if ((ret == STATUS_SUCCESS) ||
(ret == static_cast<packet::error_type>(STATUS_INVALID_HANDLE))) {
remove_open_info(handle);
@@ -206,8 +226,9 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options,
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
if (ret == STATUS_SUCCESS) {
HANDLE handle{};
DECODE_OR_IGNORE(&response, handle);
@@ -243,8 +264,9 @@ auto remote_client::winfsp_flush(PVOID file_desc, remote::file_info *file_info)
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@@ -274,8 +296,9 @@ auto remote_client::winfsp_get_file_info(
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@@ -298,8 +321,9 @@ auto remote_client::winfsp_get_security_by_name(
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
string_descriptor.clear();
DECODE_OR_IGNORE(&response, string_descriptor);
@@ -326,8 +350,9 @@ auto remote_client::winfsp_get_volume_info(
packet request;
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, total_size);
DECODE_OR_IGNORE(&response, free_size);
DECODE_OR_IGNORE(&response, volume_label);
@@ -346,8 +371,13 @@ auto remote_client::winfsp_mounted(const std::wstring &location)
request.encode(location);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
const auto mount_location = utils::string::to_utf8(location);
auto ret{
packet_client_.send(function_name, request, service_flags),
};
auto mount_location{
utils::string::to_utf8(location),
};
event_system::instance().raise<drive_mounted>(mount_location);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, mount_location, ret);
@@ -369,8 +399,9 @@ auto remote_client::winfsp_open(
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
if (ret == STATUS_SUCCESS) {
HANDLE handle{};
DECODE_OR_IGNORE(&response, handle);
@@ -406,8 +437,9 @@ auto remote_client::winfsp_overwrite(
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@@ -429,8 +461,9 @@ auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *bytes_transferred);
if (ret == STATUS_SUCCESS) {
ret = response.decode(buffer, *bytes_transferred);
@@ -464,8 +497,9 @@ auto remote_client::winfsp_read_directory(PVOID file_desc, PWSTR pattern,
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
if (ret == STATUS_SUCCESS) {
ret = packet::decode_json(response, item_list);
}
@@ -489,7 +523,10 @@ auto remote_client::winfsp_rename(
request.encode(replace_if_exists);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
auto ret{
packet_client_.send(function_name, request, service_flags),
};
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
function_name,
utils::path::create_api_path(utils::string::to_utf8(file_name)) + "|" +
@@ -516,8 +553,9 @@ auto remote_client::winfsp_set_basic_info(
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@@ -539,8 +577,9 @@ auto remote_client::winfsp_set_file_size(
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@@ -554,13 +593,17 @@ auto remote_client::winfsp_unmounted(const std::wstring &location)
static_cast<const char *>(__FUNCTION__),
};
const auto mount_location = utils::string::to_utf8(location);
auto mount_location{
utils::string::to_utf8(location),
};
event_system::instance().raise<drive_unmount_pending>(mount_location);
packet request;
request.encode(location);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
auto ret{
packet_client_.send(function_name, request, service_flags),
};
event_system::instance().raise<drive_unmounted>(mount_location);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, mount_location, ret);
@@ -587,8 +630,9 @@ auto remote_client::winfsp_write(
packet response;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(function_name, request, response, service_flags);
auto ret{
packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *bytes_transferred);
DECODE_OR_IGNORE(&response, *file_info);
@@ -603,5 +647,5 @@ auto remote_client::winfsp_write(
auto remote_client::to_handle(PVOID file_desc) -> native_handle {
return static_cast<native_handle>(reinterpret_cast<std::uint64_t>(file_desc));
}
#endif
#endif // !defined(_WIN32)
} // namespace repertory::remote_winfsp

View File

@@ -38,18 +38,11 @@
#include "types/remote.hpp"
#include "types/repertory.hpp"
#include "utils/common.hpp"
#include "utils/file.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp"
#include "utils/time.hpp"
#if !defined(_SH_DENYNO)
#define _SH_DENYRW 0x10 // deny read/write mode
#define _SH_DENYWR 0x20 // deny write mode
#define _SH_DENYRD 0x30 // deny read mode
#define _SH_DENYNO 0x40 // deny none mode
#define _SH_SECURE 0x80 // secure mode
#endif
namespace repertory::remote_winfsp {
#define RAISE_REMOTE_WINFSP_SERVER_EVENT(func, file, ret) \
if (config_.get_enable_drive_events() && \
@@ -99,10 +92,14 @@ void remote_server::populate_stat(const char *path, bool directory,
directory ? 2 + drive_.get_directory_item_count(
utils::path::create_api_path(path))
: 1);
r_stat.st_atimespec = utils::time::time64_to_unix_time(unix_st.st_atime);
r_stat.st_birthtimespec = utils::time::time64_to_unix_time(unix_st.st_ctime);
r_stat.st_ctimespec = utils::time::time64_to_unix_time(unix_st.st_ctime);
r_stat.st_mtimespec = utils::time::time64_to_unix_time(unix_st.st_mtime);
r_stat.st_atimespec =
utils::time::windows_time_t_to_unix_time(unix_st.st_atime);
r_stat.st_birthtimespec =
utils::time::windows_time_t_to_unix_time(unix_st.st_ctime);
r_stat.st_ctimespec =
utils::time::windows_time_t_to_unix_time(unix_st.st_ctime);
r_stat.st_mtimespec =
utils::time::windows_time_t_to_unix_time(unix_st.st_mtime);
r_stat.st_size = static_cast<remote::file_size>(unix_st.st_size);
r_stat.st_mode = unix_st.st_mode;
}
@@ -114,10 +111,22 @@ auto remote_server::fuse_access(const char *path, const std::int32_t &mask)
static_cast<const char *>(__FUNCTION__),
};
const auto file_path = construct_path(path);
const auto windows_mask = utils::unix_access_mask_to_windows(mask);
const auto res = _access(file_path.c_str(), windows_mask);
const auto ret = ((res < 0) ? -errno : 0);
auto file_path{
construct_path(path),
};
auto windows_mask{
utils::unix_access_mask_to_windows(mask),
};
auto res{
_access(file_path.c_str(), windows_mask),
};
auto ret{
((res < 0) ? -errno : 0),
};
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
return ret;
}
@@ -188,12 +197,15 @@ auto remote_server::fuse_fgetattr(
static_cast<const char *>(__FUNCTION__),
};
const auto file_path = construct_path(path);
memset(&r_stat, 0, sizeof(remote::stat));
r_stat = {};
auto res = has_compat_open_info(handle, EBADF);
const auto file_path = construct_path(path);
auto res{
has_compat_open_info(handle, EBADF),
};
if (res == 0) {
directory = utils::file::is_directory(file_path);
directory = utils::file::directory(file_path).exists();
struct _stat64 unix_st {};
res = _fstat64(static_cast<int>(handle), &unix_st);
if (res == 0) {
@@ -228,7 +240,9 @@ auto remote_server::fuse_fsync(
const auto file_path = construct_path(path);
auto res = has_compat_open_info(handle, EBADF);
auto res{
has_compat_open_info(handle, EBADF),
};
if (res == 0) {
res = -1;
errno = EBADF;
@@ -257,7 +271,9 @@ auto remote_server::fuse_ftruncate(
const auto file_path = construct_path(path);
auto res = has_compat_open_info(handle, EBADF);
auto res{
has_compat_open_info(handle, EBADF),
};
if (res == 0) {
res = -1;
errno = EBADF;
@@ -286,13 +302,16 @@ auto remote_server::fuse_getattr(const char *path, remote::stat &r_st,
static_cast<const char *>(__FUNCTION__),
};
const auto file_path = construct_path(path);
memset(&r_st, 0, sizeof(remote::stat));
r_st = {};
directory = utils::file::is_directory(file_path);
const auto file_path = construct_path(path);
directory = utils::file::directory(file_path).exists();
struct _stat64 st1 {};
const auto res = _stat64(file_path.c_str(), &st1);
auto res{
_stat64(file_path.c_str(), &st1),
};
if (res == 0) {
populate_stat(path, directory, r_st, st1);
}
@@ -352,7 +371,9 @@ auto remote_server::fuse_mkdir(const char *path,
};
const auto file_path = construct_path(path);
const auto res = _mkdir(file_path.c_str());
auto res{
_mkdir(file_path.c_str()),
};
const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
return ret;
@@ -366,7 +387,7 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle)
const auto file_path = construct_path(path);
const auto unicode_file_path = utils::string::from_utf8(file_path);
auto res = -1;
auto res{-1};
errno = ENOENT;
if (::PathIsDirectoryW(unicode_file_path.c_str()) != 0) {
@@ -409,8 +430,9 @@ auto remote_server::fuse_create(const char *path, const remote::file_mode &mode,
ret = -EACCES;
} else {
int file = -1;
const auto res =
_sopen_s(&file, file_path.c_str(), open_flags, _SH_DENYNO, perms);
auto res{
_sopen_s(&file, file_path.c_str(), open_flags, _SH_DENYNO, perms),
};
if (res == 0) {
handle = static_cast<remote::file_handle>(file);
ret = 0;
@@ -432,7 +454,7 @@ auto remote_server::fuse_open(const char *path, const remote::open_flags &flags,
};
const auto file_path = construct_path(path);
auto res = -1;
auto res{-1};
if ((flags & remote::open_flags::directory) ==
remote::open_flags::directory) {
@@ -467,34 +489,21 @@ auto remote_server::fuse_read(
const auto file_path = construct_path(path);
auto &data = *reinterpret_cast<data_buffer *>(buffer);
auto res = 0;
auto res{0};
if (read_size > std::numeric_limits<std::size_t>::max()) {
res = -1;
errno = ERANGE;
} else if ((res = has_compat_open_info(handle, EBADF)) == 0) {
res = -1;
errno = EBADF;
auto *os_handle =
reinterpret_cast<HANDLE>(_get_osfhandle(static_cast<int>(handle)));
if (os_handle != INVALID_HANDLE_VALUE) {
errno = EFAULT;
auto file = native_file::attach(os_handle);
std::uint64_t file_size{};
if (file->get_file_size(file_size)) {
data.resize(utils::calculate_read_size(
file_size, static_cast<std::size_t>(read_size), read_offset));
if (!data.empty()) {
std::size_t bytes_read{};
if (file->read_bytes(data.data(), data.size(), read_offset,
bytes_read)) {
res = 0;
errno = 0;
}
} else {
res = 0;
errno = 0;
}
res = static_cast<std::decay_t<decltype(res)>>(_lseeki64(
static_cast<int>(handle), static_cast<__int64>(read_offset), SEEK_SET));
if (res != -1) {
data.resize(read_size);
res = read(static_cast<int>(handle), data.data(),
static_cast<unsigned int>(data.size()));
if (res == -1) {
data.resize(0U);
} else if (data.size() != static_cast<std::size_t>(res)) {
data.resize(static_cast<std::size_t>(res));
}
}
}
@@ -514,7 +523,9 @@ auto remote_server::fuse_rename(const char *from,
const auto from_path = utils::path::combine(mount_location_, {from});
const auto to_path = utils::path::combine(mount_location_, {to});
const auto res = rename(from_path.c_str(), to_path.c_str());
auto res{
rename(from_path.c_str(), to_path.c_str()),
};
const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, from + std::string("|") + to,
@@ -532,26 +543,21 @@ auto remote_server::fuse_write(
const auto file_path = construct_path(path);
std::size_t bytes_written{};
auto res = 0;
auto res{0};
if (write_size > std::numeric_limits<std::size_t>::max()) {
res = -1;
errno = ERANGE;
} else {
res = has_compat_open_info(handle, EBADF);
if (res == 0) {
res = -1;
errno = EBADF;
auto *os_handle =
reinterpret_cast<HANDLE>(_get_osfhandle(static_cast<int>(handle)));
if (os_handle != INVALID_HANDLE_VALUE) {
errno = EFAULT;
if ((write_size == 0) ||
native_file::attach(os_handle)->write_bytes(
reinterpret_cast<const unsigned char *>(buffer),
static_cast<std::size_t>(write_size), write_offset,
bytes_written)) {
res = 0;
errno = 0;
res = static_cast<std::decay_t<decltype(res)>>(
_lseeki64(static_cast<int>(handle),
static_cast<__int64>(write_offset), SEEK_SET));
if (res != -1) {
res = write(static_cast<int>(handle), buffer,
static_cast<unsigned int>(write_size));
if (res != -1) {
bytes_written = static_cast<std::size_t>(res);
}
}
}
@@ -582,7 +588,7 @@ auto remote_server::fuse_readdir(const char *path,
};
const auto file_path = construct_path(path);
auto res = 0;
auto res{0};
if (offset > std::numeric_limits<std::size_t>::max()) {
errno = ERANGE;
res = -1;
@@ -610,7 +616,9 @@ auto remote_server::fuse_release(
const auto file_path = construct_path(path);
remove_compat_open_info(handle);
const auto res = _close(static_cast<int>(handle));
auto res{
_close(static_cast<int>(handle)),
};
const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
@@ -642,7 +650,9 @@ auto remote_server::fuse_rmdir(const char *path) -> packet::error_type {
};
const auto file_path = construct_path(path);
const auto res = _rmdir(file_path.c_str());
auto res{
_rmdir(file_path.c_str()),
};
const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
return ret;
@@ -767,9 +777,9 @@ auto remote_server::fuse_statfs_x(const char *path, std::uint64_t bsize,
r_stat.f_files = 4294967295;
r_stat.f_ffree = r_stat.f_favail =
r_stat.f_files - drive_.get_total_item_count();
strncpy(&r_stat.f_mntfromname[0U],
strncpy(r_stat.f_mntfromname.data(),
(utils::create_volume_label(config_.get_provider_type())).c_str(),
sizeof(r_stat.f_mntfromname) - 1U);
r_stat.f_mntfromname.size() - 1U);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, 0);
return 0;
@@ -783,7 +793,7 @@ auto remote_server::fuse_truncate(
const auto file_path = construct_path(path);
const auto unicode_file_path = utils::string::from_utf8(file_path);
auto res = -1;
auto res{-1};
errno = ENOENT;
const auto flags_and_attributes =
@@ -818,7 +828,9 @@ auto remote_server::fuse_unlink(const char *path) -> packet::error_type {
};
const auto file_path = construct_path(path);
const auto res = _unlink(file_path.c_str());
auto res{
_unlink(file_path.c_str()),
};
const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
return ret;
@@ -834,7 +846,7 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
const auto file_path = construct_path(path);
const auto unicode_file_path = utils::string::from_utf8(file_path);
auto res = -1;
auto res{-1};
errno = ENOENT;
const auto flags_and_attributes =
@@ -849,29 +861,27 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
if (os_handle != INVALID_HANDLE_VALUE) {
FILETIME access_time{};
FILETIME write_time{};
FILETIME *access_time_ptr = nullptr;
FILETIME *write_time_ptr = nullptr;
FILETIME *access_time_ptr{nullptr};
FILETIME *write_time_ptr{nullptr};
if ((tv[0U] == 0U) || (op0 == UTIME_NOW)) {
const auto now = utils::time::get_file_time_now();
access_time.dwHighDateTime =
static_cast<DWORD>((now >> 32U) & 0xFFFFFFFF);
access_time.dwLowDateTime = now & 0xFFFFFFFF;
access_time_ptr = &access_time;
} else if (op0 != UTIME_OMIT) {
access_time = utils::time::unix_time_to_filetime(tv[0U]);
access_time_ptr = &access_time;
}
const auto proccess_timespec = [](auto op, const auto &src, auto &dst,
auto *&dst_ptr) {
if ((src == 0U) || (op == UTIME_NOW)) {
auto now =
utils::time::unix_time_to_windows_time(utils::time::get_time_now());
dst.dwHighDateTime = static_cast<DWORD>((now >> 32U) & 0xFFFFFFFF);
dst.dwLowDateTime = now & 0xFFFFFFFF;
dst_ptr = &dst;
return;
}
if ((tv[1U] == 0U) || (op1 == UTIME_NOW)) {
const auto now = utils::time::get_file_time_now();
write_time.dwHighDateTime = static_cast<DWORD>((now >> 32U) & 0xFFFFFFFF);
write_time.dwLowDateTime = now & 0xFFFFFFFF;
write_time_ptr = &write_time;
} else if (op1 != UTIME_OMIT) {
write_time = utils::time::unix_time_to_filetime(tv[1U]);
write_time_ptr = &write_time;
}
if (op != UTIME_OMIT) {
dst = utils::time::unix_time_to_filetime(src);
dst_ptr = &dst;
}
};
proccess_timespec(op0, tv[0U], access_time, access_time_ptr);
proccess_timespec(op1, tv[1U], write_time, write_time_ptr);
errno = EFAULT;
if (::SetFileTime(os_handle, nullptr, access_time_ptr, write_time_ptr) !=
@@ -879,6 +889,7 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
res = 0;
errno = 0;
}
::CloseHandle(os_handle);
}
@@ -896,10 +907,10 @@ auto remote_server::json_create_directory_snapshot(
const auto file_path = construct_path(path);
auto res = -1;
auto res{-1};
errno = ENOENT;
if (utils::file::is_directory(file_path)) {
if (utils::file::directory(file_path).exists()) {
auto iter = std::make_shared<directory_iterator>(
drive_.get_directory_items(utils::path::create_api_path(path)));
auto handle = get_next_handle();
@@ -1037,8 +1048,11 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
const auto file_path = utils::string::from_utf8(utils::path::combine(
mount_location_, {utils::string::to_utf8(file_name)}));
exists = static_cast<BOOLEAN>(utils::file::is_file(utils::path::combine(
mount_location_, {utils::string::to_utf8(file_name)})));
exists = static_cast<BOOLEAN>(
utils::file::file(
utils::path::combine(mount_location_,
{utils::string::to_utf8(file_name)}))
.exists());
auto create_flags = FILE_FLAG_BACKUP_SEMANTICS;
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
@@ -1500,4 +1514,4 @@ auto remote_server::winfsp_get_dir_buffer(PVOID /*file_desc*/, PVOID *& /*ptr*/)
}
} // namespace repertory::remote_winfsp
#endif // _WIN32
#endif // defined(_WIN32)

View File

@@ -62,7 +62,7 @@ auto remote_winfsp_drive::winfsp_service::OnStart(ULONG, PWSTR *) -> NTSTATUS {
(mount_location[1u] == ':');
auto ret = drive_letter ? STATUS_DEVICE_BUSY : STATUS_NOT_SUPPORTED;
if ((drive_letter && not utils::file::is_directory(mount_location))) {
if ((drive_letter && not utils::file::directory(mount_location).exists())) {
auto unicode_mount_location = utils::string::from_utf8(mount_location);
host_.SetFileSystemName(&unicode_mount_location[0u]);
if (config_.get_enable_mount_manager()) {
@@ -230,7 +230,7 @@ auto remote_winfsp_drive::Init(PVOID host) -> NTSTATUS {
file_system_host->SetPersistentAcls(FALSE);
file_system_host->SetPostCleanupWhenModifiedOnly(TRUE);
file_system_host->SetPassQueryDirectoryPattern(FALSE);
file_system_host->SetVolumeCreationTime(utils::time::get_file_time_now());
file_system_host->SetVolumeCreationTime(utils::time::get_time_now());
file_system_host->SetVolumeSerialNumber(0);
return STATUS_SUCCESS;
}
@@ -363,33 +363,33 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
utils::path::strip_to_file_name(item_path));
if (not marker || (marker && item_found)) {
// if (not utils::path::is_ads_file_path(item_path)) {
union {
UINT8 B[FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
((MAX_PATH + 1) * sizeof(WCHAR))];
FSP_FSCTL_DIR_INFO D;
} directory_info_buffer;
union {
UINT8 B[FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
((MAX_PATH + 1) * sizeof(WCHAR))];
FSP_FSCTL_DIR_INFO D;
} directory_info_buffer;
auto *directory_info = &directory_info_buffer.D;
::ZeroMemory(directory_info, sizeof(*directory_info));
directory_info->Size = static_cast<UINT16>(
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
(std::min((size_t)MAX_PATH, display_name.size()) *
sizeof(WCHAR)));
auto *directory_info = &directory_info_buffer.D;
::ZeroMemory(directory_info, sizeof(*directory_info));
directory_info->Size = static_cast<UINT16>(
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
(std::min(static_cast<size_t>(MAX_PATH), display_name.size()) *
sizeof(WCHAR)));
if (not item["meta"].empty() ||
((item_path != ".") && (item_path != ".."))) {
populate_file_info(item, directory_info->FileInfo);
}
if (ret == STATUS_SUCCESS) {
::wcscpy_s(&directory_info->FileNameBuf[0], MAX_PATH,
&display_name[0]);
FspFileSystemFillDirectoryBuffer(directory_buffer,
directory_info, &ret);
if (ret != STATUS_SUCCESS) {
break;
}
if (not item["meta"].empty() ||
((item_path != ".") && (item_path != ".."))) {
populate_file_info(item, directory_info->FileInfo);
}
if (ret == STATUS_SUCCESS) {
::wcscpy_s(&directory_info->FileNameBuf[0], MAX_PATH,
&display_name[0]);
FspFileSystemFillDirectoryBuffer(directory_buffer, directory_info,
&ret);
if (ret != STATUS_SUCCESS) {
break;
}
}
// }
} else {
item_found = display_name == std::wstring(marker);

View File

@@ -81,7 +81,7 @@ auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/,
(mount_location[1U] == ':');
auto ret = drive_letter ? STATUS_DEVICE_BUSY : STATUS_NOT_SUPPORTED;
if ((drive_letter && not utils::file::is_directory(mount_location))) {
if ((drive_letter && not utils::file::directory(mount_location).exists())) {
auto unicode_mount_location = utils::string::from_utf8(mount_location);
host_.SetFileSystemName(unicode_mount_location.data());
if (config_.get_enable_mount_manager()) {
@@ -215,7 +215,7 @@ VOID winfsp_drive::Cleanup(PVOID file_node, PVOID file_desc,
if ((flags & (FspCleanupSetLastAccessTime | FspCleanupSetLastWriteTime |
FspCleanupSetChangeTime)) != 0U) {
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
if ((flags & FspCleanupSetLastAccessTime) != 0U) {
auto res = provider_.set_item_meta(api_path, META_ACCESSED,
std::to_string(now));
@@ -238,8 +238,10 @@ VOID winfsp_drive::Cleanup(PVOID file_node, PVOID file_desc,
if ((flags & FspCleanupSetChangeTime) != 0U) {
auto res = provider_.set_item_meta(
api_path, {{META_CHANGED, std::to_string(now)},
{META_MODIFIED, std::to_string(now)}});
api_path, {
{META_CHANGED, std::to_string(now)},
{META_MODIFIED, std::to_string(now)},
});
if (res != api_error::success) {
utils::error::raise_api_path_error(
function_name, api_path, res,
@@ -310,7 +312,7 @@ auto winfsp_drive::Create(PWSTR file_name, UINT32 create_options,
attributes = FILE_ATTRIBUTE_NORMAL;
}
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, attributes, now, now, (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0U,
0U, "", 0U, now, 0U, 0U, 0U,
@@ -477,8 +479,7 @@ auto winfsp_drive::get_security_by_name(
if (descriptor_size != nullptr) {
ULONG size{};
PSECURITY_DESCRIPTOR sec_desc{};
if (::ConvertStringSecurityDescriptorToSecurityDescriptor(
if (::ConvertStringSecurityDescriptorToSecurityDescriptorA(
"O:BAG:BAD:P(A;;FA;;;SY)(A;;FA;;;BA)(A;;FA;;;WD)",
SDDL_REVISION_1, &sec_desc, &size) != 0) {
if (size > *descriptor_size) {
@@ -512,6 +513,7 @@ auto winfsp_drive::GetSecurityByName(PWSTR file_name, PUINT32 attributes,
if (sds != 0U) {
*descriptor_size = static_cast<SIZE_T>(sds);
}
RAISE_WINFSP_EVENT(function_name, api_path, ret);
return ret;
}
@@ -579,7 +581,7 @@ auto winfsp_drive::Init(PVOID host) -> NTSTATUS {
file_system_host->SetPersistentAcls(FALSE);
file_system_host->SetPostCleanupWhenModifiedOnly(TRUE);
file_system_host->SetPassQueryDirectoryPattern(FALSE);
file_system_host->SetVolumeCreationTime(utils::time::get_file_time_now());
file_system_host->SetVolumeCreationTime(utils::time::get_time_now());
file_system_host->SetVolumeSerialNumber(0);
return STATUS_SUCCESS;
}
@@ -590,7 +592,7 @@ auto winfsp_drive::mount(const std::vector<std::string> &drive_args) -> int {
const auto force_no_console = utils::collection::includes(drive_args, "-nc");
auto enable_console = false;
for (const auto &arg : drive_args) {
for (auto &&arg : drive_args) {
if (arg == "-f") {
if (not force_no_console) {
enable_console = true;
@@ -620,10 +622,14 @@ auto winfsp_drive::Mounted(PVOID host) -> NTSTATUS {
static_cast<const char *>(__FUNCTION__),
};
auto ret = STATUS_SUCCESS;
utils::file::change_to_process_directory();
auto ret{STATUS_SUCCESS};
if (not utils::file::change_to_process_directory()) {
return static_cast<NTSTATUS>(utils::get_last_error_code());
}
auto *file_system_host = reinterpret_cast<FileSystemHost *>(host);
auto *file_system_host{
reinterpret_cast<FileSystemHost *>(host),
};
polling::instance().start(&config_);
fm_ = std::make_unique<file_manager>(config_, provider_);
server_ = std::make_unique<full_server>(config_, provider_, *fm_);
@@ -868,7 +874,7 @@ auto winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc, PVOID buffer,
data.clear();
auto res = provider_.set_item_meta(
api_path, META_ACCESSED,
std::to_string(utils::time::get_file_time_now()));
std::to_string(utils::time::get_time_now()));
if (res != api_error::success) {
utils::error::raise_api_path_error(
function_name, api_path, res,
@@ -929,10 +935,9 @@ auto winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
api_path, {utils::string::to_utf8(marker)})));
while ((error = iterator.get_directory_item(
offset++, dir_item)) == api_error::success) {
// if (utils::path::is_ads_file_path(dir_item.api_path) ||
// dir_item.api_path == "." || dir_item.api_path == "..") {
// continue;
// }
if (dir_item.api_path == "." || dir_item.api_path == "..") {
continue;
}
if (dir_item.meta.empty()) {
utils::error::raise_api_path_error(
@@ -1058,17 +1063,22 @@ auto winfsp_drive::SetBasicInfo(PVOID /*file_node*/, PVOID file_desc,
meta[META_ATTRIBUTES] = std::to_string(attributes);
}
if ((creation_time != 0U) && (creation_time != max_time)) {
meta[META_CREATION] = std::to_string(creation_time);
meta[META_CREATION] = std::to_string(
utils::time::windows_time_to_unix_time(creation_time));
}
if ((last_access_time != 0U) && (last_access_time != max_time)) {
meta[META_ACCESSED] = std::to_string(last_access_time);
meta[META_ACCESSED] = std::to_string(
utils::time::windows_time_to_unix_time(last_access_time));
}
if ((last_write_time != 0U) && (last_write_time != max_time)) {
meta[META_WRITTEN] = std::to_string(last_write_time);
meta[META_WRITTEN] = std::to_string(
utils::time::windows_time_to_unix_time(last_write_time));
}
if ((change_time != 0U) && (change_time != max_time)) {
meta[META_CHANGED] = std::to_string(change_time);
meta[META_MODIFIED] = std::to_string(change_time);
meta[META_CHANGED] =
std::to_string(utils::time::windows_time_to_unix_time(change_time));
meta[META_MODIFIED] =
std::to_string(utils::time::windows_time_to_unix_time(change_time));
}
error = provider_.set_item_meta(api_path, meta);

View File

@@ -116,7 +116,7 @@ file_manager::file_manager(app_config &config, i_provider &provider)
}
db_.reset(db3);
for (const auto &create_item : sql_create_tables) {
for (auto &&create_item : sql_create_tables) {
std::string err;
if (not db::execute_sql(*db_, create_item.second, err)) {
db_.reset();
@@ -176,12 +176,12 @@ void file_manager::close_timed_out_files() {
}
return items;
});
for (const auto &closeable_file : closeable_list) {
for (auto &&closeable_file : closeable_list) {
open_file_lookup_.erase(closeable_file->get_api_path());
}
file_lock.unlock();
for (auto &closeable_file : closeable_list) {
for (auto &&closeable_file : closeable_list) {
closeable_file->close();
event_system::instance().raise<item_timeout>(
closeable_file->get_api_path());
@@ -244,7 +244,7 @@ auto file_manager::evict_file(const std::string &api_path) -> bool {
open_file_lookup_.erase(api_path);
auto removed = utils::file::retry_delete_file(source_path);
auto removed = utils::file::file(source_path).remove();
if (removed) {
event_system::instance().raise<filesystem_item_evicted>(api_path,
source_path);
@@ -329,7 +329,7 @@ auto file_manager::get_open_files() const
std::unordered_map<std::string, std::size_t> ret;
recur_mutex_lock open_lock(open_file_mtx_);
for (const auto &item : open_file_lookup_) {
for (auto &&item : open_file_lookup_) {
ret[item.first] = item.second->get_open_file_count();
}
@@ -513,8 +513,8 @@ void file_manager::queue_upload(const std::string &api_path,
db::db_insert{*db_.get(), upload_table}
.or_replace()
.column_value("api_path", api_path)
.column_value("date_time", static_cast<std::int64_t>(
utils::time::get_file_time_now()))
.column_value("date_time",
static_cast<std::int64_t>(utils::time::get_time_now()))
.column_value("source_path", source_path)
.go();
if (result.ok()) {
@@ -557,7 +557,7 @@ auto file_manager::remove_file(const std::string &api_path) -> api_error {
return res;
}
if (not utils::file::retry_delete_file(fsi.source_path)) {
if (not utils::file::file(fsi.source_path).remove()) {
utils::error::raise_api_path_error(
function_name, fsi.api_path, fsi.source_path,
utils::get_last_error_code(), "failed to delete source");
@@ -778,14 +778,9 @@ auto file_manager::rename_file(const std::string &from_api_path,
return res;
}
std::uint64_t file_size{};
if (not utils::file::get_file_size(fsi.source_path, file_size)) {
return api_error::os_error;
}
res = remove_file(to_api_path);
if ((res == api_error::success) || (res == api_error::item_not_found)) {
if (not utils::file::retry_delete_file(fsi.source_path)) {
if (not utils::file::file(fsi.source_path).remove()) {
utils::error::raise_api_path_error(
function_name, fsi.api_path, fsi.source_path,
utils::get_last_error_code(), "failed to delete source path");
@@ -848,7 +843,7 @@ void file_manager::start() {
}
}
for (const auto &active_item : active_items) {
for (auto &&active_item : active_items) {
queue_upload(active_item.api_path, active_item.source_path, false);
}
active_items.clear();
@@ -878,8 +873,9 @@ void file_manager::start() {
auto res = provider_.get_filesystem_item(api_path, false, fsi);
if (res == api_error::success) {
if (source_path == fsi.source_path) {
std::uint64_t file_size{};
if (utils::file::get_file_size(fsi.source_path, file_size)) {
auto opt_size = utils::file::file{fsi.source_path}.size();
if (opt_size.has_value()) {
auto file_size{opt_size.value()};
if (file_size == fsi.size) {
auto closeable_file = std::make_shared<open_file>(
chunk_size,
@@ -941,7 +937,7 @@ void file_manager::stop() {
open_file_lookup_.clear();
upload_lock.lock();
for (auto &item : upload_lookup_) {
for (auto &&item : upload_lookup_) {
item.second->stop();
}
upload_notify_.notify_all();
@@ -1027,7 +1023,7 @@ void file_manager::upload_completed(const file_upload_completed &evt) {
bool exists{};
auto res = provider_.is_file(evt.get_api_path(), exists);
if ((res == api_error::success && not exists) ||
not utils::file::is_file(evt.get_source().get<std::string>())) {
not utils::file::file(evt.get_source().get<std::string>()).exists()) {
event_system::instance().raise<file_upload_not_found>(
evt.get_api_path(), evt.get_source());
remove_upload(evt.get_api_path(), true);
@@ -1129,7 +1125,7 @@ void file_manager::upload_handler() {
void file_manager::update_used_space(std::uint64_t &used_space) const {
recur_mutex_lock open_lock(open_file_mtx_);
for (const auto &item : open_file_lookup_) {
for (auto &&item : open_file_lookup_) {
std::uint64_t file_size{};
auto res = provider_.get_file_size(item.second->get_api_path(), file_size);
if ((res == api_error::success) &&

View File

@@ -66,8 +66,9 @@ file_manager::open_file::open_file(
}
if (not fsi.directory) {
set_api_error(native_file::create_or_open(fsi.source_path,
provider_.is_direct_only(), nf_));
nf_ = utils::file::file::open_or_create_file(fsi.source_path,
provider_.is_direct_only());
set_api_error(*nf_ ? api_error::success : api_error::os_error);
if (get_api_error() == api_error::success) {
if (read_state.has_value()) {
read_state_ = read_state.value();
@@ -77,19 +78,15 @@ file_manager::open_file::open_file(
fsi_.size, chunk_size)),
false);
std::uint64_t file_size{};
if (nf_->get_file_size(file_size)) {
if (provider_.is_direct_only() || file_size == fsi.size) {
read_state_.set(0U, read_state_.size(), true);
} else if (not nf_->truncate(fsi.size)) {
set_api_error(api_error::os_error);
}
} else {
auto file_size = nf_->size();
if (provider_.is_direct_only() || file_size == fsi.size) {
read_state_.set(0U, read_state_.size(), true);
} else if (not nf_->truncate(fsi.size)) {
set_api_error(api_error::os_error);
}
}
if (get_api_error() != api_error::success && nf_) {
if (get_api_error() != api_error::success && *nf_) {
nf_->close();
}
}
@@ -185,8 +182,7 @@ void file_manager::open_file::download_chunk(std::size_t chunk,
res = do_io([&]() -> api_error {
std::size_t bytes_written{};
if (not nf_->write_bytes(data.data(), data.size(), data_offset,
bytes_written)) {
if (not nf_->write(data, data_offset, &bytes_written)) {
return api_error::os_error;
}
@@ -296,14 +292,7 @@ auto file_manager::open_file::native_operation(
}
{
std::uint64_t file_size{};
if (not nf_->get_file_size(file_size)) {
utils::error::raise_api_path_error(function_name, get_api_path(),
utils::get_last_error_code(),
"failed to get file size");
return set_api_error(api_error::os_error);
}
auto file_size = nf_->size().value_or(0U);
if (file_size != new_file_size) {
utils::error::raise_api_path_error(
function_name, get_api_path(), api_error::file_size_mismatch,
@@ -331,7 +320,7 @@ auto file_manager::open_file::native_operation(
set_modified();
fsi_.size = new_file_size;
const auto now = std::to_string(utils::time::get_file_time_now());
const auto now = std::to_string(utils::time::get_time_now());
res = provider_.set_item_meta(
fsi_.api_path, {
{META_CHANGED, now},
@@ -372,7 +361,7 @@ auto file_manager::open_file::read(std::size_t read_size,
data.resize(read_size);
std::size_t bytes_read{};
return nf_->read_bytes(data.data(), read_size, read_offset, bytes_read)
return nf_->read(data.data(), read_size, read_offset, &bytes_read)
? api_error::success
: api_error::os_error;
});
@@ -461,7 +450,6 @@ auto file_manager::open_file::close() -> bool {
}
nf_->close();
nf_.reset();
if (modified_ && (get_api_error() == api_error::success)) {
mgr_.queue_upload(*this);
@@ -470,13 +458,13 @@ auto file_manager::open_file::close() -> bool {
mgr_.store_resume(*this);
} else if (get_api_error() != api_error::success) {
mgr_.remove_resume(get_api_path(), get_source_path());
if (not utils::file::retry_delete_file(fsi_.source_path)) {
if (not utils::file::file(fsi_.source_path).remove()) {
utils::error::raise_api_path_error(
function_name, get_api_path(), fsi_.source_path,
utils::get_last_error_code(), "failed to delete file");
}
auto parent = utils::path::remove_file_name(fsi_.source_path);
auto parent = utils::path::get_parent_path(fsi_.source_path);
fsi_.source_path =
utils::path::combine(parent, {utils::create_uuid_string()});
const auto res = provider_.set_item_meta(fsi_.api_path, META_SOURCE,
@@ -587,8 +575,7 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
}
auto res = do_io([&]() -> api_error {
if (not nf_->write_bytes(data.data(), data.size(), write_offset,
bytes_written)) {
if (not nf_->write(data, write_offset, &bytes_written)) {
return api_error::os_error;
}
@@ -599,7 +586,7 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
return set_api_error(res);
}
const auto now = std::to_string(utils::time::get_file_time_now());
const auto now = std::to_string(utils::time::get_time_now());
res = provider_.set_item_meta(fsi_.api_path, {
{META_CHANGED, now},
{META_MODIFIED, now},

View File

@@ -157,7 +157,7 @@ auto file_manager::open_file_base::get_handles() const
-> std::vector<std::uint64_t> {
recur_mutex_lock file_lock(file_mtx_);
std::vector<std::uint64_t> ret;
for (const auto &item : open_data_) {
for (auto &&item : open_data_) {
ret.emplace_back(item.first);
}

View File

@@ -64,7 +64,7 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
ring_state_.set(0U, ring_state_.size(), true);
buffer_directory = utils::path::absolute(buffer_directory);
if (not utils::file::create_full_directory_path(buffer_directory)) {
if (not utils::file::directory(buffer_directory).create_directory()) {
throw std::runtime_error("failed to create buffer directory|path|" +
buffer_directory + "|err|" +
std::to_string(utils::get_last_error_code()));
@@ -72,8 +72,8 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
fsi_.source_path =
utils::path::combine(buffer_directory, {utils::create_uuid_string()});
auto res = native_file::create_or_open(fsi_.source_path, nf_);
if (res != api_error::success) {
nf_ = utils::file::file::open_or_create_file(fsi_.source_path);
if (not *nf_) {
throw std::runtime_error("failed to create buffer file|err|" +
std::to_string(utils::get_last_error_code()));
}
@@ -93,7 +93,7 @@ file_manager::ring_buffer_open_file::~ring_buffer_open_file() {
close();
nf_->close();
if (not utils::file::retry_delete_file(fsi_.source_path)) {
if (not utils::file::file(fsi_.source_path).remove()) {
utils::error::raise_api_path_error(
function_name, fsi_.api_path, fsi_.source_path,
utils::get_last_error_code(), "failed to delete file");
@@ -128,9 +128,8 @@ auto file_manager::file_manager::ring_buffer_open_file::download_chunk(
if (res == api_error::success) {
res = do_io([&]() -> api_error {
std::size_t bytes_written{};
if (not nf_->write_bytes(buffer.data(), buffer.size(),
(chunk % ring_state_.size()) * chunk_size_,
bytes_written)) {
if (not nf_->write(buffer, (chunk % ring_state_.size()) * chunk_size_,
&bytes_written)) {
return api_error::os_error;
}
@@ -169,8 +168,8 @@ void file_manager::ring_buffer_open_file::forward(std::size_t count) {
last_chunk_ =
std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U);
} else {
for (std::size_t i = 0U; i < added; i++) {
ring_state_[(first_chunk_ + i) % ring_state_.size()] = true;
for (std::size_t idx = 0U; idx < added; ++idx) {
ring_state_[(first_chunk_ + idx) % ring_state_.size()] = true;
}
first_chunk_ += added;
current_chunk_ += count;
@@ -221,8 +220,8 @@ void file_manager::ring_buffer_open_file::reverse(std::size_t count) {
last_chunk_ =
std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U);
} else {
for (std::size_t i = 0U; i < removed; i++) {
ring_state_[(last_chunk_ - i) % ring_state_.size()] = true;
for (std::size_t idx = 0U; idx < removed; ++idx) {
ring_state_[(last_chunk_ - idx) % ring_state_.size()] = true;
}
first_chunk_ -= removed;
current_chunk_ -= count;
@@ -255,7 +254,7 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
auto res = api_error::success;
for (std::size_t chunk = start_chunk_index;
(res == api_error::success) && (read_size > 0U); chunk++) {
(res == api_error::success) && (read_size > 0U); ++chunk) {
if (chunk > current_chunk_) {
forward(chunk - current_chunk_);
} else if (chunk < current_chunk_) {
@@ -270,11 +269,11 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
res = do_io([this, &buffer, &chunk, &data, read_offset,
&to_read]() -> api_error {
std::size_t bytes_read{};
auto ret = nf_->read_bytes(buffer.data(), buffer.size(),
((chunk % ring_state_.size()) * chunk_size_),
bytes_read)
? api_error::success
: api_error::os_error;
auto ret =
nf_->read(buffer, ((chunk % ring_state_.size()) * chunk_size_),
&bytes_read)
? api_error::success
: api_error::os_error;
if (ret == api_error::success) {
data.insert(data.end(),
buffer.begin() + static_cast<std::int64_t>(read_offset),

View File

@@ -29,8 +29,8 @@
#if defined(PROJECT_REQUIRE_ALPINE) && !defined(PROJECT_IS_MINGW)
#include <filesystem>
#include <stdlib.h>
#include <pthread.h>
#include <stdlib.h>
#endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW)
#if defined(PROJECT_ENABLE_LIBSODIUM)
@@ -44,6 +44,9 @@
#include "spdlog/spdlog.h"
#include "initialize.hpp"
#if defined(PROJECT_REQUIRE_ALPINE) && !defined(PROJECT_IS_MINGW)
#include "utils/path.hpp"
#endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW)
namespace repertory {
auto project_initialize() -> bool {
@@ -61,11 +64,7 @@ auto project_initialize() -> bool {
pthread_attr_setguardsize(&attr, guard_size);
pthread_setattr_default_np(&attr);
const auto icu_dir =
std::filesystem::absolute(std::filesystem::path{"./icu"})
.lexically_normal()
.string();
setenv("ICU_DATA", icu_dir.c_str(), 1);
setenv("ICU_DATA", utils::path::combine(".", {"/icu"}).c_str(), 1);
}
#endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW)

View File

@@ -57,7 +57,7 @@ lock_data::~lock_data() {
auto lock_data::get_lock_data_file() -> std::string {
const auto dir = get_state_directory();
if (not utils::file::create_full_directory_path(dir)) {
if (not utils::file::directory(dir).create_directory()) {
throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
std::to_string(utils::get_last_error_code()));
}
@@ -67,7 +67,7 @@ auto lock_data::get_lock_data_file() -> std::string {
auto lock_data::get_lock_file() -> std::string {
const auto dir = get_state_directory();
if (not utils::file::create_full_directory_path(dir)) {
if (not utils::file::directory(dir).create_directory()) {
throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
std::to_string(utils::get_last_error_code()));
}
@@ -184,8 +184,11 @@ auto lock_data::wait_for_lock(int fd, std::uint8_t retry_count) -> int {
if (lock_status == -1) {
lock_status = errno;
if (lock_status == EWOULDBLOCK) {
auto sleep_ms =
utils::generate_random_between(1U, std::min(remain, max_sleep));
auto sleep_ms = std::min(remain, max_sleep);
if (sleep_ms > 1U) {
sleep_ms = utils::generate_random_between(1U, sleep_ms);
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
remain -= sleep_ms;
}

View File

@@ -37,10 +37,10 @@ auto base_provider::create_api_file(std::string path, std::string key,
api_file file{};
file.api_path = utils::path::create_api_path(path);
file.api_parent = utils::path::get_parent_api_path(file.api_path);
file.accessed_date = utils::time::get_file_time_now();
file.changed_date = utils::time::get_file_time_now();
file.creation_date = utils::time::get_file_time_now();
file.modified_date = utils::time::get_file_time_now();
file.accessed_date = utils::time::get_time_now();
file.changed_date = utils::time::get_time_now();
file.creation_date = utils::time::get_time_now();
file.modified_date = utils::time::get_time_now();
file.key = key;
file.file_size = size;
return file;
@@ -455,7 +455,7 @@ void base_provider::remove_deleted_files() {
std::vector<removed_item> removed_list{};
for (const auto &api_path : db3_->get_api_path_list()) {
for (auto &&api_path : db3_->get_api_path_list()) {
api_meta_map meta{};
if (get_item_meta(api_path, meta) == api_error::success) {
if (utils::string::to_bool(meta[META_DIRECTORY])) {
@@ -480,12 +480,12 @@ void base_provider::remove_deleted_files() {
}
}
for (const auto &item : removed_list) {
for (auto &&item : removed_list) {
if (not item.directory) {
if (utils::file::is_file(item.source_path)) {
if (utils::file::file(item.source_path).exists()) {
const auto orphaned_directory =
utils::path::combine(config_.get_data_directory(), {"orphaned"});
if (utils::file::create_full_directory_path(orphaned_directory)) {
if (utils::file::directory(orphaned_directory).create_directory()) {
const auto parts = utils::string::split(item.api_path, '/', false);
const auto orphaned_file = utils::path::combine(
orphaned_directory,
@@ -495,7 +495,8 @@ void base_provider::remove_deleted_files() {
event_system::instance().raise<orphaned_file_detected>(
item.source_path);
if (utils::file::reset_modified_time(item.source_path) &&
utils::file::copy_file(item.source_path, orphaned_file)) {
utils::file::file(item.source_path)
.copy_to(orphaned_file, true)) {
event_system::instance().raise<orphaned_file_processed>(
item.source_path, orphaned_file);
} else {
@@ -506,7 +507,7 @@ void base_provider::remove_deleted_files() {
} else {
utils::error::raise_error(
function_name, std::to_string(utils::get_last_error_code()),
"failed to create orphaned director|sp|" + orphaned_directory);
"failed to create orphaned directory|sp|" + orphaned_directory);
continue;
}
}
@@ -519,7 +520,7 @@ void base_provider::remove_deleted_files() {
}
}
for (const auto &item : removed_list) {
for (auto &&item : removed_list) {
if (item.directory) {
db3_->remove_api_path(item.api_path);
event_system::instance().raise<directory_removed_externally>(
@@ -640,9 +641,9 @@ auto base_provider::start(api_item_added_callback api_item_added,
repertory::event_consumer consumer(
"unmount_requested",
[&unmount_requested](const event &) { unmount_requested = true; });
for (std::uint16_t i = 0U; not online && not unmount_requested &&
(i < config_.get_online_check_retry_secs());
i++) {
for (std::uint16_t idx = 0U; not online && not unmount_requested &&
(idx < config_.get_online_check_retry_secs());
++idx) {
online = is_online();
if (not online) {
event_system::instance().raise<provider_offline>(

View File

@@ -28,12 +28,11 @@
#include "events/events.hpp"
#include "types/repertory.hpp"
#include "utils/collection.hpp"
#include "utils/encrypt.hpp"
#include "utils/encrypting_reader.hpp"
#include "utils/encryption.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp"
#include "utils/polling.hpp"
#include "utils/time.hpp"
namespace {
const std::string directory_table = "directory";
@@ -72,61 +71,24 @@ encrypt_provider::encrypt_provider(app_config &config) : config_(config) {}
auto encrypt_provider::create_api_file(
const std::string &api_path, bool directory,
const std::string &source_path) -> api_file {
#if defined(_WIN32)
struct _stat64 buf {};
_stat64(source_path.c_str(), &buf);
#else
struct stat buf {};
stat(source_path.c_str(), &buf);
#endif
auto times = utils::file::get_times(source_path);
if (not times.has_value()) {
throw std::runtime_error("failed to get file times");
}
api_file file{};
file.accessed_date = times->get(utils::file::time_type::accessed);
file.api_path = api_path;
file.api_parent = utils::path::get_parent_api_path(api_path);
file.changed_date = times->get(utils::file::time_type::modified);
file.creation_date = times->get(utils::file::time_type::created);
file.file_size =
directory
? 0U
: utils::encryption::encrypting_reader::calculate_encrypted_size(
source_path);
file.modified_date = times->get(utils::file::time_type::written);
file.source_path = source_path;
#if defined(__APPLE__)
file.changed_date =
buf.st_ctimespec.tv_nsec + (buf.st_ctimespec.tv_sec * NANOS_PER_SECOND);
file.accessed_date =
buf.st_atimespec.tv_nsec + (buf.st_atimespec.tv_sec * NANOS_PER_SECOND);
file.creation_date = buf.st_birthtimespec.tv_nsec +
(buf.st_birthtimespec.tv_sec * NANOS_PER_SECOND);
file.modified_date =
buf.st_mtimespec.tv_nsec + (buf.st_mtimespec.tv_sec * NANOS_PER_SECOND);
#elif defined(_WIN32)
auto ft = utils::time::unix_time_to_filetime(
utils::time::time64_to_unix_time(buf.st_atime));
file.accessed_date =
(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32U) | ft.dwLowDateTime;
ft = utils::time::unix_time_to_filetime(
utils::time::time64_to_unix_time(buf.st_mtime));
file.changed_date =
(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32U) | ft.dwLowDateTime;
ft = utils::time::unix_time_to_filetime(
utils::time::time64_to_unix_time(buf.st_ctime));
file.creation_date =
(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32U) | ft.dwLowDateTime;
ft = utils::time::unix_time_to_filetime(utils::time::time64_to_unix_time(buf.st_mtime));
file.modified_date =
(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32U) | ft.dwLowDateTime;
#else
file.changed_date = static_cast<std::uint64_t>(
buf.st_mtim.tv_nsec + (buf.st_mtim.tv_sec * NANOS_PER_SECOND));
file.accessed_date = static_cast<std::uint64_t>(
buf.st_atim.tv_nsec + (buf.st_atim.tv_sec * NANOS_PER_SECOND));
file.creation_date = static_cast<std::uint64_t>(
buf.st_ctim.tv_nsec + (buf.st_ctim.tv_sec * NANOS_PER_SECOND));
file.modified_date = static_cast<std::uint64_t>(
buf.st_mtim.tv_nsec + (buf.st_mtim.tv_sec * NANOS_PER_SECOND));
#endif
return file;
}
@@ -136,19 +98,21 @@ void encrypt_provider::create_item_meta(api_meta_map &meta, bool directory,
#if defined(_WIN32)
struct _stat64 buf {};
_stat64(file.source_path.c_str(), &buf);
#else
#else // !defined(_WIN32)
struct stat buf {};
stat(file.source_path.c_str(), &buf);
#endif
#endif // defined(_WIN32)
meta[META_ACCESSED] = std::to_string(file.accessed_date);
#if defined(_WIN32)
meta[META_ATTRIBUTES] =
std::to_string(::GetFileAttributesA(file.source_path.c_str()));
#endif
std::to_string(::GetFileAttributesA(file.source_path.c_str()) &
~static_cast<DWORD>(FILE_ATTRIBUTE_REPARSE_POINT));
#endif // defined(_WIN32)
#if defined(__APPLE__)
meta[META_BACKUP];
#endif
#endif // defined(__APPLE__)
meta[META_CHANGED] = std::to_string(file.changed_date);
meta[META_CREATION] = std::to_string(file.creation_date);
meta[META_DIRECTORY] = utils::string::from_bool(directory);
@@ -157,7 +121,7 @@ void encrypt_provider::create_item_meta(api_meta_map &meta, bool directory,
meta[META_MODIFIED] = std::to_string(file.modified_date);
#if defined(__APPLE__)
meta[META_OSXFLAGS];
#endif
#endif // defined(__APPLE__)
meta[META_SIZE] = std::to_string(file.file_size);
meta[META_SOURCE] = file.source_path;
meta[META_UID] = std::to_string(buf.st_uid);
@@ -180,13 +144,10 @@ auto encrypt_provider::do_fs_operation(
callback) const -> api_error {
auto cfg = config_.get_encrypt_config();
std::string source_path{api_path};
if (api_path != "/") {
auto res =
utils::encryption::decrypt_file_path(cfg.encryption_token, source_path);
if (res != api_error::success) {
return directory ? api_error::directory_not_found
: api_error::item_not_found;
}
if (api_path != "/" && not utils::encryption::decrypt_file_path(
cfg.encryption_token, source_path)) {
return directory ? api_error::directory_not_found
: api_error::item_not_found;
}
source_path = utils::path::combine(cfg.path, {source_path});
@@ -197,7 +158,11 @@ auto encrypt_provider::do_fs_operation(
: api_error::item_not_found;
}
auto exists = utils::file::is_file(source_path);
auto exists =
utils::file::file{
source_path,
}
.exists();
if (exists && directory) {
return api_error::item_exists;
}
@@ -205,7 +170,11 @@ auto encrypt_provider::do_fs_operation(
return api_error::item_not_found;
}
exists = utils::file::is_directory(source_path);
exists =
utils::file::directory{
source_path,
}
.exists();
if (exists && not directory) {
return api_error::item_exists;
}
@@ -271,10 +240,7 @@ auto encrypt_provider::get_directory_item_count(
[&api_path, &count](const encrypt_config & /* cfg */,
const std::string &source_path) -> api_error {
try {
for ([[maybe_unused]] const auto &dir_entry :
std::filesystem::directory_iterator(source_path)) {
count++;
}
count = utils::file::directory{source_path}.count();
} catch (const std::exception &ex) {
utils::error::raise_api_path_error(
function_name, api_path, source_path, ex,
@@ -301,15 +267,15 @@ auto encrypt_provider::get_directory_items(
[this, &list](const encrypt_config &cfg,
const std::string &source_path) -> api_error {
try {
for (const auto &dir_entry :
std::filesystem::directory_iterator(source_path)) {
for (auto &&dir_entry :
utils::file::directory{source_path}.get_items()) {
try {
std::string current_api_path{};
if (dir_entry.is_directory()) {
if (dir_entry->is_directory_item()) {
auto result = db::db_select{*db_, directory_table}
.column("api_path")
.where("source_path")
.equals(dir_entry.path().string())
.equals(dir_entry->get_path())
.go();
std::optional<db::db_select::row> row;
if (result.get_row(row) && row.has_value()) {
@@ -317,12 +283,13 @@ auto encrypt_provider::get_directory_items(
row->get_column("api_path").get_value<std::string>();
}
if (current_api_path.empty()) {
process_directory_entry(dir_entry, cfg, current_api_path);
process_directory_entry(*dir_entry.get(), cfg,
current_api_path);
result = db::db_select{*db_, directory_table}
.column("api_path")
.where("source_path")
.equals(dir_entry.path().string())
.equals(dir_entry->get_path())
.go();
row.reset();
if (not(result.get_row(row) && row.has_value())) {
@@ -337,7 +304,7 @@ auto encrypt_provider::get_directory_items(
auto result = db::db_select{*db_, file_table}
.column("data")
.where("source_path")
.equals(dir_entry.path().string())
.equals(dir_entry->get_path())
.go();
std::optional<db::db_select::row> row;
if (result.get_row(row) && row.has_value()) {
@@ -346,7 +313,7 @@ auto encrypt_provider::get_directory_items(
}
if (api_path_data.empty()) {
if (not process_directory_entry(dir_entry, cfg,
if (not process_directory_entry(*dir_entry.get(), cfg,
current_api_path)) {
continue;
}
@@ -357,14 +324,14 @@ auto encrypt_provider::get_directory_items(
}
}
auto file =
create_api_file(current_api_path, dir_entry.is_directory(),
dir_entry.path().string());
auto file = create_api_file(current_api_path,
dir_entry->is_directory_item(),
dir_entry->get_path());
directory_item dir_item{};
dir_item.api_parent = file.api_parent;
dir_item.api_path = file.api_path;
dir_item.directory = dir_entry.is_directory();
dir_item.directory = dir_entry->is_directory_item();
dir_item.resolved = true;
dir_item.size = file.file_size;
create_item_meta(dir_item.meta, dir_item.directory, file);
@@ -372,7 +339,7 @@ auto encrypt_provider::get_directory_items(
list.emplace_back(std::move(dir_item));
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex,
dir_entry.path().string(),
dir_entry->get_path(),
"failed to process directory item");
}
}
@@ -405,28 +372,40 @@ auto encrypt_provider::get_directory_items(
auto encrypt_provider::get_file(const std::string &api_path,
api_file &file) const -> api_error {
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
if (exists) {
return api_error::directory_exists;
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
try {
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
if (exists) {
return api_error::directory_exists;
}
auto result = db::db_select{*db_, source_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.go();
std::optional<db::db_select::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
}
file = create_api_file(
api_path, false,
row->get_column("source_path").get_value<std::string>());
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
"failed to get file");
}
auto result = db::db_select{*db_, source_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.go();
std::optional<db::db_select::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
}
file = create_api_file(
api_path, false, row->get_column("source_path").get_value<std::string>());
return api_error::success;
return api_error::error;
}
auto encrypt_provider::get_file_list(api_file_list &list) const -> api_error {
@@ -435,14 +414,15 @@ auto encrypt_provider::get_file_list(api_file_list &list) const -> api_error {
};
const auto cfg = config_.get_encrypt_config();
event_system::instance().raise<debug_log>(std::string{function_name},
cfg.path, "");
try {
for (const auto &dir_entry :
std::filesystem::recursive_directory_iterator(cfg.path)) {
for (auto &&dir_entry : utils::file::directory{cfg.path}.get_items()) {
std::string api_path{};
if (process_directory_entry(dir_entry, cfg, api_path)) {
list.emplace_back(create_api_file(api_path, dir_entry.is_directory(),
dir_entry.path().string()));
if (process_directory_entry(*dir_entry.get(), cfg, api_path)) {
list.emplace_back(create_api_file(
api_path, dir_entry->is_directory_item(), dir_entry->get_path()));
}
}
@@ -565,22 +545,33 @@ auto encrypt_provider::get_filesystem_item_from_source_path(
auto encrypt_provider::get_filesystem_item_and_file(
const std::string &api_path, api_file &file,
filesystem_item &fsi) const -> api_error {
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
if (exists) {
return api_error::directory_exists;
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
try {
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
if (exists) {
return api_error::directory_exists;
}
auto ret = get_filesystem_item(api_path, exists, fsi);
if (ret != api_error::success) {
return ret;
}
file = create_api_file(api_path, false, fsi.source_path);
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
"failed to get filesystem_item and file");
}
auto ret = get_filesystem_item(api_path, exists, fsi);
if (ret != api_error::success) {
return ret;
}
file = create_api_file(api_path, false, fsi.source_path);
return api_error::success;
return api_error::error;
}
auto encrypt_provider::get_pinned_files() const -> std::vector<std::string> {
@@ -589,27 +580,38 @@ auto encrypt_provider::get_pinned_files() const -> std::vector<std::string> {
auto encrypt_provider::get_item_meta(const std::string &api_path,
api_meta_map &meta) const -> api_error {
auto result = db::db_select{*db_, source_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.go();
std::optional<db::db_select::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
try {
auto result = db::db_select{*db_, source_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.go();
std::optional<db::db_select::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
}
auto source_path = row->get_column("source_path").get_value<std::string>();
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
auto file = create_api_file(api_path, exists, source_path);
create_item_meta(meta, exists, file);
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
"failed to get item meta");
}
auto source_path = row->get_column("source_path").get_value<std::string>();
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
auto file = create_api_file(api_path, exists, source_path);
create_item_meta(meta, exists, file);
return api_error::success;
return api_error::error;
}
auto encrypt_provider::get_item_meta(const std::string &api_path,
@@ -626,8 +628,9 @@ auto encrypt_provider::get_item_meta(const std::string &api_path,
}
auto encrypt_provider::get_total_drive_space() const -> std::uint64_t {
const auto cfg = config_.get_encrypt_config();
return utils::file::get_total_drive_space(cfg.path);
auto total_space =
utils::file::get_total_drive_space(config_.get_encrypt_config().path);
return total_space.value_or(0U);
}
auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
@@ -644,8 +647,10 @@ auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
}
auto encrypt_provider::get_used_drive_space() const -> std::uint64_t {
const auto cfg = config_.get_encrypt_config();
return get_total_drive_space() - utils::file::get_free_drive_space(cfg.path);
auto free_space =
utils::file::get_free_drive_space(config_.get_encrypt_config().path);
return free_space.has_value() ? get_total_drive_space() - free_space.value()
: 0U;
}
auto encrypt_provider::is_directory(const std::string &api_path,
@@ -661,8 +666,11 @@ auto encrypt_provider::is_directory(const std::string &api_path,
return api_error::success;
}
exists = utils::file::is_directory(
row->get_column("source_path").get_value<std::string>());
exists =
utils::file::directory{
row->get_column("source_path").get_value<std::string>(),
}
.exists();
return api_error::success;
}
@@ -679,8 +687,11 @@ auto encrypt_provider::is_file(const std::string &api_path,
return api_error::success;
}
exists = utils::file::is_file(
row->get_column("source_path").get_value<std::string>());
exists =
utils::file::file{
row->get_column("source_path").get_value<std::string>(),
}
.exists();
return api_error::success;
}
@@ -690,20 +701,24 @@ auto encrypt_provider::is_file_writeable(const std::string & /*api_path*/) const
}
auto encrypt_provider::is_online() const -> bool {
return std::filesystem::exists(config_.get_encrypt_config().path);
return utils::file::directory{
config_.get_encrypt_config().path,
}
.exists();
}
auto encrypt_provider::is_rename_supported() const -> bool { return false; }
auto encrypt_provider::process_directory_entry(
const std::filesystem::directory_entry &dir_entry,
const encrypt_config &cfg, std::string &api_path) const -> bool {
const auto add_directory = [this, &cfg](auto dir_path) -> std::string {
const utils::file::i_fs_item &dir_entry, const encrypt_config &cfg,
std::string &api_path) const -> bool {
const auto add_directory = [this,
&cfg](std::string_view dir_path) -> std::string {
auto encrypted_parts = utils::string::split(
utils::path::create_api_path(dir_path.string()), '/', false);
utils::path::create_api_path(dir_path), '/', false);
for (std::size_t part_idx = 1U; part_idx < encrypted_parts.size();
part_idx++) {
++part_idx) {
data_buffer encrypted_data;
utils::encryption::encrypt_data(
cfg.encryption_token,
@@ -718,14 +733,9 @@ auto encrypt_provider::process_directory_entry(
std::size_t current_idx{1U};
std::string current_encrypted_path{};
std::string current_source_path{cfg.path};
for (const auto &part : dir_path) {
if (part.string() == "/") {
continue;
}
current_source_path =
utils::path::combine(current_source_path, {part.string()});
auto current_source_path{cfg.path};
for (auto &&part : utils::path::get_parts(dir_path)) {
current_source_path = utils::path::combine(current_source_path, {part});
std::string current_api_path{};
auto result = db::db_select{*db_, directory_table}
@@ -767,19 +777,21 @@ auto encrypt_provider::process_directory_entry(
return current_encrypted_path;
};
if (dir_entry.is_directory()) {
api_path = add_directory(dir_entry.path().lexically_relative(cfg.path));
if (dir_entry.is_directory_item()) {
api_path = add_directory(
utils::path::get_relative_path(dir_entry.get_path(), cfg.path));
return false;
}
if (dir_entry.is_regular_file() && not dir_entry.is_symlink()) {
const auto relative_path = dir_entry.path().lexically_relative(cfg.path);
if (dir_entry.is_file_item() && not dir_entry.is_symlink()) {
auto relative_path =
utils::path::get_relative_path(dir_entry.get_path(), cfg.path);
std::string api_path_data{};
auto result = db::db_select{*db_, file_table}
.column("data")
.where("source_path")
.equals(dir_entry.path().string())
.equals(dir_entry.get_path())
.go();
std::optional<db::db_select::row> row;
if (result.get_row(row) && row.has_value()) {
@@ -790,7 +802,7 @@ auto encrypt_provider::process_directory_entry(
result = db::db_select{*db_, directory_table}
.column("api_path")
.where("source_path")
.equals(dir_entry.path().parent_path().string())
.equals(utils::path::get_parent_path(dir_entry.get_path()))
.go();
row.reset();
if (result.get_row(row) && row.has_value()) {
@@ -798,15 +810,15 @@ auto encrypt_provider::process_directory_entry(
}
if (api_parent.empty()) {
api_parent = add_directory(relative_path.parent_path());
api_parent = add_directory(utils::path::get_parent_path(relative_path));
}
if (api_path_data.empty()) {
stop_type stop_requested = false;
utils::encryption::encrypting_reader reader(
relative_path.filename().string(), dir_entry.path().string(),
utils::path::strip_to_file_name(relative_path), dir_entry.get_path(),
stop_requested, cfg.encryption_token,
relative_path.parent_path().string());
utils::path::get_parent_path(relative_path));
api_path = utils::path::create_api_path(api_parent + "/" +
reader.get_encrypted_file_name());
@@ -814,17 +826,22 @@ auto encrypt_provider::process_directory_entry(
json data = {
{"api_path", api_path},
{"iv_list", iv_list},
{"original_file_size", dir_entry.file_size()},
{
"original_file_size",
(dynamic_cast<const utils::file::i_file *>(&dir_entry)
->size()
.value_or(0U)),
},
};
auto ins_res = db::db_insert{*db_, file_table}
.column_value("source_path", dir_entry.path().string())
.column_value("source_path", dir_entry.get_path())
.column_value("data", data.dump())
.go();
// TODO handle error
ins_res = db::db_insert{*db_, source_table}
.column_value("api_path", api_path)
.column_value("source_path", dir_entry.path().string())
.column_value("source_path", dir_entry.get_path())
.go();
// TODO handle error
event_system::instance().raise<filesystem_item_added>(api_path,
@@ -874,11 +891,13 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path,
auto file_data = row->get_column("data").get_value_as_json();
std::uint64_t file_size{};
if (not utils::file::get_file_size(source_path, file_size)) {
auto opt_size = utils::file::file{source_path}.size();
if (not opt_size.has_value()) {
return api_error::os_error;
}
auto file_size{opt_size.value()};
std::vector<
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list{};
@@ -888,13 +907,12 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path,
unique_recur_mutex_lock reader_lookup_lock(reader_lookup_mtx_);
if (file_data.at("original_file_size").get<std::uint64_t>() != file_size) {
const auto relative_path =
std::filesystem::path(source_path).lexically_relative(cfg.path);
auto relative_path = utils::path::get_relative_path(source_path, cfg.path);
auto info = std::make_shared<reader_info>();
info->reader = std::make_unique<utils::encryption::encrypting_reader>(
relative_path.filename().string(), source_path, stop_requested,
cfg.encryption_token, relative_path.parent_path().string());
relative_path, source_path, stop_requested, cfg.encryption_token,
utils::path::get_parent_path(relative_path));
reader_lookup_[source_path] = info;
iv_list = info->reader->get_iv_list();
@@ -965,9 +983,9 @@ void encrypt_provider::remove_deleted_files() {
}
}
for (const auto &row : row_list) {
for (auto &&row : row_list) {
auto source_path = row.get_column("source_path").get_value<std::string>();
if (not std::filesystem::exists(source_path)) {
if (not utils::path::exists(source_path)) {
auto api_path = row.get_column("api_path").get_value<std::string>();
result = db::db_select{*db_, file_table}
.column("source_path")
@@ -979,7 +997,7 @@ void encrypt_provider::remove_deleted_files() {
}
}
for (const auto &item : removed_list) {
for (auto &&item : removed_list) {
if (not item.directory) {
auto del_res = db::db_select{*db_, source_table}
.delete_query()
@@ -998,7 +1016,7 @@ void encrypt_provider::remove_deleted_files() {
}
}
for (const auto &item : removed_list) {
for (auto &&item : removed_list) {
if (item.directory) {
auto del_res = db::db_select{*db_, source_table}
.delete_query()
@@ -1043,7 +1061,7 @@ auto encrypt_provider::start(api_item_added_callback /*api_item_added*/,
}
db_.reset(db3);
for (const auto &create : sql_create_tables) {
for (auto &&create : sql_create_tables) {
std::string err;
if (not db::execute_sql(*db_, create.second, err)) {
utils::error::raise_error(function_name, "failed to create table|" +

View File

@@ -288,7 +288,7 @@ auto meta_db::set_item_meta(const std::string &api_path,
// TODO handle error
}
for (const auto &item : meta) {
for (auto &&item : meta) {
existing_meta[item.first] = item.second;
}

View File

@@ -27,12 +27,11 @@
#include "file_manager/i_file_manager.hpp"
#include "types/repertory.hpp"
#include "types/s3.hpp"
#include "types/startup_exception.hpp"
#include "utils/collection.hpp"
#include "utils/encrypt.hpp"
#include "utils/encrypting_reader.hpp"
#include "utils/encryption.hpp"
#include "utils/error_utils.hpp"
#include "utils/file_utils.hpp"
#include "utils/file.hpp"
#include "utils/path.hpp"
#include "utils/polling.hpp"
#include "utils/string.hpp"
@@ -60,6 +59,24 @@ auto s3_provider::add_if_not_found(
return api_error::success;
}
auto s3_provider::convert_api_date(std::string_view date) -> std::uint64_t {
// 2009-10-12T17:50:30.000Z
auto date_parts = utils::string::split(date, '.', true);
auto date_time = date_parts.at(0U);
auto nanos = utils::string::to_uint64(
utils::string::split(date_parts.at(1U), 'Z', true).at(0U));
struct tm tm1 {};
#if defined(_WIN32)
utils::time::strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
#else
strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
#endif
return nanos + (static_cast<std::uint64_t>(mktime(&tm1)) *
utils::time::NANOS_PER_SECOND);
}
auto s3_provider::create_directory_impl(const std::string &api_path,
api_meta_map &meta) -> api_error {
static constexpr const std::string_view function_name{
@@ -162,13 +179,13 @@ auto s3_provider::create_path_directories(
std::string cur_key{'/'};
std::string cur_path{'/'};
for (std::size_t i = 0U; i < path_parts.size(); i++) {
for (std::size_t idx = 0U; idx < path_parts.size(); ++idx) {
if (is_encrypted) {
cur_key = utils::path::create_api_path(
utils::path::combine(cur_key, {key_parts.at(i)}));
utils::path::combine(cur_key, {key_parts.at(idx)}));
}
cur_path = utils::path::create_api_path(
utils::path::combine(cur_path, {path_parts.at(i)}));
utils::path::combine(cur_path, {path_parts.at(idx)}));
api_meta_map meta{};
auto res = get_item_meta(cur_path, meta);
@@ -189,11 +206,10 @@ auto s3_provider::create_path_directories(
auto s3_provider::decrypt_object_name(std::string &object_name) const
-> api_error {
auto parts = utils::string::split(object_name, '/', false);
for (auto &part : parts) {
auto err = utils::encryption::decrypt_file_name(
get_config().get_s3_config().encryption_token, part);
if (err != api_error::success) {
return err;
for (auto &&part : parts) {
if (not utils::encryption::decrypt_file_name(
get_config().get_s3_config().encryption_token, part)) {
return api_error::decryption_error;
}
}
@@ -313,10 +329,9 @@ auto s3_provider::get_directory_items_impl(
std::string child_object_name;
if (is_encrypted) {
child_object_name = child_api_path;
ret = utils::encryption::decrypt_file_path(cfg.encryption_token,
child_api_path);
if (ret != api_error::success) {
return ret;
if (not utils::encryption::decrypt_file_path(cfg.encryption_token,
child_api_path)) {
return api_error::decryption_error;
}
}
@@ -353,14 +368,14 @@ auto s3_provider::get_directory_items_impl(
};
auto node_list = doc.select_nodes("/ListBucketResult/CommonPrefixes/Prefix");
for (const auto &node : node_list) {
for (auto &&node : node_list) {
add_directory_item(
true, node.node().text().as_string(),
[](const directory_item &) -> std::uint64_t { return 0U; });
}
node_list = doc.select_nodes("/ListBucketResult/Contents");
for (const auto &node : node_list) {
for (auto &&node : node_list) {
auto child_object_name = utils::path::create_api_path(
node.node().select_node("Key").node().text().as_string());
if (child_object_name != utils::path::create_api_path(prefix)) {
@@ -394,7 +409,7 @@ auto s3_provider::get_file(const std::string &api_path,
return res;
}
file.accessed_date = utils::time::get_file_time_now();
file.accessed_date = utils::time::get_time_now();
file.api_path = api_path;
file.api_parent = utils::path::get_parent_api_path(file.api_path);
file.changed_date = utils::aws::format_time(result.last_modified);
@@ -431,7 +446,7 @@ auto s3_provider::get_file_list(api_file_list &list) const -> api_error {
}
auto node_list = doc.select_nodes("/ListBucketResult/Contents");
for (const auto &node : node_list) {
for (auto &&node : node_list) {
auto api_path =
std::string{node.node().select_node("Key").node().text().as_string()};
if (not utils::string::ends_with(api_path, "/")) {
@@ -449,8 +464,8 @@ auto s3_provider::get_file_list(api_file_list &list) const -> api_error {
api_file file{};
file.api_path = utils::path::create_api_path(api_path);
file.api_parent = utils::path::get_parent_api_path(file.api_path);
file.accessed_date = utils::time::get_file_time_now();
file.changed_date = utils::convert_api_date(
file.accessed_date = utils::time::get_time_now();
file.changed_date = convert_api_date(
node.node().select_node("LastModified").node().text().as_string());
file.creation_date = file.changed_date;
file.file_size =
@@ -674,10 +689,10 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
&stop_requested](std::size_t read_size, std::size_t read_offset,
data_buffer &read_buffer) -> api_error {
auto res = api_error::error;
for (std::uint32_t i = 0U;
for (std::uint32_t idx = 0U;
not stop_requested && res != api_error::success &&
i < get_config().get_retry_read_count() + 1U;
i++) {
idx < get_config().get_retry_read_count() + 1U;
++idx) {
curl::requests::http_get get{};
get.aws_service = "aws:amz:" + cfg.region + ":s3";
get.headers["response-content-type"] = "binary/octet-stream";
@@ -698,13 +713,13 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
function_name, api_path, api_error::comm_error,
"read file bytes failed|offset|" + std::to_string(read_offset) +
"|size|" + std::to_string(read_size) + "|retry|" +
std::to_string(i + 1U));
std::to_string(idx + 1U));
} else {
utils::error::raise_api_path_error(
function_name, api_path, response_code,
"read file bytes failed|offset|" + std::to_string(read_offset) +
"|size|" + std::to_string(read_size) + "|retry|" +
std::to_string(i + 1U));
std::to_string(idx + 1U));
}
std::this_thread::sleep_for(1s);
};
@@ -735,15 +750,18 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
const auto total_size = utils::string::to_uint64(temp);
return utils::encryption::read_encrypted_range(
{offset, offset + size - 1U},
utils::encryption::generate_key<utils::encryption::hash_256_t>(
cfg.encryption_token),
[&](data_buffer &ct_buffer, std::uint64_t start_offset,
std::uint64_t end_offset) -> api_error {
return read_bytes((end_offset - start_offset + 1U), start_offset,
ct_buffer);
},
total_size, data);
{offset, offset + size - 1U},
utils::encryption::generate_key<utils::encryption::hash_256_t>(
cfg.encryption_token),
[&](data_buffer &ct_buffer, std::uint64_t start_offset,
std::uint64_t end_offset) -> bool {
return read_bytes((end_offset - start_offset + 1U),
start_offset,
ct_buffer) == api_error::success;
},
total_size, data)
? api_error::success
: api_error::decryption_error;
}
return read_bytes(size, offset, data);
@@ -865,9 +883,12 @@ auto s3_provider::upload_file_impl(const std::string &api_path,
const std::string &source_path,
stop_type &stop_requested) -> api_error {
std::uint64_t file_size{};
if (utils::file::is_file(source_path) &&
not utils::file::get_file_size(source_path, file_size)) {
return api_error::comm_error;
if (utils::file::file{source_path}.exists()) {
auto opt_size = utils::file::file{source_path}.size();
if (not opt_size.has_value()) {
return api_error::comm_error;
}
file_size = opt_size.value();
}
const auto cfg = get_config().get_s3_config();

View File

@@ -80,7 +80,7 @@ auto sia_provider::get_directory_item_count(const std::string &api_path) const
std::uint64_t item_count{};
if (object_list.contains("entries")) {
for (const auto &entry : object_list.at("entries")) {
for (auto &&entry : object_list.at("entries")) {
try {
auto name = entry.at("name").get<std::string>();
auto entry_api_path = utils::path::create_api_path(name);
@@ -118,7 +118,7 @@ auto sia_provider::get_directory_items_impl(
}
if (object_list.contains("entries")) {
for (const auto &entry : object_list.at("entries")) {
for (auto &&entry : object_list.at("entries")) {
try {
auto name = entry.at("name").get<std::string>();
auto entry_api_path = utils::path::create_api_path(name);
@@ -208,7 +208,7 @@ auto sia_provider::get_file_list(api_file_list &list) const -> api_error {
}
if (object_list.contains("entries")) {
for (const auto &entry : object_list.at("entries")) {
for (auto &&entry : object_list.at("entries")) {
auto name = entry.at("name").get<std::string>();
auto entry_api_path = utils::path::create_api_path(name);
@@ -534,9 +534,10 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
long /*response_code*/) { buffer = data; };
auto res = api_error::comm_error;
for (std::uint32_t i = 0U; not stop_requested && res != api_error::success &&
i < get_config().get_retry_read_count() + 1U;
i++) {
for (std::uint32_t idx = 0U;
not stop_requested && res != api_error::success &&
idx < get_config().get_retry_read_count() + 1U;
++idx) {
long response_code{};
const auto notify_retry = [&]() {
if (response_code == 0) {
@@ -544,13 +545,13 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
function_name, api_path, api_error::comm_error,
"read file bytes failed|offset|" + std::to_string(offset) +
"|size|" + std::to_string(size) + "|retry|" +
std::to_string(i + 1U));
std::to_string(idx + 1U));
} else {
utils::error::raise_api_path_error(
function_name, api_path, response_code,
"read file bytes failed|offset|" + std::to_string(offset) +
"|size|" + std::to_string(size) + "|retry|" +
std::to_string(i + 1U));
std::to_string(idx + 1U));
}
std::this_thread::sleep_for(1s);
};

View File

@@ -22,12 +22,11 @@
#include "rpc/server/full_server.hpp"
#include "app_config.hpp"
#include "drives/directory_iterator.hpp"
#include "file_manager/i_file_manager.hpp"
#include "providers/i_provider.hpp"
#include "types/repertory.hpp"
#include "types/rpc.hpp"
#include "utils/file_utils.hpp"
#include "utils/file.hpp"
#include "utils/path.hpp"
namespace repertory {
@@ -51,11 +50,11 @@ void full_server::handle_get_directory_items(const httplib::Request &req,
void full_server::handle_get_drive_information(const httplib::Request & /*req*/,
httplib::Response &res) {
auto dir_size =
utils::file::directory(get_config().get_cache_directory()).size();
res.set_content(
json({
{"cache_space_used",
utils::file::calculate_used_space(
get_config().get_cache_directory(), false)},
{"cache_space_used", dir_size},
{"drive_space_total", provider_.get_total_drive_space()},
{"drive_space_used", provider_.get_used_drive_space()},
{"item_count", provider_.get_total_item_count()},

View File

@@ -1,21 +0,0 @@
#include "utils/action_queue.hpp"
#include "types/repertory.hpp"
namespace repertory::utils::action_queue {
action_queue::action_queue(const std::string &id,
std::uint8_t max_concurrent_actions)
: single_thread_service_base("action_queue_" + id),
id_(id),
max_concurrent_actions_(max_concurrent_actions) {}
void action_queue::service_function() {
//
}
void action_queue::push(std::function<void()> action) {
unique_mutex_lock queue_lock(queue_mtx_);
queue_.emplace_back(action);
queue_notify_.notify_all();
}
} // namespace repertory::utils::action_queue

View File

@@ -23,7 +23,8 @@
#include "app_config.hpp"
#include "utils/collection.hpp"
#include "utils/file_utils.hpp"
#include "utils/common.hpp"
#include "utils/file.hpp"
#include "utils/path.hpp"
#include "utils/string.hpp"
#include "utils/utils.hpp"
@@ -38,7 +39,7 @@ void get_api_authentication_data(std::string &user, std::string &password,
{"config.json"});
json data;
const auto success = utils::retryable_action([&]() -> bool {
const auto success = utils::retry_action([&]() -> bool {
return utils::file::read_json_file(cfg_file_path, data);
});

View File

@@ -1,117 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/encrypt.hpp"
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "types/repertory.hpp"
#include "utils/collection.hpp"
#include "utils/encrypting_reader.hpp"
#include "utils/encryption.hpp"
#include "utils/utils.hpp"
namespace repertory::utils::encryption {
auto decrypt_file_path(std::string_view encryption_token,
std::string &file_path) -> api_error {
std::string decrypted_file_path{};
for (const auto &part : std::filesystem::path(file_path)) {
auto file_name = part.string();
if (file_name == "/") {
continue;
}
auto res = decrypt_file_name(encryption_token, file_name);
if (res != api_error::success) {
return res;
}
decrypted_file_path += '/' + file_name;
}
file_path = decrypted_file_path;
return api_error::success;
}
auto decrypt_file_name(std::string_view encryption_token,
std::string &file_name) -> api_error {
data_buffer buffer;
if (not utils::collection::from_hex_string(file_name, buffer)) {
return api_error::error;
}
file_name.clear();
if (not utils::encryption::decrypt_data(encryption_token, buffer,
file_name)) {
return api_error::decryption_error;
}
return api_error::success;
}
auto read_encrypted_range(const http_range &range,
const utils::encryption::hash_256_t &key,
reader_func reader, std::uint64_t total_size,
data_buffer &data) -> api_error {
const auto encrypted_chunk_size =
utils::encryption::encrypting_reader::get_encrypted_chunk_size();
const auto data_chunk_size =
utils::encryption::encrypting_reader::get_data_chunk_size();
const auto start_chunk =
static_cast<std::size_t>(range.begin / data_chunk_size);
const auto end_chunk = static_cast<std::size_t>(range.end / data_chunk_size);
auto remain = range.end - range.begin + 1U;
auto source_offset = static_cast<std::size_t>(range.begin % data_chunk_size);
for (std::size_t chunk = start_chunk; chunk <= end_chunk; chunk++) {
data_buffer cypher;
const auto start_offset = chunk * encrypted_chunk_size;
const auto end_offset = std::min(
start_offset + (total_size - (chunk * data_chunk_size)) +
encryption_header_size - 1U,
static_cast<std::uint64_t>(start_offset + encrypted_chunk_size - 1U));
const auto result = reader(cypher, start_offset, end_offset);
if (result != api_error::success) {
return result;
}
data_buffer source_buffer;
if (not utils::encryption::decrypt_data(key, cypher, source_buffer)) {
return api_error::decryption_error;
}
cypher.clear();
const auto data_size = static_cast<std::size_t>(std::min(
remain, static_cast<std::uint64_t>(data_chunk_size - source_offset)));
std::copy(std::next(source_buffer.begin(),
static_cast<std::int64_t>(source_offset)),
std::next(source_buffer.begin(),
static_cast<std::int64_t>(source_offset + data_size)),
std::back_inserter(data));
remain -= data_size;
source_offset = 0U;
}
return api_error::success;
}
} // namespace repertory::utils::encryption

View File

@@ -1,405 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/encrypting_reader.hpp"
#include "platform/platform.hpp"
#include "types/repertory.hpp"
#include "utils/collection.hpp"
#include "utils/common.hpp"
#include "utils/error_utils.hpp"
#include "utils/file.hpp"
namespace repertory::utils::encryption {
class encrypting_streambuf final : public encrypting_reader::streambuf {
public:
encrypting_streambuf(const encrypting_streambuf &) = default;
encrypting_streambuf(encrypting_streambuf &&) = delete;
auto
operator=(const encrypting_streambuf &) -> encrypting_streambuf & = delete;
auto operator=(encrypting_streambuf &&) -> encrypting_streambuf & = delete;
explicit encrypting_streambuf(const encrypting_reader &reader)
: reader_(reader) {
setg(reinterpret_cast<char *>(0), reinterpret_cast<char *>(0),
reinterpret_cast<char *>(reader_.get_total_size()));
}
~encrypting_streambuf() override = default;
private:
encrypting_reader reader_;
protected:
auto seekoff(off_type off, std::ios_base::seekdir dir,
std::ios_base::openmode which = std::ios_base::out |
std::ios_base::in)
-> pos_type override {
if ((which & std::ios_base::in) != std::ios_base::in) {
throw std::runtime_error("output is not supported");
}
const auto set_position = [this](char *next) -> pos_type {
if ((next <= egptr()) && (next >= eback())) {
setg(eback(), next, reinterpret_cast<char *>(reader_.get_total_size()));
return static_cast<std::streamoff>(
reinterpret_cast<std::uintptr_t>(gptr()));
}
return {traits_type::eof()};
};
switch (dir) {
case std::ios_base::beg:
return set_position(eback() + off);
case std::ios_base::cur:
return set_position(gptr() + off);
case std::ios_base::end:
return set_position(egptr() + off);
}
return encrypting_reader::streambuf::seekoff(off, dir, which);
}
auto seekpos(pos_type pos, std::ios_base::openmode which =
std::ios_base::out |
std::ios_base::in) -> pos_type override {
return seekoff(pos, std::ios_base::beg, which);
}
auto uflow() -> int_type override {
auto ret = underflow();
if (ret == traits_type::eof()) {
return ret;
}
gbump(1);
return ret;
}
auto underflow() -> int_type override {
if (gptr() == egptr()) {
return traits_type::eof();
}
reader_.set_read_position(reinterpret_cast<std::uintptr_t>(gptr()));
char c{};
const auto res = encrypting_reader::reader_function(&c, 1U, 1U, &reader_);
if (res != 1) {
return traits_type::eof();
}
return c;
}
auto xsgetn(char *ptr, std::streamsize count) -> std::streamsize override {
if (gptr() == egptr()) {
return traits_type::eof();
}
reader_.set_read_position(reinterpret_cast<std::uintptr_t>(gptr()));
const auto res = encrypting_reader::reader_function(
ptr, 1U, static_cast<std::size_t>(count), &reader_);
if ((res == reader_.get_error_return()) ||
(reader_.get_stop_requested() && (res == CURL_READFUNC_ABORT))) {
return traits_type::eof();
}
setg(eback(), gptr() + res,
reinterpret_cast<char *>(reader_.get_total_size()));
return static_cast<std::streamsize>(res);
}
};
class encrypting_reader_iostream final : public encrypting_reader::iostream {
public:
encrypting_reader_iostream(const encrypting_reader_iostream &) = delete;
encrypting_reader_iostream(encrypting_reader_iostream &&) = delete;
auto operator=(const encrypting_reader_iostream &)
-> encrypting_reader_iostream & = delete;
auto operator=(encrypting_reader_iostream &&)
-> encrypting_reader_iostream & = delete;
explicit encrypting_reader_iostream(
std::unique_ptr<encrypting_streambuf> buffer)
: encrypting_reader::iostream(buffer.get()), buffer_(std::move(buffer)) {}
~encrypting_reader_iostream() override = default;
private:
std::unique_ptr<encrypting_streambuf> buffer_;
};
const std::size_t encrypting_reader::header_size_ = ([]() {
return crypto_aead_xchacha20poly1305_IETF_NPUBBYTES +
crypto_aead_xchacha20poly1305_IETF_ABYTES;
})();
const std::size_t encrypting_reader::data_chunk_size_ = (8UL * 1024UL * 1024UL);
const std::size_t encrypting_reader::encrypted_chunk_size_ =
data_chunk_size_ + header_size_;
encrypting_reader::encrypting_reader(
std::string_view file_name, std::string_view source_path,
stop_type &stop_requested, std::string_view token,
std::optional<std::string_view> relative_parent_path,
std::size_t error_return)
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
token)),
stop_requested_(stop_requested),
error_return_(error_return) {
const auto res = native_file::create_or_open(source_path, true, source_file_);
if (res != api_error::success) {
throw std::runtime_error("file open failed|src|" +
std::string{source_path} + '|' +
api_error_to_string(res));
}
data_buffer result;
utils::encryption::encrypt_data(
key_, reinterpret_cast<const unsigned char *>(file_name.data()),
file_name.size(), result);
encrypted_file_name_ = utils::collection::to_hex_string(result);
if (relative_parent_path.has_value()) {
for (auto &&part : std::filesystem::path(relative_parent_path.value())) {
utils::encryption::encrypt_data(
key_, reinterpret_cast<const unsigned char *>(part.string().c_str()),
strnlen(part.string().c_str(), part.string().size()), result);
encrypted_file_path_ += '/' + utils::collection::to_hex_string(result);
}
encrypted_file_path_ += '/' + encrypted_file_name_;
}
std::uint64_t file_size{};
if (not utils::file::get_file_size(source_path, file_size)) {
throw std::runtime_error("get file size failed|src|" +
std::string{source_path} + '|' +
std::to_string(utils::get_last_error_code()));
}
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
total_size_ = file_size + (total_chunks * encryption_header_size);
last_data_chunk_ = total_chunks - 1U;
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
: (file_size % data_chunk_size_) == 0U
? data_chunk_size_
: file_size % data_chunk_size_;
iv_list_.resize(total_chunks);
for (auto &iv : iv_list_) {
randombytes_buf(iv.data(), iv.size());
}
}
encrypting_reader::encrypting_reader(std::string_view encrypted_file_path,
std::string_view source_path,
stop_type &stop_requested,
std::string_view token,
std::size_t error_return)
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
token)),
stop_requested_(stop_requested),
error_return_(error_return) {
const auto res = native_file::create_or_open(source_path, true, source_file_);
if (res != api_error::success) {
throw std::runtime_error("file open failed|src|" +
std::string{source_path} + '|' +
api_error_to_string(res));
}
encrypted_file_path_ = encrypted_file_path;
encrypted_file_name_ =
std::filesystem::path(encrypted_file_path_).filename().string();
std::uint64_t file_size{};
if (not utils::file::get_file_size(source_path, file_size)) {
throw std::runtime_error("get file size failed|src|" +
std::string{source_path} + '|' +
std::to_string(utils::get_last_error_code()));
}
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
total_size_ = file_size + (total_chunks * encryption_header_size);
last_data_chunk_ = total_chunks - 1U;
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
: (file_size % data_chunk_size_) == 0U
? data_chunk_size_
: file_size % data_chunk_size_;
iv_list_.resize(total_chunks);
for (auto &iv : iv_list_) {
randombytes_buf(iv.data(), iv.size());
}
}
encrypting_reader::encrypting_reader(
std::string_view encrypted_file_path, std::string_view source_path,
stop_type &stop_requested, std::string_view token,
std::vector<
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list,
std::size_t error_return)
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
token)),
stop_requested_(stop_requested),
error_return_(error_return) {
const auto res = native_file::create_or_open(source_path, true, source_file_);
if (res != api_error::success) {
throw std::runtime_error("file open failed|src|" +
std::string{source_path} + '|' +
api_error_to_string(res));
}
encrypted_file_path_ = encrypted_file_path;
encrypted_file_name_ =
std::filesystem::path(encrypted_file_path_).filename().string();
std::uint64_t file_size{};
if (not utils::file::get_file_size(source_path, file_size)) {
throw std::runtime_error("get file size failed|src|" +
std::string{source_path} + '|' +
std::to_string(utils::get_last_error_code()));
}
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
total_size_ = file_size + (total_chunks * encryption_header_size);
last_data_chunk_ = total_chunks - 1U;
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
: (file_size % data_chunk_size_) == 0U
? data_chunk_size_
: file_size % data_chunk_size_;
iv_list_ = std::move(iv_list);
}
encrypting_reader::encrypting_reader(const encrypting_reader &reader)
: key_(reader.key_),
stop_requested_(reader.stop_requested_),
error_return_(reader.error_return_),
chunk_buffers_(reader.chunk_buffers_),
encrypted_file_name_(reader.encrypted_file_name_),
encrypted_file_path_(reader.encrypted_file_path_),
iv_list_(reader.iv_list_),
last_data_chunk_(reader.last_data_chunk_),
last_data_chunk_size_(reader.last_data_chunk_size_),
read_offset_(reader.read_offset_),
source_file_(native_file::clone(reader.source_file_)),
total_size_(reader.total_size_) {}
encrypting_reader::~encrypting_reader() {
if (source_file_) {
source_file_->close();
}
}
auto encrypting_reader::calculate_decrypted_size(std::uint64_t total_size)
-> std::uint64_t {
return total_size - (utils::divide_with_ceiling(
total_size, static_cast<std::uint64_t>(
get_encrypted_chunk_size())) *
encryption_header_size);
}
auto encrypting_reader::calculate_encrypted_size(std::string_view source_path)
-> std::uint64_t {
std::uint64_t file_size{};
if (not utils::file::get_file_size(source_path, file_size)) {
throw std::runtime_error("get file size failed|src|" +
std::string{source_path} + '|' +
std::to_string(utils::get_last_error_code()));
}
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
return file_size + (total_chunks * encryption_header_size);
}
auto encrypting_reader::create_iostream() const
-> std::shared_ptr<encrypting_reader::iostream> {
return std::make_shared<encrypting_reader_iostream>(
std::make_unique<encrypting_streambuf>(*this));
}
auto encrypting_reader::reader_function(char *buffer, size_t size,
size_t nitems) -> size_t {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
const auto read_size = static_cast<std::size_t>(std::min(
static_cast<std::uint64_t>(size * nitems), total_size_ - read_offset_));
auto chunk = read_offset_ / encrypted_chunk_size_;
auto chunk_offset = read_offset_ % encrypted_chunk_size_;
std::size_t total_read{};
auto ret = false;
if (read_offset_ < total_size_) {
try {
ret = true;
auto remain = read_size;
while (not stop_requested_ && ret && (remain != 0U)) {
if (chunk_buffers_.find(chunk) == chunk_buffers_.end()) {
auto &chunk_buffer = chunk_buffers_[chunk];
data_buffer file_data(chunk == last_data_chunk_
? last_data_chunk_size_
: data_chunk_size_);
chunk_buffer.resize(file_data.size() + encryption_header_size);
std::size_t bytes_read{};
if ((ret = source_file_->read_bytes(&file_data[0u], file_data.size(),
chunk * data_chunk_size_,
bytes_read))) {
utils::encryption::encrypt_data(iv_list_.at(chunk), key_, file_data,
chunk_buffer);
}
} else if (chunk) {
chunk_buffers_.erase(chunk - 1u);
}
auto &chunk_buffer = chunk_buffers_[chunk];
const auto to_read = std::min(
static_cast<std::size_t>(chunk_buffer.size() - chunk_offset),
remain);
std::memcpy(buffer + total_read, &chunk_buffer[chunk_offset], to_read);
total_read += to_read;
remain -= to_read;
chunk_offset = 0u;
chunk++;
read_offset_ += to_read;
}
} catch (const std::exception &e) {
utils::error::raise_error(function_name, e, "exception occurred");
ret = false;
}
}
return stop_requested_ ? CURL_READFUNC_ABORT
: ret ? total_read
: error_return_;
}
} // namespace repertory::utils::encryption

View File

@@ -21,392 +21,77 @@
*/
#include "utils/file_utils.hpp"
#include "types/repertory.hpp"
#include "utils/collection.hpp"
#include "utils/error_utils.hpp"
#include "utils/file.hpp"
#include "utils/path.hpp"
#include "utils/string.hpp"
#include "utils/time.hpp"
#include "utils/utils.hpp"
namespace repertory::utils::file {
auto calculate_used_space(std::string path, bool recursive) -> std::uint64_t {
path = utils::path::absolute(path);
std::uint64_t ret{};
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
do {
const auto file_name = std::string(fd.cFileName);
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (recursive && (file_name != ".") && (file_name != "..")) {
ret += calculate_used_space(utils::path::combine(path, {file_name}),
recursive);
}
} else {
std::uint64_t file_size{};
if (get_file_size(utils::path::combine(path, {file_name}), file_size)) {
ret += file_size;
}
}
} while (::FindNextFile(find, &fd) != 0);
::FindClose(find);
}
#else
auto *root = opendir(path.c_str());
if (root) {
struct dirent *de{};
while ((de = readdir(root)) != nullptr) {
if (de->d_type == DT_DIR) {
if (recursive && (strcmp(de->d_name, ".") != 0) &&
(strcmp(de->d_name, "..") != 0)) {
ret += calculate_used_space(utils::path::combine(path, {de->d_name}),
recursive);
}
} else {
std::uint64_t file_size{};
if (get_file_size(utils::path::combine(path, {de->d_name}),
file_size)) {
ret += file_size;
}
}
}
closedir(root);
}
#endif
return ret;
}
void change_to_process_directory() {
#if defined(_WIN32)
std::string file_name;
file_name.resize(MAX_PATH);
::GetModuleFileNameA(nullptr, &file_name[0U],
static_cast<DWORD>(file_name.size()));
std::string path = file_name.c_str();
::PathRemoveFileSpecA(&path[0U]);
::SetCurrentDirectoryA(&path[0U]);
#else
std::string path;
path.resize(PATH_MAX + 1);
#if defined(__APPLE__)
proc_pidpath(getpid(), &path[0U], path.size());
#else
readlink("/proc/self/exe", &path[0U], path.size());
#endif
path = utils::path::get_parent_directory(path);
chdir(path.c_str());
#endif
}
auto copy_file(std::string from_path, std::string to_path) -> bool {
from_path = utils::path::absolute(from_path);
to_path = utils::path::absolute(to_path);
if (is_file(from_path) && not is_directory(to_path)) {
return std::filesystem::copy_file(from_path, to_path);
}
return false;
}
auto copy_directory_recursively(std::string from_path,
std::string to_path) -> bool {
from_path = utils::path::absolute(from_path);
to_path = utils::path::absolute(to_path);
auto ret = create_full_directory_path(to_path);
if (ret) {
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(from_path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
ret = true;
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if ((std::string(fd.cFileName) != ".") &&
(std::string(fd.cFileName) != "..")) {
ret = copy_directory_recursively(
utils::path::combine(from_path, {fd.cFileName}),
utils::path::combine(to_path, {fd.cFileName}));
}
} else {
ret = copy_file(utils::path::combine(from_path, {fd.cFileName}),
utils::path::combine(to_path, {fd.cFileName}));
}
} while (ret && (::FindNextFile(find, &fd) != 0));
::FindClose(find);
}
#else
auto *root = opendir(from_path.c_str());
if (root) {
struct dirent *de{};
while (ret && (de = readdir(root))) {
if (de->d_type == DT_DIR) {
if ((strcmp(de->d_name, ".") != 0) &&
(strcmp(de->d_name, "..") != 0)) {
ret = copy_directory_recursively(
utils::path::combine(from_path, {de->d_name}),
utils::path::combine(to_path, {de->d_name}));
}
} else {
ret = copy_file(utils::path::combine(from_path, {de->d_name}),
utils::path::combine(to_path, {de->d_name}));
}
}
closedir(root);
}
#endif
}
return ret;
}
auto create_full_directory_path(std::string path) -> bool {
#if defined(_WIN32)
const auto unicode_path =
utils::string::from_utf8(utils::path::absolute(path));
return is_directory(path) ||
(::SHCreateDirectory(nullptr, unicode_path.c_str()) == ERROR_SUCCESS);
#else
auto ret = true;
const auto paths = utils::string::split(
utils::path::absolute(path), utils::path::directory_seperator[0U], false);
std::string current_path;
for (std::size_t i = 0U; ret && (i < paths.size()); i++) {
if (paths[i].empty()) { // Skip root
current_path = utils::path::directory_seperator;
} else {
current_path = utils::path::combine(current_path, {paths[i]});
const auto status = mkdir(current_path.c_str(), S_IRWXU);
ret = ((status == 0) || (errno == EEXIST));
}
}
return ret;
#endif
}
auto delete_directory(std::string path, bool recursive) -> bool {
if (recursive) {
return delete_directory_recursively(path);
}
path = utils::path::absolute(path);
#if defined(_WIN32)
return (not is_directory(path) || utils::retryable_action([&]() -> bool {
return !!::RemoveDirectoryA(path.c_str());
}));
#else
return not is_directory(path) || (rmdir(path.c_str()) == 0);
#endif
}
auto delete_directory_recursively(std::string path) -> bool {
path = utils::path::absolute(path);
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
auto res = true;
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if ((std::string(fd.cFileName) != ".") &&
(std::string(fd.cFileName) != "..")) {
res = delete_directory_recursively(
utils::path::combine(path, {fd.cFileName}));
}
} else {
res = retry_delete_file(utils::path::combine(path, {fd.cFileName}));
}
} while (res && (::FindNextFile(find, &fd) != 0));
::FindClose(find);
}
#else
auto *root = opendir(path.c_str());
if (root) {
auto res = true;
struct dirent *de{};
while (res && (de = readdir(root))) {
if (de->d_type == DT_DIR) {
if ((strcmp(de->d_name, ".") != 0) && (strcmp(de->d_name, "..") != 0)) {
res = delete_directory_recursively(
utils::path::combine(path, {de->d_name}));
}
} else {
res = retry_delete_file(utils::path::combine(path, {de->d_name}));
}
}
closedir(root);
}
#endif
return delete_directory(path, false);
}
auto delete_file(std::string path) -> bool {
path = utils::path::absolute(path);
#if defined(_WIN32)
return (not is_file(path) || utils::retryable_action([&]() -> bool {
const auto ret = !!::DeleteFileA(path.c_str());
if (not ret) {
std::cout << "delete failed:" << path << std::endl;
}
return ret;
}));
#else
return (not is_file(path) || (unlink(path.c_str()) == 0));
#endif
}
auto generate_sha256(const std::string &file_path) -> std::string {
crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&state);
if (res != 0) {
throw std::runtime_error("failed to initialize sha256|" +
std::to_string(res));
}
native_file_ptr nf;
if (native_file::open(file_path, nf) != api_error::success) {
throw std::runtime_error("failed to open file|" + file_path);
}
{
data_buffer buffer(1048576u);
std::uint64_t read_offset = 0U;
std::size_t bytes_read = 0U;
while (
nf->read_bytes(buffer.data(), buffer.size(), read_offset, bytes_read)) {
if (not bytes_read) {
break;
}
read_offset += bytes_read;
res = crypto_hash_sha256_update(
&state, reinterpret_cast<const unsigned char *>(buffer.data()),
bytes_read);
if (res != 0) {
nf->close();
throw std::runtime_error("failed to update sha256|" +
std::to_string(res));
}
}
nf->close();
}
std::array<unsigned char, crypto_hash_sha256_BYTES> out{};
res = crypto_hash_sha256_final(&state, out.data());
if (res != 0) {
throw std::runtime_error("failed to finalize sha256|" +
std::to_string(res));
}
return utils::collection::to_hex_string(out);
}
auto get_free_drive_space(const std::string &path) -> std::uint64_t {
#if defined(_WIN32)
ULARGE_INTEGER li{};
::GetDiskFreeSpaceEx(path.c_str(), &li, nullptr, nullptr);
return li.QuadPart;
#endif
#if defined(__linux__)
std::uint64_t ret = 0;
struct statfs64 st {};
if (statfs64(path.c_str(), &st) == 0) {
ret = st.f_bfree * st.f_bsize;
}
return ret;
#endif
#if defined(__APPLE__)
struct statvfs st {};
statvfs(path.c_str(), &st);
return st.f_bfree * st.f_frsize;
#endif
}
auto get_total_drive_space(const std::string &path) -> std::uint64_t {
#if defined(_WIN32)
ULARGE_INTEGER li{};
::GetDiskFreeSpaceEx(path.c_str(), nullptr, &li, nullptr);
return li.QuadPart;
#endif
#if defined(__linux__)
std::uint64_t ret = 0;
struct statfs64 st {};
if (statfs64(path.c_str(), &st) == 0) {
ret = st.f_blocks * st.f_bsize;
}
return ret;
#endif
#if defined(__APPLE__)
struct statvfs st {};
statvfs(path.c_str(), &st);
return st.f_blocks * st.f_frsize;
#endif
}
auto get_directory_files(std::string path, bool oldest_first,
auto get_directory_files(std::string_view path, bool oldest_first,
bool recursive) -> std::deque<std::string> {
path = utils::path::absolute(path);
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
auto abs_path = utils::path::absolute(path);
std::deque<std::string> ret;
std::unordered_map<std::string, std::uint64_t> lookup;
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"});
auto search = utils::path::combine(abs_path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
do {
const auto full_path = utils::path::combine(path, {fd.cFileName});
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
FILE_ATTRIBUTE_DIRECTORY) {
if (recursive) {
const auto sub_files =
get_directory_files(full_path, oldest_first, recursive);
ret.insert(ret.end(), sub_files.begin(), sub_files.end());
} else {
ULARGE_INTEGER li{};
li.HighPart = fd.ftLastWriteTime.dwHighDateTime;
li.LowPart = fd.ftLastWriteTime.dwLowDateTime;
lookup[full_path] = li.QuadPart;
ret.emplace_back(full_path);
try {
do {
auto full_path = utils::path::combine(abs_path, {fd.cFileName});
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
FILE_ATTRIBUTE_DIRECTORY) {
if (recursive) {
auto sub_files =
get_directory_files(full_path, oldest_first, recursive);
ret.insert(ret.end(), sub_files.begin(), sub_files.end());
} else {
ULARGE_INTEGER li{};
li.HighPart = fd.ftLastWriteTime.dwHighDateTime;
li.LowPart = fd.ftLastWriteTime.dwLowDateTime;
lookup[full_path] = li.QuadPart;
ret.emplace_back(full_path);
}
}
}
} while (::FindNextFile(find, &fd) != 0);
} while (::FindNextFile(find, &fd) != 0);
} catch (const std::exception &e) {
utils::error::raise_error(function_name, e,
"failed to get directory files");
}
::FindClose(find);
std::sort(ret.begin(), ret.end(),
[&](const auto &p1, const auto &p2) -> bool {
return (oldest_first != 0) == (lookup[p1] < lookup[p2]);
});
std::sort(ret.begin(), ret.end(), [&](auto &&path1, auto &&path2) -> bool {
return (oldest_first != 0) == (lookup[path1] < lookup[path2]);
});
}
#else
auto *root = opendir(path.c_str());
#else // !defined(_WIN32)
auto *root = opendir(abs_path.c_str());
if (root) {
struct dirent *de{};
while ((de = readdir(root)) != nullptr) {
if (de->d_type == DT_DIR) {
if (recursive) {
const auto sub_files =
get_directory_files(utils::path::combine(path, {de->d_name}),
oldest_first, recursive);
ret.insert(ret.end(), sub_files.begin(), sub_files.end());
try {
struct dirent *de{};
while ((de = readdir(root)) != nullptr) {
if (de->d_type == DT_DIR) {
if (recursive) {
auto sub_files = get_directory_files(
utils::path::combine(abs_path, {de->d_name}), oldest_first,
recursive);
ret.insert(ret.end(), sub_files.begin(), sub_files.end());
}
} else {
ret.emplace_back(utils::path::combine(abs_path, {de->d_name}));
}
} else {
ret.emplace_back(utils::path::combine(path, {de->d_name}));
}
} catch (const std::exception &e) {
utils::error::raise_error(function_name, e,
"failed to get directory files");
}
closedir(root);
const auto add_to_lookup = [&](const std::string &lookup_path) {
@@ -414,118 +99,32 @@ auto get_directory_files(std::string path, bool oldest_first,
struct stat st {};
stat(lookup_path.c_str(), &st);
#if defined(__APPLE__)
lookup[lookup_path] = static_cast<std::uint64_t>(
(st.st_mtimespec.tv_sec * NANOS_PER_SECOND) +
st.st_mtimespec.tv_nsec);
#else
lookup[lookup_path] = static_cast<std::uint64_t>(
(st.st_mtim.tv_sec * NANOS_PER_SECOND) + st.st_mtim.tv_nsec);
#endif
lookup[lookup_path] =
(static_cast<std::uint64_t>(st.st_mtimespec.tv_sec) *
utils::time::NANOS_PER_SECOND) +
static_cast<std::uint64_t>(st.st_mtimespec.tv_nsec);
#else // !defined(__APPLE__)
lookup[lookup_path] = (static_cast<std::uint64_t>(st.st_mtim.tv_sec) *
utils::time::NANOS_PER_SECOND) +
static_cast<std::uint64_t>(st.st_mtim.tv_nsec);
#endif // defined(__APPLE__)
}
};
std::sort(ret.begin(), ret.end(),
[&](const auto &p1, const auto &p2) -> bool {
add_to_lookup(p1);
add_to_lookup(p2);
return (oldest_first != 0) == (lookup[p1] < lookup[p2]);
});
std::sort(ret.begin(), ret.end(), [&](auto &&path1, auto &&path2) -> bool {
add_to_lookup(path1);
add_to_lookup(path2);
return (oldest_first != 0) == (lookup.at(path1) < lookup.at(path2));
});
}
#endif
return ret;
}
auto get_accessed_time(const std::string &path,
std::uint64_t &accessed) -> bool {
auto ret = false;
accessed = 0;
#if defined(_WIN32)
struct _stat64 st {};
if (_stat64(path.c_str(), &st) != -1) {
accessed = static_cast<uint64_t>(st.st_atime);
#else
struct stat st {};
if (stat(path.c_str(), &st) != -1) {
#if defined(__APPLE__)
accessed = static_cast<uint64_t>(
st.st_atimespec.tv_nsec + (st.st_atimespec.tv_sec * NANOS_PER_SECOND));
#else
accessed = static_cast<uint64_t>(st.st_atim.tv_nsec +
(st.st_atim.tv_sec * NANOS_PER_SECOND));
#endif
#endif
ret = true;
}
return ret;
}
auto get_modified_time(const std::string &path,
std::uint64_t &modified) -> bool {
auto ret = false;
modified = 0U;
#if defined(_WIN32)
struct _stat64 st {};
if (_stat64(path.c_str(), &st) != -1) {
modified = static_cast<uint64_t>(st.st_mtime);
#else
struct stat st {};
if (stat(path.c_str(), &st) != -1) {
#if defined(__APPLE__)
modified = static_cast<uint64_t>(
st.st_mtimespec.tv_nsec + (st.st_mtimespec.tv_sec * NANOS_PER_SECOND));
#else
modified = static_cast<uint64_t>(st.st_mtim.tv_nsec +
(st.st_mtim.tv_sec * NANOS_PER_SECOND));
#endif
#endif
ret = true;
}
return ret;
}
auto is_modified_date_older_than(const std::string &path,
const std::chrono::hours &hours) -> bool {
auto ret = false;
std::uint64_t modified{};
if (get_modified_time(path, modified)) {
const auto seconds =
std::chrono::duration_cast<std::chrono::seconds>(hours);
#if defined(_WIN32)
return (std::chrono::system_clock::from_time_t(
static_cast<time_t>(modified)) +
seconds) < std::chrono::system_clock::now();
#else
return (modified +
static_cast<std::uint64_t>(seconds.count() * NANOS_PER_SECOND)) <
utils::time::get_time_now();
#endif
}
return ret;
}
auto move_file(std::string from, std::string to) -> bool {
from = utils::path::absolute(from);
to = utils::path::absolute(to);
const auto directory = utils::path::remove_file_name(to);
if (not create_full_directory_path(directory)) {
return false;
}
#if defined(_WIN32)
const bool ret = ::MoveFile(from.c_str(), to.c_str()) != 0;
#else
const bool ret = (rename(from.c_str(), to.c_str()) == 0);
#endif
#endif // defined(_WIN32)
return ret;
}
auto read_file_lines(const std::string &path) -> std::vector<std::string> {
std::vector<std::string> ret;
if (is_file(path)) {
if (utils::file::file(path).exists()) {
std::ifstream fs(path);
std::string current_line;
while (not fs.eof() && std::getline(fs, current_line)) {
@@ -538,7 +137,7 @@ auto read_file_lines(const std::string &path) -> std::vector<std::string> {
}
auto reset_modified_time(const std::string &path) -> bool {
auto ret = false;
auto ret{false};
#if defined(_WIN32)
SYSTEMTIME st{};
::GetSystemTime(&st);
@@ -554,33 +153,14 @@ auto reset_modified_time(const std::string &path) -> bool {
::CloseHandle(handle);
}
}
#else
#else // !defined(_WIN32)
auto fd = open(path.c_str(), O_RDWR);
if ((ret = (fd != -1))) {
ret = not futimens(fd, nullptr);
ret = futimens(fd, nullptr) == 0;
close(fd);
}
#endif
#endif // defined(_WIN32)
return ret;
}
auto retry_delete_directory(const std::string &dir) -> bool {
auto deleted = false;
for (std::uint8_t i = 0U; not(deleted = delete_directory(dir)) && (i < 200U);
i++) {
std::this_thread::sleep_for(10ms);
}
return deleted;
}
auto retry_delete_file(const std::string &file) -> bool {
auto deleted = false;
for (std::uint8_t i = 0U; not(deleted = delete_file(file)) && (i < 200U);
i++) {
std::this_thread::sleep_for(10ms);
}
return deleted;
}
} // namespace repertory::utils::file

View File

@@ -1,319 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/native_file.hpp"
#include "platform/platform.hpp"
#include "types/repertory.hpp"
#include "utils/string.hpp"
#include "utils/utils.hpp"
namespace repertory {
auto native_file::get_handle() -> native_handle { return handle_; }
native_file::~native_file() {
if (auto_close) {
close();
}
}
auto native_file::clone(const native_file_ptr &ptr) -> native_file_ptr {
std::string source_path;
#if defined(_WIN32)
source_path.resize(MAX_PATH + 1);
::GetFinalPathNameByHandleA(ptr->get_handle(), source_path.data(),
MAX_PATH + 1,
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
#else
source_path.resize(PATH_MAX + 1);
#if defined(__APPLE__)
fcntl(ptr->get_handle(), F_GETPATH, source_path.data());
#else
readlink(("/proc/self/fd/" + std::to_string(ptr->get_handle())).c_str(),
source_path.data(), source_path.size());
#endif
#endif
source_path = source_path.c_str();
native_file_ptr clone;
auto res = native_file::open(source_path, clone);
if (res != api_error::success) {
throw std::runtime_error("unable to open file|sp|" + source_path + "|err|" +
api_error_to_string(res));
}
return clone;
}
auto native_file::create_or_open(std::string_view source_path, bool read_only,
native_file_ptr &ptr) -> api_error {
#if defined(_WIN32)
auto handle =
read_only ? ::CreateFileA(std::string{source_path}.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, nullptr)
: ::CreateFileA(std::string{source_path}.c_str(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, nullptr);
#else
auto handle = read_only ? ::open(std::string{source_path}.c_str(),
O_CREAT | O_RDONLY | O_CLOEXEC, 0600U)
: ::open(std::string{source_path}.c_str(),
O_CREAT | O_RDWR | O_CLOEXEC, 0600U);
if (not read_only) {
chmod(std::string{source_path}.c_str(), 0600U);
}
#endif
ptr = native_file::attach(handle);
return ((handle == REPERTORY_INVALID_HANDLE) ? api_error::os_error
: api_error::success);
}
auto native_file::create_or_open(std::string_view source_path,
native_file_ptr &ptr) -> api_error {
return create_or_open(source_path, false, ptr);
}
auto native_file::open(std::string_view source_path,
native_file_ptr &ptr) -> api_error {
return open(source_path, false, ptr);
}
auto native_file::open(std::string_view source_path, bool read_only,
native_file_ptr &ptr) -> api_error {
#if defined(_WIN32)
auto handle =
read_only
? ::CreateFileA(std::string{source_path}.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr)
: ::CreateFileA(std::string{source_path}.c_str(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr);
#else
auto handle =
read_only ? ::open(std::string{source_path}.c_str(), O_RDONLY | O_CLOEXEC)
: ::open(std::string{source_path}.c_str(), O_RDWR | O_CLOEXEC);
if (not read_only) {
chmod(std::string{source_path}.c_str(), 0600U);
}
#endif
ptr = native_file::attach(handle);
return ((handle == REPERTORY_INVALID_HANDLE) ? api_error::os_error
: api_error::success);
}
auto native_file::allocate(std::uint64_t file_size) -> bool {
#if defined(_WIN32)
LARGE_INTEGER li{};
li.QuadPart = static_cast<LONGLONG>(file_size);
return (::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN) &&
::SetEndOfFile(handle_));
#endif
#if defined(__linux__)
return (fallocate(handle_, 0, 0, static_cast<off_t>(file_size)) >= 0);
#endif
#if defined(__APPLE__)
return (ftruncate(handle_, file_size) >= 0);
#endif
}
void native_file::close() {
if (handle_ != REPERTORY_INVALID_HANDLE) {
#if defined(_WIN32)
::CloseHandle(handle_);
#else
::close(handle_);
#endif
handle_ = REPERTORY_INVALID_HANDLE;
}
}
auto native_file::copy_from(const native_file_ptr &ptr) -> bool {
std::uint64_t file_size{};
auto ret = ptr->get_file_size(file_size);
if (ret) {
data_buffer buffer;
buffer.resize(65536ULL * 2ULL);
std::uint64_t offset{};
while (ret && (file_size > 0U)) {
std::size_t bytes_read{};
ret = ptr->read_bytes(buffer.data(), buffer.size(), offset, bytes_read);
if (ret) {
std::size_t bytes_written{};
ret = write_bytes(buffer.data(), bytes_read, offset, bytes_written);
file_size -= bytes_read;
offset += bytes_read;
}
}
flush();
}
return ret;
}
auto native_file::copy_from(const std::string &path) -> bool {
auto ret = false;
native_file_ptr ptr;
if (native_file::create_or_open(path, ptr) == api_error ::success) {
ret = copy_from(ptr);
ptr->close();
}
return ret;
}
void native_file::flush() {
#if defined(_WIN32)
recur_mutex_lock l(read_write_mutex_);
::FlushFileBuffers(handle_);
#else
fsync(handle_);
#endif
}
auto native_file::get_file_size(std::uint64_t &file_size) -> bool {
auto ret = false;
#if defined(_WIN32)
LARGE_INTEGER li{};
if ((ret = ::GetFileSizeEx(handle_, &li) && (li.QuadPart >= 0))) {
file_size = static_cast<std::uint64_t>(li.QuadPart);
}
#else
#if defined(__APPLE__)
struct stat unix_st {};
if (fstat(handle_, &unix_st) >= 0) {
#else
struct stat64 unix_st {};
if (fstat64(handle_, &unix_st) >= 0) {
#endif
ret = (unix_st.st_size >= 0);
if (ret) {
file_size = static_cast<uint64_t>(unix_st.st_size);
}
}
#endif
return ret;
}
#if defined(_WIN32)
auto native_file::read_bytes(unsigned char *buffer, std::size_t read_size,
std::uint64_t read_offset,
std::size_t &bytes_read) -> bool {
recur_mutex_lock l(read_write_mutex_);
auto ret = false;
bytes_read = 0u;
LARGE_INTEGER li{};
li.QuadPart = static_cast<LONGLONG>(read_offset);
if ((ret = !!::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN))) {
DWORD current_read = 0u;
do {
current_read = 0u;
ret = !!::ReadFile(handle_, &buffer[bytes_read],
static_cast<DWORD>(read_size - bytes_read),
&current_read, nullptr);
bytes_read += current_read;
} while (ret && (bytes_read < read_size) && (current_read != 0));
}
if (ret && (read_size != bytes_read)) {
::SetLastError(ERROR_HANDLE_EOF);
}
return ret;
}
#else
auto native_file::read_bytes(unsigned char *buffer, std::size_t read_size,
std::uint64_t read_offset,
std::size_t &bytes_read) -> bool {
bytes_read = 0U;
ssize_t result = 0;
do {
result = pread64(handle_, &buffer[bytes_read], read_size - bytes_read,
static_cast<off_t>(read_offset + bytes_read));
if (result > 0) {
bytes_read += static_cast<size_t>(result);
}
} while ((result > 0) && (bytes_read < read_size));
return (result >= 0);
}
#endif
auto native_file::truncate(std::uint64_t file_size) -> bool {
#if defined(_WIN32)
recur_mutex_lock l(read_write_mutex_);
LARGE_INTEGER li{};
li.QuadPart = static_cast<LONGLONG>(file_size);
return (::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN) &&
::SetEndOfFile(handle_));
#else
return (ftruncate(handle_, static_cast<off_t>(file_size)) >= 0);
#endif
}
#if defined(_WIN32)
auto native_file::write_bytes(const unsigned char *buffer,
std::size_t write_size,
std::uint64_t write_offset,
std::size_t &bytes_written) -> bool {
recur_mutex_lock l(read_write_mutex_);
bytes_written = 0u;
auto ret = true;
LARGE_INTEGER li{};
li.QuadPart = static_cast<LONGLONG>(write_offset);
if ((ret = !!::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN))) {
do {
DWORD current_write = 0u;
ret = !!::WriteFile(handle_, &buffer[bytes_written],
static_cast<DWORD>(write_size - bytes_written),
&current_write, nullptr);
bytes_written += current_write;
} while (ret && (bytes_written < write_size));
}
return ret;
}
#else
auto native_file::write_bytes(const unsigned char *buffer,
std::size_t write_size,
std::uint64_t write_offset,
std::size_t &bytes_written) -> bool {
bytes_written = 0U;
ssize_t result{};
do {
result =
pwrite64(handle_, &buffer[bytes_written], write_size - bytes_written,
static_cast<off_t>(write_offset + bytes_written));
if (result > 0) {
bytes_written += static_cast<size_t>(result);
}
} while ((result >= 0) && (bytes_written < write_size));
return (bytes_written == write_size);
}
#endif
} // namespace repertory

View File

@@ -201,10 +201,6 @@ auto unix_error_to_windows(int err) -> std::uint32_t {
}
}
auto unix_time_to_windows_time(const remote::file_time &file_time) -> UINT64 {
return (file_time / 100ULL) + 116444736000000000ULL;
}
void windows_create_to_unix(const UINT32 &create_options,
const UINT32 &granted_access, std::uint32_t &flags,
remote::file_mode &mode) {
@@ -221,10 +217,6 @@ void windows_create_to_unix(const UINT32 &create_options,
mode |= (S_IXUSR);
}
}
auto windows_time_to_unix_time(std::uint64_t win_time) -> remote::file_time {
return (win_time - 116444736000000000ULL) * 100ULL;
}
} // namespace repertory::utils
#endif // !_WIN32

View File

@@ -22,16 +22,8 @@
#include "utils/utils.hpp"
#include "app_config.hpp"
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "providers/i_provider.hpp"
#include "types/startup_exception.hpp"
#include "utils/com_init_wrapper.hpp"
#include "utils/common.hpp"
#include "utils/native_file.hpp"
#include "utils/path.hpp"
#include "utils/string.hpp"
#include "utils/time.hpp"
namespace repertory::utils {
void calculate_allocation_size(bool directory, std::uint64_t file_size,
@@ -53,32 +45,6 @@ void calculate_allocation_size(bool directory, std::uint64_t file_size,
allocation_meta_size = std::to_string(allocation_size);
}
auto convert_api_date(const std::string &date) -> std::uint64_t {
// 2009-10-12T17:50:30.000Z
const auto date_parts = utils::string::split(date, '.', true);
const auto date_time = date_parts[0U];
const auto nanos = utils::string::to_uint64(
utils::string::split(date_parts[1U], 'Z', true)[0U]);
struct tm tm1 {};
#if defined(_WIN32)
utils::time::strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
#else
strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
#endif
return nanos + (static_cast<std::uint64_t>(mktime(&tm1)) * NANOS_PER_SECOND);
}
auto create_curl() -> CURL * {
static std::recursive_mutex mtx;
unique_recur_mutex_lock lock(mtx);
curl_global_init(CURL_GLOBAL_DEFAULT);
lock.unlock();
return reset_curl(curl_easy_init());
}
auto create_volume_label(const provider_type &prov) -> std::string {
return "repertory_" + app_config::get_provider_name(prov);
}
@@ -86,54 +52,4 @@ auto create_volume_label(const provider_type &prov) -> std::string {
auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD {
return static_cast<DWORD>(utils::string::to_uint32(meta.at(META_ATTRIBUTES)));
}
auto reset_curl(CURL *curl_handle) -> CURL * {
curl_easy_reset(curl_handle);
#if defined(__APPLE__)
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
#endif
return curl_handle;
}
auto retryable_action(const std::function<bool()> &action) -> bool {
static constexpr const auto retry_count = 20U;
auto succeeded = false;
for (std::uint8_t i = 0U; not(succeeded = action()) && (i < retry_count);
i++) {
std::this_thread::sleep_for(100ms);
}
return succeeded;
}
void spin_wait_for_mutex(std::function<bool()> complete,
std::condition_variable &cond, std::mutex &mtx,
const std::string &text) {
while (not complete()) {
unique_mutex_lock lock(mtx);
if (not complete()) {
if (not text.empty()) {
/* event_system::instance().raise<DebugLog>(__FUNCTION__,
* "spin_wait_for_mutex", text); */
}
cond.wait_for(lock, 1s);
}
lock.unlock();
}
}
void spin_wait_for_mutex(bool &complete, std::condition_variable &cond,
std::mutex &mtx, const std::string &text) {
while (not complete) {
unique_mutex_lock lock(mtx);
if (not complete) {
if (not text.empty()) {
/* event_system::instance().raise<DebugLog>(__FUNCTION__,
* "spin_wait_for_mutex", text); */
}
cond.wait_for(lock, 1s);
}
lock.unlock();
}
}
} // namespace repertory::utils

View File

@@ -23,9 +23,8 @@
#include "utils/windows/windows_utils.hpp"
#include "types/startup_exception.hpp"
#include "utils/com_init_wrapper.hpp"
#include "utils/string.hpp"
#include "utils/time.hpp"
#if !defined(STATUS_DEVICE_INSUFFICIENT_RESOURCES)
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES static_cast<NTSTATUS>(0xC0000468L)
@@ -88,19 +87,23 @@ auto from_api_error(const api_error &e) -> NTSTATUS {
}
auto get_accessed_time_from_meta(const api_meta_map &meta) -> std::uint64_t {
return utils::string::to_uint64(meta.at(META_ACCESSED));
return utils::time::unix_time_to_windows_time(
utils::string::to_uint64(meta.at(META_ACCESSED)));
}
auto get_changed_time_from_meta(const api_meta_map &meta) -> std::uint64_t {
return utils::string::to_uint64(meta.at(META_MODIFIED));
return utils::time::unix_time_to_windows_time(
utils::string::to_uint64(meta.at(META_MODIFIED)));
}
auto get_creation_time_from_meta(const api_meta_map &meta) -> std::uint64_t {
return utils::string::to_uint64(meta.at(META_CREATION));
return utils::time::unix_time_to_windows_time(
utils::string::to_uint64(meta.at(META_CREATION)));
}
auto get_written_time_from_meta(const api_meta_map &meta) -> std::uint64_t {
return utils::string::to_uint64(meta.at(META_WRITTEN));
return utils::time::unix_time_to_windows_time(
utils::string::to_uint64(meta.at(META_WRITTEN)));
}
auto unix_access_mask_to_windows(std::int32_t mask) -> int {

View File

@@ -80,7 +80,7 @@ mount(std::vector<const char *> args, std::string data_directory,
std::cout << "Generated " << app_config::get_provider_display_name(prov)
<< " Configuration" << std::endl;
std::cout << config.get_config_file_path() << std::endl;
ret = utils::file::is_file(config.get_config_file_path())
ret = utils::file::file(config.get_config_file_path()).exists()
? exit_code::success
: exit_code::file_creation_failed;
} else {

View File

@@ -21,7 +21,7 @@
*/
#if defined(PROJECT_ENABLE_BACKWARD_CPP)
#include "backward.hpp"
#endif
#endif // defined(PROJECT_ENABLE_BACKWARD_CPP)
#include "cli/actions.hpp"
#include "initialize.hpp"
@@ -34,7 +34,7 @@ using namespace repertory;
auto main(int argc, char **argv) -> int {
#if defined(PROJECT_ENABLE_BACKWARD_CPP)
static backward::SignalHandling sh;
#endif
#endif // defined(PROJECT_ENABLE_BACKWARD_CPP)
if (not repertory::project_initialize()) {
std::cerr << "fatal: failed to initialize repertory" << std::endl;

View File

@@ -0,0 +1,235 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_TEST_INCLUDE_FIXTURES_FUSE_FIXTURE_HPP
#define REPERTORY_TEST_INCLUDE_FIXTURES_FUSE_FIXTURE_HPP
#if !defined(_WIN32)
#include "test_common.hpp"
#include "app_config.hpp"
#include "comm/curl/curl_comm.hpp"
#include "drives/fuse/fuse_drive.hpp"
#include "platform/platform.hpp"
#include "providers/encrypt/encrypt_provider.hpp"
#include "providers/s3/s3_provider.hpp"
#include "providers/sia/sia_provider.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp"
#if !defined(ACCESSPERMS)
#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) /* 0777 */
#endif
namespace repertory {
inline constexpr const auto SLEEP_SECONDS{1.5s};
template <typename provider_t> class fuse_test : public ::testing::Test {
public:
static std::string cfg_directory;
static std::unique_ptr<curl_comm> comm;
static std::unique_ptr<app_config> config;
static std::filesystem::path current_directory;
static std::unique_ptr<fuse_drive> drive;
static lock_data lock_data_;
static std::string mount_location;
static std::unique_ptr<i_provider> provider;
static std::string test_directory;
protected:
static void SetUpTestCase() {
current_directory = std::filesystem::current_path();
test_directory = utils::path::combine(
test::get_test_output_dir(),
{
"fuse_test",
std::to_string(static_cast<std::uint8_t>(provider_t::type)),
});
ASSERT_TRUE(utils::file::directory(test_directory).remove_recursively());
mount_location = utils::path::combine(test_directory, {"mount"});
ASSERT_TRUE(utils::file::directory(mount_location).create_directory());
cfg_directory = utils::path::combine(test_directory, {"cfg"});
ASSERT_TRUE(utils::file::directory(cfg_directory).create_directory());
config = std::make_unique<app_config>(provider_t::type, cfg_directory);
std::vector<std::string> drive_args{};
switch (provider_t::type) {
case provider_type::s3: {
{
app_config src_cfg{
provider_type::s3,
utils::path::combine(test::get_test_input_dir(), {"storj"}),
};
config->set_enable_drive_events(true);
config->set_event_level(event_level::trace);
config->set_s3_config(src_cfg.get_s3_config());
}
comm = std::make_unique<curl_comm>(config->get_s3_config());
drive_args = std::vector<std::string>({
"-s3",
"-na",
"storj",
});
} break;
case provider_type::sia: {
{
app_config src_cfg{
provider_type::sia,
utils::path::combine(test::get_test_input_dir(), {"sia"}),
};
config->set_enable_drive_events(true);
config->set_event_level(event_level::debug);
config->set_host_config(src_cfg.get_host_config());
}
comm = std::make_unique<curl_comm>(config->get_host_config());
} break;
// case 0U: {
// config =
// std::make_unique<app_config>(provider_type::encrypt,
// cfg_directory);
// {
// app_config src_cfg(
// provider_type::s3,
// utils::path::combine(test::get_test_input_dir(), {"encrypt"}));
// config->set_enable_drive_events(true);
// config->set_event_level(event_level::trace);
// config->set_s3_config(src_cfg.get_s3_config());
// }
//
// comm = std::make_unique<curl_comm>(config->get_s3_config());
// provider = std::make_unique<s3_provider>(*config, *comm);
// drive_args = std::vector<std::string>({"-en"});
// } break;
default:
throw std::runtime_error("provider type is not implemented");
return;
}
provider = std::make_unique<provider_t>(*config, *comm);
drive_args.push_back(mount_location);
execute_mount(drive_args);
}
static void TearDownTestCase() {
execute_unmount();
std::filesystem::current_path(current_directory);
[[maybe_unused]] auto ret =
utils::file::directory(test_directory).remove_recursively();
}
public:
static auto create_file_and_test(std::string name) -> std::string {
auto file_path = utils::path::combine(mount_location, {name});
auto fd =
open(file_path.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP);
EXPECT_LE(1, fd);
EXPECT_TRUE(utils::file::file(file_path).exists());
EXPECT_FALSE(utils::file::directory(file_path).exists());
auto opt_size = utils::file::file{file_path}.size();
EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(0U, opt_size.value());
EXPECT_EQ(0, close(fd));
std::this_thread::sleep_for(SLEEP_SECONDS);
return file_path;
}
static void execute_mount(auto &&drive_args) {
auto mount_cmd = "./repertory -dd \"" + config->get_data_directory() +
"\"" + " " + utils::string::join(drive_args, ' ');
std::cout << "mount command: " << mount_cmd << std::endl;
ASSERT_EQ(0, system(mount_cmd.c_str()));
std::this_thread::sleep_for(5s);
EXPECT_EQ(0, system(("mount|grep \"" + mount_location + "\"").c_str()));
}
static void execute_unmount() {
auto unmounted{false};
for (int i = 0; not unmounted && (i < 50); i++) {
unmounted = (fuse_base::unmount(mount_location) == 0);
if (not unmounted) {
std::this_thread::sleep_for(100ms);
}
}
EXPECT_TRUE(unmounted);
}
static void unlink_file_and_test(const std::string &file_path) {
int ret = 0;
for (auto i = 0; ((ret = unlink(file_path.c_str())) != 0) && (i < 20);
i++) {
std::this_thread::sleep_for(100ms);
}
EXPECT_EQ(0, ret);
std::this_thread::sleep_for(SLEEP_SECONDS);
EXPECT_FALSE(utils::file::directory(file_path).exists());
EXPECT_FALSE(utils::file::file(file_path).exists());
}
};
template <typename provider_t>
std::string fuse_test<provider_t>::cfg_directory{};
template <typename provider_t>
std::unique_ptr<curl_comm> fuse_test<provider_t>::comm{};
template <typename provider_t>
std::unique_ptr<app_config> fuse_test<provider_t>::config{};
template <typename provider_t>
std::filesystem::path fuse_test<provider_t>::current_directory{};
template <typename provider_t>
std::unique_ptr<fuse_drive> fuse_test<provider_t>::drive{};
template <typename provider_t> lock_data fuse_test<provider_t>::lock_data_{};
template <typename provider_t>
std::string fuse_test<provider_t>::mount_location{};
template <typename provider_t>
std::unique_ptr<i_provider> fuse_test<provider_t>::provider{};
template <typename provider_t>
std::string fuse_test<provider_t>::test_directory;
typedef ::testing::Types<s3_provider, sia_provider> fuse_provider_types;
} // namespace repertory
#endif // !defined(_WIN32)
#endif // REPERTORY_TEST_INCLUDE_FIXTURES_FUSE_FIXTURE_HPP

View File

@@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_WINFSP_FIXTURE_HPP
#define REPERTORY_WINFSP_FIXTURE_HPP
#ifndef REPERTORY_TEST_INCLUDE_FIXTURES_WINFSP_FIXTURE_HPP
#define REPERTORY_TEST_INCLUDE_FIXTURES_WINFSP_FIXTURE_HPP
#if defined(_WIN32)
#include "test_common.hpp"
@@ -31,6 +31,8 @@
#include "platform/platform.hpp"
#include "providers/s3/s3_provider.hpp"
#include "providers/sia/sia_provider.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp"
extern std::size_t PROVIDER_INDEX;
@@ -47,14 +49,20 @@ protected:
void SetUp() override {
if (PROVIDER_INDEX != 0) {
if (PROVIDER_INDEX == 1) {
EXPECT_TRUE(utils::file::delete_directory_recursively(
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX)));
EXPECT_TRUE(utils::file::directory(
utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}))
.remove_recursively());
app_config src_cfg(provider_type::s3,
utils::path::combine(get_test_dir(), {"storj"}));
app_config src_cfg(
provider_type::s3,
utils::path::combine(test::get_test_input_dir(), {"storj"}));
config = std::make_unique<app_config>(
provider_type::s3,
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX));
utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}));
EXPECT_FALSE(config
->set_value_by_name("S3Config.AccessKey",
src_cfg.get_s3_config().access_key)
@@ -89,14 +97,20 @@ protected:
}
if (PROVIDER_INDEX == 2) {
EXPECT_TRUE(utils::file::delete_directory_recursively(
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX)));
EXPECT_TRUE(utils::file::directory(
utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}))
.remove_recursively());
app_config src_cfg(provider_type::sia,
utils::path::combine(get_test_dir(), {"sia"}));
app_config src_cfg(
provider_type::sia,
utils::path::combine(test::get_test_input_dir(), {"sia"}));
config = std::make_unique<app_config>(
provider_type::sia,
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX));
utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}));
[[maybe_unused]] auto val = config->set_value_by_name(
"HostConfig.AgentString", src_cfg.get_host_config().agent_string);
EXPECT_FALSE(
@@ -135,12 +149,15 @@ protected:
config.reset();
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX)));
EXPECT_TRUE(utils::file::directory(
utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}))
.remove_recursively());
}
}
};
} // namespace repertory
#endif
#endif // REPERTORY_WINFSP_FIXTURE_HPP
#endif // REPERTORY_TEST_INCLUDE_FIXTURES_WINFSP_FIXTURE_HPP

View File

@@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef TESTS_MOCKS_MOCK_FUSE_DRIVE_HPP_
#define TESTS_MOCKS_MOCK_FUSE_DRIVE_HPP_
#ifndef REPERTORY_TEST_INCLUDE_FIXTURES_MOCKS_MOCK_FUSE_DRIVE_HPP_
#define REPERTORY_TEST_INCLUDE_FIXTURES_MOCKS_MOCK_FUSE_DRIVE_HPP_
#if !defined(_WIN32)
#include "test_common.hpp"
@@ -68,10 +68,10 @@ public:
dir_item.size = 0;
dir_item.meta = {
{META_ATTRIBUTES, "16"},
{META_MODIFIED, std::to_string(utils::time::get_file_time_now())},
{META_WRITTEN, std::to_string(utils::time::get_file_time_now())},
{META_ACCESSED, std::to_string(utils::time::get_file_time_now())},
{META_CREATION, std::to_string(utils::time::get_file_time_now())}};
{META_MODIFIED, std::to_string(utils::time::get_time_now())},
{META_WRITTEN, std::to_string(utils::time::get_time_now())},
{META_ACCESSED, std::to_string(utils::time::get_time_now())},
{META_CREATION, std::to_string(utils::time::get_time_now())}};
list.emplace_back(dir_item);
dir_item.api_path = "..";
@@ -132,11 +132,11 @@ public:
utils::path::combine(mount_location_, {to_api_path});
if (overwrite) {
if (not utils::file::retry_delete_file(to_file_path)) {
if (not utils::file::file(to_file_path).remove()) {
return -1;
}
} else if (utils::file::is_directory(to_file_path) ||
utils::file::is_file(to_file_path)) {
} else if (utils::file::directory(to_file_path).exists() ||
utils::file::file(to_file_path).exists()) {
errno = EEXIST;
return -1;
}
@@ -155,5 +155,5 @@ public:
};
} // namespace repertory
#endif // _WIN32
#endif // TESTS_MOCKS_MOCK_FUSE_DRIVE_HPP_
#endif // !defined(_WIN32)
#endif // REPERTORY_TEST_INCLUDE_FIXTURES_MOCKS_MOCK_FUSE_DRIVE_HPP_

View File

@@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef TESTS_MOCKS_MOCK_OPEN_FILE_HPP_
#define TESTS_MOCKS_MOCK_OPEN_FILE_HPP_
#ifndef REPERTORY_TEST_INCLUDE_MOCKS_MOCK_OPEN_FILE_HPP_
#define REPERTORY_TEST_INCLUDE_MOCKS_MOCK_OPEN_FILE_HPP_
#include "test_common.hpp"
@@ -95,4 +95,4 @@ public:
};
} // namespace repertory
#endif // TESTS_MOCKS_MOCK_OPEN_FILE_HPP_
#endif // REPERTORY_TEST_INCLUDE_MOCKS_MOCK_OPEN_FILE_HPP_

View File

@@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef TESTS_MOCKS_MOCK_PROVIDER_HPP_
#define TESTS_MOCKS_MOCK_PROVIDER_HPP_
#ifndef REPERTORY_TEST_INCLUDE_MOCKS_MOCK_PROVIDER_HPP_
#define REPERTORY_TEST_INCLUDE_MOCKS_MOCK_PROVIDER_HPP_
#include "test_common.hpp"
@@ -159,4 +159,4 @@ public:
};
} // namespace repertory
#endif // TESTS_MOCKS_MOCK_PROVIDER_HPP_
#endif // REPERTORY_TEST_INCLUDE_MOCKS_MOCK_PROVIDER_HPP_

View File

@@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef TESTS_MOCKS_MOCK_UPLOAD_MANAGER_HPP_
#define TESTS_MOCKS_MOCK_UPLOAD_MANAGER_HPP_
#ifndef REPERTORY_TEST_INCLUDE_MOCKS_MOCK_UPLOAD_MANAGER_HPP_
#define REPERTORY_TEST_INCLUDE_MOCKS_MOCK_UPLOAD_MANAGER_HPP_
#include "test_common.hpp"
@@ -41,4 +41,4 @@ public:
};
} // namespace repertory
#endif // TESTS_MOCKS_MOCK_UPLOAD_MANAGER_HPP_
#endif // REPERTORY_TEST_INCLUDE_MOCKS_MOCK_UPLOAD_MANAGER_HPP_

View File

@@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef TESTS_MOCKS_MOCK_WINFSP_DRIVE_HPP_
#define TESTS_MOCKS_MOCK_WINFSP_DRIVE_HPP_
#ifndef REPERTORY_TEST_INCLUDE_MOCKS_MOCK_WINFSP_DRIVE_HPP_
#define REPERTORY_TEST_INCLUDE_MOCKS_MOCK_WINFSP_DRIVE_HPP_
#if defined(_WIN32)
#include "test_common.hpp"
@@ -57,10 +57,10 @@ public:
di.size = 0u;
di.meta = {
{META_ATTRIBUTES, "16"},
{META_MODIFIED, std::to_string(utils::time::get_file_time_now())},
{META_WRITTEN, std::to_string(utils::time::get_file_time_now())},
{META_ACCESSED, std::to_string(utils::time::get_file_time_now())},
{META_CREATION, std::to_string(utils::time::get_file_time_now())}};
{META_MODIFIED, std::to_string(utils::time::get_time_now())},
{META_WRITTEN, std::to_string(utils::time::get_time_now())},
{META_ACCESSED, std::to_string(utils::time::get_time_now())},
{META_CREATION, std::to_string(utils::time::get_time_now())}};
list.emplace_back(di);
di.api_path = "..";
@@ -138,7 +138,7 @@ public:
auto populate_file_info(const std::string &api_path,
remote::file_info &file_info) -> api_error override {
const auto file_path = utils::path::combine(mount_location_, {api_path});
const auto directory = utils::file::is_directory(file_path);
const auto directory = utils::file::directory(file_path).exists();
const auto attributes =
FILE_FLAG_BACKUP_SEMANTICS |
(directory ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL);
@@ -148,8 +148,14 @@ public:
FILE_BASIC_INFO fi{};
::GetFileInformationByHandleEx(handle, FileBasicInfo, &fi, sizeof(fi));
if (not directory) {
utils::file::get_file_size(file_path, file_info.FileSize);
auto opt_size = utils::file::file{file_path}.size();
if (not opt_size.has_value()) {
return api_error::os_error;
}
file_info.FileSize = opt_size.value();
}
file_info.AllocationSize =
directory ? 0
: utils::divide_with_ceiling(file_info.FileSize,
@@ -167,4 +173,4 @@ public:
} // namespace repertory
#endif // _WIN32
#endif // TESTS_MOCKS_MOCK_WINFSP_DRIVE_HPP_
#endif // REPERTORY_TEST_INCLUDE_MOCKS_MOCK_WINFSP_DRIVE_HPP_

View File

@@ -19,47 +19,15 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef TESTS_TEST_COMMON_HPP_
#define TESTS_TEST_COMMON_HPP_
#if defined(U)
#undef U
#endif
#ifndef REPERTORY_TEST_INCLUDE_TEST_COMMON_HPP_
#define REPERTORY_TEST_INCLUDE_TEST_COMMON_HPP_
REPERTORY_IGNORE_WARNINGS_ENABLE()
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "test.hpp"
REPERTORY_IGNORE_WARNINGS_DISABLE()
#include "events/consumers/console_consumer.hpp"
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "utils/encrypt.hpp"
#include "utils/file_utils.hpp"
#include "utils/native_file.hpp"
#define COMMA ,
using ::testing::_;
using namespace ::testing;
namespace repertory {
[[nodiscard]] auto create_random_file(std::string path,
std::size_t size) -> native_file_ptr;
void delete_generated_files();
[[nodiscard]] auto generate_test_file_name(
const std::string &directory,
const std::string &file_name_no_extension) -> std::string;
template <typename T, typename T2>
static void decrypt_and_verify(const T &buffer, const std::string &token,
T2 &result) {
EXPECT_TRUE(utils::encryption::decrypt_data(token, buffer, result));
}
[[nodiscard]] auto get_test_dir() -> std::string;
} // namespace repertory
#endif // TESTS_TEST_COMMON_HPP_
#endif // REPERTORY_TEST_INCLUDE_TEST_COMMON_HPP_

View File

@@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef TESTS_UTILS_EVENT_CAPTURE_HPP_
#define TESTS_UTILS_EVENT_CAPTURE_HPP_
#ifndef REPERTORY_TEST_INCLUDE_UTILS_EVENT_CAPTURE_HPP_
#define REPERTORY_TEST_INCLUDE_UTILS_EVENT_CAPTURE_HPP_
#include "test_common.hpp"
@@ -106,4 +106,4 @@ public:
};
} // namespace repertory
#endif // TESTS_UTILS_EVENT_CAPTURE_HPP_
#endif // REPERTORY_TEST_INCLUDE_UTILS_EVENT_CAPTURE_HPP_

View File

@@ -63,8 +63,6 @@ auto main(int argc, char **argv) -> int {
::testing::InitGoogleTest(&argc, argv);
auto ret = RUN_ALL_TESTS();
delete_generated_files();
repertory::project_cleanup();
return ret;

View File

@@ -33,20 +33,24 @@ public:
static console_consumer cs;
std::string s3_directory{
utils::path::combine("./test_config", {"config_test", "s3"})};
utils::path::combine(test::get_test_output_dir(), {"config_test", "s3"})};
std::string sia_directory{
utils::path::combine("./test_config", {"config_test", "sia"})};
std::string sia_directory{utils::path::combine(test::get_test_output_dir(),
{"config_test", "sia"})};
void SetUp() override {
event_system::instance().start();
ASSERT_TRUE(utils::file::delete_directory_recursively(
utils::path::combine("./test_config", {"config_test"})));
ASSERT_TRUE(
utils::file::directory(
utils::path::combine(test::get_test_output_dir(), {"config_test"}))
.remove_recursively());
}
void TearDown() override {
ASSERT_TRUE(utils::file::delete_directory_recursively(
utils::path::combine("./test_config", {"config_test"})));
ASSERT_TRUE(
utils::file::directory(
utils::path::combine(test::get_test_output_dir(), {"config_test"}))
.remove_recursively());
event_system::instance().stop();
}
};
@@ -163,10 +167,12 @@ TEST_F(config_test, sia_default_settings) {
json data;
EXPECT_TRUE(utils::file::read_json_file(config_file, data));
EXPECT_STREQ(DEFAULT_SIA_CONFIG.c_str(), data.dump(2).c_str());
EXPECT_TRUE(utils::file::is_directory(
utils::path::combine(sia_directory, {"cache"})));
EXPECT_TRUE(utils::file::is_directory(
utils::path::combine(sia_directory, {"logs"})));
EXPECT_TRUE(
utils::file::directory(utils::path::combine(sia_directory, {"cache"}))
.exists());
EXPECT_TRUE(
utils::file::directory(utils::path::combine(sia_directory, {"logs"}))
.exists());
}
}
@@ -180,10 +186,12 @@ TEST_F(config_test, s3_default_settings) {
json data;
EXPECT_TRUE(utils::file::read_json_file(config_file, data));
EXPECT_STREQ(DEFAULT_S3_CONFIG.c_str(), data.dump(2).c_str());
EXPECT_TRUE(utils::file::is_directory(
utils::path::combine(s3_directory, {"cache"})));
EXPECT_TRUE(utils::file::is_directory(
utils::path::combine(s3_directory, {"logs"})));
EXPECT_TRUE(
utils::file::directory(utils::path::combine(s3_directory, {"cache"}))
.exists());
EXPECT_TRUE(
utils::file::directory(utils::path::combine(s3_directory, {"logs"}))
.exists());
}
}

View File

@@ -35,8 +35,9 @@ TEST(database, db_insert) {
{
sqlite3 *db3_ptr{nullptr};
auto res = sqlite3_open_v2(
utils::path::combine(get_test_dir(), {"test.db3"}).c_str(), &db3_ptr,
SQLITE_OPEN_READWRITE, nullptr);
utils::path::combine(test::get_test_input_dir(), {"test.db3"})
.c_str(),
&db3_ptr, SQLITE_OPEN_READWRITE, nullptr);
ASSERT_EQ(SQLITE_OK, res);
ASSERT_TRUE(db3_ptr != nullptr);
@@ -78,8 +79,9 @@ TEST(database, db_select) {
{
sqlite3 *db3_ptr{nullptr};
auto res = sqlite3_open_v2(
utils::path::combine(get_test_dir(), {"test.db3"}).c_str(), &db3_ptr,
SQLITE_OPEN_READWRITE, nullptr);
utils::path::combine(test::get_test_input_dir(), {"test.db3"})
.c_str(),
&db3_ptr, SQLITE_OPEN_READWRITE, nullptr);
ASSERT_EQ(SQLITE_OK, res);
ASSERT_TRUE(db3_ptr != nullptr);

View File

@@ -1,283 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "test_common.hpp"
#include "types/repertory.hpp"
#include "utils/encrypting_reader.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp"
namespace repertory {
static auto get_source_file_name() -> std::string {
return generate_test_file_name("./test_data", "encrypting_reader");
}
TEST(encrypting_reader, get_encrypted_file_name) {
const auto source_file_name = get_source_file_name();
ASSERT_TRUE(utils::file::retry_delete_file(source_file_name));
const auto token = std::string("moose");
auto source_file = create_random_file(source_file_name, 1024UL);
EXPECT_TRUE(source_file != nullptr);
if (source_file) {
stop_type stop_requested = false;
utils::encryption::encrypting_reader reader(
"test.dat", source_file_name, stop_requested, token, std::nullopt);
auto file_name = reader.get_encrypted_file_name();
EXPECT_EQ(api_error::success,
utils::encryption::decrypt_file_name(token, file_name));
EXPECT_STREQ("test.dat", file_name.c_str());
source_file->close();
}
EXPECT_TRUE(utils::file::retry_delete_file(source_file_name));
}
TEST(encrypting_reader, file_data) {
const auto source_file_name = get_source_file_name();
EXPECT_TRUE(utils::file::retry_delete_file(source_file_name));
const auto token = std::string("moose");
auto source_file = create_random_file(
source_file_name,
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
EXPECT_TRUE(source_file != nullptr);
if (source_file) {
stop_type stop_requested = false;
utils::encryption::encrypting_reader reader("test.dat", source_file_name,
stop_requested, token);
for (std::uint8_t i = 0U; i < 8U; i++) {
data_buffer buffer(
utils::encryption::encrypting_reader::get_encrypted_chunk_size());
for (std::uint8_t j = 0U; j < 2U; j++) {
EXPECT_EQ(
buffer.size() / 2U,
utils::encryption::encrypting_reader::reader_function(
reinterpret_cast<char *>(&buffer[(buffer.size() / 2U) * j]),
buffer.size() / 2U, 1U, &reader));
}
data_buffer decrypted_data;
EXPECT_TRUE(
utils::encryption::decrypt_data(token, buffer, decrypted_data));
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
decrypted_data.size());
std::size_t bytes_read{};
data_buffer file_data(decrypted_data.size());
EXPECT_TRUE(source_file->read_bytes(
file_data.data(), file_data.size(),
utils::encryption::encrypting_reader::get_data_chunk_size() * i,
bytes_read));
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
file_data.size()));
}
source_file->close();
}
EXPECT_TRUE(utils::file::retry_delete_file(source_file_name));
}
TEST(encrypting_reader, file_data_in_multiple_chunks) {
const auto source_file_name = get_source_file_name();
ASSERT_TRUE(utils::file::retry_delete_file(source_file_name));
const auto token = std::string("moose");
auto source_file = create_random_file(
source_file_name,
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
EXPECT_TRUE(source_file != nullptr);
if (source_file) {
stop_type stop_requested = false;
utils::encryption::encrypting_reader reader("test.dat", source_file_name,
stop_requested, token);
for (std::uint8_t i = 0U; i < 8U; i += 2U) {
data_buffer buffer(
utils::encryption::encrypting_reader::get_encrypted_chunk_size() *
2U);
EXPECT_EQ(buffer.size(),
utils::encryption::encrypting_reader::reader_function(
reinterpret_cast<char *>(buffer.data()), buffer.size(), 1U,
&reader));
for (std::uint8_t j = 0U; j < 2U; j++) {
data_buffer decrypted_data;
const auto offset = (j * (buffer.size() / 2U));
EXPECT_TRUE(utils::encryption::decrypt_data(
token,
data_buffer(
std::next(buffer.begin(), static_cast<std::int64_t>(offset)),
std::next(buffer.begin(), static_cast<std::int64_t>(
offset + (buffer.size() / 2U)))),
decrypted_data));
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
decrypted_data.size());
std::size_t bytes_read{};
data_buffer file_data(decrypted_data.size());
EXPECT_TRUE(source_file->read_bytes(
file_data.data(), file_data.size(),
(utils::encryption::encrypting_reader::get_data_chunk_size() * i) +
(j *
utils::encryption::encrypting_reader::get_data_chunk_size()),
bytes_read));
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
file_data.size()));
}
}
source_file->close();
}
EXPECT_TRUE(utils::file::retry_delete_file(source_file_name));
}
TEST(encrypting_reader, file_data_as_stream) {
const auto source_file_name = get_source_file_name();
ASSERT_TRUE(utils::file::retry_delete_file(source_file_name));
const auto token = std::string("moose");
auto source_file = create_random_file(
source_file_name,
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
EXPECT_TRUE(source_file != nullptr);
if (source_file) {
stop_type stop_requested = false;
utils::encryption::encrypting_reader reader("test.dat", source_file_name,
stop_requested, token);
auto io_stream = reader.create_iostream();
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail());
EXPECT_TRUE(io_stream->good());
EXPECT_EQ(reader.get_total_size(),
static_cast<std::uint64_t>(io_stream->tellg()));
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::beg).fail());
EXPECT_TRUE(io_stream->good());
for (std::uint8_t i = 0U; i < 8U; i++) {
data_buffer buffer(
utils::encryption::encrypting_reader::get_encrypted_chunk_size());
EXPECT_FALSE(
io_stream->seekg(static_cast<std::streamoff>(i * buffer.size()))
.fail());
EXPECT_TRUE(io_stream->good());
for (std::uint8_t j = 0U; j < 2U; j++) {
EXPECT_FALSE(
io_stream
->read(
reinterpret_cast<char *>(&buffer[(buffer.size() / 2U) * j]),
static_cast<std::streamsize>(buffer.size()) / 2U)
.fail());
EXPECT_TRUE(io_stream->good());
}
data_buffer decrypted_data;
EXPECT_TRUE(
utils::encryption::decrypt_data(token, buffer, decrypted_data));
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
decrypted_data.size());
std::size_t bytes_read{};
data_buffer file_data(decrypted_data.size());
EXPECT_TRUE(source_file->read_bytes(
file_data.data(), file_data.size(),
utils::encryption::encrypting_reader::get_data_chunk_size() * i,
bytes_read));
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
file_data.size()));
}
source_file->close();
}
EXPECT_TRUE(utils::file::retry_delete_file(source_file_name));
}
TEST(encrypting_reader, file_data_in_multiple_chunks_as_stream) {
const auto source_file_name = get_source_file_name();
ASSERT_TRUE(utils::file::retry_delete_file(source_file_name));
const auto token = std::string("moose");
auto source_file = create_random_file(
source_file_name,
8u * utils::encryption::encrypting_reader::get_data_chunk_size());
EXPECT_TRUE(source_file != nullptr);
if (source_file) {
stop_type stop_requested = false;
utils::encryption::encrypting_reader reader("test.dat", source_file_name,
stop_requested, token);
auto io_stream = reader.create_iostream();
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::end).fail());
EXPECT_TRUE(io_stream->good());
EXPECT_EQ(reader.get_total_size(),
static_cast<std::uint64_t>(io_stream->tellg()));
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::beg).fail());
EXPECT_TRUE(io_stream->good());
for (std::uint8_t i = 0U; i < 8U; i += 2U) {
data_buffer buffer(
utils::encryption::encrypting_reader::get_encrypted_chunk_size() *
2U);
EXPECT_FALSE(io_stream
->read(reinterpret_cast<char *>(buffer.data()),
static_cast<std::streamsize>(buffer.size()))
.fail());
EXPECT_TRUE(io_stream->good());
for (std::uint8_t j = 0U; j < 2U; j++) {
data_buffer decrypted_data;
const auto offset = (j * (buffer.size() / 2U));
EXPECT_TRUE(utils::encryption::decrypt_data(
token,
data_buffer(
std::next(buffer.begin(), static_cast<std::int64_t>(offset)),
std::next(buffer.begin(), static_cast<std::int64_t>(
offset + (buffer.size() / 2U)))),
decrypted_data));
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
decrypted_data.size());
std::size_t bytes_read{};
data_buffer file_data(decrypted_data.size());
EXPECT_TRUE(source_file->read_bytes(
file_data.data(), file_data.size(),
(utils::encryption::encrypting_reader::get_data_chunk_size() * i) +
(j *
utils::encryption::encrypting_reader::get_data_chunk_size()),
bytes_read));
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
file_data.size()));
}
}
source_file->close();
}
EXPECT_TRUE(utils::file::retry_delete_file(source_file_name));
}
} // namespace repertory

View File

@@ -55,7 +55,7 @@ static void validate_write(file_manager::open_file &o, std::size_t offset,
TEST(open_file, properly_initializes_state_for_0_byte_file) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp;
mock_upload_manager um;
@@ -76,7 +76,7 @@ TEST(open_file, properly_initializes_state_for_0_byte_file) {
TEST(open_file, properly_initializes_state_based_on_chunk_size) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp;
mock_upload_manager um;
@@ -109,7 +109,7 @@ TEST(open_file, properly_initializes_state_based_on_chunk_size) {
TEST(open_file, will_not_change_source_path_for_0_byte_file) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp;
mock_upload_manager um;
@@ -128,12 +128,12 @@ TEST(open_file, will_not_change_source_path_for_0_byte_file) {
o.close();
EXPECT_EQ(api_error::success, o.get_api_error());
EXPECT_STREQ(source_path.c_str(), o.get_source_path().c_str());
EXPECT_TRUE(utils::file::is_file(fsi.source_path));
EXPECT_TRUE(utils::file::file(fsi.source_path).exists());
}
TEST(open_file, will_change_source_path_if_file_size_is_greater_than_0) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp;
mock_upload_manager um;
@@ -166,14 +166,14 @@ TEST(open_file, will_change_source_path_if_file_size_is_greater_than_0) {
o.close();
EXPECT_EQ(api_error::download_stopped, o.get_api_error());
EXPECT_STRNE(source_path.c_str(), o.get_source_path().c_str());
EXPECT_FALSE(utils::file::is_file(source_path));
EXPECT_FALSE(utils::file::file(source_path).exists());
}
TEST(open_file,
will_not_change_source_path_if_file_size_matches_existing_source) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
create_random_file(source_path, test_chunk_size)->close();
auto &rf = test::create_random_file(test_chunk_size);
const auto source_path = rf.get_path();
rf.close();
mock_provider mp;
mock_upload_manager um;
@@ -192,15 +192,12 @@ TEST(open_file,
o.close();
EXPECT_EQ(api_error::success, o.get_api_error());
EXPECT_STREQ(source_path.c_str(), o.get_source_path().c_str());
EXPECT_TRUE(utils::file::is_file(source_path));
EXPECT_TRUE(utils::file::file(source_path).exists());
}
TEST(open_file, write_with_incomplete_download) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
auto nf = create_random_file(
generate_test_file_name("./test_config", "file_manager_open_file_test"),
test_chunk_size * 2u);
const auto source_path = test::generate_test_file_name("test");
auto &nf = test::create_random_file(test_chunk_size * 2u);
mock_provider mp;
mock_upload_manager um;
@@ -236,9 +233,8 @@ TEST(open_file, write_with_incomplete_download) {
if (offset == 0u) {
std::size_t bytes_read{};
data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read)
? api_error::success
: api_error::os_error;
auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size());
return ret;
}
@@ -278,18 +274,18 @@ TEST(open_file, write_with_incomplete_download) {
test_state();
o.close();
nf->close();
nf.close();
test_state();
EXPECT_EQ(api_error::download_incomplete, o.get_api_error());
EXPECT_TRUE(utils::file::is_file(fsi.source_path));
EXPECT_TRUE(utils::file::file(fsi.source_path).exists());
}
TEST(open_file, write_new_file) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp;
mock_upload_manager um;
@@ -357,12 +353,12 @@ TEST(open_file, write_new_file) {
EXPECT_EQ(api_error::success, o.get_api_error());
EXPECT_TRUE(utils::file::is_file(fsi.source_path));
EXPECT_TRUE(utils::file::file(fsi.source_path).exists());
}
TEST(open_file, write_new_file_multiple_chunks) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp;
mock_upload_manager um;
@@ -449,13 +445,13 @@ TEST(open_file, write_new_file_multiple_chunks) {
EXPECT_EQ(api_error::success, o.get_api_error());
EXPECT_TRUE(utils::file::is_file(fsi.source_path));
EXPECT_TRUE(utils::file::file(fsi.source_path).exists());
}
TEST(open_file, resize_file_to_0_bytes) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
create_random_file(source_path, test_chunk_size * 4u)->close();
auto &rf = test::create_random_file(test_chunk_size * 4u);
const auto source_path = rf.get_path();
rf.close();
mock_provider mp;
mock_upload_manager um;
@@ -503,9 +499,9 @@ TEST(open_file, resize_file_to_0_bytes) {
}
TEST(open_file, resize_file_by_full_chunk) {
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
create_random_file(source_path, test_chunk_size * 4u)->close();
auto &rf = test::create_random_file(test_chunk_size * 4u);
const auto source_path = rf.get_path();
rf.close();
mock_provider mp;
mock_upload_manager um;
@@ -556,7 +552,7 @@ TEST(open_file, can_add_handle) {
event_system::instance().start();
console_consumer c;
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp;
mock_upload_manager um;
@@ -618,7 +614,7 @@ TEST(open_file, can_remove_handle) {
console_consumer c;
const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test");
test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp;
mock_upload_manager um;

View File

@@ -31,11 +31,11 @@
namespace repertory {
static constexpr const std::size_t test_chunk_size = 1024u;
static std::string ring_buffer_dir = utils::path::combine(
"./test_config", {"file_manager_ring_buffer_open_file_test"});
test::get_test_output_dir(), {"file_manager_ring_buffer_open_file_test"});
TEST(ring_buffer_open_file, can_forward_to_last_chunk) {
const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -61,13 +61,13 @@ TEST(ring_buffer_open_file, can_forward_to_last_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file,
can_forward_to_last_chunk_if_count_is_greater_than_remaining) {
const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -93,12 +93,12 @@ TEST(ring_buffer_open_file,
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, can_forward_after_last_chunk) {
const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -125,12 +125,12 @@ TEST(ring_buffer_open_file, can_forward_after_last_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, can_forward_and_rollover_after_last_chunk) {
const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -153,12 +153,12 @@ TEST(ring_buffer_open_file, can_forward_and_rollover_after_last_chunk) {
EXPECT_EQ(std::size_t(28u), rb.get_last_chunk());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, can_reverse_to_first_chunk) {
const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -184,13 +184,13 @@ TEST(ring_buffer_open_file, can_reverse_to_first_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file,
can_reverse_to_first_chunk_if_count_is_greater_than_remaining) {
const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -216,12 +216,12 @@ TEST(ring_buffer_open_file,
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, can_reverse_before_first_chunk) {
const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -248,12 +248,12 @@ TEST(ring_buffer_open_file, can_reverse_before_first_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, can_reverse_and_rollover_before_first_chunk) {
const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -284,12 +284,12 @@ TEST(ring_buffer_open_file, can_reverse_and_rollover_before_first_chunk) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, can_reverse_full_ring) {
const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -316,16 +316,14 @@ TEST(ring_buffer_open_file, can_reverse_full_ring) {
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, read_full_file) {
const auto download_source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
auto nf = create_random_file(download_source_path, test_chunk_size * 32u);
auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path();
const auto dest_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
const auto dest_path = test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -335,8 +333,7 @@ TEST(ring_buffer_open_file, read_full_file) {
fsi.directory = false;
fsi.api_path = "/test.txt";
fsi.size = test_chunk_size * 32u;
fsi.source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
fsi.source_path = test::generate_test_file_name("ring_buffer_open_file");
EXPECT_CALL(mp, read_file_bytes)
.WillRepeatedly([&nf](const std::string & /* api_path */,
@@ -346,9 +343,8 @@ TEST(ring_buffer_open_file, read_full_file) {
EXPECT_FALSE(stop_requested);
std::size_t bytes_read{};
data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read)
? api_error::success
: api_error::os_error;
auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size());
return ret;
});
@@ -356,8 +352,9 @@ TEST(ring_buffer_open_file, read_full_file) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u);
native_file_ptr nf2;
EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path, nf2));
auto ptr = utils::file::file::open_or_create_file(dest_path);
auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
auto to_read = fsi.size;
std::size_t chunk = 0u;
@@ -367,28 +364,31 @@ TEST(ring_buffer_open_file, read_full_file) {
rb.read(test_chunk_size, chunk * test_chunk_size, data));
std::size_t bytes_written{};
EXPECT_TRUE(nf2->write_bytes(data.data(), data.size(),
chunk * test_chunk_size, bytes_written));
EXPECT_TRUE(nf2.write(data, chunk * test_chunk_size, &bytes_written));
chunk++;
to_read -= data.size();
}
nf2->close();
nf->close();
nf2.close();
nf.close();
EXPECT_STREQ(utils::file::generate_sha256(download_source_path).c_str(),
utils::file::generate_sha256(dest_path).c_str());
auto hash1 = utils::file::file(download_source_path).sha256();
auto hash2 = utils::file::file(dest_path).sha256();
EXPECT_TRUE(hash1.has_value());
EXPECT_TRUE(hash2.has_value());
if (hash1.has_value() && hash2.has_value()) {
EXPECT_STREQ(hash1.value().c_str(), hash2.value().c_str());
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, read_full_file_in_reverse) {
const auto download_source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
auto nf = create_random_file(download_source_path, test_chunk_size * 32u);
auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path();
const auto dest_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
const auto dest_path = test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -398,8 +398,7 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
fsi.directory = false;
fsi.api_path = "/test.txt";
fsi.size = test_chunk_size * 32u;
fsi.source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
fsi.source_path = test::generate_test_file_name("ring_buffer_open_file");
EXPECT_CALL(mp, read_file_bytes)
.WillRepeatedly([&nf](const std::string & /* api_path */,
@@ -409,9 +408,8 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
EXPECT_FALSE(stop_requested);
std::size_t bytes_read{};
data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read)
? api_error::success
: api_error::os_error;
auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size());
return ret;
});
@@ -419,8 +417,9 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u);
native_file_ptr nf2;
EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path, nf2));
auto ptr = utils::file::file::open_or_create_file(dest_path);
auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
auto to_read = fsi.size;
std::size_t chunk = rb.get_total_chunks() - 1u;
@@ -430,28 +429,31 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
rb.read(test_chunk_size, chunk * test_chunk_size, data));
std::size_t bytes_written{};
EXPECT_TRUE(nf2->write_bytes(data.data(), data.size(),
chunk * test_chunk_size, bytes_written));
EXPECT_TRUE(nf2.write(data, chunk * test_chunk_size, &bytes_written));
chunk--;
to_read -= data.size();
}
nf2->close();
nf->close();
nf2.close();
nf.close();
EXPECT_STREQ(utils::file::generate_sha256(download_source_path).c_str(),
utils::file::generate_sha256(dest_path).c_str());
auto hash1 = utils::file::file(download_source_path).sha256();
auto hash2 = utils::file::file(dest_path).sha256();
EXPECT_TRUE(hash1.has_value());
EXPECT_TRUE(hash2.has_value());
if (hash1.has_value() && hash2.has_value()) {
EXPECT_STREQ(hash1.value().c_str(), hash2.value().c_str());
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
const auto download_source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
auto nf = create_random_file(download_source_path, test_chunk_size * 32u);
auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path();
const auto dest_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
const auto dest_path = test::generate_test_file_name("test");
mock_provider mp;
@@ -461,8 +463,7 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
fsi.directory = false;
fsi.api_path = "/test.txt";
fsi.size = test_chunk_size * 32u;
fsi.source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
fsi.source_path = test::generate_test_file_name("test");
EXPECT_CALL(mp, read_file_bytes)
.WillRepeatedly([&nf](const std::string & /* api_path */,
@@ -472,9 +473,8 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
EXPECT_FALSE(stop_requested);
std::size_t bytes_read{};
data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read)
? api_error::success
: api_error::os_error;
auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size());
return ret;
});
@@ -482,8 +482,11 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u);
native_file_ptr nf2;
EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path, nf2));
auto ptr = utils::file::file::open_or_create_file(dest_path);
auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
// EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path,
// nf2));
auto total_read = std::uint64_t(0u);
@@ -492,27 +495,31 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
EXPECT_EQ(api_error::success, rb.read(3u, total_read, data));
std::size_t bytes_written{};
EXPECT_TRUE(nf2->write_bytes(data.data(), data.size(), total_read,
bytes_written));
EXPECT_TRUE(
nf2.write(data.data(), data.size(), total_read, &bytes_written));
total_read += data.size();
}
nf2->close();
nf->close();
nf2.close();
nf.close();
EXPECT_STREQ(utils::file::generate_sha256(download_source_path).c_str(),
utils::file::generate_sha256(dest_path).c_str());
auto hash1 = utils::file::file(download_source_path).sha256();
auto hash2 = utils::file::file(dest_path).sha256();
EXPECT_TRUE(hash1.has_value());
EXPECT_TRUE(hash2.has_value());
if (hash1.has_value() && hash2.has_value()) {
EXPECT_STREQ(hash1.value().c_str(), hash2.value().c_str());
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
const auto download_source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
auto nf = create_random_file(download_source_path, test_chunk_size * 32u);
auto &nf = test::create_random_file(test_chunk_size * 32u);
const auto download_source_path = nf.get_path();
const auto dest_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
const auto dest_path = test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp;
@@ -522,8 +529,7 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
fsi.directory = false;
fsi.api_path = "/test.txt";
fsi.size = test_chunk_size * 32u;
fsi.source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file");
fsi.source_path = test::generate_test_file_name("ring_buffer_open_file");
EXPECT_CALL(mp, read_file_bytes)
.WillRepeatedly([&nf](const std::string & /* api_path */,
@@ -533,9 +539,8 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
EXPECT_FALSE(stop_requested);
std::size_t bytes_read{};
data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read)
? api_error::success
: api_error::os_error;
auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size());
return ret;
});
@@ -543,11 +548,12 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u);
native_file_ptr nf2;
EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path, nf2));
auto ptr = utils::file::file::open_or_create_file(dest_path);
auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
auto total_read = std::uint64_t(0u);
const auto read_size = 3u;
std::uint64_t total_read{0U};
const auto read_size{3U};
while (total_read < fsi.size) {
const auto offset = fsi.size - total_read - read_size;
@@ -560,18 +566,23 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
(remain >= read_size) ? offset : 0u, data));
std::size_t bytes_written{};
EXPECT_TRUE(nf2->write_bytes(data.data(), data.size(),
(remain >= read_size) ? offset : 0u,
bytes_written));
EXPECT_TRUE(
nf2.write(data, (remain >= read_size) ? offset : 0u, &bytes_written));
total_read += data.size();
}
nf2->close();
nf->close();
nf2.close();
nf.close();
EXPECT_STREQ(utils::file::generate_sha256(download_source_path).c_str(),
utils::file::generate_sha256(dest_path).c_str());
auto hash1 = utils::file::file(download_source_path).sha256();
auto hash2 = utils::file::file(dest_path).sha256();
EXPECT_TRUE(hash1.has_value());
EXPECT_TRUE(hash2.has_value());
if (hash1.has_value() && hash2.has_value()) {
EXPECT_STREQ(hash1.value().c_str(), hash2.value().c_str());
}
}
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir));
EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
}
} // namespace repertory

View File

@@ -34,7 +34,6 @@
#include "utils/encrypting_reader.hpp"
#include "utils/event_capture.hpp"
#include "utils/file_utils.hpp"
#include "utils/native_file.hpp"
#include "utils/path.hpp"
#include "utils/polling.hpp"
#include "utils/string.hpp"
@@ -43,7 +42,7 @@
namespace repertory {
static std::string file_manager_dir =
utils::path::combine("./test_config", {"file_manager_test"});
utils::path::combine(test::get_test_output_dir(), {"file_manager_test"});
auto file_manager::open(std::shared_ptr<i_closeable_open_file> of,
const open_file_data &ofd, std::uint64_t &handle,
@@ -85,7 +84,7 @@ TEST(file_manager, can_start_and_stop) {
}
event_system::instance().stop();
// EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
// EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
}
TEST(file_manager, can_create_and_close_file) {
@@ -118,7 +117,7 @@ TEST(file_manager, can_create_and_close_file) {
{
std::shared_ptr<i_open_file> f;
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u,
now + 2u, false, 1, "key", 2, now + 3u, 3u, 4u, 0u, source_path, 10,
@@ -202,7 +201,7 @@ TEST(file_manager, can_create_and_close_file) {
polling::instance().stop();
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, can_open_and_close_file) {
@@ -233,7 +232,7 @@ TEST(file_manager, can_open_and_close_file) {
std::uint64_t handle{};
{
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u,
now + 2u, false, 1, "key", 2, now + 3u, 3u, 4u, 0u, source_path, 10,
@@ -318,7 +317,7 @@ TEST(file_manager, can_open_and_close_file) {
polling::instance().stop();
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
@@ -340,7 +339,7 @@ TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
const auto source_path = utils::path::combine(
cfg.get_cache_directory(), {utils::create_uuid_string()});
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u,
now + 2u, false, 1, "key", 2, now + 3u, 3u, 4u, 0u, source_path, 10,
@@ -391,7 +390,7 @@ TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
polling::instance().stop();
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
@@ -420,15 +419,14 @@ TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
event_capture ec({"download_stored"},
{"file_upload_completed", "file_upload_queued"});
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
false, 1, "key", 2, now + 3u, 3u, 4u,
utils::encryption::encrypting_reader::get_data_chunk_size() * 4u,
source_path, 10, now + 4u);
auto nf = create_random_file(
generate_test_file_name("./test_config", "file_manage_test"),
utils::string::to_uint64(meta[META_SIZE]));
auto &nf =
test::create_random_file(utils::string::to_uint64(meta[META_SIZE]));
EXPECT_CALL(mp, get_filesystem_item)
.WillRepeatedly([&meta](const std::string &api_path, bool directory,
@@ -465,9 +463,8 @@ TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
if (offset == 0u) {
std::size_t bytes_read{};
data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read)
? api_error::success
: api_error::os_error;
auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size());
return ret;
}
@@ -542,11 +539,11 @@ TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
EXPECT_EQ(std::size_t(0u), fm.get_open_file_count());
EXPECT_EQ(std::size_t(0u), fm.get_open_handle_count());
nf->close();
nf.close();
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
@@ -583,15 +580,14 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
});
event_capture ec({"download_end"});
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
false, 1, "key", 2, now + 3u, 3u, 4u,
utils::encryption::encrypting_reader::get_data_chunk_size() * 4u,
source_path, 10, now + 4u);
auto nf = create_random_file(
generate_test_file_name("./test_config", "file_manage_test"),
utils::string::to_uint64(meta[META_SIZE]));
auto &nf =
test::create_random_file(utils::string::to_uint64(meta[META_SIZE]));
EXPECT_CALL(mp, get_filesystem_item)
.WillRepeatedly([&meta](const std::string &api_path, bool directory,
@@ -623,9 +619,8 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
stop_type & /* stop_requested */) -> api_error {
std::size_t bytes_read{};
data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read)
? api_error::success
: api_error::os_error;
auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size());
return ret;
});
@@ -660,16 +655,16 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
fm.stop();
nf->close();
nf.close();
}
polling::instance().stop();
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, can_evict_file) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
console_consumer c;
event_system::instance().start();
@@ -694,7 +689,7 @@ TEST(file_manager, can_evict_file) {
const auto source_path = utils::path::combine(
cfg.get_cache_directory(), {utils::create_uuid_string()});
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
@@ -735,15 +730,15 @@ TEST(file_manager, can_evict_file) {
std::size_t bytes_written{};
EXPECT_EQ(api_error::success, f->write(0U, data, bytes_written));
std::uint64_t file_size{};
EXPECT_TRUE(utils::file::get_file_size(source_path, file_size));
EXPECT_EQ(static_cast<std::uint64_t>(data.size()), file_size);
auto opt_size = utils::file::file{source_path}.size();
EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(static_cast<std::uint64_t>(data.size()), opt_size.value());
}
fm.close(handle);
capture.wait_for_empty();
EXPECT_TRUE(utils::retryable_action(
EXPECT_TRUE(utils::retry_action(
[&fm]() -> bool { return not fm.is_processing("/test_evict.txt"); }));
EXPECT_CALL(mp, get_item_meta(_, META_SOURCE, _))
@@ -764,17 +759,17 @@ TEST(file_manager, can_evict_file) {
return api_error::success;
});
EXPECT_TRUE(fm.evict_file("/test_evict.txt"));
EXPECT_FALSE(utils::file::is_file(source_path));
EXPECT_FALSE(utils::file::file(source_path).exists());
fm.stop();
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, evict_file_fails_if_file_is_pinned) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
cfg.set_enable_chunk_downloader_timeout(false);
@@ -796,11 +791,11 @@ TEST(file_manager, evict_file_fails_if_file_is_pinned) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, evict_file_fails_if_provider_is_direct_only) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -812,11 +807,11 @@ TEST(file_manager, evict_file_fails_if_provider_is_direct_only) {
EXPECT_FALSE(fm.evict_file("/test.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, evict_file_fails_if_file_is_open) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -862,12 +857,12 @@ TEST(file_manager, evict_file_fails_if_file_is_open) {
fm.close(handle);
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager,
evict_file_fails_if_unable_to_get_source_path_from_item_meta) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -897,11 +892,11 @@ TEST(file_manager,
EXPECT_FALSE(fm.evict_file("/test_open.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, evict_file_fails_if_source_path_is_empty) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -931,11 +926,11 @@ TEST(file_manager, evict_file_fails_if_source_path_is_empty) {
EXPECT_FALSE(fm.evict_file("/test_open.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, evict_file_fails_if_file_is_uploading) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
console_consumer c;
event_system::instance().start();
@@ -960,7 +955,7 @@ TEST(file_manager, evict_file_fails_if_file_is_uploading) {
const auto source_path = utils::path::combine(
cfg.get_cache_directory(), {utils::create_uuid_string()});
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
@@ -1008,29 +1003,30 @@ TEST(file_manager, evict_file_fails_if_file_is_uploading) {
std::size_t bytes_written{};
EXPECT_EQ(api_error::success, f->write(0U, data, bytes_written));
std::uint64_t file_size{};
EXPECT_TRUE(utils::file::get_file_size(source_path, file_size));
EXPECT_EQ(static_cast<std::uint64_t>(data.size()), file_size);
auto opt_size = utils::file::file{source_path}.size();
EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(static_cast<std::uint64_t>(data.size()), opt_size.value());
fm.close(handle);
EXPECT_TRUE(utils::retryable_action(
EXPECT_TRUE(utils::retry_action(
[&fm]() -> bool { return fm.is_processing("/test_evict.txt"); }));
EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
}
capture.wait_for_empty();
EXPECT_TRUE(utils::file::is_file(source_path));
EXPECT_TRUE(utils::file::file(source_path).exists());
fm.stop();
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, evict_file_fails_if_file_is_in_upload_queue) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1051,11 +1047,11 @@ TEST(file_manager, evict_file_fails_if_file_is_in_upload_queue) {
EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, evict_file_fails_if_file_is_modified) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1097,11 +1093,11 @@ TEST(file_manager, evict_file_fails_if_file_is_modified) {
EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, evict_file_fails_if_file_is_not_complete) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1145,11 +1141,11 @@ TEST(file_manager, evict_file_fails_if_file_is_not_complete) {
EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, can_get_directory_items) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1179,11 +1175,11 @@ TEST(file_manager, can_get_directory_items) {
EXPECT_EQ(std::size_t(2U), list.size());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, file_is_not_opened_if_provider_create_file_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1192,7 +1188,7 @@ TEST(file_manager, file_is_not_opened_if_provider_create_file_fails) {
EXPECT_CALL(mp, is_direct_only()).WillRepeatedly(Return(false));
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
false, 1, "", 2, now + 3u, 3u, 4u, 0u, "/test_create.src", 10,
@@ -1215,11 +1211,11 @@ TEST(file_manager, file_is_not_opened_if_provider_create_file_fails) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, create_fails_if_provider_create_is_unsuccessful) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1246,12 +1242,12 @@ TEST(file_manager, create_fails_if_provider_create_is_unsuccessful) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, get_open_file_fails_if_file_is_not_open) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1270,12 +1266,12 @@ TEST(file_manager, get_open_file_fails_if_file_is_not_open) {
EXPECT_FALSE(f);
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager,
get_open_file_promotes_non_writeable_file_if_writeable_is_specified) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1355,11 +1351,11 @@ TEST(file_manager,
EXPECT_EQ(std::size_t(1U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, open_file_fails_if_file_is_not_found) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1380,11 +1376,11 @@ TEST(file_manager, open_file_fails_if_file_is_not_found) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, open_file_fails_if_provider_get_filesystem_item_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1424,11 +1420,11 @@ TEST(file_manager, open_file_fails_if_provider_get_filesystem_item_fails) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, open_file_fails_if_provider_set_item_meta_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1475,11 +1471,11 @@ TEST(file_manager, open_file_fails_if_provider_set_item_meta_fails) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, open_file_creates_source_path_if_empty) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1538,11 +1534,11 @@ TEST(file_manager, open_file_creates_source_path_if_empty) {
EXPECT_EQ(std::size_t(1U), fm.get_open_file_count());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, open_file_first_file_handle_is_not_zero) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1586,11 +1582,11 @@ TEST(file_manager, open_file_first_file_handle_is_not_zero) {
EXPECT_GT(handle, std::uint64_t(0U));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, can_remove_file) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1601,11 +1597,11 @@ TEST(file_manager, can_remove_file) {
file_manager fm(cfg, mp);
native_file::native_file_ptr f{};
EXPECT_EQ(api_error::success,
native_file::create_or_open("./test_remove.txt", f));
f->close();
EXPECT_TRUE(utils::file::is_file("./test_remove.txt"));
{
auto file = utils::file::file::open_or_create_file("./test_remove.txt");
EXPECT_TRUE(*file);
}
EXPECT_TRUE(utils::file::file("./test_remove.txt").exists());
EXPECT_CALL(mp, get_filesystem_item)
.WillOnce([](const std::string &api_path, bool directory,
@@ -1624,14 +1620,14 @@ TEST(file_manager, can_remove_file) {
EXPECT_EQ(api_error::success, fm.remove_file("/test_remove.txt"));
EXPECT_FALSE(utils::file::is_file("./test_remove.txt"));
EXPECT_FALSE(utils::file::file("./test_remove.txt").exists());
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, can_queue_and_remove_upload) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
console_consumer c;
event_system::instance().start();
@@ -1662,11 +1658,11 @@ TEST(file_manager, can_queue_and_remove_upload) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, remove_file_fails_if_open_file_is_modified) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1716,7 +1712,7 @@ TEST(file_manager, remove_file_fails_if_open_file_is_modified) {
EXPECT_EQ(api_error::file_in_use, fm.remove_file("/test_remove.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, file_is_closed_after_download_timeout) {
@@ -1744,7 +1740,7 @@ TEST(file_manager, file_is_closed_after_download_timeout) {
ee.get_api_path().get<std::string>().c_str());
});
const auto now = utils::time::get_file_time_now();
const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
false, 1, "key", 2, now + 3u, 3u, 4u,
@@ -1814,11 +1810,11 @@ TEST(file_manager, file_is_closed_after_download_timeout) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, remove_file_fails_if_file_does_not_exist) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
cfg.set_enable_chunk_downloader_timeout(false);
@@ -1839,11 +1835,11 @@ TEST(file_manager, remove_file_fails_if_file_does_not_exist) {
EXPECT_EQ(api_error::item_not_found, fm.remove_file("/test_remove.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
TEST(file_manager, remove_file_fails_if_provider_remove_file_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{
app_config cfg(provider_type::sia, file_manager_dir);
@@ -1871,6 +1867,6 @@ TEST(file_manager, remove_file_fails_if_provider_remove_file_fails) {
EXPECT_EQ(api_error::item_not_found, fm.remove_file("/test_remove.txt"));
}
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir));
EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
}
} // namespace repertory

View File

@@ -35,8 +35,7 @@ TEST(upload, can_upload_a_valid_file) {
event_system::instance().start();
const auto source_path =
generate_test_file_name("./test_config", "upload_test");
const auto source_path = test::generate_test_file_name("upload_test");
mock_provider mp;
@@ -79,8 +78,7 @@ TEST(upload, can_cancel_upload) {
event_system::instance().start();
const auto source_path =
generate_test_file_name("./test_config", "upload_test");
const auto source_path = test::generate_test_file_name("upload_test");
mock_provider mp;
@@ -145,8 +143,7 @@ TEST(upload, can_stop_upload) {
event_system::instance().start();
const auto source_path =
generate_test_file_name("./test_config", "upload_test");
const auto source_path = test::generate_test_file_name("upload_test");
mock_provider mp;

File diff suppressed because it is too large Load Diff

View File

@@ -57,7 +57,7 @@ const auto check_forced_dirs = [](const repertory::directory_item_list &list) {
const auto create_directory = [](repertory::i_provider &provider,
const std::string &api_path) {
auto date = repertory::utils::time::get_file_time_now();
auto date = repertory::utils::time::get_time_now();
auto meta = repertory::create_meta_attributes(
date, 1U, date + 1U, date + 2U, true, getgid(), "", 0700, date + 3U, 2U,
3U, 0U, api_path + "_src", getuid(), date + 4U);
@@ -107,10 +107,9 @@ const auto create_directory = [](repertory::i_provider &provider,
const auto create_file = [](repertory::i_provider &provider,
const std::string &api_path) {
auto source_path =
repertory::generate_test_file_name("./test_config", "providers_test");
auto source_path = repertory::test::generate_test_file_name("providers_test");
auto date = repertory::utils::time::get_file_time_now();
auto date = repertory::utils::time::get_time_now();
auto meta = repertory::create_meta_attributes(
date, 1U, date + 1U, date + 2U, false, getgid(), "", 0700, date + 3U, 2U,
3U, 0U, source_path, getuid(), date + 4U);
@@ -121,7 +120,7 @@ const auto create_file = [](repertory::i_provider &provider,
EXPECT_EQ(repertory::api_error::success, provider.is_file(api_path, exists));
EXPECT_TRUE(exists);
EXPECT_TRUE(repertory::utils::file::delete_file(source_path));
EXPECT_TRUE(repertory::utils::file::file{source_path}.remove());
repertory::api_meta_map meta2{};
EXPECT_EQ(repertory::api_error::success,
@@ -167,9 +166,8 @@ const auto decrypt_parts = [](const repertory::app_config &cfg,
continue;
}
EXPECT_EQ(repertory::api_error::success,
repertory::utils::encryption::decrypt_file_name(
cfg.get_encrypt_config().encryption_token, part));
EXPECT_EQ(true, repertory::utils::encryption::decrypt_file_name(
cfg.get_encrypt_config().encryption_token, part));
}
path = repertory::utils::string::join(parts, '/');
}
@@ -398,7 +396,7 @@ static void get_directory_item_count(const app_config &cfg,
EXPECT_EQ(std::size_t(0U), provider.get_directory_item_count("/not_found"));
const auto source_path =
utils::path::combine("./test_data/encrypt", {"sub10"});
utils::path::combine(test::get_test_input_dir(), {"encrypt", "sub10"});
std::string api_path{};
EXPECT_EQ(api_error::success,
@@ -630,8 +628,8 @@ static void run_tests(const app_config &cfg, i_provider &provider) {
TEST(providers, encrypt_provider) {
const auto config_path =
utils::path::combine("./test_config", {"encrypt_provider"});
ASSERT_TRUE(utils::file::delete_directory_recursively(config_path));
utils::path::combine(test::get_test_output_dir(), {"encrypt_provider"});
ASSERT_TRUE(utils::file::directory(config_path).remove_recursively());
console_consumer consumer{};
event_system::instance().start();
@@ -639,7 +637,7 @@ TEST(providers, encrypt_provider) {
app_config cfg(provider_type::encrypt, config_path);
const auto encrypt_path =
utils::path::combine("./test_data/encrypt", {"encrypt"});
utils::path::combine(test::get_test_input_dir(), {"encrypt"});
EXPECT_STREQ(
encrypt_path.c_str(),
@@ -673,16 +671,17 @@ TEST(providers, encrypt_provider) {
TEST(providers, s3_provider) {
const auto config_path =
utils::path::combine("./test_config", {"s3_provider"});
ASSERT_TRUE(utils::file::delete_directory_recursively(config_path));
utils::path::combine(test::get_test_output_dir(), {"s3_provider"});
ASSERT_TRUE(utils::file::directory(config_path).remove_recursively());
console_consumer consumer{};
event_system::instance().start();
{
app_config cfg(provider_type::s3, config_path);
{
app_config src_cfg(provider_type::s3,
utils::path::combine(get_test_dir(), {"storj"}));
app_config src_cfg(
provider_type::s3,
utils::path::combine(test::get_test_input_dir(), {"storj"}));
cfg.set_s3_config(src_cfg.get_s3_config());
}
@@ -711,16 +710,17 @@ TEST(providers, s3_provider) {
TEST(providers, sia_provider) {
const auto config_path =
utils::path::combine("./test_config", {"sia_provider"});
ASSERT_TRUE(utils::file::delete_directory_recursively(config_path));
utils::path::combine(test::get_test_output_dir(), {"sia_provider"});
ASSERT_TRUE(utils::file::directory(config_path).remove_recursively());
console_consumer consumer{};
event_system::instance().start();
{
app_config cfg(provider_type::sia, config_path);
{
app_config src_cfg(provider_type::sia,
utils::path::combine(get_test_dir(), {"sia"}));
app_config src_cfg(
provider_type::sia,
utils::path::combine(test::get_test_input_dir(), {"sia"}));
cfg.set_host_config(src_cfg.get_host_config());
}

View File

@@ -47,12 +47,12 @@ using namespace repertory::remote_fuse;
namespace fuse_test {
static std::string mount_location_;
static std::string fuse_remote_dir =
utils::path::combine("./test_config", {"fuse_remote_test"});
utils::path::combine(test::get_test_output_dir(), {"fuse_remote_test"});
static void access_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir, {"access.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -64,13 +64,13 @@ static void access_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_access(api_path.c_str(), 0));
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void chflags_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir, {"chflags.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -86,13 +86,13 @@ static void chflags_test(repertory::remote_fuse::remote_client &client) {
#endif
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void chmod_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir, {"chmod.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -108,13 +108,13 @@ static void chmod_test(repertory::remote_fuse::remote_client &client) {
#endif
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void chown_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir, {"chown.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -134,7 +134,7 @@ static void chown_test(repertory::remote_fuse::remote_client &client) {
#endif
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void
@@ -143,7 +143,7 @@ create_and_release_test(repertory::remote_fuse::remote_client &client,
const auto test_file =
utils::path::combine(fuse_remote_dir, {"create_and_release.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -156,7 +156,7 @@ create_and_release_test(repertory::remote_fuse::remote_client &client,
EXPECT_EQ(0u, server.get_open_file_count(test_file));
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void destroy_test(repertory::remote_fuse::remote_client &client) {
@@ -167,7 +167,7 @@ static void destroy_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir,
{"fallocate.txt"}); const auto api_path =
test_file.substr(mount_location_.size());
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -181,14 +181,14 @@ remote::open_flags::ReadWrite, handle); EXPECT_EQ(0, ret); if (ret == 0) {
EXPECT_EQ(100, file_size);
}
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
}*/
static void fgetattr_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"fgetattr.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -219,23 +219,23 @@ static void fgetattr_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(st1.st_nlink, st.st_nlink);
EXPECT_EQ(st1.st_mode, st.st_mode);
EXPECT_LE(static_cast<remote::file_time>(st1.st_atime),
st.st_atimespec / NANOS_PER_SECOND);
st.st_atimespec / utils::time::NANOS_PER_SECOND);
EXPECT_EQ(static_cast<remote::file_time>(st1.st_mtime),
st.st_mtimespec / NANOS_PER_SECOND);
st.st_mtimespec / utils::time::NANOS_PER_SECOND);
EXPECT_EQ(static_cast<remote::file_time>(st1.st_ctime),
st.st_ctimespec / NANOS_PER_SECOND);
st.st_ctimespec / utils::time::NANOS_PER_SECOND);
EXPECT_EQ(static_cast<remote::file_time>(st1.st_ctime),
st.st_birthtimespec / NANOS_PER_SECOND);
st.st_birthtimespec / utils::time::NANOS_PER_SECOND);
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void fsetattr_x_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"fsetattr_x.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -253,13 +253,13 @@ static void fsetattr_x_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void fsync_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir, {"fsync.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -271,14 +271,14 @@ static void fsync_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void ftruncate_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"ftruncate.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -289,18 +289,18 @@ static void ftruncate_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_ftruncate(api_path.c_str(), 100, handle));
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
std::uint64_t file_size;
EXPECT_TRUE(utils::file::get_file_size(test_file, file_size));
EXPECT_EQ(100u, file_size);
auto opt_size = utils::file::file{test_file}.size();
EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(100U, opt_size.value());
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void getattr_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir, {"getattr.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -330,23 +330,23 @@ static void getattr_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(st1.st_nlink, st.st_nlink);
EXPECT_EQ(st1.st_mode, st.st_mode);
EXPECT_LE(static_cast<remote::file_time>(st1.st_atime),
st.st_atimespec / NANOS_PER_SECOND);
st.st_atimespec / utils::time::NANOS_PER_SECOND);
EXPECT_EQ(static_cast<remote::file_time>(st1.st_mtime),
st.st_mtimespec / NANOS_PER_SECOND);
st.st_mtimespec / utils::time::NANOS_PER_SECOND);
EXPECT_EQ(static_cast<remote::file_time>(st1.st_ctime),
st.st_ctimespec / NANOS_PER_SECOND);
st.st_ctimespec / utils::time::NANOS_PER_SECOND);
EXPECT_EQ(static_cast<remote::file_time>(st1.st_ctime),
st.st_birthtimespec / NANOS_PER_SECOND);
st.st_birthtimespec / utils::time::NANOS_PER_SECOND);
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
/*static void getxattr_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir,
{"getxattr.txt"}); const auto api_path =
test_file.substr(mount_location_.size());
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -359,14 +359,14 @@ nullptr, 0)); #else EXPECT_EQ(-EACCES, client.fuse_getxattr(api_path.c_str(),
"test", nullptr, 0)); #endif
}
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
}
static void getxattr_osx_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir,
{"getxattr_osx.txt"}); const auto api_path =
test_file.substr(mount_location_.size());
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -377,14 +377,14 @@ remote::open_flags::ReadWrite, handle); EXPECT_EQ(0, ret); if (ret == 0) {
client.fuse_getxattrOSX(api_path.c_str(), "test", nullptr, 0, 0));
}
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
}*/
static void getxtimes_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"getxtimes.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -403,7 +403,7 @@ static void getxtimes_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void init_test(repertory::remote_fuse::remote_client &client) {
@@ -414,7 +414,7 @@ static void init_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir,
{"listxattr.txt"}); const auto api_path =
test_file.substr(mount_location_.size());
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -427,29 +427,29 @@ remote::open_flags::ReadWrite, handle); EXPECT_EQ(0, ret); if (ret == 0) {
#endif
}
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
}*/
static void mkdir_test(repertory::remote_fuse::remote_client &client) {
const auto test_directory =
utils::path::combine(fuse_remote_dir, {"mkdir_test"});
const auto api_path = test_directory.substr(mount_location_.size());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
#if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0));
#else
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), S_IRWXU));
#endif
EXPECT_TRUE(utils::file::is_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).exists());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
}
static void open_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir, {"open.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
#if defined(_WIN32)
@@ -471,7 +471,7 @@ static void open_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle2));
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void
@@ -479,27 +479,27 @@ opendir_and_releasedir_test(repertory::remote_fuse::remote_client &client) {
const auto test_directory =
utils::path::combine(fuse_remote_dir, {"opendir_and_release_dir"});
const auto api_path = test_directory.substr(mount_location_.size());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
#if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0));
#else
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), S_IRWXU));
#endif
EXPECT_TRUE(utils::file::is_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).exists());
remote::file_handle handle = 0;
EXPECT_EQ(0, client.fuse_opendir(api_path.c_str(), handle));
EXPECT_EQ(0, client.fuse_releasedir(api_path.c_str(), handle));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
}
static void read_and_write_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"read_and_write.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -517,7 +517,7 @@ static void read_and_write_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void
@@ -525,7 +525,7 @@ read_and_write_base64_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"read_and_write_base64.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -534,7 +534,7 @@ read_and_write_base64_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, ret);
if (ret == 0) {
const auto data = macaron::Base64::Encode("1234567890");
EXPECT_EQ(10, client.fuse_write_base64(api_path.c_str(), &data[0],
EXPECT_EQ(10, client.fuse_write_base64(api_path.c_str(), data.data(),
data.size(), 0, handle));
data_buffer buffer(10);
EXPECT_EQ(10, client.fuse_read(api_path.c_str(),
@@ -544,21 +544,21 @@ read_and_write_base64_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void readdir_test(repertory::remote_fuse::remote_client &client) {
const auto test_directory =
utils::path::combine(fuse_remote_dir, {"readdir_test"});
const auto api_path = test_directory.substr(mount_location_.size());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
#if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0));
#else
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), S_IRWXU));
#endif
EXPECT_TRUE(utils::file::is_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).exists());
remote::file_handle handle = 0;
EXPECT_EQ(0, client.fuse_opendir(api_path.c_str(), handle));
@@ -572,14 +572,14 @@ static void readdir_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_releasedir(api_path.c_str(), handle));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
}
/*static void removexattr_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir,
{"removexattr.txt"}); const auto api_path =
test_file.substr(mount_location_.size());
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -592,7 +592,7 @@ remote::open_flags::ReadWrite, handle); EXPECT_EQ(0, ret); if (ret == 0) {
"test")); #endif
}
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
}*/
static void rename_test(repertory::remote_fuse::remote_client &client) {
@@ -602,8 +602,8 @@ static void rename_test(repertory::remote_fuse::remote_client &client) {
const auto api_path = test_file.substr(mount_location_.size());
const auto renamed_api_path =
renamed_test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::retry_delete_file(renamed_test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
EXPECT_TRUE(utils::file::file(renamed_test_file).remove());
remote::file_handle handle;
#if defined(_WIN32)
@@ -621,38 +621,38 @@ static void rename_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
EXPECT_EQ(0,
client.fuse_rename(api_path.c_str(), renamed_api_path.c_str()));
EXPECT_FALSE(utils::file::is_file(test_file));
EXPECT_TRUE(utils::file::is_file(renamed_test_file));
EXPECT_FALSE(utils::file::file(test_file).exists());
EXPECT_TRUE(utils::file::file(renamed_test_file).exists());
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::retry_delete_file(renamed_test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
EXPECT_TRUE(utils::file::file(renamed_test_file).remove());
}
static void rmdir_test(repertory::remote_fuse::remote_client &client) {
const auto test_directory =
utils::path::combine(fuse_remote_dir, {"rmdir_test"});
const auto api_path = test_directory.substr(mount_location_.size());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
#if defined(_WIN32)
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), 0));
#else
EXPECT_EQ(0, client.fuse_mkdir(api_path.c_str(), S_IRWXU));
#endif
EXPECT_TRUE(utils::file::is_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).exists());
EXPECT_EQ(0, client.fuse_rmdir(api_path.c_str()));
EXPECT_FALSE(utils::file::is_directory(test_directory));
EXPECT_FALSE(utils::file::directory(test_directory).exists());
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
}
static void setattr_x_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"setattr_x.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -670,14 +670,14 @@ static void setattr_x_test(repertory::remote_fuse::remote_client &client) {
#endif
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void setbkuptime_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"setbkuptime.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -687,7 +687,7 @@ static void setbkuptime_test(repertory::remote_fuse::remote_client &client) {
if (ret == 0) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
remote::file_time ts = utils::time::get_file_time_now();
remote::file_time ts = utils::time::get_time_now();
#if defined(_WIN32)
EXPECT_EQ(NOT_IMPLEMENTED, client.fuse_setbkuptime(api_path.c_str(), ts));
#else
@@ -695,14 +695,14 @@ static void setbkuptime_test(repertory::remote_fuse::remote_client &client) {
#endif
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void setchgtime_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"setchgtime.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -712,7 +712,7 @@ static void setchgtime_test(repertory::remote_fuse::remote_client &client) {
if (ret == 0) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
remote::file_time ts = utils::time::get_file_time_now();
remote::file_time ts = utils::time::get_time_now();
#if defined(_WIN32)
EXPECT_EQ(NOT_IMPLEMENTED, client.fuse_setchgtime(api_path.c_str(), ts));
#else
@@ -720,14 +720,14 @@ static void setchgtime_test(repertory::remote_fuse::remote_client &client) {
#endif
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void setcrtime_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"setcrtime.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -737,7 +737,7 @@ static void setcrtime_test(repertory::remote_fuse::remote_client &client) {
if (ret == 0) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
remote::file_time ts = utils::time::get_file_time_now();
remote::file_time ts = utils::time::get_time_now();
#if defined(_WIN32)
EXPECT_EQ(NOT_IMPLEMENTED, client.fuse_setcrtime(api_path.c_str(), ts));
#else
@@ -745,7 +745,7 @@ static void setcrtime_test(repertory::remote_fuse::remote_client &client) {
#endif
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void setvolname_test(repertory::remote_fuse::remote_client &client) {
@@ -756,7 +756,7 @@ static void setvolname_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir,
{"setxattr.txt"}); const auto api_path =
test_file.substr(mount_location_.size());
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -771,14 +771,14 @@ remote::open_flags::ReadWrite, handle); EXPECT_EQ(0, ret); if (ret == 0) {
5, 0)); #endif
}
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
}
static void setxattr_osx_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir,
{"setxattr_osx.txt"}); const auto api_path =
test_file.substr(mount_location_.size());
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -791,7 +791,7 @@ remote::open_flags::ReadWrite, handle); EXPECT_EQ(0, ret); if (ret == 0) {
0));
}
utils::file::retry_delete_file(test_file);
utils::file::file(test_file).remove();
}*/
#if defined(_WIN32)
@@ -832,7 +832,7 @@ static void statfs_x_test(repertory::remote_fuse::remote_client &client,
remote::statfs_x st{};
EXPECT_EQ(0, client.fuse_statfs_x(api_path.c_str(), 4096, st));
EXPECT_STREQ(&st.f_mntfromname[0],
EXPECT_STREQ(st.f_mntfromname.data(),
utils::create_volume_label(provider_type::remote).c_str());
const auto total_bytes = drive.get_total_drive_space();
@@ -853,7 +853,7 @@ static void truncate_test(repertory::remote_fuse::remote_client &client) {
const auto test_file =
utils::path::combine(fuse_remote_dir, {"truncate.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
#if defined(_WIN32)
@@ -871,18 +871,18 @@ static void truncate_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_truncate(api_path.c_str(), 100));
std::uint64_t file_size;
EXPECT_TRUE(utils::file::get_file_size(test_file, file_size));
EXPECT_EQ(100u, file_size);
auto opt_size = utils::file::file{test_file}.size();
EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(100U, opt_size.value());
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void unlink_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir, {"unlink.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -892,16 +892,16 @@ static void unlink_test(repertory::remote_fuse::remote_client &client) {
if (ret == 0) {
EXPECT_EQ(0, client.fuse_release(api_path.c_str(), handle));
EXPECT_EQ(0, client.fuse_unlink(api_path.c_str()));
EXPECT_FALSE(utils::file::is_file(test_file));
EXPECT_FALSE(utils::file::file(test_file).exists());
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void utimens_test(repertory::remote_fuse::remote_client &client) {
const auto test_file = utils::path::combine(fuse_remote_dir, {"utimens.txt"});
const auto api_path = test_file.substr(mount_location_.size());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
remote::file_handle handle;
const auto ret = client.fuse_create(
@@ -915,7 +915,7 @@ static void utimens_test(repertory::remote_fuse::remote_client &client) {
EXPECT_EQ(0, client.fuse_utimens(api_path.c_str(), tv, 0, 0));
}
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
TEST(remote_fuse, all_tests) {
@@ -934,11 +934,11 @@ TEST(remote_fuse, all_tests) {
event_system::instance().start();
#if defined(_WIN32)
mount_location_ = std::string("./test_config").substr(0, 2);
mount_location_ = fuse_remote_dir.substr(0, 2);
mock_winfsp_drive drive(mount_location_);
remote_server server(config, drive, mount_location_);
#else
mount_location_ = utils::path::absolute(".");
mount_location_ = fuse_remote_dir;
mock_fuse_drive drive(mount_location_);
remote_server server(config, drive, mount_location_);
#endif
@@ -990,6 +990,6 @@ TEST(remote_fuse, all_tests) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(fuse_remote_dir));
EXPECT_TRUE(utils::file::directory(fuse_remote_dir).remove_recursively());
}
} // namespace fuse_test

View File

@@ -33,6 +33,7 @@
#include "platform/platform.hpp"
#include "types/repertory.hpp"
#include "utils/common.hpp"
#include "utils/time.hpp"
using namespace repertory;
using namespace repertory::remote_winfsp;
@@ -40,32 +41,32 @@ using namespace repertory::remote_winfsp;
namespace winfsp_test {
static std::string mount_location_;
static std::string win_remote_dir =
utils::path::combine("./test_config", {"win_remote_test"});
utils::path::combine(test::get_test_output_dir(), {"win_remote_test"});
static void can_delete_test(remote_client &client) {
const auto test_file =
utils::path::combine(win_remote_dir, {"candelete.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
native_file::native_file_ptr nf;
EXPECT_EQ(api_error::success, native_file::create_or_open(test_file, nf));
auto ptr = utils::file::file::open_or_create_file(test_file);
auto &nf = *ptr;
EXPECT_TRUE(nf);
if (nf) {
EXPECT_EQ(STATUS_INVALID_HANDLE,
client.winfsp_can_delete(
reinterpret_cast<PVOID>(nf->get_handle()), &api_path[0]));
client.winfsp_can_delete(reinterpret_cast<PVOID>(nf.get_handle()),
api_path.data()));
nf->close();
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
nf.close();
EXPECT_TRUE(utils::file::file(test_file).remove());
}
}
template <typename t>
static void create_and_close_test(remote_client &client, t &server) {
const auto test_file = utils::path::combine(win_remote_dir, {"create.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -83,12 +84,12 @@ static void create_and_close_test(remote_client &client, t &server) {
EXPECT_EQ(0u, client.get_open_file_count(utils::string::to_utf8(api_path)));
EXPECT_EQ(0u, server.get_open_file_count(test_file));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void cleanup_test(remote_client &client) {
const auto test_file = utils::path::combine(win_remote_dir, {"cleanup.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -107,12 +108,12 @@ static void cleanup_test(remote_client &client) {
EXPECT_FALSE(was_closed);
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void flush_test(remote_client &client) {
const auto test_file = utils::path::combine(win_remote_dir, {"flush.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -129,13 +130,13 @@ static void flush_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void get_file_info_test(remote_client &client) {
const auto test_file =
utils::path::combine(win_remote_dir, {"get_file_info.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -152,13 +153,13 @@ static void get_file_info_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void get_security_by_name_test(remote_client &client) {
const auto test_file =
utils::path::combine(win_remote_dir, {"get_security_by_name.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -181,7 +182,7 @@ static void get_security_by_name_test(remote_client &client) {
EXPECT_EQ(static_cast<UINT32>(FILE_ATTRIBUTE_NORMAL), attributes);
EXPECT_FALSE(str_descriptor.empty());
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void get_volume_info_test(remote_client &client) {
@@ -202,7 +203,7 @@ static void mounted_test(remote_client &client) {
static void open_test(remote_client &client) {
const auto test_file = utils::path::combine(win_remote_dir, {"open.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -229,13 +230,13 @@ static void open_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc2));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void overwrite_test(remote_client &client) {
const auto test_file =
utils::path::combine(win_remote_dir, {"overwrite.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -259,13 +260,13 @@ static void overwrite_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void create_and_read_directory_test(remote_client &client) {
const auto test_directory =
utils::path::combine(win_remote_dir, {"read_directory"});
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
auto api_path =
utils::string::from_utf8(test_directory).substr(mount_location_.size());
@@ -278,7 +279,7 @@ static void create_and_read_directory_test(remote_client &client) {
FILE_ATTRIBUTE_DIRECTORY, 0, &file_desc, &fi, normalized_name, exists);
EXPECT_EQ(STATUS_SUCCESS, ret);
EXPECT_TRUE(utils::file::is_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).exists());
json list;
ret = client.winfsp_read_directory(file_desc, nullptr, nullptr, list);
@@ -287,13 +288,13 @@ static void create_and_read_directory_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
}
static void open_and_read_directory_test(remote_client &client) {
const auto test_directory =
utils::path::combine(win_remote_dir, {"open_and_read_directory"});
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
auto api_path =
utils::string::from_utf8(test_directory).substr(mount_location_.size());
@@ -308,7 +309,7 @@ static void open_and_read_directory_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::is_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).exists());
file_desc = reinterpret_cast<PVOID>(REPERTORY_INVALID_HANDLE);
ret = client.winfsp_open(&api_path[0], FILE_DIRECTORY_FILE,
@@ -323,13 +324,13 @@ static void open_and_read_directory_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::delete_directory(test_directory));
EXPECT_TRUE(utils::file::directory(test_directory).remove());
}
static void read_and_write_test(remote_client &client) {
const auto test_file =
utils::path::combine(win_remote_dir, {"read_and_write.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -365,14 +366,14 @@ static void read_and_write_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void rename_test(remote_client &client) {
const auto test_file = utils::path::combine(win_remote_dir, {"rename.txt"});
const auto test_file2 = utils::path::combine(win_remote_dir, {"rename2.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::retry_delete_file(test_file2));
EXPECT_TRUE(utils::file::file(test_file).remove());
EXPECT_TRUE(utils::file::file(test_file2).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
auto api_path2 =
@@ -389,20 +390,20 @@ static void rename_test(remote_client &client) {
ret = client.winfsp_rename(file_desc, &api_path[0], &api_path2[0], 0);
EXPECT_EQ(STATUS_SUCCESS, ret);
EXPECT_TRUE(utils::file::is_file(test_file2));
EXPECT_FALSE(utils::file::is_file(test_file));
EXPECT_TRUE(utils::file::file(test_file2).exists());
EXPECT_FALSE(utils::file::file(test_file).exists());
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::retry_delete_file(test_file2));
EXPECT_TRUE(utils::file::file(test_file).remove());
EXPECT_TRUE(utils::file::file(test_file2).remove());
}
static void set_basic_info_test(remote_client &client) {
const auto test_file =
utils::path::combine(win_remote_dir, {"set_basic_info.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -429,7 +430,7 @@ static void set_basic_info_test(remote_client &client) {
const auto change_time = last_write_time;
#else
const auto creation_time =
utils::unix_time_to_windows_time(utils::time::get_time_now());
utils::time::unix_time_to_windows_time(utils::time::get_time_now());
const auto last_access_time = creation_time + 1;
const auto last_write_time = creation_time + 2;
const auto change_time = last_write_time;
@@ -447,13 +448,13 @@ static void set_basic_info_test(remote_client &client) {
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void set_file_size_test(remote_client &client) {
const auto test_file =
utils::path::combine(win_remote_dir, {"set_file_size.txt"});
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
auto api_path =
utils::string::from_utf8(test_file).substr(mount_location_.size());
@@ -472,13 +473,13 @@ static void set_file_size_test(remote_client &client) {
client.winfsp_set_file_size(file_desc, new_file_size,
set_allocation_size, &fi));
std::uint64_t file_size = 0u;
EXPECT_TRUE(utils::file::get_file_size(test_file, file_size));
EXPECT_EQ(34u, file_size);
auto opt_size = utils::file::file{test_file}.size();
EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(34U, opt_size.value());
EXPECT_EQ(STATUS_SUCCESS, client.winfsp_close(file_desc));
EXPECT_TRUE(utils::file::retry_delete_file(test_file));
EXPECT_TRUE(utils::file::file(test_file).remove());
}
static void unmounted_test(remote_client &client) {
@@ -492,7 +493,6 @@ TEST(remote_winfsp, all_tests) {
EXPECT_TRUE(found_port);
if (found_port) {
console_consumer c;
app_config config(provider_type::remote, win_remote_dir);
config.set_remote_host_name_or_ip("localhost");
config.set_remote_port(port);
@@ -502,11 +502,11 @@ TEST(remote_winfsp, all_tests) {
event_system::instance().start();
#if defined(_WIN32)
mount_location_ = std::string("./test_config").substr(0, 2);
mount_location_ = win_remote_dir.substr(0, 2);
mock_winfsp_drive drive(mount_location_);
remote_server server(config, drive, mount_location_);
#else
mount_location_ = utils::path::absolute(".");
mount_location_ = win_remote_dir;
mock_fuse_drive drive(mount_location_);
remote_fuse::remote_server server(config, drive, mount_location_);
#endif
@@ -536,6 +536,6 @@ TEST(remote_winfsp, all_tests) {
}
event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(win_remote_dir));
EXPECT_TRUE(utils::file::directory(win_remote_dir).remove_recursively());
}
} // namespace winfsp_test

View File

@@ -1,73 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "test_common.hpp"
#include "types/repertory.hpp"
#include "utils/common.hpp"
#include "utils/path.hpp"
namespace repertory {
std::vector<std::string> generated_files;
void delete_generated_files() {
for (const auto &file : generated_files) {
EXPECT_TRUE(utils::file::retry_delete_file(file));
}
}
auto create_random_file(std::string path, std::size_t size) -> native_file_ptr {
native_file_ptr file;
if (native_file::create_or_open(path, file) == api_error::success) {
generated_files.emplace_back(utils::path::absolute(path));
EXPECT_TRUE(file->truncate(0U));
data_buffer buf(size);
randombytes_buf(buf.data(), buf.size());
std::size_t bytes_written{};
EXPECT_TRUE(file->write_bytes(buf.data(), buf.size(), 0U, bytes_written));
file->flush();
std::uint64_t current_size{};
EXPECT_TRUE(utils::file::get_file_size(path, current_size));
EXPECT_EQ(size, current_size);
}
return file;
}
auto generate_test_file_name(const std::string &directory,
const std::string &file_name_no_extension)
-> std::string {
static std::atomic<std::uint32_t> idx{0U};
auto path = utils::path::combine(
directory, {file_name_no_extension + std::to_string(idx++) + ".dat"});
generated_files.emplace_back(path);
return path;
}
auto get_test_dir() -> std::string {
auto dir = utils::get_environment_variable("PROJECT_TEST_DIR");
return utils::path::combine(dir.empty() ? "." : dir, {"test_config"});
}
} // namespace repertory

View File

@@ -21,17 +21,14 @@
*/
#include "test_common.hpp"
#include "platform/platform.hpp"
#include "utils/common.hpp"
#include "utils/file_utils.hpp"
#include "utils/string.hpp"
#include "utils/utils.hpp"
#include "providers/s3/s3_provider.hpp"
#include "utils/file.hpp"
namespace repertory {
#if defined(_WIN32)
TEST(utils, convert_api_date) {
LARGE_INTEGER li{};
li.QuadPart = utils::convert_api_date("2009-10-12T17:50:30.111Z");
li.QuadPart = s3_provider::convert_api_date("2009-10-12T17:50:30.111Z");
SYSTEMTIME st{};
FileTimeToSystemTime(reinterpret_cast<FILETIME *>(&li), &st);
@@ -48,10 +45,13 @@ TEST(utils, convert_api_date) {
EXPECT_EQ(20, lt.wSecond);
EXPECT_EQ(111, lt.wMilliseconds);
}
#endif
#endif // defined(_WIN32)
TEST(utils, generate_sha256) {
const auto res = utils::file::generate_sha256(__FILE__);
std::cout << res << std::endl;
auto res = utils::file::file{__FILE__}.sha256();
EXPECT_TRUE(res.has_value());
if (res.has_value()) {
std::cout << res.value() << std::endl;
}
}
} // namespace repertory

View File

@@ -69,19 +69,19 @@ static void execute_mount(winfsp_test *test,
static void unmount(winfsp_test *test, const std::string &mount_point) {
test->drive->shutdown();
auto mounted = utils::file::is_directory(mount_point);
auto mounted = utils::file::directory(mount_point).exists();
for (auto i = 0; mounted && (i < 50); i++) {
std::this_thread::sleep_for(100ms);
mounted = utils::file::is_directory(mount_point);
mounted = utils::file::directory(mount_point).exists();
}
EXPECT_FALSE(utils::file::is_directory(mount_point));
EXPECT_FALSE(utils::file::directory(mount_point).exists());
}
static void root_creation_test(const std::string &mount_point) {
TEST_HEADER(__FUNCTION__);
WIN32_FILE_ATTRIBUTE_DATA ad{};
EXPECT_TRUE(
::GetFileAttributesEx(&mount_point[0], GetFileExInfoStandard, &ad));
::GetFileAttributesEx(mount_point.c_str(), GetFileExInfoStandard, &ad));
EXPECT_EQ(FILE_ATTRIBUTE_DIRECTORY, ad.dwFileAttributes);
EXPECT_EQ(0, ad.nFileSizeHigh);
EXPECT_EQ(0, ad.nFileSizeLow);
@@ -96,11 +96,11 @@ static auto create_test(winfsp_test *test, const std::string &mount_point) {
EXPECT_NE(INVALID_HANDLE_VALUE, handle);
EXPECT_TRUE(::CloseHandle(handle));
EXPECT_TRUE(utils::file::is_file(file));
EXPECT_TRUE(utils::file::file(file).exists());
std::uint64_t file_size;
EXPECT_TRUE(utils::file::get_file_size(file, file_size));
EXPECT_EQ(0, file_size);
auto opt_size = utils::file::file(file).size();
EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(0, opt_size.value());
std::string attr;
EXPECT_EQ(api_error::success, test->provider->get_item_meta(
@@ -113,8 +113,8 @@ static auto create_test(winfsp_test *test, const std::string &mount_point) {
static void delete_file_test(const std::string &file) {
TEST_HEADER(__FUNCTION__);
event_capture ec({"file_removed"});
EXPECT_TRUE(utils::file::retry_delete_file(file));
EXPECT_FALSE(utils::file::is_file(file));
EXPECT_TRUE(utils::file::file(file).remove());
EXPECT_FALSE(utils::file::file(file).exists());
}
static void create_directory_test(const std::string &directory) {
@@ -149,11 +149,11 @@ static void write_file_test(const std::string &mount_point) {
EXPECT_EQ(10, bytes_written);
EXPECT_TRUE(::CloseHandle(handle));
EXPECT_TRUE(utils::file::is_file(file));
EXPECT_TRUE(utils::file::file(file).exists());
std::uint64_t file_size;
EXPECT_TRUE(utils::file::get_file_size(file, file_size));
EXPECT_EQ(10, file_size);
auto opt_size = utils::file::file(file).size();
EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(10U, opt_size.value());
}
static void read_file_test(const std::string &mount_point) {
@@ -199,8 +199,8 @@ static void rename_file_test(winfsp_test *test,
const auto file2 = utils::path::combine(mount_point, {"rename_file2.txt"});
EXPECT_TRUE(::MoveFile(&file[0], &file2[0]));
EXPECT_TRUE(utils::file::is_file(file2));
EXPECT_FALSE(utils::file::is_file(file));
EXPECT_TRUE(utils::file::file(file2).exists());
EXPECT_FALSE(utils::file::file(file).exists());
api_meta_map meta2{};
EXPECT_EQ(api_error::success,