v2.0.2-rc (#27)
	
		
			
	
		
	
	
		
	
		
			Some checks reported errors
		
		
	
	
		
			
				
	
				BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
				
			
		
		
	
	
				
					
				
			
		
			Some checks reported errors
		
		
	
	BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
				
			## v2.0.2-rc ### BREAKING CHANGES * Refactored `config.json` - will need to verify configuration settings prior to mounting ### Issues * \#12 \[Unit Test\] Complete all providers unit tests * \#14 \[Unit Test\] SQLite mini-ORM unit tests and cleanup * \#16 Add support for bucket name in Sia provider * \#17 Update to common c++ build system * A single 64-bit Linux Jenkins server is used to build all Linux and Windows versions * All dependency sources are now included * MSVC is no longer supported * MSYS2 is required for building Windows binaries on Windows * OS X support is temporarily disabled * \#19 \[bug\] Rename file is broken for files that are existing * \#23 \[bug\] Incorrect file size displayed while upload is pending * \#24 RocksDB implementations should be transactional * \#25 Writes should block when maximum cache size is reached * \#26 Complete ring buffer and direct download support ### Changes from v2.0.1-rc * Ability to choose between RocksDB and SQLite databases * Added direct reads and implemented download fallback * Corrected file times on S3 and Sia providers * Corrected handling of `chown()` and `chmod()` * Fixed erroneous download of chunks after resize Reviewed-on: #27
This commit is contained in:
		
							
								
								
									
										258
									
								
								repertory/librepertory/include/app_config.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								repertory/librepertory/include/app_config.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,258 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_APP_CONFIG_HPP_ | ||||
| #define REPERTORY_INCLUDE_APP_CONFIG_HPP_ | ||||
|  | ||||
| #include "events/event.hpp" | ||||
| #include "types/remote.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config final { | ||||
| public: | ||||
|   [[nodiscard]] static auto | ||||
|   default_agent_name(const provider_type &prov) -> std::string; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   default_api_port(const provider_type &prov) -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   default_data_directory(const provider_type &prov) -> std::string; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   default_remote_api_port(const provider_type &prov) -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   default_rpc_port(const provider_type &prov) -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   get_provider_display_name(const provider_type &prov) -> std::string; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   get_provider_name(const provider_type &prov) -> std::string; | ||||
|  | ||||
| public: | ||||
|   app_config(const provider_type &prov, std::string_view data_directory = ""); | ||||
|  | ||||
|   app_config() = delete; | ||||
|   app_config(app_config &&) = delete; | ||||
|   app_config(const app_config &) = delete; | ||||
|  | ||||
|   ~app_config() { save(); } | ||||
|  | ||||
|   auto operator=(const app_config &) -> app_config & = delete; | ||||
|   auto operator=(app_config &&) -> app_config & = delete; | ||||
|  | ||||
| private: | ||||
|   provider_type prov_; | ||||
|   atomic<std::string> api_auth_; | ||||
|   std::atomic<std::uint16_t> api_port_; | ||||
|   atomic<std::string> api_user_; | ||||
|   std::atomic<bool> config_changed_; | ||||
|   std::atomic<database_type> db_type_{database_type::rocksdb}; | ||||
|   std::atomic<std::uint8_t> download_timeout_secs_; | ||||
|   std::atomic<bool> enable_download_timeout_; | ||||
|   std::atomic<bool> enable_drive_events_; | ||||
| #if defined(_WIN32) | ||||
|   std::atomic<bool> enable_mount_manager_; | ||||
| #endif // defined(_WIN32) | ||||
|   std::atomic<event_level> event_level_; | ||||
|   std::atomic<std::uint32_t> eviction_delay_mins_; | ||||
|   std::atomic<bool> eviction_uses_accessed_time_; | ||||
|   std::atomic<std::uint16_t> high_freq_interval_secs_; | ||||
|   std::atomic<std::uint16_t> low_freq_interval_secs_; | ||||
|   std::atomic<std::uint64_t> max_cache_size_bytes_; | ||||
|   std::atomic<std::uint8_t> max_upload_count_; | ||||
|   std::atomic<std::uint16_t> med_freq_interval_secs_; | ||||
|   std::atomic<std::uint16_t> online_check_retry_secs_; | ||||
|   std::atomic<std::uint16_t> orphaned_file_retention_days_; | ||||
|   std::atomic<download_type> preferred_download_type_; | ||||
|   std::atomic<std::uint16_t> retry_read_count_; | ||||
|   std::atomic<std::uint16_t> ring_buffer_file_size_; | ||||
|   std::atomic<std::uint16_t> task_wait_ms_; | ||||
|  | ||||
| private: | ||||
|   std::string cache_directory_; | ||||
|   std::string data_directory_; | ||||
|   atomic<encrypt_config> encrypt_config_; | ||||
|   atomic<host_config> host_config_; | ||||
|   std::string log_directory_; | ||||
|   mutable std::recursive_mutex read_write_mutex_; | ||||
|   atomic<remote::remote_config> remote_config_; | ||||
|   atomic<remote::remote_mount> remote_mount_; | ||||
|   atomic<s3_config> s3_config_; | ||||
|   atomic<sia_config> sia_config_; | ||||
|   std::unordered_map<std::string, std::function<std::string()>> | ||||
|       value_get_lookup_; | ||||
|   std::unordered_map<std::string, | ||||
|                      std::function<std::string(const std::string &)>> | ||||
|       value_set_lookup_; | ||||
|   std::uint64_t version_{REPERTORY_CONFIG_VERSION}; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto load() -> bool; | ||||
|  | ||||
|   template <typename dest, typename source> | ||||
|   auto set_value(dest &dst, const source &src) -> bool; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto get_api_auth() const -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_api_port() const -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_api_user() const -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_cache_directory() const -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_config_file_path() const -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_database_type() const -> database_type; | ||||
|  | ||||
|   [[nodiscard]] auto get_data_directory() const -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_download_timeout_secs() const -> std::uint8_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_enable_download_timeout() const -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto get_enable_drive_events() const -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto get_encrypt_config() const -> encrypt_config; | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   [[nodiscard]] auto get_enable_mount_manager() const -> bool; | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
|   [[nodiscard]] auto get_event_level() const -> event_level; | ||||
|  | ||||
|   [[nodiscard]] auto get_eviction_delay_mins() const -> std::uint32_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_eviction_uses_accessed_time() const -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto get_high_frequency_interval_secs() const -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_host_config() const -> host_config; | ||||
|  | ||||
|   [[nodiscard]] auto get_json() const -> json; | ||||
|  | ||||
|   [[nodiscard]] auto get_log_directory() const -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_low_frequency_interval_secs() const -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_max_cache_size_bytes() const -> std::uint64_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_max_upload_count() const -> std::uint8_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_med_frequency_interval_secs() const -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_online_check_retry_secs() const -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_orphaned_file_retention_days() const -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_preferred_download_type() const -> download_type; | ||||
|  | ||||
|   [[nodiscard]] auto get_provider_type() const -> provider_type; | ||||
|  | ||||
|   [[nodiscard]] auto get_remote_config() const -> remote::remote_config; | ||||
|  | ||||
|   [[nodiscard]] auto get_remote_mount() const -> remote::remote_mount; | ||||
|  | ||||
|   [[nodiscard]] auto get_retry_read_count() const -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_ring_buffer_file_size() const -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_s3_config() const -> s3_config; | ||||
|  | ||||
|   [[nodiscard]] auto get_sia_config() const -> sia_config; | ||||
|  | ||||
|   [[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_value_by_name(const std::string &name) const -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_version() const -> std::uint64_t; | ||||
|  | ||||
|   void save(); | ||||
|  | ||||
|   void set_api_auth(const std::string &value); | ||||
|  | ||||
|   void set_api_port(std::uint16_t value); | ||||
|  | ||||
|   void set_api_user(const std::string &value); | ||||
|  | ||||
|   void set_download_timeout_secs(std::uint8_t value); | ||||
|  | ||||
|   void set_database_type(const database_type &value); | ||||
|  | ||||
|   void set_enable_download_timeout(bool value); | ||||
|  | ||||
|   void set_enable_drive_events(bool value); | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   void set_enable_mount_manager(bool value); | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
|   void set_event_level(const event_level &value); | ||||
|  | ||||
|   void set_encrypt_config(encrypt_config value); | ||||
|  | ||||
|   void set_eviction_delay_mins(std::uint32_t value); | ||||
|  | ||||
|   void set_eviction_uses_accessed_time(bool value); | ||||
|  | ||||
|   void set_high_frequency_interval_secs(std::uint16_t value); | ||||
|  | ||||
|   void set_host_config(host_config value); | ||||
|  | ||||
|   void set_low_frequency_interval_secs(std::uint16_t value); | ||||
|  | ||||
|   void set_max_cache_size_bytes(std::uint64_t value); | ||||
|  | ||||
|   void set_max_upload_count(std::uint8_t value); | ||||
|  | ||||
|   void set_med_frequency_interval_secs(std::uint16_t value); | ||||
|  | ||||
|   void set_online_check_retry_secs(std::uint16_t value); | ||||
|  | ||||
|   void set_orphaned_file_retention_days(std::uint16_t value); | ||||
|  | ||||
|   void set_preferred_download_type(const download_type &value); | ||||
|  | ||||
|   void set_remote_config(remote::remote_config value); | ||||
|  | ||||
|   void set_remote_mount(remote::remote_mount value); | ||||
|  | ||||
|   void set_retry_read_count(std::uint16_t value); | ||||
|  | ||||
|   void set_ring_buffer_file_size(std::uint16_t value); | ||||
|  | ||||
|   void set_s3_config(s3_config value); | ||||
|  | ||||
|   void set_sia_config(sia_config value); | ||||
|  | ||||
|   void set_task_wait_ms(std::uint16_t value); | ||||
|  | ||||
|   [[nodiscard]] auto set_value_by_name(const std::string &name, | ||||
|                                        const std::string &value) -> std::string; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_APP_CONFIG_HPP_ | ||||
							
								
								
									
										241
									
								
								repertory/librepertory/include/comm/curl/curl_comm.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								repertory/librepertory/include/comm/curl/curl_comm.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,241 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_ | ||||
|  | ||||
| #include "comm/curl/multi_request.hpp" | ||||
| #include "comm/i_http_comm.hpp" | ||||
| #include "events/event_system.hpp" | ||||
| #include "events/events.hpp" | ||||
| #include "utils/encryption.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class curl_comm final : public i_http_comm { | ||||
| public: | ||||
|   curl_comm() = delete; | ||||
|  | ||||
|   explicit curl_comm(host_config cfg); | ||||
|  | ||||
|   explicit curl_comm(s3_config cfg); | ||||
|  | ||||
| private: | ||||
|   using write_callback = size_t (*)(char *, size_t, size_t, void *); | ||||
|  | ||||
|   struct read_write_info final { | ||||
|     data_buffer data{}; | ||||
|     stop_type &stop_requested; | ||||
|   }; | ||||
|  | ||||
|   static const write_callback write_data; | ||||
|   static const write_callback write_headers; | ||||
|  | ||||
| private: | ||||
|   std::optional<host_config> host_config_; | ||||
|   std::optional<s3_config> s3_config_; | ||||
|  | ||||
| private: | ||||
|   bool use_s3_path_style_{false}; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] static auto create_curl() -> CURL *; | ||||
|  | ||||
|   [[nodiscard]] static auto reset_curl(CURL *curl_handle) -> CURL *; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] static auto | ||||
|   construct_url(CURL *curl, const std::string &relative_path, | ||||
|                 const host_config &cfg) -> std::string; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   create_host_config(const s3_config &cfg, | ||||
|                      bool use_s3_path_style) -> host_config; | ||||
|  | ||||
|   [[nodiscard]] static auto url_encode(CURL *curl, const std::string &data, | ||||
|                                        bool allow_slash) -> std::string; | ||||
|  | ||||
|   template <typename request_type> | ||||
|   [[nodiscard]] static auto | ||||
|   make_encrypted_request(const host_config &cfg, const request_type &request, | ||||
|                          long &response_code, | ||||
|                          stop_type &stop_requested) -> bool { | ||||
|     response_code = 0; | ||||
|  | ||||
|     if (not request.decryption_token.has_value() || | ||||
|         request.decryption_token.value().empty()) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     if (not request.range.has_value()) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     if (not request.total_size.has_value()) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     data_buffer data{}; | ||||
|     const auto key = | ||||
|         utils::encryption::generate_key<utils::encryption::hash_256_t>( | ||||
|             request.decryption_token.value()); | ||||
|     if (not utils::encryption::read_encrypted_range( | ||||
|             request.range.value(), key, | ||||
|             [&](data_buffer &ct, std::uint64_t start_offset, | ||||
|                 std::uint64_t end_offset) -> bool { | ||||
|               auto encrypted_request = request; | ||||
|               encrypted_request.decryption_token = std::nullopt; | ||||
|               encrypted_request.range = {{start_offset, end_offset}}; | ||||
|               encrypted_request.response_handler = | ||||
|                   [&ct](const auto &encrypted_data, long /*response_code*/) { | ||||
|                     ct = encrypted_data; | ||||
|                   }; | ||||
|               encrypted_request.total_size = std::nullopt; | ||||
|  | ||||
|               if (not make_request(cfg, encrypted_request, response_code, | ||||
|                                    stop_requested)) { | ||||
|                 return false; | ||||
|               } | ||||
|  | ||||
|               if (response_code != 200) { | ||||
|                 return false; | ||||
|               } | ||||
|  | ||||
|               return true; | ||||
|             }, | ||||
|             request.total_size.value(), data)) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     if (request.response_handler.has_value()) { | ||||
|       request.response_handler.value()(data, response_code); | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   template <typename request_type> | ||||
|   [[nodiscard]] static auto | ||||
|   make_request(const host_config &cfg, const request_type &request, | ||||
|                long &response_code, stop_type &stop_requested) -> bool { | ||||
|     if (request.decryption_token.has_value() && | ||||
|         not request.decryption_token.value().empty()) { | ||||
|       return make_encrypted_request(cfg, request, response_code, | ||||
|                                     stop_requested); | ||||
|     } | ||||
|  | ||||
|     response_code = 0; | ||||
|  | ||||
|     auto *curl = create_curl(); | ||||
|     if (not request.set_method(curl, stop_requested)) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     if (not cfg.agent_string.empty()) { | ||||
|       curl_easy_setopt(curl, CURLOPT_USERAGENT, cfg.agent_string.c_str()); | ||||
|     } | ||||
|  | ||||
|     if (request.allow_timeout && cfg.timeout_ms) { | ||||
|       curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, cfg.timeout_ms); | ||||
|     } | ||||
|  | ||||
|     std::string range_list{}; | ||||
|     if (request.range.has_value()) { | ||||
|       range_list = std::to_string(request.range.value().begin) + '-' + | ||||
|                    std::to_string(request.range.value().end); | ||||
|       curl_easy_setopt(curl, CURLOPT_RANGE, range_list.c_str()); | ||||
|     } | ||||
|  | ||||
|     if (request.response_headers.has_value()) { | ||||
|       curl_easy_setopt(curl, CURLOPT_HEADERDATA, | ||||
|                        &request.response_headers.value()); | ||||
|       curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_headers); | ||||
|     } | ||||
|  | ||||
|     read_write_info write_info{{}, stop_requested}; | ||||
|     if (request.response_handler.has_value()) { | ||||
|       curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_info); | ||||
|       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); | ||||
|     } | ||||
|  | ||||
|     std::string parameters{}; | ||||
|     for (const auto ¶m : request.query) { | ||||
|       parameters += (parameters.empty() ? '?' : '&') + param.first + '=' + | ||||
|                     url_encode(curl, param.second, false); | ||||
|     } | ||||
|  | ||||
|     if (not cfg.api_password.empty()) { | ||||
|       curl_easy_setopt(curl, CURLOPT_USERNAME, cfg.api_user.c_str()); | ||||
|       curl_easy_setopt(curl, CURLOPT_PASSWORD, cfg.api_password.c_str()); | ||||
|     } else if (not cfg.api_user.empty()) { | ||||
|       curl_easy_setopt(curl, CURLOPT_USERNAME, cfg.api_user.c_str()); | ||||
|     } | ||||
|  | ||||
|     if (request.aws_service.has_value()) { | ||||
|       curl_easy_setopt(curl, CURLOPT_AWS_SIGV4, | ||||
|                        request.aws_service.value().c_str()); | ||||
|     } | ||||
|  | ||||
|     auto url = construct_url(curl, request.get_path(), cfg) + parameters; | ||||
|     curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | ||||
|  | ||||
|     multi_request curl_request(curl, stop_requested); | ||||
|  | ||||
|     CURLcode curl_code{}; | ||||
|     curl_request.get_result(curl_code, response_code); | ||||
|     if (curl_code != CURLE_OK) { | ||||
|       event_system::instance().raise<curl_error>(url, curl_code); | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     if (request.response_handler.has_value()) { | ||||
|       request.response_handler.value()(write_info.data, response_code); | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
| public: | ||||
|   void enable_s3_path_style(bool enable) override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   make_request(const curl::requests::http_delete &del, long &response_code, | ||||
|                stop_type &stop_requested) const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   make_request(const curl::requests::http_get &get, long &response_code, | ||||
|                stop_type &stop_requested) const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   make_request(const curl::requests::http_head &head, long &response_code, | ||||
|                stop_type &stop_requested) const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   make_request(const curl::requests::http_post &post_file, long &response_code, | ||||
|                stop_type &stop_requested) const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   make_request(const curl::requests::http_put_file &put_file, | ||||
|                long &response_code, | ||||
|                stop_type &stop_requested) const -> bool override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_ | ||||
							
								
								
									
										44
									
								
								repertory/librepertory/include/comm/curl/multi_request.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								repertory/librepertory/include/comm/curl/multi_request.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_CURL_MULTI_REQUEST_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_CURL_MULTI_REQUEST_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class multi_request final { | ||||
| public: | ||||
|   multi_request(CURL *curl_handle, stop_type &stop_requested); | ||||
|  | ||||
|   ~multi_request(); | ||||
|  | ||||
| private: | ||||
|   CURL *curl_handle_; | ||||
|   stop_type &stop_requested_; | ||||
|   CURLM *multi_handle_; | ||||
|  | ||||
| public: | ||||
|   void get_result(CURLcode &curl_code, long &http_code); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_CURL_MULTI_REQUEST_HPP_ | ||||
| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_DELETE_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_DELETE_HPP_ | ||||
|  | ||||
| #include "comm/curl/requests/http_request_base.hpp" | ||||
|  | ||||
| namespace repertory::curl::requests { | ||||
| struct http_delete final : http_request_base { | ||||
|   ~http_delete() override = default; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   set_method(CURL *curl, | ||||
|              stop_type & /* stop_requested */) const -> bool override { | ||||
|     curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory::curl::requests | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_DELETE_HPP_ | ||||
| @@ -0,0 +1,45 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_GET_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_GET_HPP_ | ||||
|  | ||||
| #include "comm/curl/requests/http_request_base.hpp" | ||||
|  | ||||
| namespace repertory::curl::requests { | ||||
| struct http_get final : http_request_base { | ||||
|   http_get() = default; | ||||
|   http_get(const http_get &) = default; | ||||
|   http_get(http_get &&) = default; | ||||
|   auto operator=(const http_get &) -> http_get & = default; | ||||
|   auto operator=(http_get &&) -> http_get & = default; | ||||
|   ~http_get() override = default; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   set_method(CURL *curl, | ||||
|              stop_type & /*stop_requested*/) const -> bool override { | ||||
|     curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory::curl::requests | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_GET_HPP_ | ||||
| @@ -0,0 +1,41 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_HEAD_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_HEAD_HPP_ | ||||
|  | ||||
| #include "comm/curl/requests/http_request_base.hpp" | ||||
|  | ||||
| namespace repertory::curl::requests { | ||||
| struct http_head final : http_request_base { | ||||
|   ~http_head() override = default; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   set_method(CURL *curl, | ||||
|              stop_type & /* stop_requested */) const -> bool override { | ||||
|     curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD"); | ||||
|     curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory::curl::requests | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_HEAD_HPP_ | ||||
| @@ -0,0 +1,48 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_POST_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_POST_HPP_ | ||||
|  | ||||
| #include "comm/curl/requests/http_request_base.hpp" | ||||
|  | ||||
| namespace repertory::curl::requests { | ||||
| struct http_post final : http_request_base { | ||||
|   http_post() = default; | ||||
|   http_post(const http_post &) = default; | ||||
|   http_post(http_post &&) = default; | ||||
|   auto operator=(const http_post &) -> http_post & = default; | ||||
|   auto operator=(http_post &&) -> http_post & = default; | ||||
|  | ||||
|   ~http_post() override; | ||||
|  | ||||
|   std::optional<nlohmann::json> json; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   set_method(CURL *curl, stop_type & /*stop_requested*/) const -> bool override; | ||||
|  | ||||
| private: | ||||
|   mutable curl_slist *headers{nullptr}; | ||||
|   mutable std::optional<std::string> json_str; | ||||
| }; | ||||
| } // namespace repertory::curl::requests | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_POST_HPP_ | ||||
| @@ -0,0 +1,50 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_PUT_FILE_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_PUT_FILE_HPP_ | ||||
|  | ||||
| #include "comm/curl/requests/http_request_base.hpp" | ||||
| #include "utils/encrypting_reader.hpp" | ||||
|  | ||||
| namespace repertory::curl::requests { | ||||
| struct http_put_file final : http_request_base { | ||||
|   http_put_file() = default; | ||||
|   http_put_file(const http_put_file &) = default; | ||||
|   http_put_file(http_put_file &&) = default; | ||||
|  | ||||
|   auto operator=(const http_put_file &) -> http_put_file & = default; | ||||
|   auto operator=(http_put_file &&) -> http_put_file & = default; | ||||
|  | ||||
|   ~http_put_file() override = default; | ||||
|  | ||||
|   std::shared_ptr<utils::encryption::encrypting_reader> reader; | ||||
|   std::string source_path; | ||||
|  | ||||
|   [[nodiscard]] auto set_method(CURL *curl, stop_type &stop_requested) const | ||||
|       -> bool override; | ||||
|  | ||||
| private: | ||||
|   mutable std::shared_ptr<read_file_info> read_info{}; | ||||
| }; | ||||
| } // namespace repertory::curl::requests | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_PUT_FILE_HPP_ | ||||
| @@ -0,0 +1,70 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_REQUEST_BASE_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_REQUEST_BASE_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/file.hpp" | ||||
|  | ||||
| namespace repertory::curl::requests { | ||||
| using curl_response_callback = | ||||
|     std::function<void(const data_buffer &data, long response_code)>; | ||||
|  | ||||
| struct read_file_info final { | ||||
|   stop_type &stop_requested; | ||||
|   std::unique_ptr<utils::file::i_file> file{}; | ||||
|   std::uint64_t offset{}; | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] auto curl_file_reader(char *buffer, size_t size, size_t nitems, | ||||
|                                     void *instream) -> size_t; | ||||
|  | ||||
| struct http_request_base { | ||||
|   http_request_base() = default; | ||||
|   http_request_base(const http_request_base &) = default; | ||||
|   http_request_base(http_request_base &&) = default; | ||||
|  | ||||
|   auto operator=(const http_request_base &) -> http_request_base & = default; | ||||
|   auto operator=(http_request_base &&) -> http_request_base & = default; | ||||
|  | ||||
|   virtual ~http_request_base() = default; | ||||
|  | ||||
|   bool allow_timeout{}; | ||||
|   std::optional<std::string> aws_service; | ||||
|   std::optional<std::string> decryption_token{}; | ||||
|   http_headers headers{}; | ||||
|   std::string path{}; | ||||
|   http_query_parameters query{}; | ||||
|   std::optional<http_range> range{}; | ||||
|   std::optional<curl_response_callback> response_handler; | ||||
|   std::optional<http_headers> response_headers; | ||||
|   std::optional<std::uint64_t> total_size{}; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_path() const -> std::string { return path; } | ||||
|  | ||||
|   [[nodiscard]] virtual auto set_method(CURL *curl, | ||||
|                                         stop_type &stop_requested) const | ||||
|       -> bool = 0; | ||||
| }; | ||||
| } // namespace repertory::curl::requests | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_CURL_REQUESTS_HTTP_REQUEST_BASE_HPP_ | ||||
							
								
								
									
										62
									
								
								repertory/librepertory/include/comm/i_http_comm.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								repertory/librepertory/include/comm/i_http_comm.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_I_HTTP_COMM_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_I_HTTP_COMM_HPP_ | ||||
|  | ||||
| #include "comm/curl/requests/http_delete.hpp" | ||||
| #include "comm/curl/requests/http_get.hpp" | ||||
| #include "comm/curl/requests/http_head.hpp" | ||||
| #include "comm/curl/requests/http_post.hpp" | ||||
| #include "comm/curl/requests/http_put_file.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| struct i_http_comm { | ||||
|   INTERFACE_SETUP(i_http_comm); | ||||
|  | ||||
| public: | ||||
|   virtual void enable_s3_path_style(bool enable) = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   make_request(const curl::requests::http_delete &del, long &response_code, | ||||
|                stop_type &stop_requested) const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   make_request(const curl::requests::http_get &get, long &response_code, | ||||
|                stop_type &stop_requested) const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   make_request(const curl::requests::http_head &head, long &response_code, | ||||
|                stop_type &stop_requested) const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   make_request(const curl::requests::http_post &post, long &response_code, | ||||
|                stop_type &stop_requested) const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   make_request(const curl::requests::http_put_file &put_file, | ||||
|                long &response_code, | ||||
|                stop_type &stop_requested) const -> bool = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_I_HTTP_COMM_HPP_ | ||||
							
								
								
									
										110
									
								
								repertory/librepertory/include/comm/packet/client_pool.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								repertory/librepertory/include/comm/packet/client_pool.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_ | ||||
|  | ||||
| #include "comm/packet/packet.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class client_pool final { | ||||
| public: | ||||
|   using worker_callback = std::function<packet::error_type()>; | ||||
|   using worker_complete_callback = | ||||
|       std::function<void(const packet::error_type &)>; | ||||
|  | ||||
| private: | ||||
|   class pool final { | ||||
|   private: | ||||
|     struct work_item final { | ||||
|       work_item(worker_callback worker, | ||||
|                 worker_complete_callback worker_complete) | ||||
|           : work(std::move(worker)), | ||||
|             work_complete(std::move(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(std::uint8_t pool_size); | ||||
|  | ||||
|     ~pool() { shutdown(); } | ||||
|  | ||||
|   public: | ||||
|     pool(const pool &) = delete; | ||||
|     pool(pool &&) = delete; | ||||
|     auto operator=(const pool &) -> pool & = delete; | ||||
|     auto operator=(pool &&) -> pool & = delete; | ||||
|  | ||||
|   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(std::uint64_t thread_id, const worker_callback &worker, | ||||
|                  const worker_complete_callback &worker_complete); | ||||
|  | ||||
|     void shutdown(); | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   explicit client_pool(std::uint8_t pool_size = min_pool_size) | ||||
|       : pool_size_(pool_size == 0U ? min_pool_size : pool_size) {} | ||||
|  | ||||
|   ~client_pool() { shutdown(); } | ||||
|  | ||||
| public: | ||||
|   client_pool(const client_pool &) = delete; | ||||
|   client_pool(client_pool &&) = delete; | ||||
|   auto operator=(const client_pool &) -> client_pool & = delete; | ||||
|   auto operator=(client_pool &&) -> client_pool & = delete; | ||||
|  | ||||
| private: | ||||
|   std::uint8_t pool_size_; | ||||
|   std::unordered_map<std::string, std::shared_ptr<pool>> pool_lookup_; | ||||
|   std::mutex pool_mutex_; | ||||
|   bool shutdown_ = false; | ||||
|  | ||||
| private: | ||||
|   static constexpr const auto min_pool_size = 10U; | ||||
|  | ||||
| public: | ||||
|   void execute(const std::string &client_id, 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 // REPERTORY_INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_ | ||||
							
								
								
									
										231
									
								
								repertory/librepertory/include/comm/packet/packet.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								repertory/librepertory/include/comm/packet/packet.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,231 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_PACKET_PACKET_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_PACKET_PACKET_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: | ||||
|   using error_type = std::int32_t; | ||||
|  | ||||
| public: | ||||
|   packet() = default; | ||||
|  | ||||
|   explicit packet(data_buffer buffer) : buffer_(std::move(buffer)) {} | ||||
|  | ||||
|   explicit packet(data_buffer &&buffer) : buffer_(std::move(buffer)) {} | ||||
|  | ||||
|   packet(const packet &pkt) noexcept = default; | ||||
|  | ||||
|   packet(packet &&pkt) noexcept | ||||
|       : buffer_(std::move(pkt.buffer_)), decode_offset_(pkt.decode_offset_) {} | ||||
|  | ||||
|   ~packet() = default; | ||||
|  | ||||
| private: | ||||
|   data_buffer buffer_{}; | ||||
|   std::size_t decode_offset_{0U}; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] static auto decode_json(packet &response, json &json_data) | ||||
|       -> int; | ||||
|  | ||||
| public: | ||||
|   void clear(); | ||||
|  | ||||
|   [[nodiscard]] auto current_pointer() -> unsigned char * { | ||||
|     return (decode_offset_ < buffer_.size()) ? &buffer_.at(decode_offset_) | ||||
|                                              : nullptr; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto current_pointer() const -> const unsigned char * { | ||||
|     return (decode_offset_ < buffer_.size()) ? &buffer_.at(decode_offset_) | ||||
|                                              : nullptr; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::string &data) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::wstring &data) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(void *buffer, std::size_t size) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(void *&ptr) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::int8_t &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::uint8_t &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::int16_t &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::uint16_t &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::int32_t &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::uint32_t &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::int64_t &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(std::uint64_t &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(remote::open_flags &val) -> error_type { | ||||
|     return decode(reinterpret_cast<std::uint32_t &>(val)); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto decode(remote::setattr_x &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(remote::stat &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(remote::statfs &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(remote::statfs_x &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decode(remote::file_info &val) -> error_type; | ||||
|  | ||||
|   [[nodiscard]] auto decrypt(std::string_view token) -> error_type; | ||||
|  | ||||
|   void encode(const void *buffer, std::size_t size, bool should_reserve = true); | ||||
|  | ||||
|   void encode(const char *str) { | ||||
|     encode(std::string{str == nullptr ? "" : str}); | ||||
|   } | ||||
|  | ||||
|   void encode(std::string_view str); | ||||
|  | ||||
|   void encode(const wchar_t *str); | ||||
|  | ||||
|   void encode(std::wstring_view str); | ||||
|  | ||||
|   void encode(void *ptr) { | ||||
|     encode(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(ptr))); | ||||
|   } | ||||
|  | ||||
|   void encode(std::int8_t val); | ||||
|  | ||||
|   void encode(std::uint8_t val); | ||||
|  | ||||
|   void encode(std::int16_t val); | ||||
|  | ||||
|   void encode(std::uint16_t val); | ||||
|  | ||||
|   void encode(std::int32_t val); | ||||
|  | ||||
|   void encode(std::uint32_t val); | ||||
|  | ||||
|   void encode(std::int64_t val); | ||||
|  | ||||
|   void encode(std::uint64_t val); | ||||
|  | ||||
|   void encode(remote::open_flags val) { | ||||
|     encode(static_cast<std::uint32_t>(val)); | ||||
|   } | ||||
|  | ||||
|   void encode(remote::setattr_x val); | ||||
|  | ||||
|   void encode(remote::stat val); | ||||
|  | ||||
|   void encode(remote::statfs val, bool should_reserve = true); | ||||
|  | ||||
|   void encode(remote::statfs_x val); | ||||
|  | ||||
|   void encode(remote::file_info val); | ||||
|  | ||||
|   void encode_top(const void *buffer, std::size_t size, | ||||
|                   bool should_reserve = true); | ||||
|  | ||||
|   void encode_top(std::string_view str); | ||||
|  | ||||
|   void encode_top(std::wstring_view 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 val); | ||||
|  | ||||
|   void encode_top(std::uint8_t val); | ||||
|  | ||||
|   void encode_top(std::int16_t val); | ||||
|  | ||||
|   void encode_top(std::uint16_t val); | ||||
|  | ||||
|   void encode_top(std::int32_t val); | ||||
|  | ||||
|   void encode_top(std::uint32_t val); | ||||
|  | ||||
|   void encode_top(std::int64_t val); | ||||
|  | ||||
|   void encode_top(std::uint64_t val); | ||||
|  | ||||
|   void encode_top(remote::open_flags val) { | ||||
|     encode_top(static_cast<std::uint32_t>(val)); | ||||
|   } | ||||
|  | ||||
|   void encode_top(remote::setattr_x val); | ||||
|  | ||||
|   void encode_top(remote::stat val); | ||||
|  | ||||
|   void encode_top(remote::statfs val, bool should_reserve = true); | ||||
|  | ||||
|   void encode_top(remote::statfs_x val); | ||||
|  | ||||
|   void encode_top(remote::file_info val); | ||||
|  | ||||
|   void encrypt(std::string_view token); | ||||
|  | ||||
|   [[nodiscard]] auto get_size() const -> std::uint32_t { | ||||
|     return static_cast<std::uint32_t>(buffer_.size()); | ||||
|   } | ||||
|  | ||||
|   void to_buffer(data_buffer &buffer); | ||||
|  | ||||
| public: | ||||
|   auto operator=(const data_buffer &buffer) noexcept -> packet &; | ||||
|  | ||||
|   auto operator=(data_buffer &&buffer) noexcept -> packet &; | ||||
|  | ||||
|   auto operator=(const packet &pkt) noexcept -> packet &; | ||||
|  | ||||
|   auto operator=(packet &&pkt) noexcept -> packet &; | ||||
|  | ||||
|   [[nodiscard]] auto operator[](std::size_t index) -> unsigned char & { | ||||
|     return buffer_[index]; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto operator[](std::size_t index) const -> const | ||||
|       unsigned char & { | ||||
|     return buffer_.at(index); | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_PACKET_PACKET_HPP_ | ||||
							
								
								
									
										90
									
								
								repertory/librepertory/include/comm/packet/packet_client.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								repertory/librepertory/include/comm/packet/packet_client.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_PACKET_PACKET_CLIENT_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_PACKET_PACKET_CLIENT_HPP_ | ||||
|  | ||||
| #include "comm/packet/packet.hpp" | ||||
| #include "types/remote.hpp" | ||||
|  | ||||
| using boost::asio::ip::tcp; | ||||
|  | ||||
| namespace repertory { | ||||
| class packet_client final { | ||||
| private: | ||||
|   struct client final { | ||||
|     explicit client(boost::asio::io_context &ctx) : socket(ctx) {} | ||||
|     std::string nonce; | ||||
|     tcp::socket socket; | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   packet_client(remote::remote_config cfg); | ||||
|  | ||||
|   ~packet_client(); | ||||
|  | ||||
|   packet_client(const packet_client &) = delete; | ||||
|   packet_client(packet_client &&) = delete; | ||||
|   auto operator=(const packet_client &) -> packet_client & = delete; | ||||
|   auto operator=(packet_client &&) -> packet_client & = delete; | ||||
|  | ||||
| private: | ||||
|   boost::asio::io_context io_context_; | ||||
|   remote::remote_config cfg_; | ||||
|   std::string unique_id_; | ||||
|  | ||||
| private: | ||||
|   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: | ||||
|   static void close(client &cli); | ||||
|  | ||||
|   void close_all(); | ||||
|  | ||||
|   void connect(client &cli); | ||||
|  | ||||
|   [[nodiscard]] auto get_client() -> std::shared_ptr<client>; | ||||
|  | ||||
|   void put_client(std::shared_ptr<client> &cli); | ||||
|  | ||||
|   [[nodiscard]] auto read_packet(client &cli, packet &response) | ||||
|       -> packet::error_type; | ||||
|  | ||||
|   void resolve(); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto send(std::string_view method, std::uint32_t &service_flags) | ||||
|       -> packet::error_type; | ||||
|  | ||||
|   [[nodiscard]] auto send(std::string_view method, packet &request, | ||||
|                           std::uint32_t &service_flags) -> packet::error_type; | ||||
|  | ||||
|   [[nodiscard]] auto send(std::string_view method, packet &request, | ||||
|                           packet &response, std::uint32_t &service_flags) | ||||
|       -> packet::error_type; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_PACKET_PACKET_CLIENT_HPP_ | ||||
							
								
								
									
										98
									
								
								repertory/librepertory/include/comm/packet/packet_server.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								repertory/librepertory/include/comm/packet/packet_server.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_ | ||||
|  | ||||
| #include "comm/packet/client_pool.hpp" | ||||
| #include "utils/common.hpp" | ||||
|  | ||||
| using namespace boost::asio; | ||||
| using boost::asio::ip::tcp; | ||||
|  | ||||
| namespace repertory { | ||||
| class packet_server final { | ||||
| public: | ||||
|   using closed_callback = std::function<void(const std::string &)>; | ||||
|   using message_complete_callback = client_pool::worker_complete_callback; | ||||
|   using message_handler_callback = std::function<void( | ||||
|       std::uint32_t, const std::string &, std::uint64_t, const std::string &, | ||||
|       packet *, packet &, message_complete_callback)>; | ||||
|  | ||||
| public: | ||||
|   packet_server(std::uint16_t port, std::string token, std::uint8_t pool_size, | ||||
|                 closed_callback closed, | ||||
|                 message_handler_callback message_handler); | ||||
|  | ||||
|   ~packet_server(); | ||||
|  | ||||
| public: | ||||
|   packet_server(const packet_server &) = delete; | ||||
|   packet_server(packet_server &&) = delete; | ||||
|   auto operator=(const packet_server &) -> packet_server & = delete; | ||||
|   auto operator=(packet_server &&) -> packet_server & = delete; | ||||
|  | ||||
| private: | ||||
|   struct connection { | ||||
|     connection(io_context &ctx, tcp::acceptor &acceptor_) | ||||
|         : socket(ctx), acceptor(acceptor_) {} | ||||
|  | ||||
|     tcp::socket socket; | ||||
|     tcp::acceptor &acceptor; | ||||
|     data_buffer buffer; | ||||
|     std::string client_id; | ||||
|     std::string nonce; | ||||
|  | ||||
|     void generate_nonce() { nonce = utils::generate_random_string(256U); } | ||||
|   }; | ||||
|  | ||||
| private: | ||||
|   std::string encryption_token_; | ||||
|   closed_callback closed_; | ||||
|   message_handler_callback message_handler_; | ||||
|   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 &conn, 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> conn, | ||||
|                  boost::system::error_code err); | ||||
|  | ||||
|   void read_header(std::shared_ptr<connection> conn); | ||||
|  | ||||
|   void read_packet(std::shared_ptr<connection> conn, std::uint32_t data_size); | ||||
|  | ||||
|   void remove_client(connection &conn); | ||||
|  | ||||
|   void send_response(std::shared_ptr<connection> conn, | ||||
|                      const packet::error_type &result, packet &response); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_ | ||||
							
								
								
									
										291
									
								
								repertory/librepertory/include/common.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										291
									
								
								repertory/librepertory/include/common.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,291 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_COMMON_HPP_ | ||||
| #define REPERTORY_INCLUDE_COMMON_HPP_ | ||||
|  | ||||
| #if defined(__GNUC__) | ||||
| // clang-format off | ||||
| #define REPERTORY_IGNORE_WARNINGS_ENABLE()                                     \ | ||||
|   _Pragma("GCC diagnostic push")                                               \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Waggressive-loop-optimizations\"")        \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wconversion\"")                           \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wdouble-promotion\"")                     \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wduplicated-branches\"")                  \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wfloat-conversion\"")                     \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")                 \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wnull-dereference\"")                     \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wsign-conversion\"")                      \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wunused-but-set-variable\"")              \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")                     \ | ||||
|   _Pragma("GCC diagnostic ignored \"-Wuseless-cast\"") | ||||
|  | ||||
| #define REPERTORY_IGNORE_WARNINGS_DISABLE()                                    \ | ||||
|   _Pragma("GCC diagnostic pop") | ||||
| #else | ||||
| #define REPERTORY_IGNORE_WARNINGS_ENABLE()  | ||||
| #define REPERTORY_IGNORE_WARNINGS_DISABLE()                                     | ||||
| #endif // defined(__GNUC__) | ||||
| // clang-format on | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| REPERTORY_IGNORE_WARNINGS_ENABLE() | ||||
| #include "utils/config.hpp" | ||||
| REPERTORY_IGNORE_WARNINGS_DISABLE() | ||||
|  | ||||
| using namespace std::chrono_literals; | ||||
| using json = nlohmann::json; | ||||
|  | ||||
| inline constexpr const std::string_view REPERTORY = "repertory"; | ||||
| inline constexpr const std::wstring_view REPERTORY_W = L"repertory"; | ||||
|  | ||||
| inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION = 0ULL; | ||||
| inline constexpr const std::string_view REPERTORY_DATA_NAME = "repertory2"; | ||||
| inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION = "2.0.0"; | ||||
|  | ||||
| #define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE | ||||
|  | ||||
| #define WINFSP_ALLOCATION_UNIT UINT64(4096U) | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| #if defined(CreateDirectory) | ||||
| #undef CreateDirectory | ||||
| #endif | ||||
|  | ||||
| #if defined(CreateFile) | ||||
| #undef CreateFile | ||||
| #endif | ||||
|  | ||||
| #if defined(DeleteFile) | ||||
| #undef DeleteFile | ||||
| #endif | ||||
|  | ||||
| #if defined(RemoveDirectory) | ||||
| #undef RemoveDirectory | ||||
| #endif | ||||
|  | ||||
| #ifndef _SH_DENYRW | ||||
| #define _SH_DENYRW 0x10 // deny read/write mode | ||||
| #endif | ||||
|  | ||||
| #ifndef _SH_DENYWR | ||||
| #define _SH_DENYWR 0x20 // deny write mode | ||||
| #endif | ||||
|  | ||||
| #ifndef _SH_DENYRD | ||||
| #define _SH_DENYRD 0x30 // deny read mode | ||||
| #endif | ||||
|  | ||||
| #ifndef _SH_DENYNO | ||||
| #define _SH_DENYNO 0x40 // deny none mode | ||||
| #endif | ||||
|  | ||||
| #ifndef _SH_SECURE | ||||
| #define _SH_SECURE 0x80 // secure mode | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #ifndef ENETDOWN | ||||
| #define ENETDOWN 100 | ||||
| #endif | ||||
|  | ||||
| #ifndef SETATTR_WANTS_MODE | ||||
| #define SETATTR_WANTS_MODE(attr) ((attr)->valid & (1 << 0)) | ||||
| #endif // SETATTR_WANTS_MODE | ||||
|  | ||||
| #ifndef SETATTR_WANTS_UID | ||||
| #define SETATTR_WANTS_UID(attr) ((attr)->valid & (1 << 1)) | ||||
| #endif // SETATTR_WANTS_UID | ||||
|  | ||||
| #ifndef SETATTR_WANTS_GID | ||||
| #define SETATTR_WANTS_GID(attr) ((attr)->valid & (1 << 2)) | ||||
| #endif // SETATTR_WANTS_GID | ||||
|  | ||||
| #ifndef SETATTR_WANTS_SIZE | ||||
| #define SETATTR_WANTS_SIZE(attr) ((attr)->valid & (1 << 3)) | ||||
| #endif // SETATTR_WANTS_SIZE | ||||
|  | ||||
| #ifndef SETATTR_WANTS_ACCTIME | ||||
| #define SETATTR_WANTS_ACCTIME(attr) ((attr)->valid & (1 << 4)) | ||||
| #endif // SETATTR_WANTS_ACCTIME | ||||
|  | ||||
| #ifndef SETATTR_WANTS_MODTIME | ||||
| #define SETATTR_WANTS_MODTIME(attr) ((attr)->valid & (1 << 5)) | ||||
| #endif // SETATTR_WANTS_MODTIME | ||||
|  | ||||
| #ifndef SETATTR_WANTS_CRTIME | ||||
| #define SETATTR_WANTS_CRTIME(attr) ((attr)->valid & (1 << 28)) | ||||
| #endif // SETATTR_WANTS_CRTIME | ||||
|  | ||||
| #ifndef SETATTR_WANTS_CHGTIME | ||||
| #define SETATTR_WANTS_CHGTIME(attr) ((attr)->valid & (1 << 29)) | ||||
| #endif // SETATTR_WANTS_CHGTIME | ||||
|  | ||||
| #ifndef SETATTR_WANTS_BKUPTIME | ||||
| #define SETATTR_WANTS_BKUPTIME(attr) ((attr)->valid & (1 << 30)) | ||||
| #endif // SETATTR_WANTS_BKUPTIME | ||||
|  | ||||
| #ifndef SETATTR_WANTS_FLAGS | ||||
| #define SETATTR_WANTS_FLAGS(attr) ((attr)->valid & (1 << 31)) | ||||
| #endif // SETATTR_WANTS_FLAGS | ||||
|  | ||||
| #if !defined(_WIN32) | ||||
| #if defined(__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 defined(_WIN32) | ||||
| #define UTIME_NOW ((1l << 30) - 1l) | ||||
| #define UTIME_OMIT ((1l << 30) - 2l) | ||||
| #define CONVERT_STATUS_NOT_IMPLEMENTED(e) e | ||||
| #else | ||||
| using BOOLEAN = std::uint8_t; | ||||
| using DWORD = std::uint32_t; | ||||
| using HANDLE = void *; | ||||
| using NTSTATUS = std::uint32_t; | ||||
| using PUINT32 = std::uint32_t *; | ||||
| using PVOID = void *; | ||||
| using PWSTR = wchar_t *; | ||||
| using SIZE_T = std::uint64_t; | ||||
| using UINT16 = std::uint16_t; | ||||
| using UINT32 = std::uint32_t; | ||||
| using UINT64 = std::uint64_t; | ||||
| using VOID = void; | ||||
| using WCHAR = wchar_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 static_cast<DWORD>(-1) | ||||
|  | ||||
| #define MAX_PATH 260 | ||||
|  | ||||
| #define STATUS_SUCCESS std::uint32_t{0U} | ||||
| #define STATUS_ACCESS_DENIED std::uint32_t{0xC0000022L} | ||||
| #define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L} | ||||
| #define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L} | ||||
| #define STATUS_DIRECTORY_NOT_EMPTY std::uint32_t{0xC0000101L} | ||||
| #define STATUS_FILE_IS_A_DIRECTORY std::uint32_t{0xC00000BAL} | ||||
| #define STATUS_FILE_TOO_LARGE std::uint32_t{0xC0000904L} | ||||
| #define STATUS_INSUFFICIENT_RESOURCES std::uint32_t{0xC000009AL} | ||||
| #define STATUS_INTERNAL_ERROR std::uint32_t{0xC00000E5L} | ||||
| #define STATUS_INVALID_ADDRESS std::uint32_t{0xC0000141L} | ||||
| #define STATUS_INVALID_HANDLE std::uint32_t{0xC0000006L} | ||||
| #define STATUS_INVALID_IMAGE_FORMAT std::uint32_t{0xC000007BL} | ||||
| #define STATUS_INVALID_PARAMETER std::uint32_t{0xC000000DL} | ||||
| #define STATUS_NO_MEMORY std::uint32_t{0xC0000017L} | ||||
| #define STATUS_NOT_IMPLEMENTED std::uint32_t{0xC0000002L} | ||||
| #define STATUS_OBJECT_NAME_EXISTS std::uint32_t{0x40000000L} | ||||
| #define STATUS_OBJECT_NAME_NOT_FOUND std::uint32_t{0xC0000034L} | ||||
| #define STATUS_OBJECT_PATH_INVALID std::uint32_t{0xC0000039L} | ||||
| #define STATUS_UNEXPECTED_IO_ERROR std::uint32_t{0xC00000E9L} | ||||
|  | ||||
| #define CONVERT_STATUS_NOT_IMPLEMENTED(e)                                      \ | ||||
|   ((std::uint32_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{}; | ||||
| }; | ||||
|  | ||||
| using FileInfo = FSP_FSCTL_FILE_INFO; | ||||
| } // namespace Fsp::FileSystemBase | ||||
| #endif | ||||
|  | ||||
| using namespace Fsp; | ||||
|  | ||||
| #define INTERFACE_SETUP(name)                                                  \ | ||||
| public:                                                                        \ | ||||
|   name(const name &) noexcept = delete;                                        \ | ||||
|   auto operator=(const name &) noexcept -> name & = delete;                    \ | ||||
|   auto operator=(name &&) noexcept -> name & = delete;                         \ | ||||
|                                                                                \ | ||||
| protected:                                                                     \ | ||||
|   name() = default;                                                            \ | ||||
|   name(name &&) noexcept = default;                                            \ | ||||
|                                                                                \ | ||||
| public:                                                                        \ | ||||
|   virtual ~name() = default | ||||
|  | ||||
| #endif // __cplusplus | ||||
| #endif // REPERTORY_INCLUDE_COMMON_HPP_ | ||||
							
								
								
									
										34
									
								
								repertory/librepertory/include/db/file_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								repertory/librepertory/include/db/file_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_FILE_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_FILE_DB_HPP_ | ||||
|  | ||||
| #include "db/i_file_db.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| [[nodiscard]] auto create_file_db(const app_config &cfg) | ||||
|     -> std::unique_ptr<i_file_db>; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_FILE_DB_HPP_ | ||||
							
								
								
									
										34
									
								
								repertory/librepertory/include/db/file_mgr_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								repertory/librepertory/include/db/file_mgr_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_FILE_MGR_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_FILE_MGR_DB_HPP_ | ||||
|  | ||||
| #include "db/i_file_mgr_db.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| create_file_mgr_db(const app_config &cfg) -> std::unique_ptr<i_file_mgr_db>; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_FILE_MGR_DB_HPP_ | ||||
							
								
								
									
										95
									
								
								repertory/librepertory/include/db/i_file_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								repertory/librepertory/include/db/i_file_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_I_FILE_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_I_FILE_DB_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_file_db { | ||||
|   INTERFACE_SETUP(i_file_db); | ||||
|  | ||||
| public: | ||||
|   struct file_info final { | ||||
|     std::string api_path; | ||||
|     bool directory; | ||||
|     std::string source_path; | ||||
|   }; | ||||
|  | ||||
|   struct file_data final { | ||||
|     std::string api_path; | ||||
|     std::uint64_t file_size{}; | ||||
|     std::vector< | ||||
|         std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> | ||||
|         iv_list{}; | ||||
|     std::string source_path; | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] virtual auto add_directory(const std::string &api_path, | ||||
|                                            const std::string &source_path) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto add_or_update_file(const file_data &data) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   virtual void clear() = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto count() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_api_path(const std::string &source_path, | ||||
|                                           std::string &api_path) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_directory_api_path(const std::string &source_path, | ||||
|                          std::string &api_path) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_directory_source_path(const std::string &api_path, | ||||
|                             std::string &source_path) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_file_api_path(const std::string &source_path, | ||||
|                                                std::string &api_path) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_file_data(const std::string &api_path, | ||||
|                                            file_data &data) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_file_source_path(const std::string &api_path, | ||||
|                        std::string &source_path) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_item_list() const | ||||
|       -> std::vector<file_info> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_source_path(const std::string &api_path, | ||||
|                                              std::string &source_path) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_item(const std::string &api_path) | ||||
|       -> api_error = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_I_FILE_DB_HPP_ | ||||
							
								
								
									
										86
									
								
								repertory/librepertory/include/db/i_file_mgr_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								repertory/librepertory/include/db/i_file_mgr_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_I_FILE_MGR_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_I_FILE_MGR_DB_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_file_mgr_db { | ||||
|   INTERFACE_SETUP(i_file_mgr_db); | ||||
|  | ||||
| public: | ||||
|   struct resume_entry final { | ||||
|     std::string api_path; | ||||
|     std::uint64_t chunk_size{}; | ||||
|     boost::dynamic_bitset<> read_state; | ||||
|     std::string source_path; | ||||
|   }; | ||||
|  | ||||
|   struct upload_active_entry final { | ||||
|     std::string api_path; | ||||
|     std::string source_path; | ||||
|   }; | ||||
|  | ||||
|   struct upload_entry final { | ||||
|     std::string api_path; | ||||
|     std::string source_path; | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] virtual auto add_resume(const resume_entry &entry) -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto add_upload(const upload_entry &entry) -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto add_upload_active(const upload_active_entry &entry) | ||||
|       -> bool = 0; | ||||
|  | ||||
|   virtual void clear() = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_next_upload() const | ||||
|       -> std::optional<upload_entry> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_resume_list() const | ||||
|       -> std::vector<resume_entry> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_upload(const std::string &api_path) const | ||||
|       -> std::optional<upload_entry> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_upload_active_list() const | ||||
|       -> std::vector<upload_active_entry> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_resume(const std::string &api_path) | ||||
|       -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_upload(const std::string &api_path) | ||||
|       -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_upload_active(const std::string &api_path) | ||||
|       -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto rename_resume(const std::string &from_api_path, | ||||
|                                            const std::string &to_api_path) | ||||
|       -> bool = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_I_FILE_MGR_DB_HPP_ | ||||
							
								
								
									
										78
									
								
								repertory/librepertory/include/db/i_meta_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								repertory/librepertory/include/db/i_meta_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_I_META_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_I_META_DB_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_meta_db { | ||||
|   INTERFACE_SETUP(i_meta_db); | ||||
|  | ||||
| public: | ||||
|   virtual void clear() = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_api_path(const std::string &source_path, | ||||
|                                           std::string &api_path) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_api_path_list() const | ||||
|       -> std::vector<std::string> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_item_meta(const std::string &api_path, | ||||
|                                            api_meta_map &meta) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_item_meta(const std::string &api_path, | ||||
|                                            const std::string &key, | ||||
|                                            std::string &value) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_pinned_files() const | ||||
|       -> std::vector<std::string> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_total_item_count() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_total_size() const -> std::uint64_t = 0; | ||||
|  | ||||
|   virtual void remove_api_path(const std::string &api_path) = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_item_meta(const std::string &api_path, | ||||
|                                               const std::string &key) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto rename_item_meta(const std::string &from_api_path, | ||||
|                                               const std::string &to_api_path) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto set_item_meta(const std::string &api_path, | ||||
|                                            const std::string &key, | ||||
|                                            const std::string &value) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto set_item_meta(const std::string &api_path, | ||||
|                                            const api_meta_map &meta) | ||||
|       -> api_error = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_I_META_DB_HPP_ | ||||
							
								
								
									
										117
									
								
								repertory/librepertory/include/db/impl/rdb_file_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								repertory/librepertory/include/db/impl/rdb_file_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,117 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_IMPL_RDB_FILE_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_IMPL_RDB_FILE_DB_HPP_ | ||||
|  | ||||
| #include "db/i_file_db.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class rdb_file_db final : public i_file_db { | ||||
| public: | ||||
|   rdb_file_db(const app_config &cfg); | ||||
|   ~rdb_file_db() override; | ||||
|  | ||||
|   rdb_file_db(const rdb_file_db &) = delete; | ||||
|   rdb_file_db(rdb_file_db &&) = delete; | ||||
|   auto operator=(const rdb_file_db &) -> rdb_file_db & = delete; | ||||
|   auto operator=(rdb_file_db &&) -> rdb_file_db & = delete; | ||||
|  | ||||
| private: | ||||
|   const app_config &cfg_; | ||||
|  | ||||
| private: | ||||
|   std::unique_ptr<rocksdb::TransactionDB> db_{nullptr}; | ||||
|   rocksdb::ColumnFamilyHandle *directory_family_{}; | ||||
|   rocksdb::ColumnFamilyHandle *file_family_{}; | ||||
|   rocksdb::ColumnFamilyHandle *path_family_{}; | ||||
|   rocksdb::ColumnFamilyHandle *source_family_{}; | ||||
|  | ||||
| private: | ||||
|   void create_or_open(bool clear); | ||||
|  | ||||
|   [[nodiscard]] auto create_iterator(rocksdb::ColumnFamilyHandle *family) const | ||||
|       -> std::shared_ptr<rocksdb::Iterator>; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   perform_action(std::string_view function_name, | ||||
|                  std::function<rocksdb::Status()> action) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto perform_action( | ||||
|       std::string_view function_name, | ||||
|       std::function<rocksdb::Status(rocksdb::Transaction *txn)> action) | ||||
|       -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto remove_item(const std::string &api_path, | ||||
|                                  const std::string &source_path, | ||||
|                                  rocksdb::Transaction *txn) -> rocksdb::Status; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto | ||||
|   add_directory(const std::string &api_path, | ||||
|                 const std::string &source_path) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   add_or_update_file(const i_file_db::file_data &data) -> api_error override; | ||||
|  | ||||
|   void clear() override; | ||||
|  | ||||
|   [[nodiscard]] auto count() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_api_path(const std::string &source_path, | ||||
|                std::string &api_path) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_directory_api_path(const std::string &source_path, | ||||
|                          std::string &api_path) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_source_path(const std::string &api_path, | ||||
|                                                std::string &source_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_file_api_path(const std::string &source_path, | ||||
|                     std::string &api_path) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_file_data(const std::string &api_path, | ||||
|                 i_file_db::file_data &data) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_file_source_path(const std::string &api_path, | ||||
|                        std::string &source_path) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_item_list() const -> std::vector<i_file_db::file_info> override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_source_path(const std::string &api_path, | ||||
|                   std::string &source_path) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   remove_item(const std::string &api_path) -> api_error override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_IMPL_RDB_FILE_DB_HPP_ | ||||
							
								
								
									
										109
									
								
								repertory/librepertory/include/db/impl/rdb_file_mgr_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								repertory/librepertory/include/db/impl/rdb_file_mgr_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_IMPL_RDB_FILE_MGR_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_IMPL_RDB_FILE_MGR_DB_HPP_ | ||||
|  | ||||
| #include "db/i_file_mgr_db.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class rdb_file_mgr_db final : public i_file_mgr_db { | ||||
| public: | ||||
|   rdb_file_mgr_db(const app_config &cfg); | ||||
|   ~rdb_file_mgr_db() override; | ||||
|  | ||||
|   rdb_file_mgr_db(const rdb_file_mgr_db &) = delete; | ||||
|   rdb_file_mgr_db(rdb_file_mgr_db &&) = delete; | ||||
|   auto operator=(const rdb_file_mgr_db &) -> rdb_file_mgr_db & = delete; | ||||
|   auto operator=(rdb_file_mgr_db &&) -> rdb_file_mgr_db & = delete; | ||||
|  | ||||
| private: | ||||
|   const app_config &cfg_; | ||||
|  | ||||
| private: | ||||
|   std::unique_ptr<rocksdb::TransactionDB> db_{nullptr}; | ||||
|   std::atomic<std::uint64_t> id_{0U}; | ||||
|   rocksdb::ColumnFamilyHandle *resume_family_{}; | ||||
|   rocksdb::ColumnFamilyHandle *upload_active_family_{}; | ||||
|   rocksdb::ColumnFamilyHandle *upload_family_{}; | ||||
|  | ||||
| private: | ||||
|   void create_or_open(bool clear); | ||||
|  | ||||
|   [[nodiscard]] auto create_iterator(rocksdb::ColumnFamilyHandle *family) const | ||||
|       -> std::shared_ptr<rocksdb::Iterator>; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   perform_action(std::string_view function_name, | ||||
|                  std::function<rocksdb::Status()> action) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto perform_action( | ||||
|       std::string_view function_name, | ||||
|       std::function<rocksdb::Status(rocksdb::Transaction *txn)> action) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto remove_resume(const std::string &api_path, | ||||
|                                    rocksdb::Transaction *txn) | ||||
|       -> rocksdb::Status; | ||||
|  | ||||
|   [[nodiscard]] auto add_resume(const resume_entry &entry, | ||||
|                                 rocksdb::Transaction *txn) -> rocksdb::Status; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto add_resume(const resume_entry &entry) -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto add_upload(const upload_entry &entry) -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto add_upload_active(const upload_active_entry &entry) | ||||
|       -> bool override; | ||||
|  | ||||
|   void clear() override; | ||||
|  | ||||
|   [[nodiscard]] auto get_next_upload() const | ||||
|       -> std::optional<upload_entry> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_resume_list() const | ||||
|       -> std::vector<resume_entry> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_upload(const std::string &api_path) const | ||||
|       -> std::optional<upload_entry> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_upload_active_list() const | ||||
|       -> std::vector<upload_active_entry> override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_resume(const std::string &api_path) | ||||
|       -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_upload(const std::string &api_path) | ||||
|       -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_upload_active(const std::string &api_path) | ||||
|       -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto rename_resume(const std::string &from_api_path, | ||||
|                                    const std::string &to_api_path) | ||||
|       -> bool override; | ||||
| }; | ||||
|  | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_IMPL_RDB_FILE_MGR_DB_HPP_ | ||||
							
								
								
									
										127
									
								
								repertory/librepertory/include/db/impl/rdb_meta_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								repertory/librepertory/include/db/impl/rdb_meta_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_IMPL_RDB_META_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_IMPL_RDB_META_DB_HPP_ | ||||
|  | ||||
| #include "db/i_meta_db.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class rdb_meta_db final : public i_meta_db { | ||||
| public: | ||||
|   rdb_meta_db(const app_config &cfg); | ||||
|   ~rdb_meta_db() override; | ||||
|  | ||||
|   rdb_meta_db(const rdb_meta_db &) = delete; | ||||
|   rdb_meta_db(rdb_meta_db &&) = delete; | ||||
|   auto operator=(const rdb_meta_db &) -> rdb_meta_db & = delete; | ||||
|   auto operator=(rdb_meta_db &&) -> rdb_meta_db & = delete; | ||||
|  | ||||
| private: | ||||
|   const app_config &cfg_; | ||||
|  | ||||
| private: | ||||
|   std::unique_ptr<rocksdb::TransactionDB> db_{nullptr}; | ||||
|   rocksdb::ColumnFamilyHandle *meta_family_{}; | ||||
|   rocksdb::ColumnFamilyHandle *pinned_family_{}; | ||||
|   rocksdb::ColumnFamilyHandle *size_family_{}; | ||||
|   rocksdb::ColumnFamilyHandle *source_family_{}; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto create_iterator(rocksdb::ColumnFamilyHandle *family) const | ||||
|       -> std::shared_ptr<rocksdb::Iterator>; | ||||
|  | ||||
|   void create_or_open(bool clear); | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta_json(const std::string &api_path, | ||||
|                                         json &json_data) const -> api_error; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   perform_action(std::string_view function_name, | ||||
|                  std::function<rocksdb::Status()> action) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto perform_action( | ||||
|       std::string_view function_name, | ||||
|       std::function<rocksdb::Status(rocksdb::Transaction *txn)> action) | ||||
|       -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto remove_api_path(const std::string &api_path, | ||||
|                                      const std::string &source_path, | ||||
|                                      rocksdb::Transaction *txn) | ||||
|       -> rocksdb::Status; | ||||
|  | ||||
|   [[nodiscard]] auto update_item_meta(const std::string &api_path, | ||||
|                                       json json_data, | ||||
|                                       rocksdb::Transaction *base_txn = nullptr, | ||||
|                                       rocksdb::Status *status = nullptr) | ||||
|       -> api_error; | ||||
|  | ||||
| public: | ||||
|   void clear() override; | ||||
|  | ||||
|   [[nodiscard]] auto get_api_path(const std::string &source_path, | ||||
|                                   std::string &api_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_api_path_list() const | ||||
|       -> std::vector<std::string> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    api_meta_map &meta) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    const std::string &key, | ||||
|                                    std::string &value) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_pinned_files() const | ||||
|       -> std::vector<std::string> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_size() const -> std::uint64_t override; | ||||
|  | ||||
|   void remove_api_path(const std::string &api_path) override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_item_meta(const std::string &api_path, | ||||
|                                       const std::string &key) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto rename_item_meta(const std::string &from_api_path, | ||||
|                                       const std::string &to_api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto set_item_meta(const std::string &api_path, | ||||
|                                    const std::string &key, | ||||
|                                    const std::string &value) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto set_item_meta(const std::string &api_path, | ||||
|                                    const api_meta_map &meta) | ||||
|       -> api_error override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_IMPL_RDB_META_DB_HPP_ | ||||
							
								
								
									
										92
									
								
								repertory/librepertory/include/db/impl/sqlite_file_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								repertory/librepertory/include/db/impl/sqlite_file_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_IMPL_SQLITE_FILE_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_IMPL_SQLITE_FILE_DB_HPP_ | ||||
|  | ||||
| #include "db/i_file_db.hpp" | ||||
| #include "utils/db/sqlite/db_common.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class sqlite_file_db final : public i_file_db { | ||||
| public: | ||||
|   sqlite_file_db(const app_config &cfg); | ||||
|   ~sqlite_file_db() override; | ||||
|  | ||||
|   sqlite_file_db(const sqlite_file_db &) = delete; | ||||
|   sqlite_file_db(sqlite_file_db &&) = delete; | ||||
|   auto operator=(const sqlite_file_db &) -> sqlite_file_db & = delete; | ||||
|   auto operator=(sqlite_file_db &&) -> sqlite_file_db & = delete; | ||||
|  | ||||
| private: | ||||
|   utils::db::sqlite::db3_t db_; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto add_directory(const std::string &api_path, | ||||
|                                    const std::string &source_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto add_or_update_file(const i_file_db::file_data &data) | ||||
|       -> api_error override; | ||||
|  | ||||
|   void clear() override; | ||||
|  | ||||
|   [[nodiscard]] auto count() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_api_path(const std::string &source_path, | ||||
|                                   std::string &api_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_api_path(const std::string &source_path, | ||||
|                                             std::string &api_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_source_path(const std::string &api_path, | ||||
|                                                std::string &source_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_api_path(const std::string &source_path, | ||||
|                                        std::string &api_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_data(const std::string &api_path, | ||||
|                                    i_file_db::file_data &data) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_source_path(const std::string &api_path, | ||||
|                                           std::string &source_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_list() const | ||||
|       -> std::vector<i_file_db::file_info> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_source_path(const std::string &api_path, | ||||
|                                      std::string &source_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_item(const std::string &api_path) | ||||
|       -> api_error override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_IMPL_SQLITE_FILE_DB_HPP_ | ||||
| @@ -0,0 +1,82 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_IMPL_SQLITE_FILE_MGR_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_IMPL_SQLITE_FILE_MGR_DB_HPP_ | ||||
|  | ||||
| #include "db/i_file_mgr_db.hpp" | ||||
| #include "utils/db/sqlite/db_common.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class sqlite_file_mgr_db final : public i_file_mgr_db { | ||||
| public: | ||||
|   sqlite_file_mgr_db(const app_config &cfg); | ||||
|   ~sqlite_file_mgr_db() override; | ||||
|  | ||||
|   sqlite_file_mgr_db(const sqlite_file_mgr_db &) = delete; | ||||
|   sqlite_file_mgr_db(sqlite_file_mgr_db &&) = delete; | ||||
|   auto operator=(const sqlite_file_mgr_db &) -> sqlite_file_mgr_db & = delete; | ||||
|   auto operator=(sqlite_file_mgr_db &&) -> sqlite_file_mgr_db & = delete; | ||||
|  | ||||
| private: | ||||
|   utils::db::sqlite::db3_t db_; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto add_resume(const resume_entry &entry) -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto add_upload(const upload_entry &entry) -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto add_upload_active(const upload_active_entry &entry) | ||||
|       -> bool override; | ||||
|  | ||||
|   void clear() override; | ||||
|  | ||||
|   [[nodiscard]] auto get_next_upload() const | ||||
|       -> std::optional<upload_entry> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_resume_list() const | ||||
|       -> std::vector<resume_entry> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_upload(const std::string &api_path) const | ||||
|       -> std::optional<upload_entry> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_upload_active_list() const | ||||
|       -> std::vector<upload_active_entry> override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_resume(const std::string &api_path) | ||||
|       -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_upload(const std::string &api_path) | ||||
|       -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_upload_active(const std::string &api_path) | ||||
|       -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto rename_resume(const std::string &from_api_path, | ||||
|                                    const std::string &to_api_path) | ||||
|       -> bool override; | ||||
| }; | ||||
|  | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_IMPL_SQLITE_FILE_MGR_DB_HPP_ | ||||
							
								
								
									
										97
									
								
								repertory/librepertory/include/db/impl/sqlite_meta_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								repertory/librepertory/include/db/impl/sqlite_meta_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_IMPL_SQLITE_META_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_IMPL_SQLITE_META_DB_HPP_ | ||||
|  | ||||
| #include "db/i_meta_db.hpp" | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/db/sqlite/db_common.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class sqlite_meta_db final : public i_meta_db { | ||||
| public: | ||||
|   sqlite_meta_db(const app_config &cfg); | ||||
|   ~sqlite_meta_db() override; | ||||
|  | ||||
|   sqlite_meta_db(const sqlite_meta_db &) = delete; | ||||
|   sqlite_meta_db(sqlite_meta_db &&) = delete; | ||||
|   auto operator=(const sqlite_meta_db &) -> sqlite_meta_db & = delete; | ||||
|   auto operator=(sqlite_meta_db &&) -> sqlite_meta_db & = delete; | ||||
|  | ||||
| private: | ||||
|   utils::db::sqlite::db3_t db_; | ||||
|   constexpr static const auto table_name = "meta"; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto update_item_meta(const std::string &api_path, | ||||
|                                       api_meta_map meta) -> api_error; | ||||
|  | ||||
| public: | ||||
|   void clear() override; | ||||
|  | ||||
|   [[nodiscard]] auto get_api_path(const std::string &source_path, | ||||
|                                   std::string &api_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_api_path_list() const | ||||
|       -> std::vector<std::string> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    api_meta_map &meta) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    const std::string &key, | ||||
|                                    std::string &value) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_pinned_files() const | ||||
|       -> std::vector<std::string> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_size() const -> std::uint64_t override; | ||||
|  | ||||
|   void remove_api_path(const std::string &api_path) override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_item_meta(const std::string &api_path, | ||||
|                                       const std::string &key) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto rename_item_meta(const std::string &from_api_path, | ||||
|                                       const std::string &to_api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto set_item_meta(const std::string &api_path, | ||||
|                                    const std::string &key, | ||||
|                                    const std::string &value) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto set_item_meta(const std::string &api_path, | ||||
|                                    const api_meta_map &meta) | ||||
|       -> api_error override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_IMPL_SQLITE_META_DB_HPP_ | ||||
							
								
								
									
										34
									
								
								repertory/librepertory/include/db/meta_db.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								repertory/librepertory/include/db/meta_db.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DB_META_DB_HPP_ | ||||
| #define REPERTORY_INCLUDE_DB_META_DB_HPP_ | ||||
|  | ||||
| #include "db/i_meta_db.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| [[nodiscard]] auto create_meta_db(const app_config &cfg) | ||||
|     -> std::unique_ptr<i_meta_db>; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DB_META_DB_HPP_ | ||||
							
								
								
									
										76
									
								
								repertory/librepertory/include/drives/directory_cache.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								repertory/librepertory/include/drives/directory_cache.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_ | ||||
|  | ||||
| #include "utils/single_thread_service_base.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class directory_iterator; | ||||
|  | ||||
| class directory_cache final : public single_thread_service_base { | ||||
| public: | ||||
|   using execute_callback = std::function<void(directory_iterator &)>; | ||||
|  | ||||
| private: | ||||
|   struct open_directory final { | ||||
|     std::shared_ptr<directory_iterator> iterator; | ||||
|     std::vector<std::uint64_t> handles; | ||||
|     std::chrono::system_clock::time_point last_update{ | ||||
|         std::chrono::system_clock::now()}; | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   directory_cache() : single_thread_service_base("directory_cache") {} | ||||
|   ~directory_cache() override = default; | ||||
|  | ||||
|   directory_cache(const directory_cache &) = delete; | ||||
|   directory_cache(directory_cache &&) = delete; | ||||
|   auto operator=(const directory_cache &) -> directory_cache & = delete; | ||||
|   auto operator=(directory_cache &&) -> directory_cache & = delete; | ||||
|  | ||||
| private: | ||||
|   std::unordered_map<std::string, open_directory> directory_lookup_; | ||||
|   std::recursive_mutex directory_mutex_; | ||||
|   std::unique_ptr<std::thread> refresh_thread_; | ||||
|  | ||||
| protected: | ||||
|   void service_function() override; | ||||
|  | ||||
| public: | ||||
|   void execute_action(const std::string &api_path, | ||||
|                       const execute_callback &execute); | ||||
|  | ||||
|   [[nodiscard]] auto get_directory(std::uint64_t handle) | ||||
|       -> std::shared_ptr<directory_iterator>; | ||||
|  | ||||
|   [[nodiscard]] auto remove_directory(const std::string &api_path) | ||||
|       -> std::shared_ptr<directory_iterator>; | ||||
|  | ||||
|   void remove_directory(std::uint64_t handle); | ||||
|  | ||||
|   void set_directory(const std::string &api_path, std::uint64_t handle, | ||||
|                      std::shared_ptr<directory_iterator> iterator); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_ | ||||
							
								
								
									
										81
									
								
								repertory/librepertory/include/drives/directory_iterator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								repertory/librepertory/include/drives/directory_iterator.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_DIRECTORY_ITERATOR_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_DIRECTORY_ITERATOR_HPP_ | ||||
|  | ||||
| #include "types/remote.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class directory_iterator final { | ||||
| public: | ||||
| #if !defined(_WIN32) | ||||
|   using populate_stat_callback = | ||||
|       std::function<void(const std::string &, std::uint64_t, | ||||
|                          const api_meta_map &, bool, struct stat *)>; | ||||
| #endif | ||||
| public: | ||||
|   explicit directory_iterator(directory_item_list list) | ||||
|       : items_(std::move(list)) {} | ||||
|  | ||||
|   directory_iterator(const directory_iterator &iterator) noexcept = default; | ||||
|  | ||||
|   directory_iterator(directory_iterator &&iterator) noexcept | ||||
|       : items_(std::move(iterator.items_)) {} | ||||
|  | ||||
| private: | ||||
|   directory_item_list items_; | ||||
|  | ||||
| public: | ||||
| #if !defined(_WIN32) | ||||
|   [[nodiscard]] auto fill_buffer(const remote::file_offset &offset, | ||||
|                                  fuse_fill_dir_t filler_function, void *buffer, | ||||
|                                  populate_stat_callback populate_stat) -> int; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto get(std::size_t offset, std::string &item) -> int; | ||||
|  | ||||
|   [[nodiscard]] auto get_count() const -> std::size_t { return items_.size(); } | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_item(std::size_t offset, | ||||
|                                         directory_item &di) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_item(const std::string &api_path, | ||||
|                                         directory_item &di) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto get_json(std::size_t offset, json &item) -> int; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_next_directory_offset(const std::string &api_path) const -> std::size_t; | ||||
|  | ||||
| public: | ||||
|   auto operator=(const directory_iterator &iterator) noexcept | ||||
|       -> directory_iterator &; | ||||
|  | ||||
|   auto | ||||
|   operator=(directory_iterator &&iterator) noexcept -> directory_iterator &; | ||||
|  | ||||
|   auto operator=(directory_item_list list) noexcept -> directory_iterator &; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_DIRECTORY_ITERATOR_HPP_ | ||||
							
								
								
									
										59
									
								
								repertory/librepertory/include/drives/eviction.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								repertory/librepertory/include/drives/eviction.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_EVICTION_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_EVICTION_HPP_ | ||||
|  | ||||
| #include "utils/single_thread_service_base.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
| class i_file_manager; | ||||
| class i_provider; | ||||
|  | ||||
| class eviction final : public single_thread_service_base { | ||||
| public: | ||||
|   eviction(i_provider &provider, const app_config &config, | ||||
|            i_file_manager &file_mgr) | ||||
|       : single_thread_service_base("eviction"), | ||||
|         config_(config), | ||||
|         file_mgr_(file_mgr), | ||||
|         provider_(provider) {} | ||||
|  | ||||
|   ~eviction() override = default; | ||||
|  | ||||
| private: | ||||
|   const app_config &config_; | ||||
|   i_file_manager &file_mgr_; | ||||
|   i_provider &provider_; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto check_minimum_requirements(const std::string &file_path) | ||||
|       -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto get_filtered_cached_files() -> std::deque<std::string>; | ||||
|  | ||||
| protected: | ||||
|   void service_function() override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_EVICTION_HPP_ | ||||
							
								
								
									
										41
									
								
								repertory/librepertory/include/drives/fuse/events.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								repertory/librepertory/include/drives/fuse/events.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_FUSE_EVENTS_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_FUSE_EVENTS_HPP_ | ||||
|  | ||||
| #include "events/event_system.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| // clang-format off | ||||
| E_SIMPLE3(fuse_event, debug, true, | ||||
|   std::string, function, func, E_FROM_STRING, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   int, result, res, E_FROM_INT32 | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(fuse_args_parsed, info, true, | ||||
|   std::string, arguments, args, E_FROM_STRING | ||||
| ); | ||||
| // clang-format on | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_FUSE_EVENTS_HPP_ | ||||
							
								
								
									
										607
									
								
								repertory/librepertory/include/drives/fuse/fuse_base.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										607
									
								
								repertory/librepertory/include/drives/fuse/fuse_base.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,607 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_FUSE_FUSE_BASE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_FUSE_FUSE_BASE_HPP_ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #include "events/event_system.hpp" | ||||
| #include "utils/path.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
| class i_provider; | ||||
|  | ||||
| class fuse_base { | ||||
|   E_CONSUMER(); | ||||
|  | ||||
| public: | ||||
|   explicit fuse_base(app_config &config); | ||||
|  | ||||
|   virtual ~fuse_base(); | ||||
|  | ||||
| public: | ||||
|   fuse_base(const fuse_base &) = delete; | ||||
|   fuse_base(fuse_base &&) = delete; | ||||
|   auto operator=(const fuse_base &) -> fuse_base & = delete; | ||||
|   auto operator=(fuse_base &&) -> fuse_base & = delete; | ||||
|  | ||||
| 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 auto instance() -> fuse_base &; | ||||
|  | ||||
| private: | ||||
|   struct fuse_operations fuse_ops_ {}; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto | ||||
|   execute_callback(std::string_view function_name, const char *from, | ||||
|                    const char *to, | ||||
|                    const std::function<api_error(std::string, std::string)> &cb, | ||||
|                    bool disable_logging = false) -> int; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   execute_callback(std::string_view function_name, const char *path, | ||||
|                    const std::function<api_error(std::string)> &cb, | ||||
|                    bool disable_logging = false) -> int; | ||||
|  | ||||
|   static void execute_void_callback(std::string_view function_name, | ||||
|                                     const std::function<void()> &cb); | ||||
|  | ||||
|   static auto | ||||
|   execute_void_pointer_callback(std::string_view function_name, | ||||
|                                 const std::function<void *()> &cb) -> void *; | ||||
|  | ||||
|   void raise_fuse_event(std::string_view function_name, | ||||
|                         std::string_view api_path, int ret, | ||||
|                         bool disable_logging); | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] static auto access_(const char *path, int mask) -> int; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] static auto chflags_(const char *path, uint32_t flags) -> int; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] static auto chmod_(const char *path, mode_t mode, | ||||
|                                    struct fuse_file_info *fi) -> int; | ||||
| #else | ||||
|   [[nodiscard]] static auto chmod_(const char *path, mode_t mode) -> int; | ||||
| #endif | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] static auto chown_(const char *path, uid_t uid, gid_t gid, | ||||
|                                    struct fuse_file_info *fi) -> int; | ||||
| #else | ||||
|   [[nodiscard]] static auto chown_(const char *path, uid_t uid, | ||||
|                                    gid_t gid) -> int; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] static auto create_(const char *path, mode_t mode, | ||||
|                                     struct fuse_file_info *fi) -> int; | ||||
|  | ||||
|   static void destroy_(void *ptr); | ||||
|  | ||||
|   [[nodiscard]] static auto fallocate_(const char *path, int mode, off_t offset, | ||||
|                                        off_t length, | ||||
|                                        struct fuse_file_info *fi) -> int; | ||||
|  | ||||
| #if FUSE_USE_VERSION < 30 | ||||
|   [[nodiscard]] static auto fgetattr_(const char *path, struct stat *st, | ||||
|                                       struct fuse_file_info *fi) -> int; | ||||
| #endif | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] static auto fsetattr_x_(const char *path, | ||||
|                                         struct setattr_x *attr, | ||||
|                                         struct fuse_file_info *fi) -> int; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
|   [[nodiscard]] static auto fsync_(const char *path, int datasync, | ||||
|                                    struct fuse_file_info *fi) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto ftruncate_(const char *path, off_t size, | ||||
|                                        struct fuse_file_info *fi) -> int; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] static auto getattr_(const char *path, struct stat *st, | ||||
|                                      struct fuse_file_info *fi) -> int; | ||||
| #else | ||||
|   [[nodiscard]] static auto getattr_(const char *path, struct stat *st) -> int; | ||||
| #endif | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] static auto getxtimes_(const char *path, | ||||
|                                        struct timespec *bkuptime, | ||||
|                                        struct timespec *crtime) -> int; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] static auto init_(struct fuse_conn_info *conn, | ||||
|                                   struct fuse_config *cfg) -> void *; | ||||
| #else | ||||
|   [[nodiscard]] static auto init_(struct fuse_conn_info *conn) -> void *; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] static auto mkdir_(const char *path, mode_t mode) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto open_(const char *path, | ||||
|                                   struct fuse_file_info *fi) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto opendir_(const char *path, | ||||
|                                      struct fuse_file_info *fi) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto read_(const char *path, char *buffer, | ||||
|                                   size_t read_size, off_t read_offset, | ||||
|                                   struct fuse_file_info *fi) -> int; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] static auto readdir_(const char *path, void *buf, | ||||
|                                      fuse_fill_dir_t fuse_fill_dir, | ||||
|                                      off_t offset, struct fuse_file_info *fi, | ||||
|                                      fuse_readdir_flags flags) -> int; | ||||
| #else | ||||
|   [[nodiscard]] static auto readdir_(const char *path, void *buf, | ||||
|                                      fuse_fill_dir_t fuse_fill_dir, | ||||
|                                      off_t offset, | ||||
|                                      struct fuse_file_info *fi) -> int; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] static auto release_(const char *path, | ||||
|                                      struct fuse_file_info *fi) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto releasedir_(const char *path, | ||||
|                                         struct fuse_file_info *fi) -> int; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] static auto rename_(const char *from, const char *to, | ||||
|                                     unsigned int flags) -> int; | ||||
| #else | ||||
|   [[nodiscard]] static auto rename_(const char *from, const char *to) -> int; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] static auto rmdir_(const char *path) -> int; | ||||
|  | ||||
| #if defined(HAS_SETXATTR) | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] static auto getxattr_(const char *path, const char *name, | ||||
|                                       char *value, size_t size, | ||||
|                                       uint32_t position) -> int; | ||||
|  | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] static auto getxattr_(const char *path, const char *name, | ||||
|                                       char *value, size_t size) -> int; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
|   [[nodiscard]] static auto listxattr_(const char *path, char *buffer, | ||||
|                                        size_t size) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto removexattr_(const char *path, | ||||
|                                          const char *name) -> int; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] static auto setxattr_(const char *path, const char *name, | ||||
|                                       const char *value, size_t size, int flags, | ||||
|                                       uint32_t position) -> int; | ||||
|  | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] static auto setxattr_(const char *path, const char *name, | ||||
|                                       const char *value, size_t size, | ||||
|                                       int flags) -> int; | ||||
| #endif // __APPLE__ | ||||
| #endif // HAS_SETXATTR | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] static auto setattr_x_(const char *path, | ||||
|                                        struct setattr_x *attr) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   setbkuptime_(const char *path, const struct timespec *bkuptime) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto setchgtime_(const char *path, | ||||
|                                         const struct timespec *chgtime) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto setcrtime_(const char *path, | ||||
|                                        const struct timespec *crtime) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto setvolname_(const char *volname) -> int; | ||||
|  | ||||
|   [[nodiscard]] static auto statfs_x_(const char *path, | ||||
|                                       struct statfs *stbuf) -> int; | ||||
|  | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] static auto statfs_(const char *path, | ||||
|                                     struct statvfs *stbuf) -> int; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] static auto truncate_(const char *path, off_t size, | ||||
|                                       struct fuse_file_info *fi) -> int; | ||||
| #else | ||||
|   [[nodiscard]] static auto truncate_(const char *path, off_t size) -> int; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] static auto unlink_(const char *path) -> int; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] static auto utimens_(const char *path, | ||||
|                                      const struct timespec tv[2], | ||||
|                                      struct fuse_file_info *fi) -> int; | ||||
| #else | ||||
|   [[nodiscard]] static auto utimens_(const char *path, | ||||
|                                      const struct timespec tv[2]) -> int; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] static auto write_(const char *path, const char *buffer, | ||||
|                                    size_t write_size, off_t write_offset, | ||||
|                                    struct fuse_file_info *fi) -> int; | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] virtual auto access_impl(std::string /*api_path*/, | ||||
|                                          int /*mask*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] virtual auto chflags_impl(std::string /*api_path*/, | ||||
|                                           uint32_t /*flags*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] virtual auto | ||||
|   chmod_impl(std::string /*api_path*/, mode_t /*mode*/, | ||||
|              struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else | ||||
|   [[nodiscard]] virtual auto chmod_impl(std::string /*api_path*/, | ||||
|                                         mode_t /*mode*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] virtual auto | ||||
|   chown_impl(std::string /*api_path*/, uid_t /*uid*/, gid_t /*gid*/, | ||||
|              struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else | ||||
|   [[nodiscard]] virtual auto chown_impl(std::string /*api_path*/, uid_t /*uid*/, | ||||
|                                         gid_t /*gid*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   create_impl(std::string /*api_path*/, mode_t /*mode*/, | ||||
|               struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   virtual void destroy_impl(void * /*ptr*/); | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fallocate_impl(std::string /*api_path*/, int /*mode*/, off_t /*offset*/, | ||||
|                  off_t /*length*/, | ||||
|                  struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fgetattr_impl(std::string /*api_path*/, struct stat * /*st*/, | ||||
|                 struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] virtual auto | ||||
|   fsetattr_x_impl(std::string /*api_path*/, struct setattr_x * /*attr*/, | ||||
|                   struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif // __APPLE__ | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fsync_impl(std::string /*api_path*/, int /*datasync*/, | ||||
|              struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
| #if FUSE_USE_VERSION < 30 | ||||
|   [[nodiscard]] virtual auto | ||||
|   ftruncate_impl(std::string /*api_path*/, off_t /*size*/, | ||||
|                  struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] virtual auto | ||||
|   getattr_impl(std::string /*api_path*/, struct stat * /*st*/, | ||||
|                struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else | ||||
|   [[nodiscard]] virtual auto getattr_impl(std::string /*api_path*/, | ||||
|                                           struct stat * /*st*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] virtual auto | ||||
|   getxtimes_impl(std::string /*api_path*/, struct timespec * /*bkuptime*/, | ||||
|                  struct timespec * /*crtime*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   virtual auto init_impl(struct fuse_conn_info *conn, | ||||
|                          struct fuse_config *cfg) -> void *; | ||||
| #else | ||||
|   virtual auto init_impl(struct fuse_conn_info *conn) -> void *; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] virtual auto mkdir_impl(std::string /*api_path*/, | ||||
|                                         mode_t /*mode*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   open_impl(std::string /*api_path*/, | ||||
|             struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   opendir_impl(std::string /*api_path*/, | ||||
|                struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   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*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] virtual auto | ||||
|   readdir_impl(std::string /*api_path*/, void * /*buf*/, | ||||
|                fuse_fill_dir_t /*fuse_fill_dir*/, off_t /*offset*/, | ||||
|                struct fuse_file_info * /*fi*/, | ||||
|                fuse_readdir_flags /*flags*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else | ||||
|   [[nodiscard]] virtual auto | ||||
|   readdir_impl(std::string /*api_path*/, void * /*buf*/, | ||||
|                fuse_fill_dir_t /*fuse_fill_dir*/, off_t /*offset*/, | ||||
|                struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   release_impl(std::string /*api_path*/, | ||||
|                struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   releasedir_impl(std::string /*api_path*/, | ||||
|                   struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] virtual auto rename_impl(std::string /*from_api_path*/, | ||||
|                                          std::string /*to_api_path*/, | ||||
|                                          unsigned int /*flags*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else | ||||
|   [[nodiscard]] virtual auto | ||||
|   rename_impl(std::string /*from_api_path*/, | ||||
|               std::string /*to_api_path*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] virtual auto rmdir_impl(std::string /*api_path*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
| #if defined(HAS_SETXATTR) | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] virtual auto | ||||
|   getxattr_impl(std::string /*api_path*/, const char * /*name*/, | ||||
|                 char * /*value*/, size_t /*size*/, uint32_t /*position*/, | ||||
|                 int & /*attribute_size*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] virtual auto | ||||
|   getxattr_impl(std::string /*api_path*/, const char * /*name*/, | ||||
|                 char * /*value*/, size_t /*size*/, | ||||
|                 int & /*attribute_size*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif // __APPLE__ | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   listxattr_impl(std::string /*api_path*/, char * /*buffer*/, size_t /*size*/, | ||||
|                  int & /*required_size*/, bool & /*return_size*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   removexattr_impl(std::string /*api_path*/, | ||||
|                    const char * /*name*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] virtual auto setxattr_impl(std::string /*api_path*/, | ||||
|                                            const char * /*name*/, | ||||
|                                            const char * /*value*/, | ||||
|                                            size_t /*size*/, int /*flags*/, | ||||
|                                            uint32_t /*position*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] virtual auto setxattr_impl(std::string /*api_path*/, | ||||
|                                            const char * /*name*/, | ||||
|                                            const char * /*value*/, | ||||
|                                            size_t /*size*/, | ||||
|                                            int /*flags*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif // __APPLE__ | ||||
| #endif // HAS_SETXATTR | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] virtual auto | ||||
|   setattr_x_impl(std::string /*api_path*/, | ||||
|                  struct setattr_x * /*attr*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   setbkuptime_impl(std::string /*api_path*/, | ||||
|                    const struct timespec * /*bkuptime*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   setchgtime_impl(std::string /*api_path*/, | ||||
|                   const struct timespec * /*chgtime*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   setcrtime_impl(std::string /*api_path*/, | ||||
|                  const struct timespec * /*crtime*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   setvolname_impl(const char * /*volname*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   statfs_x_impl(std::string /*api_path*/, | ||||
|                 struct statfs * /*stbuf*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] virtual auto | ||||
|   statfs_impl(std::string /*api_path*/, | ||||
|               struct statvfs * /*stbuf*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] virtual auto | ||||
|   truncate_impl(std::string /*api_path*/, off_t /*size*/, | ||||
|                 struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else | ||||
|   [[nodiscard]] virtual auto truncate_impl(std::string /*api_path*/, | ||||
|                                            off_t /*size*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   unlink_impl(std::string /*api_path*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] virtual auto | ||||
|   utimens_impl(std::string /*api_path*/, const struct timespec /*tv*/[2], | ||||
|                struct fuse_file_info * /*fi*/) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #else | ||||
|   [[nodiscard]] virtual auto | ||||
|   utimens_impl(std::string /*api_path*/, | ||||
|                const struct timespec /*tv*/[2]) -> api_error { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   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*/) -> api_error { | ||||
|     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*/) {} | ||||
|  | ||||
|   [[nodiscard]] virtual auto parse_args(std::vector<std::string> &args) -> int; | ||||
|  | ||||
|   virtual void shutdown(); | ||||
|  | ||||
| public: | ||||
|   static void display_options(std::vector<const char *> args); | ||||
|  | ||||
|   static void display_version_information(std::vector<const char *> args); | ||||
|  | ||||
|   static auto unmount(const std::string &mount_location) -> int; | ||||
|  | ||||
|   [[nodiscard]] auto get_mount_location() const -> std::string { | ||||
|     return mount_location_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto mount(std::vector<std::string> args) -> int; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_FUSE_FUSE_BASE_HPP_ | ||||
							
								
								
									
										326
									
								
								repertory/librepertory/include/drives/fuse/fuse_drive.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								repertory/librepertory/include/drives/fuse/fuse_drive.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,326 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_FUSE_FUSE_DRIVE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_FUSE_FUSE_DRIVE_HPP_ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #include "drives/fuse/fuse_drive_base.hpp" | ||||
| #include "file_manager/file_manager.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
| class console_consumer; | ||||
| class directory_cache; | ||||
| class eviction; | ||||
| class full_server; | ||||
| class i_provider; | ||||
| class lock_data; | ||||
| class logging_consumer; | ||||
| namespace remote_fuse { | ||||
| class remote_server; | ||||
| } | ||||
|  | ||||
| class fuse_drive final : public fuse_drive_base { | ||||
| public: | ||||
|   fuse_drive(app_config &config, lock_data &lock_data, i_provider &provider); | ||||
|  | ||||
|   ~fuse_drive() override = default; | ||||
|  | ||||
| public: | ||||
|   fuse_drive(const fuse_drive &) = delete; | ||||
|   fuse_drive(fuse_drive &&) = delete; | ||||
|  | ||||
|   auto operator=(const fuse_drive &) -> fuse_drive & = delete; | ||||
|   auto operator=(fuse_drive &&) -> fuse_drive & = delete; | ||||
|  | ||||
| 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<eviction> eviction_; | ||||
|   std::shared_ptr<file_manager> fm_; | ||||
|   std::shared_ptr<logging_consumer> logging_consumer_; | ||||
|   std::shared_ptr<remote_fuse::remote_server> remote_server_; | ||||
|   std::shared_ptr<full_server> server_; | ||||
|   bool was_mounted_ = false; | ||||
|  | ||||
| private: | ||||
|   void update_accessed_time(const std::string &api_path); | ||||
|  | ||||
| protected: | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto chflags_impl(std::string api_path, | ||||
|                                   uint32_t flags) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   chmod_impl(std::string api_path, mode_t mode, | ||||
|              struct fuse_file_info *file_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto chmod_impl(std::string api_path, | ||||
|                                 mode_t mode) -> api_error override; | ||||
| #endif | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   chown_impl(std::string api_path, uid_t uid, gid_t gid, | ||||
|              struct fuse_file_info *file_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, | ||||
|                                 gid_t gid) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   create_impl(std::string api_path, mode_t mode, | ||||
|               struct fuse_file_info *file_info) -> api_error override; | ||||
|  | ||||
|   void destroy_impl(void *ptr) override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fallocate_impl(std::string api_path, int mode, off_t offset, off_t length, | ||||
|                  struct fuse_file_info *file_info) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fgetattr_impl(std::string api_path, struct stat *unix_st, | ||||
|                 struct fuse_file_info *file_info) -> api_error override; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto | ||||
|   fsetattr_x_impl(std::string api_path, struct setattr_x *attr, | ||||
|                   struct fuse_file_info *file_info) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fsync_impl(std::string api_path, int datasync, | ||||
|              struct fuse_file_info *file_info) -> api_error override; | ||||
|  | ||||
| #if FUSE_USE_VERSION < 30 | ||||
|   [[nodiscard]] auto | ||||
|   ftruncate_impl(std::string api_path, off_t size, | ||||
|                  struct fuse_file_info *file_info) -> api_error override; | ||||
| #endif | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   getattr_impl(std::string api_path, struct stat *unix_st, | ||||
|                struct fuse_file_info *file_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto getattr_impl(std::string api_path, | ||||
|                                   struct stat *unix_st) -> api_error override; | ||||
| #endif | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto | ||||
|   getxtimes_impl(std::string api_path, struct timespec *bkuptime, | ||||
|                  struct timespec *crtime) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   auto init_impl(struct fuse_conn_info *conn, | ||||
|                  struct fuse_config *cfg) -> void * override; | ||||
| #else | ||||
|   auto init_impl(struct fuse_conn_info *conn) -> void * override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto mkdir_impl(std::string api_path, | ||||
|                                 mode_t mode) -> api_error override; | ||||
|  | ||||
|   void notify_fuse_main_exit(int &ret) override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   open_impl(std::string api_path, | ||||
|             struct fuse_file_info *file_info) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   opendir_impl(std::string api_path, | ||||
|                struct fuse_file_info *file_info) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto read_impl(std::string api_path, char *buffer, | ||||
|                                size_t read_size, off_t read_offset, | ||||
|                                struct fuse_file_info *file_info, | ||||
|                                std::size_t &bytes_read) -> api_error override; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir, | ||||
|                off_t offset, struct fuse_file_info *file_info, | ||||
|                fuse_readdir_flags flags) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto | ||||
|   readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir, | ||||
|                off_t offset, | ||||
|                struct fuse_file_info *file_info) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   release_impl(std::string api_path, | ||||
|                struct fuse_file_info *file_info) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   releasedir_impl(std::string api_path, | ||||
|                   struct fuse_file_info *file_info) -> api_error override; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto rename_impl(std::string from_api_path, | ||||
|                                  std::string to_api_path, | ||||
|                                  unsigned int flags) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto rename_impl(std::string from_api_path, | ||||
|                                  std::string to_api_path) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto rmdir_impl(std::string api_path) -> api_error override; | ||||
|  | ||||
| #if defined(HAS_SETXATTR) | ||||
|   [[nodiscard]] auto getxattr_common(std::string api_path, const char *name, | ||||
|                                      char *value, size_t size, | ||||
|                                      int &attribute_size, | ||||
|                                      uint32_t *position) -> api_error; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto getxattr_impl(std::string api_path, const char *name, | ||||
|                                    char *value, size_t size, uint32_t position, | ||||
|                                    int &attribute_size) -> api_error override; | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] auto getxattr_impl(std::string api_path, const char *name, | ||||
|                                    char *value, size_t size, | ||||
|                                    int &attribute_size) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
|   [[nodiscard]] auto listxattr_impl(std::string api_path, char *buffer, | ||||
|                                     size_t size, int &required_size, | ||||
|                                     bool &return_size) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto removexattr_impl(std::string api_path, | ||||
|                                       const char *name) -> api_error override; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto setxattr_impl(std::string api_path, const char *name, | ||||
|                                    const char *value, size_t size, int flags, | ||||
|                                    uint32_t position) -> api_error override; | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] auto setxattr_impl(std::string api_path, const char *name, | ||||
|                                    const char *value, size_t size, | ||||
|                                    int flags) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
| #endif // HAS_SETXATTR | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto | ||||
|   setattr_x_impl(std::string api_path, | ||||
|                  struct setattr_x *attr) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   setbkuptime_impl(std::string api_path, | ||||
|                    const struct timespec *bkuptime) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   setchgtime_impl(std::string api_path, | ||||
|                   const struct timespec *chgtime) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   setcrtime_impl(std::string api_path, | ||||
|                  const struct timespec *crtime) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto setvolname_impl(const char *volname) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto statfs_x_impl(std::string api_path, | ||||
|                                    struct statfs *stbuf) -> api_error override; | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] auto statfs_impl(std::string api_path, | ||||
|                                  struct statvfs *stbuf) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   truncate_impl(std::string api_path, off_t size, | ||||
|                 struct fuse_file_info *file_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto truncate_impl(std::string api_path, | ||||
|                                    off_t size) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto unlink_impl(std::string api_path) -> api_error override; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   utimens_impl(std::string api_path, const struct timespec tv[2], | ||||
|                struct fuse_file_info *file_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto | ||||
|   utimens_impl(std::string api_path, | ||||
|                const struct timespec tv[2]) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   write_impl(std::string api_path, const char *buffer, size_t write_size, | ||||
|              off_t write_offset, struct fuse_file_info *file_info, | ||||
|              std::size_t &bytes_written) -> api_error override; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const | ||||
|       -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_items(const std::string &api_path) const | ||||
|       -> directory_item_list override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_file_size(const std::string &api_path) const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_item_meta(const std::string &api_path, | ||||
|                 api_meta_map &meta) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_item_meta(const std::string &api_path, const std::string &name, | ||||
|                 std::string &value) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override; | ||||
|  | ||||
|   void get_volume_info(UINT64 &total_size, UINT64 &free_size, | ||||
|                        std::string &volume_label) const override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   is_processing(const std::string &api_path) const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   rename_directory(const std::string &from_api_path, | ||||
|                    const std::string &to_api_path) -> int override; | ||||
|  | ||||
|   [[nodiscard]] auto rename_file(const std::string &from_api_path, | ||||
|                                  const std::string &to_api_path, | ||||
|                                  bool overwrite) -> int override; | ||||
|  | ||||
|   void set_item_meta(const std::string &api_path, const std::string &key, | ||||
|                      const std::string &value) override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_FUSE_FUSE_DRIVE_HPP_ | ||||
							
								
								
									
										137
									
								
								repertory/librepertory/include/drives/fuse/fuse_drive_base.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								repertory/librepertory/include/drives/fuse/fuse_drive_base.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_FUSE_FUSE_DRIVE_BASE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_FUSE_FUSE_DRIVE_BASE_HPP_ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #include "drives/fuse/fuse_base.hpp" | ||||
| #include "drives/fuse/i_fuse_drive.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
| class i_provider; | ||||
|  | ||||
| class fuse_drive_base : public fuse_base, public i_fuse_drive { | ||||
| public: | ||||
|   explicit fuse_drive_base(app_config &config) : fuse_base(config) {} | ||||
|  | ||||
|   ~fuse_drive_base() override = default; | ||||
|  | ||||
| public: | ||||
|   fuse_drive_base(const fuse_drive_base &) = delete; | ||||
|   fuse_drive_base(fuse_drive_base &&) = delete; | ||||
|   auto operator=(const fuse_drive_base &) -> fuse_drive_base & = delete; | ||||
|   auto operator=(fuse_drive_base &&) -> fuse_drive_base & = delete; | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto access_impl(std::string api_path, | ||||
|                                  int mask) -> api_error override; | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto check_access(const std::string &api_path, | ||||
|                                   int mask) const -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto check_and_perform( | ||||
|       const std::string &api_path, int parent_mask, | ||||
|       const std::function<api_error(api_meta_map &meta)> &action) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto get_current_gid() const -> gid_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_current_uid() const -> uid_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_effective_gid() const -> gid_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_effective_uid() const -> uid_t; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   check_open_flags(int flags, int mask, | ||||
|                    const api_error &fail_error) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto check_owner(const api_meta_map &meta) const -> api_error; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   check_readable(int flags, const api_error &fail_error) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   check_writeable(int flags, const api_error &fail_error) -> api_error; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] static auto | ||||
|   get_flags_from_meta(const api_meta_map &meta) -> __uint32_t; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   get_gid_from_meta(const api_meta_map &meta) -> gid_t; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   get_mode_from_meta(const api_meta_map &meta) -> mode_t; | ||||
|  | ||||
|   static void get_timespec_from_meta(const api_meta_map &meta, | ||||
|                                      const std::string &name, | ||||
|                                      struct timespec &ts); | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   get_uid_from_meta(const api_meta_map &meta) -> uid_t; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto | ||||
|   parse_xattr_parameters(const char *name, const uint32_t &position, | ||||
|                          std::string &attribute_name, | ||||
|                          const std::string &api_path) -> api_error; | ||||
| #else | ||||
|   [[nodiscard]] auto | ||||
|   parse_xattr_parameters(const char *name, std::string &attribute_name, | ||||
|                          const std::string &api_path) -> api_error; | ||||
| #endif | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto | ||||
|   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) -> api_error; | ||||
| #else | ||||
|   [[nodiscard]] auto | ||||
|   parse_xattr_parameters(const char *name, const char *value, size_t size, | ||||
|                          std::string &attribute_name, | ||||
|                          const std::string &api_path) -> api_error; | ||||
| #endif | ||||
|  | ||||
|   static void populate_stat(const std::string &api_path, | ||||
|                             std::uint64_t size_or_count, | ||||
|                             const api_meta_map &meta, bool directory, | ||||
|                             i_provider &provider, struct stat *st); | ||||
|  | ||||
|   static void set_timespec_from_meta(const api_meta_map &meta, | ||||
|                                      const std::string &name, | ||||
|                                      struct timespec &ts); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto | ||||
|   check_owner(const std::string &api_path) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto check_parent_access(const std::string &api_path, | ||||
|                                          int mask) const -> api_error override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_FUSE_FUSE_DRIVE_BASE_HPP_ | ||||
							
								
								
									
										84
									
								
								repertory/librepertory/include/drives/fuse/i_fuse_drive.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								repertory/librepertory/include/drives/fuse/i_fuse_drive.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_FUSE_I_FUSE_DRIVE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_FUSE_I_FUSE_DRIVE_HPP_ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_fuse_drive { | ||||
|   INTERFACE_SETUP(i_fuse_drive); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] virtual auto | ||||
|   check_owner(const std::string &api_path) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   check_parent_access(const std::string &api_path, | ||||
|                       int mask) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_directory_item_count( | ||||
|       const std::string &api_path) const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_directory_items( | ||||
|       const std::string &api_path) const -> directory_item_list = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_file_size(const std::string &api_path) const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_item_meta(const std::string &api_path, | ||||
|                 api_meta_map &meta) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_item_meta(const std::string &api_path, const std::string &name, | ||||
|                 std::string &value) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_total_drive_space() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_total_item_count() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_used_drive_space() const -> std::uint64_t = 0; | ||||
|  | ||||
|   virtual void get_volume_info(UINT64 &total_size, UINT64 &free_size, | ||||
|                                std::string &volume_label) const = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   is_processing(const std::string &api_path) const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   rename_directory(const std::string &from_api_path, | ||||
|                    const std::string &to_api_path) -> int = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto rename_file(const std::string &from_api_path, | ||||
|                                          const std::string &to_api_path, | ||||
|                                          bool overwrite) -> int = 0; | ||||
|  | ||||
|   virtual void set_item_meta(const std::string &api_path, | ||||
|                              const std::string &key, | ||||
|                              const std::string &value) = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_FUSE_I_FUSE_DRIVE_HPP_ | ||||
| @@ -0,0 +1,199 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_I_REMOTE_INSTANCE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_I_REMOTE_INSTANCE_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: | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_access(const char *path, | ||||
|               const std::int32_t &mask) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_chflags(const char *path, std::uint32_t flags) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_chmod(const char *path, | ||||
|              const remote::file_mode &mode) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_chown(const char *path, const remote::user_id &uid, | ||||
|              const remote::group_id &gid) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_create(const char *path, const remote::file_mode &mode, | ||||
|               const remote::open_flags &flags, | ||||
|               remote::file_handle &handle) -> packet::error_type = 0; | ||||
|   [[nodiscard]] virtual auto fuse_destroy() -> packet::error_type = 0; | ||||
|  | ||||
|   /*[[nodiscard]] 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;*/ | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_fgetattr(const char *path, remote::stat &r_stat, bool &directory, | ||||
|                 const remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_fsetattr_x(const char *path, const remote::setattr_x &attr, | ||||
|                   const remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_fsync(const char *path, const std::int32_t &datasync, | ||||
|              const remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_ftruncate(const char *path, const remote::file_offset &size, | ||||
|                  const remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_getattr(const char *path, remote::stat &r_stat, | ||||
|                bool &directory) -> packet::error_type = 0; | ||||
|  | ||||
|   /*[[nodiscard]] virtual packet::error_type fuse_getxattr(const char *path, | ||||
|   const char *name, char *value, const remote::file_size &size) = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual packet::error_type fuse_getxattrOSX(const char *path, | ||||
|   const char *name, char *value, const remote::file_size &size, std::uint32_t | ||||
|   position) = 0;*/ | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_getxtimes(const char *path, remote::file_time &bkuptime, | ||||
|                  remote::file_time &crtime) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto fuse_init() -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] /*virtual packet::error_type fuse_listxattr(const char *path, | ||||
|                    char *buffer, const remote::file_size &size) = 0;*/ | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_mkdir(const char *path, | ||||
|              const remote::file_mode &mode) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_open(const char *path, const remote::open_flags &flags, | ||||
|             remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_opendir(const char *path, | ||||
|                remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_read(const char *path, char *buffer, const remote::file_size &read_size, | ||||
|             const remote::file_offset &read_offset, | ||||
|             const remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_readdir(const char *path, const remote::file_offset &offset, | ||||
|                const remote::file_handle &handle, | ||||
|                std::string &item_path) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_release(const char *path, | ||||
|                const remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_releasedir(const char *path, | ||||
|                   const remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   //[[nodiscard]] virtual packet::error_type fuse_removexattr(const char *path, | ||||
|   // const char *name) = | ||||
|   // 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_rename(const char *from, const char *to) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_rmdir(const char *path) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_setattr_x(const char *path, | ||||
|                  remote::setattr_x &attr) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_setbkuptime(const char *path, | ||||
|                    const remote::file_time &bkuptime) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_setchgtime(const char *path, | ||||
|                   const remote::file_time &chgtime) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_setcrtime(const char *path, | ||||
|                  const remote::file_time &crtime) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_setvolname(const char *volname) -> packet::error_type = 0; | ||||
|  | ||||
|   /*[[nodiscard]] 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; | ||||
|   [[nodiscard]] 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, std::uint32_t position) = 0;*/ | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_statfs(const char *path, std::uint64_t frsize, | ||||
|               remote::statfs &r_stat) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_statfs_x(const char *path, std::uint64_t bsize, | ||||
|                 remote::statfs_x &r_stat) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_truncate(const char *path, | ||||
|                 const remote::file_offset &size) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_unlink(const char *path) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_utimens(const char *path, const remote::file_time *tv, std::uint64_t op0, | ||||
|                std::uint64_t op1) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   fuse_write(const char *path, const char *buffer, | ||||
|              const remote::file_size &writeSize, | ||||
|              const remote::file_offset &writeOffset, | ||||
|              const remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto fuse_write_base64( | ||||
|       const char *path, const char *buffer, const remote::file_size &writeSize, | ||||
|       const remote::file_offset &writeOffset, | ||||
|       const remote::file_handle &handle) -> packet::error_type = 0; | ||||
|  | ||||
|   virtual void set_fuse_uid_gid(const remote::user_id &uid, | ||||
|                                 const remote::group_id &gid) = 0; | ||||
| }; | ||||
|  | ||||
| using remote_instance_factory = | ||||
|     std::function<std::unique_ptr<i_remote_instance>()>; | ||||
| } // namespace repertory::remote_fuse | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_I_REMOTE_INSTANCE_HPP_ | ||||
| @@ -0,0 +1,218 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_CLIENT_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_CLIENT_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: | ||||
|   [[nodiscard]] auto fuse_access(const char *path, const std::int32_t &mask) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_chmod(const char *path, const remote::file_mode &mode) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_chown(const char *path, const remote::user_id &uid, | ||||
|              const remote::group_id &gid) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_destroy() -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] /*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 ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_fgetattr(const char *path, remote::stat &st, bool &directory, | ||||
|                 const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_fsetattr_x( | ||||
|       const char *path, const remote::setattr_x &attr, | ||||
|       const remote::file_handle &handle) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_fsync(const char *path, const std::int32_t &datasync, | ||||
|              const remote::file_handle &handle) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_ftruncate( | ||||
|       const char *path, const remote::file_offset &size, | ||||
|       const remote::file_handle &handle) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_getattr(const char *path, remote::stat &st, | ||||
|                bool &directory) -> packet::error_type override; | ||||
|  | ||||
|   /*[[nodiscard]] packet::error_type fuse_getxattr(const char *path, const char | ||||
|   *name, char *value, const remote::file_size &size) override ; | ||||
|  | ||||
|   [[nodiscard]] packet::error_type fuse_getxattrOSX(const char *path, const char | ||||
|   *name, char *value, const remote::file_size &size, std::uint32_t position) | ||||
|   override ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_getxtimes(const char *path, remote::file_time &bkuptime, | ||||
|                  remote::file_time &crtime) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_init() -> packet::error_type override; | ||||
|  | ||||
|   /*[[nodiscard]] packet::error_type fuse_listxattr(const char *path, char | ||||
|    *buffer, const remote::file_size &size) override ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto fuse_mkdir(const char *path, const remote::file_mode &mode) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_opendir(const char *path, remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_create(const char *path, const remote::file_mode &mode, | ||||
|               const remote::open_flags &flags, | ||||
|               remote::file_handle &handle) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_open(const char *path, const remote::open_flags &flags, | ||||
|             remote::file_handle &handle) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_read(const char *path, char *buffer, const remote::file_size &read_size, | ||||
|             const remote::file_offset &read_offset, | ||||
|             const remote::file_handle &handle) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_rename(const char *from, | ||||
|                                  const char *to) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_readdir(const char *path, const remote::file_offset &offset, | ||||
|                const remote::file_handle &handle, | ||||
|                std::string &item_path) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_release(const char *path, | ||||
|                                   const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_releasedir(const char *path, | ||||
|                                      const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   /*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const | ||||
|    * char *name) override | ||||
|    * ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_rmdir(const char *path) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_setattr_x(const char *path, remote::setattr_x &attr) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_setbkuptime(const char *path, | ||||
|                                       const remote::file_time &bkuptime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_setchgtime(const char *path, | ||||
|                                      const remote::file_time &chgtime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_setcrtime(const char *path, | ||||
|                                     const remote::file_time &crtime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_setvolname(const char *volname) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] /*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 ; | ||||
|  | ||||
|   [[nodiscard]] 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, std::uint32_t position) override ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_statfs(const char *path, std::uint64_t frsize, | ||||
|               remote::statfs &st) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_statfs_x(const char *path, std::uint64_t bsize, | ||||
|                 remote::statfs_x &st) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_truncate(const char *path, | ||||
|                 const remote::file_offset &size) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_unlink(const char *path) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_utimens(const char *path, const remote::file_time *tv, std::uint64_t op0, | ||||
|                std::uint64_t op1) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   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) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto 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) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto json_create_directory_snapshot( | ||||
|       const std::string &path, json &json_data) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto json_read_directory_snapshot( | ||||
|       const std::string &path, const remote::file_handle &handle, | ||||
|       std::uint32_t page, json &json_data) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto json_release_directory_snapshot( | ||||
|       const std::string &path, | ||||
|       const remote::file_handle &handle) -> packet::error_type override; | ||||
|  | ||||
|   void set_fuse_uid_gid(const remote::user_id &uid, | ||||
|                         const remote::group_id &gid) override; | ||||
| }; | ||||
| } // namespace remote_fuse | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_CLIENT_HPP_ | ||||
| @@ -0,0 +1,241 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE_HPP_ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #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 remote_fuse { | ||||
| class remote_fuse_drive final : public fuse_base { | ||||
| public: | ||||
|   remote_fuse_drive(app_config &config, remote_instance_factory factory, | ||||
|                     lock_data &lock) | ||||
|       : fuse_base(config), factory_(std::move(factory)), lock_data_(lock) {} | ||||
|  | ||||
|   ~remote_fuse_drive() override = default; | ||||
|  | ||||
| private: | ||||
|   remote_instance_factory factory_; | ||||
|   lock_data &lock_data_; | ||||
|   std::shared_ptr<console_consumer> console_consumer_; | ||||
|   std::shared_ptr<logging_consumer> logging_consumer_; | ||||
|   std::shared_ptr<i_remote_instance> remote_instance_; | ||||
|   std::shared_ptr<server> server_; | ||||
|   bool was_mounted_ = false; | ||||
|  | ||||
| private: | ||||
|   void populate_stat(const remote::stat &r_stat, bool directory, | ||||
|                      struct stat &unix_st); | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto access_impl(std::string api_path, | ||||
|                                  int mask) -> api_error override; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto chflags_impl(std::string api_path, | ||||
|                                   uint32_t flags) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   chmod_impl(std::string api_path, mode_t mode, | ||||
|              struct fuse_file_info *f_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto chmod_impl(std::string api_path, | ||||
|                                 mode_t mode) -> api_error override; | ||||
| #endif | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   chown_impl(std::string api_path, uid_t uid, gid_t gid, | ||||
|              struct fuse_file_info *f_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, | ||||
|                                 gid_t gid) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   create_impl(std::string api_path, mode_t mode, | ||||
|               struct fuse_file_info *f_info) -> api_error override; | ||||
|  | ||||
|   void destroy_impl(void * /*ptr*/) override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fgetattr_impl(std::string api_path, struct stat *unix_st, | ||||
|                 struct fuse_file_info *f_info) -> api_error override; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto | ||||
|   fsetattr_x_impl(std::string api_path, struct setattr_x *attr, | ||||
|                   struct fuse_file_info *f_info) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fsync_impl(std::string api_path, int datasync, | ||||
|              struct fuse_file_info *f_info) -> api_error override; | ||||
|  | ||||
| #if FUSE_USE_VERSION < 30 | ||||
|   [[nodiscard]] auto | ||||
|   ftruncate_impl(std::string api_path, off_t size, | ||||
|                  struct fuse_file_info *f_info) -> api_error override; | ||||
| #endif | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   getattr_impl(std::string api_path, struct stat *unix_st, | ||||
|                struct fuse_file_info *f_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto getattr_impl(std::string api_path, | ||||
|                                   struct stat *unix_st) -> api_error override; | ||||
| #endif | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto | ||||
|   getxtimes_impl(std::string api_path, struct timespec *bkuptime, | ||||
|                  struct timespec *crtime) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   auto init_impl(struct fuse_conn_info *conn, | ||||
|                  struct fuse_config *cfg) -> void * override; | ||||
| #else | ||||
|   auto init_impl(struct fuse_conn_info *conn) -> void * override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto mkdir_impl(std::string api_path, | ||||
|                                 mode_t mode) -> api_error override; | ||||
|  | ||||
|   void notify_fuse_main_exit(int &ret) override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   open_impl(std::string api_path, | ||||
|             struct fuse_file_info *f_info) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   opendir_impl(std::string api_path, | ||||
|                struct fuse_file_info *f_info) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto read_impl(std::string api_path, char *buffer, | ||||
|                                size_t read_size, off_t read_offset, | ||||
|                                struct fuse_file_info *f_info, | ||||
|                                std::size_t &bytes_read) -> api_error override; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir, | ||||
|                off_t offset, struct fuse_file_info *f_info, | ||||
|                fuse_readdir_flags flags) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto | ||||
|   readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir, | ||||
|                off_t offset, | ||||
|                struct fuse_file_info *f_info) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   release_impl(std::string api_path, | ||||
|                struct fuse_file_info *f_info) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   releasedir_impl(std::string api_path, | ||||
|                   struct fuse_file_info *f_info) -> api_error override; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto rename_impl(std::string from_api_path, | ||||
|                                  std::string to_api_path, | ||||
|                                  unsigned int flags) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto rename_impl(std::string from_api_path, | ||||
|                                  std::string to_api_path) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto rmdir_impl(std::string api_path) -> api_error override; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   [[nodiscard]] auto | ||||
|   setattr_x_impl(std::string api_path, | ||||
|                  struct setattr_x *attr) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   setbkuptime_impl(std::string api_path, | ||||
|                    const struct timespec *bkuptime) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   setchgtime_impl(std::string api_path, | ||||
|                   const struct timespec *chgtime) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   setcrtime_impl(std::string api_path, | ||||
|                  const struct timespec *crtime) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   setvolname_impl(const char *volname) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto statfs_x_impl(std::string api_path, | ||||
|                                    struct statfs *stbuf) -> api_error override; | ||||
|  | ||||
| #else  // __APPLE__ | ||||
|   [[nodiscard]] auto statfs_impl(std::string api_path, | ||||
|                                  struct statvfs *stbuf) -> api_error override; | ||||
| #endif // __APPLE__ | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   truncate_impl(std::string api_path, off_t size, | ||||
|                 struct fuse_file_info *f_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto truncate_impl(std::string api_path, | ||||
|                                    off_t size) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto unlink_impl(std::string api_path) -> api_error override; | ||||
|  | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
|   [[nodiscard]] auto | ||||
|   utimens_impl(std::string api_path, const struct timespec tv[2], | ||||
|                struct fuse_file_info *f_info) -> api_error override; | ||||
| #else | ||||
|   [[nodiscard]] auto | ||||
|   utimens_impl(std::string api_path, | ||||
|                const struct timespec tv[2]) -> api_error override; | ||||
| #endif | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   write_impl(std::string api_path, const char *buffer, size_t write_size, | ||||
|              off_t write_offset, struct fuse_file_info *f_info, | ||||
|              std::size_t &bytes_written) -> api_error override; | ||||
| }; | ||||
| } // namespace remote_fuse | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE_HPP_ | ||||
| @@ -0,0 +1,338 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_SERVER_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_SERVER_HPP_ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #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_; | ||||
|   std::atomic<std::uint64_t> next_handle_{0U}; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto construct_path(std::string path) -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto construct_path(const std::wstring &path) -> std::string; | ||||
|  | ||||
|   [[nodiscard]] static auto empty_as_zero(const json &data) -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_next_handle() -> std::uint64_t; | ||||
|  | ||||
|   [[nodiscard]] auto populate_file_info(const std::string &api_path, | ||||
|                                         remote::file_info &file_info) | ||||
|       -> packet::error_type; | ||||
|  | ||||
|   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 stat64 &unix_st, remote::stat &r_stat); | ||||
|  | ||||
|   [[nodiscard]] auto update_to_windows_format(json &item) -> json &; | ||||
|  | ||||
| public: | ||||
|   // FUSE Layer | ||||
|   [[nodiscard]] auto fuse_access(const char *path, const std::int32_t &mask) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_chmod(const char *path, const remote::file_mode &mode) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_chown(const char *path, const remote::user_id &uid, | ||||
|                                 const remote::group_id &gid) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_create(const char *path, const remote::file_mode &mode, | ||||
|               const remote::open_flags &flags, remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_destroy() -> packet::error_type override; | ||||
|  | ||||
|   /*[[nodiscard]] 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 | ||||
|      ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto fuse_fgetattr(const char *path, remote::stat &r_stat, | ||||
|                                    bool &directory, | ||||
|                                    const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_fsetattr_x(const char *path, | ||||
|                                      const remote::setattr_x &attr, | ||||
|                                      const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_fsync(const char *path, const std::int32_t &datasync, | ||||
|                                 const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_ftruncate(const char *path, | ||||
|                                     const remote::file_offset &size, | ||||
|                                     const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_getattr(const char *path, remote::stat &r_stat, | ||||
|                                   bool &directory) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   /*[[nodiscard]] packet::error_type fuse_getxattr(const char *path, const char | ||||
|   *name, char *value, const remote::file_size &size) override ; | ||||
|  | ||||
|   [[nodiscard]] packet::error_type fuse_getxattrOSX(const char *path, const char | ||||
|   *name, char *value, const remote::file_size &size, std::uint32_t position) | ||||
|   override ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto fuse_getxtimes(const char *path, | ||||
|                                     remote::file_time &bkuptime, | ||||
|                                     remote::file_time &crtime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_init() -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] /*packet::error_type fuse_listxattr(const char *path, char | ||||
|                  *buffer, const remote::file_size &size) override ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_mkdir(const char *path, const remote::file_mode &mode) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_open(const char *path, | ||||
|                                const remote::open_flags &flags, | ||||
|                                remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_opendir(const char *path, remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_read(const char *path, char *buffer, | ||||
|                                const remote::file_size &read_size, | ||||
|                                const remote::file_offset &read_offset, | ||||
|                                const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_rename(const char *from, const char *to) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   fuse_readdir(const char *path, const remote::file_offset &offset, | ||||
|                const remote::file_handle &handle, std::string &item_path) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_release(const char *path, | ||||
|                                   const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_releasedir(const char *path, | ||||
|                                      const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   /*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const | ||||
|    * char *name) override | ||||
|    * ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto fuse_rmdir(const char *path) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_setattr_x(const char *path, remote::setattr_x &attr) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_setbkuptime(const char *path, | ||||
|                                       const remote::file_time &bkuptime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_setchgtime(const char *path, | ||||
|                                      const remote::file_time &chgtime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_setcrtime(const char *path, | ||||
|                                     const remote::file_time &crtime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_setvolname(const char *volname) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   /*[[nodiscard]] 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 ; | ||||
|  | ||||
|   [[nodiscard]] 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, std::uint32_t position) override ;*/ | ||||
|  | ||||
|   [[nodiscard]] auto fuse_statfs(const char *path, std::uint64_t frsize, | ||||
|                                  remote::statfs &r_stat) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_statfs_x(const char *path, std::uint64_t bsize, | ||||
|                                    remote::statfs_x &r_stat) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_truncate(const char *path, | ||||
|                                    const remote::file_offset &size) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_unlink(const char *path) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto fuse_utimens(const char *path, const remote::file_time *tv, | ||||
|                                   std::uint64_t op0, std::uint64_t op1) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto 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) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto 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) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   void set_fuse_uid_gid(const remote::user_id &, | ||||
|                         const remote::group_id &) override {} | ||||
|  | ||||
|   // JSON Layer | ||||
|   [[nodiscard]] auto winfsp_get_dir_buffer(PVOID /*file_desc*/, | ||||
|                                            PVOID *& /*ptr*/) | ||||
|       -> packet::error_type override { | ||||
|     return static_cast<packet::error_type>(STATUS_INVALID_HANDLE); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto json_create_directory_snapshot(const std::string &path, | ||||
|                                                     json &json_data) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto json_read_directory_snapshot( | ||||
|       const std::string &path, const remote::file_handle &handle, | ||||
|       std::uint32_t page, json &json_data) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   json_release_directory_snapshot(const std::string &path, | ||||
|                                   const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   // WinFSP Layer | ||||
|   [[nodiscard]] auto winfsp_can_delete(PVOID file_desc, PWSTR file_name) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_cleanup(PVOID file_desc, PWSTR file_name, | ||||
|                                     UINT32 flags, BOOLEAN &was_deleted) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_close(PVOID file_desc) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   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) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_flush(PVOID file_desc, remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_get_file_info(PVOID file_desc, | ||||
|                                           remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes, | ||||
|                               std::uint64_t * /*security_descriptor_size*/, | ||||
|                               std::wstring & /*str_descriptor*/) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_get_volume_info(UINT64 &total_size, | ||||
|                                             UINT64 &free_size, | ||||
|                                             std::string &volume_label) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_mounted(const std::wstring &location) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_open(PWSTR file_name, UINT32 create_options, | ||||
|                                  UINT32 granted_access, PVOID *file_desc, | ||||
|                                  remote::file_info *file_info, | ||||
|                                  std::string &normalized_name) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_overwrite(PVOID file_desc, UINT32 attributes, | ||||
|                                       BOOLEAN replace_attributes, | ||||
|                                       UINT64 /*allocation_size*/, | ||||
|                                       remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, | ||||
|                                  UINT32 length, PUINT32 bytes_transferred) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_read_directory(PVOID file_desc, PWSTR /*pattern*/, | ||||
|                                            PWSTR marker, json &itemList) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_rename(PVOID /*file_desc*/, PWSTR file_name, | ||||
|                                    PWSTR new_file_name, | ||||
|                                    BOOLEAN replace_if_exists) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_set_basic_info( | ||||
|       PVOID file_desc, UINT32 attributes, UINT64 creation_time, | ||||
|       UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time, | ||||
|       remote::file_info *file_info) -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_set_file_size(PVOID file_desc, UINT64 new_size, | ||||
|                                           BOOLEAN set_allocation_size, | ||||
|                                           remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto winfsp_unmounted(const std::wstring &location) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   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) | ||||
|       -> packet::error_type override; | ||||
| }; | ||||
| } // namespace remote_fuse | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_SERVER_HPP_ | ||||
| @@ -0,0 +1,46 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_REMOTE_I_REMOTE_JSON_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_REMOTE_I_REMOTE_JSON_HPP_ | ||||
|  | ||||
| #include "comm/packet/packet.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_remote_json { | ||||
|   INTERFACE_SETUP(i_remote_json); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] virtual auto | ||||
|   json_create_directory_snapshot(const std::string &path, | ||||
|                                  json &json_data) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto json_read_directory_snapshot( | ||||
|       const std::string &path, const remote::file_handle &handle, | ||||
|       std::uint32_t page, json &json_data) -> packet::error_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto json_release_directory_snapshot( | ||||
|       const std::string &path, | ||||
|       const remote::file_handle &handle) -> packet::error_type = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_REMOTE_I_REMOTE_JSON_HPP_ | ||||
| @@ -0,0 +1,121 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_REMOTE_REMOTE_OPEN_FILE_TABLE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_REMOTE_REMOTE_OPEN_FILE_TABLE_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 final { | ||||
|     std::string client_id; | ||||
|     std::vector<remote::file_handle> handles; | ||||
|     std::string path; | ||||
|   }; | ||||
|  | ||||
|   struct open_info final { | ||||
|     std::string client_id; | ||||
|     PVOID directory_buffer{nullptr}; | ||||
|     std::vector<native_handle> handles; | ||||
|     std::string path; | ||||
|   }; | ||||
|  | ||||
| private: | ||||
|   std::unordered_map<std::string, std::unique_ptr<compat_open_info>> | ||||
|       compat_file_lookup_; | ||||
|   std::unordered_map<remote::file_handle, std::string> compat_handle_lookup_; | ||||
|  | ||||
| private: | ||||
|   std::unordered_map<std::string, std::vector<std::uint64_t>> directory_lookup_; | ||||
|  | ||||
| private: | ||||
|   std::unordered_map<std::string, std::unique_ptr<open_info>> file_lookup_; | ||||
|   std::unordered_map<native_handle, std::string> handle_lookup_; | ||||
|  | ||||
| private: | ||||
|   mutable std::recursive_mutex file_mutex_; | ||||
|  | ||||
| protected: | ||||
|   void add_directory(const std::string &client_id, std::uint64_t handle); | ||||
|  | ||||
|   void close_all(const std::string &client_id); | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   [[nodiscard]] auto get_directory_buffer(const native_handle &handle, | ||||
|                                           PVOID *&buffer) -> bool; | ||||
| #endif // _WIN32 | ||||
|  | ||||
|   [[nodiscard]] auto get_open_file_path(const native_handle &handle) | ||||
|       -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_open_info(const native_handle &handle, open_info &oi) | ||||
|       -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto has_open_directory(const std::string &client_id, | ||||
|                                         std::uint64_t handle) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto has_compat_open_info(const remote::file_handle &handle, | ||||
|                                           int error_return) -> int; | ||||
|  | ||||
|   template <typename error_type> | ||||
|   [[nodiscard]] auto has_open_info(const native_handle &handle, | ||||
|                                    const error_type &error_return) | ||||
|       -> error_type { | ||||
|     recur_mutex_lock file_lock(file_mutex_); | ||||
|     return handle_lookup_.contains(handle) ? 0 : error_return; | ||||
|   } | ||||
|  | ||||
|   void remove_all(const std::string &file_path); | ||||
|  | ||||
|   void remove_and_close_all(const native_handle &handle); | ||||
|  | ||||
|   void remove_compat_open_info(const remote::file_handle &handle); | ||||
|  | ||||
|   auto remove_directory(const std::string &client_id, std::uint64_t handle) | ||||
|       -> bool; | ||||
|  | ||||
|   void remove_open_info(const native_handle &handle); | ||||
|  | ||||
|   void set_client_id(const native_handle &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, | ||||
|                             const std::string &file_path); | ||||
|  | ||||
|   void set_open_info(const native_handle &handle, open_info op_info); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto get_open_file_count(const std::string &file_path) const | ||||
|       -> std::size_t; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_REMOTE_REMOTE_OPEN_FILE_TABLE_HPP_ | ||||
							
								
								
									
										1436
									
								
								repertory/librepertory/include/drives/remote/remote_server_base.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1436
									
								
								repertory/librepertory/include/drives/remote/remote_server_base.hpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,75 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_WINFSP_I_WINFSP_DRIVE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_WINFSP_I_WINFSP_DRIVE_HPP_ | ||||
| #if defined(_WIN32) | ||||
|  | ||||
| #include "types/remote.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_winfsp_drive { | ||||
|   INTERFACE_SETUP(i_winfsp_drive); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_directory_item_count(const std::string &api_path) const | ||||
|       -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_directory_items(const std::string &api_path) const | ||||
|       -> directory_item_list = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_file_size(const std::string &api_path) const | ||||
|       -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_item_meta(const std::string &api_path, | ||||
|                                            const std::string &name, | ||||
|                                            std::string &value) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_item_meta(const std::string &api_path, | ||||
|                                            api_meta_map &meta) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_security_by_name(PWSTR file_name, PUINT32 attributes, | ||||
|                        PSECURITY_DESCRIPTOR descriptor, | ||||
|                        std::uint64_t *descriptor_size) -> NTSTATUS = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_total_drive_space() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_total_item_count() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_used_drive_space() const -> std::uint64_t = 0; | ||||
|  | ||||
|   virtual void get_volume_info(UINT64 &total_size, UINT64 &free_size, | ||||
|                                std::string &volume_label) const = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto populate_file_info(const std::string &api_path, | ||||
|                                                 remote::file_info &fi) const | ||||
|       -> api_error = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_WINFSP_I_WINFSP_DRIVE_HPP_ | ||||
| @@ -0,0 +1,120 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_I_REMOTE_INSTANCE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_I_REMOTE_INSTANCE_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 auto winfsp_can_delete(PVOID file_desc, PWSTR file_name) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags, | ||||
|                               BOOLEAN &was_deleted) -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_close(PVOID file_desc) -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_create(PWSTR file_name, UINT32 create_options, | ||||
|                              UINT32 granted_access, UINT32 file_attributes, | ||||
|                              UINT64 allocation_size, PVOID *file_desc, | ||||
|                              remote::file_info *file_info, | ||||
|                              std::string &normalized_name, BOOLEAN &exists) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_flush(PVOID file_desc, remote::file_info *file_info) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_get_file_info(PVOID file_desc, | ||||
|                                     remote::file_info *file_info) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto | ||||
|   winfsp_get_security_by_name(PWSTR file_name, PUINT32 file_attributes, | ||||
|                               std::uint64_t *security_descriptor_size, | ||||
|                               std::wstring &str_descriptor) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size, | ||||
|                                       std::string &volume_label) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_mounted(const std::wstring &location) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_open(PWSTR file_name, UINT32 create_options, | ||||
|                            UINT32 granted_access, PVOID *file_desc, | ||||
|                            remote::file_info *file_info, | ||||
|                            std::string &normalized_name) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_overwrite(PVOID file_desc, UINT32 file_attributes, | ||||
|                                 BOOLEAN replace_file_attributes, | ||||
|                                 UINT64 allocation_size, | ||||
|                                 remote::file_info *file_info) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, | ||||
|                            UINT32 length, PUINT32 bytes_transferred) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_read_directory(PVOID file_desc, PWSTR pattern, | ||||
|                                      PWSTR marker, json &itemList) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_rename(PVOID file_desc, PWSTR file_name, | ||||
|                              PWSTR new_file_name, BOOLEAN replace_if_exists) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_set_basic_info(PVOID file_desc, UINT32 file_attributes, | ||||
|                                      UINT64 creation_time, | ||||
|                                      UINT64 last_access_time, | ||||
|                                      UINT64 last_write_time, UINT64 change_time, | ||||
|                                      remote::file_info *file_info) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_set_file_size(PVOID file_desc, UINT64 new_size, | ||||
|                                     BOOLEAN set_allocation_size, | ||||
|                                     remote::file_info *file_info) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto winfsp_unmounted(const std::wstring &location) | ||||
|       -> packet::error_type = 0; | ||||
|  | ||||
|   virtual auto 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) | ||||
|       -> packet::error_type = 0; | ||||
| }; | ||||
|  | ||||
| using remote_instance_factory = | ||||
|     std::function<std::unique_ptr<i_remote_instance>()>; | ||||
| } // namespace repertory::remote_winfsp | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_I_REMOTE_INSTANCE_HPP_ | ||||
| @@ -0,0 +1,138 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_CLIENT_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_CLIENT_HPP_ | ||||
|  | ||||
| #include "comm/packet/packet.hpp" | ||||
| #include "comm/packet/packet_client.hpp" | ||||
| #include "drives/remote/remote_open_file_table.hpp" | ||||
| #include "drives/winfsp/remotewinfsp/i_remote_instance.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: | ||||
| #if defined(_WIN32) | ||||
| #define to_handle(x) (x) | ||||
| #else  // !defined(_WIN32) | ||||
|   static auto to_handle(PVOID file_desc) -> native_handle; | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
| public: | ||||
|   auto json_create_directory_snapshot(const std::string &path, json &json_data) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto json_read_directory_snapshot(const std::string &path, | ||||
|                                     const remote::file_handle &handle, | ||||
|                                     std::uint32_t page, json &json_data) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto json_release_directory_snapshot(const std::string &path, | ||||
|                                        const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_can_delete(PVOID file_desc, PWSTR file_name) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags, | ||||
|                       BOOLEAN &was_deleted) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_close(PVOID file_desc) -> packet::error_type override; | ||||
|  | ||||
|   auto 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) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_flush(PVOID file_desc, remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes, | ||||
|                                    std::uint64_t *descriptor_size, | ||||
|                                    std::wstring &string_descriptor) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size, | ||||
|                               std::string &volume_label) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_mounted(const std::wstring &location) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_open(PWSTR file_name, UINT32 create_options, | ||||
|                    UINT32 granted_access, PVOID *file_desc, | ||||
|                    remote::file_info *file_info, std::string &normalized_name) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_overwrite(PVOID file_desc, UINT32 attributes, | ||||
|                         BOOLEAN replace_attributes, UINT64 allocation_size, | ||||
|                         remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length, | ||||
|                    PUINT32 bytes_transferred) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_read_directory(PVOID file_desc, PWSTR pattern, PWSTR marker, | ||||
|                              json &itemList) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_rename(PVOID file_desc, PWSTR file_name, PWSTR new_file_name, | ||||
|                      BOOLEAN replace_if_exists) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_set_basic_info(PVOID file_desc, UINT32 attributes, | ||||
|                              UINT64 creation_time, UINT64 last_access_time, | ||||
|                              UINT64 last_write_time, UINT64 change_time, | ||||
|                              remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_set_file_size(PVOID file_desc, UINT64 new_size, | ||||
|                             BOOLEAN set_allocation_size, | ||||
|                             remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_unmounted(const std::wstring &location) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto 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) | ||||
|       -> packet::error_type override; | ||||
| }; | ||||
| } // namespace remote_winfsp | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_CLIENT_HPP_ | ||||
| @@ -0,0 +1,293 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| // 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 REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_SERVER_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_SERVER_HPP_ | ||||
| #if defined(_WIN32) | ||||
|  | ||||
| #include "comm/packet/packet.hpp" | ||||
| #include "drives/directory_cache.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, | ||||
|                            utils::string::to_lower(mount_location)) {} | ||||
|  | ||||
| private: | ||||
|   directory_cache directory_cache_; | ||||
|   std::atomic<std::uint64_t> next_handle_{0U}; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto construct_path(std::string path) -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_next_handle() -> std::uint64_t; | ||||
|  | ||||
|   [[nodiscard]] auto populate_file_info(const std::string &api_path, | ||||
|                                         remote::file_info &file_info) | ||||
|       -> packet::error_type; | ||||
|  | ||||
|   void populate_stat(const char *path, bool directory, remote::stat &r_stat, | ||||
|                      const struct _stat64 &unix_st); | ||||
|  | ||||
| public: | ||||
|   // FUSE Layer | ||||
|   auto fuse_access(const char *path, const std::int32_t &mask) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_chflags(const char *path, std::uint32_t flags) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_chmod(const char *path, const remote::file_mode &mode) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_chown(const char *path, const remote::user_id &uid, | ||||
|                   const remote::group_id &gid) -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_destroy() -> packet::error_type 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 ;*/ | ||||
|  | ||||
|   auto fuse_fgetattr(const char *path, remote::stat &r_stat, bool &directory, | ||||
|                      const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_fsetattr_x(const char *path, const remote::setattr_x &attr, | ||||
|                        const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_fsync(const char *path, const std::int32_t &datasync, | ||||
|                   const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_ftruncate(const char *path, const remote::file_offset &size, | ||||
|                       const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_getattr(const char *path, remote::stat &r_stat, bool &directory) | ||||
|       -> packet::error_type 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, std::uint32_t position) override ;*/ | ||||
|  | ||||
|   auto fuse_getxtimes(const char *path, remote::file_time &bkuptime, | ||||
|                       remote::file_time &crtime) -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_init() -> packet::error_type override; | ||||
|  | ||||
|   /*packet::error_type fuse_listxattr(const char *path, char *buffer, | ||||
|                                          const remote::file_size &size) override | ||||
|      ;*/ | ||||
|  | ||||
|   auto fuse_mkdir(const char *path, const remote::file_mode &mode) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_opendir(const char *path, remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_create(const char *path, const remote::file_mode &mode, | ||||
|                    const remote::open_flags &flags, remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_open(const char *path, const remote::open_flags &flags, | ||||
|                  remote::file_handle &handle) -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_read(const char *path, char *buffer, | ||||
|                  const remote::file_size &read_size, | ||||
|                  const remote::file_offset &read_offset, | ||||
|                  const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_rename(const char *from, const char *to) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto 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) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto 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) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_readdir(const char *path, const remote::file_offset &offset, | ||||
|                     const remote::file_handle &handle, std::string &item_path) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_release(const char *path, const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_releasedir(const char *path, const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   /*packet::error_type fuse_removexattr(const char *path, const char *name) | ||||
|    * override ;*/ | ||||
|  | ||||
|   auto fuse_rmdir(const char *path) -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_setattr_x(const char *path, remote::setattr_x &attr) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_setbkuptime(const char *path, const remote::file_time &bkuptime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_setchgtime(const char *path, const remote::file_time &chgtime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_setcrtime(const char *path, const remote::file_time &crtime) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_setvolname(const char *volname) -> packet::error_type 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, | ||||
|                                            std::uint32_t position) override ;*/ | ||||
|  | ||||
|   auto fuse_statfs(const char *path, std::uint64_t frsize, | ||||
|                    remote::statfs &r_stat) -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_statfs_x(const char *path, std::uint64_t bsize, | ||||
|                      remote::statfs_x &r_stat) -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_truncate(const char *path, const remote::file_offset &size) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_unlink(const char *path) -> packet::error_type override; | ||||
|  | ||||
|   auto fuse_utimens(const char *path, const remote::file_time *tv, | ||||
|                     std::uint64_t op0, std::uint64_t op1) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   void set_fuse_uid_gid(const remote::user_id & /* uid */, | ||||
|                         const remote::group_id & /* gid */) override {} | ||||
|  | ||||
|   // JSON Layer | ||||
|   auto json_create_directory_snapshot(const std::string &path, json &json_data) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto json_read_directory_snapshot(const std::string &path, | ||||
|                                     const remote::file_handle &handle, | ||||
|                                     std::uint32_t page, json &json_data) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto json_release_directory_snapshot(const std::string &path, | ||||
|                                        const remote::file_handle &handle) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   // WinFSP Layer | ||||
|   auto winfsp_can_delete(PVOID file_desc, PWSTR file_name) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags, | ||||
|                       BOOLEAN &was_deleted) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_close(PVOID file_desc) -> packet::error_type override; | ||||
|  | ||||
|   auto 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) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_flush(PVOID file_desc, remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes, | ||||
|                                    std::uint64_t *descriptor_size, | ||||
|                                    std::wstring &string_descriptor) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size, | ||||
|                               std::string &volume_label) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_mounted(const std::wstring &location) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_open(PWSTR file_name, UINT32 create_options, | ||||
|                    UINT32 granted_access, PVOID *file_desc, | ||||
|                    remote::file_info *file_info, std::string &normalized_name) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_overwrite(PVOID file_desc, UINT32 attributes, | ||||
|                         BOOLEAN replace_attributes, UINT64 allocation_size, | ||||
|                         remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length, | ||||
|                    PUINT32 bytes_transferred) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_read_directory(PVOID file_desc, PWSTR pattern, PWSTR marker, | ||||
|                              json &item_list) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_rename(PVOID file_desc, PWSTR file_name, PWSTR new_file_name, | ||||
|                      BOOLEAN replace_if_exists) -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_set_basic_info(PVOID file_desc, UINT32 attributes, | ||||
|                              UINT64 creation_time, UINT64 last_access_time, | ||||
|                              UINT64 last_write_time, UINT64 change_time, | ||||
|                              remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_set_file_size(PVOID file_desc, UINT64 new_size, | ||||
|                             BOOLEAN set_allocation_size, | ||||
|                             remote::file_info *file_info) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto winfsp_unmounted(const std::wstring &location) | ||||
|       -> packet::error_type override; | ||||
|  | ||||
|   auto 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) | ||||
|       -> packet::error_type override; | ||||
| }; | ||||
| } // namespace remote_winfsp | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_SERVER_HPP_ | ||||
| @@ -0,0 +1,155 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_WINFSP_DRIVE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_WINFSP_DRIVE_HPP_ | ||||
| #if defined(_WIN32) | ||||
|  | ||||
| #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, remote_instance_factory factory, | ||||
|                       lock_data &lock); | ||||
|  | ||||
|   ~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_; | ||||
|     remote_winfsp_drive &drive_; | ||||
|     const std::vector<std::string> drive_args_; | ||||
|     FileSystemHost host_; | ||||
|     lock_data &lock_; | ||||
|  | ||||
|   protected: | ||||
|     auto OnStart(ULONG, PWSTR *) -> NTSTATUS override; | ||||
|  | ||||
|     auto OnStop() -> NTSTATUS 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 populate_file_info(const json &item, FSP_FSCTL_FILE_INFO &file_info); | ||||
|  | ||||
|   static void set_file_info(FileInfo &dest, const remote::file_info &src); | ||||
|  | ||||
| public: | ||||
|   auto CanDelete(PVOID file_node, PVOID file_desc, PWSTR file_name) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   VOID Cleanup(PVOID file_node, PVOID file_desc, PWSTR file_name, | ||||
|                ULONG flags) override; | ||||
|  | ||||
|   VOID Close(PVOID file_node, PVOID file_desc) override; | ||||
|  | ||||
|   auto 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) -> NTSTATUS override; | ||||
|  | ||||
|   auto Flush(PVOID file_node, PVOID file_desc, FileInfo *file_info) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   auto GetFileInfo(PVOID file_node, PVOID file_desc, FileInfo *file_info) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   auto GetSecurityByName(PWSTR file_name, PUINT32 attributes, | ||||
|                          PSECURITY_DESCRIPTOR descriptor, | ||||
|                          SIZE_T *descriptor_size) -> NTSTATUS override; | ||||
|  | ||||
|   auto GetVolumeInfo(VolumeInfo *volume_info) -> NTSTATUS override; | ||||
|  | ||||
|   auto Init(PVOID host) -> NTSTATUS override; | ||||
|  | ||||
|   [[nodiscard]] auto mount(const std::vector<std::string> &drive_args) -> int; | ||||
|  | ||||
|   auto Mounted(PVOID host) -> NTSTATUS override; | ||||
|  | ||||
|   auto Open(PWSTR file_name, UINT32 create_options, UINT32 granted_access, | ||||
|             PVOID *file_node, PVOID *file_desc, OpenFileInfo *ofi) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   auto Overwrite(PVOID file_node, PVOID file_desc, UINT32 attributes, | ||||
|                  BOOLEAN replace_attributes, UINT64 allocation_size, | ||||
|                  FileInfo *file_info) -> NTSTATUS override; | ||||
|  | ||||
|   auto Read(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, | ||||
|             ULONG length, PULONG bytes_transferred) -> NTSTATUS override; | ||||
|  | ||||
|   auto ReadDirectory(PVOID file_node, PVOID file_desc, PWSTR pattern, | ||||
|                      PWSTR marker, PVOID buffer, ULONG buffer_length, | ||||
|                      PULONG bytes_transferred) -> NTSTATUS override; | ||||
|  | ||||
|   auto Rename(PVOID file_node, PVOID file_desc, PWSTR file_name, | ||||
|               PWSTR new_file_name, BOOLEAN replace_if_exists) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   auto 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) -> NTSTATUS override; | ||||
|  | ||||
|   auto SetFileSize(PVOID file_node, PVOID file_desc, UINT64 new_size, | ||||
|                    BOOLEAN set_allocation_size, FileInfo *file_info) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   VOID Unmounted(PVOID host) override; | ||||
|  | ||||
|   auto 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) | ||||
|       -> NTSTATUS 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 // REPERTORY_INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_WINFSP_DRIVE_HPP_ | ||||
							
								
								
									
										210
									
								
								repertory/librepertory/include/drives/winfsp/winfsp_drive.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								repertory/librepertory/include/drives/winfsp/winfsp_drive.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_DRIVES_WINFSP_WINFSP_DRIVE_HPP_ | ||||
