Review fixes for --delay-updates: - --delete no longer deletes the staged files: the delete walker gains a skip_root_child parameter and receive_manifest passes DELAY_UPDATES_STAGING_DIR when delay_updates is active, so deletion removes genuine extras while the staging dir (a direct child of the receive root) is left for publication in both single and -m modes. - --backup-dir is rejected when it collides with the reserved internal staging name .fastsync-stage (trailing slash normalized), in client validation and in the received-config wire validation, preventing old backups from being silently installed as new files. - Staging dir is now held under an exclusive advisory flock for the whole transfer (context lifetime): two simultaneous delayed transfers to one destination root no longer share/destroy each other's staged data - the second fails cleanly. Cleanup only touches the staging dir when this context owns the lock, so a lock-contention failure cannot wipe a live session. - Post-publish staging cleanup now returns/logs instead of discarding failures (warning when the staging dir cannot be fully removed). - Reworked the publish-failure integration test to exercise real mid-publish semantics (top-level file published, nested rename fails, no rollback, sources retained under --remove-source-files) and added integration tests for --delete + --delay-updates ordering and reserved --backup-dir rejection. - RSYNC_COMPAT note documents delete ordering, the reserved-name hazard, and the concurrency guard.
28 lines
1.2 KiB
C
28 lines
1.2 KiB
C
#ifndef UTILS_H
|
|
#define UTILS_H
|
|
|
|
#include "array_list.h"
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
|
|
char* str_dup(const char* string);
|
|
char* output_escape(const char* string, bool eight_bit_output);
|
|
char* path_cat(const char* path1, const char* path2);
|
|
bool glob_match(const char* pattern, const char* str);
|
|
bool delete_extras(const char* dest_root, ArrayList* manifest);
|
|
/* Remove files/dirs under dest_root that are not listed in manifest. When
|
|
skip_root_child is non-NULL, a direct child of dest_root with that exact
|
|
name is left untouched (used to protect the --delay-updates staging
|
|
directory, which holds files that are still to be published). */
|
|
bool delete_extras_limited(const char* dest_root, ArrayList* manifest, size_t max_delete,
|
|
const char* skip_root_child);
|
|
bool utils_set_authorized_root(int fd, const char* canonical_path);
|
|
/* The fd-only compatibility form is fail-closed for path-based operations;
|
|
* callers should use utils_set_authorized_root with the canonical identity. */
|
|
void utils_set_authorized_root_fd(int fd);
|
|
bool has_path_traversal(const char* path);
|
|
bool utils_valid_batch_path(const char* path);
|
|
bool format_human_bytes(unsigned long long bytes, char* buffer, size_t buffer_size);
|
|
|
|
#endif
|