feat(p6-batch): CLI/config plumbing for --write-batch/--only-write-batch/--read-batch

This commit is contained in:
2026-09-10 21:14:30 +02:00
parent 52f45692b9
commit 4930127312
4 changed files with 33 additions and 0 deletions
+8
View File
@@ -604,6 +604,14 @@ static const OptionEntry OPTION_TABLE[] = {
* any network I/O. Client-only: the server does not negotiate, it just * any network I/O. Client-only: the server does not negotiate, it just
* enforces an exact match. */ * enforces an exact match. */
{"--protocol", NULL, OPT_STRING, offsetof(Config, version)}, {"--protocol", NULL, OPT_STRING, offsetof(Config, version)},
/* Phase 6 residual-batch (client-only): --write-batch=FILE runs the normal
* live transfer AND also emits the self-contained batch FILE;
* --only-write-batch=FILE emits FILE only (no destination, no server);
* --read-batch=FILE applies FILE to the destination (no source, no server).
* All three are LOCAL driver flags and never cross the wire. */
{"--write-batch", NULL, OPT_STRING, offsetof(Config, write_batch)},
{"--only-write-batch", NULL, OPT_STRING, offsetof(Config, only_write_batch)},
{"--read-batch", NULL, OPT_STRING, offsetof(Config, read_batch)},
{"--delete-before", NULL, OPT_FLAG, offsetof(Config, delete_before)}, {"--delete-before", NULL, OPT_FLAG, offsetof(Config, delete_before)},
{"--delete-during", "--del", OPT_FLAG, offsetof(Config, delete_during)}, {"--delete-during", "--del", OPT_FLAG, offsetof(Config, delete_during)},
{"--delete-delay", NULL, OPT_FLAG, offsetof(Config, delete_delay)}, {"--delete-delay", NULL, OPT_FLAG, offsetof(Config, delete_delay)},
+6
View File
@@ -44,6 +44,12 @@ void print_usage(void) {
printf(" --protocol=NUM Force the wire protocol version (must equal the current\n"); printf(" --protocol=NUM Force the wire protocol version (must equal the current\n");
printf(" PROTOCOL_VERSION; FastSync cannot speak older/virtual\n"); printf(" PROTOCOL_VERSION; FastSync cannot speak older/virtual\n");
printf(" wire formats)\n"); printf(" wire formats)\n");
printf(" --write-batch=FILE Run the normal live transfer AND also emit a\n");
printf(" self-contained batch file of the whole source tree\n");
printf(" --only-write-batch=FILE\n");
printf(" Emit the batch file only (no destination, no server)\n");
printf(" --read-batch=FILE Apply the batch file to the destination (no source, no\n");
printf(" server); takes only the destination as an argument\n");
printf(" --delete Delete files on receiver not in source\n"); printf(" --delete Delete files on receiver not in source\n");
printf(" (default timing: delete only after the whole\n"); printf(" (default timing: delete only after the whole\n");
printf(" transfer has succeeded)\n"); printf(" transfer has succeeded)\n");
+6
View File
@@ -181,6 +181,9 @@ static void config_set_defaults(Config* config) {
config->stop_after_mins = 0; config->stop_after_mins = 0;
config->stop_at = 0; config->stop_at = 0;
config->stop_at_set = false; config->stop_at_set = false;
config->write_batch = NULL;
config->only_write_batch = NULL;
config->read_batch = NULL;
} }
static bool valid_wire_bool(int value) { static bool valid_wire_bool(int value) {
@@ -631,6 +634,9 @@ void config_delete(Config* config) {
free(config->auth_password_hash); free(config->auth_password_hash);
free(config->password_file); free(config->password_file);
free(config->iconv_spec); free(config->iconv_spec);
free(config->write_batch);
free(config->only_write_batch);
free(config->read_batch);
free(config->fastsync_server_path); free(config->fastsync_server_path);
for (int i = 0; i < config->exclude_count; i++) for (int i = 0; i < config->exclude_count; i++)
free(config->exclude_patterns[i]); free(config->exclude_patterns[i]);
+13
View File
@@ -470,6 +470,19 @@ typedef struct Config {
int stop_after_mins; /* --stop-after=MINS minutes; 0 when unset */ int stop_after_mins; /* --stop-after=MINS minutes; 0 when unset */
time_t stop_at; /* --stop-at=... absolute wall-clock deadline */ time_t stop_at; /* --stop-at=... absolute wall-clock deadline */
bool stop_at_set; /* true when --stop-at was given */ bool stop_at_set; /* true when --stop-at was given */
// Phase 6: --write-batch / --only-write-batch / --read-batch
/* Client-only residual-batch paths. A residual batch is a self-contained
* single-file record of the whole source tree (full file images using the
* chunk codec), independent of any live server. --write-batch=FILE runs the
* normal live transfer AND additionally emits the batch FILE;
* --only-write-batch=FILE emits FILE only (no destination, no server);
* --read-batch=FILE applies FILE to the destination (no source, no server).
* All three are LOCAL to the driving process and are NEVER serialized into
* the config frame (the batch paths bypass the transport entirely). */
char* write_batch; /* --write-batch=FILE path, or NULL */
char* only_write_batch; /* --only-write-batch=FILE path, or NULL */
char* read_batch; /* --read-batch=FILE path, or NULL */
} Config; } Config;
/* Phase 5 (remote-option wave): 2.13.0 -> 2.14.0. /* Phase 5 (remote-option wave): 2.13.0 -> 2.14.0.