# Conflicts: # src/shared/config.c # src/shared/file.c # src/shared/file_types.h # tests/integration/test_features.py # tests/test_client_cli.c # tests/test_config.c
229 lines
16 KiB
C
229 lines
16 KiB
C
#include "usage.h"
|
|
#include <stdio.h>
|
|
#include <delta.h>
|
|
#include <chunk.h>
|
|
|
|
void print_usage(void) {
|
|
printf("Usage:\n");
|
|
printf(" fastsync [options] <source> <destination>\n");
|
|
printf(" fastsync [options] --source-dir <src> --dest-dir <dst>\n");
|
|
printf("\n");
|
|
printf("Destination formats:\n");
|
|
printf(" user@host:/path SSH transport (rsync-style)\n");
|
|
printf(" host:/path SSH transport (current user)\n");
|
|
printf(" /local/path TCP transport (requires server on localhost:8080)\n");
|
|
printf("\n");
|
|
printf("Options:\n");
|
|
printf(" -c [level] Enable compression (level 1-22, default 5)\n");
|
|
printf(" -z [level] Alias for -c\n");
|
|
printf(" -a, --archive Archive mode (-c -m -M)\n");
|
|
printf(" -n, --dry-run Show what would be transferred\n");
|
|
printf(" --remove-source-files Remove regular source files after successful transfer\n");
|
|
printf(" -p <port> SSH port (default: 22)\n");
|
|
printf(" --progress Show transfer progress\n");
|
|
printf(" -P Partial mode with progress (retention incomplete)\n");
|
|
printf(" -8, --8-bit-output Leave high-bit characters unescaped in output\n");
|
|
printf(" --delete Delete files on receiver not in source\n");
|
|
printf(" (default timing: delete only after the whole\n");
|
|
printf(" transfer has succeeded)\n");
|
|
printf(" --delete-before Delete extras before the transfer starts\n");
|
|
printf(" (implies --delete)\n");
|
|
printf(" --delete-during Delete extras once the keep-set manifest is known,\n");
|
|
printf(" before the data is applied (implies --delete)\n");
|
|
printf(" --del Alias for --delete-during\n");
|
|
printf(" --delete-delay Delete extras only after a successful transfer\n");
|
|
printf(" (implies --delete)\n");
|
|
printf(" --delete-after Delete only after the whole transfer succeeded\n");
|
|
printf(" (the default --delete timing; implies --delete)\n");
|
|
printf(" --delete-excluded Also delete destination files that were excluded on\n");
|
|
printf(" the source (default protects them, matching rsync)\n");
|
|
printf(" --max-delete=NUM Never delete more than NUM destination entries per run;\n");
|
|
printf(" if the extras would exceed NUM, nothing is deleted and\n");
|
|
printf(" the run fails with a clear error (implies --delete only\n");
|
|
printf(" when used with it)\n");
|
|
printf(" --ignore-errors Continue (and still delete) when a source directory is\n");
|
|
printf(" unreadable during the scan, instead of aborting with no\n");
|
|
printf(" deletion\n");
|
|
printf(" --force A file may replace a destination directory by removing\n");
|
|
printf(" that (non-empty) directory first\n");
|
|
printf(" --ignore-missing-args A --files-from entry that does not exist under the\n");
|
|
printf(" source is silently skipped instead of failing the run\n");
|
|
printf(" --delete-missing-args Implies --ignore-missing-args; also deletes each missing\n");
|
|
printf(" entry's destination mirror receiver-side. Independent of\n");
|
|
printf(" --delete (it does not imply --delete; a non-empty directory\n");
|
|
printf(" mirror is removed only with --force or --delete)\n");
|
|
printf(" --prune-empty-dirs Do not transfer empty directory entries (--dirs mode);\n");
|
|
printf(" recursive transfers never send empty dirs. rsync's -m\n");
|
|
printf(" short form stays FastSync multithreading\n");
|
|
printf(" Note: each timing flag implies --delete. Combining a timing flag with\n");
|
|
printf(" --no-delete (in either order) is rejected as a config error.\n");
|
|
printf(" --ignore-existing Skip files that already exist on receiver\n");
|
|
printf(" --delay-updates Put updated files into place only at the end of transfer\n");
|
|
printf(" --dirs, -d, --old-dirs, --old-d Transfer the named directory entries without\n");
|
|
printf(" recursing into their contents (-d <dir> mirrors the source\n");
|
|
printf(" directory empty; with --files-from listed dirs are created\n");
|
|
printf(" empty and listed files are transferred)\n");
|
|
printf(" -R, --relative With --files-from, preserve each listed entry's relative path\n");
|
|
printf(" below the destination root instead of mirroring the full\n");
|
|
printf(" source path (no effect without --files-from)\n");
|
|
printf(" --no-implied-dirs With -R --files-from, refuse to place a listed file whose\n");
|
|
printf(" parent directory is not itself listed\n");
|
|
printf(" --mkpath Create the destination root directory on the server when it\n");
|
|
printf(" does not exist yet\n");
|
|
printf(" --exclude <pattern> Exclude files matching pattern\n");
|
|
printf(" --include <pattern> Only include files matching pattern\n");
|
|
printf(" --exclude-from <file> Read exclude patterns from file\n");
|
|
printf(" --include-from <file> Read include patterns from file\n");
|
|
printf(" --files-from <file> Read the source file list from FILE (paths relative to the "
|
|
"source root)\n");
|
|
printf(" -0, --from0 Entries in --files-from are NUL-delimited\n");
|
|
printf(" --filter=RULE rsync-style filter rule (+/- include/exclude; repeatable; the\n");
|
|
printf(" rsync -f short form conflicts with FastSync sendfile -f)\n");
|
|
printf(" -C, --cvs-exclude Auto-ignore common CVS/SCM files (.git/, .svn/, *.o, *~, ...)\n");
|
|
printf(" -F Apply per-directory .rsync-filter files during the scan\n");
|
|
printf(" --max-size <n> Skip files larger than n bytes\n");
|
|
printf(" --min-size <n> Skip files smaller than n bytes\n");
|
|
printf(" --max-alloc <SIZE> Maximum single allocation (default: 1G)\n");
|
|
printf(" --incremental Skip files unchanged since last transfer\n");
|
|
printf(" --size-only Skip incremental files matching in size, ignoring mtime\n");
|
|
printf(" -I, --ignore-times Transfer files even when size and mtime match\n");
|
|
printf(" -@, --modify-window <sec> Modification time tolerance\n");
|
|
printf(" -u, --update Skip files newer than the source on receiver\n");
|
|
printf(" --existing Skip files not already present at destination\n");
|
|
printf(" --compare-dest <dir> Treat DIR (relative to destination root) as an extra\n");
|
|
printf(" comparison basis: unchanged files are not transferred\n");
|
|
printf(" (requires --incremental, which is implied)\n");
|
|
printf(" --copy-dest <dir> Like --compare-dest, but copies the unchanged file from DIR\n");
|
|
printf(" into the destination instead of transferring its data\n");
|
|
printf(" --link-dest <dir> Like --copy-dest, but hard-links the unchanged file from DIR\n");
|
|
printf(" into the destination (repeatable; earlier DIRs win)\n");
|
|
printf(" --checksum-choice, --cc <alg> Whole-file checksum algorithm for --incremental/\n");
|
|
printf(" --checksum compares (xxh64/xxhash or md5; default xxh64 with\n");
|
|
printf(" seed 0). The seed comes from --checksum-seed\n");
|
|
printf(" --checksum-seed <num> Seed for the whole-file xxHash64 digest (and the delta\n");
|
|
printf(" block strong hash, low 32 bits); md5 ignores the seed. The\n");
|
|
printf(" digest algorithm and seed must match on sender and receiver\n");
|
|
printf(" --delta Delta transfer for changed files (requires --incremental)\n");
|
|
printf(" -W, --whole-file Transfer changed files without delta processing\n");
|
|
printf(" -y, --fuzzy Use a similar-named file already in the destination\n");
|
|
printf(" directory as the delta basis when the destination has no\n");
|
|
printf(" usable file at the exact path (saves bandwidth; implies\n");
|
|
printf(" --incremental and --delta; inert with --whole-file,\n");
|
|
printf(" --no-delta, or --no-incremental)\n");
|
|
printf(" --no-fuzzy Disable --fuzzy\n");
|
|
printf(" --delta-block <n> Delta block size in bytes (default: %d)\n",
|
|
DELTA_BLOCK_SIZE_DEFAULT);
|
|
printf(" --delta-max <n> Max file size for delta transfer (default: %llu)\n",
|
|
DELTA_MAX_FILE_SIZE);
|
|
printf(" -m Enable multithreading\n");
|
|
printf(" -s Enable chunk serialization\n");
|
|
printf(" --secluded-args Accept rsync compatibility option (no effect)\n");
|
|
printf(" -f Enable sendfile (TCP only, not with -c or -s)\n");
|
|
printf(" --compress-choice <alg> Compression algorithm (default: zstd)\n");
|
|
printf(" --zc <alg> Alias for --compress-choice\n");
|
|
printf(" -v, --verbose Enable debug logging\n");
|
|
printf(" -q, --quiet Suppress non-error output\n");
|
|
printf(" --debug=FLAGS Fine-grained debug logging (use --debug=help for flags)\n");
|
|
printf(" --info=FLAGS Fine-grained info: copy,misc,skip,stats,all,none\n");
|
|
printf(" none suppresses info even with --verbose\n");
|
|
printf(" -M, --preserve Preserve file metadata\n");
|
|
printf(" -E, --executability Preserve executable permission bits\n");
|
|
printf(" -X, --xattrs Preserve user extended attributes (user.* only;\n");
|
|
printf(" privileged security.*/trusted.* namespaces are\n");
|
|
printf(" never captured or applied)\n");
|
|
printf(" -A, --acls Preserve POSIX ACLs (the system.posix_acl_* xattrs;\n");
|
|
printf(" setting an ACL the receiver is not permitted to\n");
|
|
printf(" set is warned and skipped, never fatal)\n");
|
|
printf(" --fake-super Store the source uid/gid/mode/mtime in a reserved\n");
|
|
printf(" user.fastsync.stat xattr on each written file instead\n");
|
|
printf(" of applying ownership (for a later privileged restore);\n");
|
|
printf(" partial: full rsync fake-super replay is out of scope\n");
|
|
printf(" --chmod <changes> Modify transferred permissions (rsync syntax)\n");
|
|
printf(" --numeric-ids Do not map uid/gid by name: use the source numeric\n");
|
|
printf(" ids directly when applying ownership\n");
|
|
printf(" --usermap=MAP Map usernames when applying ownership: comma-separated\n");
|
|
printf(" FROM:TO rules, first match wins. FROM/TO are names\n");
|
|
printf(" (resolved on the source machine), * (match any /\n");
|
|
printf(" current user), or @N numeric ids. e.g. *:nobody\n");
|
|
printf(" --groupmap=MAP Map group names when applying ownership (same syntax)\n");
|
|
printf(" --chown=USER:GROUP Override the ownership of transferred files. Forms:\n");
|
|
printf(" USER:GROUP, USER (owner only), :GROUP (group only); a\n");
|
|
printf(" value of * means the current/root user as appropriate.\n");
|
|
printf(" Names resolve on the source machine; @N for numerics.\n");
|
|
printf(" Note: -M is already FastSync's preserve flag; these use\n");
|
|
printf(" long forms only.\n");
|
|
printf(" --chunk-size <n> Chunk size in bytes (default: %d)\n", DEFAULT_CHUNK_SIZE);
|
|
printf(" --source-dir <path> Source directory\n");
|
|
printf(" --dest-dir <path> Destination directory\n");
|
|
printf(" --save-to-disk Write received files to disk\n");
|
|
printf(" --server-host <ip> Server IP address (default: 127.0.0.1)\n");
|
|
printf(" --server-port <n> Server port (default: 8080)\n");
|
|
printf(" --bwlimit <KB/s> Bandwidth limit in kilobytes per second\n");
|
|
printf(" --tls Enable TLS encryption\n");
|
|
printf(" --cert <path> TLS certificate file (PEM)\n");
|
|
printf(" --key <path> TLS private key file (PEM)\n");
|
|
printf(" --ca <path> TLS CA certificate file (PEM)\n");
|
|
printf(" --timeout <sec> I/O timeout in seconds (default: 30)\n");
|
|
printf(" -T <sec> Alias for --timeout\n");
|
|
printf(" --contimeout <sec> Connection timeout in seconds (default: 10)\n");
|
|
printf(" --backup Backup existing files before overwriting\n");
|
|
printf(" --backup-dir <dir> Directory for backups (requires --backup)\n");
|
|
printf(" --suffix <str> Backup suffix (default: ~)\n");
|
|
printf(" --stats Print transfer statistics at end\n");
|
|
printf(" -i, --itemize-changes Print an rsync-style per-file change line\n");
|
|
printf(" --out-format=FORMAT Output format for changed files (%%f %%n %%l %%b %%M %%%%)\n");
|
|
printf(" --list-only List source files instead of transferring\n");
|
|
printf(" --log-file-format=FORMAT Per-file log line format (needs --log-file)\n");
|
|
printf(" -h, --human-readable Print byte sizes in human-readable form\n");
|
|
printf(" --max-depth <n> Maximum directory depth (0=unlimited)\n");
|
|
printf(" -x, --one-file-system Do not cross filesystem boundaries\n");
|
|
printf(" --log-file <path> Write log messages to file\n");
|
|
printf(" --stderr=MODE Route logging to stderr: errors or all\n");
|
|
printf(" --partial Keep partial files on interrupted transfer\n");
|
|
printf(" --partial-dir <dir> Directory for partial files\n");
|
|
printf(" --temp-dir <dir> Scratch dir for temp files before atomic install\n");
|
|
printf(" --fastsync-server-path <path>\n");
|
|
printf(" Path to fastsync-server on remote (default: fastsync-server)\n");
|
|
printf(
|
|
" --old-args Disable safe SSH command argument quoting (legacy compatibility)\n");
|
|
printf(" -l, --links Copy symlinks as symlinks\n");
|
|
printf(" --copy-links Transform symlinks into referent files\n");
|
|
printf(" --safe-links Skip symlinks that point outside transfer tree\n");
|
|
printf(" --copy-unsafe-links Only transform unsafe symlinks into referent files\n");
|
|
printf(" -k, --copy-dirlinks Transform symlinks to directories into real dirs\n");
|
|
printf(" -K, --keep-dirlinks Keep an existing symlink-to-dir as that dir\n");
|
|
printf(" --munge-links Munge symlink targets on the wire (sender)\n");
|
|
printf(" -H, --hard-links Preserve hard-link relationships across the transfer\n");
|
|
printf(" -S, --sparse Handle sparse files efficiently\n");
|
|
printf(
|
|
" -D Preserve device and special files (implies --devices --specials)\n");
|
|
printf(
|
|
" --devices Recreate device nodes on the destination (privileged; skipped when\n");
|
|
printf(" the receiver lacks CAP_MKNOD)\n");
|
|
printf(" --specials Recreate special files (FIFOs) on the destination (sockets "
|
|
"skipped)\n");
|
|
printf(" --copy-devices Copy a source device's content as a regular file instead\n");
|
|
printf(" --write-devices Write received data into an existing destination device node\n");
|
|
printf(" --inplace Update files in-place (no temp+rename)\n");
|
|
printf(
|
|
" --preallocate Allocate destination file space up front (fail-fast on full disk)\n");
|
|
printf(" --append Resume a shorter destination by appending only its tail\n");
|
|
printf(" (prefix is not verified; requires --incremental)\n");
|
|
printf(" --append-verify Like --append, but verifies the retained prefix checksum\n");
|
|
printf(" before appending (falls back to a full transfer on mismatch)\n");
|
|
printf(" --fsync Fsync every written file before publication\n");
|
|
printf(" --compress-level <n> Compression level (default: 5)\n");
|
|
printf(" --zl <n> Alias for --compress-level\n");
|
|
printf(" --skip-compress=LIST Skip compression for comma-separated suffixes\n");
|
|
printf(" --compress-threads <n> Compression worker threads (requires zstd threaded support)\n");
|
|
printf(" --no-OPTION Disable a supported boolean option\n");
|
|
printf(" --help Show this help\n");
|
|
printf(" -V, --version Show version\n");
|
|
}
|
|
|
|
void print_debug_usage(void) {
|
|
printf("Supported debug flags: IO,PROTO,PACK,UTIL,ALL,NONE\n");
|
|
printf("Flags may be comma-separated, for example: --debug=io,proto\n");
|
|
printf("Other rsync debug flags are unsupported and rejected.\n");
|
|
}
|