| #define REPERTORY_INCLUDE_DRIVES_WINFSP_WINFSP_DRIVE_HPP_ | ||||
| #if defined(_WIN32) | ||||
|  | ||||
| #include "drives/eviction.hpp" | ||||
| #include "drives/winfsp/i_winfsp_drive.hpp" | ||||
| #include "drives/winfsp/remotewinfsp/remote_server.hpp" | ||||
| #include "events/event_system.hpp" | ||||
| #include "file_manager/file_manager.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: | ||||
|     app_config &config_; | ||||
|     winfsp_drive &drive_; | ||||
|     std::vector<std::string> drive_args_; | ||||
|     FileSystemHost host_; | ||||
|     lock_data &lock_; | ||||
|  | ||||
|   protected: | ||||
|     auto OnStart(ULONG, PWSTR *) -> NTSTATUS override; | ||||
|  | ||||
|     auto OnStop() -> NTSTATUS override; | ||||
|   }; | ||||
|  | ||||
| private: | ||||
|   i_provider &provider_; | ||||
|   app_config &config_; | ||||
|   lock_data &lock_; | ||||
|   std::unique_ptr<full_server> server_; | ||||
|   std::unique_ptr<file_manager> fm_; | ||||
|   std::unique_ptr<eviction> eviction_; | ||||
|   std::unique_ptr<remote_winfsp::remote_server> remote_server_; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto handle_error(std::string_view function_name, | ||||
|                                   const std::string &api_path, api_error error, | ||||
|                                   FileInfo *file_info, std::uint64_t file_size, | ||||
|                                   bool raise_on_failure_only = false) const | ||||
|       -> NTSTATUS; | ||||
|  | ||||
|   static auto parse_mount_location(const std::wstring &mount_location) | ||||
|       -> std::string; | ||||
|  | ||||
|   void populate_file_info(const std::string &api_path, std::uint64_t file_size, | ||||
|                           const api_meta_map &meta, | ||||
|                           FSP_FSCTL_OPEN_FILE_INFO &ofi) const; | ||||
|  | ||||
|   void populate_file_info(std::uint64_t file_size, api_meta_map meta, | ||||
|                           FSP_FSCTL_FILE_INFO &fi) const; | ||||
|  | ||||
|   static void set_file_info(remote::file_info &dest, | ||||
|                             const FSP_FSCTL_FILE_INFO &src); | ||||
|  | ||||
| public: | ||||
|   auto CanDelete(PVOID file_node, PVOID file_desc, PWSTR file_name) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   VOID Cleanup(PVOID file_node, PVOID file_desc, PWSTR file_name, | ||||
|                ULONG flags) override; | ||||
|  | ||||
|   VOID Close(PVOID file_node, PVOID file_desc) override; | ||||
|  | ||||
|   auto 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) -> NTSTATUS override; | ||||
|  | ||||
|   auto Flush(PVOID file_node, PVOID file_desc, FileInfo *file_info) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const | ||||
|       -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_items(const std::string &api_path) const | ||||
|       -> directory_item_list override; | ||||
|  | ||||
|   auto GetFileInfo(PVOID file_node, PVOID file_desc, FileInfo *file_info) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_size(const std::string &api_path) const | ||||
|       -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    api_meta_map &meta) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    const std::string &name, | ||||
|                                    std::string &value) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_security_by_name(PWSTR file_name, PUINT32 attributes, | ||||
|                                           PSECURITY_DESCRIPTOR descriptor, | ||||
|                                           std::uint64_t *descriptor_size) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   auto GetSecurityByName(PWSTR file_name, PUINT32 attributes, | ||||
|                          PSECURITY_DESCRIPTOR descriptor, | ||||
|                          SIZE_T *descriptor_size) -> NTSTATUS override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override; | ||||
|  | ||||
|   void get_volume_info(UINT64 &total_size, UINT64 &free_size, | ||||
|                        std::string &volume_label) const override; | ||||
|  | ||||
|   auto GetVolumeInfo(VolumeInfo *volume_info) -> NTSTATUS override; | ||||
|  | ||||
|   auto Init(PVOID host) -> NTSTATUS override; | ||||
|  | ||||
|   [[nodiscard]] auto mount(const std::vector<std::string> &drive_args) -> int; | ||||
|  | ||||
|   auto Mounted(PVOID host) -> NTSTATUS override; | ||||
|  | ||||
|   auto Open(PWSTR file_name, UINT32 create_options, UINT32 granted_access, | ||||
|             PVOID *file_node, PVOID *file_desc, OpenFileInfo *ofi) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   auto Overwrite(PVOID file_node, PVOID file_desc, UINT32 attributes, | ||||
|                  BOOLEAN replace_attributes, UINT64 allocation_size, | ||||
|                  FileInfo *file_info) -> NTSTATUS override; | ||||
|  | ||||
|   [[nodiscard]] auto populate_file_info(const std::string &api_path, | ||||
|                                         remote::file_info &file_info) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   auto Read(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, | ||||
|             ULONG length, PULONG bytes_transferred) -> NTSTATUS override; | ||||
|  | ||||
|   auto ReadDirectory(PVOID file_node, PVOID file_desc, PWSTR pattern, | ||||
|                      PWSTR marker, PVOID buffer, ULONG bufferLength, | ||||
|                      PULONG bytes_transferred) -> NTSTATUS override; | ||||
|  | ||||
|   auto Rename(PVOID file_node, PVOID file_desc, PWSTR file_name, | ||||
|               PWSTR new_file_name, BOOLEAN replace_if_exists) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   auto 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) -> NTSTATUS override; | ||||
|  | ||||
|   auto SetFileSize(PVOID file_node, PVOID file_desc, UINT64 new_size, | ||||
|                    BOOLEAN set_allocation_size, FileInfo *file_info) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   VOID Unmounted(PVOID host) override; | ||||
|  | ||||
|   auto 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) | ||||
|       -> NTSTATUS override; | ||||
|  | ||||
|   void shutdown(); | ||||
|  | ||||
|   static void display_options(std::vector<const char *> /* args */) {} | ||||
|  | ||||
|   static void | ||||
|   display_version_information(std::vector<const char *> /* args */) {} | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_DRIVES_WINFSP_WINFSP_DRIVE_HPP_ | ||||
| @@ -0,0 +1,43 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_EVENTS_CONSUMERS_CONSOLE_CONSUMER_HPP_ | ||||
| #define REPERTORY_INCLUDE_EVENTS_CONSUMERS_CONSOLE_CONSUMER_HPP_ | ||||
|  | ||||
| #include "events/event_system.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class console_consumer final { | ||||
|   E_CONSUMER(); | ||||
|  | ||||
| public: | ||||
|   console_consumer(); | ||||
|  | ||||
|   explicit console_consumer(event_level level); | ||||
|  | ||||
|   ~console_consumer(); | ||||
|  | ||||
| private: | ||||
|   void process_event(const event &e) const; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_EVENTS_CONSUMERS_CONSOLE_CONSUMER_HPP_ | ||||
| @@ -0,0 +1,46 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_EVENTS_CONSUMERS_LOGGING_CONSUMER_HPP_ | ||||
| #define REPERTORY_INCLUDE_EVENTS_CONSUMERS_LOGGING_CONSUMER_HPP_ | ||||
|  | ||||
| #include "events/event_system.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class logging_consumer { | ||||
|   E_CONSUMER(); | ||||
|  | ||||
| public: | ||||
|   logging_consumer(event_level level, std::string log_directory); | ||||
|  | ||||
|   ~logging_consumer(); | ||||
|  | ||||
| private: | ||||
|   static constexpr const std::uint8_t MAX_LOG_FILES{5U}; | ||||
|   static constexpr const std::uint64_t MAX_LOG_FILE_SIZE{1024ULL * 1024ULL * | ||||
|                                                          5ULL}; | ||||
|  | ||||
| private: | ||||
|   void process_event(const event &event) const; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_EVENTS_CONSUMERS_LOGGING_CONSUMER_HPP_ | ||||
							
								
								
									
										92
									
								
								repertory/librepertory/include/events/event.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								repertory/librepertory/include/events/event.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_EVENTS_EVENT_HPP_ | ||||
