Merge remote-tracking branch 'origin/main' into merge-all-v2
CI / lint (pull_request) Successful in 12s
CI / build-and-test (pull_request) Failing after 10s
CI / sanitizers (address) (pull_request) Failing after 14s
CI / sanitizers (undefined) (pull_request) Failing after 15s
CI / coverage (pull_request) Failing after 7s
CI / fuzz-build (pull_request) Failing after 15s
CI / valgrind (pull_request) Failing after 10s
CI / lint (pull_request) Successful in 12s
CI / build-and-test (pull_request) Failing after 10s
CI / sanitizers (address) (pull_request) Failing after 14s
CI / sanitizers (undefined) (pull_request) Failing after 15s
CI / coverage (pull_request) Failing after 7s
CI / fuzz-build (pull_request) Failing after 15s
CI / valgrind (pull_request) Failing after 10s
# Conflicts: # src/client/client_cli.c # tests/test_transport_ssh.c
This commit is contained in:
@@ -68,6 +68,9 @@ static void print_usage(void) {
|
||||
printf(" --max-depth <n> Maximum directory depth (0=unlimited)\n");
|
||||
printf(" --log-file <path> Write log messages to file\n");
|
||||
printf(" --queue-size <n> Queue capacity for multithreaded mode (default: 100)\n");
|
||||
printf(" --partial Keep partial files on interrupted transfer\n");
|
||||
printf(" --fastsync-server-path <path>\n");
|
||||
printf(" Path to fastsync-server on remote (default: fastsync-server)\n");
|
||||
printf(" --help Show this help\n");
|
||||
}
|
||||
|
||||
@@ -308,6 +311,11 @@ int main(int argc, char* argv[]) {
|
||||
exit_code = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
} 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] == '-') {
|
||||
|
||||
@@ -234,7 +234,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,
|
||||
@@ -392,7 +393,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) {
|
||||
|
||||
@@ -33,6 +33,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;
|
||||
@@ -92,6 +93,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);
|
||||
@@ -227,6 +229,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;
|
||||
|
||||
@@ -25,6 +25,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;
|
||||
|
||||
@@ -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);
|
||||
@@ -147,7 +147,7 @@ Client* client_connect_ssh(const char* destination, int port) {
|
||||
ssh_argv[ac++] = port_str;
|
||||
}
|
||||
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);
|
||||
@@ -168,7 +168,8 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,14 +4,39 @@
|
||||
|
||||
static void test_ssh_connect_invalid_dest_no_colon() {
|
||||
/* cppcheck-suppress constVariablePointer */
|
||||
Client* c = client_connect_ssh("/path/to/dest", 22);
|
||||
EXPECT_NULL(c);
|
||||
Client* client = client_connect_ssh("invalid-destination-no-colon", 22, NULL);
|
||||
EXPECT_NULL(client);
|
||||
}
|
||||
|
||||
static void test_ssh_connect_invalid_dest_empty() {
|
||||
/* cppcheck-suppress constVariablePointer */
|
||||
Client* c = client_connect_ssh("", 22);
|
||||
EXPECT_NULL(c);
|
||||
Client* client = client_connect_ssh("", 22, NULL);
|
||||
EXPECT_NULL(client);
|
||||
}
|
||||
|
||||
/* Test client_connect_ssh with malformed destination (just a colon).
|
||||
* 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, 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) {
|
||||
client_disconnect(client);
|
||||
client_delete(client);
|
||||
}
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
/* 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, NULL);
|
||||
if (client != NULL) {
|
||||
client_disconnect(client);
|
||||
client_delete(client);
|
||||
}
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
void test_transport_ssh() {
|
||||
|
||||
Reference in New Issue
Block a user