updated build system
This commit is contained in:
17
CHANGELOG.md
17
CHANGELOG.md
@@ -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 -->
|
||||
|
||||
@@ -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]=-")
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user