initial commit
This commit is contained in:
382
include/app_config.hpp
Normal file
382
include/app_config.hpp
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_APP_CONFIG_HPP_
|
||||
#define INCLUDE_APP_CONFIG_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/skynet.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config final {
|
||||
public:
|
||||
static std::string default_agent_name(const provider_type &pt);
|
||||
|
||||
static std::uint16_t default_api_port(const provider_type &pt);
|
||||
|
||||
static std::string default_data_directory(const provider_type &pt);
|
||||
|
||||
static std::uint16_t default_rpc_port(const provider_type &pt);
|
||||
|
||||
static std::string get_provider_api_password(const provider_type &pt);
|
||||
|
||||
static std::string get_provider_display_name(const provider_type &pt);
|
||||
|
||||
static std::string get_provider_minimum_version(const provider_type &pt);
|
||||
|
||||
static std::string get_provider_name(const provider_type &pt);
|
||||
|
||||
static std::string get_provider_path_name(const provider_type &pt);
|
||||
|
||||
public:
|
||||
explicit app_config(const provider_type &pt, const std::string &data_directory = "");
|
||||
|
||||
~app_config() { save(); }
|
||||
|
||||
private:
|
||||
const provider_type pt_;
|
||||
std::string api_auth_;
|
||||
std::uint16_t api_port_;
|
||||
std::string api_user_;
|
||||
bool config_changed_;
|
||||
const std::string data_directory_;
|
||||
std::uint8_t download_timeout_secs_;
|
||||
bool enable_chunk_downloader_timeout_;
|
||||
bool enable_comm_duration_events_;
|
||||
bool enable_drive_events_;
|
||||
bool enable_max_cache_size_;
|
||||
#ifdef _WIN32
|
||||
bool enable_mount_manager_;
|
||||
#endif
|
||||
bool enable_remote_mount_;
|
||||
event_level event_level_;
|
||||
std::uint32_t eviction_delay_mins_;
|
||||
bool eviction_uses_accessed_time_;
|
||||
std::uint8_t high_freq_interval_secs_;
|
||||
bool is_remote_mount_;
|
||||
std::uint32_t low_freq_interval_secs_;
|
||||
std::uint64_t max_cache_size_bytes_;
|
||||
std::uint8_t max_upload_count_;
|
||||
std::uint8_t min_download_timeout_secs_;
|
||||
double minimum_redundancy_;
|
||||
std::uint16_t online_check_retry_secs_;
|
||||
std::uint16_t orphaned_file_retention_days_;
|
||||
std::string preferred_download_type_;
|
||||
std::uint8_t read_ahead_count_;
|
||||
std::uint8_t remote_client_pool_size_;
|
||||
std::string remote_host_name_or_ip_;
|
||||
std::uint8_t remote_max_connections_;
|
||||
std::uint16_t remote_port_;
|
||||
std::uint16_t remote_receive_timeout_secs_;
|
||||
std::uint16_t remote_send_timeout_secs_;
|
||||
std::string remote_token_;
|
||||
std::uint16_t retry_read_count_;
|
||||
std::uint16_t ring_buffer_file_size_;
|
||||
api_currency storage_byte_month_;
|
||||
std::uint64_t version_ = REPERTORY_CONFIG_VERSION;
|
||||
std::string cache_directory_;
|
||||
host_config hc_;
|
||||
s3_config s3_config_;
|
||||
skynet_config skynet_config_;
|
||||
std::string log_directory_;
|
||||
std::recursive_mutex read_write_mutex_;
|
||||
std::recursive_mutex remote_mount_mutex_;
|
||||
|
||||
private:
|
||||
bool load();
|
||||
|
||||
template <typename dest>
|
||||
bool get_value(const json &json_document, const std::string &name, dest &dst,
|
||||
bool &success_flag) {
|
||||
auto ret = false;
|
||||
try {
|
||||
if (json_document.find(name) != json_document.end()) {
|
||||
dst = json_document[name].get<dest>();
|
||||
ret = true;
|
||||
} else {
|
||||
success_flag = false;
|
||||
}
|
||||
} catch (const json::exception &ex) {
|
||||
event_system::instance().raise<repertory_exception>(__FUNCTION__, ex.what());
|
||||
success_flag = false;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename dest, typename source> bool set_value(dest &dst, const source &src) {
|
||||
auto ret = false;
|
||||
recur_mutex_lock l(read_write_mutex_);
|
||||
if (dst != src) {
|
||||
dst = src;
|
||||
config_changed_ = true;
|
||||
save();
|
||||
ret = true;
|
||||
|
||||
if (reinterpret_cast<void *>(&dst) == &skynet_config_.portal_list) {
|
||||
event_system::instance().raise<skynet_portal_list_changed>();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public:
|
||||
std::string get_api_auth() const { return api_auth_; }
|
||||
|
||||
std::uint16_t get_api_port() const { return api_port_; }
|
||||
|
||||
std::string get_api_user() const { return api_user_; }
|
||||
|
||||
std::string get_cache_directory() const { return cache_directory_; }
|
||||
|
||||
std::uint8_t get_chunk_downloader_timeout_secs() const {
|
||||
return std::max(min_download_timeout_secs_, download_timeout_secs_);
|
||||
}
|
||||
|
||||
std::string get_config_file_path() const;
|
||||
|
||||
std::string get_data_directory() const { return data_directory_; }
|
||||
|
||||
bool get_enable_chunk_download_timeout() const { return enable_chunk_downloader_timeout_; }
|
||||
|
||||
bool get_enable_comm_duration_events() const { return enable_comm_duration_events_; }
|
||||
|
||||
bool get_enable_drive_events() const { return enable_drive_events_; }
|
||||
|
||||
#ifdef _WIN32
|
||||
bool get_enable_mount_manager() const { return enable_mount_manager_; }
|
||||
#endif
|
||||
|
||||
bool get_enable_max_cache_size() const { return enable_max_cache_size_; }
|
||||
|
||||
bool get_enable_remote_mount() const { return enable_remote_mount_; }
|
||||
|
||||
event_level get_event_level() const { return event_level_; }
|
||||
|
||||
std::uint32_t get_eviction_delay_mins() const { return eviction_delay_mins_; }
|
||||
|
||||
bool get_eviction_uses_accessed_time() const { return eviction_uses_accessed_time_; }
|
||||
|
||||
std::uint8_t get_high_frequency_interval_secs() const {
|
||||
return std::max((std::uint8_t)1, high_freq_interval_secs_);
|
||||
}
|
||||
|
||||
host_config get_host_config() const { return hc_; }
|
||||
|
||||
bool get_is_remote_mount() const { return is_remote_mount_; }
|
||||
|
||||
json get_json() const;
|
||||
|
||||
std::string get_log_directory() const { return log_directory_; }
|
||||
|
||||
std::uint32_t get_low_frequency_interval_secs() const {
|
||||
return std::max((std::uint32_t)1, low_freq_interval_secs_);
|
||||
}
|
||||
|
||||
std::uint64_t get_max_cache_size_bytes() const;
|
||||
|
||||
std::uint8_t get_max_upload_count() const {
|
||||
return std::max(std::uint8_t(1u), max_upload_count_);
|
||||
}
|
||||
|
||||
double get_minimum_redundancy() const { return std::max(1.5, minimum_redundancy_); }
|
||||
|
||||
std::uint16_t get_online_check_retry_secs() const {
|
||||
return std::max(std::uint16_t(15), online_check_retry_secs_);
|
||||
}
|
||||
|
||||
std::uint16_t get_orphaned_file_retention_days() const {
|
||||
return std::min((std::uint16_t)31, std::max((std::uint16_t)1, orphaned_file_retention_days_));
|
||||
}
|
||||
|
||||
download_type get_preferred_download_type() const {
|
||||
return utils::download_type_from_string(preferred_download_type_, download_type::fallback);
|
||||
}
|
||||
|
||||
provider_type get_provider_type() const { return pt_; }
|
||||
|
||||
std::uint8_t get_read_ahead_count() const { return std::max((std::uint8_t)1, read_ahead_count_); }
|
||||
|
||||
std::uint8_t get_remote_client_pool_size() const {
|
||||
return std::max((std::uint8_t)5u, remote_client_pool_size_);
|
||||
}
|
||||
|
||||
std::string get_remote_host_name_or_ip() const { return remote_host_name_or_ip_; }
|
||||
|
||||
std::uint8_t get_remote_max_connections() const {
|
||||
return std::max((std::uint8_t)1, remote_max_connections_);
|
||||
}
|
||||
|
||||
std::uint16_t get_remote_port() const { return remote_port_; }
|
||||
|
||||
std::uint16_t get_remote_receive_timeout_secs() const { return remote_receive_timeout_secs_; }
|
||||
|
||||
std::uint16_t get_remote_send_timeout_secs() const { return remote_send_timeout_secs_; }
|
||||
|
||||
std::string get_remote_token() const { return remote_token_; }
|
||||
|
||||
std::uint16_t get_retry_read_count() const {
|
||||
return std::max(std::uint16_t(2), retry_read_count_);
|
||||
}
|
||||
|
||||
std::uint16_t get_ring_buffer_file_size() const {
|
||||
return std::max((std::uint16_t)64, std::min((std::uint16_t)1024, ring_buffer_file_size_));
|
||||
}
|
||||
|
||||
s3_config get_s3_config() const { return s3_config_; }
|
||||
|
||||
skynet_config get_skynet_config() const { return skynet_config_; }
|
||||
|
||||
api_currency get_storage_byte_month() const { return storage_byte_month_; }
|
||||
|
||||
std::string get_value_by_name(const std::string &name);
|
||||
|
||||
std::uint64_t get_version() const { return version_; }
|
||||
|
||||
void save();
|
||||
|
||||
void set_api_auth(const std::string &api_auth) { set_value(api_auth_, api_auth); }
|
||||
|
||||
void set_api_port(const std::uint16_t &api_port) { set_value(api_port_, api_port); }
|
||||
|
||||
void set_api_user(const std::string &api_user) { set_value(api_user_, api_user); }
|
||||
|
||||
void set_chunk_downloader_timeout_secs(const std::uint8_t &chunk_downloader_timeout_secs) {
|
||||
set_value(download_timeout_secs_, chunk_downloader_timeout_secs);
|
||||
}
|
||||
|
||||
void set_enable_chunk_downloader_timeout(const bool &enable_chunk_downloader_timeout) {
|
||||
set_value(enable_chunk_downloader_timeout_, enable_chunk_downloader_timeout);
|
||||
}
|
||||
|
||||
void set_enable_comm_duration_events(const bool &enable_comm_duration_events) {
|
||||
set_value(enable_comm_duration_events_, enable_comm_duration_events);
|
||||
}
|
||||
|
||||
void set_enable_drive_events(const bool &enable_drive_events) {
|
||||
set_value(enable_drive_events_, enable_drive_events);
|
||||
}
|
||||
|
||||
void set_enable_max_cache_size(const bool &enable_max_cache_size) {
|
||||
set_value(enable_max_cache_size_, enable_max_cache_size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void set_enable_mount_manager(const bool &enable_mount_manager) {
|
||||
set_value(enable_mount_manager_, enable_mount_manager);
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_enable_remote_mount(const bool &enable_remote_mount);
|
||||
|
||||
void set_event_level(const event_level &level) {
|
||||
if (set_value(event_level_, level)) {
|
||||
event_system::instance().raise<event_level_changed>(event_level_to_string(level));
|
||||
}
|
||||
}
|
||||
|
||||
void set_eviction_delay_mins(const std::uint32_t &eviction_delay_mins) {
|
||||
set_value(eviction_delay_mins_, eviction_delay_mins);
|
||||
}
|
||||
|
||||
void set_eviction_uses_accessed_time(const bool &eviction_uses_accessed_time) {
|
||||
set_value(eviction_uses_accessed_time_, eviction_uses_accessed_time);
|
||||
}
|
||||
|
||||
void set_high_frequency_interval_secs(const std::uint8_t &high_frequency_interval_secs) {
|
||||
set_value(high_freq_interval_secs_, high_frequency_interval_secs);
|
||||
}
|
||||
|
||||
void set_is_remote_mount(const bool &is_remote_mount);
|
||||
|
||||
void set_low_frequency_interval_secs(const std::uint32_t &low_frequency_interval_secs) {
|
||||
set_value(low_freq_interval_secs_, low_frequency_interval_secs);
|
||||
}
|
||||
|
||||
void set_max_cache_size_bytes(const std::uint64_t &max_cache_size_bytes) {
|
||||
set_value(max_cache_size_bytes_, max_cache_size_bytes);
|
||||
}
|
||||
|
||||
void set_max_upload_count(const std::uint8_t &max_upload_count) {
|
||||
set_value(max_upload_count_, max_upload_count);
|
||||
}
|
||||
|
||||
void set_minimum_redundancy(const double &minimum_redundancy) {
|
||||
set_value(minimum_redundancy_, minimum_redundancy);
|
||||
}
|
||||
|
||||
void set_online_check_retry_secs(const std::uint16_t &online_check_retry_secs) {
|
||||
set_value(online_check_retry_secs_, online_check_retry_secs);
|
||||
}
|
||||
|
||||
void set_orphaned_file_retention_days(const std::uint16_t &orphaned_file_retention_days) {
|
||||
set_value(orphaned_file_retention_days_, orphaned_file_retention_days);
|
||||
}
|
||||
|
||||
void set_preferred_download_type(const download_type &dt) {
|
||||
set_value(preferred_download_type_, utils::download_type_to_string(dt));
|
||||
}
|
||||
|
||||
void set_read_ahead_count(const std::uint8_t &read_ahead_count) {
|
||||
set_value(read_ahead_count_, read_ahead_count);
|
||||
}
|
||||
|
||||
void set_remote_client_pool_size(const std::uint8_t &remote_client_pool_size) {
|
||||
set_value(remote_client_pool_size_, remote_client_pool_size);
|
||||
}
|
||||
|
||||
void set_ring_buffer_file_size(const std::uint16_t &ring_buffer_file_size) {
|
||||
set_value(ring_buffer_file_size_, ring_buffer_file_size);
|
||||
}
|
||||
|
||||
void set_remote_host_name_or_ip(const std::string &remote_host_name_or_ip) {
|
||||
set_value(remote_host_name_or_ip_, remote_host_name_or_ip);
|
||||
}
|
||||
|
||||
void set_remote_max_connections(const std::uint8_t &remote_max_connections) {
|
||||
set_value(remote_max_connections_, remote_max_connections);
|
||||
}
|
||||
|
||||
void set_remote_port(const std::uint16_t &remote_port) { set_value(remote_port_, remote_port); }
|
||||
|
||||
void set_remote_receive_timeout_secs(const std::uint16_t &remote_receive_timeout_secs) {
|
||||
set_value(remote_receive_timeout_secs_, remote_receive_timeout_secs);
|
||||
}
|
||||
|
||||
void set_remote_send_timeout_secs(const std::uint16_t &remote_send_timeout_secs) {
|
||||
set_value(remote_send_timeout_secs_, remote_send_timeout_secs);
|
||||
}
|
||||
|
||||
void set_remote_token(const std::string &remote_token) { set_value(remote_token_, remote_token); }
|
||||
|
||||
void set_retry_read_count(const std::uint16_t &retry_read_count) {
|
||||
set_value(retry_read_count_, retry_read_count);
|
||||
}
|
||||
|
||||
void set_storage_byte_month(const api_currency &storage_byte_month);
|
||||
|
||||
std::string set_value_by_name(const std::string &name, const std::string &value);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_APP_CONFIG_HPP_
|
96
include/cli/actions.hpp
Normal file
96
include/cli/actions.hpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_ACTIONS_HPP_
|
||||
#define INCLUDE_CLI_ACTIONS_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "cli/check_version.hpp"
|
||||
#include "cli/display_config.hpp"
|
||||
#include "cli/drive_information.hpp"
|
||||
#include "cli/export.hpp"
|
||||
#include "cli/export_all.hpp"
|
||||
#include "cli/get.hpp"
|
||||
#include "cli/get_directory_items.hpp"
|
||||
#include "cli/get_pinned_files.hpp"
|
||||
#include "cli/help.hpp"
|
||||
#include "cli/import.hpp"
|
||||
#include "cli/import_json.hpp"
|
||||
#include "cli/mount.hpp"
|
||||
#include "cli/open_files.hpp"
|
||||
#include "cli/pin_file.hpp"
|
||||
#include "cli/pinned_status.hpp"
|
||||
#include "cli/set.hpp"
|
||||
#include "cli/status.hpp"
|
||||
#include "cli/test_skynet_auth.hpp"
|
||||
#include "cli/unmount.hpp"
|
||||
#include "cli/unpin_file.hpp"
|
||||
#include "cli/version.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
typedef std::function<exit_code(const int &argc, char *argv[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &unique_id,
|
||||
std::string user, std::string password)>
|
||||
action;
|
||||
|
||||
struct option_hasher {
|
||||
std::size_t operator()(const utils::cli::option &opt) const {
|
||||
return std::hash<std::string>()(opt[0u] + '|' + opt[1u]);
|
||||
}
|
||||
};
|
||||
|
||||
static const std::unordered_map<utils::cli::option, action, option_hasher> option_actions = {
|
||||
{utils::cli::options::check_version_option, cli::actions::check_version},
|
||||
{utils::cli::options::display_config_option, cli::actions::display_config},
|
||||
{utils::cli::options::drive_information_option, cli::actions::drive_information},
|
||||
{utils::cli::options::export_option, cli::actions::export_action},
|
||||
{utils::cli::options::export_all_option, cli::actions::export_all},
|
||||
{utils::cli::options::get_directory_items_option, cli::actions::get_directory_items},
|
||||
{utils::cli::options::get_option, cli::actions::get},
|
||||
{utils::cli::options::get_pinned_files_option, cli::actions::get_pinned_files},
|
||||
{utils::cli::options::import_option, cli::actions::import},
|
||||
{utils::cli::options::import_json_option, cli::actions::import_json},
|
||||
{utils::cli::options::open_files_option, cli::actions::open_files},
|
||||
{utils::cli::options::pin_file_option, cli::actions::pin_file},
|
||||
{utils::cli::options::pinned_status_option, cli::actions::pinned_status},
|
||||
{utils::cli::options::set_option, cli::actions::set},
|
||||
{utils::cli::options::status_option, cli::actions::status},
|
||||
#if defined(REPERTORY_ENABLE_SKYNET)
|
||||
{utils::cli::options::test_skynet_auth_option, cli::actions::test_skynet_auth},
|
||||
#endif
|
||||
{utils::cli::options::unmount_option, cli::actions::unmount},
|
||||
{utils::cli::options::unpin_file_option, cli::actions::unpin_file},
|
||||
};
|
||||
|
||||
static exit_code perform_action(const utils::cli::option &opt, const int &argc, char *argv[],
|
||||
const std::string &data_directory, const provider_type &pt,
|
||||
const std::string &unique_id, std::string user,
|
||||
std::string password) {
|
||||
if (utils::cli::has_option(argc, argv, opt)) {
|
||||
if (option_actions.find(opt) != option_actions.end()) {
|
||||
return option_actions.at(opt)(argc, argv, data_directory, pt, unique_id, std::move(user),
|
||||
std::move(password));
|
||||
}
|
||||
}
|
||||
|
||||
return exit_code::option_not_found;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_ACTIONS_HPP_
|
63
include/cli/check_version.hpp
Normal file
63
include/cli/check_version.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_CHECK_VERSION_HPP_
|
||||
#define INCLUDE_CLI_CHECK_VERSION_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/curl/curl_comm.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code check_version(const int &, char *[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string,
|
||||
std::string) {
|
||||
auto ret = exit_code::success;
|
||||
|
||||
if (not((pt == provider_type::remote) || (pt == provider_type::s3) ||
|
||||
(pt == provider_type::skynet))) {
|
||||
app_config config(pt, data_directory);
|
||||
curl_comm comm(config);
|
||||
json data, err;
|
||||
|
||||
if (comm.get("/daemon/version", data, err) == api_error::success) {
|
||||
const auto res = utils::compare_version_strings(data["version"].get<std::string>(),
|
||||
app_config::get_provider_minimum_version(pt));
|
||||
if (res < 0) {
|
||||
ret = exit_code::incompatible_version;
|
||||
std::cerr << "Failed!" << std::endl;
|
||||
std::cerr << " Actual: " << data["version"].get<std::string>() << std::endl;
|
||||
std::cerr << " Minimum: " << app_config::get_provider_minimum_version(pt) << std::endl;
|
||||
} else {
|
||||
std::cout << "Success!" << std::endl;
|
||||
std::cout << " Actual: " << data["version"].get<std::string>() << std::endl;
|
||||
std::cout << " Minimum: " << app_config::get_provider_minimum_version(pt) << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Failed!" << std::endl;
|
||||
std::cerr << err.dump(2) << std::endl;
|
||||
ret = exit_code::communication_error;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_CHECK_VERSION_HPP_
|
53
include/cli/display_config.hpp
Normal file
53
include/cli/display_config.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_DISPLAY_CONFIG_HPP_
|
||||
#define INCLUDE_CLI_DISPLAY_CONFIG_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code display_config(const int &, char *[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &unique_id,
|
||||
std::string user, std::string password) {
|
||||
lock_data lock(pt, unique_id);
|
||||
const auto res = lock.grab_lock(1u);
|
||||
if (res == lock_result::success) {
|
||||
app_config config(pt, data_directory);
|
||||
const auto cfg = config.get_json();
|
||||
std::cout << 0 << std::endl;
|
||||
std::cout << cfg.dump(2) << std::endl;
|
||||
} else if (res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).get_config();
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
}
|
||||
|
||||
return exit_code::success;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_DISPLAY_CONFIG_HPP_
|
53
include/cli/drive_information.hpp
Normal file
53
include/cli/drive_information.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_DRIVE_INFORMATION_HPP_
|
||||
#define INCLUDE_CLI_DRIVE_INFORMATION_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code drive_information(const int &, char *[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &unique_id,
|
||||
std::string user, std::string password) {
|
||||
auto ret = exit_code::success;
|
||||
|
||||
lock_data lock(pt, unique_id);
|
||||
const auto res = lock.grab_lock(1u);
|
||||
if (res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).get_drive_information();
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << app_config::get_provider_display_name(pt) << " is not mounted." << std::endl;
|
||||
ret = exit_code::not_mounted;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_DRIVE_INFORMATION_HPP_
|
53
include/cli/export.hpp
Normal file
53
include/cli/export.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_EXPORT_HPP_
|
||||
#define INCLUDE_CLI_EXPORT_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code export_action(const int &argc, char *argv[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string user,
|
||||
std::string password) {
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(argc, argv,
|
||||
repertory::utils::cli::options::export_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response =
|
||||
client({"localhost", password, port, user}).export_list(utils::string::split(data, ','));
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::export_failed;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_EXPORT_HPP_
|
49
include/cli/export_all.hpp
Normal file
49
include/cli/export_all.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_EXPORT_ALL_HPP_
|
||||
#define INCLUDE_CLI_EXPORT_ALL_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "types/skynet.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code export_all(const int &, char *[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string user,
|
||||
std::string password) {
|
||||
auto ret = exit_code::success;
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).export_all();
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::export_failed;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_EXPORT_ALL_HPP_
|
60
include/cli/get.hpp
Normal file
60
include/cli/get.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_GET_HPP_
|
||||
#define INCLUDE_CLI_GET_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code get(const int &argc, char *argv[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &unique_id, std::string user,
|
||||
std::string password) {
|
||||
std::string data;
|
||||
auto ret =
|
||||
utils::cli::parse_string_option(argc, argv, repertory::utils::cli::options::get_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
lock_data lock(pt, unique_id);
|
||||
const auto res = lock.grab_lock(1);
|
||||
if (res == lock_result::success) {
|
||||
app_config config(pt, data_directory);
|
||||
const auto value = config.get_value_by_name(data);
|
||||
std::cout << (value.empty() ? static_cast<int>(rpc_response_type::config_value_not_found) : 0)
|
||||
<< std::endl;
|
||||
std::cout << json({{"value", value}}).dump(2) << std::endl;
|
||||
} else if (res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response =
|
||||
client({"localhost", password, port, user}).get_config_value_by_name(data);
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_GET_HPP_
|
53
include/cli/get_directory_items.hpp
Normal file
53
include/cli/get_directory_items.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_GET_DIRECTORY_ITEMS_HPP_
|
||||
#define INCLUDE_CLI_GET_DIRECTORY_ITEMS_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "types/skynet.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code get_directory_items(const int &argc, char *argv[],
|
||||
const std::string &data_directory, const provider_type &pt,
|
||||
const std::string &, std::string user, std::string password) {
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(
|
||||
argc, argv, repertory::utils::cli::options::get_directory_items_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).get_directory_items(data);
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::export_failed;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_GETDIRECTORYITEMS_HPP_
|
48
include/cli/get_pinned_files.hpp
Normal file
48
include/cli/get_pinned_files.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_GET_PINNED_FILES_HPP_
|
||||
#define INCLUDE_CLI_GET_PINNED_FILES_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code get_pinned_files(const int &, char *[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string user,
|
||||
std::string password) {
|
||||
auto ret = exit_code::success;
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).get_pinned_files();
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::export_failed;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_GET_PINNED_FILES_HPP_
|
106
include/cli/help.hpp
Normal file
106
include/cli/help.hpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_HELP_HPP_
|
||||
#define INCLUDE_CLI_HELP_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
template <typename drive> static void help(const int &argc, char *argv[]) {
|
||||
drive::display_options(argc, argv);
|
||||
std::cout << "Repertory options:" << std::endl;
|
||||
std::cout << " -cv,--check_version Check daemon version compatibility"
|
||||
<< std::endl;
|
||||
std::cout << " -dc,--display_config Display configuration" << std::endl;
|
||||
std::cout << " -dd,--data_directory [directory] Override data directory" << std::endl;
|
||||
std::cout << " -di,--drive_information Display mounted drive information"
|
||||
<< std::endl;
|
||||
#if defined(REPERTORY_ENABLE_SKYNET)
|
||||
std::cout << " -ea,--export_all Export all Skynet skylinks" << std::endl;
|
||||
std::cout << " -ex,--export [path1,path2,...] Export one or more Skynet skylinks"
|
||||
<< std::endl;
|
||||
#endif // defined(REPERTORY_ENABLE_SKYNET)
|
||||
#if defined(REPERTORY_ENABLE_S3)
|
||||
std::cout << " -s3,--s3 Enables S3 mode" << std::endl;
|
||||
std::cout << " -na,--name Unique name for S3 instance [Required]"
|
||||
<< std::endl;
|
||||
#endif // defined(REPERTORY_ENABLE_S3)
|
||||
std::cout << " -gc,--generate_config Generate initial configuration" << std::endl;
|
||||
std::cout << " -get,--get [name] Get configuration value" << std::endl;
|
||||
std::cout << " -gdi,--get_directory_items Get directory list in json format"
|
||||
<< std::endl
|
||||
<< " [API path]" << std::endl;
|
||||
std::cout << " -gpf,--get_pinned_files Get a list of all pinned files" << std::endl;
|
||||
std::cout << " -gt,--generate_template Generate configuration template" << std::endl;
|
||||
#if defined(REPERTORY_ENABLE_SKYNET)
|
||||
std::cout << " -ij,--import_json [json_array] Import Skynet skylink(s)" << std::endl;
|
||||
std::cout << " [json_array] format:" << std::endl;
|
||||
std::cout << " [{" << std::endl;
|
||||
std::cout << R"( "directory": "/parent",)" << std::endl;
|
||||
std::cout << R"( "skylink": "AACeCiD6WQG6DzDcCdIu3cFPSxMUMoQPx46NYSyijNMKUA",)"
|
||||
<< std::endl;
|
||||
std::cout << R"( "token": "encryption password")" << std::endl;
|
||||
std::cout << " }]" << std::endl;
|
||||
std::cout << " NOTE: 'directory' and 'token' are optional" << std::endl;
|
||||
std::cout << " -im,--import [list] Import Skynet skylink(s)" << std::endl;
|
||||
std::cout << " [list] format:" << std::endl;
|
||||
std::cout << " directory=<directory>:skylink=<skylink>:token=<token>;..." << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << " NOTE: 'directory' and 'token' are optional" << std::endl;
|
||||
std::cout << " NOTE: Use '@sem@' to escape a ';'" << std::endl;
|
||||
std::cout << " Use '@comma@' to escape a ','" << std::endl;
|
||||
std::cout << " Use '@equal@' to escape an '='" << std::endl;
|
||||
std::cout << " Use '@dbl_quote@' to escape a '\"'" << std::endl;
|
||||
#endif // defined(REPERTORY_ENABLE_SKYNET)
|
||||
std::cout << " -nc Force disable console output" << std::endl;
|
||||
std::cout << " -of,--open_files List all open files and count" << std::endl;
|
||||
std::cout << " -rm,--remote_mount [host/ip:port] Enables remote mount mode" << std::endl;
|
||||
std::cout << " -pf,--pin_file [API path] Pin a file to cache to prevent eviction"
|
||||
<< std::endl;
|
||||
std::cout << " -ps,--pinned_status [API path] Return pinned status for a file" << std::endl;
|
||||
std::cout << " -pw,--password Specify API password" << std::endl;
|
||||
#if defined(REPERTORY_ENABLE_SKYNET)
|
||||
std::cout << " -sk,--skynet [EXPERIMENTAL] Enables Skynet mode"
|
||||
<< std::endl;
|
||||
#endif // defined(REPERTORY_ENABLE_SKYNET)
|
||||
#ifndef _WIN32
|
||||
#if defined(REPERTORY_ENABLE_S3)
|
||||
std::cout << " -o s3 Enables S3 mode for 'fstab' mounts"
|
||||
<< std::endl;
|
||||
#endif // defined(REPERTORY_ENABLE_S3)
|
||||
#if defined(REPERTORY_ENABLE_SKYNET)
|
||||
std::cout << " -o sk,-o skynet Enables Skynet mode for 'fstab' mounts"
|
||||
<< std::endl;
|
||||
#endif // defined(REPERTORY_ENABLE_SKYNET)
|
||||
#endif // _WIN32
|
||||
std::cout << " -set,--set [name] [value] Set configuration value" << std::endl;
|
||||
std::cout << " -status Display mount status" << std::endl;
|
||||
#if defined(REPERTORY_ENABLE_SKYNET)
|
||||
std::cout << " -tsa,--test_skynet_auth Test Skynet portal authentication"
|
||||
<< std::endl;
|
||||
std::cout << " [URL] [user] [password] [agent string] [API key]" << std::endl;
|
||||
#endif // defined(REPERTORY_ENABLE_SKYNET)
|
||||
std::cout << " -unmount,--unmount Unmount and shutdown" << std::endl;
|
||||
std::cout << " -uf,--unpin_file [API path] Unpin a file from cache to allow eviction"
|
||||
<< std::endl;
|
||||
std::cout << " -us,--user Specify API user name" << std::endl;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_HELP_HPP_
|
62
include/cli/import.hpp
Normal file
62
include/cli/import.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_IMPORT_HPP_
|
||||
#define INCLUDE_CLI_IMPORT_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "types/skynet.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code import(const int &argc, char *argv[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string user,
|
||||
std::string password) {
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(argc, argv,
|
||||
repertory::utils::cli::options::import_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
utils::string::replace(data, "@dbl_quote@", "\"");
|
||||
const auto parts = utils::string::split(data, ';');
|
||||
skylink_import_list list;
|
||||
for (const auto &part : parts) {
|
||||
list.emplace_back(
|
||||
skylink_import::from_string(utils::string::replace_copy(part, "@sem@", ";")));
|
||||
}
|
||||
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).import_skylink(list);
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::import_failed;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_IMPORT_HPP_
|
68
include/cli/import_json.hpp
Normal file
68
include/cli/import_json.hpp
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_IMPORT_JSON_HPP_
|
||||
#define INCLUDE_CLI_IMPORT_JSON_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "types/skynet.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code import_json(const int &argc, char *argv[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string user,
|
||||
std::string password) {
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(argc, argv, {"-ij", "--import_json"}, data);
|
||||
if (ret == exit_code::success) {
|
||||
utils::string::replace(data, "@dbl_quote@", "\"");
|
||||
|
||||
skylink_import_list list;
|
||||
try {
|
||||
const auto json_data = json::parse(data);
|
||||
for (const auto &j : json_data) {
|
||||
list.emplace_back(skylink_import::from_json(j));
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "Import JSON failed:" << std::endl << e.what() << std::endl;
|
||||
ret = exit_code::import_failed;
|
||||
}
|
||||
|
||||
if (not list.empty()) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).import_skylink(list);
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::import_failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_IMPORT_JSON_HPP_
|
159
include/cli/mount.hpp
Normal file
159
include/cli/mount.hpp
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_MOUNT_HPP_
|
||||
#define INCLUDE_CLI_MOUNT_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
#include "providers/provider.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
#include "utils/com_init_wrapper.hpp"
|
||||
#include "utils/file_utils.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "drives/winfsp/remotewinfsp/remote_client.hpp"
|
||||
#include "drives/winfsp/remotewinfsp/remote_winfsp_drive.hpp"
|
||||
#include "drives/winfsp/winfsp_drive.hpp"
|
||||
|
||||
typedef repertory::winfsp_drive repertory_drive;
|
||||
typedef repertory::remote_winfsp::remote_client remote_client;
|
||||
typedef repertory::remote_winfsp::remote_winfsp_drive remote_drive;
|
||||
typedef repertory::remote_winfsp::i_remote_instance remote_instance;
|
||||
#else
|
||||
#include "drives/fuse/fuse_drive.hpp"
|
||||
#include "drives/fuse/remotefuse/remote_client.hpp"
|
||||
#include "drives/fuse/remotefuse/remote_fuse_drive.hpp"
|
||||
|
||||
typedef repertory::fuse_drive repertory_drive;
|
||||
typedef repertory::remote_fuse::remote_client remote_client;
|
||||
typedef repertory::remote_fuse::remote_fuse_drive remote_drive;
|
||||
typedef repertory::remote_fuse::i_remote_instance remote_instance;
|
||||
#endif
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code mount(const int &argc, char *argv[], std::string data_directory, int &mount_result,
|
||||
provider_type pt, const std::string &remote_host,
|
||||
const std::uint16_t &remote_port, const std::string &unique_id) {
|
||||
auto ret = exit_code::success;
|
||||
|
||||
lock_data lock(pt, unique_id);
|
||||
const auto res = lock.grab_lock();
|
||||
if (res == lock_result::locked) {
|
||||
ret = exit_code::mount_active;
|
||||
std::cerr << app_config::get_provider_display_name(pt) << " mount is already active"
|
||||
<< std::endl;
|
||||
} else if (res == lock_result::success) {
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
{
|
||||
const auto generate_config =
|
||||
utils::cli::has_option(argc, argv, utils::cli::options::generate_config_option);
|
||||
if (generate_config) {
|
||||
app_config config(pt, data_directory);
|
||||
if (pt == provider_type::remote) {
|
||||
config.set_enable_remote_mount(false);
|
||||
config.set_is_remote_mount(true);
|
||||
config.set_remote_host_name_or_ip(remote_host);
|
||||
config.set_remote_port(remote_port);
|
||||
}
|
||||
std::cout << "Generated " << app_config::get_provider_display_name(pt) << " Configuration"
|
||||
<< std::endl;
|
||||
std::cout << config.get_config_file_path() << std::endl;
|
||||
ret = utils::file::is_file(config.get_config_file_path()) ? exit_code::success
|
||||
: exit_code::file_creation_failed;
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
if (utils::cli::has_option(argc, argv, utils::cli::options::hidden_option)) {
|
||||
::ShowWindow(::GetConsoleWindow(), SW_HIDE);
|
||||
}
|
||||
#endif
|
||||
const auto driveArgs = utils::cli::parse_drive_options(argc, argv, pt, data_directory);
|
||||
std::cout << "Initializing " << app_config::get_provider_display_name(pt)
|
||||
<< (unique_id.empty() ? ""
|
||||
: (pt == provider_type::s3)
|
||||
? " [" + unique_id + ']'
|
||||
: " [" + remote_host + ':' + std::to_string(remote_port) + ']')
|
||||
<< " Drive" << std::endl;
|
||||
app_config config(pt, data_directory);
|
||||
if (pt == provider_type::remote) {
|
||||
std::uint16_t port = 0u;
|
||||
if (utils::get_next_available_port(config.get_api_port(), port)) {
|
||||
config.set_remote_host_name_or_ip(remote_host);
|
||||
config.set_remote_port(remote_port);
|
||||
config.set_api_port(port);
|
||||
config.set_is_remote_mount(true);
|
||||
config.set_enable_remote_mount(false);
|
||||
config.save();
|
||||
try {
|
||||
remote_drive drive(config, lock, [&config]() -> std::unique_ptr<remote_instance> {
|
||||
return std::unique_ptr<remote_instance>(new remote_client(config));
|
||||
});
|
||||
lock.set_mount_state(true, "", -1);
|
||||
mount_result = drive.mount(driveArgs);
|
||||
ret = exit_code::mount_result;
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "FATAL: " << e.what() << std::endl;
|
||||
ret = exit_code::startup_exception;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "FATAL: Unable to get available port" << std::endl;
|
||||
ret = exit_code::startup_exception;
|
||||
}
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
if (config.get_enable_mount_manager() && not utils::is_process_elevated()) {
|
||||
com_init_wrapper cw;
|
||||
lock.set_mount_state(true, "elevating", -1);
|
||||
lock.release();
|
||||
|
||||
mount_result = utils::run_process_elevated(argc, argv);
|
||||
lock_data lockData2(pt, unique_id);
|
||||
if (lockData2.grab_lock() == lock_result::success) {
|
||||
lockData2.set_mount_state(false, "", -1);
|
||||
lockData2.release();
|
||||
}
|
||||
|
||||
return exit_code::mount_result;
|
||||
}
|
||||
#endif
|
||||
config.set_is_remote_mount(false);
|
||||
|
||||
try {
|
||||
auto provider = create_provider(pt, config);
|
||||
repertory_drive drive(config, lock, *provider);
|
||||
lock.set_mount_state(true, "", -1);
|
||||
mount_result = drive.mount(driveArgs);
|
||||
ret = exit_code::mount_result;
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "FATAL: " << e.what() << std::endl;
|
||||
ret = exit_code::startup_exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
curl_global_cleanup();
|
||||
} else {
|
||||
ret = exit_code::lock_failed;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_MOUNT_HPP_
|
52
include/cli/open_files.hpp
Normal file
52
include/cli/open_files.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_OPEN_FILES_HPP_
|
||||
#define INCLUDE_CLI_OPEN_FILES_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code open_files(const int &, char *[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &unique_id, std::string user,
|
||||
std::string password) {
|
||||
auto ret = exit_code::success;
|
||||
lock_data lock(pt, unique_id);
|
||||
const auto res = lock.grab_lock(1u);
|
||||
if (res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).get_open_files();
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << app_config::get_provider_display_name(pt) << " is not mounted." << std::endl;
|
||||
ret = exit_code::not_mounted;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_OPEN_FILES_HPP_
|
53
include/cli/pin_file.hpp
Normal file
53
include/cli/pin_file.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_PIN_FILE_HPP_
|
||||
#define INCLUDE_CLI_PIN_FILE_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "types/skynet.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code pin_file(const int &argc, char *argv[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string user,
|
||||
std::string password) {
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(argc, argv,
|
||||
repertory::utils::cli::options::pin_file_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).pin_file(data);
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::pin_failed;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_PIN_FILE_HPP_
|
53
include/cli/pinned_status.hpp
Normal file
53
include/cli/pinned_status.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_PINNED_STATUS_HPP_
|
||||
#define INCLUDE_CLI_PINNED_STATUS_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "types/skynet.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code pinned_status(const int &argc, char *argv[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string user,
|
||||
std::string password) {
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(
|
||||
argc, argv, repertory::utils::cli::options::pinned_status_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).pinned_status(data);
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::export_failed;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_PINNED_STATUS_HPP_
|
72
include/cli/set.hpp
Normal file
72
include/cli/set.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_SET_HPP_
|
||||
#define INCLUDE_CLI_SET_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code set(const int &argc, char *argv[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &unique_id, std::string user,
|
||||
std::string password) {
|
||||
auto ret = exit_code::success;
|
||||
auto data = utils::cli::parse_option(argc, argv, "-set", 2u);
|
||||
if (data.empty()) {
|
||||
data = utils::cli::parse_option(argc, argv, "--set", 2u);
|
||||
if (data.empty()) {
|
||||
ret = exit_code::invalid_syntax;
|
||||
std::cerr << "Invalid syntax for '-set'" << std::endl;
|
||||
}
|
||||
}
|
||||
if (ret == exit_code::success) {
|
||||
lock_data lock(pt, unique_id);
|
||||
const auto res = lock.grab_lock(1u);
|
||||
if (res == lock_result::success) {
|
||||
app_config config(pt, data_directory);
|
||||
const auto value = config.set_value_by_name(data[0u], data[1u]);
|
||||
const auto notFound = value.empty() && not data[1u].empty();
|
||||
ret = notFound ? exit_code::set_option_not_found : exit_code::success;
|
||||
std::cout << (notFound ? static_cast<int>(rpc_response_type::config_value_not_found) : 0)
|
||||
<< std::endl;
|
||||
std::cout << json({{"value", value}}).dump(2) << std::endl;
|
||||
} else if (res == lock_result::locked) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response =
|
||||
client({"localhost", password, port, user}).set_config_value_by_name(data[0u], data[1u]);
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
ret = response.response_type == rpc_response_type::config_value_not_found
|
||||
? exit_code::set_option_not_found
|
||||
: response.response_type == rpc_response_type::success ? exit_code::success
|
||||
: exit_code::communication_error;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_SET_HPP_
|
44
include/cli/status.hpp
Normal file
44
include/cli/status.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_STATUS_HPP_
|
||||
#define INCLUDE_CLI_STATUS_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code status(const int &, char *[], const std::string &, const provider_type &pt,
|
||||
const std::string &unique_id, std::string, std::string) {
|
||||
auto ret = exit_code::success;
|
||||
lock_data lock(pt, unique_id);
|
||||
lock.grab_lock(10u);
|
||||
json mount_state;
|
||||
if (lock.get_mount_state(mount_state)) {
|
||||
std::cout << mount_state.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cout << "{}" << std::endl;
|
||||
ret = exit_code::failed_to_get_mount_state;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_STATUS_HPP_
|
91
include/cli/test_skynet_auth.hpp
Normal file
91
include/cli/test_skynet_auth.hpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_TEST_SKYNET_AUTH_HPP_
|
||||
#define INCLUDE_CLI_TEST_SKYNET_AUTH_HPP_
|
||||
#ifdef REPERTORY_ENABLE_SKYNET
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/curl/curl_comm.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "events/consumers/console_consumer.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
#include "utils/file_utils.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code test_skynet_auth(const int &argc, char *argv[], const std::string &,
|
||||
const provider_type &, const std::string &, std::string,
|
||||
std::string) {
|
||||
auto ret = exit_code::success;
|
||||
auto data = utils::cli::parse_option(argc, argv, "-tsa", 5u);
|
||||
if (data.empty()) {
|
||||
data = utils::cli::parse_option(argc, argv, "--test_skynet_auth", 5u);
|
||||
if (data.empty()) {
|
||||
ret = exit_code::invalid_syntax;
|
||||
std::cerr << "Invalid syntax for '-tsa'" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
const auto uuid = utils::create_uuid_string();
|
||||
const auto config_directory = utils::path::absolute(utils::path::combine("./", {uuid}));
|
||||
if (ret == exit_code::success) {
|
||||
utils::file::change_to_process_directory();
|
||||
{
|
||||
console_consumer c;
|
||||
event_system::instance().start();
|
||||
app_config config(provider_type::skynet, config_directory);
|
||||
|
||||
host_config hc{};
|
||||
hc.auth_url = data[0];
|
||||
hc.auth_user = data[1];
|
||||
hc.auth_password = data[2];
|
||||
hc.agent_string = data[3];
|
||||
hc.api_password = data[4];
|
||||
|
||||
curl_comm comm(config);
|
||||
std::string session;
|
||||
CURL *curl_handle = nullptr;
|
||||
ret = (comm.create_auth_session(curl_handle, config, hc, session))
|
||||
? exit_code::success
|
||||
: exit_code::communication_error;
|
||||
if (ret == exit_code::success) {
|
||||
curl_easy_cleanup(curl_handle);
|
||||
comm.release_auth_session(config, hc, session);
|
||||
}
|
||||
|
||||
event_system::instance().stop();
|
||||
}
|
||||
|
||||
if (ret == exit_code::success) {
|
||||
std::cout << std::endl << "Authentication Succeeded!" << std::endl;
|
||||
} else {
|
||||
std::cerr << std::endl << "Authentication Failed!" << std::endl;
|
||||
}
|
||||
}
|
||||
utils::file::delete_directory_recursively(config_directory);
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // REPERTORY_ENABLE_SKYNET
|
||||
#endif // INCLUDE_CLI_TEST_SKYNET_AUTH_HPP_
|
49
include/cli/unmount.hpp
Normal file
49
include/cli/unmount.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_UNMOUNT_HPP_
|
||||
#define INCLUDE_CLI_UNMOUNT_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code unmount(const int &, char *[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string user,
|
||||
std::string password) {
|
||||
auto ret = exit_code::success;
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).unmount();
|
||||
std::cout << static_cast<int>(response.response_type) << std::endl;
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::communication_error;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_UNMOUNT_HPP_
|
53
include/cli/unpin_file.hpp
Normal file
53
include/cli/unpin_file.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_UNPIN_FILE_HPP_
|
||||
#define INCLUDE_CLI_UNPIN_FILE_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "rpc/client/client.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "types/skynet.hpp"
|
||||
#include "utils/cli_utils.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
static exit_code unpin_file(const int &argc, char *argv[], const std::string &data_directory,
|
||||
const provider_type &pt, const std::string &, std::string user,
|
||||
std::string password) {
|
||||
std::string data;
|
||||
auto ret = utils::cli::parse_string_option(
|
||||
argc, argv, repertory::utils::cli::options::unpin_file_option, data);
|
||||
if (ret == exit_code::success) {
|
||||
auto port = app_config::default_api_port(pt);
|
||||
utils::cli::get_api_authentication_data(user, password, port, pt, data_directory);
|
||||
const auto response = client({"localhost", password, port, user}).unpin_file(data);
|
||||
if (response.response_type == rpc_response_type::success) {
|
||||
std::cout << response.data.dump(2) << std::endl;
|
||||
} else {
|
||||
std::cerr << response.data.dump(2) << std::endl;
|
||||
ret = exit_code::unpin_failed;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_UNPIN_FILE_HPP_
|
32
include/cli/version.hpp
Normal file
32
include/cli/version.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_VERSION_HPP_
|
||||
#define INCLUDE_CLI_VERSION_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
template <typename drive> static void version(const int &argc, char *argv[]) {
|
||||
std::cout << "Repertory core version: " << get_repertory_version() << std::endl;
|
||||
std::cout << "Repertory Git revision: " << get_repertory_git_revision() << std::endl;
|
||||
drive::display_version_information(argc, argv);
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // INCLUDE_CLI_VERSION_HPP_
|
124
include/comm/aws_s3/aws_s3_comm.hpp
Normal file
124
include/comm/aws_s3/aws_s3_comm.hpp
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_AWS_S3_AWS_S3_COMM_HPP_
|
||||
#define INCLUDE_COMM_AWS_S3_AWS_S3_COMM_HPP_
|
||||
#if defined(REPERTORY_ENABLE_S3)
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/i_s3_comm.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class aws_s3_comm final : public virtual i_s3_comm {
|
||||
public:
|
||||
explicit aws_s3_comm(const app_config &config);
|
||||
|
||||
~aws_s3_comm() override;
|
||||
|
||||
private:
|
||||
struct cache_entry final {
|
||||
std::chrono::system_clock::time_point expiration;
|
||||
directory_item_list items;
|
||||
|
||||
void reset_timeout(std::chrono::seconds timeout) {
|
||||
timeout = std::max(std::chrono::seconds(5u), timeout);
|
||||
expiration = std::chrono::system_clock::now() + timeout;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
const app_config &config_;
|
||||
s3_config s3_config_;
|
||||
Aws::SDKOptions sdk_options_;
|
||||
std::unique_ptr<Aws::S3::S3Client> s3_client_;
|
||||
mutable std::recursive_mutex cached_directories_mutex_;
|
||||
mutable std::unordered_map<std::string, cache_entry> cached_directories_;
|
||||
|
||||
private:
|
||||
void clear_expired_directories();
|
||||
|
||||
bool get_cached_directory_item_count(const std::string &api_path, std::size_t &count) const;
|
||||
|
||||
bool get_cached_directory_items(const std::string &api_path,
|
||||
const meta_provider_callback &meta_provider,
|
||||
directory_item_list &list) const;
|
||||
|
||||
bool get_cached_file_exists(const std::string &api_path, bool &exists) const;
|
||||
|
||||
api_error grab_directory_items(const std::string &api_path,
|
||||
const meta_provider_callback &meta_provider,
|
||||
directory_item_list &list) const;
|
||||
|
||||
api_error get_file_list(const std::string &bucket_name,
|
||||
const get_api_file_token_callback &get_api_file_token,
|
||||
const get_name_callback &get_name, api_file_list &list) const;
|
||||
|
||||
void remove_cached_directory(const std::string &api_path);
|
||||
|
||||
void set_cached_directory_items(const std::string &api_path, directory_item_list list) const;
|
||||
|
||||
public:
|
||||
api_error create_bucket(const std::string &api_path) override;
|
||||
|
||||
bool exists(const std::string &api_path, const get_key_callback &get_key) const override;
|
||||
|
||||
void get_bucket_name_and_object_name(const std::string &api_path, const get_key_callback &getKey,
|
||||
std::string &bucketName,
|
||||
std::string &objectName) const override;
|
||||
|
||||
std::size_t get_directory_item_count(const std::string &api_path,
|
||||
const meta_provider_callback &meta_provider) const override;
|
||||
|
||||
api_error get_directory_items(const std::string &api_path,
|
||||
const meta_provider_callback &meta_provider,
|
||||
directory_item_list &list) const override;
|
||||
|
||||
api_error get_file(const std::string &api_path, const get_key_callback &get_key,
|
||||
const get_name_callback &get_name, const get_token_callback &get_token,
|
||||
api_file &file) const override;
|
||||
|
||||
api_error get_file_list(const get_api_file_token_callback &get_api_file_token,
|
||||
const get_name_callback &get_name, api_file_list &list) const override;
|
||||
|
||||
s3_config get_s3_config() override { return s3_config_; }
|
||||
|
||||
s3_config get_s3_config() const override { return s3_config_; }
|
||||
|
||||
bool is_online() const override { return s3_client_->ListBuckets().IsSuccess(); }
|
||||
|
||||
api_error read_file_bytes(const std::string &api_path, const std::size_t &size,
|
||||
const std::uint64_t &offset, std::vector<char> &data,
|
||||
const get_key_callback &get_key, const get_size_callback &get_size,
|
||||
const get_token_callback &get_token,
|
||||
const bool &stop_requested) const override;
|
||||
|
||||
api_error remove_bucket(const std::string &api_path) override;
|
||||
|
||||
api_error remove_file(const std::string &api_path, const get_key_callback &get_key) override;
|
||||
|
||||
api_error rename_file(const std::string &api_path, const std::string &new_api_path) override;
|
||||
|
||||
api_error upload_file(const std::string &api_path, const std::string &source_path,
|
||||
const std::string &encryption_token, const get_key_callback &get_key,
|
||||
const set_key_callback &set_key, const bool &stop_requested) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_ENABLE_S3
|
||||
#endif // INCLUDE_COMM_AWS_S3_AWS_S3_COMM_HPP_
|
270
include/comm/curl/curl_comm.hpp
Normal file
270
include/comm/curl/curl_comm.hpp
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_CURL_CURL_COMM_HPP_
|
||||
#define INCLUDE_COMM_CURL_CURL_COMM_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/curl/multi_request.hpp"
|
||||
#include "comm/curl/session_manager.hpp"
|
||||
#include "comm/i_comm.hpp"
|
||||
#include "app_config.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class curl_resolver;
|
||||
namespace utils::encryption {
|
||||
class encrypting_reader;
|
||||
}
|
||||
struct curl_setup;
|
||||
struct raw_write_data;
|
||||
|
||||
class curl_comm : public virtual i_comm {
|
||||
public:
|
||||
typedef size_t (*curl_read_callback)(char *, size_t, size_t, void *);
|
||||
typedef size_t (*curl_write_callback)(char *, size_t, size_t, void *);
|
||||
|
||||
static curl_read_callback read_data_callback_;
|
||||
static curl_write_callback write_data_callback_;
|
||||
static curl_write_callback write_header_callback_;
|
||||
static curl_write_callback write_null_callback_;
|
||||
static curl_write_callback write_string_callback_;
|
||||
|
||||
public:
|
||||
explicit curl_comm(const app_config &config) : config_(config) {}
|
||||
|
||||
~curl_comm() override = default;
|
||||
|
||||
private:
|
||||
const app_config &config_;
|
||||
session_manager session_manager_;
|
||||
|
||||
public:
|
||||
static std::string construct_url(CURL *curl_handle, const std::string &relative_path,
|
||||
const host_config &hc);
|
||||
|
||||
static bool create_auth_session(CURL *&curl_handle, const app_config &config, host_config hc,
|
||||
std::string &session);
|
||||
|
||||
static std::string http_range_to_string(const http_range &range);
|
||||
|
||||
static void release_auth_session(const app_config &config, host_config hc,
|
||||
const std::string &session);
|
||||
|
||||
static void update_auth_session(CURL *curl_handle, const app_config &config,
|
||||
const std::string &session);
|
||||
|
||||
private:
|
||||
CURL *common_curl_setup(const std::string &path, curl_setup &setup, std::string &url,
|
||||
std::string &fields);
|
||||
|
||||
CURL *common_curl_setup(CURL *curl_handle, const std::string &path, curl_setup &setup,
|
||||
std::string &url, std::string &fields);
|
||||
|
||||
template <typename begin, typename end>
|
||||
api_error execute_binary_operation(CURL *curl_handle, const std::string &url,
|
||||
std::vector<char> &data, json &error,
|
||||
const bool &stop_requested,
|
||||
const CURLcode &default_code = CURLE_OK) {
|
||||
auto curl_code = default_code;
|
||||
long http_code = 400;
|
||||
execute_operation<begin>(curl_handle, url, curl_code, http_code, stop_requested);
|
||||
|
||||
const auto ret = process_binary_response(url, curl_code, http_code, data, error);
|
||||
if (config_.get_event_level() >= end::level) {
|
||||
event_system::instance().raise<end>(url, curl_code, http_code,
|
||||
((ret == api_error::success) ? "" : error.dump(2)));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename begin, typename end>
|
||||
api_error execute_json_operation(CURL *curl_handle, const std::string &url,
|
||||
const std::string &result, json &data, json &error,
|
||||
const bool &stop_requested,
|
||||
const CURLcode &default_code = CURLE_OK) {
|
||||
auto curl_code = default_code;
|
||||
long http_code = 400;
|
||||
execute_operation<begin>(curl_handle, url, curl_code, http_code, stop_requested);
|
||||
|
||||
const auto ret = process_json_response(url, curl_code, http_code, result, data, error);
|
||||
if (config_.get_event_level() >= end::level) {
|
||||
event_system::instance().raise<end>(url, curl_code, http_code,
|
||||
((ret == api_error::success) ? "" : error.dump(2)));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename begin>
|
||||
void execute_operation(CURL *curl_handle, const std::string &url, CURLcode &curl_code,
|
||||
long &http_code, const bool &stop_requested) {
|
||||
if (config_.get_event_level() >= begin::level) {
|
||||
event_system::instance().raise<begin>(url);
|
||||
}
|
||||
|
||||
if (curl_code == CURLE_OK) {
|
||||
multi_request request(curl_handle, stop_requested);
|
||||
request.get_result(curl_code, http_code);
|
||||
}
|
||||
}
|
||||
|
||||
api_error get_or_post(const host_config &hc, const bool &post, const std::string &path,
|
||||
const http_parameters ¶meters, json &data, json &error,
|
||||
http_headers *headers = nullptr,
|
||||
std::function<void(CURL *curl_handle)> cb = nullptr);
|
||||
|
||||
api_error get_range(const host_config &hc, const std::string &path,
|
||||
const std::uint64_t &data_size, const http_parameters ¶meters,
|
||||
const std::string &encryption_token, std::vector<char> &data,
|
||||
const http_ranges &ranges, json &error, http_headers *headers,
|
||||
const bool &stop_requested);
|
||||
|
||||
api_error get_range_unencrypted(const host_config &hc, const std::string &path,
|
||||
const http_parameters ¶meters, std::vector<char> &data,
|
||||
const http_ranges &ranges, json &error, http_headers *headers,
|
||||
const bool &stop_requested);
|
||||
|
||||
api_error process_binary_response(const std::string &url, const CURLcode &res,
|
||||
const long &http_code, std::vector<char> data, json &error);
|
||||
|
||||
api_error process_json_response(const std::string &url, const CURLcode &res,
|
||||
const long &http_code, const std::string &result, json &data,
|
||||
json &error);
|
||||
|
||||
api_error process_response(const std::string &url, const CURLcode &res, const long &http_code,
|
||||
const std::size_t &data_size,
|
||||
const std::function<std::string()> &to_string_converter,
|
||||
const std::function<void()> &success_handler, json &error) const;
|
||||
|
||||
static std::string url_encode(CURL *curl_handle, const std::string &data,
|
||||
const bool &allow_slash = false);
|
||||
|
||||
public:
|
||||
api_error get(const std::string &path, json &data, json &error) override {
|
||||
return get_or_post(config_.get_host_config(), false, path, {}, data, error);
|
||||
}
|
||||
|
||||
api_error get(const host_config &hc, const std::string &path, json &data, json &error) override {
|
||||
return get_or_post(hc, false, path, {}, data, error);
|
||||
}
|
||||
|
||||
api_error get(const std::string &path, const http_parameters ¶meters, json &data,
|
||||
json &error) override {
|
||||
return get_or_post(config_.get_host_config(), false, path, parameters, data, error);
|
||||
}
|
||||
|
||||
api_error get(const host_config &hc, const std::string &path, const http_parameters ¶meters,
|
||||
json &data, json &error) override {
|
||||
return get_or_post(hc, false, path, parameters, data, error);
|
||||
}
|
||||
|
||||
api_error get_range(const std::string &path, const std::uint64_t &data_size,
|
||||
const http_parameters ¶meters, const std::string &encryption_token,
|
||||
std::vector<char> &data, const http_ranges &ranges, json &error,
|
||||
const bool &stop_requested) override {
|
||||
return get_range(config_.get_host_config(), path, data_size, parameters, encryption_token, data,
|
||||
ranges, error, nullptr, stop_requested);
|
||||
}
|
||||
|
||||
api_error get_range(const host_config &hc, const std::string &path,
|
||||
const std::uint64_t &data_size, const http_parameters ¶meters,
|
||||
const std::string &encryption_token, std::vector<char> &data,
|
||||
const http_ranges &ranges, json &error, const bool &stop_requested) override {
|
||||
return get_range(hc, path, data_size, parameters, encryption_token, data, ranges, error,
|
||||
nullptr, stop_requested);
|
||||
}
|
||||
|
||||
api_error get_range_and_headers(const std::string &path, const std::uint64_t &dataSize,
|
||||
const http_parameters ¶meters,
|
||||
const std::string &encryption_token, std::vector<char> &data,
|
||||
const http_ranges &ranges, json &error, http_headers &headers,
|
||||
const bool &stop_requested) override {
|
||||
return get_range(config_.get_host_config(), path, dataSize, parameters, encryption_token, data,
|
||||
ranges, error, &headers, stop_requested);
|
||||
}
|
||||
|
||||
api_error get_range_and_headers(const host_config &hc, const std::string &path,
|
||||
const std::uint64_t &dataSize, const http_parameters ¶meters,
|
||||
const std::string &encryption_token, std::vector<char> &data,
|
||||
const http_ranges &ranges, json &error, http_headers &headers,
|
||||
const bool &stop_requested) override {
|
||||
return get_range(hc, path, dataSize, parameters, encryption_token, data, ranges, error,
|
||||
&headers, stop_requested);
|
||||
}
|
||||
|
||||
api_error get_raw(const std::string &path, const http_parameters ¶meters,
|
||||
std::vector<char> &data, json &error, const bool &stop_requested) override {
|
||||
return get_raw(config_.get_host_config(), path, parameters, data, error, stop_requested);
|
||||
}
|
||||
|
||||
api_error get_raw(const host_config &hc, const std::string &path,
|
||||
const http_parameters ¶meters, std::vector<char> &data, json &error,
|
||||
const bool &stop_requested) override;
|
||||
|
||||
api_error post(const std::string &path, json &data, json &error) override {
|
||||
return get_or_post(config_.get_host_config(), true, path, {}, data, error);
|
||||
}
|
||||
|
||||
api_error post(const host_config &hc, const std::string &path, json &data, json &error) override {
|
||||
return get_or_post(hc, true, path, {}, data, error);
|
||||
}
|
||||
|
||||
api_error post(const std::string &path, const http_parameters ¶meters, json &data,
|
||||
json &error) override {
|
||||
return get_or_post(config_.get_host_config(), true, path, parameters, data, error);
|
||||
}
|
||||
|
||||
api_error post(const host_config &hc, const std::string &path, const http_parameters ¶meters,
|
||||
json &data, json &error) override {
|
||||
return get_or_post(hc, true, path, parameters, data, error);
|
||||
}
|
||||
|
||||
api_error post_file(const std::string &path, const std::string &source_path,
|
||||
const http_parameters ¶meters, json &data, json &error,
|
||||
const bool &stop_requested) override {
|
||||
return post_file(config_.get_host_config(), path, source_path, parameters, data, error,
|
||||
stop_requested);
|
||||
}
|
||||
|
||||
api_error post_file(const host_config &hc, const std::string &path,
|
||||
const std::string &source_path, const http_parameters ¶meters, json &data,
|
||||
json &error, const bool &stop_requested) override;
|
||||
|
||||
api_error post_multipart_file(const std::string &path, const std::string &file_name,
|
||||
const std::string &source_path, const std::string &encryption_token,
|
||||
json &data, json &error, const bool &stop_requested) override {
|
||||
return post_multipart_file(config_.get_host_config(), path, file_name, source_path,
|
||||
encryption_token, data, error, stop_requested);
|
||||
}
|
||||
|
||||
api_error post_multipart_file(const host_config &hc, const std::string &path,
|
||||
const std::string &file_name, const std::string &source_path,
|
||||
const std::string &encryption_token, json &data, json &error,
|
||||
const bool &stop_requested) override;
|
||||
|
||||
bool tus_upload(host_config hc, const std::string &source_path, const std::string &file_name,
|
||||
std::uint64_t file_size, const std::string &location, std::string &skylink,
|
||||
const bool &stop_requested, utils::encryption::encrypting_reader *reader);
|
||||
|
||||
bool tus_upload_create(host_config hc, const std::string &file_name,
|
||||
const std::uint64_t &file_size, std::string &location);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_COMM_CURL_CURL_COMM_HPP_
|
45
include/comm/curl/curl_resolver.hpp
Normal file
45
include/comm/curl/curl_resolver.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_CURL_CURL_RESOLVER_HPP_
|
||||
#define INCLUDE_COMM_CURL_CURL_RESOLVER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class curl_resolver final {
|
||||
public:
|
||||
curl_resolver() = delete;
|
||||
curl_resolver(const curl_resolver &) noexcept = delete;
|
||||
curl_resolver(curl_resolver &&) noexcept = delete;
|
||||
curl_resolver &operator=(const curl_resolver &) noexcept = delete;
|
||||
curl_resolver &operator=(curl_resolver &&) noexcept = delete;
|
||||
|
||||
public:
|
||||
curl_resolver(CURL *handle, std::vector<std::string> items, const bool &ignore_root = false);
|
||||
|
||||
~curl_resolver();
|
||||
|
||||
private:
|
||||
std::vector<std::string> items_;
|
||||
|
||||
struct curl_slist *host_list_ = nullptr;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_COMM_CURL_CURL_RESOLVER_HPP_
|
41
include/comm/curl/multi_request.hpp
Normal file
41
include/comm/curl/multi_request.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_CURL_MULTI_REQUEST_HPP_
|
||||
#define INCLUDE_COMM_CURL_MULTI_REQUEST_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class multi_request final {
|
||||
public:
|
||||
multi_request(CURL *curl_handle, const bool &stop_requested);
|
||||
|
||||
~multi_request();
|
||||
|
||||
private:
|
||||
CURL *curl_handle_;
|
||||
const bool &stop_requested_;
|
||||
CURLM *multi_handle_;
|
||||
|
||||
public:
|
||||
void get_result(CURLcode &curl_code, long &http_code);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_COMM_CURL_MULTI_REQUEST_HPP_
|
43
include/comm/curl/session_manager.hpp
Normal file
43
include/comm/curl/session_manager.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_CURL_SESSION_MANAGER_HPP_
|
||||
#define INCLUDE_COMM_CURL_SESSION_MANAGER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class session_manager final {
|
||||
private:
|
||||
std::string session_;
|
||||
std::uint64_t session_count_ = 0u;
|
||||
std::mutex session_mutex_;
|
||||
|
||||
public:
|
||||
bool create_auth_session(CURL *&curl_handle, const app_config &config, host_config hc,
|
||||
std::string &session);
|
||||
|
||||
void release_auth_session(const app_config &config, host_config hc, const std::string &session);
|
||||
|
||||
void update_auth_session(CURL *curl_handle, const app_config &config, const host_config &hc);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_COMM_CURL_SESSION_MANAGER_HPP_
|
107
include/comm/i_comm.hpp
Normal file
107
include/comm/i_comm.hpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_I_COMM_HPP_
|
||||
#define INCLUDE_COMM_I_COMM_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_comm {
|
||||
INTERFACE_SETUP(i_comm);
|
||||
|
||||
public:
|
||||
virtual api_error get(const std::string &path, json &data, json &error) = 0;
|
||||
|
||||
virtual api_error get(const host_config &hc, const std::string &path, json &data,
|
||||
json &error) = 0;
|
||||
|
||||
virtual api_error get(const std::string &path, const http_parameters ¶meters, json &data,
|
||||
json &error) = 0;
|
||||
|
||||
virtual api_error get(const host_config &hc, const std::string &path,
|
||||
const http_parameters ¶meters, json &data, json &error) = 0;
|
||||
|
||||
virtual api_error get_range(const std::string &path, const std::uint64_t &data_size,
|
||||
const http_parameters ¶meters,
|
||||
const std::string &encryption_token, std::vector<char> &data,
|
||||
const http_ranges &ranges, json &error,
|
||||
const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error get_range(const host_config &hc, const std::string &path,
|
||||
const std::uint64_t &data_size, const http_parameters ¶meters,
|
||||
const std::string &encryption_token, std::vector<char> &data,
|
||||
const http_ranges &ranges, json &error,
|
||||
const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error get_range_and_headers(const std::string &path, const std::uint64_t &data_size,
|
||||
const http_parameters ¶meters,
|
||||
const std::string &encryption_token,
|
||||
std::vector<char> &data, const http_ranges &ranges,
|
||||
json &error, http_headers &headers,
|
||||
const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error get_range_and_headers(const host_config &hc, const std::string &path,
|
||||
const std::uint64_t &data_size,
|
||||
const http_parameters ¶meters,
|
||||
const std::string &encryption_token,
|
||||
std::vector<char> &data, const http_ranges &ranges,
|
||||
json &error, http_headers &headers,
|
||||
const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error get_raw(const std::string &path, const http_parameters ¶meters,
|
||||
std::vector<char> &data, json &error, const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error get_raw(const host_config &hc, const std::string &path,
|
||||
const http_parameters ¶meters, std::vector<char> &data, json &error,
|
||||
const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error post(const std::string &path, json &data, json &error) = 0;
|
||||
|
||||
virtual api_error post(const host_config &hc, const std::string &path, json &data,
|
||||
json &error) = 0;
|
||||
|
||||
virtual api_error post(const std::string &path, const http_parameters ¶meters, json &data,
|
||||
json &error) = 0;
|
||||
|
||||
virtual api_error post(const host_config &hc, const std::string &path,
|
||||
const http_parameters ¶meters, json &data, json &error) = 0;
|
||||
|
||||
virtual api_error post_file(const std::string &path, const std::string &sourcePath,
|
||||
const http_parameters ¶meters, json &data, json &error,
|
||||
const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error post_file(const host_config &hc, const std::string &path,
|
||||
const std::string &sourcePath, const http_parameters ¶meters,
|
||||
json &data, json &error, const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error post_multipart_file(const std::string &path, const std::string &file_name,
|
||||
const std::string &source_path,
|
||||
const std::string &encryption_token, json &data,
|
||||
json &error, const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error post_multipart_file(const host_config &hc, const std::string &path,
|
||||
const std::string &file_name,
|
||||
const std::string &source_path,
|
||||
const std::string &encryption_token, json &data,
|
||||
json &error, const bool &stop_requested) = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_COMM_I_COMM_HPP_
|
92
include/comm/i_s3_comm.hpp
Normal file
92
include/comm/i_s3_comm.hpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_I_S3_COMM_HPP_
|
||||
#define INCLUDE_COMM_I_S3_COMM_HPP_
|
||||
#if defined(REPERTORY_ENABLE_S3)
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
class i_s3_comm {
|
||||
INTERFACE_SETUP(i_s3_comm);
|
||||
|
||||
public:
|
||||
typedef std::function<std::string(const std::string &api_path)> get_api_file_token_callback;
|
||||
typedef std::function<std::string()> get_key_callback;
|
||||
typedef std::function<std::string(const std::string &key, const std::string &object_name)>
|
||||
get_name_callback;
|
||||
typedef std::function<std::uint64_t()> get_size_callback;
|
||||
typedef std::function<std::string()> get_token_callback;
|
||||
typedef std::function<api_error(const std::string &key)> set_key_callback;
|
||||
|
||||
public:
|
||||
virtual api_error create_bucket(const std::string &api_path) = 0;
|
||||
|
||||
virtual bool exists(const std::string &api_path, const get_key_callback &get_key) const = 0;
|
||||
|
||||
virtual void get_bucket_name_and_object_name(const std::string &api_path,
|
||||
const get_key_callback &get_key,
|
||||
std::string &bucket_name,
|
||||
std::string &object_name) const = 0;
|
||||
|
||||
virtual std::size_t
|
||||
get_directory_item_count(const std::string &api_path,
|
||||
const meta_provider_callback &meta_provider) const = 0;
|
||||
|
||||
virtual api_error get_directory_items(const std::string &api_path,
|
||||
const meta_provider_callback &meta_provider,
|
||||
directory_item_list &list) const = 0;
|
||||
|
||||
virtual s3_config get_s3_config() = 0;
|
||||
|
||||
virtual s3_config get_s3_config() const = 0;
|
||||
|
||||
virtual api_error get_file(const std::string &api_path, const get_key_callback &get_key,
|
||||
const get_name_callback &get_name, const get_token_callback &get_token,
|
||||
api_file &file) const = 0;
|
||||
|
||||
virtual api_error get_file_list(const get_api_file_token_callback &get_api_file_token,
|
||||
const get_name_callback &get_name, api_file_list &list) const = 0;
|
||||
|
||||
virtual bool is_online() const = 0;
|
||||
|
||||
virtual api_error read_file_bytes(const std::string &api_path, const std::size_t &size,
|
||||
const std::uint64_t &offset, std::vector<char> &data,
|
||||
const get_key_callback &get_key,
|
||||
const get_size_callback &get_size,
|
||||
const get_token_callback &get_token,
|
||||
const bool &stop_requested) const = 0;
|
||||
|
||||
virtual api_error remove_file(const std::string &api_path, const get_key_callback &get_key) = 0;
|
||||
|
||||
virtual api_error remove_bucket(const std::string &api_path) = 0;
|
||||
|
||||
virtual api_error rename_file(const std::string &api_path, const std::string &new_api_path) = 0;
|
||||
|
||||
virtual api_error upload_file(const std::string &api_path, const std::string &source_path,
|
||||
const std::string &encryption_token,
|
||||
const get_key_callback &get_key, const set_key_callback &set_key,
|
||||
const bool &stop_requested) = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_ENABLE_S3
|
||||
#endif // INCLUDE_COMM_I_S3_COMM_HPP_
|
89
include/comm/packet/client_pool.hpp
Normal file
89
include/comm/packet/client_pool.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_PACKET_CLIENT_POOL_HPP_
|
||||
#define INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/packet/packet.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class client_pool final {
|
||||
public:
|
||||
typedef std::function<packet::error_type()> worker_callback;
|
||||
typedef std::function<void(const packet::error_type &result)> worker_complete_callback;
|
||||
|
||||
private:
|
||||
class pool final {
|
||||
private:
|
||||
struct work_item final {
|
||||
work_item(const worker_callback &worker, const worker_complete_callback &worker_complete)
|
||||
: work(worker), work_complete(worker_complete) {}
|
||||
|
||||
worker_callback work;
|
||||
worker_complete_callback work_complete;
|
||||
};
|
||||
|
||||
struct work_queue final {
|
||||
std::mutex mutex;
|
||||
std::condition_variable notify;
|
||||
std::deque<std::shared_ptr<work_item>> queue;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit pool(const std::uint8_t &pool_size);
|
||||
|
||||
~pool() { shutdown(); }
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<work_queue>> pool_queues_;
|
||||
std::vector<std::thread> pool_threads_;
|
||||
bool shutdown_ = false;
|
||||
std::atomic<std::uint8_t> thread_index_;
|
||||
|
||||
public:
|
||||
void execute(const std::uint64_t &thread_id, const worker_callback &worker,
|
||||
const worker_complete_callback &worker_complete);
|
||||
|
||||
void shutdown();
|
||||
};
|
||||
|
||||
public:
|
||||
explicit client_pool(const std::uint8_t &pool_size = 10u)
|
||||
: pool_size_(pool_size ? pool_size : 10u) {}
|
||||
|
||||
~client_pool() { shutdown(); }
|
||||
|
||||
private:
|
||||
const std::uint8_t pool_size_;
|
||||
std::unordered_map<std::string, std::shared_ptr<pool>> pool_lookup_;
|
||||
std::mutex pool_mutex_;
|
||||
bool shutdown_ = false;
|
||||
|
||||
public:
|
||||
void execute(const std::string &client_id, const std::uint64_t &thread_id,
|
||||
const worker_callback &worker, const worker_complete_callback &worker_complete);
|
||||
|
||||
void remove_client(const std::string &client_id);
|
||||
|
||||
void shutdown();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_
|
213
include/comm/packet/packet.hpp
Normal file
213
include/comm/packet/packet.hpp
Normal file
@ -0,0 +1,213 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_PACKET_PACKET_HPP_
|
||||
#define INCLUDE_COMM_PACKET_PACKET_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/remote.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
#define DECODE_OR_RETURN(p, value) \
|
||||
if ((ret = (p)->decode(value)) != 0) \
|
||||
return ret
|
||||
#define DECODE_OR_IGNORE(p, value) \
|
||||
if (ret == 0) \
|
||||
ret = (p)->decode(value)
|
||||
|
||||
class packet final {
|
||||
public:
|
||||
typedef std::int32_t error_type;
|
||||
|
||||
public:
|
||||
packet() = default;
|
||||
|
||||
explicit packet(std::vector<char> buffer) : buffer_(std::move(buffer)) {}
|
||||
|
||||
explicit packet(std::vector<char> &&buffer) : buffer_(std::move(buffer)) {}
|
||||
|
||||
packet(const packet &p) noexcept : buffer_(p.buffer_), decode_offset_(p.decode_offset_) {}
|
||||
|
||||
packet(packet &&p) noexcept : buffer_(std::move(p.buffer_)), decode_offset_(p.decode_offset_) {}
|
||||
|
||||
private:
|
||||
std::vector<char> buffer_;
|
||||
std::size_t decode_offset_ = 0u;
|
||||
|
||||
public:
|
||||
static int decode_json(packet &response, json &json_data);
|
||||
|
||||
public:
|
||||
void clear();
|
||||
|
||||
char *current_pointer() {
|
||||
return (decode_offset_ < buffer_.size()) ? &buffer_[decode_offset_] : nullptr;
|
||||
}
|
||||
|
||||
const char *current_pointer() const {
|
||||
return (decode_offset_ < buffer_.size()) ? &buffer_[decode_offset_] : nullptr;
|
||||
}
|
||||
|
||||
error_type decode(std::string &data);
|
||||
|
||||
error_type decode(std::wstring &data);
|
||||
|
||||
error_type decode(void *buffer, const size_t &size);
|
||||
|
||||
error_type decode(void *&ptr);
|
||||
|
||||
error_type decode(std::int8_t &i);
|
||||
|
||||
error_type decode(std::uint8_t &i);
|
||||
|
||||
error_type decode(std::int16_t &i);
|
||||
|
||||
error_type decode(std::uint16_t &i);
|
||||
|
||||
error_type decode(std::int32_t &i);
|
||||
|
||||
error_type decode(std::uint32_t &i);
|
||||
|
||||
error_type decode(std::int64_t &i);
|
||||
|
||||
error_type decode(std::uint64_t &i);
|
||||
|
||||
error_type decode(remote::open_flags &i) {
|
||||
return decode(reinterpret_cast<std::uint32_t &>(i));
|
||||
}
|
||||
|
||||
error_type decode(remote::setattr_x &i);
|
||||
|
||||
error_type decode(remote::stat &i);
|
||||
|
||||
error_type decode(remote::statfs &i);
|
||||
|
||||
error_type decode(remote::statfs_x &i);
|
||||
|
||||
error_type decode(remote::file_info &i);
|
||||
|
||||
error_type decrypt(const std::string &token);
|
||||
|
||||
void encode(const void *buffer, const std::size_t &size, bool should_reserve = true);
|
||||
|
||||
void encode(char *str) { encode(std::string(str ? str : "")); }
|
||||
|
||||
void encode(const char *str) { encode(std::string(str ? str : "")); }
|
||||
|
||||
void encode(const std::string &str);
|
||||
|
||||
void encode(wchar_t *str);
|
||||
|
||||
void encode(const wchar_t *str);
|
||||
|
||||
void encode(const std::wstring &str);
|
||||
|
||||
void encode(void *ptr) {
|
||||
encode(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(ptr)));
|
||||
}
|
||||
|
||||
void encode(std::int8_t i);
|
||||
|
||||
void encode(std::uint8_t i);
|
||||
|
||||
void encode(std::int16_t i);
|
||||
|
||||
void encode(std::uint16_t i);
|
||||
|
||||
void encode(std::int32_t i);
|
||||
|
||||
void encode(std::uint32_t i);
|
||||
|
||||
void encode(std::int64_t i);
|
||||
|
||||
void encode(std::uint64_t i);
|
||||
|
||||
void encode(remote::open_flags i) { encode(static_cast<std::uint32_t>(i)); }
|
||||
|
||||
void encode(remote::setattr_x i);
|
||||
|
||||
void encode(remote::stat i);
|
||||
|
||||
void encode(remote::statfs i, bool should_reserve = true);
|
||||
|
||||
void encode(remote::statfs_x i);
|
||||
|
||||
void encode(remote::file_info i);
|
||||
|
||||
void encode_top(const void *buffer, const std::size_t &size, bool should_reserve = true);
|
||||
|
||||
void encode_top(const std::string &str);
|
||||
|
||||
void encode_top(const std::wstring &str);
|
||||
|
||||
void encode_top(void *ptr) {
|
||||
encode_top(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(ptr)));
|
||||
}
|
||||
|
||||
void encode_top(std::int8_t i);
|
||||
|
||||
void encode_top(std::uint8_t i);
|
||||
|
||||
void encode_top(std::int16_t i);
|
||||
|
||||
void encode_top(std::uint16_t i);
|
||||
|
||||
void encode_top(std::int32_t i);
|
||||
|
||||
void encode_top(std::uint32_t i);
|
||||
|
||||
void encode_top(std::int64_t i);
|
||||
|
||||
void encode_top(std::uint64_t i);
|
||||
|
||||
void encode_top(remote::open_flags i) { encode_top(static_cast<std::uint32_t>(i)); }
|
||||
|
||||
void encode_top(remote::setattr_x i);
|
||||
|
||||
void encode_top(remote::stat i);
|
||||
|
||||
void encode_top(remote::statfs i, bool should_reserve = true);
|
||||
|
||||
void encode_top(remote::statfs_x i);
|
||||
|
||||
void encode_top(remote::file_info i);
|
||||
|
||||
void encrypt(const std::string &token);
|
||||
|
||||
std::uint32_t get_size() const { return static_cast<std::uint32_t>(buffer_.size()); }
|
||||
|
||||
void transfer_into(std::vector<char> &buffer);
|
||||
|
||||
public:
|
||||
packet &operator=(const std::vector<char> &buffer) noexcept;
|
||||
|
||||
packet &operator=(std::vector<char> &&buffer) noexcept;
|
||||
|
||||
packet &operator=(const packet &p) noexcept;
|
||||
|
||||
packet &operator=(packet &&p) noexcept;
|
||||
|
||||
char &operator[](const size_t &index) { return buffer_[index]; }
|
||||
|
||||
const char &operator[](const size_t &index) const { return buffer_.at(index); }
|
||||
};
|
||||
typedef packet packet;
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_COMM_PACKET_PACKET_HPP_
|
84
include/comm/packet/packet_client.hpp
Normal file
84
include/comm/packet/packet_client.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_PACKET_PACKET_CLIENT_HPP_
|
||||
#define INCLUDE_COMM_PACKET_PACKET_CLIENT_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/packet/packet.hpp"
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
namespace repertory {
|
||||
class packet_client final {
|
||||
private:
|
||||
struct client {
|
||||
client(boost::asio::io_context &ctx) : nonce(""), socket(ctx) {}
|
||||
|
||||
std::string nonce;
|
||||
tcp::socket socket;
|
||||
};
|
||||
|
||||
public:
|
||||
packet_client(std::string host_name_or_ip, const std::uint8_t &max_connections,
|
||||
const std::uint16_t &port, const std::uint16_t &receive_timeout,
|
||||
const std::uint16_t &send_timeout, std::string encryption_token);
|
||||
|
||||
~packet_client();
|
||||
|
||||
private:
|
||||
boost::asio::io_context io_context_;
|
||||
const std::string host_name_or_ip_;
|
||||
const std::uint8_t max_connections_;
|
||||
const std::uint16_t port_;
|
||||
const std::uint16_t receive_timeout_;
|
||||
const std::uint16_t send_timeout_;
|
||||
const std::string encryption_token_;
|
||||
std::string unique_id_;
|
||||
|
||||
bool allow_connections_ = true;
|
||||
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type resolve_results_;
|
||||
std::mutex clients_mutex_;
|
||||
std::vector<std::shared_ptr<client>> clients_;
|
||||
|
||||
private:
|
||||
void close(client &c) const;
|
||||
|
||||
void close_all();
|
||||
|
||||
bool connect(client &c);
|
||||
|
||||
std::shared_ptr<client> get_client();
|
||||
|
||||
void put_client(std::shared_ptr<client> &c);
|
||||
|
||||
packet::error_type read_packet(client &c, packet &response);
|
||||
|
||||
void resolve();
|
||||
|
||||
public:
|
||||
packet::error_type send(const std::string &method, std::uint32_t &service_flags);
|
||||
|
||||
packet::error_type send(const std::string &method, packet &request, std::uint32_t &service_flags);
|
||||
|
||||
packet::error_type send(const std::string &method, packet &request, packet &response,
|
||||
std::uint32_t &service_flags);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_COMM_PACKET_PACKET_CLIENT_HPP_
|
90
include/comm/packet/packet_server.hpp
Normal file
90
include/comm/packet/packet_server.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMM_PACKET_PACKET_SERVER_HPP_
|
||||
#define INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/packet/client_pool.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
using namespace boost::asio;
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
namespace repertory {
|
||||
class packet_server final {
|
||||
public:
|
||||
typedef std::function<void(const std::string &clientId)> closed_callback;
|
||||
typedef client_pool::worker_complete_callback message_complete_callback;
|
||||
typedef std::function<void(const std::uint32_t &service_flags, const std::string &client_id,
|
||||
const std::uint64_t &thread_id, const std::string &method,
|
||||
packet *request, packet &response,
|
||||
message_complete_callback message_complete)>
|
||||
message_handler_callback;
|
||||
|
||||
public:
|
||||
packet_server(const std::uint16_t &port, std::string token, std::uint8_t pool_size,
|
||||
closed_callback closed, message_handler_callback message_handler);
|
||||
|
||||
~packet_server();
|
||||
|
||||
private:
|
||||
struct connection {
|
||||
connection(boost::asio::io_service &io_service, tcp::acceptor &acceptor)
|
||||
: socket(io_service), acceptor(acceptor) {}
|
||||
|
||||
tcp::socket socket;
|
||||
tcp::acceptor &acceptor;
|
||||
std::vector<char> buffer;
|
||||
std::string client_id;
|
||||
std::string nonce;
|
||||
|
||||
void generate_nonce() { nonce = utils::generate_random_string(256u); }
|
||||
};
|
||||
|
||||
private:
|
||||
const std::string encryption_token_;
|
||||
closed_callback closed_;
|
||||
message_handler_callback message_handler_;
|
||||
boost::asio::io_context io_context_;
|
||||
std::unique_ptr<std::thread> server_thread_;
|
||||
std::vector<std::thread> service_threads_;
|
||||
std::recursive_mutex connection_mutex_;
|
||||
std::unordered_map<std::string, std::uint32_t> connection_lookup_;
|
||||
|
||||
private:
|
||||
void add_client(connection &c, const std::string &client_id);
|
||||
|
||||
void initialize(const uint16_t &port, uint8_t pool_size);
|
||||
|
||||
void listen_for_connection(tcp::acceptor &acceptor);
|
||||
|
||||
void on_accept(std::shared_ptr<connection> c, boost::system::error_code ec);
|
||||
|
||||
void read_header(std::shared_ptr<connection> c);
|
||||
|
||||
void read_packet(std::shared_ptr<connection> c, const std::uint32_t &data_size);
|
||||
|
||||
void remove_client(connection &c);
|
||||
|
||||
void send_response(std::shared_ptr<connection> c, const packet::error_type &result,
|
||||
packet &response);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_
|
324
include/common.hpp
Normal file
324
include/common.hpp
Normal file
@ -0,0 +1,324 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COMMON_HPP_
|
||||
#define INCLUDE_COMMON_HPP_
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <WinSock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <Windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <ShlObj.h>
|
||||
#include <ciso646>
|
||||
#include <direct.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#define FUSE_USE_VERSION 29
|
||||
#include <climits>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <libgen.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef __linux__
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#ifdef HAS_SETXATTR
|
||||
#include <sys/types.h>
|
||||
#include <sys/xattr.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <libproc.h>
|
||||
#include <sys/attr.h>
|
||||
#include <sys/vnode.h>
|
||||
#endif
|
||||
#if __APPLE__
|
||||
#include <sys/mount.h>
|
||||
#include <sys/statvfs.h>
|
||||
#endif
|
||||
#if __linux__
|
||||
#include <utils/uuid++.hh>
|
||||
#else
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <boost/archive/text_iarchive.hpp>
|
||||
#include <boost/archive/text_oarchive.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
#include <boost/dynamic_bitset/serialization.hpp>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#include <chacha.h>
|
||||
#include <chachapoly.h>
|
||||
#include <chrono>
|
||||
#include <codecvt>
|
||||
#include <condition_variable>
|
||||
#include <curl/curl.h>
|
||||
#include <curl/multi.h>
|
||||
#include <deque>
|
||||
#include <fstream>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
#include <jsonrp.hpp>
|
||||
#include <limits>
|
||||
#include <microhttpd.h>
|
||||
#include <httpserver.hpp>
|
||||
#include <mutex>
|
||||
|
||||
#if !IS_DEBIAN9_DISTRO && HAS_STD_OPTIONAL
|
||||
#include <optional>
|
||||
#else
|
||||
#include <utils/optional.h>
|
||||
#endif
|
||||
#include <files.h>
|
||||
#include <hex.h>
|
||||
#include <json.hpp>
|
||||
#include <osrng.h>
|
||||
#include <random>
|
||||
#include <regex>
|
||||
#include <rocksdb/db.h>
|
||||
#include <sha.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <ttmath.h>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <sddl.h>
|
||||
#include <winfsp/winfsp.hpp>
|
||||
#else
|
||||
#include <fuse/fuse.h>
|
||||
#endif
|
||||
|
||||
#if defined(REPERTORY_ENABLE_S3)
|
||||
#include <aws/core/Aws.h>
|
||||
#include <aws/core/auth/AWSCredentials.h>
|
||||
#include <aws/core/utils/logging/AWSLogging.h>
|
||||
#include <aws/core/utils/logging/DefaultLogSystem.h>
|
||||
#include <aws/s3/S3Client.h>
|
||||
#include <aws/s3/model/CopyObjectRequest.h>
|
||||
#include <aws/s3/model/CreateBucketRequest.h>
|
||||
#include <aws/s3/model/DeleteBucketRequest.h>
|
||||
#include <aws/s3/model/DeleteObjectRequest.h>
|
||||
#include <aws/s3/model/GetObjectRequest.h>
|
||||
#include <aws/s3/model/HeadObjectRequest.h>
|
||||
#include <aws/s3/model/ListObjectsRequest.h>
|
||||
#include <aws/s3/model/Object.h>
|
||||
#include <aws/s3/model/PutObjectRequest.h>
|
||||
#endif
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using json = nlohmann::json;
|
||||
|
||||
const std::string &get_repertory_git_revision();
|
||||
const std::string &get_repertory_version();
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef CreateDirectory
|
||||
#undef CreateDirectory
|
||||
#endif
|
||||
#ifdef CreateFile
|
||||
#undef CreateFile
|
||||
#endif
|
||||
#ifdef DeleteFile
|
||||
#undef DeleteFile
|
||||
#endif
|
||||
#ifdef RemoveDirectory
|
||||
#undef RemoveDirectory
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MIN_REMOTE_VERSION "2.0.0"
|
||||
#define MIN_SIA_VERSION "1.4.1"
|
||||
#define MIN_SP_VERSION "1.4.1.2"
|
||||
#define REPERTORY_CONFIG_VERSION 0ull
|
||||
#define REPERTORY "repertory"
|
||||
#define REPERTORY_DATA_NAME "repertory2"
|
||||
#define REPERTORY_W L"repertory"
|
||||
|
||||
#define NANOS_PER_SECOND 1000000000L
|
||||
|
||||
#ifdef _WIN32
|
||||
#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
|
||||
#define REPERTORY_API_INVALID_HANDLE static_cast<std::uint64_t>(-1)
|
||||
#define OSHandle HANDLE
|
||||
#else
|
||||
#define REPERTORY_INVALID_HANDLE -1
|
||||
#define REPERTORY_API_INVALID_HANDLE REPERTORY_INVALID_HANDLE
|
||||
#define OSHandle int
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef __APPLE__
|
||||
#define G_PREFIX "org"
|
||||
#define G_KAUTH_FILESEC_XATTR G_PREFIX ".apple.system.Security"
|
||||
#define A_PREFIX "com"
|
||||
#define A_KAUTH_FILESEC_XATTR A_PREFIX ".apple.system.Security"
|
||||
#define XATTR_APPLE_PREFIX "com.apple."
|
||||
#endif
|
||||
|
||||
#ifndef XATTR_NAME_MAX
|
||||
#define XATTR_NAME_MAX 255 /* # chars in an extended attribute name */
|
||||
#endif
|
||||
|
||||
#ifndef XATTR_SIZE_MAX
|
||||
#define XATTR_SIZE_MAX 65536
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __APPLE__
|
||||
#define pread64 pread
|
||||
#define pwrite64 pwrite
|
||||
#endif
|
||||
|
||||
#define WINFSP_ALLOCATION_UNIT UINT64(4096U)
|
||||
|
||||
#ifdef _WIN32
|
||||
#define UTIME_NOW ((1l << 30) - 1l)
|
||||
#define UTIME_OMIT ((1l << 30) - 2l)
|
||||
#define CONVERT_STATUS_NOT_IMPLEMENTED(e) e
|
||||
#else
|
||||
#define VOID void
|
||||
#define PVOID VOID *
|
||||
typedef PVOID HANDLE;
|
||||
#define WCHAR wchar_t
|
||||
#define PWSTR WCHAR *
|
||||
#define BOOLEAN std::uint8_t
|
||||
#define UINT16 std::uint16_t
|
||||
#define UINT32 std::uint32_t
|
||||
#define PUINT32 UINT32 *
|
||||
#define UINT64 std::uint64_t
|
||||
#define SIZE_T std::uint64_t
|
||||
#define DWORD std::uint32_t
|
||||
|
||||
#define FILE_ATTRIBUTE_READONLY 0x00000001
|
||||
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
|
||||
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
|
||||
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
|
||||
#define FILE_ATTRIBUTE_DEVICE 0x00000040
|
||||
#define FILE_ATTRIBUTE_NORMAL 0x00000080
|
||||
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
|
||||
#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
|
||||
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
|
||||
#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
|
||||
#define FILE_ATTRIBUTE_OFFLINE 0x00001000
|
||||
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
|
||||
#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
|
||||
#define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x00008000
|
||||
#define FILE_ATTRIBUTE_VIRTUAL 0x00010000
|
||||
#define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000
|
||||
#define FILE_ATTRIBUTE_EA 0x00040000
|
||||
#define FILE_ATTRIBUTE_PINNED 0x00080000
|
||||
#define FILE_ATTRIBUTE_UNPINNED 0x00100000
|
||||
#define FILE_ATTRIBUTE_RECALL_ON_OPEN 0x00040000
|
||||
#define FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000
|
||||
|
||||
#define FILE_DIRECTORY_FILE 0x00000001
|
||||
|
||||
#define FILE_EXECUTE (0x0020)
|
||||
#define FILE_GENERIC_EXECUTE (0x00020000L | 0x0080 | 0x0020 | 0x00100000L)
|
||||
|
||||
#define GENERIC_READ (0x80000000L)
|
||||
#define GENERIC_WRITE (0x40000000L)
|
||||
#define GENERIC_EXECUTE (0x20000000L)
|
||||
#define GENERIC_ALL (0x10000000L)
|
||||
|
||||
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
||||
|
||||
#define MAX_PATH 260
|
||||
|
||||
#define STATUS_SUCCESS std::int32_t(0)
|
||||
#define STATUS_ACCESS_DENIED std::int32_t(0xC0000022L)
|
||||
#define STATUS_DEVICE_BUSY std::int32_t(0x80000011L)
|
||||
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::int32_t(0xC0000468L)
|
||||
#define STATUS_DIRECTORY_NOT_EMPTY std::int32_t(0xC0000101L)
|
||||
#define STATUS_FILE_IS_A_DIRECTORY std::int32_t(0xC00000BAL)
|
||||
#define STATUS_FILE_TOO_LARGE std::int32_t(0xC0000904L)
|
||||
#define STATUS_INSUFFICIENT_RESOURCES std::int32_t(0xC000009AL)
|
||||
#define STATUS_INTERNAL_ERROR std::int32_t(0xC00000E5L)
|
||||
#define STATUS_INVALID_ADDRESS std::int32_t(0xC0000141L)
|
||||
#define STATUS_INVALID_HANDLE std::int32_t(0xC0000006L)
|
||||
#define STATUS_INVALID_IMAGE_FORMAT std::int32_t(0xC000007BL)
|
||||
#define STATUS_INVALID_PARAMETER std::int32_t(0xC000000DL)
|
||||
#define STATUS_NO_MEMORY std::int32_t(0xC0000017L)
|
||||
#define STATUS_NOT_IMPLEMENTED std::int32_t(0xC0000002L)
|
||||
#define STATUS_OBJECT_NAME_EXISTS std::int32_t(0x40000000L)
|
||||
#define STATUS_OBJECT_NAME_NOT_FOUND std::int32_t(0xC0000034L)
|
||||
#define STATUS_OBJECT_PATH_INVALID std::int32_t(0xC0000039L)
|
||||
#define STATUS_UNEXPECTED_IO_ERROR std::int32_t(0xC00000E9L)
|
||||
#define CONVERT_STATUS_NOT_IMPLEMENTED(e) \
|
||||
((std::int32_t(e) == STATUS_NOT_IMPLEMENTED) ? -ENOTSUP : e)
|
||||
|
||||
namespace Fsp::FileSystemBase {
|
||||
enum {
|
||||
FspCleanupDelete = 0x01,
|
||||
FspCleanupSetAllocationSize = 0x02,
|
||||
FspCleanupSetArchiveBit = 0x10,
|
||||
FspCleanupSetLastAccessTime = 0x20,
|
||||
FspCleanupSetLastWriteTime = 0x40,
|
||||
FspCleanupSetChangeTime = 0x80
|
||||
};
|
||||
|
||||
struct FSP_FSCTL_FILE_INFO {
|
||||
UINT32 FileAttributes;
|
||||
UINT32 ReparseTag;
|
||||
UINT64 AllocationSize;
|
||||
UINT64 FileSize;
|
||||
UINT64 CreationTime;
|
||||
UINT64 LastAccessTime;
|
||||
UINT64 LastWriteTime;
|
||||
UINT64 ChangeTime;
|
||||
UINT64 IndexNumber;
|
||||
UINT32 HardLinks;
|
||||
UINT32 EaSize;
|
||||
};
|
||||
|
||||
typedef FSP_FSCTL_FILE_INFO FileInfo;
|
||||
} // namespace Fsp::FileSystemBase
|
||||
#endif
|
||||
|
||||
using namespace Fsp;
|
||||
|
||||
#define INTERFACE_SETUP(name) \
|
||||
public: \
|
||||
name(const name &) noexcept = delete; \
|
||||
name(name &&) noexcept = delete; \
|
||||
name &operator=(const name &) noexcept = delete; \
|
||||
name &operator=(name &&) noexcept = delete; \
|
||||
\
|
||||
protected: \
|
||||
name() = default; \
|
||||
\
|
||||
public: \
|
||||
virtual ~name() = default
|
||||
|
||||
#endif // INCLUDE_COMMON_HPP_
|
101
include/db/directory_db.hpp
Normal file
101
include/db/directory_db.hpp
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DB_DIRECTORY_DB_HPP_
|
||||
#define INCLUDE_DB_DIRECTORY_DB_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/rocksdb_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class directory_db final {
|
||||
private:
|
||||
class directory_tree final {
|
||||
private:
|
||||
std::unordered_map<std::string, std::vector<std::string>> sub_directory_lookup_;
|
||||
|
||||
public:
|
||||
void add_path(const std::string &api_path, const std::vector<std::string> &files,
|
||||
rocksdb::DB &db);
|
||||
|
||||
std::size_t get_count(const std::string &api_path) const;
|
||||
|
||||
std::vector<std::string> get_directories() const;
|
||||
|
||||
std::vector<std::string> get_sub_directories(const std::string &api_path) const;
|
||||
|
||||
bool is_directory(const std::string &api_path) const;
|
||||
|
||||
bool remove_directory(const std::string &api_path, rocksdb::DB &db,
|
||||
const bool &allow_remove_root = false);
|
||||
};
|
||||
|
||||
public:
|
||||
explicit directory_db(const app_config &config);
|
||||
|
||||
public:
|
||||
~directory_db();
|
||||
|
||||
private:
|
||||
mutable std::recursive_mutex directory_mutex_;
|
||||
std::unique_ptr<rocksdb::DB> db_;
|
||||
directory_tree tree_;
|
||||
const std::string DIRDB_NAME = "directory_db";
|
||||
|
||||
private:
|
||||
json get_directory_data(const std::string &api_path) const;
|
||||
|
||||
public:
|
||||
api_error create_directory(const std::string &api_path, const bool &create_always = false);
|
||||
|
||||
api_error create_file(const std::string &api_path);
|
||||
|
||||
std::uint64_t get_directory_item_count(const std::string &api_path) const;
|
||||
|
||||
api_error get_file(const std::string &api_path, api_file &file,
|
||||
api_file_provider_callback api_file_provider) const;
|
||||
|
||||
api_error get_file_list(api_file_list &list, api_file_provider_callback api_file_provider) const;
|
||||
|
||||
std::size_t get_sub_directory_count(const std::string &api_path) const;
|
||||
|
||||
std::uint64_t get_total_item_count() const;
|
||||
|
||||
bool is_directory(const std::string &api_path) const;
|
||||
|
||||
bool is_file(const std::string &api_path) const;
|
||||
|
||||
void populate_directory_files(const std::string &api_path,
|
||||
const meta_provider_callback &meta_provider,
|
||||
directory_item_list &list) const;
|
||||
|
||||
void populate_sub_directories(const std::string &api_path,
|
||||
const meta_provider_callback &meta_provider,
|
||||
directory_item_list &list) const;
|
||||
|
||||
api_error remove_directory(const std::string &api_path, const bool &allow_remove_root = false);
|
||||
|
||||
bool remove_file(const std::string &api_path);
|
||||
|
||||
api_error rename_file(const std::string &from_api_path, const std::string &to_api_path);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DB_DIRECTORY_DB_HPP_
|
81
include/db/meta_db.hpp
Normal file
81
include/db/meta_db.hpp
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DB_META_DB_HPP_
|
||||
#define INCLUDE_DB_META_DB_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/rocksdb_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class meta_db final {
|
||||
public:
|
||||
explicit meta_db(const app_config &config);
|
||||
|
||||
public:
|
||||
~meta_db();
|
||||
|
||||
private:
|
||||
std::unique_ptr<rocksdb::DB> db_;
|
||||
std::unique_ptr<rocksdb::ColumnFamilyHandle> default_family_;
|
||||
std::unique_ptr<rocksdb::ColumnFamilyHandle> source_family_;
|
||||
std::unique_ptr<rocksdb::ColumnFamilyHandle> keys_family_;
|
||||
const std::string METADB_NAME = "meta_db";
|
||||
|
||||
private:
|
||||
api_error get_item_meta_json(const std::string &api_path, json &json_data) const;
|
||||
|
||||
void release_resources();
|
||||
|
||||
public:
|
||||
std::shared_ptr<rocksdb::Iterator> create_iterator(const bool &source_family);
|
||||
|
||||
api_error get_api_path_from_key(const std::string &key, std::string &api_path) const;
|
||||
|
||||
api_error get_api_path_from_source(const std::string &source_path, std::string &api_path) const;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, const std::string &key,
|
||||
std::string &value) const;
|
||||
|
||||
bool get_item_meta_exists(const std::string &api_path) const;
|
||||
|
||||
std::vector<std::string> get_pinned_files() const;
|
||||
|
||||
bool get_source_path_exists(const std::string &source_path) const;
|
||||
|
||||
void remove_item_meta(const std::string &api_path);
|
||||
|
||||
api_error remove_item_meta(const std::string &api_path, const std::string &key);
|
||||
|
||||
api_error rename_item_meta(const std::string &source_path, const std::string &from_api_path,
|
||||
const std::string &to_api_path);
|
||||
|
||||
api_error set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value);
|
||||
|
||||
api_error set_item_meta(const std::string &api_path, const api_meta_map &meta);
|
||||
|
||||
api_error set_source_path(const std::string &api_path, const std::string &source_path);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DB_META_DB_HPP_
|
63
include/db/retry_db.hpp
Normal file
63
include/db/retry_db.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DB_RETRY_DB_HPP_
|
||||
#define INCLUDE_DB_RETRY_DB_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/rocksdb_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class retry_db final {
|
||||
public:
|
||||
typedef std::function<bool(const std::string &api_path)> process_callback;
|
||||
|
||||
public:
|
||||
explicit retry_db(const app_config &config);
|
||||
|
||||
~retry_db();
|
||||
|
||||
private:
|
||||
std::unique_ptr<rocksdb::DB> db_;
|
||||
bool paused_ = false;
|
||||
std::mutex processing_mutex_;
|
||||
const std::string ROCKS_DB_NAME = "retry_db";
|
||||
|
||||
public:
|
||||
bool exists(const std::string &api_path) const;
|
||||
|
||||
void pause();
|
||||
|
||||
bool process_all(const process_callback &process);
|
||||
|
||||
void remove(const std::string &api_path);
|
||||
|
||||
void rename(const std::string &from_api_path, const std::string &to_api_path);
|
||||
|
||||
void resume();
|
||||
|
||||
void set(const std::string &api_path);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DB_RETRY_DB_HPP_
|
78
include/download/buffered_reader.hpp
Normal file
78
include/download/buffered_reader.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_BUFFERED_READER_HPP_
|
||||
#define INCLUDE_DOWNLOAD_BUFFERED_READER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class buffered_reader final {
|
||||
public:
|
||||
buffered_reader(const app_config &config, const filesystem_item &fsi,
|
||||
const api_reader_callback &api_reader, const std::size_t &chunk_size,
|
||||
const std::size_t &total_chunks, const std::size_t &start_chunk);
|
||||
|
||||
~buffered_reader();
|
||||
|
||||
private:
|
||||
const filesystem_item &fsi_;
|
||||
const api_reader_callback &api_reader_;
|
||||
const std::size_t chunk_size_;
|
||||
const std::size_t total_chunks_;
|
||||
boost::dynamic_bitset<> ring_state_;
|
||||
|
||||
api_error error_ = api_error::success;
|
||||
std::unique_ptr<std::vector<char>> first_chunk_data_;
|
||||
std::unique_ptr<std::vector<char>> last_chunk_data_;
|
||||
std::size_t read_chunk_index_ = 0u;
|
||||
std::mutex read_mutex_;
|
||||
std::condition_variable read_notify_;
|
||||
std::size_t read_offset_ = 0u;
|
||||
bool reset_reader_ = false;
|
||||
std::vector<std::vector<char>> ring_data_;
|
||||
std::unique_ptr<std::thread> reader_thread_;
|
||||
bool stop_requested_ = false;
|
||||
std::mutex write_mutex_;
|
||||
std::size_t write_chunk_index_ = 0u;
|
||||
|
||||
private:
|
||||
bool is_active() const { return not stop_requested_ && (error_ == api_error::success); }
|
||||
|
||||
void reader_thread();
|
||||
|
||||
public:
|
||||
std::size_t get_chunk_size() const { return chunk_size_; }
|
||||
|
||||
void get_first_chunk(std::vector<char> *&data) { data = first_chunk_data_.get(); }
|
||||
|
||||
void get_last_chunk(std::vector<char> *&data) { data = last_chunk_data_.get(); }
|
||||
|
||||
bool has_first_chunk() const { return static_cast<bool>(first_chunk_data_); }
|
||||
|
||||
bool has_last_chunk() const { return static_cast<bool>(last_chunk_data_); }
|
||||
|
||||
void notify_stop_requested();
|
||||
|
||||
api_error read_chunk(const std::size_t &chunk_index, std::vector<char> &data);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_BUFFERED_READER_HPP_
|
99
include/download/direct_download.hpp
Normal file
99
include/download/direct_download.hpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_DIRECT_DOWNLOAD_HPP_
|
||||
#define INCLUDE_DOWNLOAD_DIRECT_DOWNLOAD_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "download/i_download.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class buffered_reader;
|
||||
class app_config;
|
||||
class direct_download final : public virtual i_download {
|
||||
public:
|
||||
direct_download(const app_config &config, filesystem_item fsi,
|
||||
const api_reader_callback &api_reader, const std::uint64_t &handle);
|
||||
|
||||
~direct_download() override;
|
||||
|
||||
private:
|
||||
const app_config &config_;
|
||||
const filesystem_item fsi_;
|
||||
const api_reader_callback &api_reader_;
|
||||
const std::uint64_t handle_;
|
||||
|
||||
api_error error_ = api_error::success;
|
||||
std::unique_ptr<buffered_reader> buffered_reader_;
|
||||
bool disable_download_end_ = false;
|
||||
bool download_end_notified_ = false;
|
||||
double progress_ = 0.0;
|
||||
std::mutex read_mutex_;
|
||||
bool stop_requested_ = false;
|
||||
|
||||
private:
|
||||
bool is_active() const { return not stop_requested_ && (error_ == api_error::success); }
|
||||
|
||||
void notify_download_end();
|
||||
|
||||
void set_api_error(const api_error &error);
|
||||
|
||||
public:
|
||||
api_error allocate(const std::uint64_t & /*handle*/, const std::uint64_t & /*size*/,
|
||||
const allocator_callback & /*allocator*/,
|
||||
const completer_callback & /*completer*/) override {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
api_error download_all() override { return api_error::not_implemented; }
|
||||
|
||||
api_error get_result() const override { return error_; }
|
||||
|
||||
std::string get_source_path() const override { return ""; }
|
||||
|
||||
void get_state_information(filesystem_item &, std::size_t &, std::size_t &,
|
||||
boost::dynamic_bitset<> &, boost::dynamic_bitset<> &) override {}
|
||||
|
||||
bool get_write_supported() const override { return false; }
|
||||
|
||||
void notify_stop_requested() override;
|
||||
|
||||
bool pause() override { return false; }
|
||||
|
||||
api_error read_bytes(const std::uint64_t &, std::size_t read_size,
|
||||
const std::uint64_t &read_offset, std::vector<char> &data) override;
|
||||
|
||||
void reset_timeout(const bool &) override {}
|
||||
|
||||
void resume() override {}
|
||||
|
||||
void set_api_path(const std::string &) override {}
|
||||
|
||||
void set_disable_download_end(const bool &disable) override { disable_download_end_ = disable; }
|
||||
|
||||
api_error write_bytes(const std::uint64_t &, const std::uint64_t &, std::vector<char>,
|
||||
std::size_t &bytes_written,
|
||||
const completer_callback & /*completer*/) override {
|
||||
bytes_written = 0u;
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_DIRECT_DOWNLOAD_HPP_
|
191
include/download/download.hpp
Normal file
191
include/download/download.hpp
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_DOWNLOAD_HPP_
|
||||
#define INCLUDE_DOWNLOAD_DOWNLOAD_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "download/i_download.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/native_file.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_open_file_table;
|
||||
class download final : public virtual i_download {
|
||||
private:
|
||||
struct active_chunk {
|
||||
explicit active_chunk(std::thread worker) : worker(std::move(worker)) {}
|
||||
|
||||
std::thread worker;
|
||||
std::mutex mutex;
|
||||
std::condition_variable notify;
|
||||
};
|
||||
typedef std::shared_ptr<active_chunk> active_chunk_ptr;
|
||||
|
||||
struct read_data {
|
||||
read_data(std::vector<char> &data, const std::uint64_t &offset)
|
||||
: complete(false), data(data), offset(offset) {}
|
||||
|
||||
bool complete;
|
||||
std::vector<char> &data;
|
||||
const std::uint64_t offset;
|
||||
std::mutex mutex;
|
||||
std::condition_variable notify;
|
||||
};
|
||||
typedef std::shared_ptr<read_data> read_data_ptr;
|
||||
|
||||
struct write_data {
|
||||
write_data(const std::size_t &chunk, std::vector<char> data, const std::uint64_t &offset)
|
||||
: chunk_index(chunk), data(std::move(data)), offset(offset) {}
|
||||
write_data(const std::uint64_t &offset, std::vector<char> data)
|
||||
: chunk_index(0u), data(std::move(data)), offset(offset), from_read(false) {}
|
||||
|
||||
std::size_t chunk_index;
|
||||
std::vector<char> data;
|
||||
const std::uint64_t offset;
|
||||
bool from_read = true;
|
||||
bool complete = false;
|
||||
std::mutex mutex;
|
||||
std::condition_variable notify;
|
||||
std::size_t written = 0u;
|
||||
};
|
||||
typedef std::shared_ptr<write_data> write_data_ptr;
|
||||
|
||||
public:
|
||||
download(const app_config &config, filesystem_item &fsi, const api_reader_callback &api_reader,
|
||||
const std::size_t &chunk_size, i_open_file_table &oft);
|
||||
|
||||
download(const app_config &config, filesystem_item &fsi, const api_reader_callback &api_reader,
|
||||
const std::size_t &chunk_size, std::size_t &last_chunk_size,
|
||||
boost::dynamic_bitset<> &read_state, boost::dynamic_bitset<> &write_state,
|
||||
i_open_file_table &oft);
|
||||
|
||||
~download() override;
|
||||
|
||||
private:
|
||||
// Constructor initialization
|
||||
const app_config &config_;
|
||||
filesystem_item fsi_;
|
||||
const api_reader_callback &api_reader_;
|
||||
i_open_file_table &oft_;
|
||||
const std::size_t chunk_size_;
|
||||
boost::dynamic_bitset<> read_chunk_state_;
|
||||
std::size_t last_chunk_size_;
|
||||
boost::dynamic_bitset<> write_chunk_state_;
|
||||
|
||||
// Default initialization
|
||||
bool auto_close_ = false;
|
||||
std::unordered_map<std::size_t, active_chunk_ptr> active_chunks_;
|
||||
api_error error_ = api_error::success;
|
||||
std::vector<std::thread> background_workers_;
|
||||
std::size_t current_chunk_index_ = 0u;
|
||||
bool disable_download_end_ = false;
|
||||
std::unique_ptr<std::thread> io_thread_;
|
||||
std::uint64_t open_file_handle_ = REPERTORY_API_INVALID_HANDLE;
|
||||
bool paused_ = false;
|
||||
bool processed_ = false;
|
||||
std::condition_variable processed_notify_;
|
||||
double progress_ = 0.0;
|
||||
std::size_t read_offset_ = 0u;
|
||||
std::deque<read_data_ptr> read_queue_;
|
||||
native_file_ptr read_write_file_;
|
||||
std::mutex read_write_mutex_;
|
||||
std::condition_variable read_write_notify_;
|
||||
bool stop_requested_ = false;
|
||||
std::chrono::system_clock::time_point timeout_ =
|
||||
std::chrono::system_clock::now() +
|
||||
std::chrono::seconds(config_.get_chunk_downloader_timeout_secs());
|
||||
std::deque<write_data_ptr> write_queue_;
|
||||
|
||||
private:
|
||||
void create_active_chunk(std::size_t chunk_index);
|
||||
|
||||
void download_chunk(std::size_t chunk_index, bool inactive_only);
|
||||
|
||||
bool get_complete() const;
|
||||
|
||||
bool get_timeout_enabled() const;
|
||||
|
||||
void handle_active_chunk_complete(std::size_t chunk_index, unique_mutex_lock &lock);
|
||||
|
||||
void initialize_download(filesystem_item &fsi, const bool &delete_existing);
|
||||
|
||||
void io_data_worker();
|
||||
|
||||
void notify_progress();
|
||||
|
||||
void process_download_complete(unique_mutex_lock &lock);
|
||||
|
||||
void process_read_queue(unique_mutex_lock &lock);
|
||||
|
||||
void process_timeout(unique_mutex_lock &lock);
|
||||
|
||||
void process_write_queue(unique_mutex_lock &lock);
|
||||
|
||||
void read_ahead_worker();
|
||||
|
||||
void read_behind_worker();
|
||||
|
||||
void read_end_worker();
|
||||
|
||||
void shutdown(unique_mutex_lock &lock);
|
||||
|
||||
void wait_for_io(unique_mutex_lock &lock);
|
||||
|
||||
public:
|
||||
api_error allocate(const std::uint64_t &handle, const std::uint64_t &size,
|
||||
const allocator_callback &allocator,
|
||||
const completer_callback &completer) override;
|
||||
|
||||
api_error download_all() override;
|
||||
|
||||
api_error get_result() const override { return error_; }
|
||||
|
||||
std::string get_source_path() const override { return fsi_.source_path; }
|
||||
|
||||
void get_state_information(filesystem_item &fsi, std::size_t &chunk_size,
|
||||
std::size_t &last_chunk_size, boost::dynamic_bitset<> &read_state,
|
||||
boost::dynamic_bitset<> &write_state) override;
|
||||
|
||||
bool get_write_supported() const override { return true; }
|
||||
|
||||
bool is_active() const { return not read_chunk_state_.all(); }
|
||||
|
||||
void notify_stop_requested() override;
|
||||
|
||||
bool pause() override;
|
||||
|
||||
api_error read_bytes(const std::uint64_t &handle, std::size_t read_size,
|
||||
const std::uint64_t &read_offset, std::vector<char> &data) override;
|
||||
|
||||
void reset_timeout(const bool &) override;
|
||||
|
||||
void resume() override;
|
||||
|
||||
void set_api_path(const std::string &api_path) override;
|
||||
|
||||
void set_disable_download_end(const bool &disable) override { disable_download_end_ = disable; }
|
||||
|
||||
api_error write_bytes(const std::uint64_t &handle, const std::uint64_t &write_offset,
|
||||
std::vector<char> data, std::size_t &bytes_written,
|
||||
const completer_callback &completer) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_DOWNLOAD_HPP_
|
102
include/download/download_manager.hpp
Normal file
102
include/download/download_manager.hpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_DOWNLOAD_MANAGER_HPP_
|
||||
#define INCLUDE_DOWNLOAD_DOWNLOAD_MANAGER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "download/i_download.hpp"
|
||||
#include "download/i_download_manager.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class download_end;
|
||||
class filesystem_item_handle_closed;
|
||||
class i_open_file_table;
|
||||
class download_manager final : public virtual i_download_manager {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
download_manager(const app_config &config, api_reader_callback api_reader,
|
||||
const bool &force_download = false);
|
||||
|
||||
~download_manager() override;
|
||||
|
||||
private:
|
||||
const app_config &config_;
|
||||
const api_reader_callback api_reader_;
|
||||
bool force_download_;
|
||||
i_open_file_table *oft_ = nullptr;
|
||||
mutable std::recursive_mutex download_mutex_;
|
||||
std::unordered_map<std::string, std::unordered_map<std::uint64_t, download_ptr>> download_lookup_;
|
||||
std::recursive_mutex start_stop_mutex_;
|
||||
bool stop_requested_ = true;
|
||||
std::unique_ptr<rocksdb::DB> restore_db_;
|
||||
|
||||
private:
|
||||
bool contains_handle(const std::string &api_path, const std::uint64_t &handle) const;
|
||||
|
||||
download_ptr get_download(std::uint64_t handle, filesystem_item &fsi,
|
||||
const bool &write_Supported);
|
||||
|
||||
void handle_download_end(const download_end &de);
|
||||
|
||||
void on_handle_closed(const filesystem_item_handle_closed &handle_closed);
|
||||
|
||||
void reset_timeout(const std::string &api_path, const bool &file_closed);
|
||||
|
||||
void start_incomplete();
|
||||
|
||||
public:
|
||||
api_error allocate(const std::uint64_t &handle, filesystem_item &fsi, const std::uint64_t &size,
|
||||
const i_download::allocator_callback &allocator) override;
|
||||
|
||||
bool contains_restore(const std::string &api_path) const override;
|
||||
|
||||
api_error download_file(const std::uint64_t &handle, filesystem_item &fsi) override;
|
||||
|
||||
std::size_t get_download_count() const { return download_lookup_.size(); }
|
||||
|
||||
std::string get_source_path(const std::string &api_path) const;
|
||||
|
||||
bool is_processing(const std::string &api_path) const override;
|
||||
|
||||
bool pause_download(const std::string &api_path) override;
|
||||
|
||||
api_error read_bytes(const std::uint64_t &handle, filesystem_item &fsi, std::size_t read_size,
|
||||
const std::uint64_t &read_offset, std::vector<char> &data) override;
|
||||
|
||||
void rename_download(const std::string &from_api_path, const std::string &to_api_path) override;
|
||||
|
||||
api_error resize(const std::uint64_t &handle, filesystem_item &fsi,
|
||||
const std::uint64_t &size) override;
|
||||
|
||||
void resume_download(const std::string &api_path) override;
|
||||
|
||||
void start(i_open_file_table *oft);
|
||||
|
||||
void stop();
|
||||
|
||||
api_error write_bytes(const std::uint64_t &handle, filesystem_item &fsi,
|
||||
const std::uint64_t &write_offset, std::vector<char> data,
|
||||
std::size_t &bytes_written) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_DOWNLOAD_MANAGER_HPP_
|
85
include/download/events.hpp
Normal file
85
include/download/events.hpp
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_EVENTS_HPP_
|
||||
#define INCLUDE_DOWNLOAD_EVENTS_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE2(download_begin, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(download_end, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING,
|
||||
std::uint64_t, handle, handle, E_FROM_UINT64,
|
||||
api_error, result, result, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_paused, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_progress, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING,
|
||||
double, progress, prog, E_DOUBLE_PRECISE
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_restored, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_restore_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_resumed, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_stored, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_store_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_timeout, warn, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, dest_path, dest, E_STRING
|
||||
);
|
||||
// clang-format on
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_EVENTS_HPP_
|
76
include/download/i_download.hpp
Normal file
76
include/download/i_download.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_I_DOWNLOAD_HPP_
|
||||
#define INCLUDE_DOWNLOAD_I_DOWNLOAD_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_download {
|
||||
INTERFACE_SETUP(i_download);
|
||||
|
||||
public:
|
||||
typedef std::function<api_error()> allocator_callback;
|
||||
|
||||
typedef std::function<void(std::uint64_t old_size, std::uint64_t new_size, bool changed)>
|
||||
completer_callback;
|
||||
|
||||
public:
|
||||
virtual api_error allocate(const std::uint64_t &handle, const std::uint64_t &size,
|
||||
const allocator_callback &allocator,
|
||||
const completer_callback &completer) = 0;
|
||||
|
||||
virtual api_error download_all() = 0;
|
||||
|
||||
virtual api_error get_result() const = 0;
|
||||
|
||||
virtual std::string get_source_path() const = 0;
|
||||
|
||||
virtual void get_state_information(filesystem_item &fsi, std::size_t &chunk_size,
|
||||
std::size_t &last_chunk_size,
|
||||
boost::dynamic_bitset<> &read_state,
|
||||
boost::dynamic_bitset<> &write_state) = 0;
|
||||
|
||||
virtual bool get_write_supported() const = 0;
|
||||
|
||||
virtual void notify_stop_requested() = 0;
|
||||
|
||||
virtual bool pause() = 0;
|
||||
|
||||
virtual api_error read_bytes(const std::uint64_t &handle, std::size_t read_size,
|
||||
const std::uint64_t &read_offset, std::vector<char> &data) = 0;
|
||||
|
||||
virtual void reset_timeout(const bool &file_closed) = 0;
|
||||
|
||||
virtual void resume() = 0;
|
||||
|
||||
virtual void set_api_path(const std::string &api_path) = 0;
|
||||
|
||||
virtual void set_disable_download_end(const bool &disable) = 0;
|
||||
|
||||
virtual api_error write_bytes(const std::uint64_t &handle, const std::uint64_t &write_offset,
|
||||
std::vector<char> data, std::size_t &bytes_written,
|
||||
const completer_callback &completer) = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<i_download> download_ptr;
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_I_DOWNLOAD_HPP_
|
61
include/download/i_download_manager.hpp
Normal file
61
include/download/i_download_manager.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_I_DOWNLOAD_MANAGER_HPP_
|
||||
#define INCLUDE_DOWNLOAD_I_DOWNLOAD_MANAGER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "download/i_download.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_download_manager {
|
||||
INTERFACE_SETUP(i_download_manager);
|
||||
|
||||
public:
|
||||
virtual api_error allocate(const std::uint64_t &handle, filesystem_item &fsi,
|
||||
const std::uint64_t &size,
|
||||
const i_download::allocator_callback &allocator) = 0;
|
||||
|
||||
virtual bool contains_restore(const std::string &api_path) const = 0;
|
||||
|
||||
virtual api_error download_file(const std::uint64_t &handle, filesystem_item &fsi) = 0;
|
||||
|
||||
virtual bool is_processing(const std::string &api_path) const = 0;
|
||||
|
||||
virtual bool pause_download(const std::string &api_path) = 0;
|
||||
|
||||
virtual api_error read_bytes(const std::uint64_t &handle, filesystem_item &fsi,
|
||||
std::size_t read_size, const std::uint64_t &read_offset,
|
||||
std::vector<char> &data) = 0;
|
||||
|
||||
virtual void rename_download(const std::string &from_api_path,
|
||||
const std::string &to_api_path) = 0;
|
||||
|
||||
virtual api_error resize(const std::uint64_t &handle, filesystem_item &fsi,
|
||||
const std::uint64_t &size) = 0;
|
||||
|
||||
virtual void resume_download(const std::string &api_path) = 0;
|
||||
|
||||
virtual api_error write_bytes(const std::uint64_t &handle, filesystem_item &fsi,
|
||||
const std::uint64_t &write_offset, std::vector<char> data,
|
||||
std::size_t &bytes_written) = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_I_DOWNLOAD_MANAGER_HPP_
|
87
include/download/reader_pool.hpp
Normal file
87
include/download/reader_pool.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_READER_POOL_HPP_
|
||||
#define INCLUDE_DOWNLOAD_READER_POOL_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class reader_pool final {
|
||||
public:
|
||||
typedef std::function<void(api_error error)> completed_callback;
|
||||
|
||||
private:
|
||||
struct pool_work_item {
|
||||
pool_work_item(std::string api_path, const std::size_t &read_size,
|
||||
const std::uint64_t &read_offset, std::vector<char> &data,
|
||||
completed_callback completed)
|
||||
: api_path(std::move(api_path)), read_size(read_size), read_offset(read_offset), data(data),
|
||||
completed(completed) {}
|
||||
|
||||
std::string api_path;
|
||||
std::size_t read_size;
|
||||
std::uint64_t read_offset;
|
||||
std::vector<char> &data;
|
||||
completed_callback completed;
|
||||
};
|
||||
|
||||
public:
|
||||
reader_pool(const std::size_t &pool_size, const api_reader_callback &api_reader)
|
||||
: pool_size_(pool_size), api_reader_(api_reader) {
|
||||
start();
|
||||
}
|
||||
|
||||
~reader_pool() { stop(); }
|
||||
|
||||
private:
|
||||
const std::size_t pool_size_;
|
||||
const api_reader_callback &api_reader_;
|
||||
bool paused_ = false;
|
||||
bool restart_active_ = false;
|
||||
bool stop_requested_ = false;
|
||||
std::mutex work_mutex_;
|
||||
std::condition_variable work_notify_;
|
||||
std::deque<std::shared_ptr<pool_work_item>> work_queue_;
|
||||
std::vector<std::thread> work_threads_;
|
||||
std::uint16_t active_count_ = 0u;
|
||||
|
||||
private:
|
||||
void process_work_item(pool_work_item &work);
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
|
||||
void wait_for_resume(unique_mutex_lock &lock);
|
||||
|
||||
public:
|
||||
void pause();
|
||||
|
||||
void queue_read_bytes(const std::string &api_path, const std::size_t &read_size,
|
||||
const std::uint64_t &read_offset, std::vector<char> &data,
|
||||
completed_callback completed);
|
||||
|
||||
void restart();
|
||||
|
||||
void resume();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_READER_POOL_HPP_
|
136
include/download/ring_download.hpp
Normal file
136
include/download/ring_download.hpp
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_RING_DOWNLOAD_HPP_
|
||||
#define INCLUDE_DOWNLOAD_RING_DOWNLOAD_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "download/i_download.hpp"
|
||||
#include "utils/native_file.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class buffered_reader;
|
||||
class app_config;
|
||||
class ring_download final : public virtual i_download {
|
||||
private:
|
||||
struct io_action {
|
||||
io_action(std::mutex &mtx, std::condition_variable &cv, std::function<void()> action)
|
||||
: mutex(mtx), notify(cv), action(action) {}
|
||||
|
||||
std::mutex &mutex;
|
||||
std::condition_variable ¬ify;
|
||||
std::function<void()> action;
|
||||
};
|
||||
|
||||
public:
|
||||
ring_download(const app_config &config, filesystem_item fsi,
|
||||
const api_reader_callback &api_reader, const std::uint64_t &handle,
|
||||
const std::size_t &chunk_size, const std::size_t &ring_buffer_size);
|
||||
|
||||
~ring_download() override;
|
||||
|
||||
private:
|
||||
const app_config &config_;
|
||||
const filesystem_item fsi_;
|
||||
const api_reader_callback &api_reader_;
|
||||
const std::uint64_t handle_;
|
||||
const std::size_t chunk_size_;
|
||||
boost::dynamic_bitset<> ring_state_;
|
||||
const std::size_t total_chunks_ = 0u;
|
||||
|
||||
api_error error_ = api_error::success;
|
||||
native_file_ptr buffer_file_;
|
||||
std::string buffer_file_path_;
|
||||
buffered_reader *buffered_reader_ = nullptr;
|
||||
bool disable_download_end_ = false;
|
||||
std::size_t head_chunk_index_ = 0ull;
|
||||
std::mutex io_mutex_;
|
||||
std::condition_variable io_notify_;
|
||||
std::deque<std::unique_ptr<io_action>> io_queue_;
|
||||
std::unique_ptr<std::thread> io_thread_;
|
||||
std::size_t read_chunk_ = 0ull;
|
||||
std::unique_ptr<std::thread> buffer_thread_;
|
||||
std::mutex read_mutex_;
|
||||
std::condition_variable read_notify_;
|
||||
bool stop_requested_ = false;
|
||||
std::size_t write_chunk_ = 0ull;
|
||||
std::mutex write_mutex_;
|
||||
|
||||
private:
|
||||
void buffer_thread(std::size_t start_chunk_index);
|
||||
|
||||
void io_thread();
|
||||
|
||||
bool is_active() const { return not stop_requested_ && (error_ == api_error::success); }
|
||||
|
||||
bool queue_io_item(std::mutex &m, std::condition_variable &cv, const bool &is_read,
|
||||
std::function<void()> action);
|
||||
|
||||
void read(std::size_t read_chunk_index, std::size_t read_size, std::size_t read_offset,
|
||||
std::vector<char> &data);
|
||||
|
||||
void set_api_error(const api_error &error);
|
||||
|
||||
void start(const std::size_t &start_chunk_index);
|
||||
|
||||
void stop();
|
||||
|
||||
public:
|
||||
api_error allocate(const std::uint64_t & /*handle*/, const std::uint64_t & /*size*/,
|
||||
const allocator_callback & /*allocator*/,
|
||||
const completer_callback & /*completer*/) override {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
api_error download_all() override { return api_error::not_implemented; }
|
||||
|
||||
api_error get_result() const override { return error_; }
|
||||
|
||||
std::string get_source_path() const override { return buffer_file_path_; }
|
||||
|
||||
void get_state_information(filesystem_item &, std::size_t &, std::size_t &,
|
||||
boost::dynamic_bitset<> &, boost::dynamic_bitset<> &) override {}
|
||||
|
||||
bool get_write_supported() const override { return false; }
|
||||
|
||||
void notify_stop_requested() override;
|
||||
|
||||
bool pause() override { return false; }
|
||||
|
||||
api_error read_bytes(const std::uint64_t &, std::size_t read_size,
|
||||
const std::uint64_t &read_offset, std::vector<char> &data) override;
|
||||
|
||||
void reset_timeout(const bool &) override {}
|
||||
|
||||
void resume() override {}
|
||||
|
||||
void set_api_path(const std::string &) override {}
|
||||
|
||||
void set_disable_download_end(const bool &disable) override { disable_download_end_ = disable; }
|
||||
|
||||
api_error write_bytes(const std::uint64_t &, const std::uint64_t &, std::vector<char>,
|
||||
std::size_t &bytes_written,
|
||||
const completer_callback & /*completer*/) override {
|
||||
bytes_written = 0u;
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_RING_DOWNLOAD_HPP_
|
41
include/download/utils.hpp
Normal file
41
include/download/utils.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DOWNLOAD_UTILS_HPP_
|
||||
#define INCLUDE_DOWNLOAD_UTILS_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
|
||||
namespace repertory::utils::download {
|
||||
template <typename event_type>
|
||||
void notify_progress(const app_config &config, const std::string &api_path,
|
||||
const std::string &source_path, const double ¤t, const double &total,
|
||||
double &progress) {
|
||||
if (config.get_event_level() >= event_type::level) {
|
||||
const double next_progress = (current / total) * 100.0;
|
||||
if ((next_progress == 0.0) || (next_progress >= (progress + 0.2)) ||
|
||||
((next_progress == 100.00) && (next_progress != progress))) {
|
||||
progress = next_progress;
|
||||
event_system::instance().raise<event_type>(api_path, source_path, progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace repertory::utils::download
|
||||
|
||||
#endif // INCLUDE_DOWNLOAD_UTILS_HPP_
|
68
include/drives/directory_cache.hpp
Normal file
68
include/drives/directory_cache.hpp
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_DIRECTORY_CACHE_HPP_
|
||||
#define INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class directory_iterator;
|
||||
|
||||
class directory_cache final {
|
||||
public:
|
||||
typedef std::function<void(directory_iterator &iterator)> execute_callback;
|
||||
|
||||
private:
|
||||
struct open_directory {
|
||||
directory_iterator *iterator;
|
||||
std::chrono::system_clock::time_point last_update = std::chrono::system_clock::now();
|
||||
};
|
||||
|
||||
public:
|
||||
directory_cache() = default;
|
||||
|
||||
~directory_cache() { stop(); }
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, open_directory> directory_lookup_;
|
||||
std::recursive_mutex directory_mutex_;
|
||||
bool is_shutdown_ = true;
|
||||
std::unique_ptr<std::thread> refresh_thread_;
|
||||
std::mutex shutdown_mutex_;
|
||||
std::condition_variable shutdown_notify_;
|
||||
|
||||
private:
|
||||
void refresh_thread();
|
||||
|
||||
public:
|
||||
bool execute_action(const std::string &api_path, const execute_callback &execute);
|
||||
|
||||
directory_iterator *remove_directory(const std::string &api_path);
|
||||
|
||||
void remove_directory(directory_iterator *iterator);
|
||||
|
||||
void set_directory(const std::string &api_path, directory_iterator *iterator);
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_
|
71
include/drives/directory_iterator.hpp
Normal file
71
include/drives/directory_iterator.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_DIRECTORY_ITERATOR_HPP_
|
||||
#define INCLUDE_DRIVES_DIRECTORY_ITERATOR_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/remote.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class directory_iterator final {
|
||||
public:
|
||||
#ifndef _WIN32
|
||||
typedef std::function<void(const std::string &api_path, const std::uint64_t &file_size,
|
||||
const api_meta_map &meta, const bool &directory, struct stat *st)>
|
||||
populate_stat_callback;
|
||||
#endif
|
||||
public:
|
||||
explicit directory_iterator(directory_item_list list) : items_(std::move(list)) {}
|
||||
|
||||
directory_iterator(const directory_iterator &iterator) noexcept : items_(iterator.items_) {}
|
||||
|
||||
directory_iterator(directory_iterator &&iterator) noexcept : items_(std::move(iterator.items_)) {}
|
||||
|
||||
private:
|
||||
directory_item_list items_;
|
||||
|
||||
public:
|
||||
#ifndef _WIN32
|
||||
int fill_buffer(const remote::file_offset &offset, fuse_fill_dir_t filler_function, void *buffer,
|
||||
populate_stat_callback populate_stat);
|
||||
#endif
|
||||
|
||||
int get(const std::size_t &offset, std::string &item);
|
||||
|
||||
std::size_t get_count() const { return items_.size(); }
|
||||
|
||||
api_error get_directory_item(const std::size_t &offset, directory_item &di);
|
||||
|
||||
api_error get_directory_item(const std::string &api_path, directory_item &di);
|
||||
|
||||
int get_json(const std::size_t &offset, json &item);
|
||||
|
||||
std::size_t get_next_directory_offset(const std::string &api_path) const;
|
||||
|
||||
public:
|
||||
directory_iterator &operator=(const directory_iterator &iterator) noexcept;
|
||||
|
||||
directory_iterator &operator=(directory_iterator &&iterator) noexcept;
|
||||
|
||||
directory_iterator &operator=(directory_item_list list) noexcept;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_DIRECTORY_ITERATOR_HPP_
|
59
include/drives/eviction.hpp
Normal file
59
include/drives/eviction.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_EVICTION_HPP_
|
||||
#define INCLUDE_DRIVES_EVICTION_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class i_open_file_table;
|
||||
class i_provider;
|
||||
class eviction final {
|
||||
public:
|
||||
eviction(i_provider &provider, const app_config &config, i_open_file_table &oft)
|
||||
: provider_(provider), config_(config), oft_(oft) {}
|
||||
|
||||
~eviction() = default;
|
||||
|
||||
private:
|
||||
i_provider &provider_;
|
||||
const app_config &config_;
|
||||
i_open_file_table &oft_;
|
||||
bool stop_requested_ = false;
|
||||
std::mutex start_stop_mutex_;
|
||||
std::condition_variable stop_notify_;
|
||||
std::unique_ptr<std::thread> eviction_thread_;
|
||||
std::mutex eviction_mutex_;
|
||||
|
||||
private:
|
||||
void check_items_thread();
|
||||
|
||||
bool check_minimum_requirements(const std::string &file_path);
|
||||
|
||||
std::deque<std::string> get_filtered_cached_files();
|
||||
|
||||
public:
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_EVICTION_HPP_
|
39
include/drives/fuse/events.hpp
Normal file
39
include/drives/fuse/events.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_FUSE_EVENTS_HPP_
|
||||
#define INCLUDE_DRIVES_FUSE_EVENTS_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE3(fuse_event, debug, true,
|
||||
std::string, function, func, E_STRING,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
int, result, res, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE1(fuse_args_parsed, normal, true,
|
||||
std::string, arguments, args, E_STRING
|
||||
);
|
||||
// clang-format on
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_FUSE_EVENTS_HPP_
|
506
include/drives/fuse/fuse_base.hpp
Normal file
506
include/drives/fuse/fuse_base.hpp
Normal file
@ -0,0 +1,506 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_FUSE_FUSE_BASE_HPP_
|
||||
#define INCLUDE_DRIVES_FUSE_FUSE_BASE_HPP_
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "drives/fuse/i_fuse_drive.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class i_provider;
|
||||
|
||||
class fuse_base : public i_fuse_drive {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
explicit fuse_base(app_config &config_);
|
||||
|
||||
virtual ~fuse_base();
|
||||
|
||||
protected:
|
||||
app_config &config_;
|
||||
|
||||
private:
|
||||
std::string mount_location_;
|
||||
|
||||
protected:
|
||||
bool atime_enabled_ = true;
|
||||
bool console_enabled_ = false;
|
||||
std::optional<gid_t> forced_gid_;
|
||||
std::optional<uid_t> forced_uid_;
|
||||
std::optional<mode_t> forced_umask_;
|
||||
|
||||
private:
|
||||
static fuse_base &instance();
|
||||
|
||||
private:
|
||||
// clang-format off
|
||||
struct fuse_operations fuse_ops_ {
|
||||
.getattr = fuse_base::getattr_,
|
||||
.readlink = nullptr, // int (*readlink) (const char *, char *, size_t);
|
||||
.getdir = nullptr, // int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
|
||||
.mknod = nullptr, // int (*mknod) (const char *, mode_t, dev_t);
|
||||
.mkdir = fuse_base::mkdir_,
|
||||
.unlink = fuse_base::unlink_,
|
||||
.rmdir = fuse_base::rmdir_,
|
||||
.symlink = nullptr, // int (*symlink) (const char *, const char *);
|
||||
.rename = fuse_base::rename_,
|
||||
.link = nullptr, // int (*link) (const char *, const char *);
|
||||
.chmod = fuse_base::chmod_,
|
||||
.chown = fuse_base::chown_,
|
||||
.truncate = fuse_base::truncate_,
|
||||
.utime = nullptr, // int (*utime) (const char *, struct utimbuf *);
|
||||
.open = fuse_base::open_,
|
||||
.read = fuse_base::read_,
|
||||
.write = fuse_base::write_,
|
||||
#ifdef __APPLE__
|
||||
.statfs = nullptr,
|
||||
#else // __APPLE__
|
||||
.statfs = fuse_base::statfs_,
|
||||
#endif // __APPLE__
|
||||
.flush = nullptr, // int (*flush) (const char *, struct fuse_file_info *);
|
||||
.release = fuse_base::release_,
|
||||
.fsync = fuse_base::fsync_,
|
||||
#if HAS_SETXATTR
|
||||
.setxattr = fuse_base::setxattr_,
|
||||
.getxattr = fuse_base::getxattr_,
|
||||
.listxattr = fuse_base::listxattr_,
|
||||
.removexattr = fuse_base::removexattr_,
|
||||
#else // HAS_SETXATTR
|
||||
.setxattr = nullptr,
|
||||
.getxattr = nullptr,
|
||||
.listxattr = nullptr,
|
||||
.removexattr = nullptr,
|
||||
#endif // HAS_SETXATTR
|
||||
.opendir = fuse_base::opendir_,
|
||||
.readdir = fuse_base::readdir_,
|
||||
.releasedir = fuse_base::releasedir_,
|
||||
.fsyncdir = nullptr, // int (*fsyncdir) (const char *, int, struct fuse_file_info *);
|
||||
.init = fuse_base::init_,
|
||||
.destroy = fuse_base::destroy_,
|
||||
.access = fuse_base::access_,
|
||||
.create = fuse_base::create_,
|
||||
.ftruncate = fuse_base::ftruncate_,
|
||||
.fgetattr = fuse_base::fgetattr_,
|
||||
.lock = nullptr, // int (*lock) (const char *, struct fuse_file_info *, int cmd, struct flock *);
|
||||
.utimens = fuse_base::utimens_,
|
||||
.bmap = nullptr, // int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
|
||||
.flag_nullpath_ok = 0,
|
||||
.flag_nopath = 0,
|
||||
.flag_utime_omit_ok = 1,
|
||||
.flag_reserved = 0,
|
||||
.ioctl = nullptr, // int (*ioctl) (const char *, int cmd, void *arg, struct fuse_file_info *, unsigned int flags, void *data);
|
||||
.poll = nullptr, // int (*poll) (const char *, struct fuse_file_info *, struct fuse_pollhandle *ph, unsigned *reventsp);
|
||||
.write_buf = nullptr, // int (*write_buf) (const char *, struct fuse_bufvec *buf, off_t off, struct fuse_file_info *);
|
||||
.read_buf = nullptr, // int (*read_buf) (const char *, struct fuse_bufvec **bufp, size_t size, off_t off, struct fuse_file_info *);
|
||||
.flock = nullptr, // int (*flock) (const char *, struct fuse_file_info *, int op);
|
||||
.fallocate = fuse_base::fallocate_
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
int execute_callback(const std::string &function_name, const char *from, const char *to,
|
||||
const std::function<api_error(const std::string &, const std::string &)> &cb,
|
||||
const bool &disable_logging = false);
|
||||
|
||||
int execute_callback(const std::string &function_name, const char *path,
|
||||
const std::function<api_error(const std::string &)> &cb,
|
||||
const bool &disable_logging = false);
|
||||
|
||||
static void execute_void_callback(const std::string &function_name,
|
||||
const std::function<void()> &cb);
|
||||
|
||||
static void *execute_void_pointer_callback(const std::string &function_name,
|
||||
const std::function<void *()> &cb);
|
||||
|
||||
void raise_fuse_event(std::string function_name, const std::string &api_file, const int &ret,
|
||||
const bool &disable_logging);
|
||||
|
||||
private:
|
||||
static int access_(const char *path, int mask);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static int chflags_(const char *path, uint32_t flags);
|
||||
#endif // __APPLE__
|
||||
|
||||
static int chmod_(const char *path, mode_t mode);
|
||||
|
||||
static int chown_(const char *path, uid_t uid, gid_t gid);
|
||||
|
||||
static int create_(const char *path, mode_t mode, struct fuse_file_info *fi);
|
||||
|
||||
static void destroy_(void *ptr);
|
||||
|
||||
static int fallocate_(const char *path, int mode, off_t offset, off_t length,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
static int fgetattr_(const char *path, struct stat *st, struct fuse_file_info *fi);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static int fsetattr_x_(const char *path, struct setattr_x *attr, struct fuse_file_info *fi);
|
||||
#endif // __APPLE__
|
||||
|
||||
static int fsync_(const char *path, int datasync, struct fuse_file_info *fi);
|
||||
|
||||
static int ftruncate_(const char *path, off_t size, struct fuse_file_info *fi);
|
||||
|
||||
static int getattr_(const char *path, struct stat *st);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static int getxtimes_(const char *path, struct timespec *bkuptime, struct timespec *crtime);
|
||||
#endif // __APPLE__
|
||||
|
||||
static void *init_(struct fuse_conn_info *conn);
|
||||
|
||||
static int mkdir_(const char *path, mode_t mode);
|
||||
|
||||
static int open_(const char *path, struct fuse_file_info *fi);
|
||||
|
||||
static int opendir_(const char *path, struct fuse_file_info *fi);
|
||||
|
||||
static int read_(const char *path, char *buffer, size_t read_size, off_t read_offset,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
static int readdir_(const char *path, void *buf, fuse_fill_dir_t fuse_fill_dir, off_t offset,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
static int release_(const char *path, struct fuse_file_info *fi);
|
||||
|
||||
static int releasedir_(const char *path, struct fuse_file_info *fi);
|
||||
|
||||
static int rename_(const char *from, const char *to);
|
||||
|
||||
static int rmdir_(const char *path);
|
||||
|
||||
#ifdef HAS_SETXATTR
|
||||
#ifdef __APPLE__
|
||||
static int getxattr_(const char *path, const char *name, char *value, size_t size,
|
||||
uint32_t position);
|
||||
|
||||
#else // __APPLE__
|
||||
static int getxattr_(const char *path, const char *name, char *value, size_t size);
|
||||
#endif // __APPLE__
|
||||
|
||||
static int listxattr_(const char *path, char *buffer, size_t size);
|
||||
|
||||
static int removexattr_(const char *path, const char *name);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static int setxattr_(const char *path, const char *name, const char *value, size_t size,
|
||||
int flags, uint32_t position);
|
||||
|
||||
#else // __APPLE__
|
||||
static int setxattr_(const char *path, const char *name, const char *value, size_t size,
|
||||
int flags);
|
||||
#endif // __APPLE__
|
||||
#endif // HAS_SETXATTR
|
||||
|
||||
#ifdef __APPLE__
|
||||
static int setattr_x_(const char *path, struct setattr_x *attr);
|
||||
|
||||
static int setbkuptime_(const char *path, const struct timespec *bkuptime);
|
||||
|
||||
static int setchgtime_(const char *path, const struct timespec *chgtime);
|
||||
|
||||
static int setcrtime_(const char *path, const struct timespec *crtime);
|
||||
|
||||
static int setvolname_(const char *volname);
|
||||
|
||||
static int statfs_x_(const char *path, struct statfs *stbuf);
|
||||
|
||||
#else // __APPLE__
|
||||
static int statfs_(const char *path, struct statvfs *stbuf);
|
||||
#endif // __APPLE__
|
||||
|
||||
static int truncate_(const char *path, off_t size);
|
||||
|
||||
static int unlink_(const char *path);
|
||||
|
||||
static int utimens_(const char *path, const struct timespec tv[2]);
|
||||
|
||||
static int write_(const char *path, const char *buffer, size_t write_size, off_t write_offset,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
protected:
|
||||
api_error check_access(const std::string &api_path, int mask) const;
|
||||
|
||||
api_error check_and_perform(const std::string &api_path, int parent_mask,
|
||||
const std::function<api_error(api_meta_map &meta)> &action);
|
||||
|
||||
uid_t get_effective_uid() const;
|
||||
|
||||
gid_t get_effective_gid() const;
|
||||
|
||||
static api_error check_open_flags(const int &flags, const int &mask, const api_error &fail_error);
|
||||
|
||||
api_error check_owner(const api_meta_map &meta) const;
|
||||
|
||||
static api_error check_readable(const int &flags, const api_error &fail_error);
|
||||
|
||||
static api_error check_writeable(const int &flags, const api_error &fail_error);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static __uint32_t get_flags_from_meta(const api_meta_map &meta);
|
||||
#endif // __APPLE__
|
||||
|
||||
static gid_t get_gid_from_meta(const api_meta_map &meta);
|
||||
|
||||
static mode_t get_mode_from_meta(const api_meta_map &meta);
|
||||
|
||||
static void get_timespec_from_meta(const api_meta_map &meta, const std::string &name,
|
||||
struct timespec &ts);
|
||||
|
||||
static uid_t get_uid_from_meta(const api_meta_map &meta);
|
||||
|
||||
static void populate_stat(const std::string &api_path, const std::uint64_t &size_or_count,
|
||||
const api_meta_map &meta, const bool &directory, i_provider &provider,
|
||||
struct stat *st);
|
||||
|
||||
static void set_timespec_from_meta(const api_meta_map &meta, const std::string &name,
|
||||
struct timespec &ts);
|
||||
|
||||
protected:
|
||||
virtual api_error access_impl(std::string api_path, int mask) {
|
||||
return check_access(api_path, mask);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
virtual api_error chflags_impl(std::string /*api_path*/, uint32_t /*flags*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
virtual api_error chmod_impl(std::string /*api_path*/, mode_t /*mode*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error chown_impl(std::string /*api_path*/, uid_t /*uid*/, gid_t /*gid*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error create_impl(std::string /*api_path*/, mode_t /*mode*/,
|
||||
struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual void destroy_impl(void * /*ptr*/) { return; }
|
||||
|
||||
virtual api_error fallocate_impl(std::string /*api_path*/, int /*mode*/, off_t /*offset*/,
|
||||
off_t /*length*/, struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error fgetattr_impl(std::string /*api_path*/, struct stat * /*st*/,
|
||||
struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error fsetattr_x_impl(std::string /*api_path*/, struct setattr_x * /*attr*/,
|
||||
struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error fsync_impl(std::string /*api_path*/, int /*datasync*/,
|
||||
struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error ftruncate_impl(std::string /*api_path*/, off_t /*size*/,
|
||||
struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error getattr_impl(std::string /*api_path*/, struct stat * /*st*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
virtual api_error getxtimes_impl(std::string /*api_path*/, struct timespec * /*bkuptime*/,
|
||||
struct timespec * /*crtime*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
virtual void *init_impl(struct fuse_conn_info *conn);
|
||||
|
||||
virtual api_error mkdir_impl(std::string /*api_path*/, mode_t /*mode*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error open_impl(std::string /*api_path*/, struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error opendir_impl(std::string /*api_path*/, struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error read_impl(std::string /*api_path*/, char * /*buffer*/, size_t /*read_size*/,
|
||||
off_t /*read_offset*/, struct fuse_file_info * /*fi*/,
|
||||
std::size_t & /*bytes_read*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error readdir_impl(std::string /*api_path*/, void * /*buf*/,
|
||||
fuse_fill_dir_t /*fuse_fill_dir*/, off_t /*offset*/,
|
||||
struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error release_impl(std::string /*api_path*/, struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error releasedir_impl(std::string /*api_path*/, struct fuse_file_info * /*fi*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error rename_impl(std::string /*from_api_path*/, std::string /*to_api_path*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error rmdir_impl(std::string /*api_path*/) { return api_error::not_implemented; }
|
||||
|
||||
#ifdef HAS_SETXATTR
|
||||
#ifdef __APPLE__
|
||||
virtual api_error getxattr_impl(std::string /*api_path*/, const char * /*name*/, char * /*value*/,
|
||||
size_t /*size*/, uint32_t /*position*/,
|
||||
int & /*attribute_size*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
#else // __APPLE__
|
||||
virtual api_error getxattr_impl(std::string /*api_path*/, const char * /*name*/, char * /*value*/,
|
||||
size_t /*size*/, int & /*attribute_size*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
virtual api_error listxattr_impl(std::string /*api_path*/, char * /*buffer*/, size_t /*size*/,
|
||||
int & /*required_size*/, bool & /*return_size*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error removexattr_impl(std::string /*api_path*/, const char * /*name*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
virtual api_error setxattr_impl(std::string /*api_path*/, const char * /*name*/,
|
||||
const char * /*value*/, size_t /*size*/, int /*flags*/,
|
||||
uint32_t /*position*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
#else // __APPLE__
|
||||
virtual api_error setxattr_impl(std::string /*api_path*/, const char * /*name*/,
|
||||
const char * /*value*/, size_t /*size*/, int /*flags*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
#endif // __APPLE__
|
||||
#endif // HAS_SETXATTR
|
||||
|
||||
#ifdef __APPLE__
|
||||
virtual api_error setattr_x_impl(std::string /*api_path*/, struct setattr_x * /*attr*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error setbkuptime_impl(std::string /*api_path*/,
|
||||
const struct timespec * /*bkuptime*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error setchgtime_impl(std::string /*api_path*/, const struct timespec * /*chgtime*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error setcrtime_impl(std::string /*api_path*/, const struct timespec * /*crtime*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error setvolname_impl(const char * /*volname*/) { return api_error::not_implemented; }
|
||||
|
||||
virtual api_error statfs_x_impl(std::string /*api_path*/, struct statfs * /*stbuf*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
#else // __APPLE__
|
||||
virtual api_error statfs_impl(std::string /*api_path*/, struct statvfs * /*stbuf*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
virtual api_error truncate_impl(std::string /*api_path*/, off_t /*size*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error unlink_impl(std::string /*api_path*/) { return api_error::not_implemented; }
|
||||
|
||||
virtual api_error utimens_impl(std::string /*api_path*/, const struct timespec /*tv*/[2]) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual api_error write_impl(std::string /*api_path*/, const char * /*buffer*/,
|
||||
size_t /*write_size*/, off_t /*write_offset*/,
|
||||
struct fuse_file_info * /*fi*/, std::size_t & /*bytes_written*/) {
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void notify_fuse_args_parsed(const std::vector<std::string> & /*args*/) {}
|
||||
|
||||
virtual void notify_fuse_main_exit(int & /*ret*/) {}
|
||||
|
||||
virtual int parse_args(std::vector<std::string> &args);
|
||||
|
||||
#ifdef __APPLE__
|
||||
api_error parse_xattr_parameters(const char *name, const uint32_t &position,
|
||||
std::string &attribute_name, const std::string &api_path);
|
||||
#else
|
||||
api_error parse_xattr_parameters(const char *name, std::string &attribute_name,
|
||||
const std::string &api_path);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
api_error parse_xattr_parameters(const char *name, const char *value, size_t size,
|
||||
const uint32_t &position, std::string &attribute_name,
|
||||
const std::string &api_path);
|
||||
#else
|
||||
api_error parse_xattr_parameters(const char *name, const char *value, size_t size,
|
||||
std::string &attribute_name, const std::string &api_path);
|
||||
#endif
|
||||
|
||||
virtual int shutdown();
|
||||
|
||||
public:
|
||||
static void display_options(int argc, char *argv[]);
|
||||
|
||||
static void display_version_information(int argc, char *argv[]);
|
||||
|
||||
api_error check_parent_access(const std::string &api_path, int mask) const override;
|
||||
|
||||
std::string get_mount_location() const { return mount_location_; }
|
||||
|
||||
int mount(std::vector<std::string> args);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_DRIVES_FUSE_FUSE_BASE_HPP_
|
217
include/drives/fuse/fuse_drive.hpp
Normal file
217
include/drives/fuse/fuse_drive.hpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_FUSE_FUSE_DRIVE_HPP_
|
||||
#define INCLUDE_DRIVES_FUSE_FUSE_DRIVE_HPP_
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "drives/fuse/fuse_base.hpp"
|
||||
#include "drives/open_file_table.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
class app_config;
|
||||
class console_consumer;
|
||||
class directory_cache;
|
||||
class download_manager;
|
||||
class eviction;
|
||||
class full_server;
|
||||
class lock_data;
|
||||
class logging_consumer;
|
||||
namespace remote_fuse {
|
||||
class remote_server;
|
||||
}
|
||||
|
||||
class fuse_drive final : public fuse_base {
|
||||
public:
|
||||
fuse_drive(app_config &config, lock_data &lock_data, i_provider &provider);
|
||||
|
||||
~fuse_drive() override = default;
|
||||
|
||||
private:
|
||||
lock_data &lock_data_;
|
||||
i_provider &provider_;
|
||||
|
||||
std::shared_ptr<console_consumer> console_consumer_;
|
||||
std::shared_ptr<directory_cache> directory_cache_;
|
||||
std::shared_ptr<download_manager> download_manager_;
|
||||
std::shared_ptr<eviction> eviction_;
|
||||
std::shared_ptr<logging_consumer> logging_consumer_;
|
||||
std::shared_ptr<open_file_table<open_file_data>> oft_;
|
||||
std::shared_ptr<remote_fuse::remote_server> remote_server_;
|
||||
std::shared_ptr<full_server> server_;
|
||||
bool was_mounted_ = false;
|
||||
|
||||
protected:
|
||||
#ifdef __APPLE__
|
||||
api_error chflags_impl(std::string api_path, uint32_t flags) override;
|
||||
#endif // __APPLE__
|
||||
|
||||
api_error chmod_impl(std::string api_path, mode_t mode) override;
|
||||
|
||||
api_error chown_impl(std::string api_path, uid_t uid, gid_t gid) override;
|
||||
|
||||
api_error create_impl(std::string api_path, mode_t mode, struct fuse_file_info *fi) override;
|
||||
|
||||
void destroy_impl(void *ptr) override;
|
||||
|
||||
api_error fallocate_impl(std::string api_path, int mode, off_t offset, off_t length,
|
||||
struct fuse_file_info *fi) override;
|
||||
|
||||
api_error fgetattr_impl(std::string api_path, struct stat *st,
|
||||
struct fuse_file_info *fi) override;
|
||||
|
||||
#ifdef __APPLE__
|
||||
api_error fsetattr_x_impl(std::string api_path, struct setattr_x *attr,
|
||||
struct fuse_file_info *fi) override;
|
||||
#endif // __APPLE__
|
||||
|
||||
api_error fsync_impl(std::string api_path, int datasync, struct fuse_file_info *fi) override;
|
||||
|
||||
api_error ftruncate_impl(std::string api_path, off_t size, struct fuse_file_info *fi) override;
|
||||
|
||||
api_error getattr_impl(std::string api_path, struct stat *st) override;
|
||||
|
||||
#ifdef __APPLE__
|
||||
api_error getxtimes_impl(std::string api_path, struct timespec *bkuptime,
|
||||
struct timespec *crtime) override;
|
||||
#endif // __APPLE__
|
||||
|
||||
void *init_impl(struct fuse_conn_info *conn) override;
|
||||
|
||||
api_error mkdir_impl(std::string api_path, mode_t mode) override;
|
||||
|
||||
api_error open_impl(std::string api_path, struct fuse_file_info *fi) override;
|
||||
|
||||
api_error opendir_impl(std::string api_path, struct fuse_file_info *fi) override;
|
||||
|
||||
api_error read_impl(std::string api_path, char *buffer, size_t read_size, off_t read_offset,
|
||||
struct fuse_file_info *fi, std::size_t &bytes_read) override;
|
||||
|
||||
api_error readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir,
|
||||
off_t offset, struct fuse_file_info *fi) override;
|
||||
|
||||
api_error release_impl(std::string api_path, struct fuse_file_info *fi) override;
|
||||
|
||||
api_error releasedir_impl(std::string api_path, struct fuse_file_info *fi) override;
|
||||
|
||||
api_error rename_impl(std::string from_api_path, std::string to_api_path) override;
|
||||
|
||||
api_error rmdir_impl(std::string api_path) override;
|
||||
|
||||
#ifdef HAS_SETXATTR
|
||||
api_error getxattr_common(std::string api_path, const char *name, char *value, size_t size,
|
||||
int &attribute_size, uint32_t *position);
|
||||
|
||||
#ifdef __APPLE__
|
||||
api_error getxattr_impl(std::string api_path, const char *name, char *value, size_t size,
|
||||
uint32_t position, int &attribute_size) override;
|
||||
#else // __APPLE__
|
||||
api_error getxattr_impl(std::string api_path, const char *name, char *value, size_t size,
|
||||
int &attribute_size) override;
|
||||
#endif // __APPLE__
|
||||
|
||||
api_error listxattr_impl(std::string api_path, char *buffer, size_t size, int &required_size,
|
||||
bool &return_size) override;
|
||||
|
||||
api_error removexattr_impl(std::string api_path, const char *name) override;
|
||||
|
||||
#ifdef __APPLE__
|
||||
api_error setxattr_impl(std::string api_path, const char *name, const char *value, size_t size,
|
||||
int flags, uint32_t position) override;
|
||||
#else // __APPLE__
|
||||
api_error setxattr_impl(std::string api_path, const char *name, const char *value, size_t size,
|
||||
int flags) override;
|
||||
#endif // __APPLE__
|
||||
#endif // HAS_SETXATTR
|
||||
|
||||
#ifdef __APPLE__
|
||||
api_error setattr_x_impl(std::string api_path, struct setattr_x *attr) override;
|
||||
|
||||
api_error setbkuptime_impl(std::string api_path, const struct timespec *bkuptime) override;
|
||||
|
||||
api_error setchgtime_impl(std::string api_path, const struct timespec *chgtime) override;
|
||||
|
||||
api_error setcrtime_impl(std::string api_path, const struct timespec *crtime) override;
|
||||
|
||||
api_error setvolname_impl(const char *volname) override;
|
||||
|
||||
api_error statfs_x_impl(std::string api_path, struct statfs *stbuf) override;
|
||||
#else // __APPLE__
|
||||
api_error statfs_impl(std::string api_path, struct statvfs *stbuf) override;
|
||||
#endif // __APPLE__
|
||||
|
||||
api_error truncate_impl(std::string api_path, off_t size) override;
|
||||
|
||||
api_error unlink_impl(std::string api_path) override;
|
||||
|
||||
api_error utimens_impl(std::string api_path, const struct timespec tv[2]) override;
|
||||
|
||||
api_error write_impl(std::string api_path, const char *buffer, size_t write_size,
|
||||
off_t write_offset, struct fuse_file_info *fi,
|
||||
std::size_t &bytes_written) override;
|
||||
|
||||
protected:
|
||||
void notify_fuse_args_parsed(const std::vector<std::string> &args) override;
|
||||
|
||||
void notify_fuse_main_exit(int &ret) override;
|
||||
|
||||
int shutdown() override;
|
||||
|
||||
void update_accessed_time(const std::string &api_path);
|
||||
|
||||
public:
|
||||
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
|
||||
|
||||
directory_item_list get_directory_items(const std::string &api_path) const override;
|
||||
|
||||
std::uint64_t get_file_size(const std::string &api_path) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, const std::string &name,
|
||||
std::string &value) const override;
|
||||
|
||||
std::uint64_t get_total_drive_space() const override;
|
||||
|
||||
std::uint64_t get_total_item_count() const override;
|
||||
|
||||
std::uint64_t get_used_drive_space() const override;
|
||||
|
||||
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) const override;
|
||||
|
||||
bool is_processing(const std::string &api_path) const override;
|
||||
|
||||
void populate_stat(const directory_item &di, struct stat &st) const override;
|
||||
|
||||
int rename_directory(const std::string &from_api_path, const std::string &to_api_path) override;
|
||||
|
||||
int rename_file(const std::string &from_api_path, const std::string &to_api_path,
|
||||
const bool &overwrite) override;
|
||||
|
||||
void set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) override;
|
||||
|
||||
void update_directory_item(directory_item &di) const override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_DRIVES_FUSE_FUSE_DRIVE_HPP_
|
71
include/drives/fuse/i_fuse_drive.hpp
Normal file
71
include/drives/fuse/i_fuse_drive.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_FUSE_I_FUSE_DRIVE_HPP_
|
||||
#define INCLUDE_DRIVES_FUSE_I_FUSE_DRIVE_HPP_
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_fuse_drive {
|
||||
INTERFACE_SETUP(i_fuse_drive);
|
||||
|
||||
public:
|
||||
virtual api_error check_parent_access(const std::string &api_path, int mask) const = 0;
|
||||
|
||||
virtual std::uint64_t get_directory_item_count(const std::string &api_path) const = 0;
|
||||
|
||||
virtual directory_item_list get_directory_items(const std::string &api_path) const = 0;
|
||||
|
||||
virtual std::uint64_t get_file_size(const std::string &api_path) const = 0;
|
||||
|
||||
virtual api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const = 0;
|
||||
|
||||
virtual api_error get_item_meta(const std::string &api_path, const std::string &name,
|
||||
std::string &value) const = 0;
|
||||
|
||||
virtual std::uint64_t get_total_drive_space() const = 0;
|
||||
|
||||
virtual std::uint64_t get_total_item_count() const = 0;
|
||||
|
||||
virtual std::uint64_t get_used_drive_space() const = 0;
|
||||
|
||||
virtual void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) const = 0;
|
||||
|
||||
virtual bool is_processing(const std::string &api_path) const = 0;
|
||||
|
||||
virtual void populate_stat(const directory_item &di, struct stat &st) const = 0;
|
||||
|
||||
virtual int rename_directory(const std::string &from_api_path,
|
||||
const std::string &to_api_path) = 0;
|
||||
|
||||
virtual int rename_file(const std::string &from_api_path, const std::string &to_api_path,
|
||||
const bool &overwrite) = 0;
|
||||
|
||||
virtual void set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) = 0;
|
||||
|
||||
virtual void update_directory_item(directory_item &di) const = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif
|
||||
#endif // INCLUDE_DRIVES_FUSE_I_FUSE_DRIVE_HPP_
|
151
include/drives/fuse/remotefuse/i_remote_instance.hpp
Normal file
151
include/drives/fuse/remotefuse/i_remote_instance.hpp
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_FUSE_REMOTEFUSE_I_REMOTE_INSTANCE_HPP_
|
||||
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_I_REMOTE_INSTANCE_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "drives/remote/i_remote_json.hpp"
|
||||
#include "types/remote.hpp"
|
||||
|
||||
namespace repertory::remote_fuse {
|
||||
class i_remote_instance : public virtual i_remote_json {
|
||||
INTERFACE_SETUP(i_remote_instance);
|
||||
|
||||
public:
|
||||
virtual packet::error_type fuse_access(const char *path, const std::int32_t &mask) = 0;
|
||||
|
||||
virtual packet::error_type fuse_chflags(const char *path, const std::uint32_t &flags) = 0;
|
||||
|
||||
virtual packet::error_type fuse_chmod(const char *path, const remote::file_mode &mode) = 0;
|
||||
|
||||
virtual packet::error_type fuse_chown(const char *path, const remote::user_id &uid,
|
||||
const remote::group_id &gid) = 0;
|
||||
|
||||
virtual packet::error_type fuse_create(const char *path, const remote::file_mode &mode,
|
||||
const remote::open_flags &flags,
|
||||
remote::file_handle &handle) = 0;
|
||||
virtual packet::error_type fuse_destroy() = 0;
|
||||
|
||||
/*virtual packet::error_type fuse_fallocate(const char *path, const std::int32_t &mode,
|
||||
const remote::file_offset &offset,
|
||||
const remote::file_offset &length,
|
||||
const remote::file_offset &length,
|
||||
const remote::file_handle &handle) = 0;*/
|
||||
|
||||
virtual packet::error_type fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
|
||||
const remote::file_handle &handle) = 0;
|
||||
|
||||
virtual packet::error_type fuse_fsetattr_x(const char *path, const remote::setattr_x &attr,
|
||||
const remote::file_handle &handle) = 0;
|
||||
|
||||
virtual packet::error_type fuse_fsync(const char *path, const std::int32_t &datasync,
|
||||
const remote::file_handle &handle) = 0;
|
||||
|
||||
virtual packet::error_type fuse_ftruncate(const char *path, const remote::file_offset &size,
|
||||
const remote::file_handle &handle) = 0;
|
||||
|
||||
virtual packet::error_type fuse_getattr(const char *path, remote::stat &st, bool &directory) = 0;
|
||||
|
||||
/*virtual packet::error_type fuse_getxattr(const char *path, const char *name, char *value,
|
||||
const remote::file_size &size) = 0;
|
||||
|
||||
virtual packet::error_type fuse_getxattrOSX(const char *path, const char *name, char *value,
|
||||
const remote::file_size &size,
|
||||
const std::uint32_t &position) = 0;*/
|
||||
|
||||
virtual packet::error_type fuse_getxtimes(const char *path, remote::file_time &bkuptime,
|
||||
remote::file_time &crtime) = 0;
|
||||
|
||||
virtual packet::error_type fuse_init() = 0;
|
||||
|
||||
/*virtual packet::error_type fuse_listxattr(const char *path, char *buffer,
|
||||
const remote::file_size &size) = 0;*/
|
||||
|
||||
virtual packet::error_type fuse_mkdir(const char *path, const remote::file_mode &mode) = 0;
|
||||
|
||||
virtual packet::error_type fuse_open(const char *path, const remote::open_flags &flags,
|
||||
remote::file_handle &handle) = 0;
|
||||
|
||||
virtual packet::error_type fuse_opendir(const char *path, remote::file_handle &handle) = 0;
|
||||
|
||||
virtual packet::error_type fuse_read(const char *path, char *buffer,
|
||||
const remote::file_size &readSize,
|
||||
const remote::file_offset &readOffset,
|
||||
const remote::file_handle &handle) = 0;
|
||||
|
||||
virtual packet::error_type fuse_readdir(const char *path, const remote::file_offset &offset,
|
||||
const remote::file_handle &handle, std::string &itemPath) = 0;
|
||||
|
||||
virtual packet::error_type fuse_release(const char *path, const remote::file_handle &handle) = 0;
|
||||
|
||||
virtual packet::error_type fuse_releasedir(const char *path, const remote::file_handle &handle) = 0;
|
||||
|
||||
// virtual packet::error_type fuse_removexattr(const char *path, const char *name) = 0;
|
||||
|
||||
virtual packet::error_type fuse_rename(const char *from, const char *to) = 0;
|
||||
|
||||
virtual packet::error_type fuse_rmdir(const char *path) = 0;
|
||||
|
||||
virtual packet::error_type fuse_setattr_x(const char *path, remote::setattr_x &attr) = 0;
|
||||
|
||||
virtual packet::error_type fuse_setbkuptime(const char *path, const remote::file_time &bkuptime) = 0;
|
||||
|
||||
virtual packet::error_type fuse_setchgtime(const char *path, const remote::file_time &chgtime) = 0;
|
||||
|
||||
virtual packet::error_type fuse_setcrtime(const char *path, const remote::file_time &crtime) = 0;
|
||||
|
||||
virtual packet::error_type fuse_setvolname(const char *volname) = 0;
|
||||
|
||||
/*virtual packet::error_type fuse_setxattr(const char *path, const char *name,
|
||||
const char *value, const remote::file_size &size,
|
||||
const std::int32_t &flags) = 0;
|
||||
virtual packet::error_type fuse_setxattr_osx(const char *path, const char *name,
|
||||
const char *value, const remote::file_size &size,
|
||||
const std::int32_t &flags,
|
||||
const std::uint32_t &position) = 0;*/
|
||||
|
||||
virtual packet::error_type fuse_statfs(const char *path, const std::uint64_t &frsize,
|
||||
remote::statfs &st) = 0;
|
||||
|
||||
virtual packet::error_type fuse_statfs_x(const char *path, const std::uint64_t &bsize,
|
||||
remote::statfs_x &st) = 0;
|
||||
|
||||
virtual packet::error_type fuse_truncate(const char *path, const remote::file_offset &size) = 0;
|
||||
|
||||
virtual packet::error_type fuse_unlink(const char *path) = 0;
|
||||
|
||||
virtual packet::error_type fuse_utimens(const char *path, const remote::file_time *tv,
|
||||
const std::uint64_t &op0, const std::uint64_t &op1) = 0;
|
||||
|
||||
virtual packet::error_type fuse_write(const char *path, const char *buffer,
|
||||
const remote::file_size &writeSize,
|
||||
const remote::file_offset &writeOffset,
|
||||
const remote::file_handle &handle) = 0;
|
||||
|
||||
virtual packet::error_type fuse_write_base64(const char *path, const char *buffer,
|
||||
const remote::file_size &writeSize,
|
||||
const remote::file_offset &writeOffset,
|
||||
const remote::file_handle &handle) = 0;
|
||||
|
||||
virtual void set_fuse_uid_gid(const remote::user_id &uid, const remote::group_id &gid) = 0;
|
||||
};
|
||||
typedef std::function<std::unique_ptr<i_remote_instance>()> remote_instance_factory;
|
||||
} // namespace repertory::remote_fuse
|
||||
|
||||
#endif // INCLUDE_DRIVES_FUSE_REMOTEFUSE_I_REMOTE_INSTANCE_HPP_
|
172
include/drives/fuse/remotefuse/remote_client.hpp
Normal file
172
include/drives/fuse/remotefuse/remote_client.hpp
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_FUSE_REMOTEFUSE_REMOTE_CLIENT_HPP_
|
||||
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_CLIENT_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/packet/packet_client.hpp"
|
||||
#include "drives/fuse/remotefuse/i_remote_instance.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "types/remote.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
|
||||
namespace remote_fuse {
|
||||
class remote_client final : public i_remote_instance {
|
||||
public:
|
||||
explicit remote_client(const app_config &config);
|
||||
|
||||
private:
|
||||
const app_config &config_;
|
||||
packet_client packet_client_;
|
||||
remote::user_id uid_ = 0;
|
||||
remote::group_id gid_ = 0;
|
||||
|
||||
public:
|
||||
packet::error_type fuse_access(const char *path, const std::int32_t &mask) override;
|
||||
|
||||
packet::error_type fuse_chflags(const char *path, const std::uint32_t &flags) override;
|
||||
|
||||
packet::error_type fuse_chmod(const char *path, const remote::file_mode &mode) override;
|
||||
|
||||
packet::error_type fuse_chown(const char *path, const remote::user_id &uid,
|
||||
const remote::group_id &gid) override;
|
||||
|
||||
packet::error_type fuse_destroy() override;
|
||||
|
||||
/*packet::error_type fuse_fallocate(const char *path, const std::int32_t &mode,
|
||||
const remote::file_offset &offset,
|
||||
const remote::file_offset &length,
|
||||
const remote::file_handle &handle) override ;*/
|
||||
|
||||
packet::error_type fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_fsetattr_x(const char *path, const remote::setattr_x &attr,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_fsync(const char *path, const std::int32_t &datasync,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_ftruncate(const char *path, const remote::file_offset &size,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_getattr(const char *path, remote::stat &st, bool &directory) override;
|
||||
|
||||
/*packet::error_type fuse_getxattr(const char *path, const char *name, char *value,
|
||||
const remote::file_size &size) override ;
|
||||
|
||||
packet::error_type fuse_getxattrOSX(const char *path, const char *name, char *value,
|
||||
const remote::file_size &size,
|
||||
const std::uint32_t &position) override ;*/
|
||||
|
||||
packet::error_type fuse_getxtimes(const char *path, remote::file_time &bkuptime,
|
||||
remote::file_time &crtime) override;
|
||||
|
||||
packet::error_type fuse_init() override;
|
||||
|
||||
/*packet::error_type fuse_listxattr(const char *path, char *buffer,
|
||||
const remote::file_size &size) override ;*/
|
||||
|
||||
packet::error_type fuse_mkdir(const char *path, const remote::file_mode &mode) override;
|
||||
|
||||
packet::error_type fuse_opendir(const char *path, remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_create(const char *path, const remote::file_mode &mode,
|
||||
const remote::open_flags &flags, remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_open(const char *path, const remote::open_flags &flags,
|
||||
remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_read(const char *path, char *buffer, const remote::file_size &read_size,
|
||||
const remote::file_offset &read_offset,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_rename(const char *from, const char *to) override;
|
||||
|
||||
packet::error_type fuse_readdir(const char *path, const remote::file_offset &offset,
|
||||
const remote::file_handle &handle, std::string &item_path) override;
|
||||
|
||||
packet::error_type fuse_release(const char *path, const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_releasedir(const char *path, const remote::file_handle &handle) override;
|
||||
|
||||
/*packet::error_type fuse_removexattr(const char *path, const char *name) override ;*/
|
||||
|
||||
packet::error_type fuse_rmdir(const char *path) override;
|
||||
|
||||
packet::error_type fuse_setattr_x(const char *path, remote::setattr_x &attr) override;
|
||||
|
||||
packet::error_type fuse_setbkuptime(const char *path, const remote::file_time &bkuptime) override;
|
||||
|
||||
packet::error_type fuse_setchgtime(const char *path, const remote::file_time &chgtime) override;
|
||||
|
||||
packet::error_type fuse_setcrtime(const char *path, const remote::file_time &crtime) override;
|
||||
|
||||
packet::error_type fuse_setvolname(const char *volname) override;
|
||||
|
||||
/*packet::error_type fuse_setxattr(const char *path, const char *name, const char *value,
|
||||
const remote::file_size &size,
|
||||
const std::int32_t &flags) override ;
|
||||
|
||||
packet::error_type fuse_setxattr_osx(const char *path, const char *name, const char *value,
|
||||
const remote::file_size &size, const std::int32_t &flags,
|
||||
const std::uint32_t &position) override ;*/
|
||||
|
||||
packet::error_type fuse_statfs(const char *path, const std::uint64_t &frsize,
|
||||
remote::statfs &st) override;
|
||||
|
||||
packet::error_type fuse_statfs_x(const char *path, const std::uint64_t &bsize,
|
||||
remote::statfs_x &st) override;
|
||||
|
||||
packet::error_type fuse_truncate(const char *path, const remote::file_offset &size) override;
|
||||
|
||||
packet::error_type fuse_unlink(const char *path) override;
|
||||
|
||||
packet::error_type fuse_utimens(const char *path, const remote::file_time *tv,
|
||||
const std::uint64_t &op0, const std::uint64_t &op1) override;
|
||||
|
||||
packet::error_type fuse_write(const char *path, const char *buffer,
|
||||
const remote::file_size &write_size,
|
||||
const remote::file_offset &write_offset,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_write_base64(const char *path, const char *buffer,
|
||||
const remote::file_size &write_size,
|
||||
const remote::file_offset &write_offset,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type json_create_directory_snapshot(const std::string &path,
|
||||
json &json_data) override;
|
||||
|
||||
packet::error_type json_read_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle,
|
||||
const std::uint32_t &page,
|
||||
json &json_data) override;
|
||||
|
||||
packet::error_type json_release_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
void set_fuse_uid_gid(const remote::user_id &uid, const remote::group_id &gid) override;
|
||||
};
|
||||
} // namespace remote_fuse
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_CLIENT_HPP_
|
257
include/drives/fuse/remotefuse/remote_fuse_drive.hpp
Normal file
257
include/drives/fuse/remotefuse/remote_fuse_drive.hpp
Normal file
@ -0,0 +1,257 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE_HPP_
|
||||
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE_HPP_
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "drives/fuse/remotefuse/i_remote_instance.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class console_consumer;
|
||||
class logging_consumer;
|
||||
class lock_data;
|
||||
class server;
|
||||
|
||||
namespace remote_fuse {
|
||||
class remote_fuse_drive final {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
remote_fuse_drive(app_config &config, lock_data &lock, remote_instance_factory factory);
|
||||
|
||||
~remote_fuse_drive() { E_CONSUMER_RELEASE(); }
|
||||
|
||||
private:
|
||||
app_config &config_;
|
||||
lock_data &lock_;
|
||||
remote_instance_factory factory_;
|
||||
std::string mount_location_;
|
||||
|
||||
private:
|
||||
static void shutdown(std::string mount_location);
|
||||
|
||||
private:
|
||||
class remote_fuse_impl final {
|
||||
public:
|
||||
static app_config *config_;
|
||||
static lock_data *lock_;
|
||||
static std::string *mount_location_;
|
||||
static remote_instance_factory *factory_;
|
||||
static std::unique_ptr<console_consumer> console_consumer_;
|
||||
static std::unique_ptr<logging_consumer> logging_consumer_;
|
||||
static std::unique_ptr<i_remote_instance> remote_instance_;
|
||||
static std::unique_ptr<server> server_;
|
||||
static std::optional<gid_t> forced_gid_;
|
||||
static std::optional<uid_t> forced_uid_;
|
||||
static std::optional<mode_t> forced_umask_;
|
||||
static bool console_enabled_;
|
||||
static bool was_mounted_;
|
||||
|
||||
public:
|
||||
static void tear_down(const int &ret);
|
||||
|
||||
private:
|
||||
static void populate_stat(const remote::stat &r, const bool &directory, struct stat &st);
|
||||
|
||||
public:
|
||||
static int repertory_access(const char *path, int mask);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static int repertory_chflags(const char *path, uint32_t flags);
|
||||
#endif
|
||||
|
||||
static int repertory_chmod(const char *path, mode_t mode);
|
||||
|
||||
static int repertory_chown(const char *path, uid_t uid, gid_t gid);
|
||||
|
||||
static int repertory_create(const char *path, mode_t mode, struct fuse_file_info *fi);
|
||||
|
||||
static void repertory_destroy(void * /*ptr*/);
|
||||
|
||||
/*static int repertory_fallocate(const char *path, int mode, off_t offset, off_t length,
|
||||
struct fuse_file_info *fi) ;*/
|
||||
|
||||
static int repertory_fgetattr(const char *path, struct stat *st, struct fuse_file_info *fi);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static int repertory_fsetattr_x(const char *path, struct setattr_x *attr,
|
||||
struct fuse_file_info *fi);
|
||||
#endif
|
||||
|
||||
static int repertory_fsync(const char *path, int datasync, struct fuse_file_info *fi);
|
||||
|
||||
static int repertory_ftruncate(const char *path, off_t size, struct fuse_file_info *fi);
|
||||
|
||||
static int repertory_getattr(const char *path, struct stat *st);
|
||||
|
||||
#ifdef __APPLE__
|
||||
static int repertory_getxtimes(const char *path, struct timespec *bkuptime,
|
||||
struct timespec *crtime);
|
||||
#endif
|
||||
|
||||
static void *repertory_init(struct fuse_conn_info *conn);
|
||||
|
||||
static int repertory_mkdir(const char *path, mode_t mode);
|
||||
|
||||
static int repertory_open(const char *path, struct fuse_file_info *fi);
|
||||
|
||||
static int repertory_opendir(const char *path, struct fuse_file_info *fi);
|
||||
|
||||
static int repertory_read(const char *path, char *buffer, size_t readSize, off_t readOffset,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
static int repertory_readdir(const char *path, void *buf, fuse_fill_dir_t fuseFillDir,
|
||||
off_t offset, struct fuse_file_info *fi);
|
||||
|
||||
static int repertory_release(const char *path, struct fuse_file_info *fi);
|
||||
|
||||
static int repertory_releasedir(const char *path, struct fuse_file_info *fi);
|
||||
|
||||
static int repertory_rename(const char *from, const char *to);
|
||||
|
||||
static int repertory_rmdir(const char *path);
|
||||
/*
|
||||
#ifdef HAS_SETXATTR
|
||||
#ifdef __APPLE__
|
||||
static int repertory_getxattr(const char *path, const char *name, char *value, size_t size,
|
||||
uint32_t position) ;
|
||||
#else
|
||||
static int repertory_getxattr(const char *path, const char *name, char *value, size_t size) ;
|
||||
|
||||
#endif
|
||||
static int repertory_listxattr(const char *path, char *buffer, size_t size) ;
|
||||
|
||||
static int repertory_removexattr(const char *path, const char *name) ;
|
||||
#ifdef __APPLE__
|
||||
static int repertory_setxattr(const char *path, const char *name, const char *value,
|
||||
size_t size, int flags, uint32_t position) ;
|
||||
#else
|
||||
static int repertory_setxattr(const char *path, const char *name, const char *value,
|
||||
size_t size, int flags) ;
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
static int repertory_setattr_x(const char *path, struct setattr_x *attr);
|
||||
|
||||
static int repertory_setbkuptime(const char *path, const struct timespec *bkuptime);
|
||||
|
||||
static int repertory_setchgtime(const char *path, const struct timespec *chgtime);
|
||||
|
||||
static int repertory_setcrtime(const char *path, const struct timespec *crtime);
|
||||
|
||||
static int repertory_setvolname(const char *volname);
|
||||
|
||||
static int repertory_statfs_x(const char *path, struct statfs *stbuf);
|
||||
#else
|
||||
|
||||
static int repertory_statfs(const char *path, struct statvfs *stbuf);
|
||||
|
||||
#endif
|
||||
|
||||
static int repertory_truncate(const char *path, off_t size);
|
||||
|
||||
static int repertory_unlink(const char *path);
|
||||
|
||||
static int repertory_utimens(const char *path, const struct timespec tv[2]);
|
||||
|
||||
static int repertory_write(const char *path, const char *buffer, size_t writeSize,
|
||||
off_t writeOffset, struct fuse_file_info *fi);
|
||||
};
|
||||
|
||||
private:
|
||||
// clang-format off
|
||||
struct fuse_operations fuse_ops_ {
|
||||
.getattr = remote_fuse_impl::repertory_getattr,
|
||||
.readlink = nullptr, // int (*readlink) (const char *, char *, size_t);
|
||||
.getdir = nullptr, // int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
|
||||
.mknod = nullptr, // int (*mknod) (const char *, mode_t, dev_t);
|
||||
.mkdir = remote_fuse_impl::repertory_mkdir,
|
||||
.unlink = remote_fuse_impl::repertory_unlink,
|
||||
.rmdir = remote_fuse_impl::repertory_rmdir,
|
||||
.symlink = nullptr, // int (*symlink) (const char *, const char *);
|
||||
.rename = remote_fuse_impl::repertory_rename,
|
||||
.link = nullptr, // int (*link) (const char *, const char *);
|
||||
.chmod = remote_fuse_impl::repertory_chmod,
|
||||
.chown = remote_fuse_impl::repertory_chown,
|
||||
.truncate = remote_fuse_impl::repertory_truncate,
|
||||
.utime = nullptr, // int (*utime) (const char *, struct utimbuf *);
|
||||
.open = remote_fuse_impl::repertory_open,
|
||||
.read = remote_fuse_impl::repertory_read,
|
||||
.write = remote_fuse_impl::repertory_write,
|
||||
#ifdef __APPLE__
|
||||
.statfs = nullptr,
|
||||
#else
|
||||
.statfs = remote_fuse_impl::repertory_statfs,
|
||||
#endif
|
||||
.flush = nullptr, // int (*flush) (const char *, struct fuse_file_info *);
|
||||
.release = remote_fuse_impl::repertory_release,
|
||||
.fsync = remote_fuse_impl::repertory_fsync,
|
||||
#if HAS_SETXATTR
|
||||
.setxattr = nullptr, // remote_fuse_impl::repertory_setxattr,
|
||||
.getxattr = nullptr, // remote_fuse_impl::repertory_getxattr,
|
||||
.listxattr = nullptr, // remote_fuse_impl::repertory_listxattr,
|
||||
.removexattr = nullptr, // remote_fuse_impl::repertory_removexattr,
|
||||
#else
|
||||
.setxattr = nullptr,
|
||||
.getxattr = nullptr,
|
||||
.listxattr = nullptr,
|
||||
.removexattr = nullptr,
|
||||
#endif
|
||||
.opendir = remote_fuse_impl::repertory_opendir,
|
||||
.readdir = remote_fuse_impl::repertory_readdir,
|
||||
.releasedir = remote_fuse_impl::repertory_releasedir,
|
||||
.fsyncdir = nullptr, // int (*fsyncdir) (const char *, int, struct fuse_file_info *);
|
||||
.init = remote_fuse_impl::repertory_init,
|
||||
.destroy = remote_fuse_impl::repertory_destroy,
|
||||
.access = remote_fuse_impl::repertory_access,
|
||||
.create = remote_fuse_impl::repertory_create,
|
||||
.ftruncate = remote_fuse_impl::repertory_ftruncate,
|
||||
.fgetattr = remote_fuse_impl::repertory_fgetattr,
|
||||
.lock = nullptr, // int (*lock) (const char *, struct fuse_file_info *, int cmd, struct flock *);
|
||||
.utimens = remote_fuse_impl::repertory_utimens,
|
||||
.bmap = nullptr, // int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
|
||||
.flag_nullpath_ok = 0,
|
||||
.flag_nopath = 0,
|
||||
.flag_utime_omit_ok = 1,
|
||||
.flag_reserved = 0,
|
||||
.ioctl = nullptr, // int (*ioctl) (const char *, int cmd, void *arg, struct fuse_file_info *, unsigned int flags, void *data);
|
||||
.poll = nullptr, // int (*poll) (const char *, struct fuse_file_info *, struct fuse_pollhandle *ph, unsigned *reventsp);
|
||||
.write_buf = nullptr, // int (*write_buf) (const char *, struct fuse_bufvec *buf, off_t off, struct fuse_file_info *);
|
||||
.read_buf = nullptr, // int (*read_buf) (const char *, struct fuse_bufvec **bufp, size_t size, off_t off, struct fuse_file_info *);
|
||||
.flock = nullptr, // int (*flock) (const char *, struct fuse_file_info *, int op);
|
||||
.fallocate = nullptr // remote_fuse_impl::repertory_fallocate,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
public:
|
||||
int mount(std::vector<std::string> drive_args);
|
||||
|
||||
static void display_options(int argc, char *argv[]);
|
||||
|
||||
static void display_version_information(int argc, char *argv[]);
|
||||
};
|
||||
} // namespace remote_fuse
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE_HPP_
|
101
include/drives/fuse/remotefuse/remote_fuse_drive2.hpp
Normal file
101
include/drives/fuse/remotefuse/remote_fuse_drive2.hpp
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE2_HPP_
|
||||
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE2_HPP_
|
||||
#ifndef _WIN32
|
||||
#if 0
|
||||
|
||||
#include "common.hpp"
|
||||
#include "drives/fuse/fuse_base.hpp"
|
||||
#include "drives/fuse/remotefuse/i_remote_instance.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class console_consumer;
|
||||
class logging_consumer;
|
||||
class lock_data;
|
||||
class server;
|
||||
|
||||
namespace utils {
|
||||
api_error to_api_error(packet::error_type e) { return api_error::success; }
|
||||
} // namespace utils
|
||||
|
||||
namespace remote_fuse {
|
||||
class remote_fuse_drive2 final : public fuse_base {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
~remote_fuse_drive2() override = default;
|
||||
|
||||
private:
|
||||
std::unique_ptr<i_remote_instance> remote_instance_;
|
||||
|
||||
protected:
|
||||
api_error access_impl(std::string api_path, int mask) override;
|
||||
|
||||
#ifdef __APPLE__
|
||||
api_error chflags_impl(std::string api_path, uint32_t flags) override;
|
||||
#endif // __APPLE__
|
||||
|
||||
api_error chmod_impl(std::string api_path, mode_t mode) override;
|
||||
|
||||
public:
|
||||
api_error check_parent_access(const std::string &api_path, int mask) const override;
|
||||
|
||||
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
|
||||
|
||||
directory_item_list get_directory_items(const std::string &api_path) const override;
|
||||
|
||||
std::uint64_t get_file_size(const std::string &api_path) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, const std::string &name,
|
||||
std::string &value) const override;
|
||||
|
||||
std::uint64_t get_total_drive_space() const override;
|
||||
|
||||
std::uint64_t get_total_item_count() const override;
|
||||
|
||||
std::uint64_t get_used_drive_space() const override;
|
||||
|
||||
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) const override;
|
||||
|
||||
bool is_processing(const std::string &api_path) const override;
|
||||
|
||||
void populate_stat(const directory_item &di, struct stat &st) const override;
|
||||
|
||||
int rename_directory(const std::string &from_api_path, const std::string &to_api_path) override;
|
||||
|
||||
int rename_file(const std::string &from_api_path, const std::string &to_api_path,
|
||||
const bool &overwrite) override;
|
||||
|
||||
void set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) override;
|
||||
|
||||
void update_directory_item(directory_item &di) const override;
|
||||
};
|
||||
} // namespace remote_fuse
|
||||
} // namespace repertory
|
||||
|
||||
#endif // 0
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE2_HPP_
|
253
include/drives/fuse/remotefuse/remote_server.hpp
Normal file
253
include/drives/fuse/remotefuse/remote_server.hpp
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_FUSE_REMOTEFUSE_REMOTE_SERVER_HPP_
|
||||
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_SERVER_HPP_
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "drives/directory_cache.hpp"
|
||||
#include "drives/fuse/i_fuse_drive.hpp"
|
||||
#include "drives/remote/remote_server_base.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
|
||||
namespace remote_fuse {
|
||||
class remote_server final : public virtual remote_server_base<i_fuse_drive> {
|
||||
public:
|
||||
remote_server(app_config &config, i_fuse_drive &drive, const std::string &mount_location);
|
||||
|
||||
private:
|
||||
directory_cache directory_cache_;
|
||||
|
||||
private:
|
||||
std::string construct_path(std::string path);
|
||||
|
||||
std::string construct_path(const std::wstring &path);
|
||||
|
||||
static std::string empty_as_zero(const json &data);
|
||||
|
||||
packet::error_type populate_file_info(const std::string &api_path, remote::file_info &file_info);
|
||||
|
||||
void populate_file_info(const std::string &api_path, const UINT64 &file_size,
|
||||
const UINT32 &attributes, remote::file_info &file_info);
|
||||
|
||||
static void populate_stat(const struct stat &st1, remote::stat &st);
|
||||
|
||||
json &update_to_windows_format(json &item);
|
||||
|
||||
protected:
|
||||
void delete_open_directory(void *dir) override;
|
||||
|
||||
public:
|
||||
// FUSE Layer
|
||||
packet::error_type fuse_access(const char *path, const std::int32_t &mask) override;
|
||||
|
||||
packet::error_type fuse_chflags(const char *path, const std::uint32_t &flags) override;
|
||||
|
||||
packet::error_type fuse_chmod(const char *path, const remote::file_mode &mode) override;
|
||||
|
||||
packet::error_type fuse_chown(const char *path, const remote::user_id &uid,
|
||||
const remote::group_id &gid) override;
|
||||
|
||||
packet::error_type fuse_create(const char *path, const remote::file_mode &mode,
|
||||
const remote::open_flags &flags, remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_destroy() override;
|
||||
|
||||
/*packet::error_type fuse_fallocate(const char *path, const std::int32_t &mode,
|
||||
const remote::file_offset &offset,
|
||||
const remote::file_offset &length,
|
||||
const remote::file_handle &handle) override ;*/
|
||||
|
||||
packet::error_type fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_fsetattr_x(const char *path, const remote::setattr_x &attr,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_fsync(const char *path, const std::int32_t &datasync,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_ftruncate(const char *path, const remote::file_offset &size,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_getattr(const char *path, remote::stat &st, bool &directory) override;
|
||||
|
||||
/*packet::error_type fuse_getxattr(const char *path, const char *name, char *value,
|
||||
const remote::file_size &size) override ;
|
||||
|
||||
packet::error_type fuse_getxattrOSX(const char *path, const char *name, char *value,
|
||||
const remote::file_size &size,
|
||||
const std::uint32_t &position) override ;*/
|
||||
|
||||
packet::error_type fuse_getxtimes(const char *path, remote::file_time &bkuptime,
|
||||
remote::file_time &crtime) override;
|
||||
|
||||
packet::error_type fuse_init() override;
|
||||
|
||||
/*packet::error_type fuse_listxattr(const char *path, char *buffer,
|
||||
const remote::file_size &size) override ;*/
|
||||
|
||||
packet::error_type fuse_mkdir(const char *path, const remote::file_mode &mode) override;
|
||||
|
||||
packet::error_type fuse_open(const char *path, const remote::open_flags &flags,
|
||||
remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_opendir(const char *path, remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_read(const char *path, char *buffer, const remote::file_size &read_size,
|
||||
const remote::file_offset &read_offset,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_rename(const char *from, const char *to) override;
|
||||
|
||||
packet::error_type fuse_readdir(const char *path, const remote::file_offset &offset,
|
||||
const remote::file_handle &handle, std::string &item_path) override;
|
||||
|
||||
packet::error_type fuse_release(const char *path, const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_releasedir(const char *path, const remote::file_handle &handle) override;
|
||||
|
||||
/*packet::error_type fuse_removexattr(const char *path, const char *name) override ;*/
|
||||
|
||||
packet::error_type fuse_rmdir(const char *path) override;
|
||||
|
||||
packet::error_type fuse_setattr_x(const char *path, remote::setattr_x &attr) override;
|
||||
|
||||
packet::error_type fuse_setbkuptime(const char *path, const remote::file_time &bkuptime) override;
|
||||
|
||||
packet::error_type fuse_setchgtime(const char *path, const remote::file_time &chgtime) override;
|
||||
|
||||
packet::error_type fuse_setcrtime(const char *path, const remote::file_time &crtime) override;
|
||||
|
||||
packet::error_type fuse_setvolname(const char *volname) override;
|
||||
|
||||
/*packet::error_type fuse_setxattr(const char *path, const char *name, const char *value,
|
||||
const remote::file_size &size,
|
||||
const std::int32_t &flags) override ;
|
||||
|
||||
packet::error_type fuse_setxattr_osx(const char *path, const char *name, const char *value,
|
||||
const remote::file_size &size, const std::int32_t &flags,
|
||||
const std::uint32_t &position) override ;*/
|
||||
|
||||
packet::error_type fuse_statfs(const char *path, const std::uint64_t &frsize,
|
||||
remote::statfs &st) override;
|
||||
|
||||
packet::error_type fuse_statfs_x(const char *path, const std::uint64_t &bsize,
|
||||
remote::statfs_x &st) override;
|
||||
|
||||
packet::error_type fuse_truncate(const char *path, const remote::file_offset &size) override;
|
||||
|
||||
packet::error_type fuse_unlink(const char *path) override;
|
||||
|
||||
packet::error_type fuse_utimens(const char *path, const remote::file_time *tv,
|
||||
const std::uint64_t &op0, const std::uint64_t &op1) override;
|
||||
|
||||
packet::error_type fuse_write(const char *path, const char *buffer,
|
||||
const remote::file_size &write_size,
|
||||
const remote::file_offset &write_offset,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_write_base64(const char *path, const char *buffer,
|
||||
const remote::file_size &write_size,
|
||||
const remote::file_offset &write_offset,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
void set_fuse_uid_gid(const remote::user_id &, const remote::group_id &) override {}
|
||||
|
||||
// JSON Layer
|
||||
packet::error_type winfsp_get_dir_buffer(PVOID /*file_desc*/, PVOID *& /*ptr*/) override {
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
packet::error_type json_create_directory_snapshot(const std::string &path,
|
||||
json &jsonData) override;
|
||||
|
||||
packet::error_type json_read_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle,
|
||||
const std::uint32_t &page,
|
||||
json &jsonData) override;
|
||||
|
||||
packet::error_type json_release_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
// WinFSP Layer
|
||||
packet::error_type winfsp_can_delete(PVOID file_desc, PWSTR file_name) override;
|
||||
|
||||
packet::error_type winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags,
|
||||
BOOLEAN &wasClosed) override;
|
||||
|
||||
packet::error_type winfsp_close(PVOID file_desc) override;
|
||||
|
||||
packet::error_type winfsp_create(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
|
||||
UINT32 attributes, UINT64 /*allocation_size*/, PVOID *file_desc,
|
||||
remote::file_info *file_info, std::string &normalized_name,
|
||||
BOOLEAN &exists) override;
|
||||
|
||||
packet::error_type winfsp_flush(PVOID file_desc, remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
|
||||
std::uint64_t * /*securityDescriptorSize*/,
|
||||
std::wstring & /*strDescriptor*/) override;
|
||||
|
||||
packet::error_type winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) override;
|
||||
|
||||
packet::error_type winfsp_mounted(const std::wstring &location) override;
|
||||
|
||||
packet::error_type winfsp_open(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
|
||||
PVOID *file_desc, remote::file_info *file_info,
|
||||
std::string &normalized_name) override;
|
||||
|
||||
packet::error_type winfsp_overwrite(PVOID file_desc, UINT32 attributes,
|
||||
BOOLEAN replace_attributes, UINT64 /*allocation_size*/,
|
||||
remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
|
||||
PUINT32 bytes_transferred) override;
|
||||
|
||||
packet::error_type winfsp_read_directory(PVOID file_desc, PWSTR /*pattern*/, PWSTR marker,
|
||||
json &itemList) override;
|
||||
|
||||
packet::error_type winfsp_rename(PVOID /*file_desc*/, PWSTR file_name, PWSTR new_file_name,
|
||||
BOOLEAN replace_if_exists) override;
|
||||
|
||||
packet::error_type 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) override;
|
||||
|
||||
packet::error_type winfsp_set_file_size(PVOID file_desc, UINT64 newSize,
|
||||
BOOLEAN set_allocation_size,
|
||||
remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_unmounted(const std::wstring &location) override;
|
||||
|
||||
packet::error_type winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
|
||||
BOOLEAN write_to_end, BOOLEAN constrained_io,
|
||||
PUINT32 bytes_transferred, remote::file_info *file_info) override;
|
||||
};
|
||||
} // namespace remote_fuse
|
||||
} // namespace repertory
|
||||
|
||||
#endif
|
||||
#endif // INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_SERVER_HPP_
|
64
include/drives/i_open_file_table.hpp
Normal file
64
include/drives/i_open_file_table.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_I_OPEN_FILE_TABLE_HPP_
|
||||
#define INCLUDE_DRIVES_I_OPEN_FILE_TABLE_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
class i_open_file_table {
|
||||
INTERFACE_SETUP(i_open_file_table);
|
||||
|
||||
public:
|
||||
typedef std::function<bool(i_open_file_table &oft, i_provider &provider)>
|
||||
locked_operation_callback;
|
||||
|
||||
public:
|
||||
virtual void close(const std::uint64_t &handle) = 0;
|
||||
|
||||
virtual bool contains_restore(const std::string &api_path) const = 0;
|
||||
|
||||
virtual bool evict_file(const std::string &api_path) = 0;
|
||||
|
||||
virtual void force_schedule_upload(const filesystem_item &fsi) = 0;
|
||||
|
||||
virtual directory_item_list get_directory_items(const std::string &api_path) const = 0;
|
||||
|
||||
virtual std::uint64_t get_open_count(const std::string &api_path) const = 0;
|
||||
|
||||
virtual bool get_open_file(const std::string &api_path, filesystem_item *&fsi) = 0;
|
||||
|
||||
virtual std::unordered_map<std::string, std::size_t> get_open_files() const = 0;
|
||||
|
||||
virtual bool has_no_open_file_handles() const = 0;
|
||||
|
||||
virtual api_error open(const filesystem_item &fsi, std::uint64_t &handle) = 0;
|
||||
|
||||
virtual bool perform_locked_operation(locked_operation_callback locked_operation) = 0;
|
||||
|
||||
virtual api_error set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) = 0;
|
||||
|
||||
virtual void update_directory_item(directory_item &di) const = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_I_OPEN_FILE_TABLE_HPP_
|
751
include/drives/open_file_table.hpp
Normal file
751
include/drives/open_file_table.hpp
Normal file
@ -0,0 +1,751 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_OPEN_FILE_TABLE_HPP_
|
||||
#define INCLUDE_DRIVES_OPEN_FILE_TABLE_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "db/retry_db.hpp"
|
||||
#include "download/i_download_manager.hpp"
|
||||
#include "drives/i_open_file_table.hpp"
|
||||
#include "providers/i_provider.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/file_utils.hpp"
|
||||
#include "utils/global_data.hpp"
|
||||
#include "utils/native_file.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/polling.hpp"
|
||||
|
||||
namespace repertory {
|
||||
template <typename flags> class open_file_table final : public virtual i_open_file_table {
|
||||
public:
|
||||
open_file_table(i_provider &provider, const app_config &config, i_download_manager &dm)
|
||||
: provider_(provider), config_(config), dm_(dm), retry_db_(config) {
|
||||
// Set initial value for used cache space
|
||||
global_data::instance().initialize_used_cache_space(
|
||||
utils::file::calculate_used_space(config_.get_cache_directory(), false));
|
||||
polling::instance().set_callback(
|
||||
{"last_close_clear", false, [this] {
|
||||
std::vector<std::string> keys;
|
||||
unique_mutex_lock l(last_close_mutex_);
|
||||
std::transform(last_close_lookup_.begin(), last_close_lookup_.end(),
|
||||
std::back_inserter(keys), [](const auto &kv) { return kv.first; });
|
||||
l.unlock();
|
||||
for (const auto &key : keys) {
|
||||
l.lock();
|
||||
remove_if_expired(key, last_close_lookup_[key]);
|
||||
l.unlock();
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
||||
~open_file_table() override { polling::instance().remove_callback("last_close_clear"); }
|
||||
|
||||
private:
|
||||
struct open_file_info {
|
||||
filesystem_item item;
|
||||
api_meta_map meta;
|
||||
};
|
||||
|
||||
private:
|
||||
i_provider &provider_;
|
||||
const app_config &config_;
|
||||
i_download_manager &dm_;
|
||||
retry_db retry_db_;
|
||||
std::unordered_map<std::string, std::shared_ptr<open_file_info>> open_file_lookup_;
|
||||
mutable std::recursive_mutex open_file_mutex_;
|
||||
std::unordered_map<std::uint64_t, open_file_info *> open_handle_lookup_;
|
||||
std::uint64_t next_handle_ = 1u;
|
||||
bool stop_requested_ = false;
|
||||
std::mutex retry_mutex_;
|
||||
std::unique_ptr<std::thread> retry_thread_;
|
||||
std::condition_variable retry_notify_;
|
||||
std::mutex start_stop_mutex_;
|
||||
std::mutex last_close_mutex_;
|
||||
std::unordered_map<std::string, std::uint64_t> last_close_lookup_;
|
||||
|
||||
private:
|
||||
api_error get_filesystem_item(const std::string &api_path, const bool &directory,
|
||||
filesystem_item &fsi) {
|
||||
auto ret = api_error::item_not_found;
|
||||
|
||||
const auto it = open_file_lookup_.find(api_path);
|
||||
if (it != open_file_lookup_.end()) {
|
||||
fsi = it->second->item;
|
||||
ret = api_error::success;
|
||||
} else {
|
||||
ret = provider_.get_filesystem_item(api_path, directory, fsi);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::uint64_t get_next_handle() {
|
||||
std::uint64_t ret = 0u;
|
||||
while ((ret = next_handle_++) == 0u) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
api_error handle_file_rename(const std::string &from_api_path, const std::string &to_api_path) {
|
||||
auto ret = api_error::file_in_use;
|
||||
if (dm_.pause_download(from_api_path)) {
|
||||
if ((ret = provider_.rename_file(from_api_path, to_api_path)) == api_error::success) {
|
||||
swap_renamed_items(from_api_path, to_api_path);
|
||||
dm_.rename_download(from_api_path, to_api_path);
|
||||
dm_.resume_download(to_api_path);
|
||||
|
||||
retry_db_.rename(from_api_path, to_api_path);
|
||||
} else {
|
||||
dm_.resume_download(from_api_path);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void handle_file_upload(filesystem_item &fsi) {
|
||||
fsi.changed = false;
|
||||
handle_file_upload(&fsi);
|
||||
}
|
||||
|
||||
void handle_file_upload(const filesystem_item *fsi) {
|
||||
// Remove from retry queue, if present
|
||||
retry_db_.remove(fsi->api_path);
|
||||
|
||||
// Upload file and add to retry queue on failure
|
||||
auto nf = native_file::attach(fsi->handle);
|
||||
nf->flush();
|
||||
if (provider_.upload_file(fsi->api_path, fsi->source_path, fsi->encryption_token) !=
|
||||
api_error::success) {
|
||||
retry_db_.set(fsi->api_path);
|
||||
event_system::instance().raise<failed_upload_queued>(fsi->api_path);
|
||||
}
|
||||
}
|
||||
|
||||
bool remove_if_expired(const std::string &api_path, const std::uint64_t &time) {
|
||||
auto ret = false;
|
||||
#ifdef _WIN32
|
||||
const auto delay = std::chrono::minutes(config_.get_eviction_delay_mins());
|
||||
const auto last_check = std::chrono::system_clock::from_time_t(time);
|
||||
if ((ret = ((last_check + delay) <= std::chrono::system_clock::now())))
|
||||
#else
|
||||
if ((ret = ((time + ((config_.get_eviction_delay_mins() * 60L) * NANOS_PER_SECOND)) <=
|
||||
utils::get_time_now())))
|
||||
#endif
|
||||
{
|
||||
last_close_lookup_.erase(api_path);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool retry_delete_file(const std::string &file) {
|
||||
auto deleted = false;
|
||||
for (std::uint8_t i = 0u; not(deleted = utils::file::delete_file(file)) && (i < 100u); i++) {
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
void swap_renamed_items(std::string from_api_path, std::string to_api_path) {
|
||||
const auto it = open_file_lookup_.find(from_api_path);
|
||||
if (it != open_file_lookup_.end()) {
|
||||
open_file_lookup_[to_api_path] = open_file_lookup_[from_api_path];
|
||||
open_file_lookup_.erase(from_api_path);
|
||||
auto &fsi = open_file_lookup_[to_api_path]->item;
|
||||
fsi.api_path = to_api_path;
|
||||
fsi.api_parent = utils::path::get_parent_api_path(to_api_path);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool has_no_open_file_handles() const override {
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
return std::find_if(open_file_lookup_.cbegin(), open_file_lookup_.cend(), [](const auto &kv) {
|
||||
return not kv.second->item.directory;
|
||||
}) == open_file_lookup_.cend();
|
||||
}
|
||||
|
||||
void close(const std::uint64_t &handle) override {
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
const auto it = open_handle_lookup_.find(handle);
|
||||
if (it != open_handle_lookup_.end()) {
|
||||
auto *oi = it->second;
|
||||
open_handle_lookup_.erase(handle);
|
||||
|
||||
auto &fsi = oi->item;
|
||||
const auto was_changed = fsi.changed;
|
||||
|
||||
// Handle meta change
|
||||
if (fsi.meta_changed) {
|
||||
if (provider_.set_item_meta(fsi.api_path, oi->meta) == api_error::success) {
|
||||
fsi.meta_changed = false;
|
||||
} else {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
__FUNCTION__, "failed to set file meta: " + fsi.api_path);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle source path change
|
||||
if (not fsi.directory && fsi.source_path_changed) {
|
||||
if (provider_.set_source_path(fsi.api_path, fsi.source_path) == api_error::success) {
|
||||
fsi.source_path_changed = false;
|
||||
} else {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
__FUNCTION__, "failed to set source path: " + fsi.api_path + "|" + fsi.source_path);
|
||||
}
|
||||
}
|
||||
|
||||
// Update last close time in lookup table
|
||||
if (not fsi.directory) {
|
||||
mutex_lock l2(last_close_mutex_);
|
||||
last_close_lookup_[fsi.api_path] = utils::get_time_now();
|
||||
}
|
||||
|
||||
// Handle file change
|
||||
#ifdef __APPLE__
|
||||
// Special handling for OS X - only upload if handle being closed is writable
|
||||
if (not fsi.directory && was_changed && (fsi.open_data[handle] & O_ACCMODE))
|
||||
#else
|
||||
if (not fsi.directory && was_changed)
|
||||
#endif
|
||||
{
|
||||
handle_file_upload(fsi);
|
||||
}
|
||||
|
||||
// Close internal handle if no more open files
|
||||
auto &od = fsi.open_data;
|
||||
od.erase(handle);
|
||||
event_system::instance().raise<filesystem_item_handle_closed>(
|
||||
fsi.api_path, handle, fsi.source_path, fsi.directory, was_changed);
|
||||
if (od.empty()) {
|
||||
native_file::attach(fsi.handle)->close();
|
||||
|
||||
event_system::instance().raise<filesystem_item_closed>(fsi.api_path, fsi.source_path,
|
||||
fsi.directory, was_changed);
|
||||
open_file_lookup_.erase(fsi.api_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void close_all(const std::string &api_path) {
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
const auto it = open_file_lookup_.find(api_path);
|
||||
if (it != open_file_lookup_.end()) {
|
||||
auto *oi = it->second.get();
|
||||
std::vector<std::uint64_t> handles;
|
||||
for (const auto &kv : open_handle_lookup_) {
|
||||
if (kv.second == oi) {
|
||||
handles.emplace_back(kv.first);
|
||||
}
|
||||
}
|
||||
|
||||
while (!handles.empty()) {
|
||||
close(handles.back());
|
||||
handles.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
bool contains_restore(const std::string &api_path) const override {
|
||||
return dm_.contains_restore(api_path);
|
||||
}
|
||||
|
||||
api_error derive_file_size(const std::string &api_path, std::uint64_t &file_size) {
|
||||
auto ret = api_error::success;
|
||||
file_size = 0u;
|
||||
|
||||
if (provider_.is_file(api_path)) {
|
||||
unique_recur_mutex_lock l(open_file_mutex_);
|
||||
const auto it = open_file_lookup_.find(api_path);
|
||||
if (it == open_file_lookup_.end()) {
|
||||
l.unlock();
|
||||
ret = provider_.get_file_size(api_path, file_size);
|
||||
} else {
|
||||
file_size = open_file_lookup_[api_path]->item.size;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
api_error derive_item_data(const std::string &api_path, api_meta_map &meta) {
|
||||
auto ret = api_error::success;
|
||||
meta.clear();
|
||||
|
||||
unique_recur_mutex_lock l(open_file_mutex_);
|
||||
const auto it = open_file_lookup_.find(api_path);
|
||||
if (it == open_file_lookup_.end()) {
|
||||
l.unlock();
|
||||
ret = provider_.get_item_meta(api_path, meta);
|
||||
} else {
|
||||
meta = open_file_lookup_[api_path]->meta;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
api_error derive_item_data(const directory_item &di, std::uint64_t &file_size,
|
||||
api_meta_map &meta) {
|
||||
return derive_item_data(di.api_path, di.directory, file_size, meta);
|
||||
}
|
||||
|
||||
api_error derive_item_data(const std::string &api_path, const bool &directory,
|
||||
std::uint64_t &file_size, api_meta_map &meta) {
|
||||
auto ret = api_error::success;
|
||||
meta.clear();
|
||||
file_size = 0;
|
||||
|
||||
unique_recur_mutex_lock l(open_file_mutex_);
|
||||
const auto it = open_file_lookup_.find(api_path);
|
||||
if (it == open_file_lookup_.end()) {
|
||||
l.unlock();
|
||||
ret = provider_.get_item_meta(api_path, meta);
|
||||
if ((ret == api_error::success) && not directory) {
|
||||
ret = provider_.get_file_size(api_path, file_size);
|
||||
}
|
||||
} else {
|
||||
meta = open_file_lookup_[api_path]->meta;
|
||||
if (not directory) {
|
||||
file_size = open_file_lookup_[api_path]->item.size;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool evict_file(const std::string &api_path) override {
|
||||
auto ret = false;
|
||||
auto allow_eviction = true;
|
||||
// Ensure enough time has passed since file was closed
|
||||
{
|
||||
mutex_lock l(last_close_mutex_);
|
||||
const auto it = last_close_lookup_.find(api_path);
|
||||
if (it != last_close_lookup_.end()) {
|
||||
allow_eviction = remove_if_expired(api_path, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
if (allow_eviction) {
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
// Ensure item is not in upload retry queue
|
||||
if (not retry_db_.exists(api_path) && (get_open_count(api_path) == 0u)) {
|
||||
// Ensure item is not currently downloading
|
||||
if (not dm_.is_processing(api_path)) {
|
||||
filesystem_item fsi{};
|
||||
if (provider_.get_filesystem_item(api_path, false, fsi) == api_error::success) {
|
||||
std::uint64_t file_size = 0u;
|
||||
if ((ret = (utils::file::get_file_size(fsi.source_path, file_size) &&
|
||||
retry_delete_file(fsi.source_path)))) {
|
||||
global_data::instance().update_used_space(file_size, 0, true);
|
||||
event_system::instance().raise<filesystem_item_evicted>(fsi.api_path,
|
||||
fsi.source_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void force_schedule_upload(const filesystem_item &fsi) override {
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
filesystem_item *fsi_ptr = nullptr;
|
||||
if (get_open_file(fsi.api_path, fsi_ptr)) {
|
||||
handle_file_upload(*fsi_ptr);
|
||||
} else {
|
||||
handle_file_upload(&fsi);
|
||||
}
|
||||
}
|
||||
|
||||
directory_item_list get_directory_items(const std::string &api_path) const override {
|
||||
directory_item_list list;
|
||||
provider_.get_directory_items(api_path, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
std::uint64_t get_open_count(const std::string &api_path) const override {
|
||||
std::uint64_t ret = 0u;
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
const auto it = open_file_lookup_.find(api_path);
|
||||
if (it != open_file_lookup_.end()) {
|
||||
ret = it->second->item.open_data.size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool get_open_file(const std::string &api_path, filesystem_item *&fsi) override {
|
||||
auto ret = false;
|
||||
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
const auto it = open_file_lookup_.find(api_path);
|
||||
if (it != open_file_lookup_.end()) {
|
||||
fsi = &it->second->item;
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool get_open_file(const std::uint64_t &handle, filesystem_item *&fsi) {
|
||||
auto ret = false;
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
const auto it = open_handle_lookup_.find(handle);
|
||||
if (it != open_handle_lookup_.end()) {
|
||||
fsi = &it->second->item;
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::size_t> get_open_files() const override {
|
||||
std::unordered_map<std::string, std::size_t> ret;
|
||||
unique_recur_mutex_lock l(open_file_mutex_);
|
||||
for (const auto &kv : open_file_lookup_) {
|
||||
ret.insert({kv.first, kv.second->item.open_data.size()});
|
||||
}
|
||||
l.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
api_error open(const filesystem_item &fsi, std::uint64_t &handle) override {
|
||||
auto ret = api_error::success;
|
||||
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
if (open_file_lookup_.find(fsi.api_path) == open_file_lookup_.end()) {
|
||||
api_meta_map meta;
|
||||
if ((ret = provider_.get_item_meta(fsi.api_path, meta)) == api_error::success) {
|
||||
auto oi = std::make_shared<open_file_info>();
|
||||
oi->meta = meta;
|
||||
oi->item = fsi;
|
||||
oi->item.lock = std::make_shared<std::recursive_mutex>();
|
||||
open_file_lookup_.insert({fsi.api_path, oi});
|
||||
|
||||
event_system::instance().raise<filesystem_item_opened>(
|
||||
oi->item.api_path, oi->item.source_path, oi->item.directory);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == api_error::success) {
|
||||
ret = Open(fsi.api_path, fsi.directory, utils::file::get_read_write_open_flags(), handle);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
api_error Open(const std::string &api_path, const bool &directory, const flags &f,
|
||||
std::uint64_t &handle) {
|
||||
auto ret = api_error::success;
|
||||
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
if (open_file_lookup_.find(api_path) == open_file_lookup_.end()) {
|
||||
api_meta_map meta;
|
||||
if ((ret = provider_.get_item_meta(api_path, meta)) == api_error::success) {
|
||||
auto oi = std::make_shared<open_file_info>();
|
||||
oi->meta = meta;
|
||||
if ((ret = provider_.get_filesystem_item(api_path, directory, oi->item)) ==
|
||||
api_error::success) {
|
||||
open_file_lookup_.insert({api_path, oi});
|
||||
event_system::instance().raise<filesystem_item_opened>(
|
||||
oi->item.api_path, oi->item.source_path, oi->item.directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == api_error::success) {
|
||||
auto *oi = open_file_lookup_[api_path].get();
|
||||
auto &fsi = oi->item;
|
||||
if (fsi.directory == directory) {
|
||||
handle = get_next_handle();
|
||||
fsi.open_data.insert({handle, f});
|
||||
open_handle_lookup_.insert({handle, oi});
|
||||
} else {
|
||||
ret = directory ? api_error::file_exists : api_error::directory_exists;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool perform_locked_operation(locked_operation_callback locked_operation) override {
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
return locked_operation(*this, provider_);
|
||||
}
|
||||
|
||||
api_error remove_file(const std::string &api_path) {
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
|
||||
filesystem_item fsi{};
|
||||
auto ret = api_error::file_in_use;
|
||||
if ((get_open_count(api_path) == 0u) &&
|
||||
((ret = provider_.get_filesystem_item(api_path, false, fsi)) == api_error::success) &&
|
||||
((ret = provider_.remove_file(api_path)) == api_error::success)) {
|
||||
std::uint64_t file_size = 0u;
|
||||
utils::file::get_file_size(fsi.source_path, file_size);
|
||||
if (retry_delete_file(fsi.source_path) && file_size) {
|
||||
global_data::instance().update_used_space(file_size, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAS_SETXATTR
|
||||
api_error remove_xattr_meta(const std::string &api_path, const std::string &name) {
|
||||
auto ret = api_error::xattr_not_found;
|
||||
if (utils::collection_excludes(META_USED_NAMES, name)) {
|
||||
unique_recur_mutex_lock l(open_file_mutex_);
|
||||
if (open_file_lookup_.find(api_path) == open_file_lookup_.end()) {
|
||||
l.unlock();
|
||||
ret = provider_.remove_item_meta(api_path, name);
|
||||
} else if (open_file_lookup_[api_path]->meta.find(name) !=
|
||||
open_file_lookup_[api_path]->meta.end()) {
|
||||
open_file_lookup_[api_path]->item.meta_changed = true;
|
||||
open_file_lookup_[api_path]->meta.erase(name);
|
||||
ret = api_error::success;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
api_error rename_directory(const std::string &from_api_path, const std::string &to_api_path) {
|
||||
unique_recur_mutex_lock l(open_file_mutex_);
|
||||
auto ret = api_error::not_implemented;
|
||||
if (provider_.is_rename_supported()) {
|
||||
ret = api_error::directory_not_found;
|
||||
// Ensure source directory exists
|
||||
if (provider_.is_directory(from_api_path)) {
|
||||
ret = api_error::directory_exists;
|
||||
// Ensure destination directory does not exist
|
||||
if (not provider_.is_directory(to_api_path)) {
|
||||
ret = api_error::file_exists;
|
||||
// Ensure destination is not a file
|
||||
if (not provider_.is_file(from_api_path)) {
|
||||
ret = api_error::directory_not_found;
|
||||
// Ensure parent destination directory exists
|
||||
directory_item_list list;
|
||||
if (provider_.is_directory(utils::path::get_parent_api_path(to_api_path)) &&
|
||||
((ret = provider_.create_directory_clone_source_meta(from_api_path, to_api_path)) ==
|
||||
api_error::success) &&
|
||||
((ret = provider_.get_directory_items(from_api_path, list)) ==
|
||||
api_error::success)) {
|
||||
// Rename all items - directories MUST BE returned first
|
||||
for (std::size_t i = 0u; (ret == api_error::success) && (i < list.size()); i++) {
|
||||
const auto &api_path = list[i].api_path;
|
||||
if ((api_path != ".") && (api_path != "..")) {
|
||||
const auto old_api_path = api_path;
|
||||
const auto new_api_path = utils::path::create_api_path(utils::path::combine(
|
||||
to_api_path, {old_api_path.substr(from_api_path.size())}));
|
||||
if (list[i].directory) {
|
||||
ret = rename_directory(old_api_path, new_api_path);
|
||||
} else {
|
||||
ret = rename_file(old_api_path, new_api_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == api_error::success) {
|
||||
swap_renamed_items(from_api_path, to_api_path);
|
||||
ret = provider_.remove_directory(from_api_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
api_error rename_file(const std::string &from_api_path, const std::string &to_api_path,
|
||||
const bool &overwrite = true) {
|
||||
auto ret = api_error::not_implemented;
|
||||
if (provider_.is_rename_supported()) {
|
||||
// Don't rename if paths are the same
|
||||
if ((ret = (from_api_path == to_api_path) ? api_error::file_exists : api_error::success) ==
|
||||
api_error::success) {
|
||||
retry_db_.pause();
|
||||
|
||||
unique_recur_mutex_lock l(open_file_mutex_);
|
||||
// Check allow overwrite if file exists
|
||||
if (not overwrite && provider_.is_file(to_api_path)) {
|
||||
l.unlock();
|
||||
ret = api_error::file_exists;
|
||||
} else {
|
||||
// Don't rename if source does not exist
|
||||
if ((ret = provider_.is_file(from_api_path)
|
||||
? api_error::success
|
||||
: api_error::item_not_found) == api_error::success) {
|
||||
// Don't rename if destination file is downloading
|
||||
if ((ret = dm_.is_processing(to_api_path) ? api_error::file_in_use
|
||||
: api_error::success) == api_error::success) {
|
||||
// Don't rename if destination file has open handles
|
||||
ret = api_error::file_in_use;
|
||||
if (get_open_count(to_api_path) == 0u) {
|
||||
if (provider_.is_file(
|
||||
to_api_path)) { // Handle destination file exists (should overwrite)
|
||||
filesystem_item fsi{};
|
||||
if ((ret = get_filesystem_item(to_api_path, false, fsi)) == api_error::success) {
|
||||
ret = api_error::os_error;
|
||||
std::uint64_t file_size = 0u;
|
||||
if (utils::file::get_file_size(fsi.source_path, file_size)) {
|
||||
ret = provider_.remove_file(to_api_path);
|
||||
if ((ret == api_error::success) || (ret == api_error::item_not_found)) {
|
||||
if (retry_delete_file(fsi.source_path) && file_size) {
|
||||
global_data::instance().update_used_space(file_size, 0, false);
|
||||
}
|
||||
ret = handle_file_rename(from_api_path, to_api_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
l.unlock();
|
||||
} else if (provider_.is_directory(to_api_path)) { // Handle destination is directory
|
||||
l.unlock();
|
||||
ret = api_error::directory_exists;
|
||||
} else if (provider_.is_directory(utils::path::get_parent_api_path(
|
||||
to_api_path))) { // Handle rename if destination directory exists
|
||||
ret = handle_file_rename(from_api_path, to_api_path);
|
||||
l.unlock();
|
||||
} else { // Destination directory not found
|
||||
l.unlock();
|
||||
ret = api_error::directory_not_found;
|
||||
}
|
||||
}
|
||||
} else if (provider_.is_directory(from_api_path)) {
|
||||
l.unlock();
|
||||
ret = api_error::directory_exists;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retry_db_.resume();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
api_error set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) override {
|
||||
unique_recur_mutex_lock l(open_file_mutex_);
|
||||
if (open_file_lookup_.find(api_path) == open_file_lookup_.end()) {
|
||||
l.unlock();
|
||||
return provider_.set_item_meta(api_path, key, value);
|
||||
}
|
||||
|
||||
if (open_file_lookup_[api_path]->meta[key] != value) {
|
||||
open_file_lookup_[api_path]->item.meta_changed = true;
|
||||
open_file_lookup_[api_path]->meta[key] = value;
|
||||
}
|
||||
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
api_error set_item_meta(const std::string &api_path, const api_meta_map &meta) {
|
||||
auto ret = api_error::success;
|
||||
auto it = meta.begin();
|
||||
for (std::size_t i = 0u; (ret == api_error::success) && (i < meta.size()); i++) {
|
||||
ret = set_item_meta(api_path, it->first, it->second);
|
||||
it++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void start() {
|
||||
mutex_lock start_stop_lock(start_stop_mutex_);
|
||||
if (not retry_thread_) {
|
||||
stop_requested_ = false;
|
||||
retry_thread_ = std::make_unique<std::thread>([this] {
|
||||
while (not stop_requested_) {
|
||||
const auto processed = retry_db_.process_all([this](const std::string &api_path) -> bool {
|
||||
auto success = false;
|
||||
event_system::instance().raise<failed_upload_retry>(api_path);
|
||||
unique_recur_mutex_lock open_file_lock(open_file_mutex_);
|
||||
if (open_file_lookup_.find(api_path) == open_file_lookup_.end()) {
|
||||
open_file_lock.unlock();
|
||||
|
||||
filesystem_item fsi{};
|
||||
const auto res = provider_.get_filesystem_item(api_path, false, fsi);
|
||||
if ((res == api_error::success) ||
|
||||
((res == api_error::item_not_found) && provider_.is_file(api_path))) {
|
||||
if (provider_.upload_file(api_path, fsi.source_path, fsi.encryption_token) ==
|
||||
api_error::success) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove deleted files
|
||||
if (not success && not provider_.is_file(api_path)) {
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
// File is open, so force re-upload on close
|
||||
open_file_lookup_[api_path]->item.changed = true;
|
||||
open_file_lock.unlock();
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
});
|
||||
if (not processed && not stop_requested_) {
|
||||
unique_mutex_lock retryLock(retry_mutex_);
|
||||
if (not stop_requested_) {
|
||||
retry_notify_.wait_for(retryLock, 5s);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
mutex_lock start_stop_lock(start_stop_mutex_);
|
||||
if (retry_thread_) {
|
||||
event_system::instance().raise<service_shutdown>("open_file_table");
|
||||
stop_requested_ = true;
|
||||
|
||||
unique_mutex_lock retry_lock(retry_mutex_);
|
||||
retry_notify_.notify_all();
|
||||
retry_lock.unlock();
|
||||
|
||||
retry_thread_->join();
|
||||
retry_thread_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void update_directory_item(directory_item &di) const override {
|
||||
recur_mutex_lock l(open_file_mutex_);
|
||||
const auto it = open_file_lookup_.find(di.api_path);
|
||||
if (it != open_file_lookup_.end()) {
|
||||
const auto &ofi = open_file_lookup_.at(di.api_path);
|
||||
di.meta = ofi->meta;
|
||||
if (not di.directory) {
|
||||
di.size = ofi->item.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_OPEN_FILE_TABLE_HPP_
|
44
include/drives/remote/i_remote_json.hpp
Normal file
44
include/drives/remote/i_remote_json.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_REMOTE_I_REMOTEJSON_HPP_
|
||||
#define INCLUDE_DRIVES_REMOTE_I_REMOTEJSON_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/packet/packet.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_remote_json {
|
||||
INTERFACE_SETUP(i_remote_json);
|
||||
|
||||
public:
|
||||
virtual packet::error_type json_create_directory_snapshot(const std::string &path,
|
||||
json &json_data) = 0;
|
||||
|
||||
virtual packet::error_type json_read_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle,
|
||||
const std::uint32_t &page,
|
||||
json &json_data) = 0;
|
||||
|
||||
virtual packet::error_type
|
||||
json_release_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle) = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_REMOTE_I_REMOTEJSON_HPP_
|
95
include/drives/remote/remote_open_file_table.hpp
Normal file
95
include/drives/remote/remote_open_file_table.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_REMOTE_REMOTE_OPEN_FILE_TABLE_HPP_
|
||||
#define INCLUDE_DRIVES_REMOTE_REMOTE_OPEN_FILE_TABLE_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/remote.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class remote_open_file_table {
|
||||
protected:
|
||||
remote_open_file_table() = default;
|
||||
|
||||
virtual ~remote_open_file_table() = default;
|
||||
|
||||
protected:
|
||||
struct compat_open_info {
|
||||
std::size_t count = 0u;
|
||||
std::string client_id = "";
|
||||
};
|
||||
|
||||
struct open_info {
|
||||
std::size_t count = 0u;
|
||||
std::string client_id = "";
|
||||
PVOID directory_buffer = nullptr;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
private:
|
||||
std::unordered_map<remote::file_handle, compat_open_info> compat_lookup_;
|
||||
std::mutex compat_mutex_;
|
||||
std::unordered_map<std::string, std::vector<void *>> directory_lookup_;
|
||||
std::mutex directory_mutex_;
|
||||
std::unordered_map<OSHandle, open_info> file_lookup_;
|
||||
std::mutex file_mutex_;
|
||||
|
||||
protected:
|
||||
void add_directory(const std::string &client_id, void *dir);
|
||||
|
||||
void close_all(const std::string &client_id);
|
||||
|
||||
virtual void delete_open_directory(void *dir) = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
bool get_directory_buffer(const OSHandle &handle, PVOID *&buffer);
|
||||
#endif
|
||||
|
||||
bool get_open_info(const OSHandle &handle, open_info &oi);
|
||||
|
||||
std::string get_open_file_path(const OSHandle &handle);
|
||||
|
||||
bool has_open_directory(const std::string &client_id, void *dir);
|
||||
|
||||
int has_compat_open_info(const remote::file_handle &handle, const int &error_return);
|
||||
|
||||
template <typename error_type>
|
||||
error_type has_open_info(const OSHandle &handle, const error_type &error_return) {
|
||||
mutex_lock file_lock(file_mutex_);
|
||||
return ((file_lookup_.find(handle) == file_lookup_.end()) ? error_return : 0);
|
||||
}
|
||||
|
||||
void remove_compat_open_info(const remote::file_handle &handle);
|
||||
|
||||
bool remove_directory(const std::string &client_id, void *dir);
|
||||
|
||||
void remove_open_info(const OSHandle &handle);
|
||||
|
||||
void set_client_id(const OSHandle &handle, const std::string &client_id);
|
||||
|
||||
void set_compat_client_id(const remote::file_handle &handle, const std::string &client_id);
|
||||
|
||||
void set_compat_open_info(const remote::file_handle &handle);
|
||||
|
||||
void set_open_info(const OSHandle &handle, open_info oi);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_REMOTE_REMOTE_OPEN_FILE_TABLE_HPP_
|
1348
include/drives/remote/remote_server_base.hpp
Normal file
1348
include/drives/remote/remote_server_base.hpp
Normal file
File diff suppressed because it is too large
Load Diff
61
include/drives/winfsp/i_winfsp_drive.hpp
Normal file
61
include/drives/winfsp/i_winfsp_drive.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_WINFSP_I_WINFSP_DRIVE_HPP_
|
||||
#define INCLUDE_DRIVES_WINFSP_I_WINFSP_DRIVE_HPP_
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/remote.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_winfsp_drive {
|
||||
INTERFACE_SETUP(i_winfsp_drive);
|
||||
|
||||
public:
|
||||
virtual std::uint64_t get_directory_item_count(const std::string &api_path) const = 0;
|
||||
|
||||
virtual directory_item_list get_directory_items(const std::string &api_path) const = 0;
|
||||
|
||||
virtual std::uint64_t get_file_size(const std::string &api_path) const = 0;
|
||||
|
||||
virtual api_error get_item_meta(const std::string &api_path, const std::string &name,
|
||||
std::string &value) const = 0;
|
||||
|
||||
virtual api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const = 0;
|
||||
|
||||
virtual NTSTATUS get_security_by_name(PWSTR file_name, PUINT32 attributes,
|
||||
PSECURITY_DESCRIPTOR descriptor,
|
||||
std::uint64_t *descriptor_size) = 0;
|
||||
|
||||
virtual std::uint64_t get_total_drive_space() const = 0;
|
||||
|
||||
virtual std::uint64_t get_total_item_count() const = 0;
|
||||
|
||||
virtual std::uint64_t get_used_drive_space() const = 0;
|
||||
|
||||
virtual void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) const = 0;
|
||||
|
||||
virtual api_error populate_file_info(const std::string &api_path, remote::file_info &fi) = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_DRIVES_WINFSP_I_WINFSP_DRIVE_HPP_
|
94
include/drives/winfsp/remotewinfsp/i_remote_instance.hpp
Normal file
94
include/drives/winfsp/remotewinfsp/i_remote_instance.hpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_WINFSP_REMOTEWINFSP_I_REMOTE_INSTANCE_HPP_
|
||||
#define INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_I_REMOTE_INSTANCE_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "drives/remote/i_remote_json.hpp"
|
||||
|
||||
namespace repertory::remote_winfsp {
|
||||
class i_remote_instance : public virtual i_remote_json {
|
||||
INTERFACE_SETUP(i_remote_instance);
|
||||
|
||||
public:
|
||||
virtual packet::error_type winfsp_can_delete(PVOID fileDesc, PWSTR fileName) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_cleanup(PVOID fileDesc, PWSTR fileName, UINT32 flags,
|
||||
BOOLEAN &wasClosed) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_close(PVOID fileDesc) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_create(PWSTR fileName, UINT32 createOptions,
|
||||
UINT32 grantedAccess, UINT32 fileAttributes,
|
||||
UINT64 allocationSize, PVOID *fileDesc,
|
||||
remote::file_info *fileInfo, std::string &normalizedName,
|
||||
BOOLEAN &exists) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_flush(PVOID fileDesc, remote::file_info *fileInfo) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_get_dir_buffer(PVOID fileDesc, PVOID *&ptr) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_get_file_info(PVOID fileDesc, remote::file_info *fileInfo) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_get_security_by_name(PWSTR fileName, PUINT32 fileAttributes,
|
||||
std::uint64_t *securityDescriptorSize,
|
||||
std::wstring &strDescriptor) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_get_volume_info(UINT64 &totalSize, UINT64 &freeSize,
|
||||
std::string &volumeLabel) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_mounted(const std::wstring &location) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_open(PWSTR fileName, UINT32 createOptions, UINT32 grantedAccess,
|
||||
PVOID *fileDesc, remote::file_info *fileInfo,
|
||||
std::string &normalizedName) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_overwrite(PVOID fileDesc, UINT32 fileAttributes,
|
||||
BOOLEAN replaceFileAttributes, UINT64 allocationSize,
|
||||
remote::file_info *fileInfo) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_read(PVOID fileDesc, PVOID buffer, UINT64 offset, UINT32 length,
|
||||
PUINT32 bytesTransferred) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_read_directory(PVOID fileDesc, PWSTR pattern, PWSTR marker,
|
||||
json &itemList) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_rename(PVOID fileDesc, PWSTR fileName, PWSTR newFileName,
|
||||
BOOLEAN replaceIfExists) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_set_basic_info(PVOID fileDesc, UINT32 fileAttributes,
|
||||
UINT64 creationTime, UINT64 lastAccessTime,
|
||||
UINT64 lastWriteTime, UINT64 changeTime,
|
||||
remote::file_info *fileInfo) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_set_file_size(PVOID fileDesc, UINT64 newSize,
|
||||
BOOLEAN setAllocationSize,
|
||||
remote::file_info *fileInfo) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_unmounted(const std::wstring &location) = 0;
|
||||
|
||||
virtual packet::error_type winfsp_write(PVOID fileDesc, PVOID buffer, UINT64 offset,
|
||||
UINT32 length, BOOLEAN writeToEndOfFile,
|
||||
BOOLEAN constrainedIo, PUINT32 bytesTransferred,
|
||||
remote::file_info *fileInfo) = 0;
|
||||
};
|
||||
typedef std::function<std::unique_ptr<i_remote_instance>()> remote_instance_factory;
|
||||
} // namespace repertory::remote_winfsp
|
||||
|
||||
#endif // INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_I_REMOTE_INSTANCE_HPP_
|
125
include/drives/winfsp/remotewinfsp/remote_client.hpp
Normal file
125
include/drives/winfsp/remotewinfsp/remote_client.hpp
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_CLIENT_HPP_
|
||||
#define INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_CLIENT_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/packet/packet.hpp"
|
||||
#include "comm/packet/packet_client.hpp"
|
||||
#include "drives/winfsp/remotewinfsp/i_remote_instance.hpp"
|
||||
#include "drives/remote/remote_open_file_table.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
namespace remote_winfsp {
|
||||
class remote_client final : public remote_open_file_table, public virtual i_remote_instance {
|
||||
public:
|
||||
explicit remote_client(const app_config &config);
|
||||
|
||||
private:
|
||||
const app_config &config_;
|
||||
packet_client packet_client_;
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
#define to_handle(x) (x)
|
||||
#else
|
||||
static OSHandle to_handle(PVOID file_desc) {
|
||||
return static_cast<OSHandle>(reinterpret_cast<std::uint64_t>(file_desc));
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void delete_open_directory(void * /*dir*/) override {}
|
||||
|
||||
public:
|
||||
packet::error_type json_create_directory_snapshot(const std::string &path,
|
||||
json &json_data) override;
|
||||
|
||||
packet::error_type json_read_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle,
|
||||
const std::uint32_t &page,
|
||||
json &json_data) override;
|
||||
|
||||
packet::error_type json_release_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type winfsp_can_delete(PVOID file_desc, PWSTR file_name) override;
|
||||
|
||||
packet::error_type winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags,
|
||||
BOOLEAN &was_closed) override;
|
||||
|
||||
packet::error_type winfsp_close(PVOID file_desc) override;
|
||||
|
||||
packet::error_type winfsp_create(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
|
||||
UINT32 attributes, UINT64 allocation_size, PVOID *file_desc,
|
||||
remote::file_info *file_info, std::string &normalized_name,
|
||||
BOOLEAN &exists) override;
|
||||
|
||||
packet::error_type winfsp_flush(PVOID file_desc, remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr) override;
|
||||
|
||||
packet::error_type winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
|
||||
std::uint64_t *descriptor_size,
|
||||
std::wstring &string_descriptor) override;
|
||||
|
||||
packet::error_type winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) override;
|
||||
|
||||
packet::error_type winfsp_mounted(const std::wstring &location) override;
|
||||
|
||||
packet::error_type winfsp_open(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
|
||||
PVOID *file_desc, remote::file_info *file_info,
|
||||
std::string &normalized_name) override;
|
||||
|
||||
packet::error_type winfsp_overwrite(PVOID file_desc, UINT32 attributes,
|
||||
BOOLEAN replace_attributes, UINT64 allocation_size,
|
||||
remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
|
||||
PUINT32 bytes_transferred) override;
|
||||
|
||||
packet::error_type winfsp_read_directory(PVOID file_desc, PWSTR pattern, PWSTR marker,
|
||||
json &itemList) override;
|
||||
|
||||
packet::error_type winfsp_rename(PVOID file_desc, PWSTR file_name, PWSTR new_file_name,
|
||||
BOOLEAN replace_if_exists) override;
|
||||
|
||||
packet::error_type 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) override;
|
||||
|
||||
packet::error_type winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
|
||||
BOOLEAN set_allocation_size,
|
||||
remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_unmounted(const std::wstring &location) override;
|
||||
|
||||
packet::error_type winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
|
||||
BOOLEAN write_to_end, BOOLEAN constrained_io,
|
||||
PUINT32 bytes_transferred, remote::file_info *file_info) override;
|
||||
};
|
||||
} // namespace remote_winfsp
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_CLIENT_HPP_
|
241
include/drives/winfsp/remotewinfsp/remote_server.hpp
Normal file
241
include/drives/winfsp/remotewinfsp/remote_server.hpp
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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.
|
||||
*/
|
||||
// NOTE: Most of the WinFSP pass-through code has been modified from:
|
||||
// https://github.com/billziss-gh/winfsp/blob/master/tst/passthrough-cpp/passthrough-cpp.cpp
|
||||
#ifndef INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_SERVER_HPP_
|
||||
#define INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_SERVER_HPP_
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "comm/packet/packet.hpp"
|
||||
#include "drives/remote/remote_server_base.hpp"
|
||||
#include "drives/winfsp/i_winfsp_drive.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
namespace remote_winfsp {
|
||||
class remote_server final : public virtual remote_server_base<i_winfsp_drive> {
|
||||
public:
|
||||
remote_server(app_config &config, i_winfsp_drive &drive, const std::string &mount_location)
|
||||
: remote_server_base(config, drive, mount_location) {}
|
||||
|
||||
private:
|
||||
std::string construct_path(std::string path);
|
||||
|
||||
packet::error_type populate_file_info(const std::string &api_path, remote::file_info &file_info);
|
||||
|
||||
void populate_stat(const char *path, const bool &directory, remote::stat &st,
|
||||
const struct _stat64 &st1);
|
||||
|
||||
public:
|
||||
// FUSE Layer
|
||||
packet::error_type fuse_access(const char *path, const std::int32_t &mask) override;
|
||||
|
||||
packet::error_type fuse_chflags(const char *path, const std::uint32_t &flags) override;
|
||||
|
||||
packet::error_type fuse_chmod(const char *path, const remote::file_mode &mode) override;
|
||||
|
||||
packet::error_type fuse_chown(const char *path, const remote::user_id &uid,
|
||||
const remote::group_id &gid) override;
|
||||
|
||||
packet::error_type fuse_destroy() override;
|
||||
|
||||
/*packet::error_type fuse_fallocate(const char *path, const std::int32_t &mode,
|
||||
const remote::file_offset &offset,
|
||||
const remote::file_offset &length,
|
||||
const remote::file_handle &handle) override ;*/
|
||||
|
||||
packet::error_type fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_fsetattr_x(const char *path, const remote::setattr_x &attr,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_fsync(const char *path, const std::int32_t &datasync,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_ftruncate(const char *path, const remote::file_offset &size,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_getattr(const char *path, remote::stat &st, bool &directory) override;
|
||||
|
||||
/*packet::error_type fuse_getxattr(const char *path, const char *name, char *value,
|
||||
const remote::file_size &size) override ;
|
||||
|
||||
packet::error_type fuse_getxattrOSX(const char *path, const char *name, char *value,
|
||||
const remote::file_size &size,
|
||||
const std::uint32_t &position) override ;*/
|
||||
|
||||
packet::error_type fuse_getxtimes(const char *path, remote::file_time &bkuptime,
|
||||
remote::file_time &crtime) override;
|
||||
|
||||
packet::error_type fuse_init() override;
|
||||
|
||||
/*packet::error_type fuse_listxattr(const char *path, char *buffer,
|
||||
const remote::file_size &size) override ;*/
|
||||
|
||||
packet::error_type fuse_mkdir(const char *path, const remote::file_mode &mode) override;
|
||||
|
||||
packet::error_type fuse_opendir(const char *path, remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_create(const char *path, const remote::file_mode &mode,
|
||||
const remote::open_flags &flags,
|
||||
remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_open(const char *path, const remote::open_flags &flags,
|
||||
remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_read(const char *path, char *buffer, const remote::file_size &read_size,
|
||||
const remote::file_offset &read_offset,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_rename(const char *from, const char *to) override;
|
||||
|
||||
packet::error_type fuse_write(const char *path, const char *buffer,
|
||||
const remote::file_size &write_size,
|
||||
const remote::file_offset &write_offset,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_write_base64(const char *path, const char *buffer,
|
||||
const remote::file_size &write_size,
|
||||
const remote::file_offset &write_offset,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_readdir(const char *path, const remote::file_offset &offset,
|
||||
const remote::file_handle &handle,
|
||||
std::string &item_path) override;
|
||||
|
||||
packet::error_type fuse_release(const char *path, const remote::file_handle &handle) override;
|
||||
|
||||
packet::error_type fuse_releasedir(const char *path, const remote::file_handle &handle) override;
|
||||
|
||||
/*packet::error_type fuse_removexattr(const char *path, const char *name) override ;*/
|
||||
|
||||
packet::error_type fuse_rmdir(const char *path) override;
|
||||
|
||||
packet::error_type fuse_setattr_x(const char *path, remote::setattr_x &attr) override;
|
||||
|
||||
packet::error_type fuse_setbkuptime(const char *path, const remote::file_time &bkuptime) override;
|
||||
|
||||
packet::error_type fuse_setchgtime(const char *path, const remote::file_time &chgtime) override;
|
||||
|
||||
packet::error_type fuse_setcrtime(const char *path, const remote::file_time &crtime) override;
|
||||
|
||||
packet::error_type fuse_setvolname(const char *volname) override;
|
||||
|
||||
/*packet::error_type fuse_setxattr(const char *path, const char *name, const char *value,
|
||||
const remote::file_size &size,
|
||||
const std::int32_t &flags) override ;
|
||||
|
||||
packet::error_type fuse_setxattr_osx(const char *path, const char *name, const char *value,
|
||||
const remote::file_size &size, const std::int32_t &flags,
|
||||
const std::uint32_t &position) override ;*/
|
||||
|
||||
packet::error_type fuse_statfs(const char *path, const std::uint64_t &frsize,
|
||||
remote::statfs &st) override;
|
||||
|
||||
packet::error_type fuse_statfs_x(const char *path, const std::uint64_t &bsize,
|
||||
remote::statfs_x &st) override;
|
||||
|
||||
packet::error_type fuse_truncate(const char *path, const remote::file_offset &size) override;
|
||||
|
||||
packet::error_type fuse_unlink(const char *path) override;
|
||||
|
||||
packet::error_type fuse_utimens(const char *path, const remote::file_time *tv,
|
||||
const std::uint64_t &op0, const std::uint64_t &op1) override;
|
||||
|
||||
void set_fuse_uid_gid(const remote::user_id &, const remote::group_id &) override {}
|
||||
|
||||
// JSON Layer
|
||||
packet::error_type json_create_directory_snapshot(const std::string &path,
|
||||
json &json_data) override;
|
||||
|
||||
packet::error_type json_read_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle,
|
||||
const std::uint32_t &page,
|
||||
json &json_data) override;
|
||||
|
||||
packet::error_type json_release_directory_snapshot(const std::string &path,
|
||||
const remote::file_handle &handle) override;
|
||||
|
||||
// WinFSP Layer
|
||||
packet::error_type winfsp_can_delete(PVOID file_desc, PWSTR file_name) override;
|
||||
|
||||
packet::error_type winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags,
|
||||
BOOLEAN &was_closed) override;
|
||||
|
||||
packet::error_type winfsp_close(PVOID file_desc) override;
|
||||
|
||||
packet::error_type winfsp_create(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
|
||||
UINT32 attributes, UINT64 allocation_size, PVOID *file_desc,
|
||||
remote::file_info *file_info, std::string &normalized_name,
|
||||
BOOLEAN &exists) override;
|
||||
|
||||
packet::error_type winfsp_flush(PVOID file_desc, remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr) override;
|
||||
|
||||
packet::error_type winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
|
||||
std::uint64_t *descriptor_size,
|
||||
std::wstring &string_descriptor) override;
|
||||
|
||||
packet::error_type winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) override;
|
||||
|
||||
packet::error_type winfsp_mounted(const std::wstring &location) override;
|
||||
|
||||
packet::error_type winfsp_open(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
|
||||
PVOID *file_desc, remote::file_info *file_info,
|
||||
std::string &normalized_name) override;
|
||||
|
||||
packet::error_type winfsp_overwrite(PVOID file_desc, UINT32 attributes,
|
||||
BOOLEAN replace_attributes, UINT64 allocation_size,
|
||||
remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
|
||||
PUINT32 bytes_transferred) override;
|
||||
|
||||
packet::error_type winfsp_read_directory(PVOID file_desc, PWSTR pattern, PWSTR marker,
|
||||
json &item_list) override;
|
||||
|
||||
packet::error_type winfsp_rename(PVOID file_desc, PWSTR file_name, PWSTR new_file_name,
|
||||
BOOLEAN replace_if_exists) override;
|
||||
|
||||
packet::error_type 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) override;
|
||||
|
||||
packet::error_type winfsp_set_file_size(PVOID file_desc, UINT64 newSize,
|
||||
BOOLEAN set_allocation_size,
|
||||
remote::file_info *file_info) override;
|
||||
|
||||
packet::error_type winfsp_unmounted(const std::wstring &location) override;
|
||||
|
||||
packet::error_type winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
|
||||
BOOLEAN write_to_end, BOOLEAN constrained_io,
|
||||
PUINT32 bytes_transferred, remote::file_info *file_info) override;
|
||||
};
|
||||
} // namespace remote_winfsp
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_SERVER_HPP_
|
140
include/drives/winfsp/remotewinfsp/remote_winfsp_drive.hpp
Normal file
140
include/drives/winfsp/remotewinfsp/remote_winfsp_drive.hpp
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_WINFSP_DRIVE_HPP_
|
||||
#define INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_WINFSP_DRIVE_HPP_
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "drives/winfsp/remotewinfsp/i_remote_instance.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class lock_data;
|
||||
class server;
|
||||
namespace remote_winfsp {
|
||||
class remote_winfsp_drive final : public virtual FileSystemBase {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
remote_winfsp_drive(app_config &config, lock_data &lockData,
|
||||
remote_instance_factory remoteInstanceFactory);
|
||||
|
||||
~remote_winfsp_drive() override { E_CONSUMER_RELEASE(); }
|
||||
|
||||
public:
|
||||
class winfsp_service : virtual public Service {
|
||||
public:
|
||||
winfsp_service(lock_data &lock, remote_winfsp_drive &drive, std::vector<std::string> drive_args,
|
||||
app_config &config);
|
||||
|
||||
~winfsp_service() override = default;
|
||||
|
||||
private:
|
||||
app_config &config_;
|
||||
lock_data &lock_;
|
||||
remote_winfsp_drive &drive_;
|
||||
const std::vector<std::string> drive_args_;
|
||||
FileSystemHost host_;
|
||||
|
||||
protected:
|
||||
NTSTATUS OnStart(ULONG, PWSTR *) override;
|
||||
|
||||
NTSTATUS OnStop() override;
|
||||
};
|
||||
|
||||
private:
|
||||
app_config &config_;
|
||||
lock_data &lock_;
|
||||
remote_instance_factory factory_;
|
||||
std::unique_ptr<i_remote_instance> remote_instance_;
|
||||
std::unique_ptr<server> server_;
|
||||
std::string mount_location_;
|
||||
|
||||
private:
|
||||
void PopulateFileInfo(const json &item, FSP_FSCTL_FILE_INFO &file_info);
|
||||
|
||||
static void SetFileInfo(FileInfo &dest, const remote::file_info &src);
|
||||
|
||||
public:
|
||||
NTSTATUS CanDelete(PVOID file_node, PVOID file_desc, PWSTR file_name) override;
|
||||
|
||||
VOID Cleanup(PVOID file_node, PVOID file_desc, PWSTR file_name, ULONG flags) override;
|
||||
|
||||
VOID Close(PVOID file_node, PVOID file_desc) override;
|
||||
|
||||
NTSTATUS Create(PWSTR file_name, UINT32 create_options, UINT32 granted_access, UINT32 attributes,
|
||||
PSECURITY_DESCRIPTOR descriptor, UINT64 allocation_size, PVOID *file_node,
|
||||
PVOID *file_desc, OpenFileInfo *ofi) override;
|
||||
|
||||
NTSTATUS Flush(PVOID file_node, PVOID file_desc, FileInfo *file_info) override;
|
||||
|
||||
NTSTATUS GetFileInfo(PVOID file_node, PVOID file_desc, FileInfo *file_info) override;
|
||||
|
||||
NTSTATUS GetSecurityByName(PWSTR file_name, PUINT32 attributes, PSECURITY_DESCRIPTOR descriptor,
|
||||
SIZE_T *descriptor_size) override;
|
||||
|
||||
NTSTATUS GetVolumeInfo(VolumeInfo *volume_info) override;
|
||||
|
||||
NTSTATUS Init(PVOID host) override;
|
||||
|
||||
int mount(const std::vector<std::string> &drive_args);
|
||||
|
||||
NTSTATUS Mounted(PVOID host) override;
|
||||
|
||||
NTSTATUS Open(PWSTR file_name, UINT32 create_options, UINT32 granted_access, PVOID *file_node,
|
||||
PVOID *file_desc, OpenFileInfo *ofi) override;
|
||||
|
||||
NTSTATUS Overwrite(PVOID file_node, PVOID file_desc, UINT32 attributes,
|
||||
BOOLEAN replace_attributes, UINT64 allocation_size,
|
||||
FileInfo *file_info) override;
|
||||
|
||||
NTSTATUS Read(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, ULONG length,
|
||||
PULONG bytes_transferred) override;
|
||||
|
||||
NTSTATUS ReadDirectory(PVOID file_node, PVOID file_desc, PWSTR pattern, PWSTR marker,
|
||||
PVOID buffer, ULONG buffer_length, PULONG bytes_transferred) override;
|
||||
|
||||
NTSTATUS Rename(PVOID file_node, PVOID file_desc, PWSTR file_name, PWSTR new_file_name,
|
||||
BOOLEAN replace_if_exists) override;
|
||||
|
||||
NTSTATUS SetBasicInfo(PVOID file_node, PVOID file_desc, UINT32 attributes, UINT64 creation_time,
|
||||
UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time,
|
||||
FileInfo *file_info) override;
|
||||
|
||||
NTSTATUS SetFileSize(PVOID file_node, PVOID file_desc, UINT64 new_size,
|
||||
BOOLEAN set_allocation_size, FileInfo *file_info) override;
|
||||
|
||||
VOID Unmounted(PVOID host) override;
|
||||
|
||||
NTSTATUS Write(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, ULONG length,
|
||||
BOOLEAN write_to_end, BOOLEAN constrained_io, PULONG bytes_transferred,
|
||||
FileInfo *file_info) override;
|
||||
|
||||
void shutdown() { ::GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); }
|
||||
|
||||
static void display_options(int argc, char *argv[]) {}
|
||||
|
||||
static void display_version_information(int argc, char *argv[]) {}
|
||||
};
|
||||
} // namespace remote_winfsp
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_WINFSP_DRIVE_HPP_
|
177
include/drives/winfsp/winfsp_drive.hpp
Normal file
177
include/drives/winfsp/winfsp_drive.hpp
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_DRIVES_WINFSP_WINFSP_DRIVE_HPP_
|
||||
#define INCLUDE_DRIVES_WINFSP_WINFSP_DRIVE_HPP_
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "download/download_manager.hpp"
|
||||
#include "drives/eviction.hpp"
|
||||
#include "drives/i_open_file_table.hpp"
|
||||
#include "drives/open_file_table.hpp"
|
||||
#include "drives/winfsp/i_winfsp_drive.hpp"
|
||||
#include "drives/winfsp/remotewinfsp/remote_server.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "rpc/server/full_server.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class lock_data;
|
||||
class i_provider;
|
||||
class winfsp_drive final : public virtual i_winfsp_drive, public virtual FileSystemBase {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
winfsp_drive(app_config &config, lock_data &lockData, i_provider &provider);
|
||||
|
||||
~winfsp_drive() override { E_CONSUMER_RELEASE(); }
|
||||
|
||||
private:
|
||||
class winfsp_service final : virtual public Service {
|
||||
public:
|
||||
winfsp_service(lock_data &lock, winfsp_drive &drive, std::vector<std::string> drive_args,
|
||||
app_config &config);
|
||||
|
||||
~winfsp_service() override = default;
|
||||
|
||||
private:
|
||||
lock_data &lock_;
|
||||
winfsp_drive &drive_;
|
||||
const std::vector<std::string> drive_args_;
|
||||
FileSystemHost host_;
|
||||
app_config &config_;
|
||||
|
||||
protected:
|
||||
NTSTATUS OnStart(ULONG, PWSTR *) override;
|
||||
|
||||
NTSTATUS OnStop() override;
|
||||
};
|
||||
|
||||
private:
|
||||
i_provider &provider_;
|
||||
app_config &config_;
|
||||
lock_data &lock_;
|
||||
std::unique_ptr<full_server> server_;
|
||||
std::unique_ptr<open_file_table<open_file_data>> oft_;
|
||||
std::unique_ptr<download_manager> download_manager_;
|
||||
std::unique_ptr<eviction> eviction_;
|
||||
std::unique_ptr<remote_winfsp::remote_server> remote_server_;
|
||||
|
||||
private:
|
||||
static std::string parse_mount_location(const std::wstring &mount_location);
|
||||
|
||||
void populate_file_info(const std::string &api_path, const std::uint64_t &file_size,
|
||||
const api_meta_map &meta, FSP_FSCTL_OPEN_FILE_INFO &ofi);
|
||||
|
||||
void populate_file_info(const std::uint64_t &file_size, api_meta_map meta,
|
||||
FSP_FSCTL_FILE_INFO &fi);
|
||||
|
||||
static void set_file_info(remote::file_info &dest, const FSP_FSCTL_FILE_INFO &src);
|
||||
|
||||
public:
|
||||
NTSTATUS CanDelete(PVOID file_node, PVOID file_desc, PWSTR file_name) override;
|
||||
|
||||
VOID Cleanup(PVOID file_node, PVOID file_desc, PWSTR file_name, ULONG flags) override;
|
||||
|
||||
VOID Close(PVOID file_node, PVOID file_desc) override;
|
||||
|
||||
NTSTATUS Create(PWSTR file_name, UINT32 create_options, UINT32 granted_access, UINT32 attributes,
|
||||
PSECURITY_DESCRIPTOR descriptor, UINT64 allocation_size, PVOID *file_node,
|
||||
PVOID *file_desc, OpenFileInfo *ofi) override;
|
||||
|
||||
NTSTATUS Flush(PVOID file_node, PVOID file_desc, FileInfo *file_info) override;
|
||||
|
||||
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
|
||||
|
||||
directory_item_list get_directory_items(const std::string &api_path) const override;
|
||||
|
||||
NTSTATUS GetFileInfo(PVOID file_node, PVOID file_desc, FileInfo *file_info) override;
|
||||
|
||||
std::uint64_t get_file_size(const std::string &api_path) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, const std::string &name,
|
||||
std::string &value) const override;
|
||||
|
||||
NTSTATUS get_security_by_name(PWSTR file_name, PUINT32 attributes,
|
||||
PSECURITY_DESCRIPTOR descriptor,
|
||||
std::uint64_t *descriptor_size) override;
|
||||
|
||||
NTSTATUS GetSecurityByName(PWSTR file_name, PUINT32 attributes, PSECURITY_DESCRIPTOR descriptor,
|
||||
SIZE_T *descriptor_size) override;
|
||||
|
||||
std::uint64_t get_total_drive_space() const override;
|
||||
|
||||
std::uint64_t get_total_item_count() const override;
|
||||
|
||||
std::uint64_t get_used_drive_space() const override;
|
||||
|
||||
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) const override;
|
||||
|
||||
NTSTATUS GetVolumeInfo(VolumeInfo *volume_info) override;
|
||||
|
||||
NTSTATUS Init(PVOID host) override;
|
||||
|
||||
int mount(const std::vector<std::string> &drive_args);
|
||||
|
||||
NTSTATUS Mounted(PVOID host) override;
|
||||
|
||||
NTSTATUS Open(PWSTR file_name, UINT32 create_options, UINT32 granted_access, PVOID *file_node,
|
||||
PVOID *file_desc, OpenFileInfo *ofi) override;
|
||||
|
||||
NTSTATUS Overwrite(PVOID file_node, PVOID file_desc, UINT32 attributes,
|
||||
BOOLEAN replace_attributes, UINT64 allocation_size,
|
||||
FileInfo *file_info) override;
|
||||
|
||||
api_error populate_file_info(const std::string &api_path, remote::file_info &file_info) override;
|
||||
|
||||
NTSTATUS Read(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, ULONG length,
|
||||
PULONG bytes_transferred) override;
|
||||
|
||||
NTSTATUS ReadDirectory(PVOID file_node, PVOID file_desc, PWSTR pattern, PWSTR marker,
|
||||
PVOID buffer, ULONG bufferLength, PULONG bytes_transferred) override;
|
||||
|
||||
NTSTATUS Rename(PVOID file_node, PVOID file_desc, PWSTR file_name, PWSTR newFileName,
|
||||
BOOLEAN replace_if_exists) override;
|
||||
|
||||
NTSTATUS SetBasicInfo(PVOID file_node, PVOID file_desc, UINT32 attributes, UINT64 creation_time,
|
||||
UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time,
|
||||
FileInfo *file_info) override;
|
||||
|
||||
NTSTATUS SetFileSize(PVOID file_node, PVOID file_desc, UINT64 new_size,
|
||||
BOOLEAN set_allocation_size, FileInfo *file_info) override;
|
||||
|
||||
VOID Unmounted(PVOID host) override;
|
||||
|
||||
NTSTATUS Write(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, ULONG length,
|
||||
BOOLEAN write_to_end, BOOLEAN constrained_io, PULONG bytes_transferred,
|
||||
FileInfo *file_info) override;
|
||||
|
||||
void shutdown() { ::GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); }
|
||||
|
||||
static void display_options(int argc, char *argv[]) {}
|
||||
|
||||
static void display_version_information(int argc, char *argv[]) {}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_DRIVES_WINFSP_WINFSP_DRIVE_HPP_
|
51
include/events/consumers/console_consumer.hpp
Normal file
51
include/events/consumers/console_consumer.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_EVENTS_CONSUMERS_CONSOLE_CONSUMER_HPP_
|
||||
#define INCLUDE_EVENTS_CONSUMERS_CONSOLE_CONSUMER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class console_consumer final {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
console_consumer() { E_SUBSCRIBE_ALL(process_event); }
|
||||
|
||||
public:
|
||||
~console_consumer() { E_CONSUMER_RELEASE(); }
|
||||
|
||||
private:
|
||||
void process_event(const event &e) {
|
||||
#ifdef _WIN32
|
||||
#ifdef _DEBUG
|
||||
OutputDebugString((e.get_single_line() + "\n").c_str());
|
||||
#endif
|
||||
#endif
|
||||
if (e.get_event_level() == event_level::error) {
|
||||
std::cerr << e.get_single_line() << std::endl;
|
||||
} else {
|
||||
std::cout << e.get_single_line() << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_CONSUMERS_CONSOLE_CONSUMER_HPP_
|
62
include/events/consumers/logging_consumer.hpp
Normal file
62
include/events/consumers/logging_consumer.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_EVENTS_CONSUMERS_LOGGING_CONSUMER_HPP_
|
||||
#define INCLUDE_EVENTS_CONSUMERS_LOGGING_CONSUMER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class logging_consumer {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
logging_consumer(const std::string &log_directory, const event_level &level);
|
||||
|
||||
~logging_consumer();
|
||||
|
||||
private:
|
||||
const std::uint8_t MAX_LOG_FILES = 5;
|
||||
const std::uint64_t MAX_LOG_FILE_SIZE = (1024 * 1024 * 5);
|
||||
|
||||
private:
|
||||
event_level event_level_ = event_level::normal;
|
||||
const std::string log_directory_;
|
||||
const std::string log_path_;
|
||||
bool logging_active_ = true;
|
||||
std::mutex log_mutex_;
|
||||
std::condition_variable log_notify_;
|
||||
std::deque<std::shared_ptr<event>> event_queue_;
|
||||
std::unique_ptr<std::thread> logging_thread_;
|
||||
FILE *log_file_ = nullptr;
|
||||
|
||||
private:
|
||||
void check_log_roll(const size_t &count);
|
||||
|
||||
void close_log_file();
|
||||
|
||||
void logging_thread(const bool &drain = false);
|
||||
|
||||
void process_event(const event &event);
|
||||
|
||||
void reopen_log_file();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_CONSUMERS_LOGGING_CONSUMER_HPP_
|
63
include/events/event.hpp
Normal file
63
include/events/event.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_EVENTS_EVENT_HPP_
|
||||
#define INCLUDE_EVENTS_EVENT_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory {
|
||||
enum class event_level { error, warn, normal, debug, verbose };
|
||||
|
||||
event_level event_level_from_string(std::string level);
|
||||
|
||||
std::string event_level_to_string(const event_level &level);
|
||||
|
||||
class event {
|
||||
protected:
|
||||
explicit event(const bool &allow_async) : allow_async_(allow_async) {}
|
||||
|
||||
event(const std::stringstream &ss, json j, const bool &allow_async)
|
||||
: allow_async_(allow_async), ss_(ss.str()), j_(std::move(j)) {}
|
||||
|
||||
public:
|
||||
virtual ~event() = default;
|
||||
|
||||
private:
|
||||
const bool allow_async_;
|
||||
|
||||
protected:
|
||||
std::stringstream ss_;
|
||||
json j_;
|
||||
|
||||
public:
|
||||
virtual std::shared_ptr<event> clone() const = 0;
|
||||
|
||||
bool get_allow_async() const { return allow_async_; }
|
||||
|
||||
virtual event_level get_event_level() const = 0;
|
||||
|
||||
json get_json() const { return j_; }
|
||||
|
||||
virtual std::string get_name() const = 0;
|
||||
|
||||
virtual std::string get_single_line() const = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_EVENT_HPP_
|
243
include/events/event_system.hpp
Normal file
243
include/events/event_system.hpp
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_EVENTS_EVENT_SYSTEM_HPP_
|
||||
#define INCLUDE_EVENTS_EVENT_SYSTEM_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "events/event.hpp"
|
||||
#include "events/t_event_system.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
typedef t_event_system<event> event_system;
|
||||
typedef event_system::event_consumer event_consumer;
|
||||
|
||||
#define E_CAST(t) ((std::string)t)
|
||||
#define E_DOUBLE(d) utils::string::from_double(d)
|
||||
#define E_DOUBLE_PRECISE(d) \
|
||||
([](const double &d) -> std::string { \
|
||||
std::stringstream ss; \
|
||||
ss << std::fixed << std::setprecision(2) << d; \
|
||||
return ss.str(); \
|
||||
})(d)
|
||||
#define E_FROM_BOOL(t) utils::string::from_bool(t)
|
||||
#define E_FROM_EXCEPTION(e) std::string(e.what() ? e.what() : "")
|
||||
#define E_FROM_INT32(t) utils::string::from_int32(t)
|
||||
#define E_FROM_INT64(t) utils::string::from_int64(t)
|
||||
#define E_FROM_UINT16(t) utils::string::from_uint16(t)
|
||||
#define E_FROM_STRING_ARRAY(a) \
|
||||
([](const auto &array) -> std::string { \
|
||||
std::stringstream ret; \
|
||||
for (const auto &item : array) { \
|
||||
ret << (std::string(item) + " "); \
|
||||
} \
|
||||
return std::string(ret).TrimRight(); \
|
||||
})(a)
|
||||
|
||||
#define E_PERCENT(d) \
|
||||
([](const double &d) -> std::string { \
|
||||
std::stringstream ss; \
|
||||
ss << std::fixed << std::setprecision(2) << d; \
|
||||
ss << "%"; \
|
||||
return ss; \
|
||||
})(d)
|
||||
#define E_STRING(t) t
|
||||
#define E_FROM_UINT8(t) utils::string::from_uint8(t)
|
||||
#define E_FROM_UINT32(t) utils::string::from_uint32(t)
|
||||
#define E_FROM_UINT64(t) utils::string::from_uint64(t)
|
||||
#define E_FROM_SIZE_T(t) std::to_string(t)
|
||||
#define E_FROM_API_FILE_ERROR(e) api_error_to_string(e)
|
||||
|
||||
#define E_PROP(type, name, short_name, ts) \
|
||||
private: \
|
||||
void init_##short_name(const type &tv) { \
|
||||
ss_ << "|" << #short_name << "|" << ts(tv); \
|
||||
j_[#name] = ts(tv); \
|
||||
} \
|
||||
\
|
||||
public: \
|
||||
json get_##name() const { return j_[#name]; }
|
||||
|
||||
#define E_BEGIN(name, el) \
|
||||
class name final : public virtual event { \
|
||||
private: \
|
||||
name(const std::stringstream &ss, const json &j, const bool &allow_async) \
|
||||
: event(ss, j, allow_async) {} \
|
||||
\
|
||||
public: \
|
||||
~name() override = default; \
|
||||
\
|
||||
public: \
|
||||
static const event_level level = event_level::el; \
|
||||
\
|
||||
public: \
|
||||
std::string get_name() const override { return #name; } \
|
||||
\
|
||||
event_level get_event_level() const override { return name::level; } \
|
||||
\
|
||||
std::string get_single_line() const override { \
|
||||
const auto s = ss_.str(); \
|
||||
return get_name() + (s.empty() ? "" : s); \
|
||||
} \
|
||||
\
|
||||
std::shared_ptr<event> clone() const override { \
|
||||
return std::shared_ptr<name>(new name(ss_, j_, get_allow_async())); \
|
||||
}
|
||||
#define E_END() }
|
||||
|
||||
#define E_SIMPLE(event_name, el, allow_async) \
|
||||
E_BEGIN(event_name, el) \
|
||||
public: \
|
||||
event_name() : event(allow_async) {} \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE1(event_name, el, allow_async, type, name, short_name, tc) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv) : event(allow_async) { init_##short_name(tv); } \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE2(event_name, el, allow_async, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2) : event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE3(event_name, el, allow_async, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3) : event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE4(event_name, el, allow_async, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3, type4, name4, short_name4, \
|
||||
tc4) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, const type4 &tv4) \
|
||||
: event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
init_##short_name4(tv4); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_PROP(type4, name4, short_name4, tc4) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE5(event_name, el, allow_async, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3, type4, name4, short_name4, \
|
||||
tc4, type5, name5, short_name5, tc5) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, const type4 &tv4, \
|
||||
const type5 &tv5) \
|
||||
: event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
init_##short_name4(tv4); \
|
||||
init_##short_name5(tv5); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_PROP(type4, name4, short_name4, tc4) \
|
||||
E_PROP(type5, name5, short_name5, tc5) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE6(event_name, el, allow_async, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3, type4, name4, short_name4, \
|
||||
tc4, type5, name5, short_name5, tc5, type6, name6, short_name6, tc6) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, const type4 &tv4, \
|
||||
const type5 &tv5, const type6 &tv6) \
|
||||
: event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
init_##short_name4(tv4); \
|
||||
init_##short_name5(tv5); \
|
||||
init_##short_name6(tv6); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_PROP(type4, name4, short_name4, tc4) \
|
||||
E_PROP(type5, name5, short_name5, tc5) \
|
||||
E_PROP(type6, name6, short_name6, tc6) \
|
||||
E_END()
|
||||
|
||||
#define E_SIMPLE7(event_name, el, allow_async, type, name, short_name, tc, type2, name2, \
|
||||
short_name2, tc2, type3, name3, short_name3, tc3, type4, name4, short_name4, \
|
||||
tc4, type5, name5, short_name5, tc5, type6, name6, short_name6, tc6, type7, \
|
||||
name7, short_name7, tc7) \
|
||||
E_BEGIN(event_name, el) \
|
||||
explicit event_name(const type &tv, const type2 &tv2, const type3 &tv3, const type4 &tv4, \
|
||||
const type5 &tv5, const type6 &tv6, const type7 &tv7) \
|
||||
: event(allow_async) { \
|
||||
init_##short_name(tv); \
|
||||
init_##short_name2(tv2); \
|
||||
init_##short_name3(tv3); \
|
||||
init_##short_name4(tv4); \
|
||||
init_##short_name5(tv5); \
|
||||
init_##short_name6(tv6); \
|
||||
init_##short_name7(tv7); \
|
||||
} \
|
||||
E_PROP(type, name, short_name, tc) \
|
||||
E_PROP(type2, name2, short_name2, tc2) \
|
||||
E_PROP(type3, name3, short_name3, tc3) \
|
||||
E_PROP(type4, name4, short_name4, tc4) \
|
||||
E_PROP(type5, name5, short_name5, tc5) \
|
||||
E_PROP(type6, name6, short_name6, tc6) \
|
||||
E_PROP(type7, name7, short_name7, tc7) \
|
||||
E_END()
|
||||
|
||||
#define E_CONSUMER() \
|
||||
private: \
|
||||
std::vector<std::shared_ptr<repertory::event_consumer>> event_consumers_
|
||||
|
||||
#define E_CONSUMER_RELEASE() event_consumers_.clear()
|
||||
|
||||
#define E_SUBSCRIBE(name, callback) \
|
||||
event_consumers_.emplace_back( \
|
||||
std::make_shared<repertory::event_consumer>(#name, [this](const event &e) { callback(e); }))
|
||||
|
||||
#define E_SUBSCRIBE_EXACT(name, callback) \
|
||||
event_consumers_.emplace_back(std::make_shared<repertory::event_consumer>( \
|
||||
#name, [this](const event &e) { callback(dynamic_cast<const name &>(e)); }))
|
||||
|
||||
#define E_SUBSCRIBE_ALL(callback) \
|
||||
event_consumers_.emplace_back( \
|
||||
std::make_shared<repertory::event_consumer>([this](const event &e) { callback(e); }))
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_EVENT_SYSTEM_HPP_
|
417
include/events/events.hpp
Normal file
417
include/events/events.hpp
Normal file
@ -0,0 +1,417 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_EVENTS_EVENTS_HPP_
|
||||
#define INCLUDE_EVENTS_EVENTS_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE3(cache_file_processed, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_auth_begin, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, user, user, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_auth_end, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, user, user, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_auth_logout_begin, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, user, user, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_auth_logout_end, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, user, user, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_get_begin, verbose, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_get_end, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_get_range_begin, verbose, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_get_range_end, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_get_raw_begin, verbose, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_get_raw_end, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_post_begin, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, fields, fields, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_post_end, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_duration, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, duration, duration, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_post_file_begin, debug, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_post_file_end, debug, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_post_multi_part_file_begin, debug, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_post_multi_part_file_end, debug, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_tus_upload_begin, debug, true,
|
||||
std::string, file_name, fn, E_STRING,
|
||||
std::string, url, url, E_STRING,
|
||||
std::uint64_t, remain, rem, E_FROM_UINT64,
|
||||
std::uint64_t, offset, off, E_FROM_UINT64
|
||||
);
|
||||
|
||||
E_SIMPLE6(comm_tus_upload_end, debug, true,
|
||||
std::string, file_name, fn, E_STRING,
|
||||
std::string, url, url, E_STRING,
|
||||
std::uint64_t, remain, rem, E_FROM_UINT64,
|
||||
std::uint64_t, offset, OFF, E_FROM_UINT64,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_tus_upload_create_begin, debug, true,
|
||||
std::string, file_name, fn, E_STRING,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_tus_upload_create_end, debug, true,
|
||||
std::string, file_name, fn, E_STRING,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE3(debug_log, debug, true,
|
||||
std::string, function, func, E_STRING,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, data, data, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(directory_removed, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(directory_remove_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(drive_mount_failed, error, true,
|
||||
std::string, location, loc, E_STRING,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_mounted, normal, true,
|
||||
std::string, location, loc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_mount_result, normal, true,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_unmount_pending, normal, true,
|
||||
std::string, location, loc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(drive_unmounted, normal, true,
|
||||
std::string, location, loc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(event_level_changed, normal, true,
|
||||
std::string, new_event_level, level, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(failed_upload_queued, error, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(failed_upload_removed, warn, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(failed_upload_retry, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_get_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_get_api_list_failed, error, true,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_pinned, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_read_bytes_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING,
|
||||
std::size_t, retry, retry, E_FROM_SIZE_T
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_removed, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_removed_externally, warn, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_remove_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_rename_failed, error, true,
|
||||
std::string, from_api_path, FROM, E_STRING,
|
||||
std::string, to_api_path, TO, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_get_size_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(filesystem_item_added, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, parent, parent, E_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE4(filesystem_item_closed, verbose, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL,
|
||||
bool, changed, changed, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE5(filesystem_item_handle_closed, verbose, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::uint64_t, handle, handle, E_FROM_UINT64,
|
||||
std::string, source, src, E_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL,
|
||||
bool, changed, changed, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE2(filesystem_item_evicted, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(filesystem_item_get_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(filesystem_item_opened, verbose, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
bool, directory, dir, E_FROM_BOOL
|
||||
);
|
||||
|
||||
E_SIMPLE1(file_unpinned, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_begin, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_completed, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_upload_end, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_upload_failed, error, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_not_found, warn, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_queued, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_removed, debug, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_retry, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE(item_scan_begin, normal, true);
|
||||
|
||||
E_SIMPLE(item_scan_end, normal, true);
|
||||
|
||||
E_SIMPLE1(orphaned_file_deleted, warn, true,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(orphaned_file_detected, warn, true,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(orphaned_file_processed, warn, true,
|
||||
std::string, source, src, E_STRING,
|
||||
std::string, dest, dest, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(orphaned_file_processing_failed, error, true,
|
||||
std::string, source, src, E_STRING,
|
||||
std::string, dest, dest, E_STRING,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(polling_item_begin, debug, true,
|
||||
std::string, item_name, item, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(polling_item_end, debug, true,
|
||||
std::string, item_name, item, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(provider_offline, error, true,
|
||||
std::string, host_name_or_ip, host, E_STRING,
|
||||
std::uint16_t, port, port, E_FROM_UINT16
|
||||
);
|
||||
|
||||
E_SIMPLE2(repertory_exception, error, true,
|
||||
std::string, function, func, E_STRING,
|
||||
std::string, message, msg, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(rpc_server_exception, error, true,
|
||||
std::string, exception, exception, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(service_shutdown, debug, true,
|
||||
std::string, service, svc, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(skynet_import_decryption_failed, error, true,
|
||||
std::string, skylink, skylink, E_STRING,
|
||||
std::string, sub_file, sf, E_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE3(skynet_import_directory_failed, error, true,
|
||||
std::string, skylink, skylink, E_STRING,
|
||||
std::string, sub_directory, sd, E_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE3(skynet_import_file_failed, error, true,
|
||||
std::string, skylink, skylink, E_STRING,
|
||||
std::string, sub_file, sf, E_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE(skynet_portal_list_changed, normal, true);
|
||||
|
||||
E_SIMPLE(unmount_requested, normal, true);
|
||||
#ifndef _WIN32
|
||||
E_SIMPLE2(unmount_result, normal, true,
|
||||
std::string, location, loc, E_STRING,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
#endif
|
||||
// clang-format on
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_EVENTS_HPP_
|
178
include/events/t_event_system.hpp
Normal file
178
include/events/t_event_system.hpp
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_EVENTS_T_EVENT_SYSTEM_HPP_
|
||||
#define INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "events/event.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
template <typename event_type> class t_event_system final {
|
||||
public:
|
||||
t_event_system(const t_event_system &) = delete;
|
||||
t_event_system(t_event_system &&) = delete;
|
||||
t_event_system &operator=(const t_event_system &) = delete;
|
||||
t_event_system &operator=(t_event_system &&) = delete;
|
||||
|
||||
protected:
|
||||
t_event_system() = default;
|
||||
|
||||
~t_event_system() { stop(); }
|
||||
|
||||
public:
|
||||
class event_consumer final {
|
||||
public:
|
||||
explicit event_consumer(std::function<void(const event &)> callback)
|
||||
: callback_(std::move(callback)) {
|
||||
t_event_system::instance().attach(this);
|
||||
}
|
||||
|
||||
event_consumer(const std::string &event_name, std::function<void(const event &)> callback)
|
||||
: callback_(std::move(callback)) {
|
||||
t_event_system::instance().attach(event_name, this);
|
||||
}
|
||||
|
||||
~event_consumer() { t_event_system::instance().release(this); }
|
||||
|
||||
private:
|
||||
std::function<void(const event &)> callback_;
|
||||
|
||||
public:
|
||||
void notify_event(const event &event) { callback_(event); }
|
||||
};
|
||||
|
||||
private:
|
||||
static t_event_system event_system_;
|
||||
|
||||
public:
|
||||
static t_event_system &instance();
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::deque<event_consumer *>> event_consumers_;
|
||||
std::recursive_mutex consumer_mutex_;
|
||||
std::vector<std::shared_ptr<event_type>> event_list_;
|
||||
std::condition_variable event_notify_;
|
||||
std::mutex event_mutex_;
|
||||
std::unique_ptr<std::thread> event_thread_;
|
||||
std::mutex run_mutex_;
|
||||
bool stop_requested_ = false;
|
||||
|
||||
private:
|
||||
void process_events() {
|
||||
std::vector<std::shared_ptr<event_type>> events;
|
||||
{
|
||||
unique_mutex_lock l(event_mutex_);
|
||||
if (not stop_requested_ && event_list_.empty()) {
|
||||
event_notify_.wait_for(l, 5s);
|
||||
}
|
||||
|
||||
if (not event_list_.empty()) {
|
||||
events.insert(events.end(), event_list_.begin(), event_list_.end());
|
||||
event_list_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
const auto notify_events = [this](const std::string &name, const event_type &event) {
|
||||
std::deque<std::future<void>> futures;
|
||||
recur_mutex_lock l(consumer_mutex_);
|
||||
if (event_consumers_.find(name) != event_consumers_.end()) {
|
||||
for (auto *ec : event_consumers_[name]) {
|
||||
if (event.get_allow_async()) {
|
||||
futures.emplace_back(
|
||||
std::async(std::launch::async, [ec, &event]() { ec->notify_event(event); }));
|
||||
} else {
|
||||
ec->notify_event(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (not futures.empty()) {
|
||||
futures.front().get();
|
||||
futures.pop_front();
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto &e : events) {
|
||||
notify_events("", *e.get());
|
||||
notify_events(e->get_name(), *e.get());
|
||||
}
|
||||
}
|
||||
|
||||
void queue_event(event_type *e) {
|
||||
mutex_lock l(event_mutex_);
|
||||
event_list_.emplace_back(std::shared_ptr<event_type>(e));
|
||||
event_notify_.notify_all();
|
||||
}
|
||||
|
||||
public:
|
||||
void attach(event_consumer *ec) {
|
||||
recur_mutex_lock l(consumer_mutex_);
|
||||
event_consumers_[""].push_back(ec);
|
||||
}
|
||||
|
||||
void attach(const std::string &event_name, event_consumer *ec) {
|
||||
recur_mutex_lock l(consumer_mutex_);
|
||||
event_consumers_[event_name].push_back(ec);
|
||||
}
|
||||
|
||||
template <typename t, typename... args> void raise(args &&...a) {
|
||||
queue_event(new t(std::forward<args>(a)...));
|
||||
}
|
||||
|
||||
void release(event_consumer *ec) {
|
||||
recur_mutex_lock l(consumer_mutex_);
|
||||
auto it =
|
||||
std::find_if(event_consumers_.begin(), event_consumers_.end(), [&](const auto &kv) -> bool {
|
||||
return utils::collection_includes(kv.second, ec);
|
||||
});
|
||||
|
||||
if (it != event_consumers_.end()) {
|
||||
auto &q = (*it).second;
|
||||
utils::remove_element_from(q, ec);
|
||||
}
|
||||
}
|
||||
|
||||
void start() {
|
||||
mutex_lock l(run_mutex_);
|
||||
if (not event_thread_) {
|
||||
stop_requested_ = false;
|
||||
event_thread_ = std::make_unique<std::thread>([this]() {
|
||||
while (not stop_requested_) {
|
||||
process_events();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
mutex_lock l(run_mutex_);
|
||||
if (event_thread_) {
|
||||
stop_requested_ = true;
|
||||
event_notify_.notify_all();
|
||||
event_thread_->join();
|
||||
event_thread_.reset();
|
||||
process_events();
|
||||
stop_requested_ = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_
|
25
include/platform/platform.hpp
Normal file
25
include/platform/platform.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PLATFORM_PLATFORM_HPP_
|
||||
#define INCLUDE_PLATFORM_PLATFORM_HPP_
|
||||
|
||||
#include "platform/unix_platform.hpp"
|
||||
#include "platform/win32_platform.hpp"
|
||||
|
||||
#endif // INCLUDE_PLATFORM_PLATFORM_HPP_
|
62
include/platform/unix_platform.hpp
Normal file
62
include/platform/unix_platform.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PLATFORM_UNIXPLATFORM_HPP_
|
||||
#define INCLUDE_PLATFORM_UNIXPLATFORM_HPP_
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class lock_data final {
|
||||
public:
|
||||
explicit lock_data(const provider_type &pt, std::string unique_id /*= ""*/);
|
||||
|
||||
lock_data();
|
||||
|
||||
~lock_data();
|
||||
|
||||
private:
|
||||
const provider_type pt_;
|
||||
const std::string unique_id_;
|
||||
const std::string mutex_id_;
|
||||
int lock_fd_;
|
||||
int lock_status_ = EWOULDBLOCK;
|
||||
|
||||
private:
|
||||
static std::string get_state_directory();
|
||||
|
||||
static std::string get_lock_data_file();
|
||||
|
||||
std::string get_lock_file();
|
||||
|
||||
private:
|
||||
static int wait_for_lock(const int &fd, const std::uint8_t &retry_count = 30u);
|
||||
|
||||
public:
|
||||
bool get_mount_state(json &mount_state);
|
||||
|
||||
lock_result grab_lock(const std::uint8_t &retry_count = 30u);
|
||||
|
||||
bool set_mount_state(const bool &active, const std::string &mount_location, const int &pid);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_PLATFORM_UNIXPLATFORM_HPP_
|
65
include/platform/win32_platform.hpp
Normal file
65
include/platform/win32_platform.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PLATFORM_WINPLATFORM_HPP_
|
||||
#define INCLUDE_PLATFORM_WINPLATFORM_HPP_
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
#include "app_config.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class lock_data final {
|
||||
public:
|
||||
explicit lock_data(const provider_type &pt, std::string unique_id /*= ""*/)
|
||||
: pt_(pt), unique_id_(std::move(unique_id)),
|
||||
mutex_id_("repertory_" + app_config::get_provider_name(pt) + "_" + unique_id_),
|
||||
mutex_handle_(::CreateMutex(nullptr, FALSE, &mutex_id_[0u])) {}
|
||||
|
||||
lock_data()
|
||||
: pt_(provider_type::sia), unique_id_(""), mutex_id_(""),
|
||||
mutex_handle_(INVALID_HANDLE_VALUE) {}
|
||||
|
||||
~lock_data() { release(); }
|
||||
|
||||
private:
|
||||
const provider_type pt_;
|
||||
const std::string unique_id_;
|
||||
const std::string mutex_id_;
|
||||
HANDLE mutex_handle_;
|
||||
DWORD mutex_state_ = WAIT_FAILED;
|
||||
|
||||
public:
|
||||
bool get_mount_state(const provider_type &pt, json &mount_state);
|
||||
|
||||
bool get_mount_state(json &mount_state);
|
||||
|
||||
std::string get_unique_id() const { return unique_id_; }
|
||||
|
||||
lock_result grab_lock(const std::uint8_t &retryCount = 30);
|
||||
|
||||
void release();
|
||||
|
||||
bool set_mount_state(const bool &active, const std::string &mountLocation,
|
||||
const std::int64_t &pid);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_PLATFORM_WINPLATFORM_HPP_
|
123
include/providers/base_provider.hpp
Normal file
123
include/providers/base_provider.hpp
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PROVIDERS_BASE_PROVIDER_HPP_
|
||||
#define INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "db/meta_db.hpp"
|
||||
#include "providers/i_provider.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class base_provider : public i_provider {
|
||||
public:
|
||||
explicit base_provider(app_config &config);
|
||||
|
||||
~base_provider() override = default;
|
||||
|
||||
private:
|
||||
app_config &config_;
|
||||
|
||||
protected:
|
||||
api_item_added_callback api_item_added_;
|
||||
meta_db meta_db_;
|
||||
mutable std::recursive_mutex notify_added_mutex_;
|
||||
i_open_file_table *oft_ = nullptr;
|
||||
|
||||
protected:
|
||||
app_config &get_config() { return config_; }
|
||||
|
||||
app_config &get_config() const { return config_; }
|
||||
|
||||
virtual std::string format_api_path(std::string api_path) const { return api_path; }
|
||||
|
||||
virtual std::string &restore_api_path(std::string &api_path) const { return api_path; }
|
||||
|
||||
void notify_directory_added(const std::string &api_path, const std::string &api_parent) const {
|
||||
const_cast<base_provider *>(this)->notify_directory_added(api_path, api_parent);
|
||||
}
|
||||
|
||||
virtual void notify_directory_added(const std::string &api_path, const std::string &api_parent);
|
||||
|
||||
api_error notify_file_added(const std::string &api_path, const std::string &api_parent,
|
||||
const std::uint64_t &size) const {
|
||||
return const_cast<base_provider *>(this)->notify_file_added(api_path, api_parent, size);
|
||||
}
|
||||
|
||||
virtual api_error notify_file_added(const std::string &api_path, const std::string &api_parent,
|
||||
const std::uint64_t &size) = 0;
|
||||
|
||||
void remove_item_meta(const std::string &api_path) {
|
||||
return meta_db_.remove_item_meta(format_api_path(api_path));
|
||||
}
|
||||
|
||||
void update_filesystem_item(const bool &directory, const api_error &error,
|
||||
const std::string &api_path, filesystem_item &fsi) const;
|
||||
|
||||
public:
|
||||
api_error create_directory_clone_source_meta(const std::string &source_api_path,
|
||||
const std::string &api_path) override;
|
||||
|
||||
api_error create_file(const std::string &api_path, api_meta_map &meta) override;
|
||||
|
||||
api_error get_api_path_from_source(const std::string &source_path,
|
||||
std::string &api_path) const override;
|
||||
|
||||
api_error get_filesystem_item(const std::string &api_path, const bool &directory,
|
||||
filesystem_item &fsi) const override;
|
||||
|
||||
api_error get_filesystem_item_and_file(const std::string &api_path, api_file &file,
|
||||
filesystem_item &fsi) const override;
|
||||
|
||||
api_error get_filesystem_item_from_source_path(const std::string &source_path,
|
||||
filesystem_item &fsi) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, const std::string &key,
|
||||
std::string &value) const override;
|
||||
|
||||
std::vector<std::string> get_pinned_files() const override { return meta_db_.get_pinned_files(); }
|
||||
|
||||
std::uint64_t get_used_drive_space() const override;
|
||||
|
||||
bool is_file_writeable(const std::string &) const override { return true; }
|
||||
|
||||
api_error remove_item_meta(const std::string &api_path, const std::string &key) override {
|
||||
return meta_db_.remove_item_meta(format_api_path(api_path), key);
|
||||
}
|
||||
|
||||
api_error set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) override {
|
||||
return meta_db_.set_item_meta(format_api_path(api_path), key, value);
|
||||
}
|
||||
|
||||
api_error set_item_meta(const std::string &api_path, const api_meta_map &meta) override {
|
||||
return meta_db_.set_item_meta(format_api_path(api_path), meta);
|
||||
}
|
||||
|
||||
api_error set_source_path(const std::string &api_path, const std::string &source_path) override {
|
||||
return meta_db_.set_source_path(format_api_path(api_path), source_path);
|
||||
}
|
||||
|
||||
bool start(api_item_added_callback api_item_added, i_open_file_table *oft) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_
|
115
include/providers/i_provider.hpp
Normal file
115
include/providers/i_provider.hpp
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PROVIDERS_I_PROVIDER_HPP_
|
||||
#define INCLUDE_PROVIDERS_I_PROVIDER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_open_file_table;
|
||||
class i_provider {
|
||||
INTERFACE_SETUP(i_provider);
|
||||
|
||||
public:
|
||||
virtual api_error create_directory(const std::string &api_path, const api_meta_map &meta) = 0;
|
||||
|
||||
virtual api_error create_directory_clone_source_meta(const std::string &source_api_path,
|
||||
const std::string &api_path) = 0;
|
||||
|
||||
virtual api_error create_file(const std::string &api_path, api_meta_map &meta) = 0;
|
||||
|
||||
virtual api_error get_api_path_from_source(const std::string &source_path,
|
||||
std::string &api_path) const = 0;
|
||||
|
||||
virtual api_error get_file_list(api_file_list &list) const = 0;
|
||||
|
||||
virtual std::uint64_t get_directory_item_count(const std::string &api_path) const = 0;
|
||||
|
||||
virtual api_error get_directory_items(const std::string &api_path,
|
||||
directory_item_list &list) const = 0;
|
||||
|
||||
virtual api_error get_file(const std::string &api_path, api_file &file) const = 0;
|
||||
|
||||
virtual api_error get_file_size(const std::string &api_path, std::uint64_t &file_size) const = 0;
|
||||
|
||||
virtual api_error get_filesystem_item(const std::string &api_path, const bool &directory,
|
||||
filesystem_item &fsi) const = 0;
|
||||
|
||||
virtual api_error get_filesystem_item_and_file(const std::string &api_path, api_file &file,
|
||||
filesystem_item &fsi) const = 0;
|
||||
|
||||
virtual api_error get_filesystem_item_from_source_path(const std::string &source_path,
|
||||
filesystem_item &fsi) const = 0;
|
||||
|
||||
virtual std::vector<std::string> get_pinned_files() const = 0;
|
||||
|
||||
virtual api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const = 0;
|
||||
|
||||
virtual api_error get_item_meta(const std::string &api_path, const std::string &key,
|
||||
std::string &value) const = 0;
|
||||
|
||||
virtual std::uint64_t get_total_drive_space() const = 0;
|
||||
|
||||
virtual std::uint64_t get_total_item_count() const = 0;
|
||||
|
||||
virtual provider_type get_provider_type() const = 0;
|
||||
|
||||
virtual std::uint64_t get_used_drive_space() const = 0;
|
||||
|
||||
virtual bool is_directory(const std::string &api_path) const = 0;
|
||||
|
||||
virtual bool is_file(const std::string &api_path) const = 0;
|
||||
|
||||
virtual bool is_file_writeable(const std::string &api_path) const = 0;
|
||||
|
||||
virtual bool is_online() const = 0;
|
||||
|
||||
virtual bool is_rename_supported() const = 0;
|
||||
|
||||
virtual api_error read_file_bytes(const std::string &api_path, const std::size_t &size,
|
||||
const std::uint64_t &offset, std::vector<char> &data,
|
||||
const bool &stop_requested) = 0;
|
||||
|
||||
virtual api_error remove_directory(const std::string &api_path) = 0;
|
||||
|
||||
virtual api_error remove_file(const std::string &api_path) = 0;
|
||||
|
||||
virtual api_error remove_item_meta(const std::string &api_path, const std::string &key) = 0;
|
||||
|
||||
virtual api_error rename_file(const std::string &fromApiPath, const std::string &toApiPath) = 0;
|
||||
|
||||
virtual api_error set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) = 0;
|
||||
|
||||
virtual api_error set_item_meta(const std::string &api_path, const api_meta_map &meta) = 0;
|
||||
|
||||
virtual api_error set_source_path(const std::string &api_path,
|
||||
const std::string &source_path) = 0;
|
||||
|
||||
virtual bool start(api_item_added_callback api_item_added, i_open_file_table *oft) = 0;
|
||||
|
||||
virtual void stop() = 0;
|
||||
|
||||
virtual api_error upload_file(const std::string &api_path, const std::string &source_path,
|
||||
const std::string &encryption_token) = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_PROVIDERS_I_PROVIDER_HPP_
|
115
include/providers/passthrough/passthroughprovider.hpp
Normal file
115
include/providers/passthrough/passthroughprovider.hpp
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PROVIDERS_PASSTHROUGH_PASSTHROUGHPROVIDER_HPP_
|
||||
#define INCLUDE_PROVIDERS_PASSTHROUGH_PASSTHROUGHPROVIDER_HPP_
|
||||
#if defined(REPERTORY_TESTING_NEW)
|
||||
|
||||
#include "common.hpp"
|
||||
#include "providers/basebase_provider.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class CPassthroughProvider final : public base_provider {
|
||||
public:
|
||||
explicit CPassthroughProvider(app_config &config)
|
||||
: base_provider(config), passthroughLocation_("" /*config.GetPassthroughConfig().Location*/) {
|
||||
}
|
||||
~CPassthroughProvider() override = default;
|
||||
|
||||
private:
|
||||
const std::string passthroughLocation_;
|
||||
|
||||
private:
|
||||
std::string ConstructFullPath(const std::string &api_path) const;
|
||||
|
||||
protected:
|
||||
api_error notify_file_added(const std::string &api_path, const std::string &api_parent,
|
||||
const std::uint64_t &size) override;
|
||||
|
||||
public:
|
||||
api_error CreateDirectory(const std::string &api_path, const api_meta_map &metaMap) override;
|
||||
|
||||
api_error get_file_list(ApiFileList &fileList) const override;
|
||||
|
||||
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
|
||||
|
||||
api_error get_directory_items(const std::string &api_path,
|
||||
directory_item_list &list) const override;
|
||||
|
||||
api_error GetFile(const std::string &api_path, ApiFile &file) const override;
|
||||
|
||||
api_error GetFileSize(const std::string &api_path, std::uint64_t &fileSize) const override;
|
||||
|
||||
api_error get_filesystem_item(const std::string &api_path, const bool &directory,
|
||||
FileSystemItem &fileSystemItem) const override;
|
||||
|
||||
api_error get_filesystem_item_from_source_path(const std::string &sourceFilePath,
|
||||
FileSystemItem &fileSystemItem) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const override;
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, const std::string &key,
|
||||
std::string &value) const override;
|
||||
|
||||
provider_type get_provider_type() const override { return provider_type::passthrough; }
|
||||
|
||||
std::uint64_t get_total_drive_space() const override;
|
||||
|
||||
std::uint64_t get_total_item_count() const override;
|
||||
|
||||
std::uint64_t get_used_drive_space() const override;
|
||||
|
||||
bool IsDirectory(const std::string &api_path) const override;
|
||||
|
||||
bool IsFile(const std::string &api_path) const override;
|
||||
|
||||
bool IsOnline() const override { return true; }
|
||||
|
||||
bool is_rename_supported() const override { return true; }
|
||||
|
||||
api_error read_file_bytes(const std::string &apiFilepath, const std::size_t &size,
|
||||
const std::uint64_t &offset, std::vector<char> &data,
|
||||
const bool &stop_requested) override;
|
||||
|
||||
api_error RemoveDirectory(const std::string &api_path) override;
|
||||
|
||||
api_error RemoveFile(const std::string &api_path) override;
|
||||
|
||||
api_error RenameFile(const std::string &fromApiPath, const std::string &toApiPath) override;
|
||||
|
||||
api_error remove_item_meta(const std::string &api_path, const std::string &key) override;
|
||||
|
||||
api_error set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) override;
|
||||
|
||||
api_error set_item_meta(const std::string &api_path, const api_meta_map &meta) override;
|
||||
|
||||
api_error set_source_path(const std::string &api_path, const std::string &sourcePath) override;
|
||||
|
||||
bool Start(api_item_added_callback apiItemAdded, i_open_file_table *openFileTable) override;
|
||||
|
||||
void Stop() override;
|
||||
|
||||
api_error upload_file(const std::string &api_path, const std::string &sourcePath,
|
||||
const std::string &encryptionToken) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_TESTING_NEW
|
||||
#endif // INCLUDE_PROVIDERS_PASSTHROUGH_PASSTHROUGHPROVIDER_HPP_
|
31
include/providers/provider.hpp
Normal file
31
include/providers/provider.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PROVIDERS_PROVIDER_HPP_
|
||||
#define INCLUDE_PROVIDERS_PROVIDER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class i_provider;
|
||||
std::unique_ptr<i_provider> create_provider(const provider_type &pt, app_config &config);
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_PROVIDERS_PROVIDER_HPP_
|
114
include/providers/s3/s3_provider.hpp
Normal file
114
include/providers/s3/s3_provider.hpp
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PROVIDERS_S3_S3_PROVIDER_HPP_
|
||||
#define INCLUDE_PROVIDERS_S3_S3_PROVIDER_HPP_
|
||||
#if defined(REPERTORY_ENABLE_S3)
|
||||
|
||||
#include "common.hpp"
|
||||
#include "db/directory_db.hpp"
|
||||
#include "providers/base_provider.hpp"
|
||||
#include "upload/upload_manager.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class i_s3_comm;
|
||||
class s3_provider final : public base_provider {
|
||||
public:
|
||||
s3_provider(app_config &config, i_s3_comm &s3_comm);
|
||||
|
||||
private:
|
||||
i_s3_comm &s3_comm_;
|
||||
directory_db directory_db_;
|
||||
upload_manager upload_manager_;
|
||||
std::uint64_t total_item_count_ = 0u;
|
||||
|
||||
private:
|
||||
void build_directories();
|
||||
|
||||
void update_item_meta(directory_item &di, const bool &format_path) const;
|
||||
|
||||
void upload_completed(const std::string &, const std::string &, const json &) {}
|
||||
|
||||
api_error upload_handler(const upload_manager::upload &upload, json &, json &);
|
||||
|
||||
protected:
|
||||
std::string format_api_path(std::string api_path) const override;
|
||||
|
||||
void notify_directory_added(const std::string &api_path, const std::string &api_parent) override;
|
||||
|
||||
api_error notify_file_added(const std::string &api_path, const std::string &api_parent,
|
||||
const std::uint64_t &size) override;
|
||||
|
||||
std::string &restore_api_path(std::string &api_path) const override;
|
||||
|
||||
public:
|
||||
api_error create_directory(const std::string &api_path, const api_meta_map &meta) override;
|
||||
|
||||
api_error create_file(const std::string &api_path, api_meta_map &meta) override;
|
||||
|
||||
api_error get_file_list(api_file_list &list) const override;
|
||||
|
||||
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
|
||||
|
||||
api_error get_directory_items(const std::string &api_path,
|
||||
directory_item_list &list) const override;
|
||||
|
||||
api_error get_file(const std::string &api_path, api_file &file) const override;
|
||||
|
||||
api_error get_file_size(const std::string &api_path, std::uint64_t &file_size) const override;
|
||||
|
||||
provider_type get_provider_type() const override { return provider_type::s3; }
|
||||
|
||||
std::uint64_t get_total_drive_space() const override {
|
||||
return std::numeric_limits<std::int64_t>::max() / std::int64_t(2);
|
||||
}
|
||||
|
||||
std::uint64_t get_total_item_count() const override { return total_item_count_; }
|
||||
|
||||
bool is_directory(const std::string &api_path) const override;
|
||||
|
||||
bool is_file(const std::string &api_path) const override;
|
||||
|
||||
bool is_online() const override;
|
||||
|
||||
bool is_processing(const std::string &api_path) const;
|
||||
|
||||
bool is_rename_supported() const override { return false; }
|
||||
|
||||
api_error read_file_bytes(const std::string &api_path, const std::size_t &size,
|
||||
const std::uint64_t &offset, std::vector<char> &data,
|
||||
const bool &stop_requested) override;
|
||||
|
||||
api_error remove_directory(const std::string &api_path) override;
|
||||
|
||||
api_error remove_file(const std::string &api_path) override;
|
||||
|
||||
api_error rename_file(const std::string &from_api_path, const std::string &to_api_path) override;
|
||||
|
||||
bool start(api_item_added_callback api_item_added, i_open_file_table *oft) override;
|
||||
|
||||
void stop() override;
|
||||
|
||||
api_error upload_file(const std::string &api_path, const std::string &source_path,
|
||||
const std::string &encryption_token) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_ENABLE_S3
|
||||
#endif // INCLUDE_PROVIDERS_S3_S3_PROVIDER_HPP_
|
136
include/providers/sia/sia_provider.hpp
Normal file
136
include/providers/sia/sia_provider.hpp
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PROVIDERS_SIA_SIAPROVIDER_HPP_
|
||||
#define INCLUDE_PROVIDERS_SIA_SIAPROVIDER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "providers/base_provider.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class i_comm;
|
||||
class sia_provider : public base_provider {
|
||||
public:
|
||||
sia_provider(app_config &config, i_comm &comm);
|
||||
|
||||
~sia_provider() override = default;
|
||||
|
||||
private:
|
||||
i_comm &comm_;
|
||||
std::uint64_t total_drive_space_ = 0u;
|
||||
bool stop_requested_ = false;
|
||||
std::mutex start_stop_mutex_;
|
||||
std::condition_variable start_stop_notify_;
|
||||
std::unique_ptr<std::thread> drive_space_thread_;
|
||||
|
||||
private:
|
||||
api_item_added_callback &get_api_item_added() { return api_item_added_; }
|
||||
|
||||
i_comm &get_comm() { return comm_; }
|
||||
|
||||
i_comm &get_comm() const { return comm_; } // TODO Fix non-const reference return
|
||||
|
||||
private:
|
||||
void calculate_total_drive_space();
|
||||
|
||||
api_error calculate_used_drive_space(std::uint64_t &used_space);
|
||||
|
||||
void drive_space_thread();
|
||||
|
||||
bool processed_orphaned_file(const std::string &source_path,
|
||||
const std::string &api_path = "") const;
|
||||
|
||||
void remove_deleted_files();
|
||||
|
||||
void remove_expired_orphaned_files();
|
||||
|
||||
void remove_unknown_source_files();
|
||||
|
||||
protected:
|
||||
api_error check_file_exists(const std::string &api_path) const;
|
||||
|
||||
bool check_directory_found(const json &error) const;
|
||||
|
||||
bool check_not_found(const json &error) const;
|
||||
|
||||
virtual void cleanup();
|
||||
|
||||
void create_api_file(const json &json_file, const std::string &path_name, api_file &file) const;
|
||||
|
||||
api_error get_directory(const std::string &api_path, json &result, json &error) const;
|
||||
|
||||
api_error notify_file_added(const std::string &api_path, const std::string &api_parent,
|
||||
const std::uint64_t &size) override;
|
||||
|
||||
void set_api_file_dates(const json &file, api_file &apiFile) const;
|
||||
|
||||
public:
|
||||
api_error create_directory(const std::string &api_path, const api_meta_map &meta) override;
|
||||
|
||||
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
|
||||
|
||||
api_error get_directory_items(const std::string &api_path,
|
||||
directory_item_list &list) const override;
|
||||
|
||||
api_error get_file(const std::string &api_path, api_file &file) const override;
|
||||
|
||||
api_error get_file_list(api_file_list &list) const override;
|
||||
|
||||
api_error get_file_size(const std::string &api_path, std::uint64_t &file_size) const override;
|
||||
|
||||
api_error get_filesystem_item(const std::string &api_path, const bool &directory,
|
||||
filesystem_item &fsi) const override;
|
||||
|
||||
api_error get_filesystem_item_and_file(const std::string &api_path, api_file &apiFile,
|
||||
filesystem_item &fsi) const override;
|
||||
|
||||
provider_type get_provider_type() const override { return provider_type::sia; }
|
||||
|
||||
std::uint64_t get_total_drive_space() const override { return total_drive_space_; }
|
||||
|
||||
std::uint64_t get_total_item_count() const override;
|
||||
|
||||
bool is_directory(const std::string &api_path) const override;
|
||||
|
||||
bool is_file(const std::string &api_path) const override;
|
||||
|
||||
bool is_online() const override;
|
||||
|
||||
bool is_rename_supported() const override { return true; }
|
||||
|
||||
api_error read_file_bytes(const std::string &api_path, const std::size_t &size,
|
||||
const std::uint64_t &offset, std::vector<char> &buffer,
|
||||
const bool &stop_requested) override;
|
||||
|
||||
api_error remove_directory(const std::string &api_path) override;
|
||||
|
||||
api_error remove_file(const std::string &api_path) override;
|
||||
|
||||
api_error rename_file(const std::string &from_api_path, const std::string &to_api_path) override;
|
||||
|
||||
bool start(api_item_added_callback api_item_added, i_open_file_table *oft) override;
|
||||
|
||||
void stop() override;
|
||||
|
||||
api_error upload_file(const std::string &api_path, const std::string &source_path,
|
||||
const std::string &) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_PROVIDERS_SIA_SIAPROVIDER_HPP_
|
139
include/providers/skynet/skynet_provider.hpp
Normal file
139
include/providers/skynet/skynet_provider.hpp
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_PROVIDERS_SKYNET_SKYNET_PROVIDER_HPP_
|
||||
#define INCLUDE_PROVIDERS_SKYNET_SKYNET_PROVIDER_HPP_
|
||||
#if defined(REPERTORY_ENABLE_SKYNET)
|
||||
|
||||
#include "common.hpp"
|
||||
#include "db/directory_db.hpp"
|
||||
#include "db/meta_db.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "providers/base_provider.hpp"
|
||||
#include "upload/upload_manager.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class i_comm;
|
||||
class skynet_provider final : public base_provider {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
skynet_provider(app_config &config, i_comm &comm);
|
||||
|
||||
~skynet_provider() override { E_CONSUMER_RELEASE(); }
|
||||
|
||||
private:
|
||||
i_comm &comm_;
|
||||
directory_db directory_db_;
|
||||
upload_manager upload_manager_;
|
||||
bool stop_requested_ = false;
|
||||
std::atomic<std::size_t> next_download_index_;
|
||||
std::atomic<std::size_t> next_upload_index_;
|
||||
std::shared_ptr<std::vector<host_config>> download_list_;
|
||||
std::shared_ptr<std::vector<host_config>> upload_list_;
|
||||
mutable std::mutex portal_mutex_;
|
||||
|
||||
private:
|
||||
std::size_t get_retry_count() const;
|
||||
|
||||
void populate_api_file(api_file &file) const;
|
||||
|
||||
void process_export(json &result, const std::string &api_path) const;
|
||||
|
||||
void upload_completed(const std::string &api_path, const std::string &, const json &data);
|
||||
|
||||
api_error upload_handler(const upload_manager::upload &upload, json &data, json &error);
|
||||
|
||||
protected:
|
||||
void notify_directory_added(const std::string &api_path, const std::string &api_parent) override;
|
||||
|
||||
api_error notify_file_added(const std::string &, const std::string &,
|
||||
const std::uint64_t &) override;
|
||||
|
||||
public:
|
||||
api_error create_directory(const std::string &api_path, const api_meta_map &meta) override;
|
||||
|
||||
api_error create_file(const std::string &api_path, api_meta_map &meta) override;
|
||||
|
||||
json export_all() const;
|
||||
|
||||
json export_list(const std::vector<std::string> &api_path_list) const;
|
||||
|
||||
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
|
||||
|
||||
api_error get_directory_items(const std::string &api_path,
|
||||
directory_item_list &list) const override;
|
||||
|
||||
api_error get_file(const std::string &api_path, api_file &file) const override;
|
||||
|
||||
api_error get_file_list(api_file_list &list) const override;
|
||||
|
||||
api_error get_file_size(const std::string &api_path, std::uint64_t &file_size) const override;
|
||||
|
||||
host_config get_host_config(const bool &upload);
|
||||
|
||||
provider_type get_provider_type() const override { return provider_type::skynet; }
|
||||
|
||||
api_error get_skynet_metadata(const std::string &skylink, json &json_meta);
|
||||
|
||||
std::uint64_t get_total_drive_space() const override {
|
||||
return std::numeric_limits<std::int64_t>::max() / std::int64_t(2);
|
||||
}
|
||||
|
||||
std::uint64_t get_total_item_count() const override {
|
||||
return directory_db_.get_total_item_count();
|
||||
}
|
||||
|
||||
api_error import_skylink(const skylink_import &si);
|
||||
|
||||
bool is_directory(const std::string &api_path) const override;
|
||||
|
||||
bool is_file(const std::string &api_path) const override;
|
||||
|
||||
bool is_file_writeable(const std::string &api_path) const override;
|
||||
|
||||
bool is_online() const override { return true; }
|
||||
|
||||
bool is_processing(const std::string &api_path) const;
|
||||
|
||||
bool is_rename_supported() const override { return true; }
|
||||
|
||||
api_error read_file_bytes(const std::string &api_path, const std::size_t &size,
|
||||
const std::uint64_t &offset, std::vector<char> &data,
|
||||
const bool &stop_requested) override;
|
||||
|
||||
api_error remove_directory(const std::string &api_path) override;
|
||||
|
||||
api_error remove_file(const std::string &api_path) override;
|
||||
|
||||
api_error rename_file(const std::string &from_api_path, const std::string &to_api_path) override;
|
||||
|
||||
bool start(api_item_added_callback api_item_added, i_open_file_table *oft) override;
|
||||
|
||||
void stop() override;
|
||||
|
||||
bool update_portal_list();
|
||||
|
||||
api_error upload_file(const std::string &api_path, const std::string &source_path,
|
||||
const std::string &encryption_token) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_ENABLE_SKYNET
|
||||
#endif // INCLUDE_PROVIDERS_SKYNET_SKYNET_PROVIDER_HPP_
|
70
include/rpc/client/client.hpp
Normal file
70
include/rpc/client/client.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_RPC_CLIENT_CLIENT_HPP_
|
||||
#define INCLUDE_RPC_CLIENT_CLIENT_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
#include "types/skynet.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class client {
|
||||
public:
|
||||
explicit client(rpc_host_info host_info);
|
||||
|
||||
private:
|
||||
const rpc_host_info host_info_;
|
||||
std::atomic<std::uint32_t> request_id_;
|
||||
|
||||
private:
|
||||
rpc_response make_request(const std::string &command, const std::vector<json> &args,
|
||||
std::uint32_t timeout_ms = 10000u);
|
||||
|
||||
public:
|
||||
rpc_response export_list(const std::vector<std::string> &paths);
|
||||
|
||||
rpc_response export_all();
|
||||
|
||||
rpc_response get_drive_information();
|
||||
|
||||
rpc_response get_config();
|
||||
|
||||
rpc_response get_config_value_by_name(const std::string &name);
|
||||
|
||||
rpc_response get_directory_items(const std::string &api_path);
|
||||
|
||||
rpc_response get_open_files();
|
||||
|
||||
rpc_response get_pinned_files();
|
||||
|
||||
rpc_response import_skylink(const skylink_import_list &list);
|
||||
|
||||
rpc_response pin_file(const std::string &api_file);
|
||||
|
||||
rpc_response pinned_status(const std::string &api_file);
|
||||
|
||||
rpc_response set_config_value_by_name(const std::string &name, const std::string &value);
|
||||
|
||||
rpc_response unmount();
|
||||
|
||||
rpc_response unpin_file(const std::string &api_file);
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_RPC_CLIENT_CLIENT_HPP_
|
44
include/rpc/server/full_server.hpp
Normal file
44
include/rpc/server/full_server.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_RPC_SERVER_FULL_SERVER_HPP_
|
||||
#define INCLUDE_RPC_SERVER_FULL_SERVER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "rpc/server/server.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_open_file_table;
|
||||
class i_provider;
|
||||
class full_server final : public server {
|
||||
public:
|
||||
explicit full_server(app_config &config, i_provider &provider, i_open_file_table &oft);
|
||||
|
||||
~full_server() override = default;
|
||||
|
||||
private:
|
||||
i_provider &provider_;
|
||||
i_open_file_table &oft_;
|
||||
|
||||
protected:
|
||||
bool handle_request(jsonrpcpp::request_ptr &request,
|
||||
std::unique_ptr<jsonrpcpp::Response> &response) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_RPC_SERVER_FULL_SERVER_HPP_
|
99
include/rpc/server/server.hpp
Normal file
99
include/rpc/server/server.hpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_RPC_SERVER_SERVER_HPP_
|
||||
#define INCLUDE_RPC_SERVER_SERVER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/rpc.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class server {
|
||||
typedef std::map<std::string, std::string, httpserver::http::arg_comparator> query_map;
|
||||
|
||||
private:
|
||||
class json_response final : public httpserver::http_response {
|
||||
public:
|
||||
json_response() = default;
|
||||
|
||||
explicit json_response(const json &content,
|
||||
int response_code = httpserver::http::http_utils::http_ok,
|
||||
const std::string &content_type = "application/json")
|
||||
: http_response(response_code, content_type), content(content.dump(0)) {}
|
||||
|
||||
json_response(const json_response &other) = default;
|
||||
json_response(json_response &&other) noexcept = default;
|
||||
|
||||
json_response &operator=(const json_response &b) = default;
|
||||
json_response &operator=(json_response &&b) = default;
|
||||
|
||||
~json_response() override = default;
|
||||
|
||||
MHD_Response *get_raw_response() override {
|
||||
const auto size = content.length();
|
||||
return MHD_create_response_from_buffer(size, (void *)content.c_str(), MHD_RESPMEM_PERSISTENT);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string content = "";
|
||||
};
|
||||
|
||||
class rpc_resource final : public httpserver::http_resource {
|
||||
public:
|
||||
explicit rpc_resource(server &owner);
|
||||
|
||||
private:
|
||||
server &owner_;
|
||||
|
||||
public:
|
||||
const std::shared_ptr<httpserver::http_response>
|
||||
render(const httpserver::http_request &request) override;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit server(app_config &config);
|
||||
|
||||
virtual ~server() { stop(); }
|
||||
|
||||
private:
|
||||
app_config &config_;
|
||||
rpc_resource resource_;
|
||||
std::unique_ptr<httpserver::webserver> ws_;
|
||||
std::mutex start_stop_mutex_;
|
||||
bool started_ = false;
|
||||
|
||||
private:
|
||||
bool check_authorization(const httpserver::http_request &request);
|
||||
|
||||
protected:
|
||||
app_config &get_config() { return config_; }
|
||||
|
||||
const app_config &get_config() const { return config_; }
|
||||
|
||||
virtual bool handle_request(jsonrpcpp::request_ptr &request,
|
||||
std::unique_ptr<jsonrpcpp::Response> &response);
|
||||
|
||||
public:
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_RPC_SERVER_SERVER_HPP_
|
147
include/types/remote.hpp
Normal file
147
include/types/remote.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_TYPES_REMOTE_HPP_
|
||||
#define INCLUDE_TYPES_REMOTE_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#define PACKET_SERVICE_FUSE std::uint32_t(1)
|
||||
#define PACKET_SERVICE_WINFSP std::uint32_t(2)
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PACKET_SERVICE_FLAGS PACKET_SERVICE_WINFSP
|
||||
#else
|
||||
#define PACKET_SERVICE_FLAGS PACKET_SERVICE_FUSE
|
||||
#endif
|
||||
|
||||
namespace repertory::remote {
|
||||
typedef std::uint64_t block_count;
|
||||
typedef std::uint32_t block_size;
|
||||
typedef std::uint64_t file_handle;
|
||||
typedef std::uint16_t file_mode;
|
||||
typedef std::uint16_t file_nlink;
|
||||
typedef std::uint64_t file_offset;
|
||||
typedef std::uint64_t file_size;
|
||||
typedef std::uint64_t file_time;
|
||||
typedef std::uint32_t group_id;
|
||||
typedef std::uint32_t user_id;
|
||||
|
||||
enum class open_flags : std::uint32_t {
|
||||
read_only = 0u,
|
||||
write_only = 1u,
|
||||
read_write = 2u,
|
||||
create = 4u,
|
||||
excl = 8u,
|
||||
no_ctty = 16u,
|
||||
truncate = 32u,
|
||||
append = 64u,
|
||||
non_blocking = 128u,
|
||||
sync = 256u,
|
||||
async = 512u,
|
||||
directory = 1024u,
|
||||
no_follow = 2048u,
|
||||
clo_exec = 4096u,
|
||||
direct = 8192u,
|
||||
no_atime = 16384u,
|
||||
path = 32768u,
|
||||
temp_file = 65536u,
|
||||
dsync = 131072u,
|
||||
};
|
||||
|
||||
static open_flags operator|(const open_flags &a, const open_flags &b) {
|
||||
using t = std::underlying_type_t<open_flags>;
|
||||
return static_cast<open_flags>(static_cast<t>(a) | static_cast<t>(b));
|
||||
}
|
||||
|
||||
static open_flags &operator|=(open_flags &a, const open_flags &b) {
|
||||
a = a | b;
|
||||
return a;
|
||||
}
|
||||
|
||||
static open_flags operator&(const open_flags &a, const open_flags &b) {
|
||||
using t = std::underlying_type_t<open_flags>;
|
||||
return static_cast<open_flags>(static_cast<t>(a) & static_cast<t>(b));
|
||||
}
|
||||
|
||||
#pragma pack(1)
|
||||
struct file_info {
|
||||
UINT32 FileAttributes;
|
||||
UINT32 ReparseTag;
|
||||
UINT64 AllocationSize;
|
||||
UINT64 FileSize;
|
||||
UINT64 CreationTime;
|
||||
UINT64 LastAccessTime;
|
||||
UINT64 LastWriteTime;
|
||||
UINT64 ChangeTime;
|
||||
UINT64 IndexNumber;
|
||||
UINT32 HardLinks;
|
||||
UINT32 EaSize;
|
||||
};
|
||||
|
||||
struct setattr_x {
|
||||
std::int32_t valid;
|
||||
file_mode mode;
|
||||
user_id uid;
|
||||
group_id gid;
|
||||
file_size size;
|
||||
file_time acctime;
|
||||
file_time modtime;
|
||||
file_time crtime;
|
||||
file_time chgtime;
|
||||
file_time bkuptime;
|
||||
std::uint32_t flags;
|
||||
};
|
||||
|
||||
struct stat {
|
||||
file_mode st_mode;
|
||||
file_nlink st_nlink;
|
||||
user_id st_uid;
|
||||
group_id st_gid;
|
||||
file_time st_atimespec;
|
||||
file_time st_mtimespec;
|
||||
file_time st_ctimespec;
|
||||
file_time st_birthtimespec;
|
||||
file_size st_size;
|
||||
block_count st_blocks;
|
||||
block_size st_blksize;
|
||||
std::uint32_t st_flags;
|
||||
};
|
||||
|
||||
struct statfs {
|
||||
std::uint64_t f_bavail;
|
||||
std::uint64_t f_bfree;
|
||||
std::uint64_t f_blocks;
|
||||
std::uint64_t f_favail;
|
||||
std::uint64_t f_ffree;
|
||||
std::uint64_t f_files;
|
||||
};
|
||||
|
||||
struct statfs_x : public statfs {
|
||||
char f_mntfromname[1024];
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
#ifndef _WIN32
|
||||
open_flags create_open_flags(const std::uint32_t &flags);
|
||||
|
||||
std::uint32_t create_os_open_flags(const open_flags &flags);
|
||||
#endif
|
||||
} // namespace repertory::remote
|
||||
|
||||
#endif // INCLUDE_TYPES_REMOTE_HPP_
|
310
include/types/repertory.hpp
Normal file
310
include/types/repertory.hpp
Normal file
@ -0,0 +1,310 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_TYPES_REPERTORY_HPP_
|
||||
#define INCLUDE_TYPES_REPERTORY_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory {
|
||||
#define META_ACCESSED "accessed"
|
||||
#define META_ATTRIBUTES "attributes"
|
||||
#define META_BACKUP "backup"
|
||||
#define META_CHANGED "changed"
|
||||
#define META_CREATION "creation"
|
||||
#define META_ENCRYPTION_TOKEN "token2"
|
||||
#define META_GID "gid"
|
||||
#define META_ID "id"
|
||||
#define META_KEY "key"
|
||||
#define META_MODE "mode"
|
||||
#define META_MODIFIED "modified"
|
||||
#define META_OSXFLAGS "flags"
|
||||
#define META_PINNED "pinned"
|
||||
#define META_SIZE "size"
|
||||
#define META_SOURCE "source"
|
||||
#define META_UID "uid"
|
||||
#define META_WRITTEN "written"
|
||||
|
||||
const std::vector<std::string> META_USED_NAMES = {
|
||||
META_ACCESSED, META_ATTRIBUTES, META_BACKUP, META_CHANGED, META_CREATION, META_ENCRYPTION_TOKEN,
|
||||
META_GID, META_ID, META_KEY, META_MODE, META_MODIFIED, META_OSXFLAGS,
|
||||
META_PINNED, META_SIZE, META_SOURCE, META_UID, META_WRITTEN,
|
||||
};
|
||||
|
||||
typedef std::unordered_map<std::string, std::string> api_meta_map;
|
||||
|
||||
enum class api_error {
|
||||
success = 0,
|
||||
access_denied,
|
||||
bad_address,
|
||||
buffer_overflow,
|
||||
buffer_too_small,
|
||||
comm_error,
|
||||
decryption_error,
|
||||
directory_end_of_files,
|
||||
directory_exists,
|
||||
directory_not_empty,
|
||||
directory_not_found,
|
||||
download_failed,
|
||||
download_incomplete,
|
||||
download_stopped,
|
||||
download_timeout,
|
||||
empty_ring_buffer_chunk_size,
|
||||
empty_ring_buffer_size,
|
||||
error,
|
||||
file_exists,
|
||||
file_in_use,
|
||||
incompatible_version,
|
||||
invalid_handle,
|
||||
invalid_operation,
|
||||
invalid_ring_buffer_multiple,
|
||||
invalid_ring_buffer_size,
|
||||
invalid_version,
|
||||
item_is_file,
|
||||
item_not_found,
|
||||
not_implemented,
|
||||
not_supported,
|
||||
os_error,
|
||||
permission_denied,
|
||||
upload_failed,
|
||||
upload_stopped,
|
||||
xattr_buffer_small,
|
||||
xattr_exists,
|
||||
xattr_invalid_namespace,
|
||||
xattr_not_found,
|
||||
xattr_osx_invalid,
|
||||
xattr_too_big,
|
||||
ERROR_COUNT
|
||||
};
|
||||
|
||||
const std::string &api_error_to_string(const api_error &error);
|
||||
|
||||
enum class download_type { direct, fallback, ring_buffer };
|
||||
|
||||
enum class exit_code {
|
||||
success,
|
||||
communication_error = -1,
|
||||
file_creation_failed = -2,
|
||||
incompatible_version = -3,
|
||||
invalid_syntax = -4,
|
||||
lock_failed = -5,
|
||||
mount_active = -6,
|
||||
mount_result = -7,
|
||||
not_mounted = -8,
|
||||
startup_exception = -9,
|
||||
failed_to_get_mount_state = -10,
|
||||
export_failed = -11,
|
||||
import_failed = -12,
|
||||
option_not_found = -13,
|
||||
invalid_provider_type = -14,
|
||||
set_option_not_found = -15,
|
||||
pin_failed = -16,
|
||||
unpin_failed = -17,
|
||||
};
|
||||
|
||||
enum class lock_result {
|
||||
success,
|
||||
locked,
|
||||
failure,
|
||||
};
|
||||
|
||||
enum class provider_type {
|
||||
sia,
|
||||
remote,
|
||||
s3,
|
||||
skynet,
|
||||
passthrough,
|
||||
unknown,
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
struct open_file_data {
|
||||
void *directory_buffer = nullptr;
|
||||
};
|
||||
#else
|
||||
typedef int open_file_data;
|
||||
#endif
|
||||
|
||||
struct api_file {
|
||||
std::string api_path{};
|
||||
std::string api_parent{};
|
||||
std::uint64_t accessed_date = 0u;
|
||||
std::uint64_t changed_date = 0u;
|
||||
std::uint64_t created_date = 0u;
|
||||
std::string encryption_token{};
|
||||
std::uint64_t file_size = 0u;
|
||||
std::uint64_t modified_date = 0u;
|
||||
bool recoverable = false;
|
||||
double redundancy = 0.0;
|
||||
std::string source_path{};
|
||||
};
|
||||
|
||||
struct directory_item {
|
||||
std::string api_path{};
|
||||
std::string api_parent{};
|
||||
bool directory = false;
|
||||
std::uint64_t size = 0u;
|
||||
api_meta_map meta{};
|
||||
bool resolved = false;
|
||||
|
||||
static directory_item from_json(const json &item) {
|
||||
directory_item ret{};
|
||||
ret.api_path = item["path"].get<std::string>();
|
||||
ret.api_parent = item["parent"].get<std::string>();
|
||||
ret.directory = item["directory"].get<bool>();
|
||||
ret.size = item["size"].get<std::uint64_t>();
|
||||
ret.meta = item["meta"].get<std::unordered_map<std::string, std::string>>();
|
||||
return ret;
|
||||
}
|
||||
|
||||
json to_json() const {
|
||||
return {{"path", api_path},
|
||||
{"parent", api_parent},
|
||||
{"size", size},
|
||||
{"directory", directory},
|
||||
{"meta", meta}};
|
||||
}
|
||||
};
|
||||
|
||||
struct filesystem_item {
|
||||
std::string api_path{};
|
||||
std::string api_parent{};
|
||||
bool changed = false;
|
||||
bool directory = false;
|
||||
std::string encryption_token{};
|
||||
OSHandle handle = REPERTORY_INVALID_HANDLE;
|
||||
std::shared_ptr<std::recursive_mutex> lock;
|
||||
bool meta_changed = false;
|
||||
std::unordered_map<std::uint64_t, open_file_data> open_data;
|
||||
std::uint64_t size = 0u;
|
||||
std::string source_path{};
|
||||
bool source_path_changed = false;
|
||||
|
||||
bool is_encrypted() const { return not encryption_token.empty(); }
|
||||
};
|
||||
|
||||
struct host_config {
|
||||
std::string agent_string{};
|
||||
std::string api_password{};
|
||||
std::uint16_t api_port = 0u;
|
||||
std::string host_name_or_ip = "localhost";
|
||||
std::string path{};
|
||||
std::string protocol = "http";
|
||||
std::uint32_t timeout_ms = 60000u;
|
||||
std::string auth_url{};
|
||||
std::string auth_user{};
|
||||
std::string auth_password{};
|
||||
|
||||
bool operator==(const host_config &hc) const noexcept {
|
||||
if (&hc != this) {
|
||||
return agent_string == hc.agent_string && api_password == hc.api_password &&
|
||||
api_port == hc.api_port && host_name_or_ip == hc.host_name_or_ip && path == hc.path &&
|
||||
protocol == hc.protocol && timeout_ms == hc.timeout_ms && auth_url == hc.auth_url &&
|
||||
auth_user == hc.auth_user && auth_password == hc.auth_password;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const host_config &hc) const noexcept {
|
||||
if (&hc != this) {
|
||||
return not(hc == *this);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
static void to_json(json &j, const host_config &hc) {
|
||||
j = json{{"AgentString", hc.agent_string},
|
||||
{"ApiPassword", hc.api_password},
|
||||
{"ApiPort", hc.api_port},
|
||||
{"AuthPassword", hc.auth_password},
|
||||
{"AuthURL", hc.auth_url},
|
||||
{"AuthUser", hc.auth_user},
|
||||
{"HostNameOrIp", hc.host_name_or_ip},
|
||||
{"Path", hc.path},
|
||||
{"Protocol", hc.protocol},
|
||||
{"TimeoutMs", hc.timeout_ms}};
|
||||
}
|
||||
|
||||
static void from_json(const json &j, host_config &hc) {
|
||||
j.at("AgentString").get_to(hc.agent_string);
|
||||
j.at("ApiPassword").get_to(hc.api_password);
|
||||
j.at("ApiPort").get_to(hc.api_port);
|
||||
j.at("AuthPassword").get_to(hc.auth_password);
|
||||
j.at("AuthURL").get_to(hc.auth_url);
|
||||
j.at("AuthUser").get_to(hc.auth_user);
|
||||
j.at("HostNameOrIp").get_to(hc.host_name_or_ip);
|
||||
j.at("Path").get_to(hc.path);
|
||||
j.at("Protocol").get_to(hc.protocol);
|
||||
j.at("TimeoutMs").get_to(hc.timeout_ms);
|
||||
}
|
||||
|
||||
struct http_range {
|
||||
std::uint64_t begin = 0u;
|
||||
std::uint64_t end = 0u;
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct PassthroughConfig {
|
||||
std::string Location{};
|
||||
std::string Name{};
|
||||
};
|
||||
#endif
|
||||
|
||||
struct s3_config {
|
||||
std::string access_key{};
|
||||
std::string bucket{};
|
||||
std::uint16_t cache_timeout_secs = 60u;
|
||||
std::string encryption_token{};
|
||||
std::string region = "any";
|
||||
std::string secret_key{};
|
||||
std::uint32_t timeout_ms = 60000u;
|
||||
std::string url;
|
||||
};
|
||||
|
||||
typedef ttmath::Big<1, 30> api_currency;
|
||||
|
||||
typedef std::vector<api_file> api_file_list;
|
||||
typedef std::vector<directory_item> directory_item_list;
|
||||
typedef ttmath::UInt<64> hastings;
|
||||
typedef std::unordered_map<std::string, std::string> http_headers;
|
||||
typedef std::unordered_map<std::string, std::string> http_parameters;
|
||||
typedef std::vector<http_range> http_ranges;
|
||||
|
||||
typedef std::lock_guard<std::mutex> mutex_lock;
|
||||
typedef std::lock_guard<std::recursive_mutex> recur_mutex_lock;
|
||||
typedef std::unique_lock<std::mutex> unique_mutex_lock;
|
||||
typedef std::unique_lock<std::recursive_mutex> unique_recur_mutex_lock;
|
||||
|
||||
typedef std::function<void(api_file &file)> api_file_provider_callback;
|
||||
|
||||
typedef std::function<void(const std::string &api_path, const std::string &api_parent,
|
||||
const std::string &source, const bool &directory,
|
||||
const std::uint64_t &create_date, const std::uint64_t &access_date,
|
||||
const std::uint64_t &modified_date, const std::uint64_t &changed_date)>
|
||||
api_item_added_callback;
|
||||
|
||||
typedef std::function<api_error(const std::string &path, const std::size_t &size,
|
||||
const std::uint64_t &offset, std::vector<char> &data,
|
||||
const bool &stop_requested)>
|
||||
api_reader_callback;
|
||||
|
||||
typedef std::function<void(directory_item &di, const bool &format_path)> meta_provider_callback;
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_TYPES_REPERTORY_HPP_
|
56
include/types/rpc.hpp
Normal file
56
include/types/rpc.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_TYPES_RPC_HPP_
|
||||
#define INCLUDE_TYPES_RPC_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory {
|
||||
struct rpc_host_info {
|
||||
std::string host;
|
||||
std::string password;
|
||||
std::uint16_t port;
|
||||
std::string user;
|
||||
};
|
||||
|
||||
enum class rpc_response_type { success, config_value_not_found, curl_error, http_error };
|
||||
|
||||
struct rpc_response {
|
||||
rpc_response_type response_type;
|
||||
json data;
|
||||
};
|
||||
|
||||
namespace rpc_method {
|
||||
const std::string export_links = "export";
|
||||
const std::string get_config = "get_config";
|
||||
const std::string get_config_value_by_name = "get_config_value_by_name";
|
||||
const std::string set_config_value_by_name = "set_config_value_by_name";
|
||||
const std::string get_directory_items = "get_directory_items";
|
||||
const std::string get_drive_information = "get_drive_information";
|
||||
const std::string get_open_files = "get_open_files";
|
||||
const std::string get_pinned_files = "get_pinned_files";
|
||||
const std::string import = "import";
|
||||
const std::string unmount = "unmount";
|
||||
const std::string pin_file = "pin_file";
|
||||
const std::string pinned_status = "pinned_status";
|
||||
const std::string unpin_file = "unpin_file";
|
||||
} // namespace rpc_method
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_TYPES_RPC_HPP_
|
60
include/types/skynet.hpp
Normal file
60
include/types/skynet.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_TYPES_SKYNET_HPP_
|
||||
#define INCLUDE_TYPES_SKYNET_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
static const std::array<std::string, 2u> DEFAULT_SKYNET_URLS = {
|
||||
"siasky.net",
|
||||
"https://account.siasky.net",
|
||||
};
|
||||
|
||||
struct skynet_config {
|
||||
std::string encryption_token;
|
||||
std::vector<host_config> portal_list = {
|
||||
{"", "", 443, DEFAULT_SKYNET_URLS[0u], "", "https", 60000, DEFAULT_SKYNET_URLS[1u], "", ""},
|
||||
};
|
||||
|
||||
static std::vector<host_config> from_string(const std::string &list);
|
||||
|
||||
std::string to_string() const { return to_string(portal_list); }
|
||||
|
||||
static std::string to_string(const std::vector<host_config> &list);
|
||||
};
|
||||
|
||||
struct skylink_import {
|
||||
std::string directory;
|
||||
std::string file_name; // Ignored - informational only
|
||||
std::string skylink;
|
||||
std::string token;
|
||||
|
||||
static skylink_import from_json(const json &j);
|
||||
|
||||
static skylink_import from_string(const std::string &str);
|
||||
|
||||
json to_json() const;
|
||||
};
|
||||
|
||||
typedef std::vector<skylink_import> skylink_import_list;
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_TYPES_SKYNET_HPP_
|
31
include/types/startup_exception.hpp
Normal file
31
include/types/startup_exception.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_TYPES_STARTUP_EXCEPTION_HPP_
|
||||
#define INCLUDE_TYPES_STARTUP_EXCEPTION_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class startup_exception : public virtual std::runtime_error {
|
||||
public:
|
||||
explicit startup_exception(const std::string &msg) : std::runtime_error(msg) {}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_TYPES_STARTUP_EXCEPTION_HPP_
|
97
include/upload/upload_manager.hpp
Normal file
97
include/upload/upload_manager.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_UPLOAD_UPLOAD_MANAGER_HPP_
|
||||
#define INCLUDE_UPLOAD_UPLOAD_MANAGER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class upload_manager final {
|
||||
public:
|
||||
struct upload {
|
||||
std::string api_path;
|
||||
bool cancel = false;
|
||||
std::string encryption_token;
|
||||
std::string source_path;
|
||||
std::unique_ptr<std::thread> thread;
|
||||
bool completed = true;
|
||||
bool retry = false;
|
||||
|
||||
void wait() {
|
||||
while (not completed) {
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<bool(const std::string &api_path)> api_file_exists_callback;
|
||||
typedef std::function<host_config(const bool &upload)> get_host_config_callback;
|
||||
typedef std::function<void(const std::string &api_path, const std::string &source_path,
|
||||
const json &data)>
|
||||
upload_completed_callback;
|
||||
typedef std::function<api_error(const upload &upload, json &data, json &error)>
|
||||
upload_handler_callback;
|
||||
|
||||
public:
|
||||
upload_manager(const app_config &config, api_file_exists_callback api_file_exists,
|
||||
upload_handler_callback upload_handler,
|
||||
upload_completed_callback upload_completed);
|
||||
|
||||
~upload_manager();
|
||||
|
||||
private:
|
||||
const app_config &config_;
|
||||
const api_file_exists_callback api_file_exists_;
|
||||
upload_handler_callback upload_handler_;
|
||||
const upload_completed_callback upload_completed_;
|
||||
std::unique_ptr<rocksdb::DB> upload_db_;
|
||||
std::unordered_map<std::string, std::shared_ptr<upload>> upload_lookup_;
|
||||
std::deque<upload *> upload_queue_;
|
||||
std::deque<upload *> active_uploads_;
|
||||
const std::string ROCKS_DB_NAME = "upload_db";
|
||||
bool stop_requested_ = false;
|
||||
mutable std::mutex upload_mutex_;
|
||||
std::condition_variable upload_notify_;
|
||||
std::unique_ptr<std::thread> upload_thread_;
|
||||
|
||||
private:
|
||||
void upload_thread();
|
||||
|
||||
public:
|
||||
bool execute_if_not_processing(const std::vector<std::string> &api_paths,
|
||||
const std::function<void()> &action) const;
|
||||
|
||||
std::size_t get_count() const { return upload_lookup_.size(); }
|
||||
|
||||
bool is_processing(const std::string &api_path) const;
|
||||
|
||||
api_error queue_upload(const std::string &api_path, const std::string &source_path,
|
||||
const std::string &encryption_token);
|
||||
|
||||
api_error remove_upload(const std::string &api_path);
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_UPLOAD_UPLOAD_MANAGER_HPP_
|
123
include/utils/Base64.hpp
Normal file
123
include/utils/Base64.hpp
Normal file
@ -0,0 +1,123 @@
|
||||
#ifndef _MACARON_BASE64_H_
|
||||
#define _MACARON_BASE64_H_
|
||||
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2016 tomykaira
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace macaron {
|
||||
namespace Base64 {
|
||||
static std::string Encode(const char *data, const size_t &len) {
|
||||
static constexpr char sEncodingTable[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
|
||||
|
||||
size_t in_len = len;
|
||||
std::string ret;
|
||||
if (in_len > 0) {
|
||||
size_t out_len = 4 * ((in_len + 2) / 3);
|
||||
ret = std::string(out_len, '\0');
|
||||
size_t i;
|
||||
char *p = const_cast<char *>(ret.c_str());
|
||||
|
||||
for (i = 0; i < in_len - 2; i += 3) {
|
||||
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
|
||||
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int)(data[i + 1] & 0xF0) >> 4)];
|
||||
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) | ((int)(data[i + 2] & 0xC0) >> 6)];
|
||||
*p++ = sEncodingTable[data[i + 2] & 0x3F];
|
||||
}
|
||||
if (i < in_len) {
|
||||
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
|
||||
if (i == (in_len - 1)) {
|
||||
*p++ = sEncodingTable[((data[i] & 0x3) << 4)];
|
||||
*p++ = '=';
|
||||
} else {
|
||||
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int)(data[i + 1] & 0xF0) >> 4)];
|
||||
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2)];
|
||||
}
|
||||
*p++ = '=';
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::string Encode(const std::string &data) { return Encode(&data[0], data.size()); }
|
||||
|
||||
static std::vector<char> Decode(const std::string &input) {
|
||||
static constexpr unsigned char kDecodingTable[] = {
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62,
|
||||
64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64};
|
||||
|
||||
std::vector<char> out;
|
||||
if (not input.empty()) {
|
||||
size_t in_len = input.size();
|
||||
if (in_len % 4 != 0)
|
||||
throw std::runtime_error("Input data size is not a multiple of 4");
|
||||
|
||||
size_t out_len = in_len / 4 * 3;
|
||||
if (input[in_len - 1] == '=')
|
||||
out_len--;
|
||||
if (input[in_len - 2] == '=')
|
||||
out_len--;
|
||||
|
||||
out.resize(out_len);
|
||||
|
||||
for (size_t i = 0, j = 0; i < in_len;) {
|
||||
uint32_t a = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
|
||||
uint32_t b = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
|
||||
uint32_t c = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
|
||||
uint32_t d = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
|
||||
|
||||
uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6);
|
||||
|
||||
if (j < out_len)
|
||||
out[j++] = (triple >> 2 * 8) & 0xFF;
|
||||
if (j < out_len)
|
||||
out[j++] = (triple >> 1 * 8) & 0xFF;
|
||||
if (j < out_len)
|
||||
out[j++] = (triple >> 0 * 8) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
} // namespace Base64
|
||||
} // namespace macaron
|
||||
|
||||
#endif /* _MACARON_BASE64_H_ */
|
119
include/utils/cli_utils.hpp
Normal file
119
include/utils/cli_utils.hpp
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_CLI_UTILS_HPP_
|
||||
#define INCLUDE_UTILS_CLI_UTILS_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory::utils::cli {
|
||||
typedef std::array<std::string, 2> option;
|
||||
|
||||
namespace options {
|
||||
static const option check_version_option = {"-cv", "--check_version"};
|
||||
static const option display_config_option = {"-dc", "--display_config"};
|
||||
static const option data_directory_option = {"-dd", "--data_directory"};
|
||||
static const option drive_information_option = {"-di", "--drive_information"};
|
||||
static const option export_option = {"-ex", "--export"};
|
||||
static const option export_all_option = {"-ea", "--export_all"};
|
||||
#if defined(REPERTORY_ENABLE_S3)
|
||||
static const option s3_option = {"-s3", "--s3"};
|
||||
static const option name_option = {"-na", "--name"};
|
||||
#endif // defined(REPERTORY_ENABLE_S3)
|
||||
static const option generate_config_option = {"-gc", "--generate_config"};
|
||||
static const option get_option = {"-get", "--get"};
|
||||
static const option get_directory_items_option = {"-gdi", "--get_directory_items"};
|
||||
static const option get_pinned_files_option = {"-gpf", "--get_pinned_files"};
|
||||
static const option help_option = {"-h", "--help"};
|
||||
static const option hidden_option = {"-hidden", "--hidden"};
|
||||
static const option import_option = {"-im", "--import"};
|
||||
static const option import_json_option = {"-ij", "--import_json"};
|
||||
static const option open_files_option = {"-of", "--open_files"};
|
||||
static const option pin_file_option = {"-pf", "--pin_file"};
|
||||
static const option pinned_status_option = {"-ps", "--pinned_status"};
|
||||
static const option password_option = {"-pw", "--password"};
|
||||
#if defined(REPERTORY_ENABLE_SKYNET)
|
||||
static const option skynet_option = {"-sk", "--skynet"};
|
||||
static const option test_skynet_auth_option = {"-tsa", "--test_skynet_auth"};
|
||||
#endif // defined(REPERTORY_ENABLE_SKYNET)
|
||||
static const option remote_mount_option = {"-rm", "--remote_mount"};
|
||||
static const option set_option = {"-set", "--set"};
|
||||
static const option status_option = {"-status", "--status"};
|
||||
static const option unmount_option = {"-unmount", "--unmount"};
|
||||
static const option unpin_file_option = {"-uf", "--unpin_file"};
|
||||
static const option user_option = {"-us", "--user"};
|
||||
static const option version_option = {"-V", "--version"};
|
||||
|
||||
static const std::vector<option> option_list = {
|
||||
check_version_option,
|
||||
display_config_option,
|
||||
data_directory_option,
|
||||
drive_information_option,
|
||||
export_option,
|
||||
export_all_option,
|
||||
#if defined(REPERTORY_ENABLE_S3)
|
||||
s3_option,
|
||||
name_option,
|
||||
#endif // defined(REPERTORY_ENABLE_S3)
|
||||
generate_config_option,
|
||||
get_option,
|
||||
get_directory_items_option,
|
||||
get_pinned_files_option,
|
||||
help_option,
|
||||
hidden_option,
|
||||
import_option,
|
||||
import_json_option,
|
||||
open_files_option,
|
||||
password_option,
|
||||
pin_file_option,
|
||||
pinned_status_option,
|
||||
#if defined(REPERTORY_ENABLE_SKYNET)
|
||||
skynet_option,
|
||||
test_skynet_auth_option,
|
||||
#endif // defined(REPERTORY_ENABLE_SKYNET)
|
||||
remote_mount_option,
|
||||
set_option,
|
||||
status_option,
|
||||
unmount_option,
|
||||
unpin_file_option,
|
||||
user_option,
|
||||
version_option,
|
||||
};
|
||||
} // namespace options
|
||||
|
||||
// Prototypes
|
||||
void get_api_authentication_data(std::string &user, std::string &password, std::uint16_t &port,
|
||||
const provider_type &pt, const std::string &data_directory);
|
||||
|
||||
provider_type get_provider_type_from_args(const int &argc, char *argv[]);
|
||||
|
||||
bool has_option(const int &argc, char *argv[], const std::string &option_name);
|
||||
|
||||
bool has_option(const int &argc, char *argv[], const option &opt);
|
||||
|
||||
std::vector<std::string> parse_option(const int &argc, char *argv[], const std::string &option_name,
|
||||
std::uint8_t count);
|
||||
|
||||
exit_code parse_string_option(const int &argc, char **argv, const option &opt, std::string &value);
|
||||
|
||||
std::vector<std::string> parse_drive_options(const int &argc, char **argv, provider_type &pt,
|
||||
std::string &data_directory);
|
||||
} // namespace repertory::utils::cli
|
||||
|
||||
#endif // INCLUDE_UTILS_CLI_UTILS_HPP_
|
42
include/utils/com_init_wrapper.hpp
Normal file
42
include/utils/com_init_wrapper.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright <2018-2022> <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_COM_INIT_WRAPPER_HPP_
|
||||
#define INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class com_init_wrapper {
|
||||
public:
|
||||
com_init_wrapper() : uninit_(SUCCEEDED(::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) {}
|
||||
|
||||
~com_init_wrapper() {
|
||||
if (uninit_) {
|
||||
::CoUninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const BOOL uninit_;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // _WIN32
|
||||
#endif // INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_
|
87
include/utils/encrypting_reader.hpp
Normal file
87
include/utils/encrypting_reader.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright <2018-2022> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef INCLUDE_UTILS_ENCRYPTING_READER_HPP_
|
||||
#define INCLUDE_UTILS_ENCRYPTING_READER_HPP_
|
||||
|
||||
#include "common.hpp"
|
||||
#include "utils/file_utils.hpp"
|
||||
|
||||
namespace repertory::utils::encryption {
|
||||
class encrypting_reader final {
|
||||
public:
|
||||
encrypting_reader(const std::string &file_name, const std::string &source_path,
|
||||
const bool &stop_requested, const std::string &token,
|
||||
const size_t error_return = 0);
|
||||
|
||||
encrypting_reader(const encrypting_reader &r);
|
||||
|
||||
~encrypting_reader();
|
||||
|
||||
public:
|
||||
typedef std::basic_iostream<char, std::char_traits<char>> iostream;
|
||||
typedef std::basic_streambuf<char, std::char_traits<char>> streambuf;
|
||||
|
||||
private:
|
||||
const CryptoPP::SecByteBlock key_;
|
||||
const bool &stop_requested_;
|
||||
const size_t error_return_;
|
||||
std::unordered_map<std::size_t, std::vector<char>> chunk_buffers_;
|
||||
std::string encrypted_file_name_;
|
||||
std::size_t last_data_chunk_ = 0u;
|
||||
std::size_t last_data_chunk_size_ = 0u;
|
||||
std::uint64_t read_offset_ = 0u;
|
||||
native_file_ptr source_file_;
|
||||
std::uint64_t total_size_ = 0u;
|
||||
|
||||
private:
|
||||
static const std::size_t header_size_;
|
||||
static const std::size_t data_chunk_size_;
|
||||
static const std::size_t encrypted_chunk_size_;
|
||||
|
||||
private:
|
||||
size_t reader_function(char *buffer, size_t size, size_t nitems);
|
||||
|
||||
public:
|
||||
static std::uint64_t calculate_decrypted_size(const std::uint64_t &total_size);
|
||||
|
||||
std::shared_ptr<iostream> create_iostream() const;
|
||||
|
||||
static constexpr const std::size_t &get_encrypted_chunk_size() { return encrypted_chunk_size_; }
|
||||
|
||||
static constexpr const std::size_t &get_data_chunk_size() { return data_chunk_size_; }
|
||||
|
||||
std::string get_encrypted_file_name() const { return encrypted_file_name_; }
|
||||
|
||||
std::size_t get_error_return() const { return error_return_; }
|
||||
|
||||
static constexpr const std::size_t &get_header_size() { return header_size_; }
|
||||
|
||||
const bool &get_stop_requested() const { return stop_requested_; }
|
||||
|
||||
std::uint64_t get_total_size() const { return total_size_; }
|
||||
|
||||
static size_t reader_function(char *buffer, size_t size, size_t nitems, void *instream) {
|
||||
return reinterpret_cast<encrypting_reader *>(instream)->reader_function(buffer, size, nitems);
|
||||
}
|
||||
|
||||
void set_read_position(const std::uint64_t &position) { read_offset_ = position; }
|
||||
};
|
||||
} // namespace repertory::utils::encryption
|
||||
|
||||
#endif // INCLUDE_UTILS_ENCRYPTING_READER_HPP_
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user