Files
FastSync/src/shared/metadata.c
T
TapTap 6a5a61b59f
CI / lint (push) Successful in 7s
CI / lint (pull_request) Successful in 7s
CI / build-and-test (push) Successful in 56s
CI / sanitizers (address) (push) Successful in 1m0s
CI / clang-tidy (push) Successful in 6s
CI / build-and-test (pull_request) Successful in 54s
CI / sanitizers (address) (pull_request) Successful in 59s
CI / clang-tidy (pull_request) Successful in 9s
fix: address all remaining review warnings and style issues
- config.h: bump PROTOCOL_VERSION from "1.2.0" to "1.3.0" (WARNING-1)
- client_cli.c: fix realloc leak on exclude/include patterns (WARNING-2)
- file.c: document sendfile fallback as safety net only (WARNING-4)
- metadata.c: add warning log for utimensat failure (WARNING-5/STYLE-1)
- utils.c: fix is_dir_in_manifest false prefix match (WARNING-1)
- utils.c: fix double rmdir on recursive collapse, add errno.h (WARNING-2)
- client_send.c: guard unchecked send calls for manifest/finished (WARNING-3)
- client_send.c: send STATUS_NEXT on rc==2 without delta (WARNING-4)
2026-07-20 17:48:03 +02:00

113 lines
3.3 KiB
C

#include "metadata.h"
#include "file.h"
#include "log.h"
#include "protocol.h"
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
void metadata_to_buf(char** buf, const FileMetadata* m) {
int present = (m != NULL) ? 1 : 0;
memcpy(*buf, &present, sizeof(int));
*buf += sizeof(int);
if (m == NULL)
return;
memcpy(*buf, &m->mode, sizeof(mode_t));
*buf += sizeof(mode_t);
memcpy(*buf, &m->uid, sizeof(uid_t));
*buf += sizeof(uid_t);
memcpy(*buf, &m->gid, sizeof(gid_t));
*buf += sizeof(gid_t);
memcpy(*buf, &m->mtime_sec, sizeof(time_t));
*buf += sizeof(time_t);
memcpy(*buf, &m->mtime_nsec, sizeof(long));
*buf += sizeof(long);
}
FileMetadata* metadata_from_buf(char** buf) {
int present;
memcpy(&present, *buf, sizeof(int));
*buf += sizeof(int);
if (!present)
return NULL;
FileMetadata* m = malloc(sizeof(FileMetadata));
memcpy(&m->mode, *buf, sizeof(mode_t));
*buf += sizeof(mode_t);
memcpy(&m->uid, *buf, sizeof(uid_t));
*buf += sizeof(uid_t);
memcpy(&m->gid, *buf, sizeof(gid_t));
*buf += sizeof(gid_t);
memcpy(&m->mtime_sec, *buf, sizeof(time_t));
*buf += sizeof(time_t);
memcpy(&m->mtime_nsec, *buf, sizeof(long));
*buf += sizeof(long);
return m;
}
bool metadata_send(int file_descriptor, FileMetadata* m) {
if (m == NULL) {
int zero = 0;
return send_n_data(file_descriptor, &zero, sizeof(int));
}
int present = 1;
return send_n_data(file_descriptor, &present, sizeof(int)) &&
send_n_data(file_descriptor, &m->mode, sizeof(mode_t)) &&
send_n_data(file_descriptor, &m->uid, sizeof(uid_t)) &&
send_n_data(file_descriptor, &m->gid, sizeof(gid_t)) &&
send_n_data(file_descriptor, &m->mtime_sec, sizeof(time_t)) &&
send_n_data(file_descriptor, &m->mtime_nsec, sizeof(long));
}
FileMetadata* metadata_receive(int file_descriptor, int* ok) {
int present;
if (!receive_n_data(file_descriptor, &present, sizeof(int))) {
if (ok)
*ok = 0;
return NULL;
}
if (!present) {
if (ok)
*ok = 1;
return NULL;
}
FileMetadata* m = malloc(sizeof(FileMetadata));
if (m == NULL) {
if (ok)
*ok = 0;
return NULL;
}
if (!receive_n_data(file_descriptor, &m->mode, sizeof(mode_t)) ||
!receive_n_data(file_descriptor, &m->uid, sizeof(uid_t)) ||
!receive_n_data(file_descriptor, &m->gid, sizeof(gid_t)) ||
!receive_n_data(file_descriptor, &m->mtime_sec, sizeof(time_t)) ||
!receive_n_data(file_descriptor, &m->mtime_nsec, sizeof(long))) {
free(m);
if (ok)
*ok = 0;
return NULL;
}
if (ok)
*ok = 1;
return m;
}
void file_restore_metadata(const char* path, FileMetadata* metadata) {
if (metadata == NULL)
return;
if (chmod(path, metadata->mode & 07777) != 0)
log_message(LOG_LEVEL_WARNING, "Failed to chmod %s: %s", path, strerror(errno));
if (chown(path, metadata->uid, metadata->gid) != 0)
log_message(LOG_LEVEL_WARNING, "Failed to chown %s: %s", path, strerror(errno));
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;
if (utimensat(AT_FDCWD, path, times, 0) != 0)
log_message(LOG_LEVEL_WARNING, "Failed to set timestamps on %s: %s", path, strerror(errno));
}