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
+16
View File
@@ -1,9 +1,12 @@
#include "utils.h"
#include "libgen.h"
#include "sys/stat.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
void mkdir_r(char *path) {
char *path_duplicate = malloc(strlen(path) + 1);
@@ -59,6 +62,19 @@ void to_disk(char *path, void *data, unsigned long long data_size) {
free(dir_to_free);
}
void file_restore_metadata(const char *path, FileMetadata *metadata) {
if (metadata == NULL)
return;
chmod(path, metadata->mode & 07777);
chown(path, metadata->uid, metadata->gid);
struct timespec times[2];
times[0].tv_sec = 0;
times[0].tv_nsec = UTIME_OMIT;
times[1].tv_sec = metadata->mtime_sec;
times[1].tv_nsec = metadata->mtime_nsec;
utimensat(AT_FDCWD, path, times, 0);
}
char *path_cat(char *path1, char *path2) {
if (path1 == NULL || *path1 == '\0')
return str_dup(path2);