| #define REPERTORY_INCLUDE_EVENTS_EVENT_HPP_ | ||||
|  | ||||
| namespace repertory { | ||||
| enum class event_level { | ||||
|   critical, | ||||
|   error, | ||||
|   warn, | ||||
|   info, | ||||
|   debug, | ||||
|   trace, | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| event_level_from_string(std::string level, | ||||
|                         event_level default_level = event_level::info) | ||||
|     -> event_level; | ||||
|  | ||||
| [[nodiscard]] auto event_level_to_string(event_level level) -> std::string; | ||||
|  | ||||
| class event { | ||||
| protected: | ||||
|   explicit event(bool allow_async) : allow_async_(allow_async) {} | ||||
|  | ||||
|   event(const std::stringstream &ss, json j, bool allow_async) | ||||
|       : allow_async_(allow_async), ss_(ss.str()), j_(std::move(j)) {} | ||||
|  | ||||
| public: | ||||
|   event(const event &) = delete; | ||||
|   event(event &&) = delete; | ||||
|   auto operator=(const event &) -> event & = delete; | ||||
|   auto operator=(event &&) -> event & = delete; | ||||
|   virtual ~event() = default; | ||||
|  | ||||
| private: | ||||
|   bool allow_async_; | ||||
|  | ||||
| protected: | ||||
|   std::stringstream ss_; | ||||
|   json j_; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] virtual auto clone() const -> std::shared_ptr<event> = 0; | ||||
|  | ||||
|   [[nodiscard]] auto get_allow_async() const -> bool { return allow_async_; } | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_event_level() const -> event_level = 0; | ||||
|  | ||||
|   [[nodiscard]] auto get_json() const -> json { return j_; } | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_name() const -> std::string = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_single_line() const -> std::string = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| NLOHMANN_JSON_NAMESPACE_BEGIN | ||||
| template <> struct adl_serializer<std::atomic<repertory::event_level>> { | ||||
|   static void to_json(json &data, | ||||
|                       const std::atomic<repertory::event_level> &value) { | ||||
|     data = repertory::event_level_to_string(value.load()); | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, | ||||
|                         std::atomic<repertory::event_level> &value) { | ||||
|     value.store(repertory::event_level_from_string(data.get<std::string>())); | ||||
|   } | ||||
| }; | ||||
| NLOHMANN_JSON_NAMESPACE_END | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_EVENTS_EVENT_HPP_ | ||||
							
								
								
									
										241
									
								
								repertory/librepertory/include/events/event_system.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								repertory/librepertory/include/events/event_system.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,241 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_EVENTS_EVENT_SYSTEM_HPP_ | ||||
| #define REPERTORY_INCLUDE_EVENTS_EVENT_SYSTEM_HPP_ | ||||
|  | ||||
| #include "events/event.hpp" | ||||
| #include "events/t_event_system.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| using event_system = t_event_system<event>; | ||||
| using event_consumer = event_system::event_consumer; | ||||
|  | ||||
| #define E_FROM_API_FILE_ERROR(e) api_error_to_string(e) | ||||
| #define E_FROM_BOOL(t) std::to_string(t) | ||||
| #define E_FROM_CURL_CODE(t) std::string(curl_easy_strerror(t)) | ||||
| #define E_FROM_DOUBLE(d) std::to_string(d) | ||||
| #define E_FROM_DOUBLE_PRECISE(dbl_val)                                         \ | ||||
|   ([](const double &d) -> std::string {                                        \ | ||||
|     std::stringstream ss;                                                      \ | ||||
|     ss << std::fixed << std::setprecision(2) << d;                             \ | ||||
|     return ss.str();                                                           \ | ||||
|   })(dbl_val) | ||||
| #define E_FROM_INT32(t) std::to_string(t) | ||||
| #define E_FROM_SIZE_T(t) std::to_string(t) | ||||
| #define E_FROM_STRING(t) t | ||||
| #define E_FROM_UINT16(t) std::to_string(t) | ||||
| #define E_FROM_UINT64(t) std::to_string(t) | ||||
| #define E_FROM_DOWNLOAD_TYPE(t) download_type_to_string(t) | ||||
|  | ||||
| #define E_PROP(type, name, short_name, ts)                                     \ | ||||
| private:                                                                       \ | ||||
|   void init_##short_name(const type &val) {                                    \ | ||||
|     auto ts_val = ts(val);                                                     \ | ||||
|     ss_ << "|" << #short_name << "|" << ts_val;                                \ | ||||
|     j_[#name] = ts_val;                                                        \ | ||||
|   }                                                                            \ | ||||
|                                                                                \ | ||||
| public:                                                                        \ | ||||
|   [[nodiscard]] auto get_##name() const->json { return j_[#name]; } | ||||
|  | ||||
| #define E_BEGIN(name, el)                                                      \ | ||||
|   class name final : public virtual event {                                    \ | ||||
|   private:                                                                     \ | ||||
|     name(const std::stringstream &ss, const json &j, bool allow_async)         \ | ||||
|         : event(ss, j, allow_async) {}                                         \ | ||||
|                                                                                \ | ||||
|   public:                                                                      \ | ||||
|     ~name() override = default;                                                \ | ||||
|                                                                                \ | ||||
|   public:                                                                      \ | ||||
|     static const event_level level = event_level::el;                          \ | ||||
|                                                                                \ | ||||
|   public:                                                                      \ | ||||
|     [[nodiscard]] auto get_name() const -> std::string override {              \ | ||||
|       return #name;                                                            \ | ||||
|     }                                                                          \ | ||||
|                                                                                \ | ||||
|     [[nodiscard]] auto get_event_level() const -> event_level override {       \ | ||||
|       return name::level;                                                      \ | ||||
|     }                                                                          \ | ||||
|                                                                                \ | ||||
|     [[nodiscard]] auto get_single_line() const -> std::string override {       \ | ||||
|       const auto s = ss_.str();                                                \ | ||||
|       return get_name() + (s.empty() ? "" : s);                                \ | ||||
|     }                                                                          \ | ||||
|                                                                                \ | ||||
|     [[nodiscard]] auto clone() const -> std::shared_ptr<event> 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 &evt) { callback(evt); })) | ||||
|  | ||||
| #define E_SUBSCRIBE_EXACT(name, callback)                                      \ | ||||
|   event_consumers_.emplace_back(std::make_shared<repertory::event_consumer>(   \ | ||||
|       #name, [this](const event &evt) {                                        \ | ||||
|         callback(dynamic_cast<const name &>(evt));                             \ | ||||
|       })) | ||||
|  | ||||
| #define E_SUBSCRIBE_ALL(callback)                                              \ | ||||
|   event_consumers_.emplace_back(std::make_shared<repertory::event_consumer>(   \ | ||||
|       [this](const event &evt) { callback(evt); })) | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_EVENTS_EVENT_SYSTEM_HPP_ | ||||
							
								
								
									
										295
									
								
								repertory/librepertory/include/events/events.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										295
									
								
								repertory/librepertory/include/events/events.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,295 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_EVENTS_EVENTS_HPP_ | ||||
