updated build system

This commit is contained in:
2025-10-19 13:53:06 -05:00
parent d632e46dc3
commit e5169445ae
6 changed files with 150 additions and 124 deletions

View File

@@ -15,6 +15,7 @@
* Remote mounts must be upgraded to v2.1.0+ to support new authentication scheme
* Protocol handshake added for DoS protection
<!-- markdownlint-disable-next-line -->
### Issues
* \#12 [unit test] Complete all providers unit tests
@@ -43,6 +44,8 @@
* Enhanced remote mount client thread mapping
* Threads are now mapped 1-1 from client to server instead of being tied to a fixed-size thread pool
---
## v2.0.7-release
<!-- markdownlint-disable-next-line -->
@@ -51,6 +54,8 @@
* \#55 [bug] UI is unable to launch `repertory.exe` on Windows when absolute path contains spaces
* \#57 [bug] Directory entries . and .. are incorrectly being reported as files in Linux remote mounts
---
## v2.0.6-release
<!-- markdownlint-disable-next-line -->
@@ -75,6 +80,8 @@
* Migrated to v2 error handling
* Upgraded WinFSP to v2.1 (2025)
---
## v2.0.5-rc
<!-- markdownlint-disable-next-line -->
@@ -92,6 +99,8 @@
* Renamed setting `ApiAuth` to `ApiPassword`
* Require `--name,-na` option for encryption provider
---
## v2.0.4-rc
### BREAKING CHANGES
@@ -119,6 +128,8 @@
* Refactored `app_config` unit tests
* Refactored polling to be more accurate on scheduling tasks
---
## v2.0.3-rc
<!-- markdownlint-disable-next-line -->
@@ -143,6 +154,8 @@
* Updated build system to MinGW-w64 12.0.0
* Updated copyright to 2018-2025
---
## v2.0.2-rc
<!-- markdownlint-disable-next-line -->
@@ -175,6 +188,8 @@
* Corrected handling of `chown()` and `chmod()`
* Fixed erroneous download of chunks after resize
---
## v2.0.1-rc
<!-- markdownlint-disable-next-line -->
@@ -197,6 +212,8 @@
* Updated `curl` to v8.4.0
* Updated `libsodium` to v1.0.19
---
## v2.0.0-rc
<!-- markdownlint-disable-next-line -->

View File

