fix: clarify secluded args compatibility semantics
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 38s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 14s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 33s
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 38s
CI / sanitizers (undefined) (pull_request) Successful in 37s
CI / fuzz-build (pull_request) Successful in 14s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 33s
This commit is contained in:
@@ -89,7 +89,7 @@ partial, alternate, and planned behavior.
|
|||||||
| `-a, --archive` | Archive mode: enables `-c -m -M` (no `-s`) |
|
| `-a, --archive` | Archive mode: enables `-c -m -M` (no `-s`) |
|
||||||
| `-m` | Multithreading mode |
|
| `-m` | Multithreading mode |
|
||||||
| `-s` | Chunk serialization (batch all files per chunk) |
|
| `-s` | Chunk serialization (batch all files per chunk) |
|
||||||
| `--secluded-args` | Rsync-compatible long form. SSH already sends transfer arguments through FastSync's protocol; `-s` remains chunk serialization. |
|
| `--secluded-args` | Accepted as an rsync compatibility option with no effect; `-s` remains chunk serialization. |
|
||||||
| `-f, --sendfile` | Sendfile zero-copy. Incompatible with `-c` / `-s`. TCP only. |
|
| `-f, --sendfile` | Sendfile zero-copy. Incompatible with `-c` / `-s`. TCP only. |
|
||||||
| `-M, --preserve` | Preserve supported file metadata (mode and mtime; ownership and atime are unsupported) |
|
| `-M, --preserve` | Preserve supported file metadata (mode and mtime; ownership and atime are unsupported) |
|
||||||
| `-n, --dry-run` | Scan and print what would be transferred |
|
| `-n, --dry-run` | Scan and print what would be transferred |
|
||||||
@@ -360,10 +360,9 @@ particular, FastSync currently uses `-p` for SSH port, `-s` for chunk
|
|||||||
serialization, and `-S` for sparse handling. These meanings must be reconciled
|
serialization, and `-S` for sparse handling. These meanings must be reconciled
|
||||||
before FastSync can claim full rsync CLI compatibility.
|
before FastSync can claim full rsync CLI compatibility.
|
||||||
|
|
||||||
`--secluded-args` is supported as a long-form compatibility option. FastSync's
|
`--secluded-args` is accepted as a long-form compatibility no-op. It does not
|
||||||
SSH transport already launches only the remote server's `--stdio` command and
|
change FastSync's transport or protocol behavior. The rsync short form `-s` is
|
||||||
sends transfer configuration through its protocol. The rsync short form `-s`
|
intentionally not aliased because it remains FastSync's chunk-serialization
|
||||||
is intentionally not aliased because it remains FastSync's chunk-serialization
|
|
||||||
option.
|
option.
|
||||||
|
|
||||||
## Client Options
|
## Client Options
|
||||||
|
|||||||
+3
-2
@@ -6,9 +6,10 @@ This document maps rsync's full feature set to FastSync's current implementation
|
|||||||
|
|
||||||
| Status | Count | Description |
|
| Status | Count | Description |
|
||||||
|--------|-------|-------------|
|
|--------|-------|-------------|
|
||||||
| ✅ Implemented | 34 | Feature works end-to-end |
|
| ✅ Implemented | 33 | Feature works end-to-end |
|
||||||
| 🔀 Alt Arg | 3 | Functionality exists but under different flag/semantics |
|
| 🔀 Alt Arg | 3 | Functionality exists but under different flag/semantics |
|
||||||
| ⚠️ Partial | 1 | Flag parsed/stored but behavior incomplete |
|
| ⚠️ Partial | 1 | Flag parsed/stored but behavior incomplete |
|
||||||
|
| 🔄 Compatibility No-op | 1 | Flag is accepted for CLI compatibility but has no effect |
|
||||||
| ❌ Not Implemented | 98 | Flag not recognized or no behavior |
|
| ❌ Not Implemented | 98 | Flag not recognized or no behavior |
|
||||||
| **Total** | **136** | |
|
| **Total** | **136** | |
|
||||||
|
|
||||||
@@ -233,7 +234,7 @@ This document maps rsync's full feature set to FastSync's current implementation
|
|||||||
| `--protocol=NUM` | Force older protocol version | ❌ Not Implemented | |
|
| `--protocol=NUM` | Force older protocol version | ❌ Not Implemented | |
|
||||||
| `--iconv=CONVERT_SPEC` | Charset conversion | ❌ Not Implemented | |
|
| `--iconv=CONVERT_SPEC` | Charset conversion | ❌ Not Implemented | |
|
||||||
| `--checksum-seed=NUM` | Set checksum seed | ❌ Not Implemented | |
|
| `--checksum-seed=NUM` | Set checksum seed | ❌ Not Implemented | |
|
||||||
| `--secluded-args` | Use protocol to send args | ✅ Implemented | SSH already sends transfer configuration through FastSync's protocol; `-s` remains chunk serialization because of the existing FastSync short-option meaning. |
|
| `--secluded-args` | Use protocol to send args | 🔄 Compatibility No-op | Accepted for CLI compatibility; it does not change FastSync transport or protocol behavior. `-s` remains chunk serialization. |
|
||||||
| `--no-OPTION` | Turn off implied option | ❌ Not Implemented | |
|
| `--no-OPTION` | Turn off implied option | ❌ Not Implemented | |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ static int config_add_pattern(char*** patterns, int* count, const char* value,
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OPT_FLAG,
|
OPT_FLAG,
|
||||||
|
OPT_NOOP,
|
||||||
OPT_STRING,
|
OPT_STRING,
|
||||||
OPT_POS_INT,
|
OPT_POS_INT,
|
||||||
OPT_NONNEG_INT,
|
OPT_NONNEG_INT,
|
||||||
@@ -131,10 +132,10 @@ typedef struct {
|
|||||||
const char* name;
|
const char* name;
|
||||||
const char* alias;
|
const char* alias;
|
||||||
OptKind kind;
|
OptKind kind;
|
||||||
size_t offset; /* offsetof of the target field in Config */
|
size_t offset; /* offsetof of the target field in Config, or 0 for OPT_NOOP */
|
||||||
} OptionEntry;
|
} OptionEntry;
|
||||||
|
|
||||||
/* Options that map directly onto a Config field with no side effects. */
|
/* Options parsed directly into Config, plus compatibility options with no effect. */
|
||||||
static const OptionEntry OPTION_TABLE[] = {
|
static const OptionEntry OPTION_TABLE[] = {
|
||||||
{"--dry-run", "-n", OPT_FLAG, offsetof(Config, dry_run)},
|
{"--dry-run", "-n", OPT_FLAG, offsetof(Config, dry_run)},
|
||||||
{"--delete", NULL, OPT_FLAG, offsetof(Config, use_delete)},
|
{"--delete", NULL, OPT_FLAG, offsetof(Config, use_delete)},
|
||||||
@@ -146,7 +147,7 @@ static const OptionEntry OPTION_TABLE[] = {
|
|||||||
{"--backup", NULL, OPT_FLAG, offsetof(Config, backup)},
|
{"--backup", NULL, OPT_FLAG, offsetof(Config, backup)},
|
||||||
{"--stats", NULL, OPT_FLAG, offsetof(Config, stats)},
|
{"--stats", NULL, OPT_FLAG, offsetof(Config, stats)},
|
||||||
{"--partial", NULL, OPT_FLAG, offsetof(Config, partial)},
|
{"--partial", NULL, OPT_FLAG, offsetof(Config, partial)},
|
||||||
{"--secluded-args", NULL, OPT_FLAG, offsetof(Config, use_secluded_args)},
|
{"--secluded-args", NULL, OPT_NOOP, 0},
|
||||||
{"--links", "-l", OPT_FLAG, offsetof(Config, follow_symlinks)},
|
{"--links", "-l", OPT_FLAG, offsetof(Config, follow_symlinks)},
|
||||||
{"--copy-links", NULL, OPT_FLAG, offsetof(Config, copy_links)},
|
{"--copy-links", NULL, OPT_FLAG, offsetof(Config, copy_links)},
|
||||||
{"--safe-links", NULL, OPT_FLAG, offsetof(Config, safe_links)},
|
{"--safe-links", NULL, OPT_FLAG, offsetof(Config, safe_links)},
|
||||||
@@ -186,11 +187,16 @@ static const OptionEntry* find_table_option(const char* arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int apply_table_option(Config* config, const OptionEntry* entry, const char* value) {
|
static int apply_table_option(Config* config, const OptionEntry* entry, const char* value) {
|
||||||
|
if (entry->kind == OPT_NOOP)
|
||||||
|
return 0;
|
||||||
|
|
||||||
void* field = (char*)config + entry->offset;
|
void* field = (char*)config + entry->offset;
|
||||||
switch (entry->kind) {
|
switch (entry->kind) {
|
||||||
case OPT_FLAG:
|
case OPT_FLAG:
|
||||||
*(bool*)field = true;
|
*(bool*)field = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
case OPT_NOOP:
|
||||||
|
return 0;
|
||||||
case OPT_STRING:
|
case OPT_STRING:
|
||||||
return set_string_option((char**)field, value, entry->name);
|
return set_string_option((char**)field, value, entry->name);
|
||||||
case OPT_POS_INT:
|
case OPT_POS_INT:
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ void print_usage(void) {
|
|||||||
DELTA_MAX_FILE_SIZE);
|
DELTA_MAX_FILE_SIZE);
|
||||||
printf(" -m Enable multithreading\n");
|
printf(" -m Enable multithreading\n");
|
||||||
printf(" -s Enable chunk serialization\n");
|
printf(" -s Enable chunk serialization\n");
|
||||||
printf(" --secluded-args Send transfer arguments through the protocol (SSH)\n");
|
printf(" --secluded-args Accept rsync compatibility option (no effect)\n");
|
||||||
printf(" -f Enable sendfile (TCP only, not with -c or -s)\n");
|
printf(" -f Enable sendfile (TCP only, not with -c or -s)\n");
|
||||||
printf(" -v, --verbose Enable debug logging\n");
|
printf(" -v, --verbose Enable debug logging\n");
|
||||||
printf(" -M, --preserve Preserve file metadata\n");
|
printf(" -M, --preserve Preserve file metadata\n");
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ static void config_set_defaults(Config* config) {
|
|||||||
config->relative = false;
|
config->relative = false;
|
||||||
config->rsh_command = NULL;
|
config->rsh_command = NULL;
|
||||||
config->rsync_path = NULL;
|
config->rsync_path = NULL;
|
||||||
config->use_secluded_args = false;
|
|
||||||
config->temp_dir = NULL;
|
config->temp_dir = NULL;
|
||||||
config->compare_dest = NULL;
|
config->compare_dest = NULL;
|
||||||
config->copy_dest = NULL;
|
config->copy_dest = NULL;
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ typedef struct Config {
|
|||||||
// Issue #130: Remote shell/connection options
|
// Issue #130: Remote shell/connection options
|
||||||
char* rsh_command;
|
char* rsh_command;
|
||||||
char* rsync_path;
|
char* rsync_path;
|
||||||
bool use_secluded_args;
|
|
||||||
char* temp_dir;
|
char* temp_dir;
|
||||||
char* compare_dest;
|
char* compare_dest;
|
||||||
char* copy_dest;
|
char* copy_dest;
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ static void test_parse_args_archive() {
|
|||||||
config_delete(cfg);
|
config_delete(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --secluded-args is the rsync-compatible long form; -s keeps its FastSync meaning. */
|
/* --secluded-args is accepted for compatibility but has no effect. */
|
||||||
static void test_parse_args_secluded_args() {
|
static void test_parse_args_secluded_args() {
|
||||||
Config* cfg = config_create();
|
Config* cfg = config_create();
|
||||||
char* argv[] = {"fastsync", "--secluded-args", "/src", "/dst"};
|
char* argv[] = {"fastsync", "--secluded-args", "/src", "/dst"};
|
||||||
@@ -347,7 +347,6 @@ static void test_parse_args_secluded_args() {
|
|||||||
int positional_count = 0;
|
int positional_count = 0;
|
||||||
|
|
||||||
EXPECT_EQ_INT(parse_args(cfg, 4, argv, positional_args, &positional_count), 0);
|
EXPECT_EQ_INT(parse_args(cfg, 4, argv, positional_args, &positional_count), 0);
|
||||||
EXPECT_TRUE(cfg->use_secluded_args);
|
|
||||||
EXPECT_FALSE(cfg->use_chunk_serialization);
|
EXPECT_FALSE(cfg->use_chunk_serialization);
|
||||||
config_delete(cfg);
|
config_delete(cfg);
|
||||||
}
|
}
|
||||||
@@ -360,7 +359,6 @@ static void test_parse_args_short_s_remains_chunk_serialization() {
|
|||||||
|
|
||||||
EXPECT_EQ_INT(parse_args(cfg, 4, argv, positional_args, &positional_count), 0);
|
EXPECT_EQ_INT(parse_args(cfg, 4, argv, positional_args, &positional_count), 0);
|
||||||
EXPECT_TRUE(cfg->use_chunk_serialization);
|
EXPECT_TRUE(cfg->use_chunk_serialization);
|
||||||
EXPECT_FALSE(cfg->use_secluded_args);
|
|
||||||
config_delete(cfg);
|
config_delete(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user