| #define REPERTORY_INCLUDE_EVENTS_EVENTS_HPP_ | ||||
|  | ||||
| #include "events/event_system.hpp" | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/utils.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| // clang-format off | ||||
| E_SIMPLE2(curl_error, error, true, | ||||
|   std::string, url, url, E_FROM_STRING, | ||||
|   CURLcode, res, res, E_FROM_CURL_CODE  | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(debug_log, debug, true, | ||||
|   std::string, function, func, E_FROM_STRING, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, data, data, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(directory_removed, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(directory_removed_externally, warn, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(directory_remove_failed, error, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, error, err, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(drive_mount_failed, error, true, | ||||
|   std::string, location, loc, E_FROM_STRING, | ||||
|   std::string, result, res, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(drive_mounted, info, true, | ||||
|   std::string, location, loc, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(drive_mount_result, info, true, | ||||
|   std::string, result, res, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(drive_unmount_pending, info, true, | ||||
|   std::string, location, loc, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(drive_unmounted, info, true, | ||||
|   std::string, location, loc, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(event_level_changed, info, true, | ||||
|   std::string, new_event_level, level, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(failed_upload_queued, error, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(failed_upload_removed, warn, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(failed_upload_retry, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(file_get_failed, error, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, error, err, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(file_get_api_list_failed, error, true, | ||||
|   std::string, error, err, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(file_pinned, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(file_read_bytes_failed, error, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, error, err, E_FROM_STRING, | ||||
|   std::size_t, retry, retry, E_FROM_SIZE_T | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(file_removed, debug, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(file_removed_externally, warn, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(file_remove_failed, error, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, error, err, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(file_rename_failed, error, true, | ||||
|   std::string, from_api_path, FROM, E_FROM_STRING, | ||||
|   std::string, to_api_path, TO, E_FROM_STRING, | ||||
|   std::string, error, err, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(file_get_size_failed, error, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, error, err, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(filesystem_item_added, debug, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, parent, parent, E_FROM_STRING, | ||||
|   bool, directory, dir, E_FROM_BOOL | ||||
| ); | ||||
|  | ||||
| E_SIMPLE4(filesystem_item_closed, trace, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   bool, directory, dir, E_FROM_BOOL, | ||||
|   bool, changed, changed, E_FROM_BOOL | ||||
| ); | ||||
|  | ||||
| E_SIMPLE5(filesystem_item_handle_closed, trace, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::uint64_t, handle, handle, E_FROM_UINT64, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   bool, directory, dir, E_FROM_BOOL, | ||||
|   bool, changed, changed, E_FROM_BOOL | ||||
| ); | ||||
|  | ||||
| E_SIMPLE4(filesystem_item_handle_opened, trace, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::uint64_t, handle, handle, E_FROM_UINT64, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   bool, directory, dir, E_FROM_BOOL | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(filesystem_item_evicted, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(filesystem_item_opened, trace, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   bool, directory, dir, E_FROM_BOOL | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(file_unpinned, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE4(file_upload_completed, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   api_error, result, res, E_FROM_API_FILE_ERROR, | ||||
|   bool, cancelled, cancel, E_FROM_BOOL | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(file_upload_failed, error, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   std::string, error, err, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(file_upload_not_found, warn, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(file_upload_queued, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(file_upload_removed, debug, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(file_upload_retry, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   api_error, result, res, E_FROM_API_FILE_ERROR | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(file_upload_started, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(orphaned_file_deleted, warn, true, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(orphaned_file_detected, warn, true, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(orphaned_file_processing_failed, error, true, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   std::string, dest, dest, E_FROM_STRING, | ||||
|   std::string, result, res, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(orphaned_source_file_detected, info, true, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(orphaned_source_file_removed, info, true, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(polling_item_begin, debug, true, | ||||
|   std::string, item_name, item, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(polling_item_end, debug, true, | ||||
|   std::string, item_name, item, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(provider_offline, error, true, | ||||
|   std::string, host_name_or_ip, host, E_FROM_STRING, | ||||
|   std::uint16_t, port, port, E_FROM_UINT16 | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(provider_upload_begin, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(provider_upload_end, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   api_error, result, res, E_FROM_API_FILE_ERROR | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(repertory_exception, error, true, | ||||
|   std::string, function, func, E_FROM_STRING, | ||||
|   std::string, message, msg, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(rpc_server_exception, error, true, | ||||
|   std::string, exception, exception, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(service_shutdown_begin, debug, true, | ||||
|   std::string, service, svc, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(service_shutdown_end, debug, true, | ||||
|   std::string, service, svc, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(service_started, debug, true, | ||||
|   std::string, service, svc, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE(unmount_requested, info, true); | ||||
| #if !defined(_WIN32) | ||||
| E_SIMPLE2(unmount_result, info, true, | ||||
|   std::string, location, loc, E_FROM_STRING, | ||||
|   std::string, result, res, E_FROM_STRING | ||||
| ); | ||||
| #endif | ||||
| // clang-format on | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_EVENTS_EVENTS_HPP_ | ||||
							
								
								
									
										193
									
								
								repertory/librepertory/include/events/t_event_system.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								repertory/librepertory/include/events/t_event_system.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_ | ||||
| #define REPERTORY_INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_ | ||||
|  | ||||
| #include "events/event.hpp" | ||||
| #include "utils/collection.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; | ||||
|   auto operator=(const t_event_system &) -> t_event_system & = delete; | ||||
|   auto operator=(t_event_system &&) -> 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); } | ||||
|  | ||||
|   public: | ||||
|     event_consumer(const event_consumer &) = delete; | ||||
|     event_consumer(event_consumer &&) = delete; | ||||
|     auto operator=(const event_consumer &) -> event_consumer & = delete; | ||||
|     auto operator=(event_consumer &&) -> event_consumer & = delete; | ||||
|  | ||||
|   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 auto instance() -> t_event_system &; | ||||
|  | ||||
| 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_; | ||||
|   stop_type stop_requested_ = false; | ||||
|  | ||||
| private: | ||||
|   void process_events() { | ||||
|     std::vector<std::shared_ptr<event_type>> events; | ||||
|     { | ||||
|       unique_mutex_lock lock(event_mutex_); | ||||
|       if (not stop_requested_ && event_list_.empty()) { | ||||
|         event_notify_.wait_for(lock, 1s); | ||||
|       } | ||||
|  | ||||
|       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 lock(consumer_mutex_); | ||||
|       if (event_consumers_.find(name) != event_consumers_.end()) { | ||||
|         for (auto *consumer : event_consumers_[name]) { | ||||
|           if (event.get_allow_async()) { | ||||
|             futures.emplace_back( | ||||
|                 std::async(std::launch::async, [consumer, &event]() { | ||||
|                   consumer->notify_event(event); | ||||
|                 })); | ||||
|           } else { | ||||
|             consumer->notify_event(event); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       while (not futures.empty()) { | ||||
|         futures.front().get(); | ||||
|         futures.pop_front(); | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|     for (const auto &evt : events) { | ||||
|       notify_events("", *evt.get()); | ||||
|       notify_events(evt->get_name(), *evt.get()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void queue_event(std::shared_ptr<event_type> evt) { | ||||
|     mutex_lock lock(event_mutex_); | ||||
|     event_list_.push_back(std::move(evt)); | ||||
|     event_notify_.notify_all(); | ||||
|   } | ||||
|  | ||||
| public: | ||||
|   void attach(event_consumer *consumer) { | ||||
|     recur_mutex_lock lock(consumer_mutex_); | ||||
|     event_consumers_[""].push_back(consumer); | ||||
|   } | ||||
|  | ||||
|   void attach(const std::string &event_name, event_consumer *consumer) { | ||||
|     recur_mutex_lock lock(consumer_mutex_); | ||||
|     event_consumers_[event_name].push_back(consumer); | ||||
|   } | ||||
|  | ||||
|   template <typename event_t, typename... arg_t> void raise(arg_t &&...args) { | ||||
|     queue_event(std::make_shared<event_t>(std::forward<arg_t>(args)...)); | ||||
|   } | ||||
|  | ||||
|   void release(event_consumer *consumer) { | ||||
|     recur_mutex_lock lock(consumer_mutex_); | ||||
|     auto iter = std::find_if(event_consumers_.begin(), event_consumers_.end(), | ||||
|                              [&](const auto &item) -> bool { | ||||
|                                return utils::collection::includes(item.second, | ||||
|                                                                   consumer); | ||||
|                              }); | ||||
|  | ||||
|     if (iter != event_consumers_.end()) { | ||||
|       utils::collection::remove_element((*iter).second, consumer); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void start() { | ||||
|     mutex_lock lock(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 lock(run_mutex_); | ||||
|     if (event_thread_) { | ||||
|       stop_requested_ = true; | ||||
|       event_notify_.notify_all(); | ||||
|  | ||||
|       event_thread_->join(); | ||||
|       event_thread_.reset(); | ||||
|  | ||||
|       process_events(); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_ | ||||
| @@ -0,0 +1,67 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_CACHE_SIZE_MGR_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_CACHE_SIZE_MGR_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class cache_size_mgr final { | ||||
| public: | ||||
|   cache_size_mgr(const cache_size_mgr &) = delete; | ||||
|   cache_size_mgr(cache_size_mgr &&) = delete; | ||||
|   auto operator=(const cache_size_mgr &) -> cache_size_mgr & = delete; | ||||
|   auto operator=(cache_size_mgr &&) -> cache_size_mgr & = delete; | ||||
|  | ||||
| protected: | ||||
|   cache_size_mgr() = default; | ||||
|  | ||||
|   ~cache_size_mgr() { stop(); } | ||||
|  | ||||
| private: | ||||
|   static cache_size_mgr instance_; | ||||
|  | ||||
| private: | ||||
|   app_config *cfg_{nullptr}; | ||||
|   std::uint64_t cache_size_{0U}; | ||||
|   mutable std::mutex mtx_; | ||||
|   std::condition_variable notify_; | ||||
|   stop_type stop_requested_{false}; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto expand(std::uint64_t size) -> api_error; | ||||
|  | ||||
|   void initialize(app_config *cfg); | ||||
|  | ||||
|   [[nodiscard]] static auto instance() -> cache_size_mgr & { return instance_; } | ||||
|  | ||||
|   [[nodiscard]] auto shrink(std::uint64_t size) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto size() const -> std::uint64_t; | ||||
|  | ||||
|   void stop(); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_CACHE_SIZE_MGR_HPP_ | ||||
| @@ -0,0 +1,83 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_DIRECT_OPEN_FILE_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_DIRECT_OPEN_FILE_HPP_ | ||||
|  | ||||
| #include "file_manager/ring_buffer_base.hpp" | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_provider; | ||||
| class i_upload_manager; | ||||
|  | ||||
| class direct_open_file final : public ring_buffer_base { | ||||
| public: | ||||
|   direct_open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, | ||||
|                    filesystem_item fsi, i_provider &provider); | ||||
|  | ||||
|   ~direct_open_file() override; | ||||
|  | ||||
| public: | ||||
|   direct_open_file() = delete; | ||||
|   direct_open_file(const direct_open_file &) noexcept = delete; | ||||
|   direct_open_file(direct_open_file &&) noexcept = delete; | ||||
|   auto operator=(direct_open_file &&) noexcept -> direct_open_file & = delete; | ||||
|   auto | ||||
|   operator=(const direct_open_file &) noexcept -> direct_open_file & = delete; | ||||
|  | ||||
| private: | ||||
|   std::array<data_buffer, min_ring_size> ring_data_; | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto on_check_start() -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   on_chunk_downloaded(std::size_t /* chunk */, | ||||
|                       const data_buffer & /* buffer */) -> api_error override { | ||||
|     return api_error::success; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   on_read_chunk(std::size_t chunk, std::size_t read_size, | ||||
|                 std::uint64_t read_offset, data_buffer &data, | ||||
|                 std::size_t &bytes_read) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto use_buffer(std::size_t chunk, | ||||
|                                 std::function<api_error(data_buffer &)> func) | ||||
|       -> api_error override; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto native_operation(native_operation_callback /* callback */) | ||||
|       -> api_error override { | ||||
|     return api_error::not_supported; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto native_operation(std::uint64_t /* new_file_size */, | ||||
|                                       native_operation_callback /* callback */) | ||||
|       -> api_error override { | ||||
|     return api_error::not_supported; | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_DIRECT_OPEN_FILE_HPP_ | ||||
							
								
								
									
										86
									
								
								repertory/librepertory/include/file_manager/events.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								repertory/librepertory/include/file_manager/events.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_EVENTS_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_EVENTS_HPP_ | ||||
|  | ||||
| #include "events/events.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| // clang-format off | ||||
| E_SIMPLE2(download_begin, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, dest_path, dest, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(download_end, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, dest_path, dest, E_FROM_STRING, | ||||
|   api_error, result, result, E_FROM_API_FILE_ERROR | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(download_progress, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, dest_path, dest, E_FROM_STRING, | ||||
|   double, progress, prog, E_FROM_DOUBLE_PRECISE | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(download_restored, info, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, dest_path, dest, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(download_restore_failed, error, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, dest_path, dest, E_FROM_STRING, | ||||
|   std::string, error, err, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(download_resume_add_failed, error, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, dest_path, dest, E_FROM_STRING, | ||||
|   std::string, error, err, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(download_resume_added, debug, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, dest_path, dest, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE2(download_resume_removed, debug, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, dest_path, dest, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE1(item_timeout, trace, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING | ||||
| ); | ||||
|  | ||||
| E_SIMPLE3(download_type_selected, debug, true, | ||||
|   std::string, api_path, ap, E_FROM_STRING, | ||||
|   std::string, source, src, E_FROM_STRING, | ||||
|   download_type, download_type, type, E_FROM_DOWNLOAD_TYPE | ||||
| ); | ||||
| // clang-format on | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_EVENTS_HPP_ | ||||
							
								
								
									
										175
									
								
								repertory/librepertory/include/file_manager/file_manager.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								repertory/librepertory/include/file_manager/file_manager.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,175 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_FILE_MANAGER_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_FILE_MANAGER_HPP_ | ||||
|  | ||||
| #include "db/i_file_mgr_db.hpp" | ||||
| #include "events/event_system.hpp" | ||||
| #include "events/events.hpp" | ||||
| #include "file_manager/i_file_manager.hpp" | ||||
| #include "file_manager/i_open_file.hpp" | ||||
| #include "file_manager/i_upload_manager.hpp" | ||||
| #include "file_manager/upload.hpp" | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/file.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
| class i_provider; | ||||
|  | ||||
| class file_manager final : public i_file_manager, public i_upload_manager { | ||||
|   E_CONSUMER(); | ||||
|  | ||||
| public: | ||||
|   file_manager(app_config &config, i_provider &provider); | ||||
|  | ||||
|   ~file_manager() override; | ||||
|  | ||||
| public: | ||||
|   file_manager() = delete; | ||||
|   file_manager(const file_manager &) noexcept = delete; | ||||
|   file_manager(file_manager &&) noexcept = delete; | ||||
|   auto operator=(file_manager &&) noexcept -> file_manager & = delete; | ||||
|   auto operator=(const file_manager &) noexcept -> file_manager & = delete; | ||||
|  | ||||
| private: | ||||
|   app_config &config_; | ||||
|   i_provider &provider_; | ||||
|  | ||||
| private: | ||||
|   std::unique_ptr<i_file_mgr_db> mgr_db_; | ||||
|   std::atomic<std::uint64_t> next_handle_{0U}; | ||||
|   mutable std::recursive_mutex open_file_mtx_; | ||||
|   std::unordered_map<std::string, std::shared_ptr<i_closeable_open_file>> | ||||
|       open_file_lookup_; | ||||
|   stop_type stop_requested_{false}; | ||||
|   std::unordered_map<std::string, std::unique_ptr<upload>> upload_lookup_; | ||||
|   mutable std::mutex upload_mtx_; | ||||
|   std::condition_variable upload_notify_; | ||||
|   std::unique_ptr<std::thread> upload_thread_; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto close_all(const std::string &api_path) -> bool; | ||||
|  | ||||
|   void close_timed_out_files(); | ||||
|  | ||||
|   auto get_open_file_by_handle(std::uint64_t handle) const | ||||
|       -> std::shared_ptr<i_closeable_open_file>; | ||||
|  | ||||
|   auto get_open_file_count(const std::string &api_path) const -> std::size_t; | ||||
|  | ||||
|   auto open(const std::string &api_path, bool directory, | ||||
|             const open_file_data &ofd, std::uint64_t &handle, | ||||
|             std::shared_ptr<i_open_file> &file, | ||||
|             std::shared_ptr<i_closeable_open_file> closeable_file) -> api_error; | ||||
|  | ||||
|   void queue_upload(const std::string &api_path, const std::string &source_path, | ||||
|                     bool no_lock); | ||||
|  | ||||
|   void remove_resume(const std::string &api_path, | ||||
|                      const std::string &source_path, bool no_lock); | ||||
|  | ||||
|   void remove_upload(const std::string &api_path, bool no_lock); | ||||
|  | ||||
|   void swap_renamed_items(std::string from_api_path, std::string to_api_path, | ||||
|                           bool directory); | ||||
|  | ||||
|   void upload_completed(const file_upload_completed &evt); | ||||
|  | ||||
|   void upload_handler(); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto get_next_handle() -> std::uint64_t; | ||||
|  | ||||
|   auto handle_file_rename(const std::string &from_api_path, | ||||
|                           const std::string &to_api_path) -> api_error; | ||||
|  | ||||
|   void queue_upload(const i_open_file &file) override; | ||||
|  | ||||
|   void remove_resume(const std::string &api_path, | ||||
|                      const std::string &source_path) override; | ||||
|  | ||||
|   static auto remove_source_and_shrink_cache(const std::string &api_path, | ||||
|                                              const std::string &source_path, | ||||
|                                              std::uint64_t file_size, | ||||
|                                              bool allocated) -> bool; | ||||
|  | ||||
|   void remove_upload(const std::string &api_path) override; | ||||
|  | ||||
|   void store_resume(const i_open_file &file) override; | ||||
|  | ||||
| public: | ||||
|   void close(std::uint64_t handle); | ||||
|  | ||||
|   [[nodiscard]] auto create(const std::string &api_path, api_meta_map &meta, | ||||
|                             open_file_data ofd, std::uint64_t &handle, | ||||
|                             std::shared_ptr<i_open_file> &file) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto evict_file(const std::string &api_path) -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_items(const std::string &api_path) const | ||||
|       -> directory_item_list override; | ||||
|  | ||||
|   [[nodiscard]] auto get_open_file(std::uint64_t handle, bool write_supported, | ||||
|                                    std::shared_ptr<i_open_file> &file) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto get_open_file_count() const -> std::size_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_open_files() const | ||||
|       -> std::unordered_map<std::string, std::size_t> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_open_handle_count() const -> std::size_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_stored_downloads() const | ||||
|       -> std::vector<i_file_mgr_db::resume_entry>; | ||||
|  | ||||
|   [[nodiscard]] auto has_no_open_file_handles() const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto is_processing(const std::string &api_path) const | ||||
|       -> bool override; | ||||
|  | ||||
| #if defined(PROJECT_TESTING) | ||||
|   [[nodiscard]] auto open(std::shared_ptr<i_closeable_open_file> of, | ||||
|                           const open_file_data &ofd, std::uint64_t &handle, | ||||
|                           std::shared_ptr<i_open_file> &file) -> api_error; | ||||
| #endif // defined(PROJECT_TESTING) | ||||
|   [[nodiscard]] auto open(const std::string &api_path, bool directory, | ||||
|                           const open_file_data &ofd, std::uint64_t &handle, | ||||
|                           std::shared_ptr<i_open_file> &file) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto remove_file(const std::string &api_path) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto rename_directory(const std::string &from_api_path, | ||||
|                                       const std::string &to_api_path) | ||||
|       -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto rename_file(const std::string &from_api_path, | ||||
|                                  const std::string &to_api_path, bool overwrite) | ||||
|       -> api_error; | ||||
|  | ||||
|   void start(); | ||||
|  | ||||
|   void stop(); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_FILE_MANAGER_HPP_ | ||||
| @@ -0,0 +1,51 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_I_FILE_MANAGER_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_I_FILE_MANAGER_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_provider; | ||||
|  | ||||
| class i_file_manager { | ||||
|   INTERFACE_SETUP(i_file_manager); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] virtual auto evict_file(const std::string &api_path) | ||||
|       -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_directory_items(const std::string &api_path) const | ||||
|       -> directory_item_list = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_open_files() const | ||||
|       -> std::unordered_map<std::string, std::size_t> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto has_no_open_file_handles() const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_processing(const std::string &api_path) const | ||||
|       -> bool = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_I_FILE_MANAGER_HPP_ | ||||
							
								
								
									
										117
									
								
								repertory/librepertory/include/file_manager/i_open_file.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								repertory/librepertory/include/file_manager/i_open_file.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,117 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_I_OPEN_FILE_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_I_OPEN_FILE_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_open_file { | ||||
|   INTERFACE_SETUP(i_open_file); | ||||
|  | ||||
| public: | ||||
|   using native_operation_callback = std::function<api_error(native_handle)>; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] virtual auto get_api_path() const -> std::string = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_chunk_size() const -> std::size_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_file_size() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_filesystem_item() const -> filesystem_item = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_open_data() | ||||
|       -> std::map<std::uint64_t, open_file_data> & = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_open_data() const | ||||
|       -> const std::map<std::uint64_t, open_file_data> & = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_open_data(std::uint64_t handle) | ||||
|       -> open_file_data & = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_open_data(std::uint64_t handle) const | ||||
|       -> const open_file_data & = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_open_file_count() const -> std::size_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_read_state() const | ||||
|       -> boost::dynamic_bitset<> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_read_state(std::size_t chunk) const | ||||
|       -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_source_path() const -> std::string = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_complete() const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_directory() const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_write_supported() const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto has_handle(std::uint64_t handle) const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   native_operation(native_operation_callback callback) -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   native_operation(std::uint64_t new_file_size, | ||||
|                    native_operation_callback callback) -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto read(std::size_t read_size, | ||||
|                                   std::uint64_t read_offset, data_buffer &data) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto resize(std::uint64_t new_file_size) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   virtual void set_api_path(const std::string &api_path) = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto write(std::uint64_t write_offset, | ||||
|                                    const data_buffer &data, | ||||
|                                    std::size_t &bytes_written) -> api_error = 0; | ||||
| }; | ||||
|  | ||||
| class i_closeable_open_file : public i_open_file { | ||||
|   INTERFACE_SETUP(i_closeable_open_file); | ||||
|  | ||||
| public: | ||||
|   virtual void add(std::uint64_t handle, open_file_data ofd) = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_allocated() const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto can_close() const -> bool = 0; | ||||
|  | ||||
|   virtual auto close() -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_handles() const | ||||
|       -> std::vector<std::uint64_t> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_modified() const -> bool = 0; | ||||
|  | ||||
|   virtual void remove(std::uint64_t handle) = 0; | ||||
|  | ||||
|   virtual void remove_all() = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_I_OPEN_FILE_HPP_ | ||||
| @@ -0,0 +1,43 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_I_UPLOAD_MANAGER_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_I_UPLOAD_MANAGER_HPP_ | ||||
|  | ||||
| namespace repertory { | ||||
| class i_open_file; | ||||
|  | ||||
| class i_upload_manager { | ||||
|   INTERFACE_SETUP(i_upload_manager); | ||||
|  | ||||
| public: | ||||
|   virtual void queue_upload(const i_open_file &file) = 0; | ||||
|  | ||||
|   virtual void remove_resume(const std::string &api_path, | ||||
|                              const std::string &source_path) = 0; | ||||
|  | ||||
|   virtual void remove_upload(const std::string &api_path) = 0; | ||||
|  | ||||
|   virtual void store_resume(const i_open_file &file) = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_I_UPLOAD_MANAGER_HPP_ | ||||
							
								
								
									
										135
									
								
								repertory/librepertory/include/file_manager/open_file.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								repertory/librepertory/include/file_manager/open_file.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_HPP_ | ||||
|  | ||||
| #include "file_manager/open_file_base.hpp" | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/types/file/i_file.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_provider; | ||||
| class i_upload_manager; | ||||
|  | ||||
| class open_file final : public open_file_base { | ||||
| public: | ||||
|   open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, | ||||
|             filesystem_item fsi, i_provider &provider, i_upload_manager &mgr); | ||||
|  | ||||
|   open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, | ||||
|             filesystem_item fsi, | ||||
|             std::map<std::uint64_t, open_file_data> open_data, | ||||
|             i_provider &provider, i_upload_manager &mgr); | ||||
|  | ||||
|   open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, | ||||
|             filesystem_item fsi, i_provider &provider, | ||||
|             std::optional<boost::dynamic_bitset<>> read_state, | ||||
|             i_upload_manager &mgr); | ||||
|  | ||||
| private: | ||||
|   open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, | ||||
|             filesystem_item fsi, | ||||
|             std::map<std::uint64_t, open_file_data> open_data, | ||||
|             i_provider &provider, | ||||
|             std::optional<boost::dynamic_bitset<>> read_state, | ||||
|             i_upload_manager &mgr); | ||||
|  | ||||
| public: | ||||
|   open_file() = delete; | ||||
|   open_file(const open_file &) noexcept = delete; | ||||
|   open_file(open_file &&) noexcept = delete; | ||||
|   auto operator=(open_file &&) noexcept -> open_file & = delete; | ||||
|   auto operator=(const open_file &) noexcept -> open_file & = delete; | ||||
|  | ||||
| public: | ||||
|   ~open_file() override; | ||||
|  | ||||
| private: | ||||
|   i_upload_manager &mgr_; | ||||
|  | ||||
| private: | ||||
|   bool allocated{false}; | ||||
|   std::unique_ptr<utils::file::i_file> nf_; | ||||
|   bool notified_{false}; | ||||
|   std::size_t read_chunk_{}; | ||||
|   boost::dynamic_bitset<> read_state_; | ||||
|   std::unique_ptr<std::thread> reader_thread_; | ||||
|   mutable std::recursive_mutex rw_mtx_; | ||||
|   stop_type stop_requested_{false}; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto adjust_cache_size(std::uint64_t file_size, | ||||
|                                        bool shrink) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto check_start() -> api_error; | ||||
|  | ||||
|   void download_chunk(std::size_t chunk, bool skip_active, bool should_reset); | ||||
|  | ||||
|   void download_range(std::size_t begin_chunk, std::size_t end_chunk, | ||||
|                       bool should_reset); | ||||
|  | ||||
|   void set_modified(); | ||||
|  | ||||
|   void set_read_state(std::size_t chunk); | ||||
|  | ||||
|   void set_read_state(boost::dynamic_bitset<> read_state); | ||||
|  | ||||
|   void update_reader(std::size_t chunk); | ||||
|  | ||||
| public: | ||||
|   auto close() -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto get_allocated() const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto get_read_state() const -> boost::dynamic_bitset<> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_read_state(std::size_t chunk) const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto is_complete() const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto is_write_supported() const -> bool override { | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   native_operation(native_operation_callback callback) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   native_operation(std::uint64_t new_file_size, | ||||
|                    native_operation_callback callback) -> api_error override; | ||||
|  | ||||
|   void remove(std::uint64_t handle) override; | ||||
|  | ||||
|   void remove_all() override; | ||||
|  | ||||
|   [[nodiscard]] auto read(std::size_t read_size, std::uint64_t read_offset, | ||||
|                           data_buffer &data) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto resize(std::uint64_t new_file_size) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto write(std::uint64_t write_offset, const data_buffer &data, | ||||
|                            std::size_t &bytes_written) -> api_error override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_HPP_ | ||||
							
								
								
									
										221
									
								
								repertory/librepertory/include/file_manager/open_file_base.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								repertory/librepertory/include/file_manager/open_file_base.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,221 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_BASE_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_BASE_HPP_ | ||||
|  | ||||
| #include "file_manager/i_open_file.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_provider; | ||||
|  | ||||
| class open_file_base : public i_closeable_open_file { | ||||
| public: | ||||
|   open_file_base(std::uint64_t chunk_size, std::uint8_t chunk_timeout, | ||||
|                  filesystem_item fsi, i_provider &provider, bool disable_io); | ||||
|  | ||||
|   open_file_base(std::uint64_t chunk_size, std::uint8_t chunk_timeout, | ||||
|                  filesystem_item fsi, | ||||
|                  std::map<std::uint64_t, open_file_data> open_data, | ||||
|                  i_provider &provider, bool disable_io); | ||||
|  | ||||
|   ~open_file_base() override = default; | ||||
|  | ||||
| public: | ||||
|   open_file_base() = delete; | ||||
|   open_file_base(const open_file_base &) noexcept = delete; | ||||
|   open_file_base(open_file_base &&) noexcept = delete; | ||||
|   auto operator=(open_file_base &&) noexcept -> open_file_base & = delete; | ||||
|   auto operator=(const open_file_base &) noexcept -> open_file_base & = delete; | ||||
|  | ||||
| public: | ||||
|   class download final { | ||||
|   public: | ||||
|     download() = default; | ||||
|  | ||||
|     ~download() = default; | ||||
|  | ||||
|   public: | ||||
|     download(const download &) noexcept = delete; | ||||
|     download(download &&) noexcept = delete; | ||||
|     auto operator=(download &&) noexcept -> download & = delete; | ||||
|     auto operator=(const download &) noexcept -> download & = delete; | ||||
|  | ||||
|   private: | ||||
|     bool complete_{false}; | ||||
|     api_error error_{api_error::success}; | ||||
|     std::mutex mtx_; | ||||
|     std::condition_variable notify_; | ||||
|  | ||||
|   public: | ||||
|     void notify(const api_error &err); | ||||
|  | ||||
|     auto wait() -> api_error; | ||||
|   }; | ||||
|  | ||||
|   class io_item final { | ||||
|   public: | ||||
|     io_item(std::function<api_error()> action) : action_(std::move(action)) {} | ||||
|  | ||||
|     ~io_item() = default; | ||||
|  | ||||
|   public: | ||||
|     io_item() = delete; | ||||
|     io_item(const io_item &) noexcept = delete; | ||||
|     io_item(io_item &&) noexcept = delete; | ||||
|     auto operator=(io_item &&) noexcept -> io_item & = delete; | ||||
|     auto operator=(const io_item &) noexcept -> io_item & = delete; | ||||
|  | ||||
|   private: | ||||
|     std::function<api_error()> action_; | ||||
|     std::mutex mtx_; | ||||
|     std::condition_variable notify_; | ||||
|     std::optional<api_error> result_; | ||||
|  | ||||
|   public: | ||||
|     void action(); | ||||
|  | ||||
|     [[nodiscard]] auto get_result() -> api_error; | ||||
|   }; | ||||
|  | ||||
| private: | ||||
|   std::uint64_t chunk_size_; | ||||
|   std::uint8_t chunk_timeout_; | ||||
|   filesystem_item fsi_; | ||||
|   std::size_t last_chunk_size_; | ||||
|   std::map<std::uint64_t, open_file_data> open_data_; | ||||
|   i_provider &provider_; | ||||
|  | ||||
| private: | ||||
|   std::unordered_map<std::size_t, std::shared_ptr<download>> active_downloads_; | ||||
|   api_error error_{api_error::success}; | ||||
|   mutable std::mutex error_mtx_; | ||||
|   mutable std::recursive_mutex file_mtx_; | ||||
|   stop_type io_stop_requested_{false}; | ||||
|   std::unique_ptr<std::thread> io_thread_; | ||||
|   mutable std::mutex io_thread_mtx_; | ||||
|   std::condition_variable io_thread_notify_; | ||||
|   std::deque<std::shared_ptr<io_item>> io_thread_queue_; | ||||
|   std::atomic<std::chrono::system_clock::time_point> last_access_{ | ||||
|       std::chrono::system_clock::now(), | ||||
|   }; | ||||
|   bool modified_{false}; | ||||
|   bool removed_{false}; | ||||
|  | ||||
| private: | ||||
|   void file_io_thread(); | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto do_io(std::function<api_error()> action) -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto get_active_downloads() | ||||
|       -> std::unordered_map<std::size_t, std::shared_ptr<download>> & { | ||||
|     return active_downloads_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_mutex() const -> std::recursive_mutex & { | ||||
|     return file_mtx_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_last_chunk_size() const -> std::size_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_provider() -> i_provider & { return provider_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_provider() const -> const i_provider & { | ||||
|     return provider_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto is_removed() const -> bool; | ||||
|  | ||||
|   void notify_io(); | ||||
|  | ||||
|   void reset_timeout(); | ||||
|  | ||||
|   auto set_api_error(const api_error &err) -> api_error; | ||||
|  | ||||
|   void set_file_size(std::uint64_t size); | ||||
|  | ||||
|   void set_last_chunk_size(std::size_t size); | ||||
|  | ||||
|   void set_modified(bool modified); | ||||
|  | ||||
|   void set_removed(bool removed); | ||||
|  | ||||
|   void set_source_path(std::string source_path); | ||||
|  | ||||
|   void wait_for_io(stop_type &stop_requested); | ||||
|  | ||||
| public: | ||||
|   void add(std::uint64_t handle, open_file_data ofd) override; | ||||
|  | ||||
|   [[nodiscard]] auto can_close() const -> bool override; | ||||
|  | ||||
|   auto close() -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto get_allocated() const -> bool override { return false; } | ||||
|  | ||||
|   [[nodiscard]] auto get_api_error() const -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto get_api_path() const -> std::string override; | ||||
|  | ||||
|   [[nodiscard]] auto get_chunk_size() const -> std::size_t override { | ||||
|     return chunk_size_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_file_size() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_filesystem_item() const -> filesystem_item override; | ||||
|  | ||||
|   [[nodiscard]] auto get_handles() const -> std::vector<std::uint64_t> override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_open_data() -> std::map<std::uint64_t, open_file_data> & override; | ||||
|  | ||||
|   [[nodiscard]] auto get_open_data() const | ||||
|       -> const std::map<std::uint64_t, open_file_data> & override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_open_data(std::uint64_t handle) -> open_file_data & override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_open_data(std::uint64_t handle) const -> const open_file_data & override; | ||||
|  | ||||
|   [[nodiscard]] auto get_open_file_count() const -> std::size_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_source_path() const -> std::string override; | ||||
|  | ||||
|   [[nodiscard]] auto has_handle(std::uint64_t handle) const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto is_directory() const -> bool override { | ||||
|     return fsi_.directory; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto is_modified() const -> bool override; | ||||
|  | ||||
|   void remove(std::uint64_t handle) override; | ||||
|  | ||||
|   void remove_all() override; | ||||
|  | ||||
|   void set_api_path(const std::string &api_path) override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_BASE_HPP_ | ||||
							
								
								
									
										150
									
								
								repertory/librepertory/include/file_manager/ring_buffer_base.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								repertory/librepertory/include/file_manager/ring_buffer_base.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_BASE_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_BASE_HPP_ | ||||
|  | ||||
| #include "file_manager/open_file_base.hpp" | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/file.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_provider; | ||||
| class i_upload_manager; | ||||
|  | ||||
| class ring_buffer_base : public open_file_base { | ||||
| public: | ||||
|   ring_buffer_base(std::uint64_t chunk_size, std::uint8_t chunk_timeout, | ||||
|                    filesystem_item fsi, i_provider &provider, | ||||
|                    std::size_t ring_size, bool disable_io); | ||||
|  | ||||
|   ~ring_buffer_base() override = default; | ||||
|  | ||||
| public: | ||||
|   ring_buffer_base() = delete; | ||||
|   ring_buffer_base(const ring_buffer_base &) noexcept = delete; | ||||
|   ring_buffer_base(ring_buffer_base &&) noexcept = delete; | ||||
|   auto operator=(ring_buffer_base &&) noexcept -> ring_buffer_base & = delete; | ||||
|   auto | ||||
|   operator=(const ring_buffer_base &) noexcept -> ring_buffer_base & = delete; | ||||
|  | ||||
| public: | ||||
|   static constexpr const auto min_ring_size{5U}; | ||||
|  | ||||
| private: | ||||
|   boost::dynamic_bitset<> read_state_; | ||||
|   std::size_t total_chunks_; | ||||
|  | ||||
| private: | ||||
|   std::condition_variable chunk_notify_; | ||||
|   mutable std::mutex chunk_mtx_; | ||||
|   std::mutex read_mtx_; | ||||
|   std::unique_ptr<std::thread> reader_thread_; | ||||
|   std::size_t ring_begin_{}; | ||||
|   std::size_t ring_end_{}; | ||||
|   std::size_t ring_pos_{}; | ||||
|   stop_type stop_requested_{false}; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto check_start() -> api_error; | ||||
|  | ||||
|   auto download_chunk(std::size_t chunk, bool skip_active) -> api_error; | ||||
|  | ||||
|   void reader_thread(); | ||||
|  | ||||
|   void update_position(std::size_t count, bool is_forward); | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto has_reader_thread() const -> bool { | ||||
|     return reader_thread_ != nullptr; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_ring_size() const -> std::size_t { | ||||
|     return read_state_.size(); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto on_check_start() -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   on_chunk_downloaded(std::size_t chunk, | ||||
|                       const data_buffer &buffer) -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   on_read_chunk(std::size_t chunk, std::size_t read_size, | ||||
|                 std::uint64_t read_offset, data_buffer &data, | ||||
|                 std::size_t &bytes_read) -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   use_buffer(std::size_t chunk, | ||||
|              std::function<api_error(data_buffer &)> func) -> api_error = 0; | ||||
|  | ||||
| public: | ||||
|   auto close() -> bool override; | ||||
|  | ||||
|   void forward(std::size_t count); | ||||
|  | ||||
|   [[nodiscard]] auto get_current_chunk() const -> std::size_t { | ||||
|     return ring_pos_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_first_chunk() const -> std::size_t { | ||||
|     return ring_begin_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_last_chunk() const -> std::size_t { return ring_end_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_read_state() const -> boost::dynamic_bitset<> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_read_state(std::size_t chunk) const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_chunks() const -> std::size_t { | ||||
|     return total_chunks_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto is_complete() const -> bool override { return false; } | ||||
|  | ||||
|   [[nodiscard]] auto is_write_supported() const -> bool override { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto read(std::size_t read_size, std::uint64_t read_offset, | ||||
|                           data_buffer &data) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto resize(std::uint64_t /* size */) -> api_error override { | ||||
|     return api_error::not_supported; | ||||
|   } | ||||
|  | ||||
|   void reverse(std::size_t count); | ||||
|  | ||||
|   void set(std::size_t first_chunk, std::size_t current_chunk); | ||||
|  | ||||
|   void set_api_path(const std::string &api_path) override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   write(std::uint64_t /* write_offset */, const data_buffer & /* data */, | ||||
|         std::size_t & /* bytes_written */) -> api_error override { | ||||
|     return api_error::not_supported; | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_BASE_HPP_ | ||||
| @@ -0,0 +1,93 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_OPEN_FILE_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_OPEN_FILE_HPP_ | ||||
|  | ||||
| #include "file_manager/ring_buffer_base.hpp" | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/file.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_provider; | ||||
| class i_upload_manager; | ||||
|  | ||||
| class ring_buffer_open_file final : public ring_buffer_base { | ||||
| public: | ||||
|   ring_buffer_open_file(std::string buffer_directory, std::uint64_t chunk_size, | ||||
|                         std::uint8_t chunk_timeout, filesystem_item fsi, | ||||
|                         i_provider &provider, std::size_t ring_size); | ||||
|  | ||||
|   ~ring_buffer_open_file() override; | ||||
|  | ||||
| public: | ||||
|   ring_buffer_open_file() = delete; | ||||
|   ring_buffer_open_file(const ring_buffer_open_file &) noexcept = delete; | ||||
|   ring_buffer_open_file(ring_buffer_open_file &&) noexcept = delete; | ||||
|   auto operator=(ring_buffer_open_file &&) noexcept -> ring_buffer_open_file & = | ||||
|                                                            delete; | ||||
|   auto operator=(const ring_buffer_open_file &) noexcept | ||||
|       -> ring_buffer_open_file & = delete; | ||||
|  | ||||
| private: | ||||
|   std::string source_path_; | ||||
|  | ||||
| private: | ||||
|   std::unique_ptr<utils::file::i_file> nf_; | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto on_check_start() -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   on_chunk_downloaded(std::size_t chunk, | ||||
|                       const data_buffer &buffer) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   on_read_chunk(std::size_t chunk, std::size_t read_size, | ||||
|                 std::uint64_t read_offset, data_buffer &data, | ||||
|                 std::size_t &bytes_read) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto use_buffer(std::size_t chunk, | ||||
|                                 std::function<api_error(data_buffer &)> func) | ||||
|       -> api_error override; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] static auto can_handle_file(std::uint64_t file_size, | ||||
|                                             std::size_t chunk_size, | ||||
|                                             std::size_t ring_size) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   native_operation(native_operation_callback callback) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto native_operation(std::uint64_t /* new_file_size */, | ||||
|                                       native_operation_callback /* callback */) | ||||
|       -> api_error override { | ||||
|     return api_error::not_supported; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_source_path() const -> std::string override { | ||||
|     return source_path_; | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_OPEN_FILE_HPP_ | ||||
							
								
								
									
										75
									
								
								repertory/librepertory/include/file_manager/upload.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								repertory/librepertory/include/file_manager/upload.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_UPLOAD_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_UPLOAD_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_provider; | ||||
|  | ||||
| class upload final { | ||||
| public: | ||||
|   upload(filesystem_item fsi, i_provider &provider); | ||||
|  | ||||
|   ~upload(); | ||||
|  | ||||
| public: | ||||
|   upload() = delete; | ||||
|   upload(const upload &) noexcept = delete; | ||||
|   upload(upload &&) noexcept = delete; | ||||
|   auto operator=(upload &&) noexcept -> upload & = delete; | ||||
|   auto operator=(const upload &) noexcept -> upload & = delete; | ||||
|  | ||||
| private: | ||||
|   filesystem_item fsi_; | ||||
|   i_provider &provider_; | ||||
|  | ||||
| private: | ||||
|   bool cancelled_{false}; | ||||
|   api_error error_{api_error::success}; | ||||
|   std::unique_ptr<std::thread> thread_; | ||||
|   stop_type stop_requested_{false}; | ||||
|  | ||||
| private: | ||||
|   void upload_thread(); | ||||
|  | ||||
| public: | ||||
|   void cancel(); | ||||
|  | ||||
|   [[nodiscard]] auto get_api_error() const -> api_error { return error_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_api_path() const -> std::string { | ||||
|     return fsi_.api_path; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_source_path() const -> std::string { | ||||
|     return fsi_.source_path; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto is_cancelled() const -> bool { return cancelled_; } | ||||
|  | ||||
|   void stop(); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif //  REPERTORY_INCLUDE_FILE_MANAGER_UPLOAD_HPP_ | ||||
							
								
								
									
										10
									
								
								repertory/librepertory/include/initialize.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								repertory/librepertory/include/initialize.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #ifndef LIBREPERTORY_INCLUDE_INITIALIZE_HPP_ | ||||
| #define LIBREPERTORY_INCLUDE_INITIALIZE_HPP_ | ||||
|  | ||||
| namespace repertory { | ||||
| void project_cleanup(); | ||||
|  | ||||
| [[nodiscard]] auto project_initialize() -> bool; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // LIBREPERTORY_INCLUDE_INITIALIZE_HPP_ | ||||
							
								
								
									
										35
									
								
								repertory/librepertory/include/platform/platform.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								repertory/librepertory/include/platform/platform.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_PLATFORM_PLATFORM_HPP_ | ||||
| #define REPERTORY_INCLUDE_PLATFORM_PLATFORM_HPP_ | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| #include "platform/win32_platform.hpp" | ||||
| #include "utils/windows.hpp" | ||||
| #include "utils/windows/windows_utils.hpp" | ||||
| #else // !defined(_WIN32) | ||||
| #include "platform/unix_platform.hpp" | ||||
| #include "utils/unix.hpp" | ||||
| #include "utils/unix/unix_utils.hpp" | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_PLATFORM_PLATFORM_HPP_ | ||||
							
								
								
									
										80
									
								
								repertory/librepertory/include/platform/unix_platform.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								repertory/librepertory/include/platform/unix_platform.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_PLATFORM_UNIXPLATFORM_HPP_ | ||||
| #define REPERTORY_INCLUDE_PLATFORM_UNIXPLATFORM_HPP_ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_provider; | ||||
|  | ||||
| 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: | ||||
|   [[nodiscard]] static auto get_state_directory() -> std::string; | ||||
|  | ||||
|   [[nodiscard]] static auto get_lock_data_file() -> std::string; | ||||
|  | ||||
|   [[nodiscard]] auto get_lock_file() -> std::string; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] static auto | ||||
|   wait_for_lock(int fd, std::uint8_t retry_count = 30u) -> int; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto get_mount_state(json &mount_state) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto grab_lock(std::uint8_t retry_count = 30u) -> lock_result; | ||||
|  | ||||
|   [[nodiscard]] auto set_mount_state(bool active, | ||||
|                                      const std::string &mount_location, | ||||
|                                      int pid) -> bool; | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] auto create_meta_attributes( | ||||
|     std::uint64_t accessed_date, std::uint32_t attributes, | ||||
|     std::uint64_t changed_date, std::uint64_t creation_date, bool directory, | ||||
|     std::uint32_t gid, const std::string &key, std::uint32_t mode, | ||||
|     std::uint64_t modified_date, std::uint32_t osx_backup, | ||||
|     std::uint32_t osx_flags, std::uint64_t size, const std::string &source_path, | ||||
|     std::uint32_t uid, std::uint64_t written_date) -> api_meta_map; | ||||
|  | ||||
| [[nodiscard]] auto provider_meta_handler(i_provider &provider, bool directory, | ||||
|                                          const api_file &file) -> api_error; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_PLATFORM_UNIXPLATFORM_HPP_ | ||||
							
								
								
									
										86
									
								
								repertory/librepertory/include/platform/win32_platform.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								repertory/librepertory/include/platform/win32_platform.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_PLATFORM_WINPLATFORM_HPP_ | ||||
| #define REPERTORY_INCLUDE_PLATFORM_WINPLATFORM_HPP_ | ||||
| #if defined(_WIN32) | ||||
|  | ||||
| #include "app_config.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_provider; | ||||
|  | ||||
| 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: | ||||
|   [[nodiscard]] auto get_mount_state(const provider_type &pt, | ||||
|                                      json &mount_state) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto get_mount_state(json &mount_state) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto get_unique_id() const -> std::string { return unique_id_; } | ||||
|  | ||||
|   [[nodiscard]] auto grab_lock(std::uint8_t retry_count = 30) -> lock_result; | ||||
|  | ||||
|   void release(); | ||||
|  | ||||
|   [[nodiscard]] auto set_mount_state(bool active, | ||||
|                                      const std::string &mount_location, | ||||
|                                      const std::int64_t &pid) -> bool; | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] auto create_meta_attributes( | ||||
|     std::uint64_t accessed_date, std::uint32_t attributes, | ||||
|     std::uint64_t changed_date, std::uint64_t creation_date, bool directory, | ||||
|     std::uint32_t gid, const std::string &key, std::uint32_t mode, | ||||
|     std::uint64_t modified_date, std::uint32_t osx_backup, | ||||
|     std::uint32_t osx_flags, std::uint64_t size, const std::string &source_path, | ||||
|     std::uint32_t uid, std::uint64_t written_date) -> api_meta_map; | ||||
|  | ||||
| [[nodiscard]] auto provider_meta_handler(i_provider &provider, bool directory, | ||||
|                                          const api_file &file) -> api_error; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_PLATFORM_WINPLATFORM_HPP_ | ||||
							
								
								
									
										225
									
								
								repertory/librepertory/include/providers/base_provider.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								repertory/librepertory/include/providers/base_provider.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,225 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_ | ||||
| #define REPERTORY_INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_ | ||||
|  | ||||
| #include "db/i_meta_db.hpp" | ||||
| #include "providers/i_provider.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
| class i_file_manager; | ||||
| class i_http_comm; | ||||
|  | ||||
| class base_provider : public i_provider { | ||||
| private: | ||||
|   struct removed_item final { | ||||
|     std::string api_path; | ||||
|     bool directory{}; | ||||
|     std::string source_path; | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   base_provider(app_config &config, i_http_comm &comm) | ||||
|       : config_(config), comm_(comm) {} | ||||
|  | ||||
| private: | ||||
|   app_config &config_; | ||||
|   i_http_comm &comm_; | ||||
|  | ||||
| private: | ||||
|   api_item_added_callback api_item_added_; | ||||
|   std::unique_ptr<i_meta_db> db3_; | ||||
|   i_file_manager *fm_{}; | ||||
|  | ||||
| private: | ||||
|   void add_all_items(const stop_type &stop_requested); | ||||
|  | ||||
|   void process_removed_directories(std::deque<removed_item> removed_list, | ||||
|                                    const stop_type &stop_requested); | ||||
|  | ||||
|   void process_removed_files(std::deque<removed_item> removed_list, | ||||
|                              const stop_type &stop_requested); | ||||
|  | ||||
|   void process_removed_items(const stop_type &stop_requested); | ||||
|  | ||||
|   void remove_deleted_items(const stop_type &stop_requested); | ||||
|  | ||||
|   void remove_unmatched_source_files(const stop_type &stop_requested); | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] static auto create_api_file(std::string path, std::string key, | ||||
|                                             std::uint64_t size, | ||||
|                                             std::uint64_t file_time) | ||||
|       -> api_file; | ||||
|  | ||||
|   [[nodiscard]] static auto create_api_file(std::string path, | ||||
|                                             std::uint64_t size, | ||||
|                                             api_meta_map &meta) -> api_file; | ||||
|  | ||||
|   [[nodiscard]] virtual auto create_directory_impl(const std::string &api_path, | ||||
|                                                    api_meta_map &meta) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   create_file_extra(const std::string & /* api_path */, | ||||
|                     api_meta_map & /* meta */) -> api_error { | ||||
|     return api_error::success; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_api_item_added() -> api_item_added_callback & { | ||||
|     return api_item_added_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_api_item_added() const | ||||
|       -> const api_item_added_callback & { | ||||
|     return api_item_added_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_comm() -> i_http_comm & { return comm_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_comm() const -> const i_http_comm & { return comm_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_config() -> app_config & { return config_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_config() const -> const app_config & { | ||||
|     return config_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_db() -> i_meta_db & { return *db3_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_db() const -> const i_meta_db & { return *db3_; } | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_directory_items_impl(const std::string &api_path, | ||||
|                            directory_item_list &list) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_mgr() -> i_file_manager * { return fm_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_file_mgr() const -> const i_file_manager * { | ||||
|     return fm_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_directory_impl(const std::string &api_path) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_file_impl(const std::string &api_path) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto upload_file_impl(const std::string &api_path, | ||||
|                                               const std::string &source_path, | ||||
|                                               stop_type &stop_requested) | ||||
|       -> api_error = 0; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto | ||||
|   create_directory_clone_source_meta(const std::string &source_api_path, | ||||
|                                      const std::string &api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto create_directory(const std::string &api_path, | ||||
|                                       api_meta_map &meta) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto create_file(const std::string &api_path, | ||||
|                                  api_meta_map &meta) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_api_path_from_source(const std::string &source_path, | ||||
|                                               std::string &api_path) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_items(const std::string &api_path, | ||||
|                                          directory_item_list &list) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_size(const std::string &api_path, | ||||
|                                    std::uint64_t &file_size) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_filesystem_item(const std::string &api_path, | ||||
|                                          bool directory, | ||||
|                                          filesystem_item &fsi) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_filesystem_item_and_file(const std::string &api_path, | ||||
|                                                   api_file &f, | ||||
|                                                   filesystem_item &fsi) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_filesystem_item_from_source_path(const std::string &source_path, | ||||
|                                        filesystem_item &fsi) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    api_meta_map &meta) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    const std::string &key, | ||||
|                                    std::string &value) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_pinned_files() const | ||||
|       -> std::vector<std::string> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto is_file_writeable(const std::string &api_path) const | ||||
|       -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto is_read_only() const -> bool override { return false; } | ||||
|  | ||||
|   [[nodiscard]] auto remove_directory(const std::string &api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_file(const std::string &api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_item_meta(const std::string &api_path, | ||||
|                                       const std::string &key) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto set_item_meta(const std::string &api_path, | ||||
|                                    const std::string &key, | ||||
|                                    const std::string &value) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto set_item_meta(const std::string &api_path, | ||||
|                                    const api_meta_map &meta) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto start(api_item_added_callback api_item_added, | ||||
|                            i_file_manager *mgr) -> bool override; | ||||
|  | ||||
|   void stop() override; | ||||
|  | ||||
|   [[nodiscard]] auto upload_file(const std::string &api_path, | ||||
|                                  const std::string &source_path, | ||||
|                                  stop_type &stop_requested) | ||||
|       -> api_error override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_ | ||||
| @@ -0,0 +1,236 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_PROVIDERS_ENCRYPT_ENCRYPT_PROVIDER_HPP_ | ||||
| #define REPERTORY_INCLUDE_PROVIDERS_ENCRYPT_ENCRYPT_PROVIDER_HPP_ | ||||
|  | ||||
| #include "app_config.hpp" | ||||
| #include "db/i_file_db.hpp" | ||||
| #include "providers/i_provider.hpp" | ||||
| #include "utils/encrypting_reader.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class encrypt_provider final : public i_provider { | ||||
| public: | ||||
|   static const constexpr auto type{provider_type::encrypt}; | ||||
|  | ||||
| public: | ||||
|   explicit encrypt_provider(app_config &config); | ||||
|  | ||||
|   ~encrypt_provider() override = default; | ||||
|  | ||||
| public: | ||||
|   encrypt_provider(const encrypt_provider &) = delete; | ||||
|   encrypt_provider(encrypt_provider &&) = delete; | ||||
|   auto operator=(const encrypt_provider &) -> encrypt_provider & = delete; | ||||
|   auto operator=(encrypt_provider &&) -> encrypt_provider & = delete; | ||||
|  | ||||
| private: | ||||
|   struct reader_info final { | ||||
|     std::chrono::system_clock::time_point last_access_time{ | ||||
|         std::chrono::system_clock::now(), | ||||
|     }; | ||||
|     std::unique_ptr<utils::encryption::encrypting_reader> reader; | ||||
|     std::mutex reader_mtx; | ||||
|   }; | ||||
|  | ||||
| private: | ||||
|   app_config &config_; | ||||
|   encrypt_config encrypt_config_; | ||||
|  | ||||
| private: | ||||
|   std::unique_ptr<i_file_db> db_{nullptr}; | ||||
|   i_file_manager *fm_{nullptr}; | ||||
|   std::unordered_map<std::string, std::shared_ptr<reader_info>> reader_lookup_; | ||||
|   std::recursive_mutex reader_lookup_mtx_; | ||||
|  | ||||
| private: | ||||
|   static auto create_api_file(const std::string &api_path, bool directory, | ||||
|                               const std::string &source_path) -> api_file; | ||||
|  | ||||
|   static void create_item_meta(api_meta_map &meta, bool directory, | ||||
|                                const api_file &file); | ||||
|  | ||||
|   auto do_fs_operation(const std::string &api_path, bool directory, | ||||
|                        std::function<api_error(const encrypt_config &cfg, | ||||
|                                                const std::string &source_path)> | ||||
|                            callback) const -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto get_encrypt_config() const -> const encrypt_config & { | ||||
|     return encrypt_config_; | ||||
|   } | ||||
|  | ||||
|   auto process_directory_entry(const utils::file::i_fs_item &dir_entry, | ||||
|                                const encrypt_config &cfg, | ||||
|                                std::string &api_path) const -> bool; | ||||
|  | ||||
|   void remove_deleted_files(const stop_type &stop_requested); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto create_directory(const std::string &api_path, | ||||
|                                       api_meta_map &meta) -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   create_directory_clone_source_meta(const std::string & /*source_api_path*/, | ||||
|                                      const std::string & /*api_path*/) | ||||
|       -> api_error override { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto create_file(const std::string & /*api_path*/, | ||||
|                                  api_meta_map & /*meta*/) | ||||
|       -> api_error override { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_api_path_from_source(const std::string & /*source_path*/, | ||||
|                            std::string & /*api_path*/) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const | ||||
|       -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_items(const std::string &api_path, | ||||
|                                          directory_item_list &list) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_list(api_file_list &list, | ||||
|                                    std::string &marker) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_size(const std::string &api_path, | ||||
|                                    std::uint64_t &file_size) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_filesystem_item(const std::string &api_path, | ||||
|                                          bool directory, | ||||
|                                          filesystem_item &fsi) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_filesystem_item_and_file(const std::string &api_path, | ||||
|                                                   api_file &file, | ||||
|                                                   filesystem_item &fsi) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_filesystem_item_from_source_path(const std::string &source_path, | ||||
|                                        filesystem_item &fsi) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_pinned_files() const | ||||
|       -> std::vector<std::string> override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    api_meta_map &meta) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_item_meta(const std::string &api_path, | ||||
|                                    const std::string &key, | ||||
|                                    std::string &value) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_provider_type() const -> provider_type override { | ||||
|     return type; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto is_directory(const std::string &api_path, | ||||
|                                   bool &exists) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto is_file_writeable(const std::string &api_path) const | ||||
|       -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto is_online() const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto is_read_only() const -> bool override { return true; } | ||||
|  | ||||
|   [[nodiscard]] auto is_rename_supported() const -> bool override { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto read_file_bytes(const std::string &api_path, | ||||
|                                      std::size_t size, std::uint64_t offset, | ||||
|                                      data_buffer &data, | ||||
|                                      stop_type &stop_requested) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_directory(const std::string & /*api_path*/) | ||||
|       -> api_error override { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto remove_file(const std::string & /*api_path*/) | ||||
|       -> api_error override { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto remove_item_meta(const std::string & /*api_path*/, | ||||
|                                       const std::string & /*key*/) | ||||
|       -> api_error override { | ||||
|     return api_error::success; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto rename_file(const std::string & /*from_api_path*/, | ||||
|                                  const std::string & /*to_api_path*/) | ||||
|       -> api_error override { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto set_item_meta(const std::string & /*api_path*/, | ||||
|                                    const std::string & /*key*/, | ||||
|                                    const std::string & /*value*/) | ||||
|       -> api_error override { | ||||
|     return api_error::success; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto set_item_meta(const std::string & /*api_path*/, | ||||
|                                    const api_meta_map & /*meta*/) | ||||
|       -> api_error override { | ||||
|     return api_error::success; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto start(api_item_added_callback api_item_added, | ||||
|                            i_file_manager *mgr) -> bool override; | ||||
|  | ||||
|   void stop() override; | ||||
|  | ||||
|   [[nodiscard]] auto upload_file(const std::string & /*api_path*/, | ||||
|                                  const std::string & /*source_path*/, | ||||
|                                  stop_type & /*stop_requested*/) | ||||
|       -> api_error override { | ||||
|     return api_error::not_implemented; | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_PROVIDERS_ENCRYPT_ENCRYPT_PROVIDER_HPP_ | ||||
							
								
								
									
										158
									
								
								repertory/librepertory/include/providers/i_provider.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								repertory/librepertory/include/providers/i_provider.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_PROVIDERS_I_PROVIDER_HPP_ | ||||
| #define REPERTORY_INCLUDE_PROVIDERS_I_PROVIDER_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_file_manager; | ||||
|  | ||||
| class i_provider { | ||||
|   INTERFACE_SETUP(i_provider); | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] virtual auto create_directory(const std::string &api_path, | ||||
|                                               api_meta_map &meta) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   create_directory_clone_source_meta(const std::string &source_api_path, | ||||
|                                      const std::string &api_path) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto create_file(const std::string &api_path, | ||||
|                                          api_meta_map &meta) -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_api_path_from_source(const std::string &source_path, | ||||
|                            std::string &api_path) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_directory_item_count(const std::string &api_path) const | ||||
|       -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_directory_items(const std::string &api_path, | ||||
|                       directory_item_list &list) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_file(const std::string &api_path, | ||||
|                                       api_file &file) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_file_list(api_file_list &list, | ||||
|                                            std::string &marker) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_file_size(const std::string &api_path, | ||||
|                                            std::uint64_t &file_size) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_filesystem_item(const std::string &api_path, | ||||
|                                                  bool directory, | ||||
|                                                  filesystem_item &fsi) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_filesystem_item_and_file(const std::string &api_path, api_file &file, | ||||
|                                filesystem_item &fsi) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   get_filesystem_item_from_source_path(const std::string &source_path, | ||||
|                                        filesystem_item &fsi) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_item_meta(const std::string &api_path, | ||||
|                                            api_meta_map &meta) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_item_meta(const std::string &api_path, | ||||
|                                            const std::string &key, | ||||
|                                            std::string &value) const | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_pinned_files() const | ||||
|       -> std::vector<std::string> = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_provider_type() const -> provider_type = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_total_drive_space() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_total_item_count() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto get_used_drive_space() const -> std::uint64_t = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_directory(const std::string &api_path, | ||||
|                                           bool &exists) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_file(const std::string &api_path, | ||||
|                                      bool &exists) const -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   is_file_writeable(const std::string &api_path) const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_online() const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_read_only() const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto is_rename_supported() const -> bool = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto | ||||
|   read_file_bytes(const std::string &api_path, std::size_t size, | ||||
|                   std::uint64_t offset, data_buffer &data, | ||||
|                   stop_type &stop_requested) -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_directory(const std::string &api_path) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_file(const std::string &api_path) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto remove_item_meta(const std::string &api_path, | ||||
|                                               const std::string &key) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto rename_file(const std::string &from_api_path, | ||||
|                                          const std::string &to_api_path) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto set_item_meta(const std::string &api_path, | ||||
|                                            const std::string &key, | ||||
|                                            const std::string &value) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto set_item_meta(const std::string &api_path, | ||||
|                                            const api_meta_map &meta) | ||||
|       -> api_error = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto start(api_item_added_callback api_item_added, | ||||
|                                    i_file_manager *mgr) -> bool = 0; | ||||
|  | ||||
|   virtual void stop() = 0; | ||||
|  | ||||
|   [[nodiscard]] virtual auto upload_file(const std::string &api_path, | ||||
|                                          const std::string &source_path, | ||||
|                                          stop_type &stop_requested) | ||||
|       -> api_error = 0; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_PROVIDERS_I_PROVIDER_HPP_ | ||||
							
								
								
									
										36
									
								
								repertory/librepertory/include/providers/provider.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								repertory/librepertory/include/providers/provider.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_PROVIDERS_PROVIDER_HPP_ | ||||
| #define REPERTORY_INCLUDE_PROVIDERS_PROVIDER_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
| class i_provider; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| create_provider(const provider_type &prov, | ||||
|                 app_config &config) -> std::unique_ptr<i_provider>; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_PROVIDERS_PROVIDER_HPP_ | ||||
							
								
								
									
										157
									
								
								repertory/librepertory/include/providers/s3/s3_provider.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								repertory/librepertory/include/providers/s3/s3_provider.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_PROVIDERS_S3_S3_PROVIDER_HPP_ | ||||
| #define REPERTORY_INCLUDE_PROVIDERS_S3_S3_PROVIDER_HPP_ | ||||
|  | ||||
| #include "providers/base_provider.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
| class i_file_manager; | ||||
| class i_http_comm; | ||||
| struct head_object_result; | ||||
|  | ||||
| class s3_provider final : public base_provider { | ||||
| public: | ||||
|   static const constexpr auto type{provider_type::s3}; | ||||
|  | ||||
| public: | ||||
|   s3_provider(app_config &config, i_http_comm &comm); | ||||
|  | ||||
|   ~s3_provider() override = default; | ||||
|  | ||||
| public: | ||||
|   s3_provider(const s3_provider &) = delete; | ||||
|   s3_provider(s3_provider &&) = delete; | ||||
|   auto operator=(const s3_provider &) -> s3_provider & = delete; | ||||
|   auto operator=(s3_provider &&) -> s3_provider & = delete; | ||||
|  | ||||
| private: | ||||
|   s3_config s3_config_; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto add_if_not_found(api_file &file, | ||||
|                                       const std::string &object_name) const | ||||
|       -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto create_file_extra(const std::string &api_path, | ||||
|                                        api_meta_map &meta) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto create_path_directories(const std::string &api_path, | ||||
|                                              const std::string &key) const | ||||
|       -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto decrypt_object_name(std::string &object_name) const | ||||
|       -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto get_last_modified(bool directory, | ||||
|                                        const std::string &api_path) const | ||||
|       -> std::uint64_t; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_object_info(bool directory, const std::string &api_path, | ||||
|                   bool &is_encrypted, std::string &object_name, | ||||
|                   head_object_result &result) const -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_object_list(std::string &response_data, long &response_code, | ||||
|                   std::optional<std::string> delimiter = std::nullopt, | ||||
|                   std::optional<std::string> prefix = std::nullopt, | ||||
|                   std::optional<std::string> token = std::nullopt) const | ||||
|       -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto get_s3_config() const -> const s3_config & { | ||||
|     return s3_config_; | ||||
|   } | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto create_directory_impl(const std::string &api_path, | ||||
|                                            api_meta_map &meta) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_items_impl(const std::string &api_path, | ||||
|                                               directory_item_list &list) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_directory_impl(const std::string &api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_file_impl(const std::string &api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto upload_file_impl(const std::string &api_path, | ||||
|                                       const std::string &source_path, | ||||
|                                       stop_type &stop_requested) | ||||
|       -> api_error override; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] static auto convert_api_date(std::string_view date) | ||||
|       -> std::uint64_t; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const | ||||
|       -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_list(api_file_list &list, | ||||
|                                    std::string &marker) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_provider_type() const -> provider_type override { | ||||
|     return type; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto is_directory(const std::string &api_path, | ||||
|                                   bool &exists) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto is_online() const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto is_rename_supported() const -> bool override { | ||||
|     return false; | ||||
|   }; | ||||
|  | ||||
|   [[nodiscard]] auto read_file_bytes(const std::string &api_path, | ||||
|                                      std::size_t size, std::uint64_t offset, | ||||
|                                      data_buffer &data, | ||||
|                                      stop_type &stop_requested) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto rename_file(const std::string &from_api_path, | ||||
|                                  const std::string &to_api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto start(api_item_added_callback api_item_added, | ||||
|                            i_file_manager *mgr) -> bool override; | ||||
|  | ||||
|   void stop() override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_PROVIDERS_S3_S3_PROVIDER_HPP_ | ||||
							
								
								
									
										128
									
								
								repertory/librepertory/include/providers/sia/sia_provider.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								repertory/librepertory/include/providers/sia/sia_provider.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_PROVIDERS_SIA_SIA_PROVIDER_HPP_ | ||||
| #define REPERTORY_INCLUDE_PROVIDERS_SIA_SIA_PROVIDER_HPP_ | ||||
|  | ||||
| #include "providers/base_provider.hpp" | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
| class i_file_manager; | ||||
| class i_http_comm; | ||||
|  | ||||
| class sia_provider : public base_provider { | ||||
| public: | ||||
|   static const constexpr auto type{provider_type::sia}; | ||||
|  | ||||
| public: | ||||
|   sia_provider(app_config &config, i_http_comm &comm); | ||||
|  | ||||
|   ~sia_provider() override = default; | ||||
|  | ||||
| public: | ||||
|   sia_provider(const sia_provider &) = delete; | ||||
|   sia_provider(sia_provider &&) = delete; | ||||
|   auto operator=(const sia_provider &) -> sia_provider & = delete; | ||||
|   auto operator=(sia_provider &&) -> sia_provider & = delete; | ||||
|  | ||||
| private: | ||||
|   sia_config sia_config_; | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto get_object_info(const std::string &api_path, | ||||
|                                      json &object_info) const -> api_error; | ||||
|  | ||||
|   [[nodiscard]] auto get_object_list(const std::string &api_path, | ||||
|                                      nlohmann::json &object_list) const -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto get_sia_config() const -> const auto & { | ||||
|     return sia_config_; | ||||
|   } | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto create_directory_impl(const std::string &api_path, | ||||
|                                            api_meta_map &meta) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_directory_items_impl(const std::string &api_path, | ||||
|                                               directory_item_list &list) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_directory_impl(const std::string &api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto remove_file_impl(const std::string &api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto upload_file_impl(const std::string &api_path, | ||||
|                                       const std::string &source_path, | ||||
|                                       stop_type &stop_requested) | ||||
|       -> api_error override; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const | ||||
|       -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_file_list(api_file_list &list, | ||||
|                                    std::string &marker) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto get_provider_type() const -> provider_type override { | ||||
|     return type; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; | ||||
|  | ||||
|   [[nodiscard]] auto is_directory(const std::string &api_path, | ||||
|                                   bool &exists) const -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto is_online() const -> bool override; | ||||
|  | ||||
|   [[nodiscard]] auto is_rename_supported() const -> bool override { | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto read_file_bytes(const std::string &api_path, | ||||
|                                      std::size_t size, std::uint64_t offset, | ||||
|                                      data_buffer &buffer, | ||||
|                                      stop_type &stop_requested) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto rename_file(const std::string &from_api_path, | ||||
|                                  const std::string &to_api_path) | ||||
|       -> api_error override; | ||||
|  | ||||
|   [[nodiscard]] auto start(api_item_added_callback api_item_added, | ||||
|                            i_file_manager *mgr) -> bool override; | ||||
|  | ||||
|   void stop() override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_PROVIDERS_SIA_SIA_PROVIDER_HPP_ | ||||
							
								
								
									
										65
									
								
								repertory/librepertory/include/rpc/client/client.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								repertory/librepertory/include/rpc/client/client.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_RPC_CLIENT_CLIENT_HPP_ | ||||
| #define REPERTORY_INCLUDE_RPC_CLIENT_CLIENT_HPP_ | ||||
|  | ||||
| #include "types/rpc.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_; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto get_drive_information() -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto get_config() -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_config_value_by_name(const std::string &name) -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   get_directory_items(const std::string &api_path) -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto get_open_files() -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto get_pinned_files() -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto pin_file(const std::string &api_file) -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto pinned_status(const std::string &api_file) -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto | ||||
|   set_config_value_by_name(const std::string &name, | ||||
|                            const std::string &value) -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto unmount() -> rpc_response; | ||||
|  | ||||
|   [[nodiscard]] auto unpin_file(const std::string &api_file) -> rpc_response; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_RPC_CLIENT_CLIENT_HPP_ | ||||
							
								
								
									
										67
									
								
								repertory/librepertory/include/rpc/server/full_server.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								repertory/librepertory/include/rpc/server/full_server.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_RPC_SERVER_FULL_SERVER_HPP_ | ||||
| #define REPERTORY_INCLUDE_RPC_SERVER_FULL_SERVER_HPP_ | ||||
|  | ||||
| #include "rpc/server/server.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class i_file_manager; | ||||
| class i_provider; | ||||
|  | ||||
| class full_server final : public server { | ||||
| public: | ||||
|   explicit full_server(app_config &config, i_provider &provider, | ||||
|                        i_file_manager &fm); | ||||
|  | ||||
|   ~full_server() override = default; | ||||
|  | ||||
| private: | ||||
|   i_provider &provider_; | ||||
|   i_file_manager &fm_; | ||||
|  | ||||
| private: | ||||
|   void handle_get_directory_items(const httplib::Request &req, | ||||
|                                   httplib::Response &res); | ||||
|  | ||||
|   void handle_get_drive_information(const httplib::Request &req, | ||||
|                                     httplib::Response &res); | ||||
|  | ||||
|   void handle_get_open_files(const httplib::Request &req, | ||||
|                              httplib::Response &res); | ||||
|  | ||||
|   void handle_get_pinned_files(const httplib::Request &req, | ||||
|                                httplib::Response &res); | ||||
|  | ||||
|   void handle_get_pinned_status(const httplib::Request &req, | ||||
|                                 httplib::Response &res); | ||||
|  | ||||
|   void handle_pin_file(const httplib::Request &req, httplib::Response &res); | ||||
|  | ||||
|   void handle_unpin_file(const httplib::Request &req, httplib::Response &res); | ||||
|  | ||||
| protected: | ||||
|   void initialize(httplib::Server &inst) override; | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_RPC_SERVER_FULL_SERVER_HPP_ | ||||
							
								
								
									
										75
									
								
								repertory/librepertory/include/rpc/server/server.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								repertory/librepertory/include/rpc/server/server.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_RPC_SERVER_SERVER_HPP_ | ||||
| #define REPERTORY_INCLUDE_RPC_SERVER_SERVER_HPP_ | ||||
|  | ||||
| #include "types/rpc.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class server { | ||||
| public: | ||||
|   explicit server(app_config &config); | ||||
|  | ||||
|   virtual ~server() { stop(); } | ||||
|  | ||||
| private: | ||||
|   app_config &config_; | ||||
|   std::unique_ptr<httplib::Server> server_; | ||||
|   std::unique_ptr<std::thread> server_thread_; | ||||
|   std::mutex start_stop_mutex_; | ||||
|   std::atomic<bool> started_ = false; | ||||
|  | ||||
| private: | ||||
|   // [[nodiscard]] bool check_authorization(const httpserver::http_request | ||||
|   // &request); | ||||
|  | ||||
|   [[nodiscard]] auto check_authorization(const httplib::Request &req) -> bool; | ||||
|  | ||||
|   void handle_get_config(const httplib::Request &req, httplib::Response &res); | ||||
|  | ||||
|   void handle_get_config_value_by_name(const httplib::Request &req, | ||||
|                                        httplib::Response &res); | ||||
|  | ||||
|   void handle_set_config_value_by_name(const httplib::Request &req, | ||||
|                                        httplib::Response &res); | ||||
|  | ||||
|   void handle_unmount(const httplib::Request &req, httplib::Response &res); | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto get_config() -> app_config & { return config_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_config() const -> const app_config & { | ||||
|     return config_; | ||||
|   } | ||||
|  | ||||
|   virtual void initialize(httplib::Server &inst); | ||||
|  | ||||
| public: | ||||
|   void start(); | ||||
|  | ||||
|   void stop(); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_RPC_SERVER_SERVER_HPP_ | ||||
							
								
								
									
										267
									
								
								repertory/librepertory/include/types/remote.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								repertory/librepertory/include/types/remote.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,267 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_TYPES_REMOTE_HPP_ | ||||
| #define REPERTORY_INCLUDE_TYPES_REMOTE_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| inline constexpr const auto PACKET_SERVICE_FUSE{1U}; | ||||
| inline constexpr const auto PACKET_SERVICE_WINFSP{2U}; | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| inline constexpr const auto PACKET_SERVICE_FLAGS{PACKET_SERVICE_WINFSP}; | ||||
| #else  // !defined(_WIN32) | ||||
| inline constexpr const auto PACKET_SERVICE_FLAGS{PACKET_SERVICE_FUSE}; | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
| constexpr const auto default_remote_client_pool_size{20U}; | ||||
| constexpr const auto default_remote_max_connections{20U}; | ||||
| constexpr const auto default_remote_receive_timeout_ms{120U * 1000U}; | ||||
| constexpr const auto default_remote_send_timeout_ms{30U * 1000U}; | ||||
|  | ||||
| namespace repertory::remote { | ||||
| struct remote_config final { | ||||
|   std::uint16_t api_port{}; | ||||
|   std::string encryption_token; | ||||
|   std::string host_name_or_ip; | ||||
|   std::uint8_t max_connections{default_remote_max_connections}; | ||||
|   std::uint32_t recv_timeout_ms{default_remote_receive_timeout_ms}; | ||||
|   std::uint32_t send_timeout_ms{default_remote_send_timeout_ms}; | ||||
|  | ||||
|   auto operator==(const remote_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return api_port == cfg.api_port && | ||||
|              encryption_token == cfg.encryption_token && | ||||
|              host_name_or_ip == cfg.host_name_or_ip && | ||||
|              max_connections == cfg.max_connections && | ||||
|              recv_timeout_ms == cfg.recv_timeout_ms && | ||||
|              send_timeout_ms == cfg.send_timeout_ms; | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   auto operator!=(const remote_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return not(cfg == *this); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| struct remote_mount final { | ||||
|   std::uint16_t api_port{}; | ||||
|   std::uint8_t client_pool_size{default_remote_client_pool_size}; | ||||
|   bool enable{false}; | ||||
|   std::string encryption_token; | ||||
|  | ||||
|   auto operator==(const remote_mount &cfg) const noexcept -> bool { | ||||
|     if (&cfg == this) { | ||||
|       return true; | ||||
|     } | ||||
|  | ||||
|     return api_port == cfg.api_port && | ||||
|            client_pool_size == cfg.client_pool_size && enable == cfg.enable && | ||||
|            encryption_token == cfg.encryption_token; | ||||
|   } | ||||
|  | ||||
|   auto operator!=(const remote_mount &cfg) const noexcept -> bool { | ||||
|     if (&cfg == this) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     return not(cfg == *this); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| using block_count = std::uint64_t; | ||||
| using block_size = std::uint32_t; | ||||
| using file_handle = std::uint64_t; | ||||
| using file_mode = std::uint16_t; | ||||
| using file_nlink = std::uint16_t; | ||||
| using file_offset = std::uint64_t; | ||||
| using file_size = std::uint64_t; | ||||
| using file_time = std::uint64_t; | ||||
| using group_id = std::uint32_t; | ||||
| using user_id = std::uint32_t; | ||||
|  | ||||
| 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, | ||||
| }; | ||||
|  | ||||
| #if defined(__GNUG__) | ||||
| __attribute__((unused)) | ||||
| #endif // defined(__GNUG__) | ||||
| inline auto | ||||
| operator|(const open_flags &flag_1, const open_flags &flag_2) -> open_flags { | ||||
|   using flag_t = std::underlying_type_t<open_flags>; | ||||
|   return static_cast<open_flags>(static_cast<flag_t>(flag_1) | | ||||
|                                  static_cast<flag_t>(flag_2)); | ||||
| } | ||||
|  | ||||
| #if defined(__GNUG__) | ||||
| __attribute__((unused)) | ||||
| #endif // defined(__GNUG__) | ||||
| inline auto | ||||
| operator|=(open_flags &flag_1, const open_flags &flag_2) -> open_flags & { | ||||
|   flag_1 = flag_1 | flag_2; | ||||
|   return flag_1; | ||||
| } | ||||
|  | ||||
| #if defined(__GNUG__) | ||||
| __attribute__((unused)) | ||||
| #endif // defined(__GNUG__) | ||||
| inline auto | ||||
| operator&(const open_flags &flag_1, const open_flags &flag_2) -> open_flags { | ||||
|   using flag_t = std::underlying_type_t<open_flags>; | ||||
|   return static_cast<open_flags>(static_cast<flag_t>(flag_1) & | ||||
|                                  static_cast<flag_t>(flag_2)); | ||||
| } | ||||
|  | ||||
| #pragma pack(1) | ||||
| struct file_info final { | ||||
|   UINT32 FileAttributes{}; | ||||
|   UINT32 ReparseTag{}; | ||||
|   UINT64 AllocationSize{}; | ||||
|   UINT64 FileSize{}; | ||||
|   UINT64 CreationTime{}; | ||||
|   UINT64 LastAccessTime{}; | ||||
|   UINT64 LastWriteTime{}; | ||||
|   UINT64 ChangeTime{}; | ||||
|   UINT64 IndexNumber{}; | ||||
|   UINT32 HardLinks{}; | ||||
|   UINT32 EaSize{}; | ||||
| }; | ||||
|  | ||||
| struct setattr_x final { | ||||
|   std::int32_t valid{}; | ||||
|   file_mode mode{}; | ||||
|   user_id uid{}; | ||||
|   group_id gid{}; | ||||
|   file_size size{}; | ||||
|   file_time acctime{}; | ||||
|   file_time modtime{}; | ||||
|   file_time crtime{}; | ||||
|   file_time chgtime{}; | ||||
|   file_time bkuptime{}; | ||||
|   std::uint32_t flags{}; | ||||
| }; | ||||
|  | ||||
| struct stat final { | ||||
|   file_mode st_mode{}; | ||||
|   file_nlink st_nlink{}; | ||||
|   user_id st_uid{}; | ||||
|   group_id st_gid{}; | ||||
|   file_time st_atimespec{}; | ||||
|   file_time st_mtimespec{}; | ||||
|   file_time st_ctimespec{}; | ||||
|   file_time st_birthtimespec{}; | ||||
|   file_size st_size{}; | ||||
|   block_count st_blocks{}; | ||||
|   block_size st_blksize{}; | ||||
|   std::uint32_t st_flags{}; | ||||
| }; | ||||
|  | ||||
| struct statfs { | ||||
|   std::uint64_t f_bavail{}; | ||||
|   std::uint64_t f_bfree{}; | ||||
|   std::uint64_t f_blocks{}; | ||||
|   std::uint64_t f_favail{}; | ||||
|   std::uint64_t f_ffree{}; | ||||
|   std::uint64_t f_files{}; | ||||
| }; | ||||
|  | ||||
| struct statfs_x final : public statfs { | ||||
|   std::array<char, 1024U> f_mntfromname{}; | ||||
| }; | ||||
| #pragma pack() | ||||
|  | ||||
| #if !defined(_WIN32) | ||||
| [[nodiscard]] auto create_open_flags(std::uint32_t flags) -> open_flags; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| create_os_open_flags(const open_flags &flags) -> std::uint32_t; | ||||
| #endif // !defined(_WIN32) | ||||
| } // namespace repertory::remote | ||||
|  | ||||
| NLOHMANN_JSON_NAMESPACE_BEGIN | ||||
| template <> struct adl_serializer<repertory::remote::remote_config> { | ||||
|   static void to_json(json &data, | ||||
|                       const repertory::remote::remote_config &value) { | ||||
|     data[repertory::JSON_API_PORT] = value.api_port; | ||||
|     data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token; | ||||
|     data[repertory::JSON_HOST_NAME_OR_IP] = value.host_name_or_ip; | ||||
|     data[repertory::JSON_MAX_CONNECTIONS] = value.max_connections; | ||||
|     data[repertory::JSON_RECV_TIMEOUT_MS] = value.recv_timeout_ms; | ||||
|     data[repertory::JSON_SEND_TIMEOUT_MS] = value.send_timeout_ms; | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, | ||||
|                         repertory::remote::remote_config &value) { | ||||
|     data.at(repertory::JSON_API_PORT).get_to(value.api_port); | ||||
|     data.at(repertory::JSON_ENCRYPTION_TOKEN).get_to(value.encryption_token); | ||||
|     data.at(repertory::JSON_HOST_NAME_OR_IP).get_to(value.host_name_or_ip); | ||||
|     data.at(repertory::JSON_MAX_CONNECTIONS).get_to(value.max_connections); | ||||
|     data.at(repertory::JSON_RECV_TIMEOUT_MS).get_to(value.recv_timeout_ms); | ||||
|     data.at(repertory::JSON_SEND_TIMEOUT_MS).get_to(value.send_timeout_ms); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<repertory::remote::remote_mount> { | ||||
|   static void to_json(json &data, | ||||
|                       const repertory::remote::remote_mount &value) { | ||||
|     data[repertory::JSON_API_PORT] = value.api_port; | ||||
|     data[repertory::JSON_CLIENT_POOL_SIZE] = value.client_pool_size; | ||||
|     data[repertory::JSON_ENABLE_REMOTE_MOUNT] = value.enable; | ||||
|     data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token; | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, | ||||
|                         repertory::remote::remote_mount &value) { | ||||
|     data.at(repertory::JSON_API_PORT).get_to(value.api_port); | ||||
|     data.at(repertory::JSON_CLIENT_POOL_SIZE).get_to(value.client_pool_size); | ||||
|     data.at(repertory::JSON_ENABLE_REMOTE_MOUNT).get_to(value.enable); | ||||
|     data.at(repertory::JSON_ENCRYPTION_TOKEN).get_to(value.encryption_token); | ||||
|   } | ||||
| }; | ||||
| NLOHMANN_JSON_NAMESPACE_END | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_TYPES_REMOTE_HPP_ | ||||
							
								
								
									
										655
									
								
								repertory/librepertory/include/types/repertory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										655
									
								
								repertory/librepertory/include/types/repertory.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,655 @@ | ||||
| /* | ||||
|   Copyright <2018-2023> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_TYPES_REPERTORY_HPP_ | ||||
| #define REPERTORY_INCLUDE_TYPES_REPERTORY_HPP_ | ||||
|  | ||||
| namespace repertory { | ||||
| constexpr const auto default_api_auth_size{48U}; | ||||
| constexpr const auto default_download_timeout_ces{30U}; | ||||
| constexpr const auto default_eviction_delay_mins{1U}; | ||||
| constexpr const auto default_high_freq_interval_secs{30U}; | ||||
| constexpr const auto default_low_freq_interval_secs{0U * 60U}; | ||||
| constexpr const auto default_max_cache_size_bytes{ | ||||
|     std::uint64_t(20UL * 1024UL * 1024UL * 1024UL), | ||||
| }; | ||||
| constexpr const auto default_max_upload_count{5U}; | ||||
| constexpr const auto default_med_freq_interval_secs{2U * 60U}; | ||||
| constexpr const auto default_online_check_retry_secs{60U}; | ||||
| constexpr const auto default_orphaned_file_retention_days{15U}; | ||||
| constexpr const auto default_retry_read_count{6U}; | ||||
| constexpr const auto default_ring_buffer_file_size{512U}; | ||||
| constexpr const auto default_task_wait_ms{100U}; | ||||
| constexpr const auto default_timeout_ms{60000U}; | ||||
| constexpr const auto max_orphaned_file_retention_days{std::uint16_t(31U)}; | ||||
| constexpr const auto max_ring_buffer_file_size{std::uint16_t(1024U)}; | ||||
| constexpr const auto min_cache_size_bytes{ | ||||
|     std::uint64_t(100UL * 1024UL * 1024UL)}; | ||||
| constexpr const auto min_download_timeout_secs{std::uint8_t(5U)}; | ||||
| constexpr const auto min_online_check_retry_secs{std::uint16_t(15U)}; | ||||
| constexpr const auto min_orphaned_file_retention_days{std::uint16_t(1U)}; | ||||
| constexpr const auto min_retry_read_count{std::uint16_t(2U)}; | ||||
| constexpr const auto min_ring_buffer_file_size{std::uint16_t(64U)}; | ||||
| constexpr const auto min_task_wait_ms{std::uint16_t(50U)}; | ||||
|  | ||||
| template <typename data_t> class atomic final { | ||||
| public: | ||||
|   atomic() : mtx_(std::make_shared<std::mutex>()) {} | ||||
|  | ||||
|   atomic(const atomic &at_data) | ||||
|       : data_(at_data.load()), mtx_(std::make_shared<std::mutex>()) {} | ||||
|  | ||||
|   atomic(data_t data) | ||||
|       : data_(std::move(data)), mtx_(std::make_shared<std::mutex>()) {} | ||||
|  | ||||
|   atomic(atomic &&) = default; | ||||
|  | ||||
|   ~atomic() = default; | ||||
|  | ||||
| private: | ||||
|   data_t data_; | ||||
|   std::shared_ptr<std::mutex> mtx_; | ||||
|  | ||||
| public: | ||||
|   [[nodiscard]] auto load() const -> data_t { | ||||
|     mutex_lock lock(*mtx_); | ||||
|     return data_; | ||||
|   } | ||||
|  | ||||
|   auto store(data_t data) -> data_t { | ||||
|     mutex_lock lock(*mtx_); | ||||
|     data_ = std::move(data); | ||||
|     return data_; | ||||
|   } | ||||
|  | ||||
|   auto operator=(const atomic &at_data) -> atomic & { | ||||
|     if (&at_data == this) { | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     store(at_data.load()); | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|   auto operator=(atomic &&) -> atomic & = default; | ||||
|  | ||||
|   auto operator=(data_t data) -> atomic & { | ||||
|     if (&data == &data_) { | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     store(std::move(data)); | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto operator==(const atomic &at_data) const -> bool { | ||||
|     if (&at_data == this) { | ||||
|       return true; | ||||
|     } | ||||
|  | ||||
|     mutex_lock lock(*mtx_); | ||||
|     return at_data.load() == data_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto operator==(const data_t &data) const -> bool { | ||||
|     if (&data == &data_) { | ||||
|       return true; | ||||
|     } | ||||
|  | ||||
|     mutex_lock lock(*mtx_); | ||||
|     return data == data_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto operator!=(const atomic &at_data) const -> bool { | ||||
|     if (&at_data == this) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     mutex_lock lock(*mtx_); | ||||
|     return at_data.load() != data_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto operator!=(const data_t &data) const -> bool { | ||||
|     if (&data == &data_) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     mutex_lock lock(*mtx_); | ||||
|     return data != data_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] operator data_t() const { return load(); } | ||||
| }; | ||||
|  | ||||
| inline constexpr const auto max_time{ | ||||
|     std::numeric_limits<std::uint64_t>::max(), | ||||
| }; | ||||
|  | ||||
| inline constexpr const std::string META_ACCESSED{"accessed"}; | ||||
| inline constexpr const std::string META_ATTRIBUTES{"attributes"}; | ||||
| inline constexpr const std::string META_BACKUP{"backup"}; | ||||
| inline constexpr const std::string META_CHANGED{"changed"}; | ||||
| inline constexpr const std::string META_CREATION{"creation"}; | ||||
| inline constexpr const std::string META_DIRECTORY{"directory"}; | ||||
| inline constexpr const std::string META_GID{"gid"}; | ||||
| inline constexpr const std::string META_KEY{"key"}; | ||||
| inline constexpr const std::string META_MODE{"mode"}; | ||||
| inline constexpr const std::string META_MODIFIED{"modified"}; | ||||
| inline constexpr const std::string META_OSXFLAGS{"flags"}; | ||||
| inline constexpr const std::string META_PINNED{"pinned"}; | ||||
| inline constexpr const std::string META_SIZE{"size"}; | ||||
| inline constexpr const std::string META_SOURCE{"source"}; | ||||
| inline constexpr const std::string META_UID{"uid"}; | ||||
| inline constexpr const std::string META_WRITTEN{"written"}; | ||||
|  | ||||
| inline constexpr const std::array<std::string, 16U> META_USED_NAMES = { | ||||
|     META_ACCESSED, META_ATTRIBUTES, META_BACKUP,   META_CHANGED, | ||||
|     META_CREATION, META_DIRECTORY,  META_GID,      META_KEY, | ||||
|     META_MODE,     META_MODIFIED,   META_OSXFLAGS, META_PINNED, | ||||
|     META_SIZE,     META_SOURCE,     META_UID,      META_WRITTEN, | ||||
| }; | ||||
|  | ||||
| using api_meta_map = std::map<std::string, std::string>; | ||||
|  | ||||
| enum class api_error { | ||||
|   success = 0, | ||||
|   access_denied, | ||||
|   bad_address, | ||||
|   buffer_overflow, | ||||
|   buffer_too_small, | ||||
|   cache_not_initialized, | ||||
|   comm_error, | ||||
|   decryption_error, | ||||
|   directory_end_of_files, | ||||
|   directory_exists, | ||||
|   directory_not_empty, | ||||
|   directory_not_found, | ||||
|   download_failed, | ||||
|   download_incomplete, | ||||
|   download_stopped, | ||||
|   empty_ring_buffer_chunk_size, | ||||
|   empty_ring_buffer_size, | ||||
|   error, | ||||
|   file_in_use, | ||||
|   file_size_mismatch, | ||||
|   incompatible_version, | ||||
|   invalid_handle, | ||||
|   invalid_operation, | ||||
|   invalid_ring_buffer_multiple, | ||||
|   invalid_ring_buffer_position, | ||||
|   invalid_ring_buffer_size, | ||||
|   invalid_version, | ||||
|   item_exists, | ||||
|   item_not_found, | ||||
|   more_data, | ||||
|   no_disk_space, | ||||
|   not_implemented, | ||||
|   not_supported, | ||||
|   os_error, | ||||
|   out_of_memory, | ||||
|   permission_denied, | ||||
|   upload_failed, | ||||
|   xattr_buffer_small, | ||||
|   xattr_exists, | ||||
|   xattr_not_found, | ||||
|   xattr_too_big, | ||||
|   ERROR_COUNT | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] auto api_error_from_string(std::string_view str) -> api_error; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| api_error_to_string(const api_error &error) -> const std::string &; | ||||
|  | ||||
| enum class database_type { | ||||
|   rocksdb, | ||||
|   sqlite, | ||||
| }; | ||||
| [[nodiscard]] auto database_type_from_string( | ||||
|     std::string type, | ||||
|     database_type default_type = database_type::rocksdb) -> database_type; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| database_type_to_string(const database_type &type) -> std::string; | ||||
|  | ||||
| enum class download_type { | ||||
|   default_, | ||||
|   direct, | ||||
|   ring_buffer, | ||||
| }; | ||||
| [[nodiscard]] auto download_type_from_string( | ||||
|     std::string type, | ||||
|     download_type default_type = download_type::default_) -> download_type; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| download_type_to_string(const download_type &type) -> std::string; | ||||
|  | ||||
| enum class exit_code : std::int32_t { | ||||
|   success = 0, | ||||
|   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, | ||||
|   init_failed = -18, | ||||
| }; | ||||
|  | ||||
| enum http_error_codes : std::int32_t { | ||||
|   ok = 200, | ||||
|   multiple_choices = 300, | ||||
|   not_found = 404, | ||||
| }; | ||||
|  | ||||
| enum class lock_result { | ||||
|   success, | ||||
|   locked, | ||||
|   failure, | ||||
| }; | ||||
|  | ||||
| enum class provider_type : std::size_t { | ||||
|   sia, | ||||
|   remote, | ||||
|   s3, | ||||
|   encrypt, | ||||
|   unknown, | ||||
| }; | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| struct open_file_data final { | ||||
|   PVOID directory_buffer{nullptr}; | ||||
| }; | ||||
| #else | ||||
| using open_file_data = int; | ||||
| #endif | ||||
|  | ||||
| struct api_file final { | ||||
|   std::string api_path; | ||||
|   std::string api_parent; | ||||
|   std::uint64_t accessed_date{}; | ||||
|   std::uint64_t changed_date{}; | ||||
|   std::uint64_t creation_date{}; | ||||
|   std::uint64_t file_size{}; | ||||
|   std::string key; | ||||
|   std::uint64_t modified_date{}; | ||||
|   std::string source_path; | ||||
| }; | ||||
|  | ||||
| struct directory_item final { | ||||
|   std::string api_path; | ||||
|   std::string api_parent; | ||||
|   bool directory{false}; | ||||
|   std::uint64_t size{}; | ||||
|   api_meta_map meta; | ||||
|   bool resolved{false}; | ||||
| }; | ||||
|  | ||||
| struct encrypt_config final { | ||||
|   std::string encryption_token; | ||||
|   std::string path; | ||||
|  | ||||
|   auto operator==(const encrypt_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return encryption_token == cfg.encryption_token && path == cfg.path; | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   auto operator!=(const encrypt_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return not(cfg == *this); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| struct filesystem_item final { | ||||
|   std::string api_path; | ||||
|   std::string api_parent; | ||||
|   bool directory{false}; | ||||
|   std::uint64_t size{}; | ||||
|   std::string source_path; | ||||
| }; | ||||
|  | ||||
| struct host_config final { | ||||
|   std::string agent_string; | ||||
|   std::string api_password; | ||||
|   std::string api_user; | ||||
|   std::uint16_t api_port; | ||||
|   std::string host_name_or_ip{"localhost"}; | ||||
|   std::string path; | ||||
|   std::string protocol{"http"}; | ||||
|   std::uint32_t timeout_ms{default_timeout_ms}; | ||||
|  | ||||
|   auto operator==(const host_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return agent_string == cfg.agent_string && | ||||
|              api_password == cfg.api_password && api_user == cfg.api_user && | ||||
|              api_port == cfg.api_port && | ||||
|              host_name_or_ip == cfg.host_name_or_ip && path == cfg.path && | ||||
|              protocol == cfg.protocol && timeout_ms == cfg.timeout_ms; | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   auto operator!=(const host_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return not(cfg == *this); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| struct s3_config final { | ||||
|   std::string access_key; | ||||
|   std::string bucket; | ||||
|   std::string encryption_token; | ||||
|   std::string region{"any"}; | ||||
|   std::string secret_key; | ||||
|   std::uint32_t timeout_ms{default_timeout_ms}; | ||||
|   std::string url; | ||||
|   bool use_path_style{false}; | ||||
|   bool use_region_in_url{false}; | ||||
|  | ||||
|   auto operator==(const s3_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return access_key == cfg.access_key && bucket == cfg.bucket && | ||||
|              encryption_token == cfg.encryption_token && region == cfg.region && | ||||
|              secret_key == cfg.secret_key && timeout_ms == cfg.timeout_ms && | ||||
|              url == cfg.url && use_path_style == cfg.use_path_style && | ||||
|              use_region_in_url == cfg.use_region_in_url; | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   auto operator!=(const s3_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return not(cfg == *this); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| struct sia_config final { | ||||
|   std::string bucket; | ||||
|  | ||||
|   auto operator==(const sia_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return bucket == cfg.bucket; | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   auto operator!=(const sia_config &cfg) const noexcept -> bool { | ||||
|     if (&cfg != this) { | ||||
|       return not(cfg == *this); | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| using api_file_list = std::vector<api_file>; | ||||
| using api_file_provider_callback = std::function<void(api_file &)>; | ||||
| using api_item_added_callback = std::function<api_error(bool, api_file &)>; | ||||
| using directory_item_list = std::vector<directory_item>; | ||||
| using meta_provider_callback = std::function<void(directory_item &)>; | ||||
|  | ||||
| inline constexpr const auto JSON_ACCESS_KEY{"AccessKey"}; | ||||
| inline constexpr const auto JSON_AGENT_STRING{"AgentString"}; | ||||
| inline constexpr const auto JSON_API_AUTH{"ApiAuth"}; | ||||
| inline constexpr const auto JSON_API_PARENT{"ApiParent"}; | ||||
| inline constexpr const auto JSON_API_PASSWORD{"ApiPassword"}; | ||||
| inline constexpr const auto JSON_API_PATH{"ApiPath"}; | ||||
| inline constexpr const auto JSON_API_PORT{"ApiPort"}; | ||||
| inline constexpr const auto JSON_API_USER{"ApiUser"}; | ||||
| inline constexpr const auto JSON_BUCKET{"Bucket"}; | ||||
| inline constexpr const auto JSON_CLIENT_POOL_SIZE{"ClientPoolSize"}; | ||||
| inline constexpr const auto JSON_DATABASE_TYPE{"DatabaseType"}; | ||||
| inline constexpr const auto JSON_DIRECTORY{"Directory"}; | ||||
| inline constexpr const auto JSON_DOWNLOAD_TIMEOUT_SECS{ | ||||
|     "DownloadTimeoutSeconds"}; | ||||
| inline constexpr const auto JSON_ENABLE_DRIVE_EVENTS{"EnableDriveEvents"}; | ||||
| inline constexpr const auto JSON_ENABLE_DOWNLOAD_TIMEOUT{ | ||||
|     "EnableDownloadTimeout"}; | ||||
| inline constexpr const auto JSON_ENABLE_MOUNT_MANAGER{"EnableMountManager"}; | ||||
| inline constexpr const auto JSON_ENABLE_REMOTE_MOUNT{"Enable"}; | ||||
| inline constexpr const auto JSON_ENCRYPTION_TOKEN{"EncryptionToken"}; | ||||
| inline constexpr const auto JSON_ENCRYPT_CONFIG{"EncryptConfig"}; | ||||
| inline constexpr const auto JSON_EVENT_LEVEL{"EventLevel"}; | ||||
| inline constexpr const auto JSON_EVICTION_DELAY_MINS{"EvictionDelayMinutes"}; | ||||
| inline constexpr const auto JSON_EVICTION_USE_ACCESS_TIME{ | ||||
|     "EvictionUseAccessedTime"}; | ||||
| inline constexpr const auto JSON_HIGH_FREQ_INTERVAL_SECS{ | ||||
|     "HighFreqIntervalSeconds"}; | ||||
| inline constexpr const auto JSON_HOST_CONFIG{"HostConfig"}; | ||||
| inline constexpr const auto JSON_HOST_NAME_OR_IP{"HostNameOrIp"}; | ||||
| inline constexpr const auto JSON_LOW_FREQ_INTERVAL_SECS{ | ||||
|     "LowFreqIntervalSeconds"}; | ||||
| inline constexpr const auto JSON_MAX_CACHE_SIZE_BYTES{"MaxCacheSizeBytes"}; | ||||
| inline constexpr const auto JSON_MAX_CONNECTIONS{"MaxConnections"}; | ||||
| inline constexpr const auto JSON_MAX_UPLOAD_COUNT{"MaxUploadCount"}; | ||||
| inline constexpr const auto JSON_MED_FREQ_INTERVAL_SECS{ | ||||
|     "MedFreqIntervalSeconds"}; | ||||
| inline constexpr const auto JSON_META{"Meta"}; | ||||
| inline constexpr const auto JSON_ONLINE_CHECK_RETRY_SECS{ | ||||
|     "OnlineCheckRetrySeconds"}; | ||||
| inline constexpr const auto JSON_ORPHANED_FILE_RETENTION_DAYS{ | ||||
|     "OrphanedFileRetentionDays"}; | ||||
| inline constexpr const auto JSON_PATH{"Path"}; | ||||
| inline constexpr const auto JSON_PREFERRED_DOWNLOAD_TYPE{ | ||||
|     "PreferredDownloadType"}; | ||||
| inline constexpr const auto JSON_PROTOCOL{"Protocol"}; | ||||
| inline constexpr const auto JSON_RECV_TIMEOUT_MS{"ReceiveTimeoutMs"}; | ||||
| inline constexpr const auto JSON_REGION{"Region"}; | ||||
| inline constexpr const auto JSON_REMOTE_CONFIG{"RemoteConfig"}; | ||||
| inline constexpr const auto JSON_REMOTE_MOUNT{"RemoteMount"}; | ||||
| inline constexpr const auto JSON_RETRY_READ_COUNT{"RetryReadCount"}; | ||||
| inline constexpr const auto JSON_RING_BUFFER_FILE_SIZE{"RingBufferFileSize"}; | ||||
| inline constexpr const auto JSON_S3_CONFIG{"S3Config"}; | ||||
| inline constexpr const auto JSON_SECRET_KEY{"SecretKey"}; | ||||
| inline constexpr const auto JSON_SEND_TIMEOUT_MS{"SendTimeoutMs"}; | ||||
| inline constexpr const auto JSON_SIA_CONFIG{"SiaConfig"}; | ||||
| inline constexpr const auto JSON_SIZE{"Size"}; | ||||
| inline constexpr const auto JSON_TASK_WAIT_MS{"TaskWaitMs"}; | ||||
| inline constexpr const auto JSON_TIMEOUT_MS{"TimeoutMs"}; | ||||
| inline constexpr const auto JSON_URL{"URL"}; | ||||
| inline constexpr const auto JSON_USE_PATH_STYLE{"UsePathStyle"}; | ||||
| inline constexpr const auto JSON_USE_REGION_IN_URL{"UseRegionInURL"}; | ||||
| inline constexpr const auto JSON_VERSION{"Version"}; | ||||
| } // namespace repertory | ||||
|  | ||||
| NLOHMANN_JSON_NAMESPACE_BEGIN | ||||
| template <> struct adl_serializer<repertory::directory_item> { | ||||
|   static void to_json(json &data, const repertory::directory_item &value) { | ||||
|     data[repertory::JSON_API_PARENT] = value.api_parent; | ||||
|     data[repertory::JSON_API_PATH] = value.api_path; | ||||
|     data[repertory::JSON_DIRECTORY] = value.directory; | ||||
|     data[repertory::JSON_META] = value.meta; | ||||
|     data[repertory::JSON_SIZE] = value.size; | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, repertory::directory_item &value) { | ||||
|     data.at(repertory::JSON_API_PARENT).get_to<std::string>(value.api_parent); | ||||
|     data.at(repertory::JSON_API_PATH).get_to<std::string>(value.api_path); | ||||
|     data.at(repertory::JSON_DIRECTORY).get_to<bool>(value.directory); | ||||
|     data.at(repertory::JSON_META).get_to<repertory::api_meta_map>(value.meta); | ||||
|     data.at(repertory::JSON_SIZE).get_to<std::uint64_t>(value.size); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<repertory::encrypt_config> { | ||||
|   static void to_json(json &data, const repertory::encrypt_config &value) { | ||||
|     data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token; | ||||
|     data[repertory::JSON_PATH] = value.path; | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, repertory::encrypt_config &value) { | ||||
|     data.at(repertory::JSON_ENCRYPTION_TOKEN).get_to(value.encryption_token); | ||||
|     data.at(repertory::JSON_PATH).get_to(value.path); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<repertory::host_config> { | ||||
|   static void to_json(json &data, const repertory::host_config &value) { | ||||
|     data[repertory::JSON_AGENT_STRING] = value.agent_string; | ||||
|     data[repertory::JSON_API_PASSWORD] = value.api_password; | ||||
|     data[repertory::JSON_API_PORT] = value.api_port; | ||||
|     data[repertory::JSON_API_USER] = value.api_user; | ||||
|     data[repertory::JSON_HOST_NAME_OR_IP] = value.host_name_or_ip; | ||||
|     data[repertory::JSON_PATH] = value.path; | ||||
|     data[repertory::JSON_PROTOCOL] = value.protocol; | ||||
|     data[repertory::JSON_TIMEOUT_MS] = value.timeout_ms; | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, repertory::host_config &value) { | ||||
|     data.at(repertory::JSON_AGENT_STRING).get_to(value.agent_string); | ||||
|     data.at(repertory::JSON_API_PASSWORD).get_to(value.api_password); | ||||
|     data.at(repertory::JSON_API_PORT).get_to(value.api_port); | ||||
|     data.at(repertory::JSON_API_USER).get_to(value.api_user); | ||||
|     data.at(repertory::JSON_HOST_NAME_OR_IP).get_to(value.host_name_or_ip); | ||||
|     data.at(repertory::JSON_PATH).get_to(value.path); | ||||
|     data.at(repertory::JSON_PROTOCOL).get_to(value.protocol); | ||||
|     data.at(repertory::JSON_TIMEOUT_MS).get_to(value.timeout_ms); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<repertory::s3_config> { | ||||
|   static void to_json(json &data, const repertory::s3_config &value) { | ||||
|     data[repertory::JSON_ACCESS_KEY] = value.access_key; | ||||
|     data[repertory::JSON_BUCKET] = value.bucket; | ||||
|     data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token; | ||||
|     data[repertory::JSON_REGION] = value.region; | ||||
|     data[repertory::JSON_SECRET_KEY] = value.secret_key; | ||||
|     data[repertory::JSON_TIMEOUT_MS] = value.timeout_ms; | ||||
|     data[repertory::JSON_URL] = value.url; | ||||
|     data[repertory::JSON_USE_PATH_STYLE] = value.use_path_style; | ||||
|     data[repertory::JSON_USE_REGION_IN_URL] = value.use_region_in_url; | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, repertory::s3_config &value) { | ||||
|     data.at(repertory::JSON_ACCESS_KEY).get_to(value.access_key); | ||||
|     data.at(repertory::JSON_BUCKET).get_to(value.bucket); | ||||
|     data.at(repertory::JSON_ENCRYPTION_TOKEN).get_to(value.encryption_token); | ||||
|     data.at(repertory::JSON_REGION).get_to(value.region); | ||||
|     data.at(repertory::JSON_SECRET_KEY).get_to(value.secret_key); | ||||
|     data.at(repertory::JSON_TIMEOUT_MS).get_to(value.timeout_ms); | ||||
|     data.at(repertory::JSON_URL).get_to(value.url); | ||||
|     data.at(repertory::JSON_USE_PATH_STYLE).get_to(value.use_path_style); | ||||
|     data.at(repertory::JSON_USE_REGION_IN_URL).get_to(value.use_region_in_url); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<repertory::sia_config> { | ||||
|   static void to_json(json &data, const repertory::sia_config &value) { | ||||
|     data[repertory::JSON_BUCKET] = value.bucket; | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, repertory::sia_config &value) { | ||||
|     data.at(repertory::JSON_BUCKET).get_to(value.bucket); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename data_t> struct adl_serializer<repertory::atomic<data_t>> { | ||||
|   static void to_json(json &data, const repertory::atomic<data_t> &value) { | ||||
|     data = value.load(); | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, repertory::atomic<data_t> &value) { | ||||
|     value.store(data.get<data_t>()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename primitive_t> | ||||
| struct adl_serializer<std::atomic<primitive_t>> { | ||||
|   static void to_json(json &data, const std::atomic<primitive_t> &value) { | ||||
|     data = value.load(); | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, std::atomic<primitive_t> &value) { | ||||
|     value.store(data.get<primitive_t>()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<std::atomic<repertory::database_type>> { | ||||
|   static void to_json(json &data, | ||||
|                       const std::atomic<repertory::database_type> &value) { | ||||
|     data = repertory::database_type_to_string(value.load()); | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, | ||||
|                         std::atomic<repertory::database_type> &value) { | ||||
|     value.store(repertory::database_type_from_string(data.get<std::string>())); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<std::atomic<repertory::download_type>> { | ||||
|   static void to_json(json &data, | ||||
|                       const std::atomic<repertory::download_type> &value) { | ||||
|     data = repertory::download_type_to_string(value.load()); | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, | ||||
|                         std::atomic<repertory::download_type> &value) { | ||||
|     value.store(repertory::download_type_from_string(data.get<std::string>())); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<repertory::database_type> { | ||||
|   static void to_json(json &data, const repertory::database_type &value) { | ||||
|     data = repertory::database_type_to_string(value); | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, repertory::database_type &value) { | ||||
|     value = repertory::database_type_from_string(data.get<std::string>()); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> struct adl_serializer<repertory::download_type> { | ||||
|   static void to_json(json &data, const repertory::download_type &value) { | ||||
|     data = repertory::download_type_to_string(value); | ||||
|   } | ||||
|  | ||||
|   static void from_json(const json &data, repertory::download_type &value) { | ||||
|     value = repertory::download_type_from_string(data.get<std::string>()); | ||||
|   } | ||||
| }; | ||||
| NLOHMANN_JSON_NAMESPACE_END | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_TYPES_REPERTORY_HPP_ | ||||
							
								
								
									
										59
									
								
								repertory/librepertory/include/types/rpc.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								repertory/librepertory/include/types/rpc.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_TYPES_RPC_HPP_ | ||||
| #define REPERTORY_INCLUDE_TYPES_RPC_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, | ||||
|   http_error, | ||||
| }; | ||||
|  | ||||
| struct rpc_response { | ||||
|   rpc_response_type response_type; | ||||
|   json data; | ||||
| }; | ||||
|  | ||||
| namespace rpc_method { | ||||
| const std::string get_config = "get_config"; | ||||
| const std::string get_config_value_by_name = "get_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 pin_file = "pin_file"; | ||||
| const std::string pinned_status = "pinned_status"; | ||||
| const std::string set_config_value_by_name = "set_config_value_by_name"; | ||||
| const std::string unmount = "unmount"; | ||||
| const std::string unpin_file = "unpin_file"; | ||||
| } // namespace rpc_method | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_TYPES_RPC_HPP_ | ||||
							
								
								
									
										76
									
								
								repertory/librepertory/include/types/s3.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								repertory/librepertory/include/types/s3.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_TYPES_S3_HPP_ | ||||
| #define REPERTORY_INCLUDE_TYPES_S3_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/string.hpp" | ||||
| #include "utils/time.hpp" | ||||
| #include "utils/utils.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| using get_key_callback = std::function<std::string()>; | ||||
|  | ||||
| using get_api_file_token_callback = | ||||
|     std::function<std::string(const std::string &api_path)>; | ||||
|  | ||||
| using get_name_callback = std::function<std::string( | ||||
|     const std::string &key, const std::string &object_name)>; | ||||
|  | ||||
| using get_size_callback = std::function<std::uint64_t()>; | ||||
|  | ||||
| using get_token_callback = std::function<std::string()>; | ||||
|  | ||||
| using set_key_callback = std::function<api_error(const std::string &key)>; | ||||
|  | ||||
| using list_directories_result = api_file_list; | ||||
|  | ||||
| using list_files_result = api_file_list; | ||||
|  | ||||
| using list_objects_result = std::vector<directory_item>; | ||||
|  | ||||
| struct head_object_result { | ||||
|   std::uint64_t content_length{}; | ||||
|   std::string content_type{}; | ||||
|   std::uint64_t last_modified{}; | ||||
|  | ||||
|   inline auto from_headers(http_headers headers) -> head_object_result & { | ||||
|     content_length = utils::string::to_uint64(headers["content-length"]); | ||||
|     content_type = headers["content-type"]; | ||||
|     auto date = headers["last-modified"]; | ||||
|     if (not date.empty()) { | ||||
|       struct tm tm1 {}; | ||||
|       // Mon, 17 Dec 2012 02:14:10 GMT | ||||
| #if defined(_WIN32) | ||||
|       utils::time::strptime(date.c_str(), "%a, %d %b %Y %H:%M:%S %Z", &tm1); | ||||
| #else | ||||
|       strptime(date.c_str(), "%a, %d %b %Y %H:%M:%S %Z", &tm1); | ||||
| #endif | ||||
|       last_modified = static_cast<std::uint64_t>(mktime(&tm1)) * | ||||
|                       utils::time::NANOS_PER_SECOND; | ||||
|     } | ||||
|     return *this; | ||||
|   } | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_TYPES_S3_HPP_ | ||||
							
								
								
									
										33
									
								
								repertory/librepertory/include/types/startup_exception.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								repertory/librepertory/include/types/startup_exception.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_TYPES_STARTUP_EXCEPTION_HPP_ | ||||
| #define REPERTORY_INCLUDE_TYPES_STARTUP_EXCEPTION_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 // REPERTORY_INCLUDE_TYPES_STARTUP_EXCEPTION_HPP_ | ||||
							
								
								
									
										112
									
								
								repertory/librepertory/include/utils/cli_utils.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								repertory/librepertory/include/utils/cli_utils.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_CLI_UTILS_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_CLI_UTILS_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory::utils::cli { | ||||
| using option = std::array<std::string, 2>; | ||||
|  | ||||
| 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 encrypt_option = {"-en", "--encrypt"}; | ||||
| static const option drive_information_option = {"-di", "--drive_information"}; | ||||
| static const option name_option = {"-na", "--name"}; | ||||
| static const option s3_option = {"-s3", "--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 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"}; | ||||
| 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, | ||||
|     encrypt_option, | ||||
|     s3_option, | ||||
|     name_option, | ||||
|     generate_config_option, | ||||
|     get_option, | ||||
|     get_directory_items_option, | ||||
|     get_pinned_files_option, | ||||
|     help_option, | ||||
|     hidden_option, | ||||
|     open_files_option, | ||||
|     password_option, | ||||
|     pin_file_option, | ||||
|     pinned_status_option, | ||||
|     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 &prov, | ||||
|                                  const std::string &data_directory); | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| get_provider_type_from_args(std::vector<const char *> args) -> provider_type; | ||||
|  | ||||
| [[nodiscard]] auto has_option(std::vector<const char *> args, | ||||
|                               const std::string &option_name) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto has_option(std::vector<const char *> args, | ||||
|                               const option &opt) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto parse_option(std::vector<const char *> args, | ||||
|                                 const std::string &option_name, | ||||
|                                 std::uint8_t count) -> std::vector<std::string>; | ||||
|  | ||||
| [[nodiscard]] auto parse_string_option(std::vector<const char *> args, | ||||
|                                        const option &opt, | ||||
|                                        std::string &value) -> exit_code; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| parse_drive_options(std::vector<const char *> args, provider_type &prov, | ||||
|                     std::string &data_directory) -> std::vector<std::string>; | ||||
| } // namespace repertory::utils::cli | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_CLI_UTILS_HPP_ | ||||
							
								
								
									
										95
									
								
								repertory/librepertory/include/utils/error_utils.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								repertory/librepertory/include/utils/error_utils.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_ERROR_UTILS_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_ERROR_UTILS_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory::utils::error { | ||||
| void raise_error(std::string_view function, std::string_view msg); | ||||
|  | ||||
| void raise_error(std::string_view function, const api_error &err, | ||||
|                  std::string_view msg); | ||||
|  | ||||
| void raise_error(std::string_view function, const std::exception &exception); | ||||
|  | ||||
| void raise_error(std::string_view function, const std::exception &exception, | ||||
|                  std::string_view msg); | ||||
|  | ||||
| void raise_error(std::string_view function, std::int64_t err, | ||||
|                  std::string_view msg); | ||||
|  | ||||
| void raise_error(std::string_view function, const json &err, | ||||
|                  std::string_view msg); | ||||
|  | ||||
| void raise_error(std::string_view function, const api_error &err, | ||||
|                  std::string_view file_path, std::string_view msg); | ||||
|  | ||||
| void raise_error(std::string_view function, std::int64_t err, | ||||
|                  std::string_view file_path, std::string_view msg); | ||||
|  | ||||
| void raise_error(std::string_view function, const std::exception &exception, | ||||
|                  std::string_view file_path, std::string_view msg); | ||||
|  | ||||
| void raise_api_path_error(std::string_view function, std::string_view api_path, | ||||
|                           const api_error &err, std::string_view msg); | ||||
|  | ||||
| void raise_api_path_error(std::string_view function, std::string_view api_path, | ||||
|                           const std::exception &exception); | ||||
|  | ||||
| void raise_api_path_error(std::string_view function, std::string_view api_path, | ||||
|                           const std::exception &exception, | ||||
|                           std::string_view msg); | ||||
|  | ||||
| void raise_api_path_error(std::string_view function, std::string_view api_path, | ||||
|                           std::int64_t err, std::string_view msg); | ||||
|  | ||||
| void raise_api_path_error(std::string_view function, std::string_view api_path, | ||||
|                           const json &err, std::string_view msg); | ||||
|  | ||||
| void raise_api_path_error(std::string_view function, std::string_view api_path, | ||||
|                           std::string_view source_path, const api_error &err, | ||||
|                           std::string_view msg); | ||||
|  | ||||
| void raise_api_path_error(std::string_view function, std::string_view api_path, | ||||
|                           std::string_view source_path, std::int64_t err, | ||||
|                           std::string_view msg); | ||||
|  | ||||
| void raise_api_path_error(std::string_view function, std::string_view api_path, | ||||
|                           std::string_view source_path, | ||||
|                           const std::exception &exception, | ||||
|                           std::string_view msg); | ||||
|  | ||||
| void raise_url_error(std::string_view function, std::string_view url, | ||||
|                      CURLcode err, std::string_view msg); | ||||
|  | ||||
| void raise_url_error(std::string_view function, std::string_view url, | ||||
|                      std::string_view source_path, | ||||
|                      const std::exception &exception); | ||||
|  | ||||
| void raise_url_error(std::string_view function, std::string_view url, | ||||
|                      std::string_view source_path, | ||||
|                      const std::exception &exception, std::string_view msg); | ||||
|  | ||||
| } // namespace repertory::utils::error | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_ERROR_UTILS_HPP_ | ||||
							
								
								
									
										38
									
								
								repertory/librepertory/include/utils/file_utils.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								repertory/librepertory/include/utils/file_utils.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_FILE_UTILS_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_FILE_UTILS_HPP_ | ||||
|  | ||||
| #include "utils/file.hpp" | ||||
|  | ||||
| namespace repertory::utils::file { | ||||
| [[nodiscard]] auto | ||||
| get_directory_files(std::string_view path, bool oldest_first, | ||||
|                     bool recursive = false) -> std::deque<std::string>; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| read_file_lines(const std::string &path) -> std::vector<std::string>; | ||||
|  | ||||
| [[nodiscard]] auto reset_modified_time(const std::string &path) -> bool; | ||||
| } // namespace repertory::utils::file | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_FILE_UTILS_HPP_ | ||||
							
								
								
									
										89
									
								
								repertory/librepertory/include/utils/polling.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								repertory/librepertory/include/utils/polling.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_POLLING_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_POLLING_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class polling final { | ||||
| public: | ||||
|   enum struct frequency { | ||||
|     high, | ||||
|     low, | ||||
|     medium, | ||||
|     second, | ||||
|     size, | ||||
|   }; | ||||
|  | ||||
|   struct polling_item final { | ||||
|     std::string name; | ||||
|     frequency freq; | ||||
|     std::function<void(const stop_type &stop_requested)> action; | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   polling(const polling &) = delete; | ||||
|   polling(polling &&) = delete; | ||||
|   auto operator=(const polling &) -> polling & = delete; | ||||
|   auto operator=(polling &&) -> polling & = delete; | ||||
|  | ||||
| private: | ||||
|   polling() = default; | ||||
|  | ||||
|   ~polling() { stop(); } | ||||
|  | ||||
| private: | ||||
|   static polling instance_; | ||||
|  | ||||
| public: | ||||
|   static auto instance() -> polling & { return instance_; } | ||||
|  | ||||
| private: | ||||
|   app_config *config_{nullptr}; | ||||
|   std::array<std::unique_ptr<std::thread>, | ||||
|              static_cast<std::size_t>(frequency::size)> | ||||
|       frequency_threads_; | ||||
|   std::unordered_map<std::string, polling_item> items_; | ||||
|   std::mutex mutex_; | ||||
|   std::condition_variable notify_; | ||||
|   std::mutex start_stop_mutex_; | ||||
|   stop_type stop_requested_{false}; | ||||
|  | ||||
| private: | ||||
|   void frequency_thread(std::function<std::uint32_t()> get_frequency_seconds, | ||||
|                         frequency freq); | ||||
|  | ||||
| public: | ||||
|   void remove_callback(const std::string &name); | ||||
|  | ||||
|   void set_callback(const polling_item &item); | ||||
|  | ||||
|   void start(app_config *config); | ||||
|  | ||||
|   void stop(); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_POLLING_HPP_ | ||||
| @@ -0,0 +1,68 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_SINGLE_THREAD_SERVICE_BASE_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_SINGLE_THREAD_SERVICE_BASE_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class single_thread_service_base { | ||||
| public: | ||||
|   explicit single_thread_service_base(std::string service_name) | ||||
|       : service_name_(std::move(service_name)) {} | ||||
|  | ||||
|   virtual ~single_thread_service_base() { stop(); } | ||||
|  | ||||
| private: | ||||
|   const std::string service_name_; | ||||
|   mutable std::mutex mtx_; | ||||
|   mutable std::condition_variable notify_; | ||||
|   stop_type stop_requested_ = false; | ||||
|   std::unique_ptr<std::thread> thread_; | ||||
|  | ||||
| protected: | ||||
|   [[nodiscard]] auto get_mutex() const -> std::mutex & { return mtx_; } | ||||
|  | ||||
|   [[nodiscard]] auto get_notify() const -> std::condition_variable & { | ||||
|     return notify_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_stop_requested() const -> bool { | ||||
|     return stop_requested_; | ||||
|   } | ||||
|  | ||||
|   void notify_all() const; | ||||
|  | ||||
|   virtual void on_start() {} | ||||
|  | ||||
|   virtual void on_stop() {} | ||||
|  | ||||
|   virtual void service_function() = 0; | ||||
|  | ||||
| public: | ||||
|   void start(); | ||||
|  | ||||
|   void stop(); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_SINGLE_THREAD_SERVICE_BASE_HPP_ | ||||
							
								
								
									
										116
									
								
								repertory/librepertory/include/utils/tasks.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								repertory/librepertory/include/utils/tasks.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_TASKS_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_TASKS_HPP_ | ||||
|  | ||||
| #include "common.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| class tasks final { | ||||
| public: | ||||
|   struct task final { | ||||
|     std::function<void(const stop_type &task_stopped)> action; | ||||
|   }; | ||||
|  | ||||
|   class i_task { | ||||
|     INTERFACE_SETUP(i_task); | ||||
|  | ||||
|   public: | ||||
|     virtual auto wait() const -> bool = 0; | ||||
|   }; | ||||
|  | ||||
|   using task_ptr = std::shared_ptr<i_task>; | ||||
|  | ||||
| private: | ||||
|   class task_wait final : public i_task { | ||||
|   public: | ||||
|     task_wait() = default; | ||||
|     task_wait(const task_wait &) = delete; | ||||
|     task_wait(task_wait &&) = delete; | ||||
|  | ||||
|     ~task_wait() override { set_result(false); } | ||||
|  | ||||
|     auto operator=(const task_wait &) -> task_wait & = delete; | ||||
|     auto operator=(task_wait &&) -> task_wait & = delete; | ||||
|  | ||||
|   private: | ||||
|     bool complete{false}; | ||||
|     mutable std::mutex mtx; | ||||
|     mutable std::condition_variable notify; | ||||
|     bool success{false}; | ||||
|  | ||||
|   public: | ||||
|     void set_result(bool result); | ||||
|  | ||||
|     auto wait() const -> bool override; | ||||
|   }; | ||||
|  | ||||
|   struct scheduled_task final { | ||||
|     task item; | ||||
|  | ||||
|     std::shared_ptr<task_wait> wait{ | ||||
|         std::make_shared<task_wait>(), | ||||
|     }; | ||||
|   }; | ||||
|  | ||||
| public: | ||||
|   tasks(const tasks &) = delete; | ||||
|   tasks(tasks &&) = delete; | ||||
|   auto operator=(const tasks &) -> tasks & = delete; | ||||
|   auto operator=(tasks &&) -> tasks & = delete; | ||||
|  | ||||
| private: | ||||
|   tasks() = default; | ||||
|  | ||||
|   ~tasks() { stop(); } | ||||
|  | ||||
| private: | ||||
|   static tasks instance_; | ||||
|  | ||||
| public: | ||||
|   static auto instance() -> tasks & { return instance_; } | ||||
|  | ||||
| private: | ||||
|   app_config *config_{nullptr}; | ||||
|   std::atomic<std::uint64_t> count_{0U}; | ||||
|   std::mutex mutex_; | ||||
|   std::condition_variable notify_; | ||||
|   std::mutex start_stop_mutex_; | ||||
|   stop_type stop_requested_{false}; | ||||
|   std::vector<std::unique_ptr<std::jthread>> task_threads_; | ||||
|   std::deque<scheduled_task> tasks_; | ||||
|  | ||||
| private: | ||||
|   void task_thread(); | ||||
|  | ||||
| public: | ||||
|   auto schedule(task item) -> task_ptr; | ||||
|  | ||||
|   void start(app_config *config); | ||||
|  | ||||
|   void stop(); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_TASKS_HPP_ | ||||
							
								
								
									
										59
									
								
								repertory/librepertory/include/utils/throttle.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								repertory/librepertory/include/utils/throttle.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_THROTTLE_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_THROTTLE_HPP_ | ||||
|  | ||||
| namespace repertory { | ||||
| class throttle final { | ||||
| public: | ||||
|   throttle() : max_size_(10u) {} | ||||
|  | ||||
|   explicit throttle(std::size_t max_size) : max_size_(max_size) {} | ||||
|  | ||||
| public: | ||||
|   throttle(const throttle &) noexcept = delete; | ||||
|   throttle(throttle &&) noexcept = delete; | ||||
|   auto operator=(const throttle &) -> throttle & = delete; | ||||
|   auto operator=(throttle &&) -> throttle & = delete; | ||||
|  | ||||
| public: | ||||
|   ~throttle() { shutdown(); } | ||||
|  | ||||
| private: | ||||
|   const std::size_t max_size_; | ||||
|   std::size_t count_ = 0u; | ||||
|   bool shutdown_ = false; | ||||
|   std::mutex mutex_; | ||||
|   std::condition_variable notify_; | ||||
|  | ||||
| public: | ||||
|   void decrement(); | ||||
|  | ||||
|   void increment_or_wait(); | ||||
|  | ||||
|   void reset(); | ||||
|  | ||||
|   void shutdown(); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_THROTTLE_HPP_ | ||||
							
								
								
									
										50
									
								
								repertory/librepertory/include/utils/timeout.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								repertory/librepertory/include/utils/timeout.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_TIMEOUT_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_TIMEOUT_HPP_ | ||||
|  | ||||
| namespace repertory { | ||||
| class timeout final { | ||||
| public: | ||||
|   timeout(const timeout &) noexcept = delete; | ||||
|   timeout(timeout &&) noexcept = delete; | ||||
|   auto operator=(const timeout &) noexcept -> timeout & = delete; | ||||
|   auto operator=(timeout &&) noexcept -> timeout & = delete; | ||||
|  | ||||
| public: | ||||
|   timeout(std::function<void()> timeout_callback, | ||||
|           const std::chrono::system_clock::duration &duration = 10s); | ||||
|  | ||||
|   ~timeout() { disable(); } | ||||
|  | ||||
| private: | ||||
|   bool timeout_killed_; | ||||
|   std::unique_ptr<std::thread> timeout_thread_; | ||||
|   std::mutex timeout_mutex_; | ||||
|   std::condition_variable timeout_notify_; | ||||
|  | ||||
| public: | ||||
|   void disable(); | ||||
| }; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_TIMEOUT_HPP_ | ||||
							
								
								
									
										52
									
								
								repertory/librepertory/include/utils/unix/unix_utils.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								repertory/librepertory/include/utils/unix/unix_utils.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_UNIX_UNIX_UTILS_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_UNIX_UNIX_UTILS_HPP_ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #include "types/remote.hpp" | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/unix.hpp" | ||||
|  | ||||
| namespace repertory::utils { | ||||
| #if defined(__linux__) | ||||
| inline const std::array<std::string, 4U> attribute_namespaces = { | ||||
|     "security", | ||||
|     "system", | ||||
|     "trusted", | ||||
|     "user", | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| [[nodiscard]] auto from_api_error(const api_error &err) -> int; | ||||
|  | ||||
| [[nodiscard]] auto to_api_error(int err) -> api_error; | ||||
|  | ||||
| [[nodiscard]] auto unix_error_to_windows(int err) -> std::uint32_t; | ||||
|  | ||||
| void windows_create_to_unix(const UINT32 &create_options, | ||||
|                             const UINT32 &granted_access, std::uint32_t &flags, | ||||
|                             remote::file_mode &mode); | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // !_WIN32 | ||||
| #endif // REPERTORY_INCLUDE_UTILS_UNIX_UNIX_UTILS_HPP_ | ||||
							
								
								
									
										48
									
								
								repertory/librepertory/include/utils/utils.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								repertory/librepertory/include/utils/utils.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_UTILS_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_UTILS_HPP_ | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| class app_config; | ||||
|  | ||||
| namespace utils { | ||||
| void calculate_allocation_size(bool directory, std::uint64_t file_size, | ||||
|                                UINT64 allocation_size, | ||||
|                                std::string &allocation_meta_size); | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| create_rocksdb(const app_config &cfg, const std::string &name, | ||||
|                const std::vector<rocksdb::ColumnFamilyDescriptor> &families, | ||||
|                std::vector<rocksdb::ColumnFamilyHandle *> &handles, bool clear) | ||||
|     -> std::unique_ptr<rocksdb::TransactionDB>; | ||||
|  | ||||
| [[nodiscard]] auto create_volume_label(const provider_type &prov) | ||||
|     -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD; | ||||
| } // namespace utils | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_UTILS_HPP_ | ||||
| @@ -0,0 +1,54 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_WINDOWS_WINDOWS_UTILS_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_WINDOWS_WINDOWS_UTILS_HPP_ | ||||
| #if defined(_WIN32) | ||||
|  | ||||
| #include "types/remote.hpp" | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/windows.hpp" | ||||
|  | ||||
| namespace repertory::utils { | ||||
| [[nodiscard]] auto | ||||
| get_accessed_time_from_meta(const api_meta_map &meta) -> std::uint64_t; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| get_changed_time_from_meta(const api_meta_map &meta) -> std::uint64_t; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| get_creation_time_from_meta(const api_meta_map &meta) -> std::uint64_t; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| get_written_time_from_meta(const api_meta_map &meta) -> std::uint64_t; | ||||
|  | ||||
| [[nodiscard]] auto from_api_error(const api_error &e) -> NTSTATUS; | ||||
|  | ||||
| [[nodiscard]] auto unix_access_mask_to_windows(std::int32_t mask) -> int; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| unix_open_flags_to_flags_and_perms(const remote::file_mode &mode, | ||||
|                                    const remote::open_flags &flags, | ||||
|                                    std::int32_t &perms) -> int; | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // _WIN32 | ||||
| #endif // REPERTORY_INCLUDE_UTILS_WINDOWS_WINDOWS_UTILS_HPP_ | ||||
							
								
								
									
										12
									
								
								repertory/librepertory/include/version.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								repertory/librepertory/include/version.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| #ifndef LIBREPERTORY_INCLUDE_VERSION_HPP_ | ||||
| #define LIBREPERTORY_INCLUDE_VERSION_HPP_ | ||||
|  | ||||
| #include <string_view> | ||||
|  | ||||
| namespace repertory { | ||||
| [[nodiscard]] auto project_get_git_rev() -> std::string_view; | ||||
|  | ||||
| [[nodiscard]] auto project_get_version() -> std::string_view; | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // LIBREPERTORY_INCLUDE_VERSION_HPP_ | ||||
							
								
								
									
										1259
									
								
								repertory/librepertory/src/app_config.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1259
									
								
								repertory/librepertory/src/app_config.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										200
									
								
								repertory/librepertory/src/comm/curl/curl_comm.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								repertory/librepertory/src/comm/curl/curl_comm.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,200 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "comm/curl/curl_comm.hpp" | ||||
|  | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/path.hpp" | ||||
| #include "utils/string.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| const curl_comm::write_callback curl_comm::write_data = | ||||
|     static_cast<curl_comm::write_callback>([](char *buffer, size_t size, | ||||
|                                               size_t nitems, | ||||
|                                               void *outstream) -> size_t { | ||||
|       auto &info = *reinterpret_cast<read_write_info *>(outstream); | ||||
|       std::copy(buffer, buffer + (size * nitems), | ||||
|                 std::back_inserter(info.data)); | ||||
|       return info.stop_requested ? 0 : size * nitems; | ||||
|     }); | ||||
|  | ||||
| const curl_comm::write_callback curl_comm::write_headers = | ||||
|     static_cast<curl_comm::write_callback>([](char *buffer, size_t size, | ||||
|                                               size_t nitems, | ||||
|                                               void *outstream) -> size_t { | ||||
|       auto &headers = *reinterpret_cast<http_headers *>(outstream); | ||||
|       const auto header = std::string(buffer, size * nitems); | ||||
|       const auto parts = utils::string::split(header, ':', false); | ||||
|       if (parts.size() > 1U) { | ||||
|         auto data = header.substr(parts[0U].size() + 1U); | ||||
|         utils::string::left_trim(data); | ||||
|         utils::string::right_trim(data, '\r'); | ||||
|         utils::string::right_trim(data, '\n'); | ||||
|         utils::string::right_trim(data, '\r'); | ||||
|         headers[utils::string::to_lower(parts[0U])] = data; | ||||
|       } | ||||
|       return size * nitems; | ||||
|     }); | ||||
|  | ||||
| curl_comm::curl_comm(host_config cfg) | ||||
|     : host_config_(std::move(cfg)), s3_config_(std::nullopt) {} | ||||
|  | ||||
| curl_comm::curl_comm(s3_config cfg) | ||||
|     : host_config_(std::nullopt), s3_config_(std::move(cfg)) {} | ||||
|  | ||||
| auto curl_comm::construct_url(CURL *curl, const std::string &relative_path, | ||||
|                               const host_config &cfg) -> std::string { | ||||
|   static constexpr const auto http = 80U; | ||||
|   static constexpr const auto https = 443U; | ||||
|  | ||||
|   auto custom_port = (((cfg.protocol == "http") && | ||||
|                        (cfg.api_port == http || cfg.api_port == 0U)) || | ||||
|                       ((cfg.protocol == "https") && | ||||
|                        (cfg.api_port == https || cfg.api_port == 0U))) | ||||
|                          ? "" | ||||
|                          : ":" + std::to_string(cfg.api_port); | ||||
|   auto url = cfg.protocol + "://" + | ||||
|              utils::string::trim_copy(cfg.host_name_or_ip) + custom_port; | ||||
|  | ||||
|   static const auto complete_url = [](const std::string ¤t_path, | ||||
|                                       const std::string &parent_path, | ||||
|                                       std::string &final_url) -> std::string & { | ||||
|     final_url += utils::path::create_api_path(current_path); | ||||
|     if (utils::string::ends_with(parent_path, "/")) { | ||||
|       final_url += '/'; | ||||
|     } | ||||
|     return final_url; | ||||
|   }; | ||||
|  | ||||
|   auto path = utils::path::combine("/", {cfg.path}); | ||||
|   return relative_path.empty() | ||||
|              ? complete_url(path, cfg.path, url) | ||||
|              : complete_url(utils::path::combine( | ||||
|                                 path, {url_encode(curl, relative_path, true)}), | ||||
|                             relative_path, url); | ||||
| } | ||||
|  | ||||
| auto curl_comm::create_curl() -> CURL * { return reset_curl(curl_easy_init()); } | ||||
|  | ||||
| auto curl_comm::reset_curl(CURL *curl_handle) -> CURL * { | ||||
|   curl_easy_reset(curl_handle); | ||||
| #if defined(__APPLE__) | ||||
|   curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1); | ||||
| #endif // defined(__APPLE__) | ||||
|   return curl_handle; | ||||
| } | ||||
|  | ||||
| auto curl_comm::create_host_config(const s3_config &cfg, | ||||
|                                    bool use_s3_path_style) -> host_config { | ||||
|   host_config host_cfg{}; | ||||
|   host_cfg.api_password = cfg.secret_key; | ||||
|   host_cfg.api_user = cfg.access_key; | ||||
|  | ||||
|   auto pos = cfg.url.find(':'); | ||||
|   host_cfg.host_name_or_ip = cfg.url.substr(pos + 3U); | ||||
|   if (cfg.use_region_in_url && not cfg.region.empty()) { | ||||
|     auto parts = utils::string::split(host_cfg.host_name_or_ip, '.', true); | ||||
|     if (parts.size() > 1U) { | ||||
|       parts.insert(parts.begin() + 1U, cfg.region); | ||||
|       host_cfg.host_name_or_ip = utils::string::join(parts, '.'); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (not use_s3_path_style) { | ||||
|     host_cfg.host_name_or_ip = cfg.bucket + '.' + host_cfg.host_name_or_ip; | ||||
|   } | ||||
|  | ||||
|   host_cfg.protocol = cfg.url.substr(0U, pos); | ||||
|   if (use_s3_path_style) { | ||||
|     host_cfg.path = '/' + cfg.bucket; | ||||
|   } | ||||
|  | ||||
|   return host_cfg; | ||||
| } | ||||
|  | ||||
| void curl_comm::enable_s3_path_style(bool enable) { | ||||
|   use_s3_path_style_ = enable; | ||||
| } | ||||
|  | ||||
| auto curl_comm::make_request(const curl::requests::http_delete &del, | ||||
|                              long &response_code, | ||||
|                              stop_type &stop_requested) const -> bool { | ||||
|   return make_request( | ||||
|       s3_config_.has_value() | ||||
|           ? create_host_config(s3_config_.value(), use_s3_path_style_) | ||||
|           : host_config_.value_or(host_config{}), | ||||
|       del, response_code, stop_requested); | ||||
| } | ||||
|  | ||||
| auto curl_comm::make_request(const curl::requests::http_get &get, | ||||
|                              long &response_code, | ||||
|                              stop_type &stop_requested) const -> bool { | ||||
|   return make_request( | ||||
|       s3_config_.has_value() | ||||
|           ? create_host_config(s3_config_.value(), use_s3_path_style_) | ||||
|           : host_config_.value_or(host_config{}), | ||||
|       get, response_code, stop_requested); | ||||
| } | ||||
|  | ||||
| auto curl_comm::make_request(const curl::requests::http_head &head, | ||||
|                              long &response_code, | ||||
|                              stop_type &stop_requested) const -> bool { | ||||
|   return make_request( | ||||
|       s3_config_.has_value() | ||||
|           ? create_host_config(s3_config_.value(), use_s3_path_style_) | ||||
|           : host_config_.value_or(host_config{}), | ||||
|       head, response_code, stop_requested); | ||||
| } | ||||
|  | ||||
| auto curl_comm::make_request(const curl::requests::http_post &post, | ||||
|                              long &response_code, | ||||
|                              stop_type &stop_requested) const -> bool { | ||||
|   return make_request( | ||||
|       s3_config_.has_value() | ||||
|           ? create_host_config(s3_config_.value(), use_s3_path_style_) | ||||
|           : host_config_.value_or(host_config{}), | ||||
|       post, response_code, stop_requested); | ||||
| } | ||||
|  | ||||
| auto curl_comm::make_request(const curl::requests::http_put_file &put_file, | ||||
|                              long &response_code, | ||||
|                              stop_type &stop_requested) const -> bool { | ||||
|   return make_request( | ||||
|       s3_config_.has_value() | ||||
|           ? create_host_config(s3_config_.value(), use_s3_path_style_) | ||||
|           : host_config_.value_or(host_config{}), | ||||
|       put_file, response_code, stop_requested); | ||||
| } | ||||
|  | ||||
| auto curl_comm::url_encode(CURL *curl, const std::string &data, | ||||
|                            bool allow_slash) -> std::string { | ||||
|   auto *value = | ||||
|       curl_easy_escape(curl, data.c_str(), static_cast<int>(data.size())); | ||||
|   std::string ret = value; | ||||
|   curl_free(value); | ||||
|  | ||||
|   if (allow_slash) { | ||||
|     utils::string::replace(ret, "%2F", "/"); | ||||
|   } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
| } // namespace repertory | ||||
							
								
								
									
										68
									
								
								repertory/librepertory/src/comm/curl/multi_request.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								repertory/librepertory/src/comm/curl/multi_request.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "comm/curl/multi_request.hpp" | ||||
|  | ||||
| #include "utils/utils.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| multi_request::multi_request(CURL *curl_handle, stop_type &stop_requested) | ||||
|     : curl_handle_(curl_handle), | ||||
|       stop_requested_(stop_requested), | ||||
|       multi_handle_(curl_multi_init()) { | ||||
|   curl_multi_add_handle(multi_handle_, curl_handle); | ||||
| } | ||||
|  | ||||
| multi_request::~multi_request() { | ||||
|   curl_multi_remove_handle(multi_handle_, curl_handle_); | ||||
|   curl_easy_cleanup(curl_handle_); | ||||
|   curl_multi_cleanup(multi_handle_); | ||||
| } | ||||
|  | ||||
| void multi_request::get_result(CURLcode &curl_code, long &http_code) { | ||||
|   static constexpr const auto timeout_ms = 100; | ||||
|  | ||||
|   curl_code = CURLcode::CURLE_ABORTED_BY_CALLBACK; | ||||
|   http_code = -1; | ||||
|  | ||||
|   auto error = false; | ||||
|   int running_handles = 0; | ||||
|   curl_multi_perform(multi_handle_, &running_handles); | ||||
|   while (not error && (running_handles > 0) && not stop_requested_) { | ||||
|     int ignored{}; | ||||
|     curl_multi_wait(multi_handle_, nullptr, 0, timeout_ms, &ignored); | ||||
|  | ||||
|     const auto ret = curl_multi_perform(multi_handle_, &running_handles); | ||||
|     error = (ret != CURLM_CALL_MULTI_PERFORM) && (ret != CURLM_OK); | ||||
|   } | ||||
|  | ||||
|   if (not stop_requested_) { | ||||
|     int remaining_messages = 0; | ||||
|     auto *multi_result = | ||||
|         curl_multi_info_read(multi_handle_, &remaining_messages); | ||||
|     if ((multi_result != nullptr) && (multi_result->msg == CURLMSG_DONE)) { | ||||
|       curl_easy_getinfo(multi_result->easy_handle, CURLINFO_RESPONSE_CODE, | ||||
|                         &http_code); | ||||
|       curl_code = multi_result->data.result; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| } // namespace repertory | ||||
							
								
								
									
										45
									
								
								repertory/librepertory/src/comm/curl/requests/http_post.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								repertory/librepertory/src/comm/curl/requests/http_post.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "comm/curl/requests/http_post.hpp" | ||||
|  | ||||
| namespace repertory::curl::requests { | ||||
| http_post::~http_post() { | ||||
|   if (headers != nullptr) { | ||||
|     curl_slist_free_all(headers); | ||||
|   } | ||||
| } | ||||
|  | ||||
| auto http_post::set_method(CURL *curl, stop_type & /*stop_requested*/) const | ||||
|     -> bool { | ||||
|   curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); | ||||
|   if (json.has_value()) { | ||||
|     headers = curl_slist_append(headers, "content-type: application/json"); | ||||
|     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); | ||||
|  | ||||
|     json_str = json->dump(); | ||||
|     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_str->c_str()); | ||||
|     curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1L); | ||||
|   } | ||||
|  | ||||
|   return true; | ||||
| } | ||||
| } // namespace repertory::curl::requests | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user