Fix exit() in library code, add --include/--max-size/--min-size

This commit is contained in:
2026-07-16 14:15:38 +02:00
parent 07207cd71d
commit bbdf027be8
27 changed files with 568 additions and 264 deletions
+83 -26
View File
@@ -20,26 +20,29 @@
int send_chunk(Client *client, Chunk *chunk, Config *config) {
if (config->use_chunk_serialization) {
send_status(client->file_descriptor, STATUS_CHUNK);
if (!send_status(client->file_descriptor, STATUS_CHUNK)) return -1;
Data *data;
if (config->use_compression) {
data = chunk_compress(chunk, config->compression_level, config->use_metadata);
} else {
data = chunk_serialize(chunk, config->use_metadata);
}
send_data(client->file_descriptor, data);
if (data == NULL) return -1;
if (!send_data(client->file_descriptor, data)) { data_destroy(data); return -1; }
data_destroy(data);
} else if (config->use_sendfile && !config->use_compression) {
for (int i = 0; i < chunk->element_count; i++) {
send_status(client->file_descriptor, STATUS_NEXT);
file_send_sendfile(chunk->items[i], client->file_descriptor, config->use_metadata);
if (!send_status(client->file_descriptor, STATUS_NEXT)) return -1;
if (!file_send_sendfile(chunk->items[i], client->file_descriptor, config->use_metadata))
return -1;
}
} else {
for (int i = 0; i < chunk->element_count; i++) {
send_status(client->file_descriptor, STATUS_NEXT);
file_send_single_calls(chunk->items[i], client->file_descriptor,
if (!send_status(client->file_descriptor, STATUS_NEXT)) return -1;
if (!file_send_single_calls(chunk->items[i], client->file_descriptor,
config->use_metadata,
config->use_compression ? config->compression_level : 0);
config->use_compression ? config->compression_level : 0))
return -1;
}
}
return 0;
@@ -56,9 +59,17 @@ static int send_chunks_multithreaded(void *pipeline_context) {
client = client_connect_ssh(context->config->ssh_destination, context->config->ssh_port);
} else {
client = client_create();
client_connect(client, server_host, server_port);
if (!client || !client_connect(client, server_host, server_port)) {
if (client) client_delete(client);
fprintf(stderr, "Error: could not connect to server\n");
return thrd_error;
}
}
if (!config_send(client->file_descriptor, context->config)) {
client_disconnect(client);
client_delete(client);
return thrd_error;
}
config_send(client->file_descriptor, context->config);
while (true) {
Chunk *current_chunk = queue_dequeue_multithreaded(
@@ -74,14 +85,17 @@ static int send_chunks_multithreaded(void *pipeline_context) {
(char *)context->manifest->items[i]);
}
send_status(client->file_descriptor, STATUS_FINISHED);
int ok = receive_status(client->file_descriptor) == STATUS_OK;
Status s;
int ok = receive_status(client->file_descriptor, &s) && s == STATUS_OK;
client_disconnect(client);
client_delete(client);
return ok ? thrd_success : thrd_error;
}
if (send_chunk(client, current_chunk, context->config) != 0) {
perror("Something unexpected happend while sending the chunk");
exit(EXIT_FAILURE);
fprintf(stderr, "Error: unexpected error while sending chunk\n");
client_disconnect(client);
client_delete(client);
return thrd_error;
}
chunk_destroy(current_chunk);
}
@@ -93,7 +107,9 @@ static int scan_directory_multithreaded(void *pipeline_context) {
DirectoryScanner *scanner = directory_scanner_create(
context->config->send_directory, context->config->use_metadata,
context->config->chunk_size, context->config->exclude_patterns,
context->config->exclude_count);
context->config->exclude_count, context->config->include_patterns,
context->config->include_count, context->config->max_size,
context->config->min_size);
mtx_unlock(&context->mutex_scanner);
Chunk *current_chunk;
@@ -136,8 +152,13 @@ static int load_files_multithreaded(void *pipeline_context) {
return thrd_success;
}
if (!context->config->use_sendfile) {
for (int i = 0; i < chunk->element_count; i++)
file_load_data(chunk->items[i]);
for (int i = 0; i < chunk->element_count; i++) {
if (!file_load_data(chunk->items[i])) {
log_message(LOG_LEVEL_ERROR, "Failed to load file data, skipping");
file_destroy(chunk->items[i]);
chunk->items[i] = NULL;
}
}
}
queue_enqueue_multithreaded(context->queue_loader, chunk,
&context->mutex_loader,
@@ -150,7 +171,9 @@ int send_files(Config *config) {
if (config->dry_run) {
DirectoryScanner *scanner = directory_scanner_create(
config->send_directory, config->use_metadata, config->chunk_size,
config->exclude_patterns, config->exclude_count);
config->exclude_patterns, config->exclude_count,
config->include_patterns, config->include_count,
config->max_size, config->min_size);
Chunk *chunk;
int file_count = 0;
unsigned long long total_bytes = 0;
@@ -177,14 +200,25 @@ int send_files(Config *config) {
return 1;
}
client = client_connect_ssh(config->ssh_destination, config->ssh_port);
if (!client) return 1;
} else {
client = client_create();
client_connect(client, server_host, server_port);
if (!client || !client_connect(client, server_host, server_port)) {
if (client) client_delete(client);
fprintf(stderr, "Error: could not connect to server\n");
return 1;
}
}
if (!config_send(client->file_descriptor, config)) {
client_disconnect(client);
client_delete(client);
return 1;
}
config_send(client->file_descriptor, config);
DirectoryScanner *scanner = directory_scanner_create(
config->send_directory, config->use_metadata, config->chunk_size,
config->exclude_patterns, config->exclude_count);
config->exclude_patterns, config->exclude_count,
config->include_patterns, config->include_count,
config->max_size, config->min_size);
Chunk *current_chunk;
unsigned long long total_bytes = 0;
time_t last_progress = 0;
@@ -201,10 +235,18 @@ int send_files(Config *config) {
}
}
if (!config->use_sendfile) {
for (int i = 0; i < current_chunk->element_count; i++)
file_load_data(current_chunk->items[i]);
for (int i = 0; i < current_chunk->element_count; i++) {
if (!file_load_data(current_chunk->items[i])) {
log_message(LOG_LEVEL_ERROR, "Failed to load file data");
continue;
}
}
}
if (send_chunk(client, current_chunk, config) != 0) {
log_message(LOG_LEVEL_ERROR, "Failed to send chunk");
chunk_destroy(current_chunk);
break;
}
send_chunk(client, current_chunk, config);
if (config->show_progress) {
total_bytes += chunk_bytes;
time_t now = time(NULL);
@@ -226,7 +268,8 @@ int send_files(Config *config) {
array_list_delete(manifest);
}
send_status(client->file_descriptor, STATUS_FINISHED);
int ok = receive_status(client->file_descriptor) == STATUS_OK;
Status s;
int ok = receive_status(client->file_descriptor, &s) && s == STATUS_OK;
if (config->show_progress) {
double elapsed = difftime(time(NULL), start);
double rate = elapsed > 0 ? total_bytes / (1048576.0 * elapsed) : 0;
@@ -242,7 +285,9 @@ int send_files_multithreaded(Config *config) {
if (config->dry_run) {
DirectoryScanner *scanner = directory_scanner_create(
config->send_directory, config->use_metadata, config->chunk_size,
config->exclude_patterns, config->exclude_count);
config->exclude_patterns, config->exclude_count,
config->include_patterns, config->include_count,
config->max_size, config->min_size);
Chunk *chunk;
int file_count = 0;
unsigned long long total_bytes = 0;
@@ -262,9 +307,20 @@ int send_files_multithreaded(Config *config) {
return 0;
}
Queue *q1 = queue_create(100, chunk_destroy);
Queue *q2 = queue_create(100, chunk_destroy);
if (!q1 || !q2) {
if (q1) queue_destroy(q1);
if (q2) queue_destroy(q2);
return 1;
}
PipelineContextSender *context =
pipeline_context_sender_create(config, queue_create(100, chunk_destroy),
queue_create(100, chunk_destroy));
pipeline_context_sender_create(config, q1, q2);
if (!context) {
queue_destroy(q1);
queue_destroy(q2);
return 1;
}
if (config->use_delete)
context->manifest = array_list_create(free);
@@ -275,6 +331,7 @@ int send_files_multithreaded(Config *config) {
thrd_create(&sender, send_chunks_multithreaded, context) !=
thrd_success) {
perror("Error creating threads.\n");
pipeline_context_sender_destroy(context);
return 1;
}