The STATUS_MANIFEST frame now carries two count-delimited sections: the kept paths and a protected-prefix list (excluded-on-source paths the walker must not delete unless --delete-excluded opted out). The receiver's DeleteManifest is passed through the commit/early paths unchanged. manifest_delete_extras honors a client --max-delete (all-or-nothing) and produces a distinct error for it versus the 100000-entry server bound. --force clears a non-empty directory that blocks an incoming regular file (confined, symlink-safe) via a new file_remove_tree_secure helper.
49 lines
2.0 KiB
C
49 lines
2.0 KiB
C
#ifndef RECEIVER_H
|
|
#define RECEIVER_H
|
|
|
|
#include "config.h"
|
|
#include "file.h"
|
|
#include "file_receive.h"
|
|
|
|
typedef bool (*ReceiverFileSink)(File* file, void* context);
|
|
|
|
/* Ordered per-file save outcomes for one connection. One entry is appended
|
|
for every data-bearing file the receiver processes (in the order the files
|
|
were sent) so the sender of a --remove-source-files transfer can be told
|
|
which sources were actually written versus skipped on the receiver. */
|
|
typedef struct {
|
|
unsigned char* entries; /* FILE_SAVE_WRITTEN or FILE_SAVE_SKIPPED */
|
|
size_t count;
|
|
size_t capacity;
|
|
} ReceiverOutcomes;
|
|
|
|
typedef bool (*ReceiverSuccessFrame)(int fd, void* context);
|
|
|
|
typedef struct {
|
|
ReceiverFileSink store_file;
|
|
void* context;
|
|
bool send_error;
|
|
bool send_success;
|
|
/* Emits the end-of-transfer success frame. When the sender requested
|
|
--remove-source-files this includes one per-file status per processed
|
|
data file followed by the final STATUS_OK; otherwise just STATUS_OK. */
|
|
ReceiverSuccessFrame send_success_frame;
|
|
} ReceiverSink;
|
|
|
|
bool receiver_outcomes_append(ReceiverOutcomes* outcomes, unsigned char code);
|
|
void receiver_outcomes_destroy(ReceiverOutcomes* outcomes);
|
|
bool receiver_send_final_success(int fd, const Config* config, const ReceiverOutcomes* outcomes);
|
|
|
|
int receiver_process(Config* config, int file_descriptor, const ReceiverSink* sink);
|
|
/* receiver_process with an escape hatch for the commit-style (late) deletion:
|
|
when `pending_manifest` is non-NULL the receiver does NOT delete at
|
|
STATUS_FINISHED itself; instead it stores the owned keep-set manifest there
|
|
(leaving *pending_manifest untouched on early modes/errors) so the caller can
|
|
commit the deletion only after its disk writer has fully drained. Pass NULL
|
|
to keep the default behaviour (delete before the success frame). */
|
|
int receiver_process_pending(Config* config, int file_descriptor, const ReceiverSink* sink,
|
|
DeleteManifest** pending_manifest);
|
|
int receiver_receive_files(Config* config, int file_descriptor);
|
|
|
|
#endif
|