Deletion timing is now real and selected by the four rsync flags plus the plain --delete default. Wire protocol bumps to 2.8.0: two new config booleans (delete_during, delete_delay) are serialized and validated, joining the existing delete_before/delete_after. - Early modes (--delete-before, --delete-during/--del): the sender pre-scans the whole tree (paths only), transmits the keep-set manifest BEFORE any file data, and the receiver removes extras and acks STATUS_OK; the sender only streams data after the deletion committed. Deletion is thus performed even if a later transfer phase fails (rsync delete-before/during are destructive by definition). FastSync streams in a single scan so it cannot interleave per-directory like rsync delete-during; --delete-during selects the same engine mode as --delete-before (documented divergence). - Late/commit modes (plain --delete, --delete-after, --delete-delay): the manifest closes the data stream and deletion is committed only after STATUS_FINISHED proves the whole transfer succeeded, preserving FastSync's commit-style safety. --delete-delay converges with --delete-after because FastSync never snapshots the destination during data flow (documented). - The STATUS_MANIFEST frame is now self-delimiting and position-independent. Single-threaded receivers delete before the success frame; the -m receiver hands the keep-set to server.c, which commits the deletion only after the disk writer thread has drained (fixes a delete-vs-in-flight-temp race). - Every timing flag implies --delete; at most one timing flag is allowed. - Each timing flag implies --delete, matching rsync; conflicts are rejected.
32 lines
1.4 KiB
C
32 lines
1.4 KiB
C
#ifndef FILE_RECEIVE_H
|
|
#define FILE_RECEIVE_H
|
|
|
|
#include "config.h"
|
|
#include "file_types.h"
|
|
#include <stdbool.h>
|
|
|
|
/* Server-side file receive/save path. */
|
|
|
|
File* file_receive(const Config* config, int file_descriptor);
|
|
File* file_receive_directory(int file_descriptor);
|
|
File* receive_incremental_check(int fd, const Config* config, bool* skipped);
|
|
/* Read a delete-manifest frame: entry count then paths (self-delimiting; the
|
|
leading STATUS_MANIFEST code has been consumed). Returns an owned path
|
|
ArrayList, or NULL after signalling STATUS_ERROR on a malformed frame. */
|
|
ArrayList* receive_manifest_entries(int fd);
|
|
/* Remove destination entries under config->receive_root_directory that are not
|
|
in `manifest` (bounded walk, staging-dir skip). The caller decides WHEN to
|
|
run it based on the negotiated delete timing. */
|
|
bool manifest_delete_extras(const Config* config, ArrayList* manifest);
|
|
|
|
/* Outcome of a single file_save_to_disk operation. The receiver needs to
|
|
distinguish "written" from "skipped" so --remove-source-files can be told
|
|
which sources were actually stored. */
|
|
typedef enum { FILE_SAVE_ERROR = 0, FILE_SAVE_WRITTEN = 1, FILE_SAVE_SKIPPED = 2 } FileSaveResult;
|
|
|
|
FileSaveResult file_save_to_disk_full(const char* root_directory, const File* file,
|
|
const Config* config);
|
|
bool file_save_to_disk(const char* root_directory, const File* file, const Config* config);
|
|
|
|
#endif
|