From 9443db8db827775d69f2df4a1e29ff56e5c336d3 Mon Sep 17 00:00:00 2001 From: TapTap Date: Tue, 21 Jul 2026 18:09:50 +0200 Subject: [PATCH] feat: add --fastsync-server-path flag to configure remote server binary path --- src/client/client_cli.c | 5 +++++ src/client/client_send.c | 6 ++++-- src/shared/config.c | 3 +++ src/shared/config.h | 1 + src/shared/transport_ssh.c | 6 +++--- src/shared/transport_ssh.h | 2 +- tests/test_transport_ssh.c | 8 ++++---- 7 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/client/client_cli.c b/src/client/client_cli.c index 0ebc391..b23ae50 100644 --- a/src/client/client_cli.c +++ b/src/client/client_cli.c @@ -56,6 +56,8 @@ static void print_usage(void) { printf(" --key TLS private key file (PEM)\n"); printf(" --ca TLS CA certificate file (PEM)\n"); printf(" --partial Keep partial files on interrupted transfer\n"); + printf(" --fastsync-server-path \n"); + printf(" Path to fastsync-server on remote (default: fastsync-server)\n"); printf(" --help Show this help\n"); printf(" -V, --version Show version and exit\n"); } @@ -224,6 +226,9 @@ int main(int argc, char* argv[]) { config->tls_ca = str_dup(argv[++i]); } else if (strcmp(argv[i], "--partial") == 0) { config->partial = true; + } else if (strcmp(argv[i], "--fastsync-server-path") == 0 && i + 1 < argc) { + free(config->fastsync_server_path); + config->fastsync_server_path = str_dup(argv[++i]); } else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) { set_log_level(LOG_LEVEL_DEBUG); } else if (argv[i][0] == '-') { diff --git a/src/client/client_send.c b/src/client/client_send.c index 256d8e4..c9712b0 100644 --- a/src/client/client_send.c +++ b/src/client/client_send.c @@ -228,7 +228,8 @@ static int send_chunks_multithreaded(void* pipeline_context) { fprintf(stderr, "Error: -f/--sendfile is not supported with SSH transport\n"); return 1; } - client = client_connect_ssh(context->config->ssh_destination, context->config->ssh_port); + client = client_connect_ssh(context->config->ssh_destination, context->config->ssh_port, + context->config->fastsync_server_path); } else if (context->config->use_tls) { client = client_create(); if (!client || !client_connect_tls(client, context->config->server_host, @@ -385,7 +386,8 @@ int send_files(Config* config) { fprintf(stderr, "Error: -f/--sendfile is not supported with SSH transport\n"); return 1; } - client = client_connect_ssh(config->ssh_destination, config->ssh_port); + client = client_connect_ssh(config->ssh_destination, config->ssh_port, + config->fastsync_server_path); if (!client) return 1; } else if (config->use_tls) { diff --git a/src/shared/config.c b/src/shared/config.c index e4654b3..e846c42 100644 --- a/src/shared/config.c +++ b/src/shared/config.c @@ -34,6 +34,7 @@ Config* config_create(char* version, char* send_directory, char* receive_directo config->ssh_port = 22; config->transport = TRANSPORT_TCP; config->ssh_destination = NULL; + config->fastsync_server_path = NULL; config->exclude_patterns = NULL; config->exclude_count = 0; config->include_patterns = NULL; @@ -88,6 +89,7 @@ void config_delete(Config* config) { free(config->send_directory); free(config->receive_root_directory); free(config->ssh_destination); + free(config->fastsync_server_path); for (int i = 0; i < config->exclude_count; i++) free(config->exclude_patterns[i]); free(config->exclude_patterns); @@ -238,6 +240,7 @@ Config* config_receive(int file_descriptor) { config->ssh_port = 22; config->transport = TRANSPORT_TCP; config->ssh_destination = NULL; + config->fastsync_server_path = NULL; config->exclude_patterns = NULL; config->exclude_count = 0; config->include_patterns = NULL; diff --git a/src/shared/config.h b/src/shared/config.h index 213cb93..3a0d114 100644 --- a/src/shared/config.h +++ b/src/shared/config.h @@ -24,6 +24,7 @@ typedef struct Config { int ssh_port; TransportType transport; char* ssh_destination; + char* fastsync_server_path; char** exclude_patterns; int exclude_count; char** include_patterns; diff --git a/src/shared/transport_ssh.c b/src/shared/transport_ssh.c index 377fa63..a6c5f76 100644 --- a/src/shared/transport_ssh.c +++ b/src/shared/transport_ssh.c @@ -67,7 +67,7 @@ static int parse_remote_dest(const char* dest, RemoteDest* r) { return 0; } -Client* client_connect_ssh(const char* destination, int port) { +Client* client_connect_ssh(const char* destination, int port, const char* server_path) { RemoteDest r; if (parse_remote_dest(destination, &r) != 0) { fprintf(stderr, "Invalid remote destination: %s\n", destination); @@ -152,7 +152,7 @@ Client* client_connect_ssh(const char* destination, int port) { _exit(1); } ssh_argv[ac++] = ssh_user; - ssh_argv[ac++] = "fastsync-server"; + ssh_argv[ac++] = (char*)(server_path ? server_path : "fastsync-server"); ssh_argv[ac++] = "--stdio"; ssh_argv[ac] = NULL; execvp("ssh", ssh_argv); @@ -174,7 +174,7 @@ Client* client_connect_ssh(const char* destination, int port) { close(sv[0]); waitpid(pid, NULL, 0); remote_dest_destroy(&r); - fprintf(stderr, "Error: could not launch 'fastsync-server --stdio' on remote\n"); + fprintf(stderr, "Error: could not launch '%s --stdio' on remote\n", server_path ? server_path : "fastsync-server"); return NULL; } diff --git a/src/shared/transport_ssh.h b/src/shared/transport_ssh.h index d6b9845..315f37d 100644 --- a/src/shared/transport_ssh.h +++ b/src/shared/transport_ssh.h @@ -3,6 +3,6 @@ #include "transport_tcp.h" -Client* client_connect_ssh(const char* destination, int port); +Client* client_connect_ssh(const char* destination, int port, const char* server_path); #endif diff --git a/tests/test_transport_ssh.c b/tests/test_transport_ssh.c index b38f7a0..4cfec1a 100644 --- a/tests/test_transport_ssh.c +++ b/tests/test_transport_ssh.c @@ -9,14 +9,14 @@ static void test_ssh_connect_invalid_dest() { /* Missing colon — parse_remote_dest should fail and return NULL */ /* cppcheck-suppress constVariablePointer */ - Client* client = client_connect_ssh("invalid-destination-no-colon", 22); + Client* client = client_connect_ssh("invalid-destination-no-colon", 22, NULL); EXPECT_NULL(client); } /* Test client_connect_ssh with empty destination */ static void test_ssh_connect_empty_dest() { /* cppcheck-suppress constVariablePointer */ - Client* client = client_connect_ssh("", 22); + Client* client = client_connect_ssh("", 22, NULL); EXPECT_NULL(client); } @@ -24,7 +24,7 @@ static void test_ssh_connect_empty_dest() { * parse_remote_dest succeeds, ssh is exec'd and fails, but the function * creates a Client that must be cleaned up. */ static void test_ssh_connect_malformed() { - Client* client = client_connect_ssh(":", 22); + Client* client = client_connect_ssh(":", 22, NULL); /* ssh binary exists, so exec succeeds; the function returns a Client. * We just verify it doesn't crash and clean up properly. */ if (client != NULL) { @@ -37,7 +37,7 @@ static void test_ssh_connect_malformed() { /* Test client_connect_ssh with valid format but unreachable host. * The function launches ssh which will fail to connect, returns a Client. */ static void test_ssh_connect_unreachable() { - Client* client = client_connect_ssh("nonexistent.invalid:/remote/path", 22); + Client* client = client_connect_ssh("nonexistent.invalid:/remote/path", 22, NULL); if (client != NULL) { client_disconnect(client); client_delete(client);