@@ -120,7 +120,7 @@ if(PROJECT_BUILD)
@ONLY
)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.iss.in")
if (PROJECT_IS_MINGW AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.iss.in")
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.iss.in
${PROJECT_DIST_DIR}/../${PROJECT_NAME}.iss
@@ -128,6 +128,14 @@ if(PROJECT_BUILD)
)
endif()
if (PROJECT_IS_DARWIN AND EXISTS "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist.in")
configure_file(
${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist.in
${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist
@ONLY
)
endif()
find_package(ICU REQUIRED COMPONENTS data i18n io uc)
else()
message(STATUS "-=[CMake Settings]=-")

View File

@@ -1,17 +1,9 @@
set(CMAKE_CXX_FLAGS "-include common.hpp ${CMAKE_CXX_FLAGS}")
if (PROJECT_IS_DARWIN)
configure_file(
${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist.in
${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist
@ONLY
)
endif()
add_project_library(lib${PROJECT_NAME} "" "" "${PROJECT_ADDITIONAL_SOURCES}")
add_project_executable(${PROJECT_NAME} lib${PROJECT_NAME} lib${PROJECT_NAME})
if (PROJECT_IS_DARWIN)
if (PROJECT_IS_DARWIN AND EXISTS "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist")
set_target_properties(${PROJECT_NAME} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/Info.plist
)

View File

@@ -129,21 +129,15 @@ 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_;
}
-> std::unordered_map<std::size_t, std::shared_ptr<download>> &;
[[nodiscard]] auto get_mutex() const -> std::recursive_mutex & {
return file_mtx_;
}
[[nodiscard]] auto get_mutex() const -> std::recursive_mutex &;
[[nodiscard]] auto get_last_chunk_size() const -> std::size_t;
[[nodiscard]] auto get_provider() -> i_provider & { return provider_; }
[[nodiscard]] auto get_provider() -> i_provider &;
[[nodiscard]] auto get_provider() const -> const i_provider & {
return provider_;
}
[[nodiscard]] auto get_provider() const -> const i_provider &;
[[nodiscard]] auto is_removed() const -> bool;
@@ -208,9 +202,7 @@ public:
[[nodiscard]] auto has_handle(std::uint64_t handle) const -> bool override;
[[nodiscard]] auto is_directory() const -> bool override {
return fsi_.directory;
}
[[nodiscard]] auto is_directory() const -> bool override;
[[nodiscard]] auto is_unlinked() const -> bool override;

View File

@@ -122,64 +122,62 @@ auto packet_server::handshake(std::shared_ptr<connection> conn) const -> bool {
conn->socket, boost::asio::buffer(boost::asio::buffer(buffer)));
write_timeout.disable();
if (bytes_written == buffer.size()) {
conn->buffer.resize(to_read);
if (bytes_written != buffer.size()) {
throw std::runtime_error("failed to send handshake");
}
conn->buffer.resize(to_read);
utils::timeout read_timeout(
timeout_handler,
std::chrono::milliseconds(server_handshake_timeout_ms));
utils::timeout read_timeout(
timeout_handler,
std::chrono::milliseconds(server_handshake_timeout_ms));
std::uint32_t total_read{};
while ((total_read < to_read) && conn->socket.is_open()) {
auto bytes_read = boost::asio::read(
conn->socket,
boost::asio::buffer(&conn->buffer[total_read],
conn->buffer.size() - total_read));
if (bytes_read == 0) {
throw std::runtime_error("0 bytes read");
}
total_read += static_cast<std::uint32_t>(bytes_read);
}
read_timeout.disable();
if (total_read == to_read) {
packet response(conn->buffer);
if (response.decrypt(encryption_token_) == 0) {
std::uint32_t client_version{};
if (response.decode(client_version) == 0) {
std::uint32_t client_version_check{};
if (response.decode(client_version_check) == 0) {
if (~client_version != client_version_check) {
throw std::runtime_error("client version check failed");
}
std::string nonce;
if (response.decode(nonce) == 0) {
if (nonce == conn->nonce) {
conn->generate_nonce();
return true;
}
throw std::runtime_error("nonce mismatch");
}
throw std::runtime_error("invalid nonce");
}
throw std::runtime_error("invalid client version");
}
throw std::runtime_error("invalid client version");
}
throw std::runtime_error("decryption failed");
std::uint32_t total_read{};
while ((total_read < to_read) && conn->socket.is_open()) {
auto bytes_read = boost::asio::read(
conn->socket, boost::asio::buffer(&conn->buffer[total_read],
conn->buffer.size() - total_read));
if (bytes_read == 0) {
throw std::runtime_error("0 bytes read");
}
total_read += static_cast<std::uint32_t>(bytes_read);
}
read_timeout.disable();
if (total_read != to_read) {
throw std::runtime_error("invalid handshake");
}
throw std::runtime_error("failed to send handshake");
packet response(conn->buffer);
if (response.decrypt(encryption_token_) != 0) {
throw std::runtime_error("decryption failed");
}
std::uint32_t client_version{};
if (response.decode(client_version) != 0) {
throw std::runtime_error("invalid client version");
}
std::uint32_t client_version_check{};
if (response.decode(client_version_check) != 0) {
throw std::runtime_error("invalid client version");
}
if (~client_version != client_version_check) {
throw std::runtime_error("client version check failed");
}
std::string nonce;
if (response.decode(nonce) != 0) {
throw std::runtime_error("invalid nonce");
}
if (nonce != conn->nonce) {
throw std::runtime_error("nonce mismatch");
}
conn->generate_nonce();
return true;
} catch (const std::exception &e) {
repertory::utils::error::raise_error(function_name, e, "handlshake failed");
}
@@ -303,57 +301,59 @@ void packet_server::read_packet(std::shared_ptr<connection> conn,
packet::error_type ret{};
auto request = std::make_shared<packet>(conn->buffer);
if (request->decrypt(encryption_token_) == 0) {
std::string nonce;
ret = request->decode(nonce);
if (ret == 0) {
if (nonce != conn->nonce) {
throw std::runtime_error("nonce mismatch");
}
conn->generate_nonce();
std::string version;
ret = request->decode(version);
if (ret == 0) {
if (utils::compare_version_strings(
version, std::string{REPERTORY_MIN_REMOTE_VERSION}) >= 0) {
std::uint32_t service_flags{};
DECODE_OR_IGNORE(request, service_flags);
std::string client_id;
DECODE_OR_IGNORE(request, client_id);
std::uint64_t thread_id{};
DECODE_OR_IGNORE(request, thread_id);
std::string method;
DECODE_OR_IGNORE(request, method);
if (ret == 0) {
if (conn->client_id.empty()) {
add_client(*conn, client_id);
}
should_send_response = false;
message_handler_(service_flags, client_id, thread_id, method,
request.get(), *response,
[this, conn, request,
response](const packet::error_type &result) {
this->send_response(conn, result, *response);
});
}
} else {
ret = utils::from_api_error(api_error::incompatible_version);
}
} else {
ret = utils::from_api_error(api_error::invalid_version);
}
} else {
throw std::runtime_error("invalid nonce");
}
} else {
if (request->decrypt(encryption_token_) != 0) {
throw std::runtime_error("decryption failed");
}
std::string nonce;
ret = request->decode(nonce);
if (ret != 0) {
throw std::runtime_error("invalid nonce");
}
if (nonce != conn->nonce) {
throw std::runtime_error("nonce mismatch");
}
conn->generate_nonce();
std::string version;
ret = request->decode(version);
if (ret == 0) {
if (utils::compare_version_strings(
version, std::string{REPERTORY_MIN_REMOTE_VERSION}) >= 0) {
std::uint32_t service_flags{};
DECODE_OR_IGNORE(request, service_flags);
std::string client_id;
DECODE_OR_IGNORE(request, client_id);
std::uint64_t thread_id{};
DECODE_OR_IGNORE(request, thread_id);
std::string method;
DECODE_OR_IGNORE(request, method);
if (ret == 0) {
if (conn->client_id.empty()) {
add_client(*conn, client_id);
}
should_send_response = false;
message_handler_(service_flags, client_id, thread_id, method,
request.get(), *response,
[this, conn, request,
response](const packet::error_type &result) {
this->send_response(conn, result, *response);
});
}
} else {
ret = utils::from_api_error(api_error::incompatible_version);
}
} else {
ret = utils::from_api_error(api_error::invalid_version);
}
if (should_send_response) {
send_response(conn, ret, *response);
}

View File

@@ -206,6 +206,11 @@ void open_file_base::file_io_thread() {
process_queue();
}
auto open_file_base::get_active_downloads()
-> std::unordered_map<std::size_t, std::shared_ptr<download>> & {
return active_downloads_;
}
auto open_file_base::get_api_error() const -> api_error {
mutex_lock error_lock(error_mtx_);
return error_;
@@ -221,11 +226,23 @@ auto open_file_base::get_file_size() const -> std::uint64_t {
return fsi_.size;
}
[[nodiscard]] auto open_file_base::get_last_chunk_size() const -> std::size_t {
auto open_file_base::get_last_chunk_size() const -> std::size_t {
recur_mutex_lock file_lock(file_mtx_);
return last_chunk_size_;
}
auto open_file_base::get_mutex() const -> std::recursive_mutex & {
return file_mtx_;
}
auto open_file_base::get_provider() -> i_provider & { return provider_; }
auto open_file_base::get_provider() const -> const i_provider & {
return provider_;
}
auto open_file_base::is_directory() const -> bool { return fsi_.directory; }
void open_file_base::set_file_size(std::uint64_t size) {
recur_mutex_lock file_lock(file_mtx_);
fsi_.size = size;