Pure structural split of src/shared/file_receive.c into focused translation units behind the unchanged file_receive.h facade: - file_save.c : save-to-disk, special nodes, --delay-updates staging - incremental_check.c : xattr/delta/basis/fuzzy receive + check state machine - delete_commit.c : manifest receive + delete budget walkers - file_receive.c : wire receive dispatch + deferred dir metadata The shared receive_file_xattrs helper and MAX_FILE_DATA_SIZE are declared in incremental_check.h. file_save_to_disk_full_ex is decomposed into static helpers (validation, special dispatch, dir/symlink creation, path resolution, pre-write policies, data install) routed through one cleanup epilogue. No behavior change.
78 lines
3.8 KiB
C
78 lines
3.8 KiB
C
#ifndef FILE_RECEIVE_H
|
|
#define FILE_RECEIVE_H
|
|
|
|
#include "config.h"
|
|
#include "delete_commit.h"
|
|
#include "file_save.h"
|
|
#include "file_types.h"
|
|
#include "incremental_check.h"
|
|
#include "utils.h"
|
|
#include <stdbool.h>
|
|
|
|
/* Server-side file receive/save path.
|
|
*
|
|
* This header is the public facade for the file_receive module family: the
|
|
* wire receive dispatch (this file) plus the save-to-disk (file_save.h), the
|
|
* incremental check (incremental_check.h) and the delete-commit
|
|
* (delete_commit.h) modules. */
|
|
|
|
/* Cumulative caps for the deferred directory-time accumulator. The sender may
|
|
* legitimately split a large tree across repeated STATUS_DIR_TIMES frames, so a
|
|
* per-frame bound is not enough: the receiver must bound the TOTAL it retains
|
|
* against a hostile sender. Mirror the delete-manifest limits
|
|
* (MAX_MANIFEST_ENTRIES / MAX_MANIFEST_BYTES): the entry count bounds the
|
|
* metadata array and the byte budget bounds the concatenated path strings. */
|
|
#define MAX_DIR_TIME_ENTRIES (1024 * 1024)
|
|
#define MAX_DIR_TIME_BYTES (16ULL * 1024 * 1024)
|
|
|
|
File* file_receive(const Config* config, int file_descriptor);
|
|
File* file_receive_directory(int file_descriptor, const Config* config);
|
|
File* file_receive_dir_time(int file_descriptor, const Config* config);
|
|
File* file_receive_hardlink(int file_descriptor);
|
|
File* file_receive_symlink(int file_descriptor, const Config* config);
|
|
File* file_receive_special(int file_descriptor);
|
|
|
|
/* P7 Wave D directory-time accumulator. The receiver collects the metadata of
|
|
* every directory it creates/receives (STATUS_MKDIR with metadata and/or the
|
|
* trailing STATUS_DIR_TIMES frame(s)) and applies the times only at the END of the
|
|
* transfer, after all children have been written and after the delete /
|
|
* --delay-updates phases have committed (writing or removing a child bumps the
|
|
* parent's mtime). -O/--omit-dir-times skips the application entirely. The
|
|
* list owns deep copies of the paths and metadata; freed on every path. */
|
|
typedef struct {
|
|
char** paths; /* owned, destination-relative wire paths */
|
|
FileMetadata* entries; /* owned, parallel to paths */
|
|
FileXattrList** xattrs; /* owned, parallel to paths; NULL when none */
|
|
size_t count;
|
|
size_t capacity;
|
|
size_t bytes; /* cumulative strlen of every retained path */
|
|
} DirTimeList;
|
|
|
|
/* Capture gate shared by the sender-side and receiver-side sinks: directory
|
|
* metadata is accumulated only when a directory attribute is requested
|
|
* (-p/--perms for directory modes, or -t/--times for directory mtimes with
|
|
* -O/--omit-dir-times not suppressing them) and metadata rides the wire. Kept
|
|
* here, next to the accumulator it guards, so both call sites express the same
|
|
* condition. */
|
|
bool dir_metadata_should_capture(const Config* config);
|
|
|
|
void dir_time_list_init(DirTimeList* list);
|
|
void dir_time_list_free(DirTimeList* list);
|
|
/* Deep-copy one directory's path + metadata (and, when non-NULL, its captured
|
|
* xattr/ACL block) into the list. Returns false on allocation failure OR when
|
|
* the cumulative entry/byte caps would be exceeded (the caller fails the
|
|
* transfer). */
|
|
bool dir_time_list_add(DirTimeList* list, const char* wire_path, const FileMetadata* metadata,
|
|
const FileXattrList* xattrs);
|
|
/* Apply every accumulated directory's metadata beneath `root_directory`,
|
|
* confined fd-relative: ownership through the negotiated identity policy,
|
|
* times (mtime, plus atime when -U captured one under -t), the mode (through
|
|
* --chmod when configured, under -p), and the captured xattrs/ACLs (under
|
|
* -X/-A). Best-effort per entry: an absent directory (an empty/pruned source
|
|
* dir that was deliberately not created) or a non-directory at the path is
|
|
* skipped QUIETLY, an unreachable one with a warning, and never fatal. */
|
|
void dir_metadata_list_apply(const DirTimeList* list, const char* root_directory,
|
|
const Config* config);
|
|
|
|
#endif
|