revert
All checks were successful
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good

This commit is contained in:
2024-01-29 11:36:26 -06:00
parent d175a38ad1
commit 99533a9687
213 changed files with 43429 additions and 41103 deletions

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -28,52 +28,73 @@
#include "utils/unix/unix_utils.hpp"
#include "utils/utils.hpp"
namespace {
constexpr const auto default_api_auth_size = 48U;
constexpr const auto default_download_timeout_ces = 30U;
constexpr const auto default_eviction_delay_mins = 10U;
constexpr const auto default_high_freq_interval_secs = 30U;
constexpr const auto default_low_freq_interval_secs = 60U * 60U;
constexpr const auto default_max_cache_size_bytes =
20ULL * 1024ULL * 1024ULL * 1024ULL;
constexpr const auto default_max_upload_count = 5U;
constexpr const auto default_min_download_timeout_secs = 5U;
constexpr const auto default_online_check_retry_secs = 60U;
constexpr const auto default_orphaned_file_retention_days = 15U;
constexpr const auto default_read_ahead_count = 4U;
constexpr const auto default_remote_client_pool_size = 10U;
constexpr const auto default_remote_host_name_or_ip = "";
constexpr const auto default_remote_max_connections = 20U;
constexpr const auto default_remote_receive_timeout_secs = 120U;
constexpr const auto default_remote_send_timeout_secs = 30U;
constexpr const auto default_remote_token = "";
constexpr const auto default_retry_read_count = 6U;
constexpr const auto default_ring_buffer_file_size = 512U;
constexpr const auto retry_save_count = 5U;
} // namespace
namespace repertory {
app_config::app_config(const provider_type &prov,
const std::string &data_directory)
: prov_(prov),
api_auth_(utils::generate_random_string(48U)),
api_auth_(utils::generate_random_string(default_api_auth_size)),
api_port_(default_rpc_port(prov)),
api_user_("repertory"),
api_user_(REPERTORY),
config_changed_(false),
data_directory_(data_directory.empty()
? default_data_directory(prov)
: utils::path::absolute(data_directory)),
download_timeout_secs_(30),
download_timeout_secs_(default_download_timeout_ces),
enable_chunk_downloader_timeout_(true),
enable_comm_duration_events_(false),
enable_drive_events_(false),
enable_max_cache_size_(true),
enable_max_cache_size_(false),
#ifdef _WIN32
enable_mount_manager_(false),
#endif
enable_remote_mount_(false),
event_level_(event_level::normal),
eviction_delay_mins_(30),
eviction_delay_mins_(default_eviction_delay_mins),
eviction_uses_accessed_time_(false),
high_freq_interval_secs_(30),
high_freq_interval_secs_(default_high_freq_interval_secs),
is_remote_mount_(false),
low_freq_interval_secs_(60 * 60),
max_cache_size_bytes_(20 * 1024 * 1024 * 1024ULL),
max_upload_count_(5U),
min_download_timeout_secs_(5),
online_check_retry_secs_(60),
orphaned_file_retention_days_(15),
low_freq_interval_secs_(default_low_freq_interval_secs),
max_cache_size_bytes_(default_max_cache_size_bytes),
max_upload_count_(default_max_upload_count),
min_download_timeout_secs_(default_min_download_timeout_secs),
online_check_retry_secs_(default_online_check_retry_secs),
orphaned_file_retention_days_(default_orphaned_file_retention_days),
preferred_download_type_(
utils::download_type_to_string(download_type::fallback)),
read_ahead_count_(4),
remote_client_pool_size_(10),
remote_host_name_or_ip_(""),
remote_max_connections_(20),
remote_port_((prov == provider_type::sia) ? 20000
: (prov == provider_type::s3) ? 20001
: (prov == provider_type::encrypt) ? 20002
: 20003),
remote_receive_timeout_secs_(120),
remote_send_timeout_secs_(30),
remote_token_(""),
retry_read_count_(6),
ring_buffer_file_size_(512) {
read_ahead_count_(default_read_ahead_count),
remote_client_pool_size_(default_remote_client_pool_size),
remote_host_name_or_ip_(default_remote_host_name_or_ip),
remote_max_connections_(default_remote_max_connections),
remote_port_(default_remote_port(prov)),
remote_receive_timeout_secs_(default_remote_receive_timeout_secs),
remote_send_timeout_secs_(default_remote_send_timeout_secs),
remote_token_(default_remote_token),
retry_read_count_(default_retry_read_count),
ring_buffer_file_size_(default_ring_buffer_file_size) {
cache_directory_ = utils::path::combine(data_directory_, {"cache"});
log_directory_ = utils::path::combine(data_directory_, {"logs"});
@@ -105,16 +126,26 @@ auto app_config::get_config_file_path() const -> std::string {
auto app_config::default_agent_name(const provider_type &prov) -> std::string {
static const std::array<std::string,
static_cast<std::size_t>(provider_type::unknown)>
PROVIDER_AGENT_NAMES = {"Sia-Agent", "", "", ""};
PROVIDER_AGENT_NAMES = {
"Sia-Agent",
"",
"",
"",
};
return PROVIDER_AGENT_NAMES[static_cast<std::size_t>(prov)];
return PROVIDER_AGENT_NAMES.at(static_cast<std::size_t>(prov));
}
auto app_config::default_api_port(const provider_type &prov) -> std::uint16_t {
static const std::array<std::uint16_t,
static_cast<std::size_t>(provider_type::unknown)>
PROVIDER_API_PORTS = {9980U, 0U, 0U, 0U};
return PROVIDER_API_PORTS[static_cast<std::size_t>(prov)];
PROVIDER_API_PORTS = {
9980U,
0U,
0U,
0U,
};
return PROVIDER_API_PORTS.at(static_cast<std::size_t>(prov));
}
auto app_config::default_data_directory(const provider_type &prov)
@@ -137,16 +168,28 @@ auto app_config::default_data_directory(const provider_type &prov)
return data_directory;
}
auto app_config::default_remote_port(const provider_type &prov)
-> std::uint16_t {
static const std::array<std::uint16_t,
static_cast<std::size_t>(provider_type::unknown)>
PROVIDER_REMOTE_PORTS = {
20000U,
20010U,
20100U,
20001U,
};
return PROVIDER_REMOTE_PORTS.at(static_cast<std::size_t>(prov));
}
auto app_config::default_rpc_port(const provider_type &prov) -> std::uint16_t {
static const std::array<std::uint16_t,
static_cast<std::size_t>(provider_type::unknown)>
PROVIDER_RPC_PORTS = {
11101U,
11102U,
11103U,
11104U,
10000U,
10010U,
10100U,
10002U,
};
return PROVIDER_RPC_PORTS[static_cast<std::size_t>(prov)];
return PROVIDER_RPC_PORTS.at(static_cast<std::size_t>(prov));
}
auto app_config::get_json() const -> json {
@@ -289,7 +332,7 @@ auto app_config::get_provider_api_password(const provider_type &prov)
#endif
#endif
auto lines = utils::file::read_file_lines(api_file);
return lines.empty() ? "" : utils::string::trim(lines[0]);
return lines.empty() ? "" : utils::string::trim(lines[0U]);
}
auto app_config::get_provider_display_name(const provider_type &prov)
@@ -302,7 +345,7 @@ auto app_config::get_provider_display_name(const provider_type &prov)
"S3",
"Encrypt",
};
return PROVIDER_DISPLAY_NAMES[static_cast<std::size_t>(prov)];
return PROVIDER_DISPLAY_NAMES.at(static_cast<std::size_t>(prov));
}
auto app_config::get_provider_name(const provider_type &prov) -> std::string {
@@ -314,10 +357,12 @@ auto app_config::get_provider_name(const provider_type &prov) -> std::string {
"s3",
"encrypt",
};
return PROVIDER_NAMES[static_cast<std::size_t>(prov)];
return PROVIDER_NAMES.at(static_cast<std::size_t>(prov));
}
auto app_config::get_value_by_name(const std::string &name) -> std::string {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
if (name == "ApiAuth") {
return api_auth_;
@@ -332,16 +377,16 @@ auto app_config::get_value_by_name(const std::string &name) -> std::string {
return std::to_string(get_chunk_downloader_timeout_secs());
}
if (name == "EnableChunkDownloaderTimeout") {
return std::to_string(get_enable_chunk_download_timeout());
return utils::string::from_bool(get_enable_chunk_download_timeout());
}
if (name == "GetEnableCommDurationEvents") {
return std::to_string(get_enable_comm_duration_events());
return utils::string::from_bool(get_enable_comm_duration_events());
}
if (name == "EnableDriveEvents") {
return std::to_string(get_enable_drive_events());
return utils::string::from_bool(get_enable_drive_events());
}
if (name == "EnableMaxCacheSize") {
return std::to_string(get_enable_max_cache_size());
return utils::string::from_bool(get_enable_max_cache_size());
#ifdef _WIN32
}
if (name == "EnableMountManager") {
@@ -361,7 +406,7 @@ auto app_config::get_value_by_name(const std::string &name) -> std::string {
return std::to_string(get_eviction_delay_mins());
}
if (name == "EvictionUsesAccessedTime") {
return std::to_string(get_eviction_uses_accessed_time());
return utils::string::from_bool(get_eviction_uses_accessed_time());
}
if (name == "HighFreqIntervalSeconds") {
return std::to_string(get_high_frequency_interval_secs());
@@ -404,10 +449,10 @@ auto app_config::get_value_by_name(const std::string &name) -> std::string {
return std::to_string(get_read_ahead_count());
}
if (name == "RemoteMount.EnableRemoteMount") {
return std::to_string(get_enable_remote_mount());
return utils::string::from_bool(get_enable_remote_mount());
}
if (name == "RemoteMount.IsRemoteMount") {
return std::to_string(get_is_remote_mount());
return utils::string::from_bool(get_is_remote_mount());
}
if (name == "RemoteMount.RemoteClientPoolSize") {
return std::to_string(get_remote_client_pool_size());
@@ -467,12 +512,14 @@ auto app_config::get_value_by_name(const std::string &name) -> std::string {
return std::to_string(s3_config_.timeout_ms);
}
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
return "";
}
auto app_config::load() -> bool {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto ret = false;
const auto config_file_path = get_config_file_path();
@@ -485,7 +532,8 @@ auto app_config::load() -> bool {
stream << config_file.rdbuf();
const auto json_text = stream.str();
config_file.close();
if ((ret = not json_text.empty())) {
ret = not json_text.empty();
if (ret) {
const auto json_document = json::parse(json_text);
get_value(json_document, "ApiAuth", api_auth_, ret);
@@ -627,7 +675,7 @@ auto app_config::load() -> bool {
config_changed_ = true;
}
} catch (const std::exception &ex) {
utils::error::raise_error(__FUNCTION__, ex, "exception occurred");
utils::error::raise_error(function_name, ex, "exception occurred");
ret = false;
}
}
@@ -636,22 +684,25 @@ auto app_config::load() -> bool {
}
void app_config::save() {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
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_)) {
utils::error::raise_error(
__FUNCTION__, "failed to create directory|sp|" + data_directory_ +
"|err|" +
std::to_string(utils::get_last_error_code()));
function_name, "failed to create directory|sp|" + data_directory_ +
"|err|" +
std::to_string(utils::get_last_error_code()));
}
}
config_changed_ = false;
json data = get_json();
auto success = false;
for (auto i = 0; not success && (i < 5); i++) {
if (not(success = utils::file::write_json_file(file_path, data))) {
for (auto i = 0U; not success && (i < retry_save_count); i++) {
success = utils::file::write_json_file(file_path, data);
if (not success) {
std::this_thread::sleep_for(1s);
}
}
@@ -680,6 +731,8 @@ void app_config::set_is_remote_mount(bool is_remote_mount) {
auto app_config::set_value_by_name(const std::string &name,
const std::string &value) -> std::string {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
if (name == "ApiAuth") {
set_api_auth(value);
@@ -879,8 +932,9 @@ auto app_config::set_value_by_name(const std::string &name,
return s3_config_.encryption_token;
}
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
return "";
}
} // namespace repertory

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -154,6 +154,16 @@ auto curl_comm::make_request(const curl::requests::http_head &head,
head, response_code, stop_requested);
}
auto curl_comm::make_request(const curl::requests::http_post &post,
long &response_code,
stop_type &stop_requested) const -> bool {
return make_request(
s3_config_.has_value()
? create_host_config(s3_config_.value(), use_s3_path_style_)
: host_config_.value_or(host_config{}),
post, response_code, stop_requested);
}
auto curl_comm::make_request(const curl::requests::http_put_file &put_file,
long &response_code,
stop_type &stop_requested) const -> bool {

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,45 +1,3 @@
<<<<<<< HEAD:include/utils/rocksdb_utils.hpp
/*
Copyright <2018-2023> <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_ROCKSDB_UTILS_HPP_
#define INCLUDE_UTILS_ROCKSDB_UTILS_HPP_
namespace repertory {
class app_config;
namespace utils::db {
void create_rocksdb(const app_config &config, const std::string &name,
std::unique_ptr<rocksdb::DB> &db);
void create_rocksdb(
const app_config &config, const std::string &name,
const std::vector<rocksdb::ColumnFamilyDescriptor> &families,
std::vector<rocksdb::ColumnFamilyHandle *> &handles,
std::unique_ptr<rocksdb::DB> &db);
} // namespace utils::db
} // namespace repertory
#endif // INCLUDE_UTILS_ROCKSDB_UTILS_HPP_
=======
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
@@ -85,4 +43,3 @@ auto http_post::set_method(CURL *curl, stop_type & /*stop_requested*/) const
return true;
}
} // namespace repertory::curl::requests
>>>>>>> 9b453327a81e182a9ec87ef1aae13169516436e0:src/comm/curl/requests/http_post.cpp

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -40,6 +40,8 @@ void client_pool::pool::execute(
}
client_pool::pool::pool(std::uint8_t pool_size) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
event_system::instance().raise<service_started>("client_pool");
for (std::uint8_t i = 0U; i < pool_size; i++) {
@@ -75,7 +77,7 @@ client_pool::pool::pool(std::uint8_t pool_size) {
item->work_complete(result);
} catch (const std::exception &e) {
item->work_complete(utils::from_api_error(api_error::error));
utils::error::raise_error(__FUNCTION__, e,
utils::error::raise_error(function_name, e,
"exception occurred in work item");
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -219,13 +219,16 @@ auto packet::decode(remote::file_info &val) -> packet::error_type {
}
auto packet::decode_json(packet &response, json &json_data) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
std::string data;
auto ret = response.decode(data);
if (ret == 0) {
try {
json_data = json::parse(data);
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "failed to parse json string");
utils::error::raise_error(function_name, e,
"failed to parse json string");
ret = -EIO;
}
}
@@ -234,6 +237,8 @@ auto packet::decode_json(packet &response, json &json_data) -> int {
}
auto packet::decrypt(const std::string &token) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto ret = utils::from_api_error(api_error::success);
try {
data_buffer result;
@@ -245,7 +250,7 @@ auto packet::decrypt(const std::string &token) -> packet::error_type {
buffer_ = std::move(result);
decode_offset_ = 0;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
ret = utils::from_api_error(api_error::error);
}
@@ -514,13 +519,15 @@ void packet::encode_top(remote::file_info val) {
}
void packet::encrypt(const std::string &token) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
data_buffer result;
utils::encryption::encrypt_data(token, buffer_, result);
buffer_ = std::move(result);
encode_top(static_cast<std::uint32_t>(buffer_.size()));
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -39,9 +39,8 @@ packet_client::packet_client(std::string host_name_or_ip,
std::uint16_t receive_timeout,
std::uint16_t send_timeout,
std::string encryption_token)
: io_context_(),
host_name_or_ip_(std::move(host_name_or_ip)),
max_connections_(max_connections ? max_connections : 20u),
: host_name_or_ip_(std::move(host_name_or_ip)),
max_connections_(max_connections == 0U ? 20U : max_connections),
port_(port),
receive_timeout_(receive_timeout),
send_timeout_(send_timeout),
@@ -54,38 +53,40 @@ packet_client::~packet_client() {
io_context_.stop();
}
void packet_client::close(client &cli) const {
void packet_client::close(client &cli) {
try {
boost::system::error_code ec;
cli.socket.close(ec);
boost::system::error_code err;
cli.socket.close(err);
} catch (...) {
}
}
void packet_client::close_all() {
unique_mutex_lock clients_lock(clients_mutex_);
for (auto &c : clients_) {
close(*c.get());
for (auto &cli : clients_) {
close(*cli);
}
clients_.clear();
unique_id_ = utils::create_uuid_string();
}
void packet_client::connect(client &c) {
void packet_client::connect(client &cli) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
resolve();
boost::asio::connect(c.socket, resolve_results_);
c.socket.set_option(boost::asio::ip::tcp::no_delay(true));
c.socket.set_option(boost::asio::socket_base::linger(false, 0));
boost::asio::connect(cli.socket, resolve_results_);
cli.socket.set_option(boost::asio::ip::tcp::no_delay(true));
cli.socket.set_option(boost::asio::socket_base::linger(false, 0));
packet response;
const auto res = read_packet(c, response);
const auto res = read_packet(cli, response);
if (res != 0) {
throw std::runtime_error(std::to_string(res));
}
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "connection handshake failed");
utils::error::raise_error(function_name, e, "connection handshake failed");
}
}
@@ -99,7 +100,7 @@ auto packet_client::get_client() -> std::shared_ptr<packet_client::client> {
ret = std::make_shared<client>(io_context_);
connect(*ret);
} else {
ret = clients_[0u];
ret = clients_[0U];
utils::remove_element_from(clients_, ret);
clients_lock.unlock();
}
@@ -108,21 +109,21 @@ auto packet_client::get_client() -> std::shared_ptr<packet_client::client> {
return ret;
}
void packet_client::put_client(std::shared_ptr<client> &c) {
void packet_client::put_client(std::shared_ptr<client> &cli) {
mutex_lock clientsLock(clients_mutex_);
if (clients_.size() < max_connections_) {
clients_.emplace_back(c);
clients_.emplace_back(cli);
}
}
auto packet_client::read_packet(client &c, packet &response)
auto packet_client::read_packet(client &cli, packet &response)
-> packet::error_type {
data_buffer buffer(sizeof(std::uint32_t));
const auto read_buffer = [&]() {
std::uint32_t offset = 0u;
std::uint32_t offset{};
while (offset < buffer.size()) {
const auto bytes_read = boost::asio::read(
c.socket,
cli.socket,
boost::asio::buffer(&buffer[offset], buffer.size() - offset));
if (bytes_read <= 0) {
throw std::runtime_error("read failed|" + std::to_string(bytes_read));
@@ -133,7 +134,7 @@ auto packet_client::read_packet(client &c, packet &response)
read_buffer();
const auto size = boost::endian::big_to_native(
*reinterpret_cast<std::uint32_t *>(&buffer[0u]));
*reinterpret_cast<std::uint32_t *>(buffer.data()));
buffer.resize(size);
read_buffer();
@@ -141,7 +142,7 @@ auto packet_client::read_packet(client &c, packet &response)
auto ret = response.decrypt(encryption_token_);
if (ret == 0) {
ret = response.decode(c.nonce);
ret = response.decode(cli.nonce);
}
return ret;
@@ -169,6 +170,8 @@ auto packet_client::send(const std::string &method, packet &request,
auto packet_client::send(const std::string &method, packet &request,
packet &response, std::uint32_t &service_flags)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto success = false;
packet::error_type ret = utils::from_api_error(api_error::error);
request.encode_top(method);
@@ -177,28 +180,29 @@ auto packet_client::send(const std::string &method, packet &request,
request.encode_top(PACKET_SERVICE_FLAGS);
request.encode_top(get_repertory_version());
static const std::uint8_t max_attempts = 5u;
for (std::uint8_t i = 1u;
static const std::uint8_t max_attempts{5U};
for (std::uint8_t i = 1U;
allow_connections_ && not success && (i <= max_attempts); i++) {
auto c = get_client();
if (c) {
auto current_client = get_client();
if (current_client) {
try {
request.encode_top(c->nonce);
request.encode_top(current_client->nonce);
request.encrypt(encryption_token_);
timeout request_timeout(
[this, method, c]() {
[method, current_client]() {
event_system::instance().raise<packet_client_timeout>("request",
method);
close(*c.get());
packet_client::close(*current_client);
},
std::chrono::seconds(send_timeout_));
std::uint32_t offset = 0u;
std::uint32_t offset{};
while (offset < request.get_size()) {
const auto bytes_written = boost::asio::write(
c->socket, boost::asio::buffer(&request[offset],
request.get_size() - offset));
current_client->socket,
boost::asio::buffer(&request[offset],
request.get_size() - offset));
if (bytes_written <= 0) {
throw std::runtime_error("write failed|" +
std::to_string(bytes_written));
@@ -208,27 +212,29 @@ auto packet_client::send(const std::string &method, packet &request,
request_timeout.disable();
timeout response_timeout(
[this, method, c]() {
[method, current_client]() {
event_system::instance().raise<packet_client_timeout>("response",
method);
close(*c.get());
packet_client::close(*current_client);
},
std::chrono::seconds(receive_timeout_));
ret = read_packet(*c, response);
ret = read_packet(*current_client, response);
response_timeout.disable();
if (ret == 0) {
if ((ret = response.decode(service_flags)) == 0) {
ret = response.decode(service_flags);
if (ret == 0) {
packet::error_type res{};
if ((ret = response.decode(res)) == 0) {
ret = response.decode(res);
if (ret == 0) {
ret = res;
success = true;
put_client(c);
put_client(current_client);
}
}
}
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "send failed");
utils::error::raise_error(function_name, e, "send failed");
close_all();
if (allow_connections_ && (i < max_attempts)) {
std::this_thread::sleep_for(1s);

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -45,7 +45,7 @@ packet_server::packet_server(std::uint16_t port, std::string token,
packet_server::~packet_server() {
event_system::instance().raise<service_shutdown_begin>("packet_server");
std::thread([this]() {
for (std::size_t i = 0u; i < service_threads_.size(); i++) {
for (std::size_t i = 0U; i < service_threads_.size(); i++) {
io_context_.stop();
}
}).detach();
@@ -55,19 +55,21 @@ packet_server::~packet_server() {
event_system::instance().raise<service_shutdown_end>("packet_server");
}
void packet_server::add_client(connection &c, const std::string &client_id) {
c.client_id = client_id;
void packet_server::add_client(connection &conn, const std::string &client_id) {
conn.client_id = client_id;
recur_mutex_lock connection_lock(connection_mutex_);
if (connection_lookup_.find(client_id) == connection_lookup_.end()) {
connection_lookup_[client_id] = 1u;
connection_lookup_[client_id] = 1U;
} else {
connection_lookup_[client_id]++;
connection_lookup_.at(client_id)++;
}
}
void packet_server::initialize(const uint16_t &port, uint8_t pool_size) {
pool_size = std::max(uint8_t(1u), pool_size);
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
pool_size = std::max(uint8_t(1U), pool_size);
server_thread_ = std::make_unique<std::thread>([this, port, pool_size]() {
tcp::acceptor acceptor(io_context_);
try {
@@ -77,72 +79,79 @@ void packet_server::initialize(const uint16_t &port, uint8_t pool_size) {
acceptor.bind(endpoint);
acceptor.listen();
} catch (const std::exception &e) {
repertory::utils::error::raise_error(__FUNCTION__, e,
repertory::utils::error::raise_error(function_name, e,
"exception occurred");
}
listen_for_connection(acceptor);
for (std::uint8_t i = 0u; i < pool_size; i++) {
for (std::uint8_t i = 0U; i < pool_size; i++) {
service_threads_.emplace_back([this]() { io_context_.run(); });
}
for (auto &th : service_threads_) {
th.join();
for (auto &thread : service_threads_) {
thread.join();
}
});
}
void packet_server::listen_for_connection(tcp::acceptor &acceptor) {
auto c = std::make_shared<packet_server::connection>(io_context_, acceptor);
acceptor.async_accept(c->socket,
boost::bind(&packet_server::on_accept, this, c,
boost::asio::placeholders::error));
auto conn =
std::make_shared<packet_server::connection>(io_context_, acceptor);
acceptor.async_accept(conn->socket, [this, conn](auto &&err) {
on_accept(conn, std::forward<decltype(err)>(err));
});
}
void packet_server::on_accept(std::shared_ptr<connection> c,
boost::system::error_code ec) {
listen_for_connection(c->acceptor);
if (ec) {
utils::error::raise_error(__FUNCTION__, ec.message());
void packet_server::on_accept(std::shared_ptr<connection> conn,
boost::system::error_code err) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
listen_for_connection(conn->acceptor);
if (err) {
utils::error::raise_error(function_name, err.message());
std::this_thread::sleep_for(1s);
} else {
c->socket.set_option(boost::asio::ip::tcp::no_delay(true));
c->socket.set_option(boost::asio::socket_base::linger(false, 0));
conn->socket.set_option(boost::asio::ip::tcp::no_delay(true));
conn->socket.set_option(boost::asio::socket_base::linger(false, 0));
c->generate_nonce();
conn->generate_nonce();
packet response;
send_response(c, 0, response);
send_response(conn, 0, response);
}
}
void packet_server::read_header(std::shared_ptr<connection> c) {
static const std::string function_name = __FUNCTION__;
void packet_server::read_header(std::shared_ptr<connection> conn) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
c->buffer.resize(sizeof(std::uint32_t));
conn->buffer.resize(sizeof(std::uint32_t));
boost::asio::async_read(
c->socket, boost::asio::buffer(&c->buffer[0u], c->buffer.size()),
[this, c](boost::system::error_code ec, std::size_t) {
if (ec) {
remove_client(*c);
repertory::utils::error::raise_error(function_name, ec.message());
conn->socket,
boost::asio::buffer(conn->buffer.data(), conn->buffer.size()),
[this, conn](boost::system::error_code err, std::size_t) {
if (err) {
remove_client(*conn);
repertory::utils::error::raise_error(function_name, err.message());
} else {
auto to_read = *reinterpret_cast<std::uint32_t *>(&c->buffer[0u]);
auto to_read =
*reinterpret_cast<std::uint32_t *>(conn->buffer.data());
boost::endian::big_to_native_inplace(to_read);
read_packet(c, to_read);
read_packet(conn, to_read);
}
});
}
void packet_server::read_packet(std::shared_ptr<connection> c,
void packet_server::read_packet(std::shared_ptr<connection> conn,
std::uint32_t data_size) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
const auto read_buffer = [&]() {
std::uint32_t offset = 0u;
while (offset < c->buffer.size()) {
std::uint32_t offset{};
while (offset < conn->buffer.size()) {
const auto bytes_read = boost::asio::read(
c->socket,
boost::asio::buffer(&c->buffer[offset], c->buffer.size() - offset));
conn->socket, boost::asio::buffer(&conn->buffer[offset],
conn->buffer.size() - offset));
if (bytes_read <= 0) {
throw std::runtime_error("read failed|" + std::to_string(bytes_read));
}
@@ -152,46 +161,48 @@ void packet_server::read_packet(std::shared_ptr<connection> c,
auto should_send_response = true;
auto response = std::make_shared<packet>();
c->buffer.resize(data_size);
conn->buffer.resize(data_size);
read_buffer();
packet::error_type ret;
auto request = std::make_shared<packet>(c->buffer);
packet::error_type ret{};
auto request = std::make_shared<packet>(conn->buffer);
if (request->decrypt(encryption_token_) == 0) {
std::string nonce;
if ((ret = request->decode(nonce)) == 0) {
if (nonce != c->nonce) {
ret = request->decode(nonce);
if (ret == 0) {
if (nonce != conn->nonce) {
throw std::runtime_error("invalid nonce");
}
c->generate_nonce();
conn->generate_nonce();
std::string version;
if ((ret = request->decode(version)) == 0) {
ret = request->decode(version);
if (ret == 0) {
if (utils::compare_version_strings(
version, REPERTORY_MIN_REMOTE_VERSION) >= 0) {
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
DECODE_OR_IGNORE(request, service_flags);
std::string client_id;
DECODE_OR_IGNORE(request, client_id);
std::uint64_t thread_id = 0u;
std::uint64_t thread_id{};
DECODE_OR_IGNORE(request, thread_id);
std::string method;
DECODE_OR_IGNORE(request, method);
if (ret == 0) {
if (c->client_id.empty()) {
add_client(*c, client_id);
if (conn->client_id.empty()) {
add_client(*conn, client_id);
}
should_send_response = false;
message_handler_(service_flags, client_id, thread_id, method,
request.get(), *response,
[this, c, request,
[this, conn, request,
response](const packet::error_type &result) {
this->send_response(c, result, *response);
this->send_response(conn, result, *response);
});
}
} else {
@@ -207,43 +218,43 @@ void packet_server::read_packet(std::shared_ptr<connection> c,
throw std::runtime_error("decryption failed");
}
if (should_send_response) {
send_response(c, ret, *response);
send_response(conn, ret, *response);
}
} catch (const std::exception &e) {
remove_client(*c);
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
remove_client(*conn);
utils::error::raise_error(function_name, e, "exception occurred");
}
}
void packet_server::remove_client(connection &c) {
if (not c.client_id.empty()) {
void packet_server::remove_client(connection &conn) {
if (not conn.client_id.empty()) {
recur_mutex_lock connection_lock(connection_mutex_);
if (not --connection_lookup_[c.client_id]) {
connection_lookup_.erase(c.client_id);
closed_(c.client_id);
if (--connection_lookup_[conn.client_id] == 0U) {
connection_lookup_.erase(conn.client_id);
closed_(conn.client_id);
}
}
}
void packet_server::send_response(std::shared_ptr<connection> c,
void packet_server::send_response(std::shared_ptr<connection> conn,
const packet::error_type &result,
packet &response) {
static const std::string function_name = __FUNCTION__;
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
response.encode_top(result);
response.encode_top(PACKET_SERVICE_FLAGS);
response.encode_top(c->nonce);
response.encode_top(conn->nonce);
response.encrypt(encryption_token_);
response.transfer_into(c->buffer);
response.transfer_into(conn->buffer);
boost::asio::async_write(
c->socket, boost::asio::buffer(c->buffer),
[this, c](boost::system::error_code ec, std::size_t /*length*/) {
if (ec) {
remove_client(*c);
utils::error::raise_error(function_name, ec.message());
conn->socket, boost::asio::buffer(conn->buffer),
[this, conn](boost::system::error_code err, std::size_t /*length*/) {
if (err) {
remove_client(*conn);
utils::error::raise_error(function_name, err.message());
} else {
read_header(c);
read_header(conn);
}
});
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -49,7 +49,11 @@ void repertory_init() {
}
curl_global_init(CURL_GLOBAL_DEFAULT);
sqlite3_initialize();
}
void repertory_shutdown() { curl_global_cleanup(); }
void repertory_shutdown() {
curl_global_cleanup();
sqlite3_shutdown();
}
} // namespace repertory

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -31,6 +31,8 @@ auto directory_iterator::fill_buffer(const remote::file_offset &offset,
void *buffer,
populate_stat_callback populate_stat)
-> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (offset < items_.size()) {
try {
std::string item_name;
@@ -54,16 +56,18 @@ auto directory_iterator::fill_buffer(const remote::file_offset &offset,
}
#if FUSE_USE_VERSION >= 30
if (filler_function(buffer, &item_name[0], pst, offset + 1,
if (filler_function(buffer, item_name.data(), pst,
static_cast<off_t>(offset + 1),
FUSE_FILL_DIR_PLUS) != 0) {
#else
if (filler_function(buffer, &item_name[0], pst, offset + 1) != 0) {
if (filler_function(buffer, item_name.data(), pst,
static_cast<off_t>(offset + 1)) != 0) {
#endif
errno = ENOMEM;
return -1;
}
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e,
utils::error::raise_error(function_name, e,
"failed to fill fuse directory buffer");
}
@@ -121,13 +125,14 @@ auto directory_iterator::get_json(std::size_t offset, json &item) -> int {
auto directory_iterator::get_next_directory_offset(
const std::string &api_path) const -> std::size_t {
const auto it = std::find_if(
items_.begin(), items_.end(),
[&api_path](const auto &di) -> bool { return api_path == di.api_path; });
const auto iter = std::find_if(items_.begin(), items_.end(),
[&api_path](const auto &dir_item) -> bool {
return api_path == dir_item.api_path;
});
return (it == items_.end())
? 0
: std::distance(items_.begin(), it) + std::size_t(1u);
return (iter == items_.end()) ? 0U
: static_cast<std::size_t>(
std::distance(items_.begin(), iter) + 1);
}
auto directory_iterator::operator=(const directory_iterator &iterator) noexcept

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -33,31 +33,34 @@
namespace repertory {
auto eviction::check_minimum_requirements(const std::string &file_path)
-> bool {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
std::uint64_t file_size{};
if (not utils::file::get_file_size(file_path, file_size)) {
utils::error::raise_error(__FUNCTION__, utils::get_last_error_code(),
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) {
if (file_size != 0U) {
std::uint64_t reference_time{};
if ((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))) {
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) {
#ifdef _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(reference_time) + delay) <=
now);
ret = ((std::chrono::system_clock::from_time_t(
static_cast<time_t>(reference_time)) +
delay) <= now);
#else
const auto now = utils::get_time_now();
const auto delay =
(config_.get_eviction_delay_mins() * 60L) * NANOS_PER_SECOND;
ret = ((reference_time + delay) <= now);
ret = ((reference_time + static_cast<std::uint64_t>(delay)) <= now);
#endif
}
}
@@ -77,6 +80,8 @@ auto eviction::get_filtered_cached_files() -> std::deque<std::string> {
}
void eviction::service_function() {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto should_evict = true;
// Handle maximum cache size eviction
@@ -116,13 +121,13 @@ void eviction::service_function() {
}
} else {
utils::error::raise_api_path_error(
__FUNCTION__, file.api_path, file.source_path,
function_name, file.api_path, file.source_path,
utils::get_last_error_code(), "failed to get file size");
}
}
}
} catch (const std::exception &ex) {
utils::error::raise_error(__FUNCTION__, ex,
utils::error::raise_error(function_name, ex,
"failed to process cached file|sp|" +
cached_files_list.front());
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -19,6 +19,7 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "common.hpp"
#ifndef _WIN32
#include "drives/fuse/fuse_base.hpp"
@@ -28,6 +29,7 @@
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "providers/i_provider.hpp"
#include "utils/file_utils.hpp"
#include "utils/path_utils.hpp"
#include "utils/string_utils.hpp"
#include "utils/utils.hpp"
@@ -99,16 +101,20 @@ fuse_base::fuse_base(app_config &config) : config_(config) {
fuse_base::~fuse_base() { E_CONSUMER_RELEASE(); }
auto fuse_base::access_(const char *path, int mask) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().access_impl(api_path, mask);
});
}
#ifdef __APPLE__
auto fuse_base::chflags_(const char *path, uint32_t flags) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chflags_impl(api_path, flags);
});
}
@@ -117,15 +123,19 @@ auto fuse_base::chflags_(const char *path, uint32_t flags) -> int {
#if FUSE_USE_VERSION >= 30
auto fuse_base::chmod_(const char *path, mode_t mode, struct fuse_file_info *fi)
-> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chmod_impl(api_path, mode, fi);
});
}
#else
auto fuse_base::chmod_(const char *path, mode_t mode) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chmod_impl(api_path, mode);
});
}
@@ -134,15 +144,19 @@ auto fuse_base::chmod_(const char *path, mode_t mode) -> int {
#if FUSE_USE_VERSION >= 30
auto fuse_base::chown_(const char *path, uid_t uid, gid_t gid,
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chown_impl(api_path, uid, gid, fi);
});
}
#else
auto fuse_base::chown_(const char *path, uid_t uid, gid_t gid) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().chown_impl(api_path, uid, gid);
});
}
@@ -150,16 +164,22 @@ auto fuse_base::chown_(const char *path, uid_t uid, gid_t gid) -> int {
auto fuse_base::create_(const char *path, mode_t mode,
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().create_impl(api_path, mode, fi);
});
}
void fuse_base::destroy_(void *ptr) {
execute_void_callback(__FUNCTION__, [&]() { instance().destroy_impl(ptr); });
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
execute_void_callback(function_name, [&]() { instance().destroy_impl(ptr); });
}
void fuse_base::destroy_impl(void * /* ptr */) { repertory_shutdown(); }
void fuse_base::display_options(
[[maybe_unused]] std::vector<const char *> args) {
#if FUSE_USE_VERSION >= 30
@@ -176,7 +196,7 @@ void fuse_base::display_options(
void fuse_base::display_version_information(std::vector<const char *> args) {
struct fuse_operations fuse_ops {};
fuse_main(args.size(),
fuse_main(static_cast<int>(args.size()),
reinterpret_cast<char **>(const_cast<char **>(args.data())),
&fuse_ops, nullptr);
}
@@ -224,8 +244,10 @@ auto fuse_base::execute_void_pointer_callback(const std::string &function_name,
auto fuse_base::fallocate_(const char *path, int mode, off_t offset,
off_t length, struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().fallocate_impl(api_path, mode, offset, length, fi);
});
}
@@ -233,8 +255,10 @@ auto fuse_base::fallocate_(const char *path, int mode, off_t offset,
#if FUSE_USE_VERSION < 30
auto fuse_base::fgetattr_(const char *path, struct stat *st,
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().fgetattr_impl(api_path, st, fi);
});
}
@@ -243,8 +267,10 @@ auto fuse_base::fgetattr_(const char *path, struct stat *st,
#ifdef __APPLE__
auto fuse_base::fsetattr_x_(const char *path, struct setattr_x *attr,
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().fsetattr_x_impl(api_path, attr, fi);
});
}
@@ -252,8 +278,10 @@ auto fuse_base::fsetattr_x_(const char *path, struct setattr_x *attr,
auto fuse_base::fsync_(const char *path, int datasync,
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().fsync_impl(api_path, datasync, fi);
});
}
@@ -261,8 +289,10 @@ auto fuse_base::fsync_(const char *path, int datasync,
#if FUSE_USE_VERSION < 30
auto fuse_base::ftruncate_(const char *path, off_t size,
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().ftruncate_impl(api_path, size, fi);
});
}
@@ -271,15 +301,19 @@ auto fuse_base::ftruncate_(const char *path, off_t size,
#if FUSE_USE_VERSION >= 30
auto fuse_base::getattr_(const char *path, struct stat *st,
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getattr_impl(api_path, st, fi);
});
}
#else
auto fuse_base::getattr_(const char *path, struct stat *st) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getattr_impl(api_path, st);
});
}
@@ -288,8 +322,10 @@ auto fuse_base::getattr_(const char *path, struct stat *st) -> int {
#ifdef __APPLE__
auto fuse_base::getxtimes_(const char *path, struct timespec *bkuptime,
struct timespec *crtime) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getxtimes_impl(api_path, bkuptime, crtime);
});
}
@@ -298,20 +334,27 @@ auto fuse_base::getxtimes_(const char *path, struct timespec *bkuptime,
#if FUSE_USE_VERSION >= 30
auto fuse_base::init_(struct fuse_conn_info *conn, struct fuse_config *cfg)
-> void * {
return execute_void_pointer_callback(__FUNCTION__, [&]() -> void * {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return execute_void_pointer_callback(function_name, [&]() -> void * {
return instance().init_impl(conn, cfg);
});
}
#else
auto fuse_base::init_(struct fuse_conn_info *conn) -> void * {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return execute_void_pointer_callback(
__FUNCTION__, [&]() -> void * { return instance().init_impl(conn); });
function_name, [&]() -> void * { return instance().init_impl(conn); });
}
#endif
#if FUSE_USE_VERSION >= 30
auto fuse_base::init_impl([[maybe_unused]] struct fuse_conn_info *conn,
struct fuse_config *cfg) -> void * {
utils::file::change_to_process_directory();
repertory_init();
#ifdef __APPLE__
conn->want |= FUSE_CAP_VOL_RENAME;
conn->want |= FUSE_CAP_XTIMES;
@@ -324,6 +367,9 @@ auto fuse_base::init_impl([[maybe_unused]] struct fuse_conn_info *conn,
}
#else
auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * {
utils::file::change_to_process_directory();
repertory_init();
#ifdef __APPLE__
conn->want |= FUSE_CAP_VOL_RENAME;
conn->want |= FUSE_CAP_XTIMES;
@@ -336,8 +382,10 @@ auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * {
#endif
auto fuse_base::mkdir_(const char *path, mode_t mode) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().mkdir_impl(api_path, mode);
});
}
@@ -351,8 +399,9 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
}
{
struct fuse_args fa = FUSE_ARGS_INIT(static_cast<int>(fuse_argv.size()),
(char **)&fuse_argv[0]);
struct fuse_args fa = FUSE_ARGS_INIT(
static_cast<int>(fuse_argv.size()),
reinterpret_cast<char **>(const_cast<char **>(fuse_argv.data())));
char *mount_location{nullptr};
#if FUSE_USE_VERSION >= 30
@@ -374,8 +423,10 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
#if FUSE_USE_VERSION < 30
umask(0);
#endif
ret = fuse_main(static_cast<int>(fuse_argv.size()), (char **)&fuse_argv[0],
&fuse_ops_, this);
ret = fuse_main(
static_cast<int>(fuse_argv.size()),
reinterpret_cast<char **>(const_cast<char **>(fuse_argv.data())),
&fuse_ops_, this);
notify_fuse_main_exit(ret);
}
@@ -383,24 +434,30 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
}
auto fuse_base::open_(const char *path, struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().open_impl(api_path, fi);
});
}
auto fuse_base::opendir_(const char *path, struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().opendir_impl(api_path, fi);
});
}
auto fuse_base::read_(const char *path, char *buffer, size_t read_size,
off_t read_offset, struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
std::size_t bytes_read{};
const auto res = instance().execute_callback(
__FUNCTION__, path,
function_name, path,
[&](const std::string &api_path) -> api_error {
return instance().read_impl(api_path, buffer, read_size, read_offset,
fi, bytes_read);
@@ -414,8 +471,10 @@ auto fuse_base::readdir_(const char *path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi, fuse_readdir_flags flags)
-> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().readdir_impl(api_path, buf, fuse_fill_dir, offset, fi,
flags);
});
@@ -424,8 +483,10 @@ auto fuse_base::readdir_(const char *path, void *buf,
auto fuse_base::readdir_(const char *path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().readdir_impl(api_path, buf, fuse_fill_dir, offset,
fi);
});
@@ -433,16 +494,20 @@ auto fuse_base::readdir_(const char *path, void *buf,
#endif
auto fuse_base::release_(const char *path, struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().release_impl(api_path, fi);
});
}
auto fuse_base::releasedir_(const char *path, struct fuse_file_info *fi)
-> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().releasedir_impl(api_path, fi);
});
}
@@ -450,8 +515,10 @@ auto fuse_base::releasedir_(const char *path, struct fuse_file_info *fi)
#if FUSE_USE_VERSION >= 30
auto fuse_base::rename_(const char *from, const char *to, unsigned int flags)
-> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, from, to,
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);
@@ -459,8 +526,10 @@ auto fuse_base::rename_(const char *from, const char *to, unsigned int flags)
}
#else
auto fuse_base::rename_(const char *from, const char *to) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, from, to,
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);
@@ -469,8 +538,10 @@ auto fuse_base::rename_(const char *from, const char *to) -> int {
#endif
auto fuse_base::rmdir_(const char *path) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().rmdir_impl(api_path);
});
}
@@ -479,9 +550,11 @@ auto fuse_base::rmdir_(const char *path) -> int {
#ifdef __APPLE__
auto fuse_base::getxattr_(const char *path, const char *name, char *value,
size_t size, uint32_t position) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
int attribute_size = 0;
const auto res = instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getxattr_impl(api_path, name, value, size, position,
attribute_size);
});
@@ -491,9 +564,11 @@ auto fuse_base::getxattr_(const char *path, const char *name, char *value,
#else // __APPLE__
auto fuse_base::getxattr_(const char *path, const char *name, char *value,
size_t size) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
int attribute_size = 0;
const auto res = instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().getxattr_impl(api_path, name, value, size,
attribute_size);
});
@@ -503,11 +578,13 @@ auto fuse_base::getxattr_(const char *path, const char *name, char *value,
#endif // __APPLE__
auto fuse_base::listxattr_(const char *path, char *buffer, size_t size) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
int required_size = 0;
bool return_size = false;
const auto res = instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().listxattr_impl(api_path, buffer, size, required_size,
return_size);
});
@@ -620,8 +697,10 @@ void fuse_base::raise_fuse_event(std::string function_name,
}
auto fuse_base::removexattr_(const char *path, const char *name) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().removexattr_impl(api_path, name);
});
}
@@ -629,8 +708,10 @@ auto fuse_base::removexattr_(const char *path, const char *name) -> int {
#ifdef __APPLE__
auto fuse_base::setxattr_(const char *path, const char *name, const char *value,
size_t size, int flags, uint32_t position) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const auto res = instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setxattr_impl(api_path, name, value, size, flags,
position);
});
@@ -643,8 +724,10 @@ auto fuse_base::setxattr_(const char *path, const char *name, const char *value,
#else // __APPLE__
auto fuse_base::setxattr_(const char *path, const char *name, const char *value,
size_t size, int flags) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const auto res = instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setxattr_impl(api_path, name, value, size, flags);
});
if (res != 0) {
@@ -664,53 +747,67 @@ void fuse_base::shutdown() {
#ifdef __APPLE__
auto fuse_base::setattr_x_(const char *path, struct setattr_x *attr) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setattr_x_impl(api_path, attr);
});
}
auto fuse_base::setbkuptime_(const char *path, const struct timespec *bkuptime)
-> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setbkuptime_impl(api_path, bkuptime);
});
}
auto fuse_base::setchgtime_(const char *path, const struct timespec *chgtime)
-> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setchgtime_impl(api_path, chgtime);
});
}
auto fuse_base::setcrtime_(const char *path, const struct timespec *crtime)
-> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().setcrtime_impl(api_path, crtime);
});
}
auto fuse_base::setvolname_(const char *volname) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, volname, [&](const std::string &api_path) -> api_error {
function_name, volname, [&](const std::string &api_path) -> api_error {
return instance().setvolname_impl(volname);
});
}
auto fuse_base::statfs_x_(const char *path, struct statfs *stbuf) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().statfs_x_impl(api_path, stbuf);
});
}
#else // __APPLE__
auto fuse_base::statfs_(const char *path, struct statvfs *stbuf) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().statfs_impl(api_path, stbuf);
});
}
@@ -719,23 +816,29 @@ auto fuse_base::statfs_(const char *path, struct statvfs *stbuf) -> int {
#if FUSE_USE_VERSION >= 30
auto fuse_base::truncate_(const char *path, off_t size,
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().truncate_impl(api_path, size, fi);
});
}
#else
auto fuse_base::truncate_(const char *path, off_t size) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().truncate_impl(api_path, size);
});
}
#endif
auto fuse_base::unlink_(const char *path) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().unlink_impl(api_path);
});
}
@@ -757,15 +860,19 @@ auto fuse_base::unmount(const std::string &mount_location) -> int {
#if FUSE_USE_VERSION >= 30
auto fuse_base::utimens_(const char *path, const struct timespec tv[2],
struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().utimens_impl(api_path, tv, fi);
});
}
#else
auto fuse_base::utimens_(const char *path, const struct timespec tv[2]) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
return instance().execute_callback(
__FUNCTION__, path, [&](const std::string &api_path) -> api_error {
function_name, path, [&](const std::string &api_path) -> api_error {
return instance().utimens_impl(api_path, tv);
});
}
@@ -773,10 +880,12 @@ auto fuse_base::utimens_(const char *path, const struct timespec tv[2]) -> int {
auto fuse_base::write_(const char *path, const char *buffer, size_t write_size,
off_t write_offset, struct fuse_file_info *fi) -> int {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
std::size_t bytes_written{};
const auto res = instance().execute_callback(
__FUNCTION__, path,
function_name, path,
[&](const std::string &api_path) -> api_error {
return instance().write_impl(api_path, buffer, write_size, write_offset,
fi, bytes_written);

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -204,7 +204,9 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode,
return api_error::success;
}
void fuse_drive::destroy_impl(void * /* ptr */) {
void fuse_drive::destroy_impl(void *ptr) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
event_system::instance().raise<drive_unmount_pending>(get_mount_location());
remote_server_.reset();
@@ -240,8 +242,10 @@ void fuse_drive::destroy_impl(void * /* ptr */) {
config_.save();
if (not lock_data_.set_mount_state(false, "", -1)) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
fuse_base::destroy_impl(ptr);
}
auto fuse_drive::fallocate_impl(std::string /*api_path*/, int mode,
@@ -387,10 +391,12 @@ auto fuse_drive::get_directory_item_count(const std::string &api_path) const
auto fuse_drive::get_directory_items(const std::string &api_path) const
-> directory_item_list {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
directory_item_list list{};
auto res = provider_.get_directory_items(api_path, list);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to get directory items");
}
@@ -399,10 +405,12 @@ auto fuse_drive::get_directory_items(const std::string &api_path) const
auto fuse_drive::get_file_size(const std::string &api_path) const
-> std::uint64_t {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
std::uint64_t file_size{};
auto res = provider_.get_file_size(api_path, file_size);
if (res == api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to get file size from provider");
}
@@ -519,7 +527,13 @@ auto fuse_drive::init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
#else
void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
#endif
utils::file::change_to_process_directory();
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
#if FUSE_USE_VERSION >= 30
auto *ret = fuse_drive_base::init_impl(conn, cfg);
#else
auto *ret = fuse_drive_base::init_impl(conn);
#endif
if (console_enabled_) {
console_consumer_ = std::make_unique<console_consumer>();
@@ -562,22 +576,18 @@ void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
}
if (not lock_data_.set_mount_state(true, get_mount_location(), getpid())) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
event_system::instance().raise<drive_mounted>(get_mount_location());
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception during fuse init");
utils::error::raise_error(function_name, e, "exception during fuse init");
destroy_impl(this);
fuse_exit(fuse_get_context()->fuse);
}
#if FUSE_USE_VERSION >= 30
return fuse_drive_base::init_impl(conn, cfg);
#else
return fuse_drive_base::init_impl(conn);
#endif
return ret;
}
auto fuse_drive::is_processing(const std::string &api_path) const -> bool {
@@ -585,6 +595,8 @@ auto fuse_drive::is_processing(const std::string &api_path) const -> bool {
}
auto fuse_drive::mkdir_impl(std::string api_path, mode_t mode) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto res = check_parent_access(api_path, W_OK | X_OK);
if (res != api_error::success) {
return res;
@@ -594,17 +606,18 @@ auto fuse_drive::mkdir_impl(std::string api_path, mode_t mode) -> api_error {
auto meta = create_meta_attributes(now, FILE_ATTRIBUTE_DIRECTORY, now, now,
true, get_effective_gid(), "", mode, now,
0U, 0U, 0U, "", get_effective_uid(), now);
if ((res = provider_.create_directory(api_path, meta)) !=
api_error::success) {
res = provider_.create_directory(api_path, meta);
if (res != api_error::success) {
return res;
}
if (api_path != "/") {
if ((res = provider_.set_item_meta(
utils::path::get_parent_api_path(api_path), META_MODIFIED,
std::to_string(now))) != api_error::success) {
res = provider_.set_item_meta(utils::path::get_parent_api_path(api_path),
META_MODIFIED, std::to_string(now));
if (res != api_error::success) {
utils::error::raise_api_path_error(
__FUNCTION__, api_path, res, "failed to set directory modified time");
function_name, api_path, res,
"failed to set directory modified time");
}
}
@@ -661,13 +674,6 @@ auto fuse_drive::opendir_impl(std::string api_path,
return api_error::success;
}
void fuse_drive::populate_stat(const directory_item &dir_item,
struct stat &st) const {
fuse_drive_base::populate_stat(dir_item.api_path, dir_item.size,
dir_item.meta, dir_item.directory, provider_,
&st);
}
auto fuse_drive::read_impl(std::string api_path, char *buffer, size_t read_size,
off_t read_offset, struct fuse_file_info *file_info,
std::size_t &bytes_read) -> api_error {
@@ -910,8 +916,8 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
#endif
const auto attribute_name_size = strlen(attribute_name.c_str()) + 1U;
if (size >= attribute_name_size) {
strncpy(&buffer[required_size], attribute_name.c_str(),
attribute_name_size);
std::memcpy(&buffer[required_size], attribute_name.data(),
attribute_name_size);
size -= attribute_name_size;
} else {
res = api_error::xattr_buffer_small;
@@ -1024,9 +1030,11 @@ auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
void fuse_drive::set_item_meta(const std::string &api_path,
const std::string &key,
const std::string &value) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto res = provider_.set_item_meta(api_path, key, value);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"key|" + key + "|value|" + value);
}
}
@@ -1187,10 +1195,11 @@ auto fuse_drive::statfs_x_impl(std::string /*api_path*/, struct statfs *stbuf)
stbuf->f_files = 4294967295;
stbuf->f_ffree = stbuf->f_files - provider_.get_total_item_count();
stbuf->f_owner = getuid();
strncpy(&stbuf->f_mntonname[0], get_mount_location().c_str(), MNAMELEN);
strncpy(&stbuf->f_mntfromname[0],
strncpy(&stbuf->f_mntonname[0U], get_mount_location().c_str(),
get_mount_location().size());
strncpy(&stbuf->f_mntfromname[0U],
(utils::create_volume_label(config_.get_provider_type())).c_str(),
MNAMELEN);
sizeof(stbuf->f_mntfromname) - 1U);
return api_error::success;
}
@@ -1203,11 +1212,10 @@ auto fuse_drive::statfs_impl(std::string /*api_path*/, struct statvfs *stbuf)
const auto total_bytes = provider_.get_total_drive_space();
const auto total_used = provider_.get_used_drive_space();
const auto used_blocks = utils::divide_with_ceiling(
total_used, static_cast<std::uint64_t>(stbuf->f_frsize));
const auto used_blocks =
utils::divide_with_ceiling(total_used, stbuf->f_frsize);
stbuf->f_files = 4294967295;
stbuf->f_blocks = utils::divide_with_ceiling(
total_bytes, static_cast<std::uint64_t>(stbuf->f_frsize));
stbuf->f_blocks = utils::divide_with_ceiling(total_bytes, stbuf->f_frsize);
stbuf->f_bavail = stbuf->f_bfree =
stbuf->f_blocks == 0U ? 0 : (stbuf->f_blocks - used_blocks);
stbuf->f_ffree = stbuf->f_favail =
@@ -1345,11 +1353,13 @@ auto fuse_drive::write_impl(std::string /*api_path*/
}
void fuse_drive::update_accessed_time(const std::string &api_path) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (atime_enabled_) {
auto res = provider_.set_item_meta(
api_path, META_ACCESSED, std::to_string(utils::get_file_time_now()));
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to set accessed time");
}
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -232,9 +232,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 t = utils::string::to_uint64(meta.at(name));
ts.tv_nsec = t % NANOS_PER_SECOND;
ts.tv_sec = t / NANOS_PER_SECOND;
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 fuse_drive_base::get_uid_from_meta(const api_meta_map &meta) -> uid_t {
@@ -304,22 +304,23 @@ void fuse_drive_base::populate_stat(const std::string &api_path,
const api_meta_map &meta, bool directory,
i_provider &provider, struct stat *st) {
memset(st, 0, sizeof(struct stat));
st->st_nlink =
(directory
? 2 + (size_or_count ? size_or_count
: provider.get_directory_item_count(api_path))
: 1);
st->st_nlink = static_cast<nlink_t>(
directory ? 2 + (size_or_count == 0U
? provider.get_directory_item_count(api_path)
: size_or_count)
: 1);
if (directory) {
st->st_blocks = 0;
} else {
st->st_size = size_or_count;
static const auto block_size_stat = static_cast<std::uint64_t>(512u);
static const auto block_size = static_cast<std::uint64_t>(4096u);
st->st_size = static_cast<off_t>(size_or_count);
static const auto block_size_stat = static_cast<std::uint64_t>(512U);
static const auto block_size = static_cast<std::uint64_t>(4096U);
const auto size = utils::divide_with_ceiling(
static_cast<std::uint64_t>(st->st_size), block_size) *
block_size;
st->st_blocks = std::max(block_size / block_size_stat,
utils::divide_with_ceiling(size, block_size_stat));
st->st_blocks = static_cast<blkcnt_t>(
std::max(block_size / block_size_stat,
utils::divide_with_ceiling(size, block_size_stat)));
}
st->st_gid = get_gid_from_meta(meta);
st->st_mode = (directory ? S_IFDIR : S_IFREG) | get_mode_from_meta(meta);
@@ -344,9 +345,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 t = utils::string::to_uint64(meta.at(name));
ts.tv_nsec = t % NANOS_PER_SECOND;
ts.tv_sec = t / NANOS_PER_SECOND;
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;
}
} // namespace repertory

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -36,49 +36,59 @@ remote_client::remote_client(const app_config &config)
auto remote_client::fuse_access(const char *path, const std::int32_t &mask)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(mask);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_chflags(const char *path, std::uint32_t flags)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(flags);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_chmod(const char *path, const remote::file_mode &mode)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(mode);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_chown(const char *path, const remote::user_id &uid,
const remote::group_id &gid)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(uid);
request.encode(gid);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_destroy() -> packet::error_type {
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, service_flags);
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
std::uint32_t service_flags{};
return packet_client_.send(function_name, service_flags);
}
/*packet::error_type remote_client::fuse_fallocate(const char *path, const
@@ -90,14 +100,16 @@ std::int32_t &mode, const remote::file_offset &offset, const remote::file_offset
request.encode(length);
request.encode(handle);
std::uint32_t service_flags = 0u;
return packetClient_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags {};
return packetClient_.send(function_name, request, service_flags);
}*/
auto remote_client::fuse_fgetattr(const char *path, remote::stat &st,
bool &directory,
const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(handle);
@@ -105,12 +117,12 @@ auto remote_client::fuse_fgetattr(const char *path, remote::stat &st,
request.encode(gid_);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
if ((ret = response.decode(st)) == 0) {
std::uint8_t d = 0u;
std::uint8_t d{};
if ((ret = response.decode(d)) == 0) {
directory = static_cast<bool>(d);
}
@@ -124,51 +136,59 @@ auto remote_client::fuse_fsetattr_x(const char *path,
const remote::setattr_x &attr,
const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(attr);
request.encode(handle);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_fsync(const char *path, const std::int32_t &datasync,
const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(datasync);
request.encode(handle);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_ftruncate(const char *path,
const remote::file_offset &size,
const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(size);
request.encode(handle);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_getattr(const char *path, remote::stat &st,
bool &directory) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(uid_);
request.encode(gid_);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
if ((ret = response.decode(st)) == 0) {
std::uint8_t d = 0;
@@ -188,8 +208,8 @@ packet request; request.encode(path); request.encode(name);
request.encode(size);
packet response;
std::uint32_t service_flags = 0u;
if ((ret = packetClient_.send(__FUNCTION__, request, response,
std::uint32_t service_flags {};
if ((ret = packetClient_.send(function_name, request, response,
service_flags)) == 0) { remote::file_size size2; if ((ret =
response.decode(size2)) == 0) { if (size2 >
std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else { memcpy(value,
@@ -211,8 +231,8 @@ packet::error_type ret = 0; if (size > std::numeric_limits<std::size_t>::max())
request.encode(position);
packet response;
std::uint32_t service_flags = 0u;
if ((ret = packetClient_.send(__FUNCTION__, request, response,
std::uint32_t service_flags {};
if ((ret = packetClient_.send(function_name, request, response,
service_flags)) == 0) { remote::file_size size2; if ((ret =
response.decode(size2)) == 0) { if (size2 >
std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else { memcpy(value,
@@ -229,13 +249,15 @@ auto remote_client::fuse_getxtimes(const char *path,
remote::file_time &bkuptime,
remote::file_time &crtime)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
DECODE_OR_RETURN(&response, bkuptime);
DECODE_OR_RETURN(&response, crtime);
@@ -245,8 +267,10 @@ auto remote_client::fuse_getxtimes(const char *path,
}
auto remote_client::fuse_init() -> packet::error_type {
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, service_flags);
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
std::uint32_t service_flags{};
return packet_client_.send(function_name, service_flags);
}
/*packet::error_type remote_client::fuse_listxattr(const char *path, char
@@ -255,8 +279,8 @@ std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else { packet
request; request.encode(path); request.encode(size);
packet response;
std::uint32_t service_flags = 0u;
if ((ret = packetClient_.send(__FUNCTION__, request, response,
std::uint32_t service_flags {};
if ((ret = packetClient_.send(function_name, request, response,
service_flags)) == 0) { remote::file_size size2; if ((ret =
response.decode(size2)) == 0) { if (size2 >
std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else {
@@ -272,23 +296,27 @@ static_cast<std::size_t>(size2));
auto remote_client::fuse_mkdir(const char *path, const remote::file_mode &mode)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(mode);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_opendir(const char *path, remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
ret = response.decode(handle);
}
@@ -300,15 +328,17 @@ auto remote_client::fuse_create(const char *path, const remote::file_mode &mode,
const remote::open_flags &flags,
remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(mode);
request.encode(flags);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
ret = response.decode(handle);
}
@@ -319,14 +349,16 @@ auto remote_client::fuse_create(const char *path, const remote::file_mode &mode,
auto remote_client::fuse_open(const char *path, const remote::open_flags &flags,
remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(flags);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
ret = response.decode(handle);
}
@@ -339,6 +371,8 @@ auto remote_client::fuse_read(const char *path, char *buffer,
const remote::file_offset &read_offset,
const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(read_size);
@@ -346,11 +380,11 @@ auto remote_client::fuse_read(const char *path, char *buffer,
request.encode(handle);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret > 0) {
memcpy(buffer, response.current_pointer(), ret);
memcpy(buffer, response.current_pointer(), static_cast<std::size_t>(ret));
}
return ret;
@@ -358,12 +392,14 @@ auto remote_client::fuse_read(const char *path, char *buffer,
auto remote_client::fuse_rename(const char *from, const char *to)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(from);
request.encode(to);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_write(const char *path, const char *buffer,
@@ -371,6 +407,8 @@ auto remote_client::fuse_write(const char *path, const char *buffer,
const remote::file_offset &write_offset,
const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (write_size > std::numeric_limits<std::size_t>::max()) {
return -ERANGE;
}
@@ -382,8 +420,8 @@ auto remote_client::fuse_write(const char *path, const char *buffer,
request.encode(write_offset);
request.encode(handle);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_write_base64(const char *path, const char *buffer,
@@ -391,6 +429,8 @@ auto remote_client::fuse_write_base64(const char *path, const char *buffer,
const remote::file_offset &write_offset,
const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (write_size > std::numeric_limits<std::size_t>::max()) {
return -ERANGE;
}
@@ -402,23 +442,25 @@ auto remote_client::fuse_write_base64(const char *path, const char *buffer,
request.encode(write_offset);
request.encode(handle);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_readdir(const char *path,
const remote::file_offset &offset,
const remote::file_handle &handle,
std::string &item_path) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(offset);
request.encode(handle);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
DECODE_OR_IGNORE(&response, item_path);
}
@@ -429,90 +471,106 @@ auto remote_client::fuse_readdir(const char *path,
auto remote_client::fuse_release(const char *path,
const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(handle);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_releasedir(const char *path,
const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(handle);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
/*packet::error_type remote_client::fuse_removexattr(const char *path, const
char *name) override { packet request; request.encode(path);
request.Encode(name);
std::uint32_t service_flags = 0u;
return packetClient_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags {};
return packetClient_.send(function_name, request, service_flags);
}*/
auto remote_client::fuse_rmdir(const char *path) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_setattr_x(const char *path, remote::setattr_x &attr)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(attr);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_setbkuptime(const char *path,
const remote::file_time &bkuptime)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(bkuptime);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_setchgtime(const char *path,
const remote::file_time &chgtime)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(chgtime);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_setcrtime(const char *path,
const remote::file_time &crtime)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(crtime);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_setvolname(const char *volname) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(volname);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
/*packet::error_type remote_client::fuse_setxattr(const char *path, const char
@@ -523,8 +581,8 @@ request; request.encode(path); request.encode(name); request.encode(size);
request.encode(value, static_cast<std::size_t>(size));
request.encode(flags);
std::uint32_t service_flags = 0u;
ret = packetClient_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags {};
ret = packetClient_.send(function_name, request, service_flags);
}
return ret;
@@ -538,8 +596,8 @@ packet request; request.encode(path); request.Encode(name);
request.Encode(size); request.encode(value, static_cast<std::size_t>(size));
request.encode(flags); request.encode(position);
std::uint32_t service_flags = 0u;
ret = packetClient_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags {};
ret = packetClient_.send(function_name, request, service_flags);
}
return ret;
@@ -547,14 +605,16 @@ request.encode(flags); request.encode(position);
auto remote_client::fuse_statfs(const char *path, std::uint64_t frsize,
remote::statfs &st) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(frsize);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
ret = response.decode(st);
}
@@ -564,14 +624,16 @@ auto remote_client::fuse_statfs(const char *path, std::uint64_t frsize,
auto remote_client::fuse_statfs_x(const char *path, std::uint64_t bsize,
remote::statfs_x &st) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(bsize);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
ret = response.decode(st);
}
@@ -582,45 +644,53 @@ auto remote_client::fuse_statfs_x(const char *path, std::uint64_t bsize,
auto remote_client::fuse_truncate(const char *path,
const remote::file_offset &size)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(size);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_unlink(const char *path) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::fuse_utimens(const char *path, const remote::file_time *tv,
std::uint64_t op0, std::uint64_t op1)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(&tv[0], sizeof(remote::file_time) * 2);
request.encode(op0);
request.encode(op1);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
auto remote_client::json_create_directory_snapshot(const std::string &path,
json &json_data)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
ret = packet::decode_json(response, json_data);
}
@@ -631,15 +701,17 @@ auto remote_client::json_create_directory_snapshot(const std::string &path,
auto remote_client::json_read_directory_snapshot(
const std::string &path, const remote::file_handle &handle,
std::uint32_t page, json &json_data) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(handle);
request.encode(page);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
ret = packet::decode_json(response, json_data);
}
@@ -650,12 +722,14 @@ auto remote_client::json_read_directory_snapshot(
auto remote_client::json_release_directory_snapshot(
const std::string &path, const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(handle);
std::uint32_t service_flags = 0u;
return packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags);
}
void remote_client::set_fuse_uid_gid(const remote::user_id &uid,

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -54,7 +54,7 @@ api_error remote_fuse_drive::chflags_impl(std::string api_path,
#if FUSE_USE_VERSION >= 30
auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode,
struct fuse_file_info * /*fi*/)
struct fuse_file_info * /*f_info*/)
-> api_error {
#else
auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode)
@@ -66,7 +66,7 @@ auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode)
#if FUSE_USE_VERSION >= 30
auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid,
struct fuse_file_info * /*fi*/)
struct fuse_file_info * /*f_info*/)
-> api_error {
#else
auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
@@ -77,14 +77,17 @@ auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
}
auto remote_fuse_drive::create_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi) -> api_error {
struct fuse_file_info *f_info)
-> api_error {
return utils::to_api_error(remote_instance_->fuse_create(
api_path.c_str(), static_cast<remote::file_mode>(mode),
remote::create_open_flags(static_cast<std::uint32_t>(fi->flags)),
fi->fh));
remote::create_open_flags(static_cast<std::uint32_t>(f_info->flags)),
f_info->fh));
}
void remote_fuse_drive::destroy_impl(void * /*ptr*/) {
void remote_fuse_drive::destroy_impl(void *ptr) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
event_system::instance().raise<drive_unmount_pending>(get_mount_location());
if (server_) {
@@ -95,7 +98,7 @@ void remote_fuse_drive::destroy_impl(void * /*ptr*/) {
if (remote_instance_) {
const auto res = remote_instance_->fuse_destroy();
if (res != 0) {
utils::error::raise_error(__FUNCTION__,
utils::error::raise_error(function_name,
"remote fuse_destroy() failed|err|" +
std::to_string(res));
}
@@ -103,21 +106,25 @@ void remote_fuse_drive::destroy_impl(void * /*ptr*/) {
}
if (not lock_data_.set_mount_state(false, "", -1)) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
event_system::instance().raise<drive_unmounted>(get_mount_location());
fuse_base::destroy_impl(ptr);
}
auto remote_fuse_drive::fgetattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi) -> api_error {
remote::stat r{};
auto remote_fuse_drive::fgetattr_impl(std::string api_path,
struct stat *unix_st,
struct fuse_file_info *f_info)
-> api_error {
remote::stat r_stat{};
auto directory = false;
const auto res =
remote_instance_->fuse_fgetattr(api_path.c_str(), r, directory, fi->fh);
const auto res = remote_instance_->fuse_fgetattr(api_path.c_str(), r_stat,
directory, f_info->fh);
if (res == 0) {
populate_stat(r, directory, *st);
populate_stat(r_stat, directory, *unix_st);
}
return utils::to_api_error(res);
@@ -126,7 +133,7 @@ auto remote_fuse_drive::fgetattr_impl(std::string api_path, struct stat *st,
#ifdef __APPLE__
api_error remote_fuse_drive::fsetattr_x_impl(std::string api_path,
struct setattr_x *attr,
struct fuse_file_info *fi) {
struct fuse_file_info *f_info) {
remote::setattr_x attributes{};
attributes.valid = attr->valid;
attributes.mode = attr->mode;
@@ -144,41 +151,42 @@ api_error remote_fuse_drive::fsetattr_x_impl(std::string api_path,
attributes.bkuptime =
((attr->bkuptime.tv_sec * 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, fi->fh));
return utils::to_api_error(remote_instance_->fuse_fsetattr_x(
api_path.c_str(), attributes, f_info->fh));
}
#endif
auto remote_fuse_drive::fsync_impl(std::string api_path, int datasync,
struct fuse_file_info *fi) -> api_error {
struct fuse_file_info *f_info) -> api_error {
return utils::to_api_error(
remote_instance_->fuse_fsync(api_path.c_str(), datasync, fi->fh));
remote_instance_->fuse_fsync(api_path.c_str(), datasync, f_info->fh));
}
#if FUSE_USE_VERSION < 30
auto remote_fuse_drive::ftruncate_impl(std::string api_path, off_t size,
struct fuse_file_info *fi) -> api_error {
struct fuse_file_info *f_info)
-> api_error {
return utils::to_api_error(
remote_instance_->fuse_ftruncate(api_path.c_str(), size, fi->fh));
remote_instance_->fuse_ftruncate(api_path.c_str(), size, f_info->fh));
}
#endif
#if FUSE_USE_VERSION >= 30
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info * /*fi*/)
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st,
struct fuse_file_info * /*f_info*/)
-> api_error {
#else
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *st)
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st)
-> api_error {
#endif
bool directory = false;
remote::stat r{};
remote::stat r_stat{};
const auto res =
remote_instance_->fuse_getattr(api_path.c_str(), r, directory);
remote_instance_->fuse_getattr(api_path.c_str(), r_stat, directory);
if (res == 0) {
populate_stat(r, directory, *st);
populate_stat(r_stat, directory, *unix_st);
}
return utils::to_api_error(res);
@@ -214,7 +222,14 @@ auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn,
#else
auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * {
#endif
utils::file::change_to_process_directory();
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
#if FUSE_USE_VERSION >= 30
auto *ret = fuse_base::init_impl(conn, cfg);
#else
auto *ret = fuse_base::init_impl(conn);
#endif
was_mounted_ = true;
if (console_enabled_) {
@@ -225,14 +240,14 @@ auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * {
event_system::instance().start();
if (not lock_data_.set_mount_state(true, get_mount_location(), getpid())) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
remote_instance_ = factory_();
remote_instance_->set_fuse_uid_gid(getuid(), getgid());
if (remote_instance_->fuse_init() != 0) {
utils::error::raise_error(__FUNCTION__,
utils::error::raise_error(function_name,
"failed to connect to remote server");
event_system::instance().raise<unmount_requested>();
} else {
@@ -241,11 +256,7 @@ auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * {
event_system::instance().raise<drive_mounted>(get_mount_location());
}
#if FUSE_USE_VERSION >= 30
return fuse_base::init_impl(conn, cfg);
#else
return fuse_base::init_impl(conn);
#endif
return ret;
}
auto remote_fuse_drive::mkdir_impl(std::string api_path, mode_t mode)
@@ -264,76 +275,88 @@ void remote_fuse_drive::notify_fuse_main_exit(int &ret) {
}
auto remote_fuse_drive::open_impl(std::string api_path,
struct fuse_file_info *fi) -> api_error {
struct fuse_file_info *f_info) -> api_error {
return utils::to_api_error(remote_instance_->fuse_open(
api_path.c_str(), remote::create_open_flags(fi->flags), fi->fh));
api_path.c_str(),
remote::create_open_flags(static_cast<std::uint32_t>(f_info->flags)),
f_info->fh));
}
auto remote_fuse_drive::opendir_impl(std::string api_path,
struct fuse_file_info *fi) -> api_error {
struct fuse_file_info *f_info)
-> api_error {
return utils::to_api_error(
remote_instance_->fuse_opendir(api_path.c_str(), fi->fh));
remote_instance_->fuse_opendir(api_path.c_str(), f_info->fh));
}
void remote_fuse_drive::populate_stat(const remote::stat &r, bool directory,
struct stat &st) {
memset(&st, 0, sizeof(struct stat));
void remote_fuse_drive::populate_stat(const remote::stat &r_stat,
bool directory, struct stat &unix_st) {
memset(&unix_st, 0, sizeof(struct stat));
#ifdef __APPLE__
st.st_blksize = 0;
unix_st.st_blksize = 0;
st.st_atimespec.tv_nsec = r.st_atimespec % NANOS_PER_SECOND;
st.st_atimespec.tv_sec = r.st_atimespec / NANOS_PER_SECOND;
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;
st.st_birthtimespec.tv_nsec = r.st_birthtimespec % NANOS_PER_SECOND;
st.st_birthtimespec.tv_sec = r.st_birthtimespec / 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;
st.st_ctimespec.tv_nsec = r.st_ctimespec % NANOS_PER_SECOND;
st.st_ctimespec.tv_sec = r.st_ctimespec / 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;
st.st_mtimespec.tv_nsec = r.st_mtimespec % NANOS_PER_SECOND;
st.st_mtimespec.tv_sec = r.st_mtimespec / 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;
st.st_flags = r.st_flags;
unix_st.st_flags = r_stat.st_flags;
#else
st.st_blksize = 4096;
unix_st.st_blksize = 4096;
st.st_atim.tv_nsec = r.st_atimespec % NANOS_PER_SECOND;
st.st_atim.tv_sec = r.st_atimespec / NANOS_PER_SECOND;
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);
st.st_ctim.tv_nsec = r.st_ctimespec % NANOS_PER_SECOND;
st.st_ctim.tv_sec = r.st_ctimespec / 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);
st.st_mtim.tv_nsec = r.st_mtimespec % NANOS_PER_SECOND;
st.st_mtim.tv_sec = r.st_mtimespec / NANOS_PER_SECOND;
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);
const auto size = utils::divide_with_ceiling(
static_cast<std::uint64_t>(st.st_size), block_size) *
block_size;
st.st_blocks = std::max(block_size / block_size_stat,
utils::divide_with_ceiling(size, block_size_stat));
const auto block_size_stat = static_cast<std::uint64_t>(512U);
const auto block_size = static_cast<std::uint64_t>(4096U);
const auto size =
utils::divide_with_ceiling(static_cast<std::uint64_t>(unix_st.st_size),
block_size) *
block_size;
unix_st.st_blocks = static_cast<blkcnt_t>(
std::max(block_size / block_size_stat,
utils::divide_with_ceiling(size, block_size_stat)));
}
st.st_gid = r.st_gid;
st.st_mode = (directory ? S_IFDIR : S_IFREG) | r.st_mode;
unix_st.st_gid = r_stat.st_gid;
unix_st.st_mode = (directory ? S_IFDIR : S_IFREG) | r_stat.st_mode;
st.st_nlink = r.st_nlink;
st.st_size = r.st_size;
st.st_uid = r.st_uid;
unix_st.st_nlink = r_stat.st_nlink;
unix_st.st_size = static_cast<off_t>(r_stat.st_size);
unix_st.st_uid = r_stat.st_uid;
}
auto remote_fuse_drive::read_impl(std::string api_path, char *buffer,
size_t read_size, off_t read_offset,
struct fuse_file_info *fi,
struct fuse_file_info *f_info,
std::size_t &bytes_read) -> api_error {
auto res = remote_instance_->fuse_read(api_path.c_str(), buffer, read_size,
read_offset, fi->fh);
auto res = remote_instance_->fuse_read(
api_path.c_str(), buffer, read_size,
static_cast<remote::file_offset>(read_offset), f_info->fh);
if (res >= 0) {
bytes_read = res;
bytes_read = static_cast<size_t>(res);
return api_error::success;
}
@@ -343,19 +366,22 @@ auto remote_fuse_drive::read_impl(std::string api_path, char *buffer,
#if FUSE_USE_VERSION >= 30
auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir,
off_t offset, struct fuse_file_info *fi,
off_t offset,
struct fuse_file_info *f_info,
fuse_readdir_flags /*flags*/)
-> api_error {
#else
auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir,
off_t offset, struct fuse_file_info *fi)
off_t offset,
struct fuse_file_info *f_info)
-> api_error {
#endif
std::string item_path;
int res = 0;
while ((res = remote_instance_->fuse_readdir(api_path.c_str(), offset, fi->fh,
item_path)) == 0) {
while ((res = remote_instance_->fuse_readdir(
api_path.c_str(), static_cast<remote::file_offset>(offset),
f_info->fh, item_path)) == 0) {
if ((item_path != ".") && (item_path != "..")) {
item_path = utils::path::strip_to_file_name(item_path);
}
@@ -378,16 +404,17 @@ auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf,
}
auto remote_fuse_drive::release_impl(std::string api_path,
struct fuse_file_info *fi) -> api_error {
struct fuse_file_info *f_info)
-> api_error {
return utils::to_api_error(
remote_instance_->fuse_release(api_path.c_str(), fi->fh));
remote_instance_->fuse_release(api_path.c_str(), f_info->fh));
}
auto remote_fuse_drive::releasedir_impl(std::string api_path,
struct fuse_file_info *fi)
struct fuse_file_info *f_info)
-> api_error {
return utils::to_api_error(
remote_instance_->fuse_releasedir(api_path.c_str(), fi->fh));
remote_instance_->fuse_releasedir(api_path.c_str(), f_info->fh));
}
#if FUSE_USE_VERSION >= 30
@@ -471,8 +498,8 @@ api_error remote_fuse_drive::statfs_x_impl(std::string api_path,
stbuf->f_ffree = r.f_ffree;
stbuf->f_files = r.f_files;
stbuf->f_owner = getuid();
strncpy(&stbuf->f_mntonname[0u], get_mount_location().c_str(), MNAMELEN);
strncpy(&stbuf->f_mntfromname[0u], &r.f_mntfromname[0], MNAMELEN);
strncpy(&stbuf->f_mntonname[0U], get_mount_location().c_str(), MNAMELEN);
strncpy(&stbuf->f_mntfromname[0U], &r.f_mntfromname[0U], MNAMELEN);
}
} else {
res = -errno;
@@ -485,15 +512,16 @@ auto remote_fuse_drive::statfs_impl(std::string api_path, struct statvfs *stbuf)
-> api_error {
auto res = statvfs(config_.get_data_directory().c_str(), stbuf);
if (res == 0) {
remote::statfs r{};
if ((res = remote_instance_->fuse_statfs(api_path.c_str(), stbuf->f_frsize,
r)) == 0) {
stbuf->f_blocks = r.f_blocks;
stbuf->f_bavail = r.f_bavail;
stbuf->f_bfree = r.f_bfree;
stbuf->f_ffree = r.f_ffree;
stbuf->f_favail = r.f_favail;
stbuf->f_files = r.f_files;
remote::statfs r_stat{};
res = remote_instance_->fuse_statfs(api_path.c_str(), stbuf->f_frsize,
r_stat);
if (res == 0) {
stbuf->f_blocks = r_stat.f_blocks;
stbuf->f_bavail = r_stat.f_bavail;
stbuf->f_bfree = r_stat.f_bfree;
stbuf->f_ffree = r_stat.f_ffree;
stbuf->f_favail = r_stat.f_favail;
stbuf->f_files = r_stat.f_files;
}
} else {
res = -errno;
@@ -505,14 +533,14 @@ auto remote_fuse_drive::statfs_impl(std::string api_path, struct statvfs *stbuf)
#if FUSE_USE_VERSION >= 30
auto remote_fuse_drive::truncate_impl(std::string api_path, off_t size,
struct fuse_file_info * /*fi*/)
struct fuse_file_info * /*f_info*/)
-> api_error {
#else
auto remote_fuse_drive::truncate_impl(std::string api_path, off_t size)
-> api_error {
#endif
return utils::to_api_error(
remote_instance_->fuse_truncate(api_path.c_str(), size));
return utils::to_api_error(remote_instance_->fuse_truncate(
api_path.c_str(), static_cast<remote::file_offset>(size)));
}
auto remote_fuse_drive::unlink_impl(std::string api_path) -> api_error {
@@ -522,31 +550,35 @@ auto remote_fuse_drive::unlink_impl(std::string api_path) -> api_error {
#if FUSE_USE_VERSION >= 30
auto remote_fuse_drive::utimens_impl(std::string api_path,
const struct timespec tv[2],
struct fuse_file_info * /*fi*/)
struct fuse_file_info * /*f_info*/)
-> api_error {
#else
auto remote_fuse_drive::utimens_impl(std::string api_path,
const struct timespec tv[2]) -> api_error {
#endif
remote::file_time rtv[2u] = {0};
if (tv) {
rtv[0u] = tv[0u].tv_nsec + (tv[0u].tv_sec * NANOS_PER_SECOND);
rtv[1u] = tv[1u].tv_nsec + (tv[1u].tv_sec * NANOS_PER_SECOND);
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));
}
return utils::to_api_error(remote_instance_->fuse_utimens(
api_path.c_str(), rtv, tv ? tv[0u].tv_nsec : 0u,
tv ? tv[1u].tv_nsec : 0u));
api_path.c_str(), &rtv[0U],
static_cast<std::uint64_t>(tv == nullptr ? 0 : tv[0U].tv_nsec),
static_cast<std::uint64_t>(tv == nullptr ? 0 : tv[1U].tv_nsec)));
}
auto remote_fuse_drive::write_impl(std::string api_path, const char *buffer,
size_t write_size, off_t write_offset,
struct fuse_file_info *fi,
struct fuse_file_info *f_info,
std::size_t &bytes_written) -> api_error {
const auto res = remote_instance_->fuse_write(
api_path.c_str(), buffer, write_size, write_offset, fi->fh);
api_path.c_str(), buffer, write_size,
static_cast<remote::file_offset>(write_offset), f_info->fh);
if (res >= 0) {
bytes_written = res;
bytes_written = static_cast<std::size_t>(res);
return api_error::success;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -54,14 +54,16 @@ remote_client::remote_client(const app_config &config)
auto remote_client::winfsp_can_delete(PVOID file_desc, PWSTR file_name)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
request.encode(file_name);
std::uint32_t service_flags = 0u;
const auto ret = packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__,
function_name,
utils::path::create_api_path(utils::string::to_utf8(file_name)), ret);
return ret;
}
@@ -69,58 +71,66 @@ auto remote_client::winfsp_can_delete(PVOID file_desc, PWSTR file_name)
auto remote_client::json_create_directory_snapshot(const std::string &path,
json &json_data)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
ret = packet::decode_json(response, json_data);
}
RAISE_REMOTE_WINFSP_CLIENT_EVENT(__FUNCTION__, path, ret);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, path, ret);
return ret;
}
auto remote_client::json_read_directory_snapshot(
const std::string &path, const remote::file_handle &handle,
std::uint32_t page, json &json_data) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(handle);
request.encode(page);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == 0) {
ret = packet::decode_json(response, json_data);
}
RAISE_REMOTE_WINFSP_CLIENT_EVENT(__FUNCTION__, path, ret);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, path, ret);
return ret;
}
auto remote_client::json_release_directory_snapshot(
const std::string &path, const remote::file_handle &handle)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(path);
request.encode(handle);
std::uint32_t service_flags = 0u;
const auto ret = packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(__FUNCTION__, path, ret);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, path, ret);
return ret;
}
auto remote_client::winfsp_cleanup(PVOID file_desc, PWSTR file_name,
UINT32 flags, BOOLEAN &was_closed)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto handle = to_handle(file_desc);
const auto file_path = get_open_file_path(handle);
was_closed = 0;
@@ -131,18 +141,20 @@ auto remote_client::winfsp_cleanup(PVOID file_desc, PWSTR file_name,
request.encode(flags);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
DECODE_OR_IGNORE(&response, was_closed);
if (was_closed) {
if (was_closed != 0U) {
remove_all(file_path);
}
RAISE_REMOTE_WINFSP_CLIENT_EVENT(__FUNCTION__, file_path, ret);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, file_path, ret);
return ret;
}
auto remote_client::winfsp_close(PVOID file_desc) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
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);
@@ -150,11 +162,11 @@ auto remote_client::winfsp_close(PVOID file_desc) -> packet::error_type {
packet request;
request.encode(file_desc);
std::uint32_t service_flags = 0u;
const auto ret = packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
if ((ret == STATUS_SUCCESS) || (ret == STATUS_INVALID_HANDLE)) {
remove_open_info(handle);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(__FUNCTION__, file_path, ret);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, file_path, ret);
}
}
@@ -167,6 +179,8 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options,
remote::file_info *file_info,
std::string &normalized_name, BOOLEAN &exists)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_name);
request.encode(create_options);
@@ -175,11 +189,11 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options,
request.encode(allocation_size);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == STATUS_SUCCESS) {
HANDLE handle;
HANDLE handle{};
DECODE_OR_IGNORE(&response, handle);
DECODE_OR_IGNORE(&response, *file_info);
DECODE_OR_IGNORE(&response, normalized_name);
@@ -198,23 +212,25 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options,
}
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(*file_desc)), ret);
function_name, get_open_file_path(to_handle(*file_desc)), ret);
return ret;
}
auto remote_client::winfsp_flush(PVOID file_desc, remote::file_info *file_info)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(file_desc)), ret);
function_name, get_open_file_path(to_handle(file_desc)), ret);
return ret;
}
@@ -232,17 +248,19 @@ auto remote_client::winfsp_get_dir_buffer([[maybe_unused]] PVOID file_desc,
auto remote_client::winfsp_get_file_info(PVOID file_desc,
remote::file_info *file_info)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(file_desc)), ret);
function_name, get_open_file_path(to_handle(file_desc)), ret);
return ret;
}
@@ -251,16 +269,18 @@ auto remote_client::winfsp_get_security_by_name(PWSTR file_name,
std::uint64_t *descriptor_size,
std::wstring &string_descriptor)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_name);
request.encode(
static_cast<std::uint64_t>(descriptor_size ? *descriptor_size : 0));
request.encode(static_cast<std::uint64_t>(
descriptor_size == nullptr ? 0 : *descriptor_size));
request.encode(static_cast<std::uint8_t>(attributes != nullptr));
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
string_descriptor.clear();
DECODE_OR_IGNORE(&response, string_descriptor);
@@ -268,11 +288,11 @@ auto remote_client::winfsp_get_security_by_name(PWSTR file_name,
string_descriptor = L"O:BAG:BAD:P(A;;FA;;;SY)(A;;FA;;;BA)(A;;FA;;;WD)";
}
if (attributes) {
if (attributes != nullptr) {
DECODE_OR_IGNORE(&response, *attributes);
}
RAISE_REMOTE_WINFSP_CLIENT_EVENT(__FUNCTION__,
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name,
utils::string::to_utf8(file_name), ret);
return ret;
}
@@ -281,11 +301,13 @@ auto remote_client::winfsp_get_volume_info(UINT64 &total_size,
UINT64 &free_size,
std::string &volume_label)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
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);
@@ -295,16 +317,18 @@ auto remote_client::winfsp_get_volume_info(UINT64 &total_size,
auto remote_client::winfsp_mounted(const std::wstring &location)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(get_repertory_version());
request.encode(location);
std::uint32_t service_flags = 0u;
const auto ret = packet_client_.send(__FUNCTION__, request, service_flags);
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);
event_system::instance().raise<drive_mounted>(mount_location);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(__FUNCTION__, mount_location, ret);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, mount_location, ret);
return ret;
}
@@ -313,17 +337,19 @@ auto remote_client::winfsp_open(PWSTR file_name, UINT32 create_options,
remote::file_info *file_info,
std::string &normalized_name)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_name);
request.encode(create_options);
request.encode(granted_access);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == STATUS_SUCCESS) {
HANDLE handle;
HANDLE handle{};
DECODE_OR_IGNORE(&response, handle);
DECODE_OR_IGNORE(&response, *file_info);
DECODE_OR_IGNORE(&response, normalized_name);
@@ -337,7 +363,7 @@ auto remote_client::winfsp_open(PWSTR file_name, UINT32 create_options,
}
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(*file_desc)), ret);
function_name, get_open_file_path(to_handle(*file_desc)), ret);
return ret;
}
@@ -346,6 +372,8 @@ auto remote_client::winfsp_overwrite(PVOID file_desc, UINT32 attributes,
UINT64 allocation_size,
remote::file_info *file_info)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
request.encode(attributes);
@@ -353,28 +381,30 @@ auto remote_client::winfsp_overwrite(PVOID file_desc, UINT32 attributes,
request.encode(allocation_size);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(file_desc)), ret);
function_name, get_open_file_path(to_handle(file_desc)), ret);
return ret;
}
auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
UINT32 length, PUINT32 bytes_transferred)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
request.encode(offset);
request.encode(length);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
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);
@@ -388,7 +418,7 @@ auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
if (ret != STATUS_SUCCESS) {
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(file_desc)), ret);
function_name, get_open_file_path(to_handle(file_desc)), ret);
}
return ret;
@@ -397,21 +427,23 @@ auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
auto remote_client::winfsp_read_directory(PVOID file_desc, PWSTR pattern,
PWSTR marker, json &item_list)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
request.encode(pattern);
request.encode(marker);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
if (ret == STATUS_SUCCESS) {
ret = packet::decode_json(response, item_list);
}
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(file_desc)), ret);
function_name, get_open_file_path(to_handle(file_desc)), ret);
return ret;
}
@@ -419,16 +451,18 @@ auto remote_client::winfsp_rename(PVOID file_desc, PWSTR file_name,
PWSTR new_file_name,
BOOLEAN replace_if_exists)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
request.encode(file_name);
request.encode(new_file_name);
request.encode(replace_if_exists);
std::uint32_t service_flags = 0u;
const auto ret = packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__,
function_name,
utils::path::create_api_path(utils::string::to_utf8(file_name)) + "|" +
utils::path::create_api_path(utils::string::to_utf8(new_file_name)),
ret);
@@ -439,6 +473,8 @@ auto remote_client::winfsp_set_basic_info(
PVOID file_desc, UINT32 attributes, UINT64 creation_time,
UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time,
remote::file_info *file_info) -> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
request.encode(attributes);
@@ -448,13 +484,13 @@ auto remote_client::winfsp_set_basic_info(
request.encode(change_time);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(file_desc)), ret);
function_name, get_open_file_path(to_handle(file_desc)), ret);
return ret;
}
@@ -462,34 +498,38 @@ auto remote_client::winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
BOOLEAN set_allocation_size,
remote::file_info *file_info)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
request.encode(new_size);
request.encode(set_allocation_size);
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(file_desc)), ret);
function_name, get_open_file_path(to_handle(file_desc)), ret);
return ret;
}
auto remote_client::winfsp_unmounted(const std::wstring &location)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const 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 = 0u;
const auto ret = packet_client_.send(__FUNCTION__, request, service_flags);
std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags);
event_system::instance().raise<drive_unmounted>(mount_location);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(__FUNCTION__, mount_location, ret);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, mount_location, ret);
return ret;
}
@@ -499,32 +539,34 @@ auto remote_client::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
PUINT32 bytes_transferred,
remote::file_info *file_info)
-> packet::error_type {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
packet request;
request.encode(file_desc);
request.encode(length);
request.encode(offset);
request.encode(write_to_end);
request.encode(constrained_io);
if (length) {
if (length != 0U) {
request.encode(buffer, length);
}
packet response;
std::uint32_t service_flags = 0u;
std::uint32_t service_flags{};
auto ret =
packet_client_.send(__FUNCTION__, request, response, service_flags);
packet_client_.send(function_name, request, response, service_flags);
DECODE_OR_IGNORE(&response, *bytes_transferred);
DECODE_OR_IGNORE(&response, *file_info);
if (ret != STATUS_SUCCESS) {
RAISE_REMOTE_WINFSP_CLIENT_EVENT(
__FUNCTION__, get_open_file_path(to_handle(file_desc)), ret);
function_name, get_open_file_path(to_handle(file_desc)), ret);
}
return ret;
}
#ifndef _WIN32
native_handle remote_client::to_handle(PVOID file_desc) {
auto remote_client::to_handle(PVOID file_desc) -> native_handle {
return static_cast<native_handle>(reinterpret_cast<std::uint64_t>(file_desc));
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -21,8 +21,6 @@
*/
#ifdef _WIN32
#include <utility>
#include "drives/winfsp/remotewinfsp/remote_winfsp_drive.hpp"
#include "app_config.hpp"
@@ -49,6 +47,8 @@ remote_winfsp_drive::winfsp_service::winfsp_service(
host_(drive) {}
auto remote_winfsp_drive::winfsp_service::OnStart(ULONG, PWSTR *) -> NTSTATUS {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const auto mount_location = utils::string::to_lower(
utils::path::absolute((drive_args_.size() > 1u) ? drive_args_[1u] : ""));
const auto drive_letter =
@@ -75,7 +75,7 @@ auto remote_winfsp_drive::winfsp_service::OnStart(ULONG, PWSTR *) -> NTSTATUS {
event_system::instance().raise<drive_mount_failed>(mount_location,
std::to_string(ret));
if (not lock_.set_mount_state(false, "", -1)) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
}
@@ -83,9 +83,11 @@ auto remote_winfsp_drive::winfsp_service::OnStart(ULONG, PWSTR *) -> NTSTATUS {
}
auto remote_winfsp_drive::winfsp_service::OnStop() -> NTSTATUS {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
host_.Unmount();
if (not lock_.set_mount_state(false, "", -1)) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
return STATUS_SUCCESS;
@@ -134,7 +136,8 @@ auto remote_winfsp_drive::Create(PWSTR file_name, UINT32 create_options,
set_file_info(ofi->FileInfo, fi);
const auto file_path = utils::string::from_utf8(normalized_name);
wcsncpy(ofi->NormalizedName, &file_path[0], wcslen(&file_path[0]));
ofi->NormalizedNameSize = (UINT16)(wcslen(&file_path[0]) * sizeof(WCHAR));
ofi->NormalizedNameSize =
static_cast<UINT16>(wcslen(&file_path[0]) * sizeof(WCHAR));
}
return ret;
@@ -258,6 +261,8 @@ auto remote_winfsp_drive::mount(const std::vector<std::string> &drive_args)
}
auto remote_winfsp_drive::Mounted(PVOID host) -> NTSTATUS {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto *file_system_host = reinterpret_cast<FileSystemHost *>(host);
remote_instance_ = factory_();
server_ = std::make_unique<server>(config_);
@@ -265,7 +270,7 @@ auto remote_winfsp_drive::Mounted(PVOID host) -> NTSTATUS {
mount_location_ = utils::string::to_utf8(file_system_host->MountPoint());
if (not lock_.set_mount_state(true, mount_location_,
::GetCurrentProcessId())) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
return remote_instance_->winfsp_mounted(file_system_host->MountPoint());
@@ -284,7 +289,8 @@ auto remote_winfsp_drive::Open(PWSTR file_name, UINT32 create_options,
set_file_info(ofi->FileInfo, fi);
const auto file_path = utils::string::from_utf8(normalize_name);
wcsncpy(ofi->NormalizedName, &file_path[0], wcslen(&file_path[0]));
ofi->NormalizedNameSize = (UINT16)(wcslen(&file_path[0]) * sizeof(WCHAR));
ofi->NormalizedNameSize =
static_cast<UINT16>(wcslen(&file_path[0]) * sizeof(WCHAR));
}
return ret;
@@ -445,11 +451,13 @@ auto remote_winfsp_drive::SetFileSize(PVOID /*file_node*/, PVOID file_desc,
}
VOID remote_winfsp_drive::Unmounted(PVOID host) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
server_->stop();
server_.reset();
auto *file_system_host = reinterpret_cast<FileSystemHost *>(host);
if (not lock_.set_mount_state(false, "", -1)) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
remote_instance_->winfsp_unmounted(file_system_host->MountPoint());
remote_instance_.reset();

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -69,6 +69,8 @@ logging_consumer::~logging_consumer() {
}
void logging_consumer::check_log_roll(std::size_t count) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
std::uint64_t file_size{};
const auto success = utils::file::get_file_size(log_path_, file_size);
if (success && (file_size + count) >= MAX_LOG_FILE_SIZE) {
@@ -85,7 +87,7 @@ void logging_consumer::check_log_roll(std::size_t count) {
log_directory_,
{"repertory." + std::to_string(i + std::uint8_t(1)) + ".log"});
if (not utils::file::move_file(temp_log_path, next_file_path)) {
utils::error::raise_error(__FUNCTION__,
utils::error::raise_error(function_name,
utils::get_last_error_code(),
temp_log_path + "|dest|" + next_file_path,
"failed to move file");
@@ -97,7 +99,7 @@ void logging_consumer::check_log_roll(std::size_t count) {
auto backup_log_path =
utils::path::combine(log_directory_, {"repertory.1.log"});
if (not utils::file::move_file(log_path_, backup_log_path)) {
utils::error::raise_error(__FUNCTION__, utils::get_last_error_code(),
utils::error::raise_error(function_name, utils::get_last_error_code(),
log_path_ + "|dest|" + backup_log_path,
"failed to move file");
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -64,13 +64,12 @@ file_manager::open_file::open_file(
}
if (not fsi.directory) {
set_api_error(native_file::create_or_open(
fsi.source_path, not provider_.is_direct_only(), nf_));
set_api_error(native_file::create_or_open(fsi.source_path,
provider_.is_direct_only(), nf_));
if (get_api_error() == api_error::success) {
if (read_state.has_value()) {
modified_ = true;
mgr_.store_resume(*this);
read_state_ = read_state.value();
set_modified();
} else if (fsi_.size > 0U) {
read_state_.resize(static_cast<std::size_t>(utils::divide_with_ceiling(
fsi_.size, chunk_size)),
@@ -238,7 +237,7 @@ auto file_manager::open_file::is_complete() const -> bool {
}
auto file_manager::open_file::native_operation(
const i_open_file::native_operation_callback &callback) -> api_error {
i_open_file::native_operation_callback callback) -> api_error {
unique_recur_mutex_lock file_lock(file_mtx_);
if (stop_requested_) {
return api_error::download_stopped;
@@ -250,7 +249,9 @@ auto file_manager::open_file::native_operation(
auto file_manager::open_file::native_operation(
std::uint64_t new_file_size,
const i_open_file::native_operation_callback &callback) -> api_error {
i_open_file::native_operation_callback callback) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (fsi_.directory) {
return api_error::invalid_operation;
}
@@ -284,7 +285,7 @@ auto file_manager::open_file::native_operation(
auto res = do_io([&]() -> api_error { return callback(nf_->get_handle()); });
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, get_api_path(),
utils::error::raise_api_path_error(function_name, get_api_path(),
utils::get_last_error_code(),
"failed to allocate file");
return res;
@@ -293,7 +294,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__, get_api_path(),
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);
@@ -301,7 +302,7 @@ auto file_manager::open_file::native_operation(
if (file_size != new_file_size) {
utils::error::raise_api_path_error(
__FUNCTION__, get_api_path(), api_error::file_size_mismatch,
function_name, get_api_path(), api_error::file_size_mismatch,
"allocated file size mismatch|expected|" +
std::to_string(new_file_size) + "|actual|" +
std::to_string(file_size));
@@ -323,11 +324,7 @@ auto file_manager::open_file::native_operation(
}
if (original_file_size != new_file_size) {
if (not modified_) {
mgr_.store_resume(*this);
}
modified_ = true;
mgr_.remove_upload(get_api_path());
set_modified();
fsi_.size = new_file_size;
const auto now = std::to_string(utils::get_file_time_now());
@@ -339,7 +336,7 @@ auto file_manager::open_file::native_operation(
{META_WRITTEN, now},
});
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, get_api_path(), res,
utils::error::raise_api_path_error(function_name, get_api_path(), res,
"failed to set file meta");
return set_api_error(res);
}
@@ -409,6 +406,10 @@ void file_manager::open_file::remove(std::uint64_t handle) {
mgr_.queue_upload(*this);
modified_ = false;
}
if (removed_ && (get_open_file_count() == 0U)) {
removed_ = false;
}
}
auto file_manager::open_file::resize(std::uint64_t new_file_size) -> api_error {
@@ -424,6 +425,8 @@ auto file_manager::open_file::resize(std::uint64_t new_file_size) -> api_error {
}
auto file_manager::open_file::close() -> bool {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (not fsi_.directory && not stop_requested_) {
stop_requested_ = true;
@@ -463,7 +466,7 @@ auto file_manager::open_file::close() -> bool {
mgr_.remove_resume(get_api_path(), get_source_path());
if (not utils::file::retry_delete_file(fsi_.source_path)) {
utils::error::raise_api_path_error(
__FUNCTION__, get_api_path(), fsi_.source_path,
function_name, get_api_path(), fsi_.source_path,
utils::get_last_error_code(), "failed to delete file");
}
@@ -473,7 +476,7 @@ auto file_manager::open_file::close() -> bool {
const auto res = provider_.set_item_meta(fsi_.api_path, META_SOURCE,
fsi_.source_path);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, get_api_path(),
utils::error::raise_api_path_error(function_name, get_api_path(),
fsi_.source_path, res,
"failed to set file meta");
}
@@ -486,6 +489,18 @@ auto file_manager::open_file::close() -> bool {
return false;
}
void file_manager::open_file::set_modified() {
if (not modified_) {
modified_ = true;
mgr_.store_resume(*this);
}
if (not removed_) {
removed_ = true;
mgr_.remove_upload(get_api_path());
}
}
void file_manager::open_file::update_background_reader(std::size_t read_chunk) {
recur_mutex_lock reader_lock(file_mtx_);
read_chunk_index_ = read_chunk;
@@ -524,6 +539,8 @@ void file_manager::open_file::update_background_reader(std::size_t read_chunk) {
auto file_manager::open_file::write(std::uint64_t write_offset,
const data_buffer &data,
std::size_t &bytes_written) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
bytes_written = 0U;
if (fsi_.directory || provider_.is_direct_only()) {
@@ -581,17 +598,12 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
{META_WRITTEN, now},
});
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, get_api_path(), res,
utils::error::raise_api_path_error(function_name, get_api_path(), res,
"failed to set file meta");
return set_api_error(res);
}
if (not modified_) {
mgr_.store_resume(*this);
}
modified_ = true;
mgr_.remove_upload(get_api_path());
set_modified();
return api_error::success;
}
} // namespace repertory

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -22,9 +22,9 @@
#include "file_manager/file_manager.hpp"
namespace repertory {
void file_manager::open_file_base::download::notify(const api_error &e) {
void file_manager::open_file_base::download::notify(const api_error &err) {
complete_ = true;
error_ = e;
error_ = err;
unique_mutex_lock lock(mtx_);
notify_.notify_all();
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -36,6 +36,6 @@ auto file_manager::open_file_base::io_item::get_result() -> api_error {
}
notify_.wait(lock);
return result_.value();
return result_.value_or(api_error::error);
}
} // namespace repertory

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -85,12 +85,14 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
}
file_manager::ring_buffer_open_file::~ring_buffer_open_file() {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
close();
nf_->close();
if (not utils::file::retry_delete_file(fsi_.source_path)) {
utils::error::raise_api_path_error(
__FUNCTION__, fsi_.api_path, fsi_.source_path,
function_name, fsi_.api_path, fsi_.source_path,
utils::get_last_error_code(), "failed to delete file");
}
}
@@ -195,7 +197,7 @@ auto file_manager::ring_buffer_open_file::is_download_complete() const -> bool {
}
auto file_manager::ring_buffer_open_file::native_operation(
const i_open_file::native_operation_callback &callback) -> api_error {
i_open_file::native_operation_callback callback) -> api_error {
return do_io([&]() -> api_error { return callback(nf_->get_handle()); });
}
@@ -258,7 +260,8 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
}
reset_timeout();
if ((res = download_chunk(chunk)) == api_error::success) {
res = download_chunk(chunk);
if (res == api_error::success) {
const auto to_read = std::min(
static_cast<std::size_t>(chunk_size_ - read_offset), read_size);
res = do_io([this, &buffer, &chunk, &data, read_offset,
@@ -270,8 +273,10 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
? api_error::success
: api_error::os_error;
if (ret == api_error::success) {
data.insert(data.end(), buffer.begin() + read_offset,
buffer.begin() + read_offset + to_read);
data.insert(data.end(),
buffer.begin() + static_cast<std::int64_t>(read_offset),
buffer.begin() +
static_cast<std::int64_t>(read_offset + to_read));
reset_timeout();
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -27,10 +27,11 @@
#include "utils/unix/unix_utils.hpp"
namespace repertory {
using std::bind;
file_manager::upload::upload(filesystem_item fsi, i_provider &provider)
: fsi_(fsi), provider_(provider) {
thread_ =
std::make_unique<std::thread>(std::bind(&upload::upload_thread, this));
: fsi_(std::move(fsi)), provider_(provider) {
thread_ = std::make_unique<std::thread>([this] { upload_thread(); });
}
file_manager::upload::~upload() {
@@ -48,11 +49,13 @@ void file_manager::upload::cancel() {
void file_manager::upload::stop() { stop_requested_ = true; }
void file_manager::upload::upload_thread() {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
error_ =
provider_.upload_file(fsi_.api_path, fsi_.source_path, stop_requested_);
if (not utils::file::reset_modified_time(fsi_.source_path)) {
utils::error::raise_api_path_error(
__FUNCTION__, fsi_.api_path, fsi_.source_path,
function_name, fsi_.api_path, fsi_.source_path,
utils::get_last_error_code(), "failed to reset modified time");
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -39,7 +39,12 @@ std::size_t PROVIDER_INDEX{0U};
auto main(int argc, char **argv) -> int {
repertory_init();
std::vector<const char *> args(argv, argv + argc);
std::vector<const char *> args;
{
auto args_span = std::span(argv, static_cast<std::size_t>(argc));
std::copy(args_span.begin(), args_span.end(), std::back_inserter(args));
}
#ifdef REPERTORY_TESTING
#ifdef _WIN32
if (utils::cli::has_option(args, "--provider_index")) {
@@ -81,9 +86,9 @@ auto main(int argc, char **argv) -> int {
std::string unique_id;
if ((res == exit_code::success) && (prov == provider_type::remote)) {
std::string data;
if ((res = utils::cli::parse_string_option(
args, utils::cli::options::remote_mount_option, data)) ==
exit_code::success) {
res = utils::cli::parse_string_option(
args, utils::cli::options::remote_mount_option, data);
if (res == exit_code::success) {
const auto parts = utils::string::split(data, ':');
if (parts.size() != 2) {
std::cerr << "Invalid syntax for host/port '-rm "
@@ -111,9 +116,9 @@ auto main(int argc, char **argv) -> int {
#ifdef REPERTORY_ENABLE_S3
if ((res == exit_code::success) && (prov == provider_type::s3)) {
std::string data;
if ((res = utils::cli::parse_string_option(args,
utils::cli::options::name_option,
data)) == exit_code::success) {
res = utils::cli::parse_string_option(
args, utils::cli::options::name_option, data);
if (res == exit_code::success) {
unique_id = utils::string::trim(data);
if (unique_id.empty()) {
std::cerr << "Name of S3 instance not provided" << std::endl;

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -101,6 +101,8 @@ auto lock_data::get_state_directory() -> std::string {
}
auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (lock_fd_ == -1) {
return lock_result::failure;
}
@@ -109,7 +111,7 @@ auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
switch (lock_status_) {
case 0:
if (not set_mount_state(false, "", -1)) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
return lock_result::success;
case EWOULDBLOCK:
@@ -121,16 +123,18 @@ auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
auto lock_data::set_mount_state(bool active, const std::string &mount_location,
int pid) -> bool {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto ret = false;
auto fd =
auto handle =
open(get_lock_data_file().c_str(), O_CREAT | O_RDWR, S_IWUSR | S_IRUSR);
if (fd != -1) {
if (wait_for_lock(fd) == 0) {
if (handle != -1) {
if (wait_for_lock(handle) == 0) {
const auto mount_id =
app_config::get_provider_display_name(pt_) + unique_id_;
json mount_state;
if (not utils::file::read_json_file(get_lock_data_file(), mount_state)) {
utils::error::raise_error(__FUNCTION__,
utils::error::raise_error(function_name,
"failed to read mount state file|sp|" +
get_lock_file());
}
@@ -157,22 +161,25 @@ auto lock_data::set_mount_state(bool active, const std::string &mount_location,
ret = true;
}
flock(fd, LOCK_UN);
flock(handle, LOCK_UN);
}
close(fd);
close(handle);
}
return ret;
}
auto lock_data::wait_for_lock(int fd, std::uint8_t retry_count) -> int {
static constexpr const std::uint32_t max_sleep = 100U;
auto lock_status = EWOULDBLOCK;
std::int16_t remain = retry_count * 100u;
auto remain = static_cast<std::uint32_t>(retry_count * max_sleep);
while ((remain > 0) && (lock_status == EWOULDBLOCK)) {
if ((lock_status = flock(fd, LOCK_EX | LOCK_NB)) == -1) {
if ((lock_status = errno) == EWOULDBLOCK) {
const auto sleep_ms = utils::random_between(
std::int16_t(1), std::min(remain, std::int16_t(100)));
lock_status = flock(fd, LOCK_EX | LOCK_NB);
if (lock_status == -1) {
lock_status = errno;
if (lock_status == EWOULDBLOCK) {
auto sleep_ms = utils::random_between(1U, std::min(remain, max_sleep));
std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
remain -= sleep_ms;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -73,6 +73,8 @@ auto lock_data::get_mount_state(json &mount_state) -> bool {
}
auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto ret = lock_result::success;
if (mutex_handle_ == INVALID_HANDLE_VALUE) {
ret = lock_result::failure;
@@ -97,7 +99,7 @@ auto lock_data::grab_lock(std::uint8_t retry_count) -> lock_result {
if (should_reset) {
if (not set_mount_state(false, "", -1)) {
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
utils::error::raise_error(function_name, "failed to set mount state");
}
}
} break;

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -22,13 +22,15 @@
#include "providers/base_provider.hpp"
#include "app_config.hpp"
#include "database/db_common.hpp"
#include "database/db_insert.hpp"
#include "database/db_select.hpp"
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "file_manager/i_file_manager.hpp"
#include "utils/file_utils.hpp"
#include "utils/path_utils.hpp"
#include "utils/polling.hpp"
#include "utils/rocksdb_utils.hpp"
namespace repertory {
auto base_provider::create_api_file(std::string path, std::string key,
@@ -66,13 +68,15 @@ auto base_provider::create_api_file(std::string path, std::uint64_t size,
auto base_provider::create_directory_clone_source_meta(
const std::string &source_api_path, const std::string &api_path)
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
bool exists{};
auto res = is_file(source_api_path, exists);
if (res != api_error::success) {
return res;
}
if (exists) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::item_exists,
"failed to create directory");
return api_error::item_exists;
@@ -83,7 +87,7 @@ auto base_provider::create_directory_clone_source_meta(
return res;
}
if (exists) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::directory_exists,
"failed to create directory");
return api_error::directory_exists;
@@ -94,7 +98,7 @@ auto base_provider::create_directory_clone_source_meta(
return res;
}
if (exists) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::item_exists,
"failed to create directory");
return api_error::item_exists;
@@ -106,7 +110,7 @@ auto base_provider::create_directory_clone_source_meta(
if (res == api_error::item_not_found) {
res = api_error::directory_not_found;
}
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to create directory");
return res;
}
@@ -116,13 +120,15 @@ auto base_provider::create_directory_clone_source_meta(
auto base_provider::create_directory(const std::string &api_path,
api_meta_map &meta) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
if (exists) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::directory_exists,
"failed to create directory");
return api_error::directory_exists;
@@ -130,12 +136,12 @@ auto base_provider::create_directory(const std::string &api_path,
res = is_file(api_path, exists);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to create directory");
return res;
}
if (exists) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::item_exists,
"failed to create directory");
return api_error::item_exists;
@@ -144,12 +150,12 @@ auto base_provider::create_directory(const std::string &api_path,
try {
res = create_directory_impl(api_path, meta);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to create directory");
return res;
}
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
utils::error::raise_api_path_error(function_name, api_path, e,
"failed to create directory");
return api_error::error;
}
@@ -160,13 +166,15 @@ auto base_provider::create_directory(const std::string &api_path,
auto base_provider::create_file(const std::string &api_path, api_meta_map &meta)
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success && res != api_error::item_not_found) {
return res;
}
if (exists) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::directory_exists,
"failed to create file");
return api_error::directory_exists;
@@ -177,7 +185,7 @@ auto base_provider::create_file(const std::string &api_path, api_meta_map &meta)
return res;
}
if (exists) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::item_exists,
"failed to create file");
return api_error::item_exists;
@@ -186,7 +194,7 @@ auto base_provider::create_file(const std::string &api_path, api_meta_map &meta)
try {
res = create_file_extra(api_path, meta);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to create file");
return res;
}
@@ -194,7 +202,7 @@ auto base_provider::create_file(const std::string &api_path, api_meta_map &meta)
meta[META_DIRECTORY] = utils::string::from_bool(false);
res = set_item_meta(api_path, meta);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to create file");
return res;
}
@@ -202,12 +210,12 @@ auto base_provider::create_file(const std::string &api_path, api_meta_map &meta)
stop_type stop_requested{false};
res = upload_file(api_path, meta[META_SOURCE], stop_requested);
if (res != api_error::success) {
get_db()->Delete(rocksdb::WriteOptions(), api_path);
db3_->remove_api_path(api_path);
}
return res;
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
utils::error::raise_api_path_error(function_name, api_path, e,
"failed to create file");
}
@@ -217,38 +225,23 @@ auto base_provider::create_file(const std::string &api_path, api_meta_map &meta)
auto base_provider::get_api_path_from_source(const std::string &source_path,
std::string &api_path) const
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (source_path.empty()) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::item_not_found,
"failed to source path from api path");
return api_error::item_not_found;
}
auto iterator = std::unique_ptr<rocksdb::Iterator>(
db_->NewIterator(rocksdb::ReadOptions()));
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
std::string current_source_path{};
if (get_item_meta(iterator->key().ToString(), META_SOURCE,
current_source_path) != api_error::success) {
continue;
}
if (current_source_path.empty()) {
continue;
}
if (current_source_path == source_path) {
api_path = iterator->key().ToString();
return api_error::success;
}
}
return api_error::item_not_found;
return db3_->get_api_path(source_path, api_path);
}
auto base_provider::get_directory_items(const std::string &api_path,
directory_item_list &list) const
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
@@ -264,7 +257,7 @@ auto base_provider::get_directory_items(const std::string &api_path,
return res;
}
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
utils::error::raise_api_path_error(function_name, api_path, e,
"failed to get directory items");
return api_error::error;
}
@@ -392,81 +385,32 @@ auto base_provider::get_filesystem_item_from_source_path(
auto base_provider::get_item_meta(const std::string &api_path,
api_meta_map &meta) const -> api_error {
std::string meta_value{};
db_->Get(rocksdb::ReadOptions(), api_path, &meta_value);
if (meta_value.empty()) {
return api_error::item_not_found;
}
try {
meta = json::parse(meta_value).get<api_meta_map>();
return api_error::success;
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
"failed to get item meta");
}
return api_error::error;
return db3_->get_item_meta(api_path, meta);
}
auto base_provider::get_item_meta(const std::string &api_path,
const std::string &key,
std::string &value) const -> api_error {
std::string meta_value{};
db_->Get(rocksdb::ReadOptions(), api_path, &meta_value);
if (meta_value.empty()) {
return api_error::item_not_found;
}
try {
value = json::parse(meta_value)[key];
return api_error::success;
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
"failed to get item meta");
}
return api_error::error;
return db3_->get_item_meta(api_path, key, value);
}
auto base_provider::get_pinned_files() const -> std::vector<std::string> {
std::vector<std::string> ret{};
auto iterator = std::unique_ptr<rocksdb::Iterator>(
db_->NewIterator(rocksdb::ReadOptions()));
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
std::string pinned{};
if (get_item_meta(iterator->key().ToString(), META_PINNED, pinned) !=
api_error::success) {
continue;
}
if (pinned.empty() || not utils::string::to_bool(pinned)) {
continue;
}
ret.emplace_back(iterator->key().ToString());
}
return ret;
return db3_->get_pinned_files();
}
auto base_provider::get_total_item_count() const -> std::uint64_t {
std::uint64_t ret{};
auto iterator = std::unique_ptr<rocksdb::Iterator>(
db_->NewIterator(rocksdb::ReadOptions()));
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
ret++;
}
return ret;
return db3_->get_total_item_count();
}
auto base_provider::get_used_drive_space() const -> std::uint64_t {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
auto used_space = get_used_drive_space_impl();
get_file_mgr()->update_used_space(used_space);
return used_space;
} catch (const std::exception &ex) {
utils::error::raise_error(__FUNCTION__, ex,
utils::error::raise_error(function_name, ex,
"failed to get used drive space");
}
@@ -485,6 +429,8 @@ auto base_provider::is_file_writeable(const std::string &api_path) const
}
void base_provider::remove_deleted_files() {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
struct removed_item {
std::string api_path{};
bool directory{};
@@ -494,36 +440,33 @@ void base_provider::remove_deleted_files() {
api_file_list list{};
auto res = get_file_list(list);
if (res != api_error::success) {
utils::error::raise_error(__FUNCTION__, res, "failed to get file list");
utils::error::raise_error(function_name, res, "failed to get file list");
return;
}
std::vector<removed_item> removed_list{};
auto iterator = std::unique_ptr<rocksdb::Iterator>(
db_->NewIterator(rocksdb::ReadOptions()));
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
for (const auto &api_path : db3_->get_api_path_list()) {
api_meta_map meta{};
if (get_item_meta(iterator->key().ToString(), meta) == api_error::success) {
if (get_item_meta(api_path, meta) == api_error::success) {
if (utils::string::to_bool(meta[META_DIRECTORY])) {
bool exists{};
if (is_directory(iterator->key().ToString(), exists) !=
api_error::success) {
if (is_directory(api_path, exists) != api_error::success) {
continue;
}
if (not exists) {
removed_list.emplace_back(
removed_item{iterator->key().ToString(), true, ""});
removed_list.emplace_back(removed_item{api_path, true, ""});
}
continue;
}
bool exists{};
if (is_file(iterator->key().ToString(), exists) != api_error::success) {
if (is_file(api_path, exists) != api_error::success) {
continue;
}
if (not exists) {
removed_list.emplace_back(
removed_item{iterator->key().ToString(), false, meta[META_SOURCE]});
removed_item{api_path, false, meta[META_SOURCE]});
}
}
}
@@ -553,14 +496,14 @@ void base_provider::remove_deleted_files() {
}
} else {
utils::error::raise_error(
__FUNCTION__, std::to_string(utils::get_last_error_code()),
function_name, std::to_string(utils::get_last_error_code()),
"failed to create orphaned director|sp|" + orphaned_directory);
continue;
}
}
if (fm_->evict_file(item.api_path)) {
db_->Delete(rocksdb::WriteOptions(), item.api_path);
db3_->remove_api_path(item.api_path);
event_system::instance().raise<file_removed_externally>(
item.api_path, item.source_path);
}
@@ -569,7 +512,7 @@ void base_provider::remove_deleted_files() {
for (const auto &item : removed_list) {
if (item.directory) {
db_->Delete(rocksdb::WriteOptions(), item.api_path);
db3_->remove_api_path(item.api_path);
event_system::instance().raise<directory_removed_externally>(
item.api_path, item.source_path);
}
@@ -588,20 +531,10 @@ auto base_provider::remove_file(const std::string &api_path) -> api_error {
return error;
};
const auto *const function_name = __FUNCTION__;
const auto remove_file_meta = [this, &api_path, &function_name,
&notify_end]() -> api_error {
const auto remove_file_meta = [this, &api_path, &notify_end]() -> api_error {
api_meta_map meta{};
auto res = get_item_meta(api_path, meta);
auto res2 = get_db()->Delete(rocksdb::WriteOptions(), api_path);
if (not res2.ok()) {
utils::error::raise_api_path_error(function_name, api_path, res2.code(),
"failed to remove file");
return notify_end(api_error::error);
}
db3_->remove_api_path(api_path);
return notify_end(res);
};
@@ -658,109 +591,42 @@ auto base_provider::remove_directory(const std::string &api_path) -> api_error {
return notify_end(res);
}
auto status = get_db()->Delete(rocksdb::WriteOptions(), api_path);
if (not status.ok()) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, status.code(),
"failed to remove directory");
return notify_end(api_error::error);
}
db3_->remove_api_path(api_path);
return notify_end(api_error::success);
}
auto base_provider::remove_item_meta(const std::string &api_path,
const std::string &key) -> api_error {
api_meta_map meta{};
auto res = get_item_meta(api_path, meta);
if (res != api_error::success) {
return res;
}
meta.erase(key);
auto res2 = db_->Put(rocksdb::WriteOptions(), api_path, json(meta).dump());
if (not res2.ok()) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res2.code(),
"failed to remove item meta");
return api_error::error;
}
return api_error::success;
return db3_->remove_item_meta(api_path, key);
}
auto base_provider::set_item_meta(const std::string &api_path,
const std::string &key,
const std::string &value) -> api_error {
json meta_json{};
std::string meta_value{};
db_->Get(rocksdb::ReadOptions(), api_path, &meta_value);
if (not meta_value.empty()) {
try {
meta_json = json::parse(meta_value);
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
"failed to set item meta");
return api_error::error;
}
}
meta_json[key] = value;
const auto res =
db_->Put(rocksdb::WriteOptions(), api_path, meta_json.dump());
if (not res.ok()) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res.code(),
"failed to set item meta");
return api_error::error;
}
return api_error::success;
return db3_->set_item_meta(api_path, key, value);
}
auto base_provider::set_item_meta(const std::string &api_path,
const api_meta_map &meta) -> api_error {
json meta_json{};
std::string meta_value{};
db_->Get(rocksdb::ReadOptions(), api_path, &meta_value);
if (not meta_value.empty()) {
try {
meta_json = json::parse(meta_value);
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
"failed to set item meta");
return api_error::error;
}
}
for (const auto &kv : meta) {
meta_json[kv.first] = kv.second;
}
const auto res =
db_->Put(rocksdb::WriteOptions(), api_path, meta_json.dump());
if (not res.ok()) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res.code(),
"failed to set item meta");
return api_error::error;
}
return api_error::success;
return db3_->set_item_meta(api_path, meta);
}
auto base_provider::start(api_item_added_callback api_item_added,
i_file_manager *mgr) -> bool {
utils::db::create_rocksdb(config_, DB_NAME, db_);
api_item_added_ = api_item_added;
fm_ = mgr;
db3_ = std::make_unique<meta_db>(config_);
api_meta_map meta{};
if (get_item_meta("/", meta) == api_error::item_not_found) {
auto dir = create_api_file("/", "", 0U);
api_item_added_(true, dir);
}
auto online = false;
auto unmount_requested = false;
auto online{false};
auto unmount_requested{false};
{
repertory::event_consumer consumer(
"unmount_requested",
@@ -789,12 +655,14 @@ auto base_provider::start(api_item_added_callback api_item_added,
void base_provider::stop() {
polling::instance().remove_callback("check_deleted");
db_.reset();
db3_.reset();
}
auto base_provider::upload_file(const std::string &api_path,
const std::string &source_path,
stop_type &stop_requested) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
event_system::instance().raise<provider_upload_begin>(api_path, source_path);
const auto notify_end = [&api_path,
@@ -806,7 +674,7 @@ auto base_provider::upload_file(const std::string &api_path,
try {
return notify_end(upload_file_impl(api_path, source_path, stop_requested));
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
return notify_end(api_error::error);

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -36,7 +36,6 @@
#include "utils/file_utils.hpp"
#include "utils/path_utils.hpp"
#include "utils/polling.hpp"
#include "utils/rocksdb_utils.hpp"
#include "utils/string_utils.hpp"
namespace repertory {
@@ -64,6 +63,8 @@ auto s3_provider::add_if_not_found(api_file &file,
auto s3_provider::create_directory_impl(const std::string &api_path,
api_meta_map &meta) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const auto cfg = get_config().get_s3_config();
const auto is_encrypted = not cfg.encryption_token.empty();
stop_type stop_requested{false};
@@ -73,7 +74,7 @@ auto s3_provider::create_directory_impl(const std::string &api_path,
auto res = get_item_meta(utils::path::get_parent_api_path(api_path),
META_KEY, encrypted_file_path);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to create file");
return res;
}
@@ -98,14 +99,14 @@ auto s3_provider::create_directory_impl(const std::string &api_path,
long response_code{};
if (not get_comm().make_request(put_file, response_code, stop_requested)) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::comm_error,
"failed to create directory");
return api_error::comm_error;
}
if (response_code != http_error_codes::ok) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to create directory");
return api_error::comm_error;
}
@@ -115,12 +116,14 @@ auto s3_provider::create_directory_impl(const std::string &api_path,
auto s3_provider::create_file_extra(const std::string &api_path,
api_meta_map &meta) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (not get_config().get_s3_config().encryption_token.empty()) {
std::string encrypted_file_path;
auto res = get_item_meta(utils::path::get_parent_api_path(api_path),
META_KEY, encrypted_file_path);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
utils::error::raise_api_path_error(function_name, api_path, res,
"failed to create file");
return res;
}
@@ -198,6 +201,8 @@ auto s3_provider::decrypt_object_name(std::string &object_name) const
auto s3_provider::get_directory_item_count(const std::string &api_path) const
-> std::uint64_t {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
const auto cfg = get_config().get_s3_config();
const auto is_encrypted = not cfg.encryption_token.empty();
@@ -248,7 +253,7 @@ auto s3_provider::get_directory_item_count(const std::string &api_path) const
return ret;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
return 0U;
@@ -372,6 +377,8 @@ auto s3_provider::get_directory_items_impl(const std::string &api_path,
auto s3_provider::get_file(const std::string &api_path, api_file &file) const
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
bool is_encrypted{};
std::string object_name;
@@ -395,7 +402,7 @@ auto s3_provider::get_file(const std::string &api_path, api_file &file) const
file.modified_date = utils::aws::format_time(result.last_modified);
return add_if_not_found(file, object_name);
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
return api_error::error;
@@ -465,6 +472,8 @@ auto s3_provider::get_object_info(bool directory, const std::string &api_path,
bool &is_encrypted, std::string &object_name,
head_object_result &result) const
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
const auto cfg = get_config().get_s3_config();
is_encrypted = not cfg.encryption_token.empty();
@@ -503,7 +512,7 @@ auto s3_provider::get_object_info(bool directory, const std::string &api_path,
return api_error::success;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
return api_error::error;
@@ -572,6 +581,8 @@ auto s3_provider::get_used_drive_space_impl() const -> std::uint64_t {
auto s3_provider::is_directory(const std::string &api_path, bool &exists) const
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
exists = false;
if (api_path == "/") {
exists = true;
@@ -590,7 +601,7 @@ auto s3_provider::is_directory(const std::string &api_path, bool &exists) const
exists = res != api_error::item_not_found;
return api_error::success;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
return api_error::error;
@@ -598,6 +609,8 @@ auto s3_provider::is_directory(const std::string &api_path, bool &exists) const
auto s3_provider::is_file(const std::string &api_path, bool &exists) const
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
exists = false;
if (api_path == "/") {
return api_error::success;
@@ -615,7 +628,7 @@ auto s3_provider::is_file(const std::string &api_path, bool &exists) const
exists = res != api_error::item_not_found;
return api_error::success;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
return api_error::error;
@@ -629,6 +642,8 @@ auto s3_provider::is_online() const -> bool {
auto s3_provider::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 {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
const auto cfg = get_config().get_s3_config();
const auto is_encrypted = not cfg.encryption_token.empty();
@@ -669,13 +684,13 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
const auto notify_retry = [&]() {
if (response_code == 0) {
utils::error::raise_api_path_error(
__FUNCTION__, api_path, api_error::comm_error,
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));
} else {
utils::error::raise_api_path_error(
__FUNCTION__, api_path, response_code,
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));
@@ -721,7 +736,7 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
return read_bytes(size, offset, data);
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
}
return api_error::error;
@@ -729,6 +744,8 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
auto s3_provider::remove_directory_impl(const std::string &api_path)
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const auto cfg = get_config().get_s3_config();
const auto is_encrypted = not cfg.encryption_token.empty();
@@ -751,7 +768,7 @@ auto s3_provider::remove_directory_impl(const std::string &api_path)
long response_code{};
stop_type stop_requested{};
if (not get_comm().make_request(del, response_code, stop_requested)) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::comm_error,
"failed to remove directory");
return api_error::comm_error;
@@ -760,7 +777,7 @@ auto s3_provider::remove_directory_impl(const std::string &api_path)
if ((response_code < http_error_codes::ok ||
response_code >= http_error_codes::multiple_choices) &&
response_code != http_error_codes::not_found) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to remove directory");
return api_error::comm_error;
}
@@ -769,6 +786,8 @@ auto s3_provider::remove_directory_impl(const std::string &api_path)
}
auto s3_provider::remove_file_impl(const std::string &api_path) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const auto cfg = get_config().get_s3_config();
const auto is_encrypted = not cfg.encryption_token.empty();
@@ -791,15 +810,16 @@ auto s3_provider::remove_file_impl(const std::string &api_path) -> api_error {
long response_code{};
stop_type stop_requested{};
if (not get_comm().make_request(del, response_code, stop_requested)) {
utils::error::raise_api_path_error(
__FUNCTION__, api_path, api_error::comm_error, "failed to remove file");
utils::error::raise_api_path_error(function_name, api_path,
api_error::comm_error,
"failed to remove file");
return api_error::comm_error;
}
if ((response_code < http_error_codes::ok ||
response_code >= http_error_codes::multiple_choices) &&
response_code != http_error_codes::not_found) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to remove file");
return api_error::comm_error;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -31,7 +31,6 @@
#include "utils/file_utils.hpp"
#include "utils/path_utils.hpp"
#include "utils/polling.hpp"
#include "utils/rocksdb_utils.hpp"
#include "utils/string_utils.hpp"
#include "utils/utils.hpp"
@@ -42,6 +41,8 @@ sia_provider::sia_provider(app_config &config, i_http_comm &comm)
auto sia_provider::create_directory_impl(const std::string &api_path,
api_meta_map & /* meta */)
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
curl::requests::http_put_file put_file{};
put_file.allow_timeout = true;
put_file.path = "/api/worker/objects" + api_path + "/";
@@ -49,14 +50,14 @@ auto sia_provider::create_directory_impl(const std::string &api_path,
long response_code{};
stop_type stop_requested{};
if (not get_comm().make_request(put_file, response_code, stop_requested)) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::comm_error,
"failed to create directory");
return api_error::comm_error;
}
if (response_code != http_error_codes::ok) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to create directory");
return api_error::comm_error;
}
@@ -66,6 +67,8 @@ auto sia_provider::create_directory_impl(const std::string &api_path,
auto sia_provider::get_directory_item_count(const std::string &api_path) const
-> std::uint64_t {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
json object_list{};
if (not get_object_list(api_path, object_list)) {
@@ -84,7 +87,7 @@ auto sia_provider::get_directory_item_count(const std::string &api_path) const
}
++item_count;
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
utils::error::raise_api_path_error(function_name, api_path, e,
"failed to process entry|" +
entry.dump());
}
@@ -93,7 +96,7 @@ auto sia_provider::get_directory_item_count(const std::string &api_path) const
return item_count;
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
utils::error::raise_api_path_error(function_name, api_path, e,
"failed to get directory item count");
}
@@ -103,6 +106,8 @@ auto sia_provider::get_directory_item_count(const std::string &api_path) const
auto sia_provider::get_directory_items_impl(const std::string &api_path,
directory_item_list &list) const
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
json object_list{};
if (not get_object_list(api_path, object_list)) {
return api_error::comm_error;
@@ -129,7 +134,7 @@ auto sia_provider::get_directory_items_impl(const std::string &api_path,
get_api_item_added()(directory, file);
auto res = get_item_meta(entry_api_path, meta);
if (res != api_error::success) {
utils::error::raise_error(__FUNCTION__, res,
utils::error::raise_error(function_name, res,
"failed to get item meta");
continue;
}
@@ -148,7 +153,7 @@ auto sia_provider::get_directory_items_impl(const std::string &api_path,
dir_item.size = file.file_size;
list.emplace_back(std::move(dir_item));
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
utils::error::raise_api_path_error(function_name, api_path, e,
"failed to process entry|" +
entry.dump());
}
@@ -186,6 +191,8 @@ auto sia_provider::get_file(const std::string &api_path, api_file &file) const
}
auto sia_provider::get_file_list(api_file_list &list) const -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
using dir_func = std::function<api_error(std::string api_path)>;
const dir_func get_files_in_dir = [&](std::string api_path) -> api_error {
try {
@@ -236,7 +243,7 @@ auto sia_provider::get_file_list(api_file_list &list) const -> api_error {
return api_error::success;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e,
utils::error::raise_error(function_name, e,
"failed to process directory|" + api_path);
}
@@ -248,6 +255,8 @@ auto sia_provider::get_file_list(api_file_list &list) const -> api_error {
auto sia_provider::get_object_info(const std::string &api_path,
json &object_info) const -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
curl::requests::http_get get{};
get.allow_timeout = true;
@@ -271,14 +280,14 @@ auto sia_provider::get_object_info(const std::string &api_path,
}
if (response_code != http_error_codes::ok) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to get object info");
return api_error::comm_error;
}
return api_error::success;
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
utils::error::raise_api_path_error(function_name, api_path, e,
"failed to get object info");
}
@@ -287,6 +296,8 @@ auto sia_provider::get_object_info(const std::string &api_path,
auto sia_provider::get_object_list(const std::string &api_path,
nlohmann::json &object_list) const -> bool {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
curl::requests::http_get get{};
get.allow_timeout = true;
get.path = "/api/bus/objects" + api_path + "/";
@@ -301,14 +312,14 @@ auto sia_provider::get_object_list(const std::string &api_path,
long response_code{};
stop_type stop_requested{};
if (not get_comm().make_request(get, response_code, stop_requested)) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::comm_error,
"failed to get object list");
return false;
}
if (response_code != http_error_codes::ok) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to get object list");
return false;
}
@@ -317,6 +328,8 @@ auto sia_provider::get_object_list(const std::string &api_path,
}
auto sia_provider::get_total_drive_space() const -> std::uint64_t {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
curl::requests::http_get get{};
get.allow_timeout = true;
@@ -337,14 +350,14 @@ auto sia_provider::get_total_drive_space() const -> std::uint64_t {
}
if (response_code != http_error_codes::ok) {
utils::error::raise_error(__FUNCTION__, response_code,
utils::error::raise_error(function_name, response_code,
"failed to get total drive space");
return 0U;
}
return config_data["contracts"]["storage"].get<std::uint64_t>();
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e,
utils::error::raise_error(function_name, e,
"failed to get total drive space");
}
@@ -352,6 +365,8 @@ auto sia_provider::get_total_drive_space() const -> std::uint64_t {
}
auto sia_provider::get_used_drive_space_impl() const -> std::uint64_t {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
curl::requests::http_get get{};
get.allow_timeout = true;
get.path = "/api/bus/stats/objects";
@@ -371,7 +386,7 @@ auto sia_provider::get_used_drive_space_impl() const -> std::uint64_t {
}
if (response_code != http_error_codes::ok) {
utils::error::raise_error(__FUNCTION__, response_code,
utils::error::raise_error(function_name, response_code,
"failed to get used drive space");
return 0U;
}
@@ -381,6 +396,8 @@ auto sia_provider::get_used_drive_space_impl() const -> std::uint64_t {
auto sia_provider::is_directory(const std::string &api_path, bool &exists) const
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (api_path == "/") {
exists = true;
return api_error::success;
@@ -403,7 +420,7 @@ auto sia_provider::is_directory(const std::string &api_path, bool &exists) const
}) != object_list.at("entries").end();
return api_error::success;
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
utils::error::raise_api_path_error(function_name, api_path, e,
"failed to determine path is directory");
}
@@ -412,6 +429,8 @@ auto sia_provider::is_directory(const std::string &api_path, bool &exists) const
auto sia_provider::is_file(const std::string &api_path, bool &exists) const
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
exists = false;
if (api_path == "/") {
return api_error::success;
@@ -431,7 +450,7 @@ auto sia_provider::is_file(const std::string &api_path, bool &exists) const
exists = not file_data.contains("entries");
return api_error::success;
} catch (const std::exception &e) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
utils::error::raise_api_path_error(function_name, api_path, e,
"failed to determine path is directory");
}
@@ -439,6 +458,8 @@ auto sia_provider::is_file(const std::string &api_path, bool &exists) const
}
auto sia_provider::is_online() const -> bool {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
try {
curl::requests::http_get get{};
get.allow_timeout = true;
@@ -455,22 +476,22 @@ auto sia_provider::is_online() const -> bool {
long response_code{};
stop_type stop_requested{};
if (not get_comm().make_request(get, response_code, stop_requested)) {
utils::error::raise_error(__FUNCTION__, api_error::comm_error,
utils::error::raise_error(function_name, api_error::comm_error,
"failed to determine if provider is online");
return false;
}
if (response_code != http_error_codes::ok) {
utils::error::raise_error(__FUNCTION__, response_code,
utils::error::raise_error(function_name, response_code,
"failed to determine if provider is online");
return false;
}
event_system::instance().raise<debug_log>(__FUNCTION__, "",
event_system::instance().raise<debug_log>(function_name, "",
state_data.dump());
return true;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e,
utils::error::raise_error(function_name, e,
"failed to determine if provider is online");
}
@@ -481,6 +502,8 @@ auto sia_provider::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 {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
curl::requests::http_get get{};
get.path = "/api/worker/objects" + api_path;
get.range = {{
@@ -498,13 +521,13 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
const auto notify_retry = [&]() {
if (response_code == 0) {
utils::error::raise_api_path_error(
__FUNCTION__, api_path, api_error::comm_error,
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));
} else {
utils::error::raise_api_path_error(
__FUNCTION__, api_path, response_code,
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));
@@ -531,6 +554,8 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
auto sia_provider::remove_directory_impl(const std::string &api_path)
-> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
curl::requests::http_delete del{};
del.allow_timeout = true;
del.path = "/api/bus/objects" + api_path + "/";
@@ -538,14 +563,14 @@ auto sia_provider::remove_directory_impl(const std::string &api_path)
long response_code{};
stop_type stop_requested{};
if (not get_comm().make_request(del, response_code, stop_requested)) {
utils::error::raise_api_path_error(__FUNCTION__, api_path,
utils::error::raise_api_path_error(function_name, api_path,
api_error::comm_error,
"failed to remove directory");
return api_error::comm_error;
}
if (response_code != http_error_codes::ok) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to remove directory");
return api_error::comm_error;
}
@@ -554,6 +579,8 @@ auto sia_provider::remove_directory_impl(const std::string &api_path)
}
auto sia_provider::remove_file_impl(const std::string &api_path) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
curl::requests::http_delete del{};
del.allow_timeout = true;
del.path = "/api/bus/objects" + api_path;
@@ -561,14 +588,15 @@ auto sia_provider::remove_file_impl(const std::string &api_path) -> api_error {
long response_code{};
stop_type stop_requested{};
if (not get_comm().make_request(del, response_code, stop_requested)) {
utils::error::raise_api_path_error(
__FUNCTION__, api_path, api_error::comm_error, "failed to remove file");
utils::error::raise_api_path_error(function_name, api_path,
api_error::comm_error,
"failed to remove file");
return api_error::comm_error;
}
if (response_code != http_error_codes::ok &&
response_code != http_error_codes::not_found) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to remove file");
return api_error::comm_error;
}
@@ -576,10 +604,36 @@ auto sia_provider::remove_file_impl(const std::string &api_path) -> api_error {
return api_error::success;
}
auto sia_provider::rename_file(const std::string & /*from_api_path*/,
const std::string & /*to_api_path*/)
-> api_error {
return api_error::not_implemented;
auto sia_provider::rename_file(const std::string &from_api_path,
const std::string &to_api_path) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
curl::requests::http_post post{};
post.path = "/api/bus/objects/rename";
post.json = nlohmann::json({
{"from", from_api_path},
{"to", to_api_path},
{"mode", "single"},
});
long response_code{};
stop_type stop_requested{};
if (not get_comm().make_request(post, response_code, stop_requested)) {
utils::error::raise_api_path_error(
function_name, from_api_path + '|' + to_api_path, api_error::comm_error,
"failed to rename file");
return api_error::comm_error;
}
if (response_code < http_error_codes::ok ||
response_code >= http_error_codes::multiple_choices) {
utils::error::raise_api_path_error(
function_name, from_api_path + '|' + to_api_path, response_code,
"failed to rename file file");
return api_error::comm_error;
}
return get_db().rename_item_meta(from_api_path, to_api_path);
}
auto sia_provider::start(api_item_added_callback api_item_added,
@@ -597,20 +651,22 @@ void sia_provider::stop() {
auto sia_provider::upload_file_impl(const std::string &api_path,
const std::string &source_path,
stop_type &stop_requested) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
curl::requests::http_put_file put_file{};
put_file.path = "/api/worker/objects" + api_path;
put_file.source_path = source_path;
long response_code{};
if (not get_comm().make_request(put_file, response_code, stop_requested)) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, source_path,
utils::error::raise_api_path_error(function_name, api_path, source_path,
api_error::comm_error,
"failed to upload file");
return api_error::comm_error;
}
if (response_code != http_error_codes::ok) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, source_path,
utils::error::raise_api_path_error(function_name, api_path, source_path,
response_code, "failed to upload file");
return api_error::comm_error;
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -89,13 +89,15 @@ void full_server::handle_get_pinned_files(const httplib::Request & /*req*/,
void full_server::handle_get_pinned_status(const httplib::Request &req,
httplib::Response &res) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const auto api_path =
utils::path::create_api_path(req.get_param_value("api_path"));
std::string pinned;
const auto result = provider_.get_item_meta(api_path, META_PINNED, pinned);
if (result != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, result,
utils::error::raise_api_path_error(function_name, api_path, result,
"failed to get pinned status");
res.status = 500;
return;
@@ -111,13 +113,15 @@ void full_server::handle_get_pinned_status(const httplib::Request &req,
void full_server::handle_pin_file(const httplib::Request &req,
httplib::Response &res) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const auto api_path =
utils::path::create_api_path(req.get_param_value("api_path"));
bool exists{};
auto result = provider_.is_file(api_path, exists);
if (result != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, result,
utils::error::raise_api_path_error(function_name, api_path, result,
"failed to pin file");
res.status = 500;
return;
@@ -138,13 +142,15 @@ void full_server::handle_pin_file(const httplib::Request &req,
void full_server::handle_unpin_file(const httplib::Request &req,
httplib::Response &res) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
const auto api_path =
utils::path::create_api_path(req.get_param_value("api_path"));
bool exists{};
auto result = provider_.is_file(api_path, exists);
if (result != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, result,
utils::error::raise_api_path_error(function_name, api_path, result,
"failed to unpin file");
res.status = 500;
return;

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -29,8 +29,10 @@ namespace repertory {
server::server(app_config &config) : config_(config) {}
auto server::check_authorization(const httplib::Request &req) -> bool {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (config_.get_api_auth().empty() || config_.get_api_user().empty()) {
utils::error::raise_error(__FUNCTION__,
utils::error::raise_error(function_name,
"authorization user or password is not set");
return false;
}
@@ -118,7 +120,9 @@ void server::initialize(httplib::Server &inst) {
}
void server::start() {
mutex_lock l(start_stop_mutex_);
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
mutex_lock lock(start_stop_mutex_);
if (not started_) {
event_system::instance().raise<service_started>("server");
server_ = std::make_unique<httplib::Server>();
@@ -132,11 +136,11 @@ void server::start() {
std::rethrow_exception(ep);
} catch (std::exception &e) {
data["error"] = e.what() ? e.what() : "unknown error";
utils::error::raise_error(__FUNCTION__, e,
utils::error::raise_error(function_name, e,
"failed request: " + req.path);
} catch (...) {
data["error"] = "unknown error";
utils::error::raise_error(__FUNCTION__, "unknown error",
utils::error::raise_error(function_name, "unknown error",
"failed request: " + req.path);
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -104,8 +104,7 @@ protected:
return traits_type::eof();
}
reader_.set_read_position(
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(gptr())));
reader_.set_read_position(reinterpret_cast<std::uintptr_t>(gptr()));
char c{};
const auto res = encrypting_reader::reader_function(&c, 1U, 1U, &reader_);
@@ -121,8 +120,7 @@ protected:
return traits_type::eof();
}
reader_.set_read_position(
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(gptr())));
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_);
@@ -172,8 +170,7 @@ encrypting_reader::encrypting_reader(
: key_(utils::encryption::generate_key(token)),
stop_requested_(stop_requested),
error_return_(error_return) {
const auto res = native_file::create_or_open(
source_path, not relative_parent_path.has_value(), source_file_);
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|" + source_path + '|' +
api_error_to_string(res));
@@ -202,15 +199,15 @@ encrypting_reader::encrypting_reader(
std::to_string(utils::get_last_error_code()));
}
const auto total_chunks = static_cast<std::size_t>(utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_)));
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
total_size_ =
file_size + (total_chunks * encrypting_reader::get_header_size());
last_data_chunk_ = total_chunks - 1U;
last_data_chunk_size_ = static_cast<std::size_t>(
(file_size <= data_chunk_size_) ? file_size
: (file_size % data_chunk_size_) == 0U ? data_chunk_size_
: file_size % data_chunk_size_);
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());
@@ -225,8 +222,7 @@ encrypting_reader::encrypting_reader(const std::string &encrypted_file_path,
: key_(utils::encryption::generate_key(token)),
stop_requested_(stop_requested),
error_return_(error_return) {
const auto res =
native_file::create_or_open(source_path, false, source_file_);
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|" + source_path + '|' +
api_error_to_string(res));
@@ -242,15 +238,15 @@ encrypting_reader::encrypting_reader(const std::string &encrypted_file_path,
std::to_string(utils::get_last_error_code()));
}
const auto total_chunks = static_cast<std::size_t>(utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_)));
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
total_size_ =
file_size + (total_chunks * encrypting_reader::get_header_size());
last_data_chunk_ = total_chunks - 1U;
last_data_chunk_size_ = static_cast<std::size_t>(
(file_size <= data_chunk_size_) ? file_size
: (file_size % data_chunk_size_) == 0U ? data_chunk_size_
: file_size % data_chunk_size_);
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());
@@ -267,8 +263,7 @@ encrypting_reader::encrypting_reader(
: key_(utils::encryption::generate_key(token)),
stop_requested_(stop_requested),
error_return_(error_return) {
const auto res =
native_file::create_or_open(source_path, false, source_file_);
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|" + source_path + '|' +
api_error_to_string(res));
@@ -284,15 +279,15 @@ encrypting_reader::encrypting_reader(
std::to_string(utils::get_last_error_code()));
}
const auto total_chunks = static_cast<std::size_t>(utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_)));
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
total_size_ =
file_size + (total_chunks * encrypting_reader::get_header_size());
last_data_chunk_ = total_chunks - 1U;
last_data_chunk_size_ = static_cast<std::size_t>(
(file_size <= data_chunk_size_) ? file_size
: (file_size % data_chunk_size_) == 0U ? data_chunk_size_
: file_size % data_chunk_size_);
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);
}
@@ -332,8 +327,8 @@ auto encrypting_reader::calculate_encrypted_size(const std::string &source_path)
std::to_string(utils::get_last_error_code()));
}
const auto total_chunks = static_cast<std::size_t>(utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_)));
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
return file_size + (total_chunks * encrypting_reader::get_header_size());
}
@@ -345,20 +340,21 @@ auto encrypting_reader::create_iostream() const
auto encrypting_reader::reader_function(char *buffer, size_t size,
size_t nitems) -> size_t {
constexpr const auto *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 = static_cast<std::size_t>(read_offset_ / encrypted_chunk_size_);
auto chunk_offset =
static_cast<std::size_t>(read_offset_ % encrypted_chunk_size_);
std::size_t total_read = 0u;
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) {
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_
@@ -378,8 +374,9 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
}
auto &chunk_buffer = chunk_buffers_[chunk];
const auto to_read =
std::min(chunk_buffer.size() - chunk_offset, remain);
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;
@@ -388,7 +385,7 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
read_offset_ += to_read;
}
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
utils::error::raise_error(function_name, e, "exception occurred");
ret = false;
}
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -72,16 +72,16 @@ auto generate_key(const std::string &encryption_token) -> key_type {
throw std::runtime_error("failed to initialize sha256|" +
std::to_string(res));
}
if ((res = crypto_hash_sha256_update(
&state,
reinterpret_cast<const unsigned char *>(encryption_token.c_str()),
strnlen(encryption_token.c_str(), encryption_token.size()))) != 0) {
res = crypto_hash_sha256_update(
&state, reinterpret_cast<const unsigned char *>(encryption_token.c_str()),
strnlen(encryption_token.c_str(), encryption_token.size()));
if (res != 0) {
throw std::runtime_error("failed to update sha256|" + std::to_string(res));
}
key_type ret{};
if ((res = crypto_hash_sha256_final(&state, ret.data())) != 0) {
res = crypto_hash_sha256_final(&state, ret.data());
if (res != 0) {
throw std::runtime_error("failed to finalize sha256|" +
std::to_string(res));
}
@@ -89,11 +89,9 @@ auto generate_key(const std::string &encryption_token) -> key_type {
return ret;
}
auto read_encrypted_range(
const http_range &range, const key_type &key,
const std::function<api_error(data_buffer &ct, std::uint64_t start_offset,
std::uint64_t end_offset)> &reader,
std::uint64_t total_size, data_buffer &data) -> api_error {
auto read_encrypted_range(const http_range &range, const key_type &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 =
@@ -108,31 +106,33 @@ auto read_encrypted_range(
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 ct;
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)) + header_size -
1U,
static_cast<std::uint64_t>(start_offset + encrypted_chunk_size - 1U));
const auto result = reader(ct, start_offset, end_offset);
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, ct, source_buffer)) {
if (not utils::encryption::decrypt_data(key, cypher, source_buffer)) {
return api_error::decryption_error;
}
ct.clear();
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(source_buffer.begin() + source_offset,
source_buffer.begin() + source_offset + data_size,
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;
source_offset = 0U;
}
return api_error::success;

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -26,147 +26,141 @@
#include "types/repertory.hpp"
namespace repertory::utils::error {
void raise_error(std::string_view function, std::string_view msg) {
void raise_error(std::string function, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function), static_cast<std::string>(msg));
function, static_cast<std::string>(msg));
}
void raise_error(std::string_view function, const api_error &e,
void raise_error(std::string function, const api_error &err,
std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|err|" + api_error_to_string(e));
function,
static_cast<std::string>(msg) + "|err|" + api_error_to_string(err));
}
void raise_error(std::string_view function, const std::exception &e,
void raise_error(std::string function, const std::exception &exception,
std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
function,
static_cast<std::string>(msg) + "|err|" +
(e.what() ? e.what() : "unknown error"));
(exception.what() == nullptr ? "unknown error" : exception.what()));
}
void raise_error(std::string_view function, const json &e,
std::string_view msg) {
void raise_error(std::string function, const json &err, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|err|" + e.dump(2));
function, static_cast<std::string>(msg) + "|err|" + err.dump(2));
}
void raise_error(std::string_view function, std::int64_t e,
std::string_view msg) {
void raise_error(std::string function, std::int64_t err, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|err|" + std::to_string(e));
function, static_cast<std::string>(msg) + "|err|" + std::to_string(err));
}
void raise_error(std::string_view function, const api_error &e,
void raise_error(std::string function, const api_error &err,
std::string_view file_path, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
function, static_cast<std::string>(msg) + "|sp|" +
static_cast<std::string>(file_path) + "|err|" +
api_error_to_string(err));
}
void raise_error(std::string function, std::int64_t err,
std::string_view file_path, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
function, static_cast<std::string>(msg) + "|sp|" +
static_cast<std::string>(file_path) + "|err|" +
std::to_string(err));
}
void raise_error(std::string function, const std::exception &exception,
std::string_view file_path, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
function,
static_cast<std::string>(msg) + "|sp|" +
static_cast<std::string>(file_path) + "|err|" +
api_error_to_string(e));
(exception.what() == nullptr ? "unknown error" : exception.what()));
}
void raise_error(std::string_view function, std::int64_t e,
std::string_view file_path, std::string_view msg) {
void raise_api_path_error(std::string function, std::string_view api_path,
const api_error &err, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|sp|" +
static_cast<std::string>(file_path) + "|err|" + std::to_string(e));
function, static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|err|" +
api_error_to_string(err));
}
void raise_error(std::string_view function, const std::exception &e,
std::string_view file_path, std::string_view msg) {
void raise_api_path_error(std::string function, std::string_view api_path,
std::int64_t err, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|sp|" +
static_cast<std::string>(file_path) + "|err|" +
(e.what() ? e.what() : "unknown error"));
function, static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|err|" +
std::to_string(err));
}
void raise_api_path_error(std::string_view function, std::string_view api_path,
const api_error &e, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|err|" +
api_error_to_string(e));
}
void raise_api_path_error(std::string_view function, std::string_view api_path,
std::int64_t e, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|err|" + std::to_string(e));
}
void raise_api_path_error(std::string_view function, std::string_view api_path,
const std::exception &e, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|err|" +
(e.what() ? e.what() : "unknown error"));
}
void raise_api_path_error(std::string_view function, std::string_view api_path,
std::string_view source_path, const api_error &e,
void raise_api_path_error(std::string function, std::string_view api_path,
const std::exception &exception,
std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
function,
static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|err|" +
(exception.what() == nullptr ? "unknown error" : exception.what()));
}
void raise_api_path_error(std::string function, std::string_view api_path,
std::string_view source_path, const api_error &err,
std::string_view msg) {
event_system::instance().raise<repertory_exception>(
function, static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|sp|" +
static_cast<std::string>(source_path) + "|err|" +
api_error_to_string(err));
}
void raise_api_path_error(std::string function, std::string_view api_path,
std::string_view source_path, std::int64_t err,
std::string_view msg) {
event_system::instance().raise<repertory_exception>(
function, static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|sp|" +
static_cast<std::string>(source_path) + "|err|" +
std::to_string(err));
}
void raise_api_path_error(std::string function, std::string_view api_path,
const json &err, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
function, static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|err|" + err.dump(2));
}
void raise_api_path_error(std::string function, std::string_view api_path,
std::string_view source_path,
const std::exception &exception,
std::string_view msg) {
event_system::instance().raise<repertory_exception>(
function,
static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|sp|" +
static_cast<std::string>(source_path) + "|err|" +
api_error_to_string(e));
(exception.what() == nullptr ? "unknown error" : exception.what()));
}
void raise_api_path_error(std::string_view function, std::string_view api_path,
std::string_view source_path, std::int64_t e,
std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|sp|" +
static_cast<std::string>(source_path) + "|err|" + std::to_string(e));
}
void raise_api_path_error(std::string_view function, std::string_view api_path,
const json &e, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|err|" + e.dump(2));
}
void raise_api_path_error(std::string_view function, std::string_view api_path,
std::string_view source_path, const std::exception &e,
std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|ap|" +
static_cast<std::string>(api_path) + "|sp|" +
static_cast<std::string>(source_path) + "|err|" +
(e.what() ? e.what() : "unknown error"));
}
void raise_url_error(std::string_view function, std::string_view url,
CURLcode e, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
static_cast<std::string>(msg) + "|url|" + static_cast<std::string>(url) +
"|err|" + curl_easy_strerror(e));
}
void raise_url_error(std::string_view function, std::string_view url,
std::string_view source_path, const std::exception &e,
void raise_url_error(std::string function, std::string_view url, CURLcode err,
std::string_view msg) {
event_system::instance().raise<repertory_exception>(
static_cast<std::string>(function),
function, static_cast<std::string>(msg) + "|url|" +
static_cast<std::string>(url) + "|err|" +
curl_easy_strerror(err));
}
void raise_url_error(std::string function, std::string_view url,
std::string_view source_path,
const std::exception &exception, std::string_view msg) {
event_system::instance().raise<repertory_exception>(
function,
static_cast<std::string>(msg) + "|url|" + static_cast<std::string>(url) +
"|sp|" + static_cast<std::string>(source_path) + "|err|" +
(e.what() ? e.what() : "unknown error"));
(exception.what() == nullptr ? "unknown error" : exception.what()));
}
} // namespace repertory::utils::error

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -30,9 +30,9 @@
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 = 0u;
std::uint64_t ret{};
#ifdef _WIN32
WIN32_FIND_DATA fd = {0};
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
@@ -118,7 +118,7 @@ auto copy_directory_recursively(std::string from_path, std::string to_path)
auto ret = create_full_directory_path(to_path);
if (ret) {
#ifdef _WIN32
WIN32_FIND_DATA fd = {0};
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(from_path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
@@ -209,7 +209,7 @@ auto delete_directory_recursively(std::string path) -> bool {
path = utils::path::absolute(path);
#ifdef _WIN32
WIN32_FIND_DATA fd = {0};
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
@@ -361,7 +361,7 @@ auto get_directory_files(std::string path, bool oldest_first, bool recursive)
std::deque<std::string> ret;
std::unordered_map<std::string, std::uint64_t> lookup;
#ifdef _WIN32
WIN32_FIND_DATA fd = {0};
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
@@ -531,15 +531,17 @@ auto is_file(const std::string &path) -> bool {
auto is_modified_date_older_than(const std::string &path,
const std::chrono::hours &hours) -> bool {
auto ret = false;
std::uint64_t modified = 0;
std::uint64_t modified{};
if (get_modified_time(path, modified)) {
const auto seconds =
std::chrono::duration_cast<std::chrono::seconds>(hours);
#ifdef _WIN32
return (std::chrono::system_clock::from_time_t(modified) + seconds) <
std::chrono::system_clock::now();
return (std::chrono::system_clock::from_time_t(
static_cast<time_t>(modified)) +
seconds) < std::chrono::system_clock::now();
#else
return (modified + (seconds.count() * NANOS_PER_SECOND)) <
return (modified +
static_cast<std::uint64_t>(seconds.count() * NANOS_PER_SECOND)) <
utils::get_time_now();
#endif
}
@@ -579,6 +581,8 @@ auto read_file_lines(const std::string &path) -> std::vector<std::string> {
}
auto read_json_file(const std::string &path, json &data) -> bool {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (not utils::file::is_file(path)) {
return true;
}
@@ -603,7 +607,7 @@ auto read_json_file(const std::string &path, json &data) -> bool {
}
}
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, path,
utils::error::raise_error(function_name, e, path,
"failed to read json file");
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -35,20 +35,21 @@ native_file::~native_file() {
}
}
auto native_file::clone(const native_file_ptr &nf) -> native_file_ptr {
auto native_file::clone(const native_file_ptr &ptr) -> native_file_ptr {
std::string source_path;
#ifdef _WIN32
source_path.resize(MAX_PATH + 1);
::GetFinalPathNameByHandleA(nf->get_handle(), &source_path[0u], 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);
#ifdef __APPLE__
fcntl(nf->get_handle(), F_GETPATH, &source_path[0u]);
fcntl(ptr->get_handle(), F_GETPATH, source_path.data());
#else
readlink(("/proc/self/fd/" + std::to_string(nf->get_handle())).c_str(),
&source_path[0u], source_path.size());
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();
@@ -63,52 +64,60 @@ auto native_file::clone(const native_file_ptr &nf) -> native_file_ptr {
return clone;
}
auto native_file::create_or_open(const std::string &source_path,
[[maybe_unused]] bool should_chmod,
native_file_ptr &nf) -> api_error {
auto native_file::create_or_open(const std::string &source_path, bool read_only,
native_file_ptr &ptr) -> api_error {
#ifdef _WIN32
auto handle = ::CreateFileA(source_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, nullptr);
auto handle =
read_only
? ::CreateFileA(source_path.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, nullptr)
: ::CreateFileA(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 = should_chmod ? ::open(source_path.c_str(),
O_CREAT | O_RDWR | O_CLOEXEC, 0600u)
: ::open(source_path.c_str(), O_RDWR | O_CLOEXEC);
if (should_chmod) {
chmod(source_path.c_str(), 0600u);
auto handle =
read_only
? ::open(source_path.c_str(), O_CREAT | O_RDONLY | O_CLOEXEC, 0600U)
: ::open(source_path.c_str(), O_CREAT | O_RDWR | O_CLOEXEC, 0600U);
if (not read_only) {
chmod(source_path.c_str(), 0600U);
}
#endif
nf = native_file::attach(handle);
ptr = native_file::attach(handle);
return ((handle == REPERTORY_INVALID_HANDLE) ? api_error::os_error
: api_error::success);
}
auto native_file::create_or_open(const std::string &source_path,
native_file_ptr &nf) -> api_error {
return create_or_open(source_path, true, nf);
native_file_ptr &ptr) -> api_error {
return create_or_open(source_path, false, ptr);
}
auto native_file::open(const std::string &source_path, native_file_ptr &nf)
auto native_file::open(const std::string &source_path, native_file_ptr &ptr)
-> api_error {
return open(source_path, true, nf);
return open(source_path, false, ptr);
}
auto native_file::open(const std::string &source_path,
[[maybe_unused]] bool should_chmod, native_file_ptr &nf)
-> api_error {
auto native_file::open(const std::string &source_path, bool read_only,
native_file_ptr &ptr) -> api_error {
#ifdef _WIN32
auto handle = ::CreateFileA(source_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr);
auto handle =
read_only
? ::CreateFileA(source_path.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr)
: ::CreateFileA(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 = should_chmod
? ::open(source_path.c_str(), O_RDWR | O_CLOEXEC, 0600u)
: ::open(source_path.c_str(), O_RDONLY | O_CLOEXEC);
if (should_chmod) {
chmod(source_path.c_str(), 0600u);
auto handle = read_only ? ::open(source_path.c_str(), O_RDONLY | O_CLOEXEC)
: ::open(source_path.c_str(), O_RDWR | O_CLOEXEC);
if (not read_only) {
chmod(source_path.c_str(), 0600U);
}
#endif
nf = native_file::attach(handle);
ptr = native_file::attach(handle);
return ((handle == REPERTORY_INVALID_HANDLE) ? api_error::os_error
: api_error::success);
}
@@ -116,12 +125,12 @@ auto native_file::open(const std::string &source_path,
auto native_file::allocate(std::uint64_t file_size) -> bool {
#ifdef _WIN32
LARGE_INTEGER li{};
li.QuadPart = file_size;
li.QuadPart = static_cast<LONGLONG>(file_size);
return (::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN) &&
::SetEndOfFile(handle_));
#endif
#ifdef __linux__
return (fallocate(handle_, 0, 0, file_size) >= 0);
return (fallocate(handle_, 0, 0, static_cast<off_t>(file_size)) >= 0);
#endif
#ifdef __APPLE__
return (ftruncate(handle_, file_size) >= 0);
@@ -139,19 +148,19 @@ void native_file::close() {
}
}
auto native_file::copy_from(const native_file_ptr &nf) -> bool {
auto ret = false;
std::uint64_t file_size = 0u;
if ((ret = nf->get_file_size(file_size))) {
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(65536u * 2u);
std::uint64_t offset = 0u;
while (ret && (file_size > 0u)) {
buffer.resize(65536ULL * 2ULL);
std::uint64_t offset{};
while (ret && (file_size > 0U)) {
std::size_t bytes_read{};
if ((ret = nf->read_bytes(&buffer[0u], buffer.size(), offset,
bytes_read))) {
std::size_t bytes_written = 0u;
ret = write_bytes(&buffer[0u], bytes_read, offset, bytes_written);
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;
}
@@ -164,10 +173,10 @@ auto native_file::copy_from(const native_file_ptr &nf) -> bool {
auto native_file::copy_from(const std::string &path) -> bool {
auto ret = false;
native_file_ptr nf;
if (native_file::create_or_open(path, nf) == api_error ::success) {
ret = copy_from(nf);
nf->close();
native_file_ptr ptr;
if (native_file::create_or_open(path, ptr) == api_error ::success) {
ret = copy_from(ptr);
ptr->close();
}
return ret;
@@ -191,14 +200,15 @@ auto native_file::get_file_size(std::uint64_t &file_size) -> bool {
}
#else
#if __APPLE__
struct stat st {};
if (fstat(handle_, &st) >= 0) {
struct stat unix_st {};
if (fstat(handle_, &unix_st) >= 0) {
#else
struct stat64 st {};
if (fstat64(handle_, &st) >= 0) {
struct stat64 unix_st {};
if (fstat64(handle_, &unix_st) >= 0) {
#endif
if ((ret = (st.st_size >= 0))) {
file_size = static_cast<uint64_t>(st.st_size);
ret = (unix_st.st_size >= 0);
if (ret) {
file_size = static_cast<uint64_t>(unix_st.st_size);
}
}
#endif
@@ -214,7 +224,7 @@ auto native_file::read_bytes(char *buffer, std::size_t read_size,
auto ret = false;
bytes_read = 0u;
LARGE_INTEGER li{};
li.QuadPart = read_offset;
li.QuadPart = static_cast<LONGLONG>(read_offset);
if ((ret = !!::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN))) {
DWORD current_read = 0u;
do {
@@ -236,11 +246,11 @@ auto native_file::read_bytes(char *buffer, std::size_t read_size,
auto native_file::read_bytes(char *buffer, std::size_t read_size,
std::uint64_t read_offset, std::size_t &bytes_read)
-> bool {
bytes_read = 0u;
bytes_read = 0U;
ssize_t result = 0;
do {
result = pread64(handle_, &buffer[bytes_read], read_size - bytes_read,
read_offset + bytes_read);
static_cast<off_t>(read_offset + bytes_read));
if (result > 0) {
bytes_read += static_cast<size_t>(result);
}
@@ -253,11 +263,11 @@ auto native_file::truncate(std::uint64_t file_size) -> bool {
#ifdef _WIN32
recur_mutex_lock l(read_write_mutex_);
LARGE_INTEGER li{};
li.QuadPart = file_size;
li.QuadPart = static_cast<LONGLONG>(file_size);
return (::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN) &&
::SetEndOfFile(handle_));
#else
return (ftruncate(handle_, file_size) >= 0);
return (ftruncate(handle_, static_cast<off_t>(file_size)) >= 0);
#endif
}
@@ -271,7 +281,7 @@ auto native_file::write_bytes(const char *buffer, std::size_t write_size,
auto ret = true;
LARGE_INTEGER li{};
li.QuadPart = write_offset;
li.QuadPart = static_cast<LONGLONG>(write_offset);
if ((ret = !!::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN))) {
do {
DWORD current_write = 0u;
@@ -288,11 +298,12 @@ auto native_file::write_bytes(const char *buffer, std::size_t write_size,
auto native_file::write_bytes(const char *buffer, std::size_t write_size,
std::uint64_t write_offset,
std::size_t &bytes_written) -> bool {
bytes_written = 0;
ssize_t result = 0;
bytes_written = 0U;
ssize_t result{};
do {
result = pwrite64(handle_, &buffer[bytes_written],
write_size - bytes_written, write_offset + bytes_written);
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);
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -30,13 +30,15 @@ namespace repertory::utils::string {
return std::equal(val.rbegin(), val.rend(), str.rbegin());
}
auto from_bool(bool val) -> std::string { return std::to_string(val); }
auto from_bool(bool val) -> std::string {
return std::to_string(static_cast<int>(val));
}
auto from_dynamic_bitset(const boost::dynamic_bitset<> &bitset) -> std::string {
std::stringstream ss;
boost::archive::text_oarchive archive(ss);
std::stringstream stream;
boost::archive::text_oarchive archive(stream);
archive << bitset;
return ss.str();
return stream.str();
}
auto from_utf8(const std::string &str) -> std::wstring {
@@ -46,27 +48,28 @@ auto from_utf8(const std::string &str) -> std::wstring {
.from_bytes(str);
}
/* constexpr c++20 */ auto is_numeric(std::string_view s) -> bool {
if ((s.length() > 1u) && (s[0u] == '+' || s[0u] == '-')) {
s = s.substr(1u);
/* constexpr c++20 */ auto is_numeric(std::string_view str) -> bool {
if ((str.length() > 1U) && (str[0U] == '+' || str[0U] == '-')) {
str = str.substr(1U);
}
if (s.empty()) {
if (str.empty()) {
return false;
}
auto has_decimal = false;
return std::find_if(
s.begin(), s.end(),
[&has_decimal](const std::string_view::value_type &c) -> bool {
if (has_decimal && c == '.') {
return true;
}
if ((has_decimal = has_decimal || c == '.')) {
return false;
}
return not std::isdigit(c);
}) == s.end();
return std::find_if(str.begin(), str.end(),
[&has_decimal](
const std::string_view::value_type &cur_ch) -> bool {
if (has_decimal && cur_ch == '.') {
return true;
}
has_decimal = has_decimal || cur_ch == '.';
if (has_decimal) {
return false;
}
return std::isdigit(cur_ch) == 0;
}) == str.end();
}
auto join(const std::vector<std::string> &arr, const char &delim)
@@ -76,15 +79,17 @@ auto join(const std::vector<std::string> &arr, const char &delim)
}
return std::accumulate(
std::next(arr.begin()), arr.end(), arr[0u],
[&delim](auto s, const auto &v) { return s + delim + v; });
std::next(arr.begin()), arr.end(), arr[0U],
[&delim](auto str, const auto &cur) { return str + delim + cur; });
}
auto left_trim(std::string &s) -> std::string & { return left_trim(s, ' '); }
auto left_trim(std::string &str) -> std::string & {
return left_trim(str, ' ');
}
auto left_trim(std::string &s, const char &c) -> std::string & {
s.erase(0, s.find_first_not_of(c));
return s;
auto left_trim(std::string &str, const char &trim_ch) -> std::string & {
str.erase(0, str.find_first_not_of(trim_ch));
return str;
}
auto replace(std::string &src, const char &character, const char &with)
@@ -115,47 +120,49 @@ auto replace_copy(std::string src, const std::string &find,
return replace(src, find, with, start_pos);
}
auto right_trim(std::string &s) -> std::string & { return right_trim(s, ' '); }
auto right_trim(std::string &str) -> std::string & {
return right_trim(str, ' ');
}
auto right_trim(std::string &s, const char &c) -> std::string & {
s.erase(s.find_last_not_of(c) + 1);
return s;
auto right_trim(std::string &str, const char &trim_ch) -> std::string & {
str.erase(str.find_last_not_of(trim_ch) + 1);
return str;
}
auto split(const std::string &str, const char &delim, bool should_trim)
-> std::vector<std::string> {
std::vector<std::string> ret;
std::stringstream ss(str);
std::stringstream stream(str);
std::string item;
while (std::getline(ss, item, delim)) {
while (std::getline(stream, item, delim)) {
ret.push_back(should_trim ? trim(item) : item);
}
return ret;
}
auto to_bool(std::string val) -> bool {
auto b = false;
auto ret = false;
trim(val);
if (is_numeric(val)) {
if (contains(val, ".")) {
b = (to_double(val) != 0.0);
ret = (to_double(val) != 0.0);
} else {
std::istringstream(val) >> b;
std::istringstream(val) >> ret;
}
} else {
std::istringstream(to_lower(val)) >> std::boolalpha >> b;
std::istringstream(to_lower(val)) >> std::boolalpha >> ret;
}
return b;
return ret;
}
auto to_double(const std::string &str) -> double { return std::stod(str); }
auto to_dynamic_bitset(const std::string &val) -> boost::dynamic_bitset<> {
std::stringstream ss(val);
std::stringstream stream(val);
boost::dynamic_bitset<> bitset;
boost::archive::text_iarchive archive(ss);
boost::archive::text_iarchive archive(stream);
archive >> bitset;
return bitset;
}
@@ -209,15 +216,15 @@ auto trim(std::string &str) -> std::string & {
return right_trim(left_trim(str));
}
auto trim(std::string &str, const char &c) -> std::string & {
return right_trim(left_trim(str, c), c);
auto trim(std::string &str, const char &trim_ch) -> std::string & {
return right_trim(left_trim(str, trim_ch), trim_ch);
}
auto trim_copy(std::string str) -> std::string {
return right_trim(left_trim(str));
}
auto trim_copy(std::string str, const char &c) -> std::string {
return right_trim(left_trim(str, c), c);
auto trim_copy(std::string str, const char &trim_ch) -> std::string {
return right_trim(left_trim(str, trim_ch), trim_ch);
}
} // namespace repertory::utils::string

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -28,13 +28,13 @@
namespace repertory::utils {
#ifndef __APPLE__
auto convert_to_uint64(const pthread_t &t) -> std::uint64_t {
return static_cast<std::uint64_t>(t);
auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t {
return static_cast<std::uint64_t>(thread);
}
#endif
auto from_api_error(const api_error &e) -> int {
switch (e) {
auto from_api_error(const api_error &err) -> int {
switch (err) {
case api_error::access_denied:
return -EACCES;
case api_error::bad_address:
@@ -107,18 +107,16 @@ auto get_thread_id() -> std::uint64_t {
}
auto is_uid_member_of_group(const uid_t &uid, const gid_t &gid) -> bool {
static const auto function_name = __FUNCTION__;
std::vector<gid_t> groups{};
use_getpwuid(uid, [&groups](struct passwd *pw) {
use_getpwuid(uid, [&groups](struct passwd *pass) {
int group_count{};
if (getgrouplist(pw->pw_name, pw->pw_gid, nullptr, &group_count) < 0) {
if (getgrouplist(pass->pw_name, pass->pw_gid, nullptr, &group_count) < 0) {
groups.resize(static_cast<std::size_t>(group_count));
#ifdef __APPLE__
getgrouplist(pw->pw_name, pw->pw_gid,
getgrouplist(pass->pw_name, pass->pw_gid,
reinterpret_cast<int *>(groups.data()), &group_count);
#else
getgrouplist(pw->pw_name, pw->pw_gid, groups.data(), &group_count);
getgrouplist(pass->pw_name, pass->pw_gid, groups.data(), &group_count);
#endif
}
});
@@ -126,8 +124,8 @@ auto is_uid_member_of_group(const uid_t &uid, const gid_t &gid) -> bool {
return collection_includes(groups, gid);
}
auto to_api_error(int e) -> api_error {
switch (abs(e)) {
auto to_api_error(int err) -> api_error {
switch (abs(err)) {
case 0:
return api_error::success;
case EBADF:
@@ -196,8 +194,8 @@ auto to_api_error(int e) -> api_error {
void set_last_error_code(int error_code) { errno = error_code; }
auto unix_error_to_windows(int e) -> std::int32_t {
switch (e) {
auto unix_error_to_windows(int err) -> std::int32_t {
switch (err) {
case 0:
return STATUS_SUCCESS;
case EACCES:
@@ -236,20 +234,23 @@ auto unix_error_to_windows(int e) -> std::int32_t {
}
}
auto unix_time_to_windows_time(const remote::file_time &ts) -> UINT64 {
return (ts / 100ull) + 116444736000000000ull;
auto unix_time_to_windows_time(const remote::file_time &file_time) -> UINT64 {
return (file_time / 100ULL) + 116444736000000000ULL;
}
void use_getpwuid(uid_t uid, std::function<void(struct passwd *pw)> fn) {
void use_getpwuid(uid_t uid,
std::function<void(struct passwd *pass)> callback) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
static std::mutex mtx{};
mutex_lock lock{mtx};
auto *pw = getpwuid(uid);
if (not pw) {
utils::error::raise_error(__FUNCTION__, "'getpwuid' returned nullptr");
auto *temp_pw = getpwuid(uid);
if (temp_pw == nullptr) {
utils::error::raise_error(function_name, "'getpwuid' returned nullptr");
return;
}
fn(pw);
callback(temp_pw);
}
void windows_create_to_unix(const UINT32 &create_options,
@@ -257,20 +258,20 @@ void windows_create_to_unix(const UINT32 &create_options,
remote::file_mode &mode) {
mode = S_IRUSR | S_IWUSR;
flags = O_CREAT | O_RDWR;
if (create_options & FILE_DIRECTORY_FILE) {
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
mode |= S_IXUSR;
flags = O_DIRECTORY;
}
if ((granted_access & GENERIC_EXECUTE) ||
(granted_access & FILE_GENERIC_EXECUTE) ||
(granted_access & FILE_EXECUTE)) {
if (((granted_access & GENERIC_EXECUTE) != 0U) ||
((granted_access & FILE_GENERIC_EXECUTE) != 0U) ||
((granted_access & FILE_EXECUTE) != 0U)) {
mode |= (S_IXUSR);
}
}
auto windows_time_to_unix_time(std::uint64_t t) -> remote::file_time {
return (t - 116444736000000000ull) * 100ull;
auto windows_time_to_unix_time(std::uint64_t win_time) -> remote::file_time {
return (win_time - 116444736000000000ULL) * 100ULL;
}
} // namespace repertory::utils

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -30,7 +30,6 @@
#include "utils/native_file.hpp"
#include "utils/path_utils.hpp"
#include "utils/string_utils.hpp"
#include <limits>
namespace repertory::utils {
void calculate_allocation_size(bool directory, std::uint64_t file_size,
@@ -171,16 +170,16 @@ auto download_type_to_string(const download_type &type) -> std::string {
// https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
auto filetime_to_unix_time(const FILETIME &ft) -> remote::file_time {
LARGE_INTEGER date{};
date.HighPart = ft.dwHighDateTime;
date.HighPart = static_cast<LONG>(ft.dwHighDateTime);
date.LowPart = ft.dwLowDateTime;
date.QuadPart -= 116444736000000000ULL;
date.QuadPart -= 116444736000000000LL;
return date.QuadPart * 100ULL;
return static_cast<remote::file_time>(date.QuadPart) * 100ULL;
}
void unix_time_to_filetime(const remote::file_time &ts, FILETIME &ft) {
const auto win_time = (ts / 100ULL) + 116444736000000000ULL;
ft.dwHighDateTime = win_time >> 32U;
ft.dwHighDateTime = static_cast<DWORD>(win_time >> 32U);
ft.dwLowDateTime = win_time & 0xFFFFFFFF;
}
#endif
@@ -217,7 +216,8 @@ auto get_file_time_now() -> std::uint64_t {
::GetSystemTime(&st);
FILETIME ft{};
::SystemTimeToFileTime(&st, &ft);
return static_cast<std::uint64_t>(((LARGE_INTEGER *)&ft)->QuadPart);
return static_cast<std::uint64_t>(
(reinterpret_cast<LARGE_INTEGER *>(&ft))->QuadPart);
#else
return get_time_now();
#endif
@@ -231,13 +231,7 @@ void get_local_time_now(struct tm &local_time) {
#ifdef _WIN32
localtime_s(&local_time, &now);
#else
static std::mutex mtx{};
mutex_lock lock{mtx};
const auto *tmp = std::localtime(&now);
if (tmp != nullptr) {
memcpy(&local_time, tmp, sizeof(local_time));
}
localtime_r(&now, &local_time);
#endif
}

View File

@@ -1,5 +1,5 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
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
@@ -28,7 +28,7 @@
#include "utils/string_utils.hpp"
#ifndef STATUS_DEVICE_INSUFFICIENT_RESOURCES
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC0000468L)
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES static_cast<NTSTATUS>(0xC0000468L)
#endif
namespace repertory::utils {
@@ -95,9 +95,9 @@ auto get_local_app_data_directory() -> const std::string & {
PWSTR local_app_data{};
if (SUCCEEDED(::SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr,
&local_app_data))) {
auto app_data = utils::string::to_utf8(local_app_data);
auto ret = utils::string::to_utf8(local_app_data);
::CoTaskMemFree(local_app_data);
return app_data;
return ret;
}
throw startup_exception("unable to detect local application data folder");
@@ -164,14 +164,14 @@ auto run_process_elevated(std::vector<const char *> args) -> int {
sei.nShow = SW_NORMAL;
if (::ShellExecuteEx(&sei)) {
::WaitForSingleObject(sei.hProcess, INFINITE);
DWORD exit_code = 0u;
DWORD exit_code{};
::GetExitCodeProcess(sei.hProcess, &exit_code);
::CloseHandle(sei.hProcess);
return exit_code;
return static_cast<int>(exit_code);
}
}
return ::GetLastError();
return static_cast<int>(::GetLastError());
}
void set_last_error_code(DWORD error_code) { ::SetLastError(error_code); }
@@ -234,7 +234,7 @@ auto unix_open_flags_to_flags_and_perms(const remote::file_mode & /*mode*/,
}
auto time64_to_unix_time(const __time64_t &t) -> remote::file_time {
return t * NANOS_PER_SECOND;
return static_cast<remote::file_time>(t * NANOS_PER_SECOND);
}
} // namespace repertory::utils