Old rsync version archive
Static rsync binaries built from historical release tags. Two uses:
- Cross-version behaviour checks - confirming whether a behaviour a user reported on an old release is version-specific or option-driven.
- The version-mixing test suite:
testsuite/runtests.py --rsync-bin2=...runs the current code against one of these as the daemon or remote-shell peer. CI (.github/workflows/ubuntu-version-mix.yml) exercises every binary against its peer profile intestsuite/profiles/.
Binaries are statically linked so they run regardless of the host's shared libraries and named rsync_<version>:
| Binary | Version | Protocol | Notes |
|---|---|---|---|
| rsync_2.6.0 | 2.6.0 | 27 | 2004; needs autoconf regeneration |
| rsync_3.0.0 | 3.0.0 | 30 | 2008 |
| rsync_3.1.0 | 3.1.0 | 31 | 2013 |
| rsync_3.1.3 | 3.1.3 | 31 | Ubuntu 18.04 and Debian Buster era, 2018 |
| rsync_3.2.0 | 3.2.0 | 31 | 2020; zstd, lz4 and xxhash negotiation added |
| rsync_3.2.7 | 3.2.7 | 31 | 2022 |
| rsync_3.3.0 | 3.3.0 | 31 | 2024 |
| rsync_3.4.0 | 3.4.0 | 32 | 2025 |
| rsync_3.4.1 | 3.4.1 | 32 | 2025 |
These are every x.y.0 release from 2.6.0 (2004) onward plus a few point releases. 2.6.0 is the practical floor: older tags need progressively more porting to build on a current toolchain.
All built --disable-openssl and with _FORTIFY_SOURCE disabled (see below); xxhash/zstd/lz4 are compiled in where the version supports them.
Adding a version
./build_static.sh 3.2.7 # uses git tag v3.2.7
./build_static.sh 3.0.9 v3.0.9 # explicit tag if naming differs
The script checks out the tag into a throwaway git worktree, applies the minimal patches needed to compile old sources on a modern toolchain, links statically and verifies the result. It then installs rsync_<version> here and removes the worktree.
Override the source repo with RSYNC_REPO=/path/to/rsync ./build_static.sh ... (defaults to ../rsync.4).
Why the patches?
Modern GCC (>= 14, C23 default) and glibc reject things old rsync relied on. build_static.sh handles these, each guarded so it's a no-op when not needed:
-
K&R
lseek64()redeclaration insyscall.cclashes with glibc's real prototype - removed. -
gettimeofday()- glibc only has the 2-arg form; configure misdetects the 1-arg form, soHAVE_GETTIMEOFDAY_TZis forced on inconfig.h. -
C23
()==(void)breaks K&R prototypes called with arguments such as theqsortcomparator andpool->bomb- built with-std=gnu11. -
Assorted modern
-Werrorpromotions (incompatible pointer types, implicit declarations) downgraded to warnings; bundled zlib/popt used to keep the static link self-contained. -
OpenSSL (3.2+) is disabled with
--disable-openssl: linkinglibcrypto.astatically drags in jitterentropy (jent_*) and zlib'suncompress(OpenSSL's COMP module), which don't resolve here. OpenSSL only provided optional MD4/MD5, which rsync implements natively, so checksum behaviour is unaffected. -
_FORTIFY_SOURCEdisabled (-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0): modern Ubuntu defaults it to=3, whose stricter object-size checks turn latent (historically benign) over-reads in OLD rsync into hard*** buffer overflow detected ***aborts when the binary runs as a server or daemon - which made 3.1.3 and 3.2.7 unusable as peers. Disabling it makes the archival binaries behave as the released versions did. -
Pre-3.0 tags such as 2.6.0 ship
configure.in, not a generatedconfigure. The script runsautoheader/autoconfto generate it, after neutralizing theAC_CHECK_FUNCS(fn,,AC_LIBOBJ(lib/...))fallbacks forinet_ntop/inet_pton/getaddrinfo/getnameinfo- modern autoconf emits broken shell for those never-taken branches (the funcs exist in glibc). It also generatesproto.h(no make rule in that era) and stubs the vendoredlib/addrinfo.hthe tag dropped (modern glibc suppliesstruct addrinfo). All guarded so they no-op on 3.x.
Newer versions may need fewer or different tweaks; if a build fails, the script prints the first compiler errors from its log.