TapTap
282aebb7f5
Merge feat/p6-stop: --stop-after/--stop-at deadline stop
2026-09-10 18:16:55 +02:00
TapTap
b2afcf2c65
Merge feat/p6-iconv: --iconv charset conversion + PROTOCOL 2.16.0
2026-09-10 18:16:51 +02:00
TapTap
09a07179c9
fix(p6-stop): init -m scan_stopped_early; gate delete warning; stabilize partial-stop test
2026-09-10 18:16:35 +02:00
TapTap
cac805b661
fix(p6-iconv): prevent convert buffer overflow; validate both directions; reset on error; more tests
2026-09-10 17:49:29 +02:00
TapTap
ac7e9e3bc1
fix(p6-stop): block delete-manifest on early stop; sync -m manifest access; overflow guard
2026-09-10 17:39:34 +02:00
TapTap
7d6665633d
test(p6-iconv): iconv unit, config wire-roundtrip, integration tests
2026-09-10 17:13:06 +02:00
TapTap
6e02a24232
feat(p6-iconv): --iconv charset conversion + PROTOCOL 2.16.0
2026-09-10 17:13:01 +02:00
TapTap
37cff96537
test(p6-stop): unit and integration tests for stop deadlines
2026-09-10 16:27:49 +02:00
TapTap
24d1448246
feat(p6-stop): --stop-after/--stop-at deadline transfer stop
2026-09-10 16:27:49 +02:00
TapTap
6bb63c6f21
docs: recount RSYNC_COMPAT to 118/13 after daemon Wave C (--no-motd + MOTD)
CI / lint (push) Successful in 1m14s
CI / sanitizers (address) (push) Successful in 55s
CI / sanitizers (undefined) (push) Successful in 53s
CI / fuzz-build (push) Successful in 21s
CI / coverage (push) Successful in 45s
CI / valgrind (push) Successful in 38s
CI / build-and-test (push) Successful in 5m42s
2026-09-10 13:59:15 +02:00
TapTap
61eb08023a
Merge feat/d5-daemon-motd: daemon MOTD display + --no-motd
2026-09-10 13:59:07 +02:00
TapTap
0c35cf2b82
test(d5-daemon-motd): assert no banner when no config key
2026-09-10 13:58:21 +02:00
TapTap
cf5f730940
feat(d5-daemon-motd): daemon MOTD display + --no-motd
2026-09-10 13:52:24 +02:00
TapTap
8330f275a6
docs: recount RSYNC_COMPAT to 117/14 after daemon Wave B auth (--password-file, --early-input)
CI / lint (push) Successful in 1m13s
CI / sanitizers (undefined) (push) Successful in 54s
CI / sanitizers (address) (push) Successful in 56s
CI / fuzz-build (push) Successful in 20s
CI / coverage (push) Successful in 44s
CI / valgrind (push) Successful in 38s
CI / build-and-test (push) Successful in 5m10s
2026-09-10 13:27:39 +02:00
TapTap
d3c9f1d218
Merge feat/d5-daemon-auth: daemon password auth (--password-file, --early-input)
2026-09-10 13:27:27 +02:00
TapTap
accd34ad60
fix(d5-daemon-auth): address auth review findings (Wave B)
...
- test_credentials.c: NUL-terminate the overlong-line stack buffer before
make_tmp_file's strlen() (was a stack-buffer-overflow READ under ASan);
still exercises the overlong-rejection path.
- Add redacted protocol string variants (protocol_send_str_redacted /
receive + fd send_str_redacted/receive_str_redacted) and use them for the
daemon auth username/digest so --verbose / LOG_DEBUG_ALL never logs a
replayable credential while other protocol strings keep their debug trace.
- credentials_verify/gate: replace byte-wise-short-circuiting strcmp with a
fixed-length constant-time username compare (closes user-enumeration oracle);
update doc comment to match.
- read_secret_file: preserve password exact bytes (only strip trailing CR/LF)
and burn the stack line buffer; document the whitespace behavior.
- test_server_cli.c: note the parser zero-inits opts on failure.
- Add debug-level daemon test asserting the digest never appears under --verbose.
PROTOCOL_VERSION stays 2.15.0.
2026-09-10 13:20:42 +02:00
TapTap
dd5ae60459
feat(d5-daemon-auth): password auth, --password-file, --early-input
2026-09-10 12:50:56 +02:00
TapTap
958eddf414
docs: recount RSYNC_COMPAT to 115/16 after daemon Wave A (--daemon/--config/--dparam/--no-detach)
CI / lint (push) Successful in 1m12s
CI / sanitizers (undefined) (push) Successful in 54s
CI / sanitizers (address) (push) Successful in 55s
CI / fuzz-build (push) Successful in 22s
CI / coverage (push) Successful in 46s
CI / valgrind (push) Successful in 38s
CI / build-and-test (push) Successful in 4m41s
2026-09-09 18:40:06 +02:00
TapTap
8440dbfdb8
Merge feat/d5-daemon-core: daemon lifecycle, module config, ::dest (PROTOCOL 2.15.0)
2026-09-09 18:39:37 +02:00
TapTap
7c55409a6b
fix(d5-daemon-core): cppcheck const-correctness, wire module length cap, daemonize chdir/umask, daemon confinement tests
...
- daemon_conf.c/server.c/test_daemon_conf.c: const-qualify parse/loop pointers;
scope user_path static inside its block (clears the 9-wave-A cppcheck findings)
- config.c receive_daemon_module: reject invalid/over-long wire module names
(> DAEMON_MAX_MODULE_NAME) with a clean STATUS_ERROR; client side already
enforced via daemon_module_name_valid in config_parse_daemon_dest
- server.c daemonize: chdir(/) and umask(0) so module paths resolve from /
and config-requested file modes are honored; PROTOCOL_VERSION stays 2.15.0
- test_daemon.py: confinement (read-only/unknown no-write anywhere), module-less
and dot-dot destination refusal, real daemon_detach double-fork path
2026-09-09 18:30:52 +02:00
TapTap
b3d7d64347
feat(d5-daemon-core): daemon lifecycle, module config, ::dest, PROTOCOL 2.15.0
2026-09-09 17:48:07 +02:00
TapTap
9d17e951f1
docs: recount RSYNC_COMPAT to 111/20 after Phase 5 waves A-C; clang-format 18 reflow
CI / lint (push) Successful in 1m9s
CI / sanitizers (undefined) (push) Successful in 53s
CI / sanitizers (address) (push) Successful in 55s
CI / fuzz-build (push) Successful in 19s
CI / coverage (push) Successful in 43s
CI / valgrind (push) Successful in 37s
CI / build-and-test (push) Successful in 4m28s
2026-09-09 14:37:52 +02:00
TapTap
1e02ebcd32
Merge feat/p5-remote-option: --remote-option, --trust-sender
...
# Conflicts:
# RSYNC_COMPAT.md
# src/client/client_cli.c
# src/client/client_send.c
# src/shared/transport_ssh.c
# src/shared/transport_ssh.h
# tests/integration/test_ssh.py
# tests/test_client_cli.c
# tests/test_transport_ssh.c
2026-09-09 14:35:26 +02:00
TapTap
b1c63ff947
Merge feat/p5-socket: --address, -4/-6, --sockopts, server bind options
...
# Conflicts:
# RSYNC_COMPAT.md
# tests/test_client_cli.c
2026-09-09 14:30:36 +02:00
TapTap
35f4297538
Merge feat/p5-rsh: --rsh/-e, --rsync-path, --blocking-io, --outbuf
2026-09-09 14:29:58 +02:00
TapTap
f86ba7a556
fix(p5-socket): clang-format 18 reflow + cppcheck const-correctness
2026-09-09 14:29:46 +02:00
TapTap
cdcaf21acd
fix(p5-rsh): NULL-check argv tail str_dups in ssh_build_client_argv
2026-09-09 14:29:46 +02:00
TapTap
ad228db915
fix(p5-remote-option): wire server --trust-sender, align save-layer gates, add hostile-sender test
2026-09-09 14:23:59 +02:00
TapTap
07d1dd84f7
feat(p5-socket): --address, -4/-6, --sockopts, server bind options
2026-09-09 13:41:28 +02:00
TapTap
858af3d63d
feat(p5-rsh): --rsh/-e, --rsync-path, --blocking-io, --outbuf
2026-09-09 13:41:28 +02:00
TapTap
5e79d7d76b
feat(p5-remote-option): --remote-option (probe 2.14.0), --trust-sender
2026-09-09 13:41:28 +02:00
TapTap
90ccf297d7
style: cppcheck — const-correctness in file_send_special and test_chunk
...
CI / lint (push) Successful in 1m7s
CI / sanitizers (address) (push) Successful in 53s
CI / sanitizers (undefined) (push) Successful in 53s
CI / fuzz-build (push) Successful in 21s
CI / coverage (push) Successful in 44s
CI / valgrind (push) Successful in 37s
CI / build-and-test (push) Successful in 4m41s
file_send_special now takes const File*; test_chunk declares the deserialized
Chunk* const. cppcheck (--error-exitcode=1) now exits clean; clang-format
clean; unit 29/29.
2026-09-08 22:53:47 +02:00
TapTap
5a00a4fe2b
style: cppcheck — drop redundant if(fd>=0) in test_xattr copy-fallback test
...
CI / lint (push) Failing after 1m6s
CI / build-and-test (push) Skipped
CI / sanitizers (address) (push) Skipped
CI / sanitizers (undefined) (push) Skipped
CI / fuzz-build (push) Skipped
CI / coverage (push) Skipped
CI / valgrind (push) Skipped
EXPECT_TRUE(fd >= 0) already guards; the enclosing if is flagged always-true
by cppcheck. read(-1) is safe.
2026-09-08 22:46:43 +02:00
TapTap
743b00ffdd
docs: recount RSYNC_COMPAT summary after Phase-4 wave C (symlink-trust + devices + acl/xattr)
...
CI / lint (push) Failing after 1m8s
CI / build-and-test (push) Skipped
CI / sanitizers (address) (push) Skipped
CI / sanitizers (undefined) (push) Skipped
CI / fuzz-build (push) Skipped
CI / coverage (push) Skipped
CI / valgrind (push) Skipped
Wave C moved 12 rows: -l/--links now real (was Partial). New Implemented (7):
--munge-links, -k/--copy-dirlinks, -K/--keep-dirlinks, -D, -A/--acls, -X/--xattrs
(links was Partial->Implemented). New Partial (5): --devices, --specials,
--copy-devices, --write-devices, --fake-super. Summary: Implemented 94->101,
Partial 6->10, Not Implemented 41->30 (Total 147).
Final Phase-4 summary: 101/3/10/3/30 = 147; PROTOCOL_VERSION 2.13.0.
2026-09-08 22:42:02 +02:00
TapTap
94b6662018
Merge feat/p4-acl-xattr: -X/-A/--fake-super
...
# 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
2026-09-08 22:38:15 +02:00
TapTap
5bbdc5b450
Merge feat/p4-devices
...
# Conflicts:
# src/client/client_send.c
# src/server/receiver.c
# src/shared/chunk.c
# src/shared/file.c
# src/shared/file_receive.c
# src/shared/file_receive.h
# src/shared/file_types.h
# src/shared/protocol.h
# tests/test_chunk.c
2026-09-08 22:33:52 +02:00
TapTap
e600b56f10
Merge feat/p4-symlink-trust
2026-09-08 22:27:56 +02:00
TapTap
747946c318
acls/xattrs: -X/--xattrs, -A/--acls, --fake-super
...
CI / lint (pull_request) Failing after 55s
CI / build-and-test (pull_request) Skipped
CI / sanitizers (address) (pull_request) Skipped
CI / sanitizers (undefined) (pull_request) Skipped
CI / fuzz-build (pull_request) Skipped
CI / coverage (pull_request) Skipped
CI / valgrind (pull_request) Skipped
New src/shared/xattr.{c,h}: capture user.* + POSIX ACL xattrs, transmit a bounded
per-file block, re-apply fd-relative. security.*/trusted.*/other system.* never
transmitted/applied (receiver re-validates). Bounds: name<=255 value<=1MiB count
<=256 total<=4MiB. --fake-super records uid:gid:mode:mtime in reserved
user.fastsync.stat (receiver-only). PROTOCOL_VERSION 2.12.0->2.13.0. Review
fixes: reserved key not forwardable, link/hardlink copy-fallback preserves
xattrs, no const-param mutation, per-file warning dedup.
2026-09-08 22:27:53 +02:00
TapTap
007e8f90f2
devices: --devices/--specials/-D/--copy-devices/--write-devices
...
CI / lint (pull_request) Failing after 56s
CI / build-and-test (pull_request) Skipped
CI / sanitizers (address) (pull_request) Skipped
CI / sanitizers (undefined) (pull_request) Skipped
CI / fuzz-build (pull_request) Skipped
CI / coverage (pull_request) Skipped
CI / valgrind (pull_request) Skipped
Recreate char/block nodes via mknodat (privilege-gated, EPERM->warn+skip) and
FIFOs via mkfifoat; new STATUS_SPECIAL frame + validated rdev; sockets skipped;
-copy-devices copies st_size; -write-devices O_NOFOLLOW+O_NONBLOCK warn+skip.
preserve_specials/copy_devices/write_devices cross the wire. PROTOCOL_VERSION
2.12.0->2.13.0. Review fixes: -m source-removal keeps recreated specials, FIFO
ENXIO skip, rdev bounds at chunk_deserialize, STATUS_ERROR on receive branch,
scanner_prepare_special dedup.
2026-09-08 22:27:53 +02:00
TapTap
820188c2cc
symlink-trust: -k/--copy-dirlinks, -K/--keep-dirlinks, --munge-links (+real -l/--links)
...
CI / lint (pull_request) Successful in 1m1s
CI / sanitizers (address) (pull_request) Skipped
CI / sanitizers (undefined) (pull_request) Skipped
CI / fuzz-build (pull_request) Skipped
CI / coverage (pull_request) Skipped
CI / valgrind (pull_request) Skipped
CI / build-and-test (pull_request) Successful in 1m19s
Adds symlink-target transmission (File is_symlink+symlink_target, STATUS_SYMLINK
frame, chunk type 2), munge-links sender containment + receiver-side symmetric
target containment, keep-dirlinks confined dir-symlink following (O_NOFOLLOW
realpath-rechecked), and fixes -l to copy symlinks as symlinks. munge_links +
keep_dirlinks cross the wire; copy_dirlinks client-only. PROTOCOL_VERSION
2.12.0->2.13.0. Review fixes: receiver rejects absolute/.. targets, gated unmunge,
-K O_NOFOLLOW+re-fstat, keep_dirlinks set once at config-accept, rel_buf overflow
fails the walk.
2026-09-08 22:27:53 +02:00
TapTap
0de859b302
docs: recount RSYNC_COMPAT summary after Phase-4 wave B (metadata times + hard links)
...
CI / lint (push) Successful in 53s
CI / sanitizers (address) (push) Successful in 49s
CI / sanitizers (undefined) (push) Successful in 49s
CI / fuzz-build (push) Successful in 20s
CI / coverage (push) Successful in 43s
CI / valgrind (push) Successful in 37s
CI / build-and-test (push) Successful in 4m28s
Wave B moved 6 rows: -U/--atimes, --open-noatime, -H/--hard-links -> ✅ ;
-N/--crtimes -> ⚠️ ; -O/--omit-dir-times, -J/--omit-link-times -> 🔄 (no-ops).
Summary: ✅ 91->94, ⚠️ 5->6, 🔄 1->3, ❌ 47->41 (Total 147).
2026-09-08 21:02:34 +02:00
TapTap
4e7e84f947
Merge feat/p4-metadata-capture: atimes/crtimes/open-noatime/omit-dir-times/omit-link-times
...
# Conflicts:
# src/shared/config.c
# tests/integration/test_features.py
2026-09-08 21:00:07 +02:00
TapTap
cf7cc5b8ca
Merge feat/p4-hard-links: -H/--hard-links
2026-09-08 20:59:04 +02:00
TapTap
e80888ce7b
metadata times: -U/--atimes, -N/--crtimes, --open-noatime, -O/-J
...
CI / lint (pull_request) Successful in 52s
CI / sanitizers (address) (pull_request) Skipped
CI / sanitizers (undefined) (pull_request) Skipped
CI / fuzz-build (pull_request) Skipped
CI / coverage (pull_request) Skipped
CI / valgrind (pull_request) Skipped
CI / build-and-test (pull_request) Successful in 1m19s
Capture+transmit source atime (pre-read stat; O_NOATIME sender guard) and birth
time (statx STATX_BTIME); receiver restores atime with mtime (crtime not settable
portably -> transmitted, explicitly not applied). --open-noatime is client-only.
-O/-J documented as accepted no-ops (FastSync never preserves dir/symlink times).
Wire: metadata frame gains atime/crtime val+sec+nsec; PROTOCOL_VERSION
2.11.0->2.12.0. Review fixes: gate atime capture to Linux (no epoch clobber on
non-Linux), close fd on fdopen failure, honest -O/-J status (Compat no-op).
2026-09-08 20:58:56 +02:00
TapTap
f891cd0a6a
hard-links: -H/--hard-links preserves inode relationships
...
CI / lint (pull_request) Successful in 50s
CI / sanitizers (address) (pull_request) Skipped
CI / sanitizers (undefined) (pull_request) Skipped
CI / fuzz-build (pull_request) Skipped
CI / coverage (pull_request) Skipped
CI / valgrind (pull_request) Skipped
CI / build-and-test (pull_request) Successful in 1m19s
Source files sharing (st_dev,st_ino) are recreated as hard links on the
destination; only the first member's data crosses the wire (siblings ride a
payload-less STATUS_HARDLINK frame). Ordering requires the single-FIFO-writer
receiver + forced sequential scan (documented). link()-failure falls back to a
byte-identical local copy. Rejects -s/--append. PROTOCOL_VERSION 2.11.0->2.12.0.
Review fixes: delete the dead HardLinkRegistry (ordering holds by FIFO writer),
and --existing no longer aborts when the first member is absent but the sibling
exists (leaves the sibling in place).
2026-09-08 20:58:56 +02:00
TapTap
cbb09e41ab
identity: fix use-after-free in --usermap/--groupmap parse error path
...
CI / lint (push) Successful in 48s
CI / sanitizers (undefined) (push) Successful in 53s
CI / sanitizers (address) (push) Successful in 53s
CI / fuzz-build (push) Successful in 18s
CI / coverage (push) Successful in 42s
CI / valgrind (push) Successful in 37s
CI / build-and-test (push) Successful in 4m37s
identity_parse_map freed the str_dup'd list before logging the offending rule
( points into that buffer), causing an invalid read caught by CI valgrind
(MSAN/MSAN-style; the ONLY definite valgrind error in the suite). Log before
freeing. valgrind now reports 0 errors / 0 definite leaks in both the parent
and the forked wire-roundtrip child.
2026-09-08 18:49:23 +02:00
TapTap
30048dddef
style: clang-format 18 (CI lint) on Wave-A sources
...
CI / lint (push) Successful in 48s
CI / sanitizers (address) (push) Successful in 47s
CI / sanitizers (undefined) (push) Successful in 48s
CI / fuzz-build (push) Successful in 19s
CI / coverage (push) Successful in 44s
CI / valgrind (push) Failing after 37s
CI / build-and-test (push) Successful in 4m36s
Reflow usage.c, config.c, file.c, test_client_cli.c, test_file.c so the
clang-format check passes. Whitespace-only; no behavior change.
2026-09-08 18:38:50 +02:00
TapTap
ba82a0b6da
docs: recount RSYNC_COMPAT summary after Phase-4 wave A (identity + preallocate)
...
CI / lint (push) Failing after 5s
CI / build-and-test (push) Skipped
CI / sanitizers (address) (push) Skipped
CI / sanitizers (undefined) (push) Skipped
CI / fuzz-build (push) Skipped
CI / coverage (push) Skipped
CI / valgrind (push) Skipped
5 rows moved ❌ -> ✅ : --numeric-ids/--usermap/--groupmap/--chown and
--preallocate. Summary: ✅ 86 -> ✅ 91, ❌ 52 -> ❌ 47 (Total 147 unchanged).
2026-09-08 18:37:45 +02:00
TapTap
b283c8084c
identity: keep --numeric-ids in the activate set (-M --numeric-ids)
...
CI / lint (push) Failing after 4s
CI / build-and-test (push) Skipped
CI / sanitizers (address) (push) Skipped
CI / sanitizers (undefined) (push) Skipped
CI / fuzz-build (push) Skipped
CI / coverage (push) Skipped
CI / valgrind (push) Skipped
identity_active_enabled() only gates identity_apply_ownership, which runs only
when metadata is present, so --numeric-ids must stay in the set: combined with
-M it activates raw-id application, while a standalone --numeric-ids (no
ownership-affecting flag) carries no metadata and correctly stays inert. My
earlier review fix removed it and broke 'owner not applied' for -M --numeric-ids
(uid 0 instead of the source ids). Revert that removal.
2026-09-08 18:37:07 +02:00
TapTap
279fc8468a
Merge feat/p4-preallocate: --preallocate
...
# Conflicts:
# tests/test_client_cli.c
# tests/test_config.c
2026-09-08 18:25:49 +02:00