refactor: merge File/FileReceive, add optional metadata transfer with -M flag

- Remove FileReceive struct; use File everywhere with nullable FileMetadata*
- Remove struct stat from File; file size lives in Data->size (data_create_reserve)
- Add FileMetadata struct (mode, uid, gid, mtime) sent conditionally over wire
- Add -M / --preserve flag to client
- Restore permissions, ownership, timestamps on disk write
- Wire format uses per-file present flag for metadata (zero overhead when off)
This commit is contained in:
2026-07-05 20:21:46 +02:00
parent e7c23c135b
commit 4a1e666365
17 changed files with 285 additions and 165 deletions
+6 -3
View File
@@ -49,7 +49,7 @@ int scan_directory_multithreaded(void *pipeline_context) {
PipelineContextSender *context = (PipelineContextSender *)pipeline_context;
mtx_lock(&context->mutex_scanner);
DirectoryScanner *scanner =
directory_scanner_create(context->config->send_directory);
directory_scanner_create(context->config->send_directory, context->config->use_metadata);
mtx_unlock(&context->mutex_scanner);
Chunk *current_chunk;
@@ -127,7 +127,7 @@ int send_files(Config *config) {
int port = env_port ? atoi(env_port) : 8080;
client_connect(client, (char *)ip, port);
config_send(client->file_descriptor, config);
DirectoryScanner *scanner = directory_scanner_create(config->send_directory);
DirectoryScanner *scanner = directory_scanner_create(config->send_directory, config->use_metadata);
Chunk *current_chunk;
while ((current_chunk = directory_scanner_next(scanner)) != NULL) {
for (int i = 0; i < current_chunk->element_count; i++)
@@ -192,7 +192,7 @@ int main(int argc, char *argv[]) {
}
Config *config = config_create(str_dup("1.0.0"), source_dir, dest_dir,
save_to_disk, false, false, false, 5, 20);
save_to_disk, false, false, false, false, 5, 20);
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-c") == 0) {
config->use_compression = true;
@@ -215,6 +215,9 @@ int main(int argc, char *argv[]) {
config->receive_root_directory = str_dup(argv[++i]);
} else if (strcmp(argv[i], "--save-to-disk") == 0) {
config->save_to_disk = true;
} else if (strcmp(argv[i], "-M") == 0 || strcmp(argv[i], "--preserve") == 0) {
config->use_metadata = true;
log_message(LOG_LEVEL_INFO, "Enabled metadata preservation");
} else {
handle_arg(argv[i], "-m", &config->use_multithreading,
"Enabled Multithreading");
+8 -3
View File
@@ -1,6 +1,7 @@
#include "scanner.h"
#include "array_list.h"
#include "chunk.h"
#include "file.h"
#include "queue.h"
#include "utils.h"
#include <dirent.h>
@@ -10,11 +11,12 @@
#include <sys/stat.h>
#include <unistd.h>
DirectoryScanner *directory_scanner_create(char *root_directory) {
DirectoryScanner *directory_scanner_create(char *root_directory, bool use_metadata) {
DirectoryScanner *scanner = malloc(sizeof(DirectoryScanner));
scanner->directories = queue_create(100, free);
scanner->current_dir = NULL;
scanner->current_path = NULL;
scanner->use_metadata = use_metadata;
queue_enqueue(scanner->directories, str_dup(root_directory));
return scanner;
}
@@ -91,9 +93,12 @@ Chunk *directory_scanner_next(DirectoryScanner *scanner) {
if (!S_ISREG(stats.st_mode)) {
queue_enqueue(scanner->directories, (void *)cur_path);
} else {
File *file = file_create(cur_path, &stats);
File *file = file_create(cur_path);
file->data->size = stats.st_size;
if (scanner->use_metadata)
file->metadata = file_metadata_create(&stats);
array_list_add(chunk_data, file);
chunk_data_size += file->stats.st_size;
chunk_data_size += file->data->size;
if (chunk_data_size > DESIRED_CHUNK_SIZE)
return chunk_data_to_chunk(chunk_data);
free(cur_path);
+3 -1
View File
@@ -4,14 +4,16 @@
#include "chunk.h"
#include "queue.h"
#include <dirent.h>
#include <stdbool.h>
typedef struct {
Queue *directories;
DIR *current_dir;
char *current_path;
bool use_metadata;
} DirectoryScanner;
DirectoryScanner *directory_scanner_create(char *root_directory);
DirectoryScanner *directory_scanner_create(char *root_directory, bool use_metadata);
Chunk *directory_scanner_next(DirectoryScanner *scanner);
void directory_scanner_destroy(DirectoryScanner *scanner);