diff --git a/src/client/client_send.c b/src/client/client_send.c index d295a82..2ef909a 100644 --- a/src/client/client_send.c +++ b/src/client/client_send.c @@ -547,7 +547,7 @@ int send_files_multithreaded(Config* config) { if (config->use_delete) context->manifest = array_list_create(free); - thrd_t scanner, loader, sender; + thrd_t scanner, loader, sender, progress; if (thrd_create(&scanner, scan_directory_multithreaded, context) != thrd_success || thrd_create(&loader, load_files_multithreaded, context) != thrd_success || thrd_create(&sender, send_chunks_multithreaded, context) != thrd_success) { @@ -556,11 +556,26 @@ int send_files_multithreaded(Config* config) { return 1; } + if (config->show_progress) { + if (thrd_create(&progress, progress_thread_fn, context) != thrd_success) { + perror("Error creating progress thread.\n"); + /* Non-fatal; continue without progress reporting */ + } + } + int sender_result; thrd_join(scanner, NULL); thrd_join(loader, NULL); thrd_join(sender, &sender_result); + if (config->show_progress) { + /* Signal progress thread to exit if it hasn't already */ + mtx_lock(&context->mutex_progress); + context->sender_done = true; + mtx_unlock(&context->mutex_progress); + thrd_join(progress, NULL); + } + pipeline_context_sender_destroy(context); return sender_result == thrd_success ? 0 : 1; } diff --git a/src/shared/config.c b/src/shared/config.c index e31df05..355f516 100644 --- a/src/shared/config.c +++ b/src/shared/config.c @@ -89,6 +89,18 @@ Config* config_create(void) { config->compare_dest = NULL; config->copy_dest = NULL; config->link_dest = NULL; + config->partial_dir = NULL; + config->suffix = NULL; + config->delete_before = false; + config->address = NULL; + config->bind_address = NULL; + config->ipv6 = false; + config->ipv4 = false; + config->daemon = false; + config->daemon_config = NULL; + config->server_mode = false; + config->checksum = false; + config->compress_choice = NULL; return config; } @@ -143,6 +155,12 @@ void config_delete(Config* config) { free(config->compare_dest); free(config->copy_dest); free(config->link_dest); + free(config->partial_dir); + free(config->suffix); + free(config->address); + free(config->bind_address); + free(config->daemon_config); + free(config->compress_choice); if (config->filters) { array_list_delete(config->filters); } @@ -224,6 +242,18 @@ bool config_send(int file_descriptor, const Config* config) { return false; if (!send_str(file_descriptor, config->temp_dir ? config->temp_dir : "")) return false; + if (!send_int(file_descriptor, config->partial)) + return false; + if (!send_str(file_descriptor, config->partial_dir ? config->partial_dir : "")) + return false; + if (!send_str(file_descriptor, config->suffix ? config->suffix : "")) + return false; + if (!send_int(file_descriptor, config->delete_before)) + return false; + if (!send_int(file_descriptor, config->checksum)) + return false; + if (!send_str(file_descriptor, config->compress_choice ? config->compress_choice : "")) + return false; Status status; if (!receive_status(file_descriptor, &status)) return false; diff --git a/src/shared/config.h b/src/shared/config.h index e178318..9c78505 100644 --- a/src/shared/config.h +++ b/src/shared/config.h @@ -100,6 +100,32 @@ typedef struct Config { char* compare_dest; char* copy_dest; char* link_dest; + + // PR #174: Partial transfer resumption + char* partial_dir; + + // PR #178: Backup versioning + char* suffix; + + // PR #179: Delete policies + bool delete_before; + + // PR #181: IPv6 and bind address + char* address; + char* bind_address; + bool ipv6; + bool ipv4; + + // PR #182: Daemon/server mode + bool daemon; + char* daemon_config; + bool server_mode; + + // PR #183: Checksum comparison + bool checksum; + + // PR #184: Compression algorithm negotiation + char* compress_choice; } Config; #define PROTOCOL_VERSION "1.3.0" diff --git a/src/shared/multiprocessing.h b/src/shared/multiprocessing.h index 5d0a39e..8cb28dd 100644 --- a/src/shared/multiprocessing.h +++ b/src/shared/multiprocessing.h @@ -23,6 +23,9 @@ typedef struct { cnd_t condition_not_empty_loader; bool loader_done; ArrayList* manifest; + mtx_t mutex_progress; + unsigned long long progress_bytes; + bool sender_done; } PipelineContextSender; typedef struct PipelineContextReceiver { @@ -37,10 +40,10 @@ typedef struct PipelineContextReceiver { } PipelineContextReceiver; PipelineContextSender* pipeline_context_sender_create(Config* config, Queue* queue_scanner, - Queue* queue_loader); + Queue* queue_loader); void pipeline_context_sender_destroy(PipelineContextSender* context); PipelineContextReceiver* pipeline_context_receiver_create(Config* config, Queue* queue_receiver, - int file_descriptor, SSL* ssl); + int file_descriptor, SSL* ssl); void pipeline_context_receiver_destroy(PipelineContextReceiver* context); int receive_thread(void* pipeline_context); int write_thread(void* pipeline_context); diff --git a/src/shared/transport_tcp.h b/src/shared/transport_tcp.h index 71b03a2..d74d694 100644 --- a/src/shared/transport_tcp.h +++ b/src/shared/transport_tcp.h @@ -15,7 +15,7 @@ typedef struct Server { } Server; typedef struct Client { - struct sockaddr_in address; + struct sockaddr_storage address; unsigned int address_length; int file_descriptor; pid_t ssh_child_pid; @@ -33,5 +33,6 @@ bool client_connect(Client* client, char* host, int port); void client_disconnect(Client* client); void client_delete(Client* client); void tcp_set_timeouts(int timeout_sec, int contimeout_sec); +int tcp_get_contimeout_sec(void); #endif