Commit Graph

72 Commits

Author SHA1 Message Date
TapTap 38be7c090a Fix 11 Gitea issues (#29, #30, #31, #35, #38, #41, #42, #43, #44, #45, #46)
CI / lint (push) Failing after 3s
CI / build-and-test (push) Has been skipped
CI / sanitizers (address) (push) Has been skipped
CI / clang-tidy (push) Has been skipped
CI / lint (pull_request) Failing after 2s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / clang-tidy (pull_request) Has been skipped
#29 - compression_level now used in data_compress()
#30 - chunk_size no longer truncated to 32-bit
#31 - chmod/chown failures now logged
#35 - strtok -> strtok_r for thread safety
#38 - open_next_directory returns -1 on opendir failure
#41 - file_send_sendfile uses compression_level param
#42 - dirname() uses copy to avoid modifying input
#43 - delete_extras_walk checks manifest before rmdir
#44 - server_host/port moved into Config struct
#45 - SSH parse_remote_dest uses dynamic allocation
#46 - send_chunk refactored, reduced nesting/duplication
2026-07-20 17:09:12 +02:00
TapTap 5c686b0655 fix: address PR review — doc accuracy, clang-tidy info, config leak fix
CI / lint (push) Successful in 7s
CI / lint (pull_request) Successful in 7s
CI / build-and-test (push) Successful in 54s
CI / clang-tidy (push) Successful in 6s
CI / sanitizers (address) (push) Successful in 59s
CI / build-and-test (pull_request) Successful in 55s
CI / clang-tidy (pull_request) Successful in 5s
CI / sanitizers (address) (pull_request) Successful in 57s
Review findings addressed:

Critical:
- cmake-expert.md: replace commented-out sanitizer lines with actual
  SANITIZER cache variable block, fix ENABLE_ASAN/TSAN/UBSAN pattern
- integrator.md: update YAML example to v7, use -DSANITIZER= instead
  of raw flags, add symlink + LSAN suppression steps

Warnings:
- ci.yaml: rename clang-tidy step to 'informational, non-blocking',
  add ::warning:: workflow command for visibility
- client_cli.c: add goto cleanup pattern to free config on error paths
  (skip for multithreaded path where pipeline_context_sender_destroy
  already owns config)

Suggestions:
- test-writer.md: clarify conftest.py is at tests/conftest.py
- .lsan-suppressions.txt: remove config_create suppression (leak fixed)
2026-07-20 14:28:42 +02:00
TapTap bd17f50f9b feat: update AI automation agents, add reviewer agent, fix leaks, enhance CI
Agents:
- cmake-expert: fix stale CMake version (4.1 -> 3.22), add OpenSSL/xxHash deps
- integrator: fix stale test.py references to tests/integration/, update CI docs
- test-writer: update integration test patterns for modular test structure
- reviewer: new comprehensive PR reviewer (code, build, CI, docs, quality)

Bug fixes:
- delta.c: set instructions[i].type = DELTA_INSTR_LITERAL in deserialize
- scanner.c: free ArrayList when directory_scanner_next returns NULL

CI:
- Add sanitizer job (ASan + UBSan) with LSAN suppressions for pre-existing leaks
- Add clang-tidy job with proper warning/error detection
- Remove || true masking (fixes now make sanitizer useful)

Cleanup:
- gitignore build-asan/
- .lsan-suppressions.txt for known CLI config leaks
2026-07-20 14:22:27 +02:00
TapTap 8531f9e4c1 fix: set DELTA_INSTR_LITERAL type in deserialize and fix error path leaks
CI / lint (push) Successful in 7s
CI / lint (pull_request) Successful in 8s
CI / build-and-test (push) Successful in 53s
CI / sanitizers (address) (push) Successful in 14s
CI / build-and-test (pull_request) Successful in 52s
CI / sanitizers (address) (pull_request) Successful in 14s
2026-07-19 17:15:43 +02:00
TapTap 413f69de90 fix: const-correct delta.c and use unread variable in test for cppcheck
CI / lint (push) Successful in 7s
CI / lint (pull_request) Successful in 8s
CI / build-and-test (push) Successful in 52s
CI / sanitizers (address) (push) Failing after 13s
CI / build-and-test (pull_request) Successful in 53s
CI / sanitizers (address) (pull_request) Failing after 13s
2026-07-19 17:07:14 +02:00
TapTap d7b9d4dbbc fix: apply clang-format to merged code from main
CI / lint (push) Failing after 8s
CI / build-and-test (push) Has been skipped
CI / sanitizers (address) (push) Has been skipped
CI / lint (pull_request) Failing after 7s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
2026-07-19 17:04:05 +02:00
TapTap b9840b123d Merge remote-tracking branch 'origin/main' into ci/tier1-review-automation
CI / lint (push) Failing after 3s
CI / build-and-test (push) Has been skipped
CI / sanitizers (address) (push) Has been skipped
CI / lint (pull_request) Failing after 2s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
# Conflicts:
#	src/client/client_send.c
#	src/shared/config.c
#	src/shared/file.c
#	src/shared/file.h
#	src/shared/protocol.h
2026-07-19 16:58:53 +02:00
TapTap 971a070b65 fix: const-correct config_send and file_send_single_calls for cppcheck
CI / lint (push) Successful in 6s
CI / lint (pull_request) Successful in 6s
CI / build-and-test (push) Successful in 47s
CI / sanitizers (address) (push) Successful in 4s
CI / build-and-test (pull_request) Successful in 47s
CI / sanitizers (address) (pull_request) Successful in 4s
2026-07-19 16:44:01 +02:00
TapTap dc7ada552b fix: const-correct protocol send functions, remove duplicate typedef, null check
CI / lint (push) Failing after 6s
CI / build-and-test (push) Has been skipped
CI / sanitizers (address) (push) Has been skipped
CI / lint (pull_request) Failing after 5s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
- send_n_data: void* data → const void* data
- send_str: char* data → const char* data
- send_data: Data* data → const Data* data
- Remove duplicate typedef struct ssl_st SSL in protocol.h
- Add NULL check after malloc in directory_scanner_create
2026-07-19 16:40:47 +02:00
TapTap 5dfc262cf7 fix: scanner leak, remove TSan (Docker incompatible)
CI / lint (push) Successful in 6s
CI / lint (pull_request) Successful in 5s
CI / build-and-test (push) Successful in 48s
CI / sanitizers (address) (push) Successful in 5s
CI / build-and-test (pull_request) Successful in 47s
CI / sanitizers (address) (pull_request) Successful in 4s
- Fix ArrayList leak in directory_scanner_next when no files found
- Remove TSan from CI matrix (Docker 'unexpected memory mapping')
- Keep ASan which now passes clean
2026-07-19 16:22:16 +02:00
TapTap ba6d42ea2d fix: const-correct local Config* in multiprocessing.c for cppcheck
CI / lint (push) Successful in 5s
CI / lint (pull_request) Successful in 6s
CI / build-and-test (push) Successful in 47s
CI / sanitizers (address) (push) Failing after 4s
CI / sanitizers (thread) (push) Failing after 4s
CI / build-and-test (pull_request) Successful in 47s
CI / sanitizers (address) (pull_request) Failing after 4s
CI / sanitizers (thread) (pull_request) Failing after 5s
2026-07-19 16:16:28 +02:00
TapTap 256e1d7567 fix: const-correct receive_incremental_check for cppcheck
CI / lint (push) Failing after 6s
CI / build-and-test (push) Has been skipped
CI / sanitizers (address) (push) Has been skipped
CI / sanitizers (thread) (push) Has been skipped
CI / lint (pull_request) Failing after 5s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (thread) (pull_request) Has been skipped
2026-07-19 16:13:47 +02:00
TapTap f899085de4 fix: reformat queue.c/queue.h after const-correctness change
CI / lint (push) Failing after 2s
CI / build-and-test (push) Has been skipped
CI / sanitizers (address) (push) Has been skipped
CI / sanitizers (thread) (push) Has been skipped
CI / lint (pull_request) Failing after 2s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (thread) (pull_request) Has been skipped
2026-07-19 16:06:57 +02:00
TapTap 23b1d6660c fix: reformat codebase and fix const-correctness for CI lint
CI / lint (push) Failing after 16s
CI / build-and-test (push) Has been skipped
CI / sanitizers (address) (push) Has been skipped
CI / sanitizers (thread) (push) Has been skipped
CI / lint (pull_request) Failing after 44s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (thread) (pull_request) Has been skipped
- Reformat all C/H files to match .clang-format (LLVM style)
- Fix 26 cppcheck const-correctness warnings (constParameterPointer,
  constVariablePointer, constVariable)
- Update function declarations in headers to match const parameters
2026-07-19 15:57:31 +02:00
TapTap 02266710fb ci: add static analysis, sanitizers, and formatting enforcement
CI / lint (push) Failing after 16s
CI / build-and-test (push) Has been skipped
CI / sanitizers (address) (push) Has been skipped
CI / sanitizers (thread) (push) Has been skipped
CI / lint (pull_request) Failing after 30s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (thread) (pull_request) Has been skipped
Add Tier 1 review automation to catch issues before human review:

- Add cppcheck and clang-format to CI lint job
- Add sanitizer matrix (ASan + TSan) CI job
- Enable -Wextra -Wpedantic -Werror in CI build
- Add SANITIZER and STRICT_WARNINGS CMake options
- Add .clang-format for consistent code style
- Update Dockerfile with cppcheck and clang-format
- Fix sign-compare and unused-parameter warnings for -Werror
2026-07-19 15:37:18 +02:00
TapTap 12557c351c refactor: replace vendored xxhash.h with CMake FetchContent dependency
CI / build-and-test (push) Successful in 33s
CI / build-and-test (pull_request) Successful in 32s
Remove 7490-line vendored xxhash.h, use FetchContent to pull xxHash v0.8.3
at CMake configure time (SOURCE_SUBDIR cmake_unofficial). Links as static
library via the xxhash target.
2026-07-19 15:21:35 +02:00
TapTap 598e4e7514 fix: address PR review - rolling adler32, extract helpers, configurable max file size
CI / build-and-test (push) Successful in 29s
CI / build-and-test (pull_request) Successful in 28s
- Fix rolling adler32: add missing -1 in s2 update formula (was producing
  wrong checksums, causing zero block matches)
- Fix file_send_sendfile signature to match typedef (add unused
  compression_level param)
- Extract receive_delta_file() from receive_incremental_check() to reduce
  nesting depth
- Extract send_file_incremental() helper in client_send.c
- Add delta_max_file_size to Config, serialized over wire
- Add --delta-max CLI flag
- Add test_large_file_delta (200KB) and extra delta_should_attempt cases
- Remove unused pos_in_block variable from delta_compute
2026-07-19 02:02:28 +02:00
TapTap e16db56580 feat: add delta transfer for incremental sync
CI / build-and-test (push) Successful in 28s
CI / build-and-test (pull_request) Successful in 28s
Implement rsync-style delta transfer using rolling checksums (Adler-32 +
xxHash32). When a file exists on both sides but has changed, only the
changed blocks are transmitted instead of the entire file.

- New status codes: STATUS_DELTA_SIGNATURE, STATUS_DELTA_DATA
- Protocol version bumped to 1.2.0
- Server generates block signature, client computes delta
- Auto-fallback to whole-file when delta >= 70% of file size
- Works with zstd compression on delta stream
- Configurable block size (default 8KB, --delta-block flag)
- 13 unit tests covering hashing, signature roundtrip, delta compute/apply,
  file growth/shrink, and decision logic
2026-07-18 20:00:15 +02:00
TapTap 907baf3379 fix: initialize ssl/ssl_ctx in client_connect_ssh to prevent use-after-free
CI / build-and-test (push) Failing after 3s
CI / build-and-test (pull_request) Failing after 3s
2026-07-18 17:39:37 +02:00
TapTap 8b6550f8c6 fix: io_set_ssl NULL in client_disconnect, SSL* type safety in protocol.h 2026-07-18 17:39:37 +02:00
TapTap 20ede4391c Fix re-review: remove __thread from io_ssl (breaks -m), strtol port parsing, --ca warning 2026-07-18 17:39:37 +02:00
TapTap 864eb1316d Fix TLS code review issues: SSL cleanup, TLS 1.2 min, CA verify, deprecation guards, server --help, port validation, __thread io_ssl, shared accept loop 2026-07-18 17:39:37 +02:00
TapTap eff50346fd TLS transport: OpenSSL-based encrypted TCP
- New transport_tls.h/c: TLS server (server_create_tls, server_listen_tls)
  and client (client_connect_tls) using OpenSSL
- protocol.c: io_set_ssl() + SSL_read/SSL_write in send_n_data/receive_n_data
- transport_tcp.h: ssl/ssl_ctx fields added to Server/Client structs
- config.h/c: use_tls, tls_cert, tls_key fields
- client_cli.c: --tls, --cert, --key flags
- server.c: --tls, --cert, --key, -p flags with TLS support
- CMakeLists.txt: OpenSSL::SSL + OpenSSL::Crypto linkage
- shell.nix: openssl added to buildInputs
2026-07-18 17:38:55 +02:00
TapTap 46c650e9ae refactor: consolidate _no_path file send variants
CI / build-and-test (push) Successful in 26s
CI / build-and-test (pull_request) Successful in 26s
Add bool send_path parameter to file_send_single_calls and
file_send_sendfile, remove the _no_path variants. Callers in
client_send.c pass true (send path) or false (skip path) based
on whether an incremental check already transmitted the path.
2026-07-18 17:27:33 +02:00
TapTap 7876721906 refactor: extract receive_chunk_data and receive_manifest shared helpers
- receive_chunk_data(fd, config) -> Chunk*: shared receive/decompress/deserialize
  (eliminates ~25 lines of duplication between server.c and multiprocessing.c)
- receive_manifest(fd, config, next_status): moved from server.c to file.c,
  fixes missing 'Deleting files not in manifest...' log in multiprocessing.c
- Removes redundant manual free loop in multiprocessing.c manifest handling
  (array_list_create(free) destructor already handles this)
- server.c and multiprocessing.c: remove local chunk/manifest helpers,
  remove compression.h include (no longer needed)
2026-07-18 17:19:12 +02:00
TapTap 5ed12f2bf0 refactor: deduplicate server receive logic, extract shared helpers
- Extract file_save_to_disk() helper (replaces 4x duplicated disk-save boilerplate)
- Extract receive_incremental_check() shared helper (deduplicates STATUS_CHECK
  handling between server.c single-threaded and multiprocessing.c multi-threaded paths)
- Break receive_files() into receive_chunk() and receive_manifest() sub-handlers
- Add incremental sync test case to test.py
- Rebase onto main
2026-07-18 17:19:12 +02:00
TapTap 03d6ba0da5 fix: address review #69 - STATUS_ERROR sends, metadata_receive error handling, extract incremental_check helper 2026-07-18 17:19:12 +02:00
TapTap f1af88a25c Fix incremental-sync review: sendfile_no_path, reject -s+incremental, no data mutation, auto -M, STATUS_ERROR handling, PROTOCOL_VERSION bump 2026-07-18 17:19:12 +02:00
TapTap 1905369c9f Incremental sync: --incremental flag to skip unchanged files
- New STATUS_CHECK protocol status (value 6)
- Client sends path + size + mtime; server replies OK (skip) or NEXT (send)
- config.h/c: use_incremental field sent/received over wire
- file.c/h: file_send_single_calls_no_path helper for incremental path
- client_cli.c: --incremental flag
- client_send.c: per-file check before send in both single and chunk paths
- server.c: STATUS_CHECK handling in receive_files()
- multiprocessing.c: STATUS_CHECK handling in receive_thread()
- test.py: incremental sync test case
2026-07-18 17:19:12 +02:00
TapTap 4f8ae5bb70 fix: bw_tokens initialized to io_bwlimit, overflow check for --bwlimit 2026-07-17 10:07:18 +02:00
TapTap 3dcaf0b79d Fix bwlimit review: remove __thread (breaks -m), validate >0, handle nanosleep EINTR 2026-07-16 17:00:14 +02:00
TapTap 09a76e2a9a Bandwidth throttling: --bwlimit <KB/s> with token bucket
- protocol.h/c: io_set_bwlimit() + token bucket in send_n_data
  (64KB chunks, nanosleep-based deficit compensation)
- client_cli.c: --bwlimit <KB/s> flag
- test.py: bandwidth limit test case
2026-07-16 15:42:16 +02:00
TapTap a62894be05 Merge main into server-improvements: resolve conflicts (protocol signatures, error returns) 2026-07-16 15:08:56 +02:00
TapTap bbdf027be8 Fix exit() in library code, add --include/--max-size/--min-size 2026-07-16 14:15:38 +02:00
TapTap efb98d8964 Multi-client server, protocol versioning, streaming decompression fixes 2026-07-16 13:59:41 +02:00
TapTap 2ff51246c3 Update README and add feature tests for rsync-compatible flags 2026-07-16 13:31:43 +02:00
TapTap 284bf8f8bc rsync flags: -a, -n, -p, --exclude, --delete
Feature changes across 15 files:

- -a/--archive: enables -c -m -M (no -s, which slows transfers)
- -n/--dry-run: scan + print without connecting or transferring
- -p <port>: custom SSH port (passed as -p to ssh via execvp)
- --exclude <pattern>: glob-based filename filtering in scanner
- --delete: sender collects file manifest; receiver deletes unlisted files

Protocol: added STATUS_MANIFEST, use_delete field in Config wire format.
New utilities: glob_match(), delete_extras() with recursive directory walk.
Scanner: accepts exclude patterns; skips matching entries.
SSH transport: switched from execlp to execvp for dynamic port arg.
Server + multiprocessing: handle STATUS_MANIFEST in both single and
multithreaded receive paths.

Builds clean, all 7 tests pass.
2026-07-16 12:39:05 +02:00
TapTap f778d1903c Merge pull request 'Streaming zstd: switch to ZSTD_compressStream2 / ZSTD_decompressStream' (#7) from streaming-zstd into main
Reviewed-on: #7
2026-07-16 12:31:49 +02:00
TapTap 52571bc960 streaming zstd: switch to ZSTD_compressStream2 / ZSTD_decompressStream
Replaced one-shot ZSTD_compress / ZSTD_decompress with streaming
API (ZSTD_compressStream2 + ZSTD_decompressStream) in both
data_compress and data_decompress. Interface unchanged.

Prepares for true streaming transfer where compression can be
interleaved with transmission.
2026-07-16 12:29:31 +02:00
TapTap d1a23fc4df quick-wins: ControlMaster, -z alias, --progress, fix write warning
- SSH ControlMaster auto with ControlPath for connection reuse
- -z as alias for -c (compression)
- --progress flag showing transfer rate in send_files
- Fixed unused-result warning on write() in transport_ssh.c
2026-07-16 12:28:16 +02:00
TapTap ca29109664 perf: downsized test data, increased SSH socket buffer, and made chunk size configurable
- Reduced test data from 50MB to 25MB (test.py)
- Increased SSH socketpair buffer to 1MB via setsockopt (transport_ssh.c)
- Made chunk size configurable: new Config field, --chunk-size CLI flag,
  sent over wire, and used in scanner instead of DESIRED_CHUNK_SIZE
- Fixed DESIRED_CHUNK_SIZE macro parentheses (chunk.h)
2026-07-16 12:20:02 +02:00
TapTap 8f4ea62ae7 Phase 1+2: bug fixes and dead code cleanup
Phase 1 — Bugs:
- receive_data: fix unsigned long long vs size_t mismatch
- chunk_deserialize: add NULL check in multiprocessing.c and server.c
- file_content_to_buffer: add missing fclose on error path
- send_files_multithreaded: propagate sender thread result
- server: add SIGPIPE handler
- to_disk: check fwrite return value
- scanner: use S_ISDIR instead of !S_ISREG
- scanner: free cur_path before early return

Phase 2 — Cleanup:
- Remove unused chunk_decompress function
- Remove unused array_list_clear function
- Remove unused num_connections config field
- Remove duplicate FILE_METADATA_WIRE_SIZE macro
- Update tests for removed APIs
2026-07-16 12:08:09 +02:00
TapTap d36768792a fixup: address PR review comments
- Merge io.h/c back into protocol.h/c
- Change send_data to take Data* argument
- Remove redundant file_load_data from send_chunk
- Move compression into file_send_single_calls
- Move file_receive from multiprocessing.c to file.c
2026-07-16 11:54:20 +02:00
TapTap 02619cca5c refactor: split monolithic modules and extract shared components
- Remove dead socket.c/socket.h (accumulated duplicate symbols)
- Extract compression.h/c (data_compress/decompress from data.c)
- Extract io.h/c (low-level I/O from protocol.c)
- Extract metadata.h/c (unified metadata wire format from file.c, chunk.c, utils.c)
- Split client.c into client_cli.c (CLI parsing) + client_send.c (send logic)
- Move receiver pipeline threads from server.c to multiprocessing.c
- Move to_disk/file_restore_metadata from utils.c to file.c/metadata.c
- Fix const qualifiers on to_disk and str_dup signatures
- Suppress chown unused-result warning
2026-07-15 19:36:26 +02:00
TapTap b3f69208ce cleanup: remove dead code, fix bugs, refactor SSH dest parsing
- Remove debug printf calls from file.c
- Remove dead code: chunk_print, chunk_format, chunk_data_create/delete
- Remove unused config.use_single_send_per_file field
- Fix server_delete() no-op (double-pointer)
- Fix double cast (long)(long) -> ptrdiff_t in chunk.c
- Fix thread return value: thrd_error instead of 1
- Remove unused config param from receive_chunk_enqueue()
- Make queue_double_capacity() static
- Move SSH dest parsing into config.c as config_parse_ssh_dest()
- Fix test_config_ssh_dest to test parsing round-trip
- Remove chunk_format test (obsolete format)
- Replace chunk_data_delete with data_destroy in tests
2026-07-07 19:07:24 +02:00
TapTap a96d48f0ed feat: default log level to WARNING, add -v/--verbose flag 2026-07-06 20:26:20 +02:00
TapTap 372c559ef2 fix: SSH transport - log to stderr, use-after-free, systemd scope conflict 2026-07-06 20:15:36 +02:00
TapTap 1012c5c151 refactor: address PR review feedback
- Replace FASTSYNC_SERVER_IP/FASTSYNC_SERVER_PORT env vars with
  --server-host and --server-port CLI flags
- Simplify STATUS_OK handshake: single disconnect/delete path
- Remove hardcoded default directory (require explicit source/dest)
- Clean up free(NULL) on positional args path
- Fix send_files() resource leak on STATUS_OK failure
2026-07-06 19:54:22 +02:00
TapTap fbd7ccf4dd feat: add SSH transport, rsync-style CLI, and --stdio server mode
- Replace send()/recv() with read()/write() + io_set_fds() for fd abstraction
- Add client_connect_ssh() via socketpair + fork/exec; reap child in client_disconnect()
- Add server --stdio flag for SSH invocation
- Replace handle_arg() with rsync-style positional args (fastsync <src> <dest>)
- Add SSH vs TCP auto-detection via is_remote_dest()
- Add TransportType and ssh_destination to Config, fix uninitialized fields in
  config_receive() (pre-existing multithreaded crash)
- Sender threads now wait for server STATUS_OK before disconnecting
- Add --help, error handling for sendfile+SSH combos
- Add pre-flight checks and Posix Args test case to test.py
- Add test_config_ssh_dest() unit test
2026-07-06 18:42:33 +02:00
TapTap c55d89c40f fix: sendfile path now conditionally sends metadata 2026-07-05 20:52:18 +02:00