Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc63ea82f2 | ||
|
|
0d4fb1bc89 | ||
|
|
52480aaac2 | ||
|
|
702a8f61b7 | ||
|
|
2928b2742e | ||
|
|
f1d5a3c815 | ||
|
|
3086dbc0fd | ||
|
|
63e599b921 | ||
|
|
340238421d | ||
|
|
31fbb17d23 | ||
|
|
edf298ace5 | ||
|
|
1d5b5ab83a | ||
|
|
b0ba699031 | ||
|
|
e57c7f5d87 | ||
|
|
05f30c05c9 | ||
|
|
922681e140 | ||
|
|
273b9f265f | ||
|
|
0d546ee3b4 | ||
|
|
d6124a82a4 | ||
|
|
1d828f35ca | ||
|
|
7bba25e675 | ||
|
|
6e3140d5ba | ||
|
|
1d8f47cc71 | ||
|
|
743d715d43 | ||
|
|
4b862306e5 | ||
|
|
70948a9dc3 | ||
|
|
951bf0a446 | ||
|
|
bea8a3a16f | ||
|
|
bf8aab51e8 | ||
|
|
1f689ec0c2 | ||
|
|
8839314025 | ||
|
|
47e087d8eb | ||
|
|
e1c5f0e93a | ||
|
|
cfdc27c613 | ||
|
|
7e7372a0c5 | ||
|
|
8cad2097e9 | ||
|
|
d039cfa829 | ||
|
|
0af88421dc | ||
|
|
9d014670df | ||
|
|
647a00a278 |
7
.gitattributes
vendored
@@ -1 +1,8 @@
|
|||||||
* text=auto eol=lf
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
# The rsync-web/ subdirectory holds the project website source content
|
||||||
|
# (mirrors what gets pushed to https://rsync.samba.org). Exclude it from
|
||||||
|
# `git archive` output so the release source tarball produced by
|
||||||
|
# packaging/release.py step_7_tarball does not bloat with HTML the
|
||||||
|
# tarball doesn't need.
|
||||||
|
/rsync-web/ export-ignore
|
||||||
|
|||||||
9
.github/workflows/almalinux-8-build.yml
vendored
@@ -59,8 +59,13 @@ jobs:
|
|||||||
run: ./rsync --version
|
run: ./rsync --version
|
||||||
- name: check
|
- name: check
|
||||||
# In the container we already run as root, so no sudo. The
|
# In the container we already run as root, so no sudo. The
|
||||||
# crtimes-not-supported skip matches the other Linux jobs.
|
# crtimes-not-supported skip matches the other Linux jobs;
|
||||||
run: RSYNC_EXPECT_SKIPPED=crtimes make check
|
# daemon-chroot-acl and proxy-response-line-too-long skip because
|
||||||
|
# the default (secure) transport opens no listening socket.
|
||||||
|
run: RSYNC_EXPECT_SKIPPED=crtimes,daemon-access-ip,daemon-chroot-acl,proxy-response-line-too-long make check
|
||||||
|
- name: check (TCP daemon transport)
|
||||||
|
# Second run exercising the real loopback-TCP daemon path.
|
||||||
|
run: ./runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
|
||||||
- name: ssl file list
|
- name: ssl file list
|
||||||
run: ./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
run: ./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||||
- name: save artifact
|
- name: save artifact
|
||||||
|
|||||||
120
.github/workflows/android-static-build.yml
vendored
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
name: Build static rsync for Android
|
||||||
|
|
||||||
|
# Cross-compiles statically-linked rsync binaries with the Android NDK,
|
||||||
|
# suitable for dropping onto a phone (adb push / Termux) with no shared
|
||||||
|
# libraries. arm64-v8a covers all modern phones; armeabi-v7a covers older
|
||||||
|
# 32-bit devices. The binaries are uploaded as workflow artifacts.
|
||||||
|
#
|
||||||
|
# These are cross-compiled, so the test suite can't run here; we sanity
|
||||||
|
# check that each binary is the right architecture, is static, and that
|
||||||
|
# it executes (`--version`) under qemu-user.
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/workflows/*.yml'
|
||||||
|
- '!.github/workflows/android-static-build.yml'
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/workflows/*.yml'
|
||||||
|
- '!.github/workflows/android-static-build.yml'
|
||||||
|
schedule:
|
||||||
|
- cron: '42 8 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Minimum supported API level. 24 (Android 7.0) runs on every modern
|
||||||
|
# phone while keeping broad reach; bump if you need newer Bionic APIs.
|
||||||
|
ANDROID_API: 24
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: ${{ matrix.abi }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- abi: arm64-v8a # modern phones
|
||||||
|
triple: aarch64-linux-android
|
||||||
|
qemu: qemu-aarch64-static
|
||||||
|
- abi: armeabi-v7a # older 32-bit phones
|
||||||
|
triple: armv7a-linux-androideabi
|
||||||
|
qemu: qemu-arm-static
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Install build prerequisites
|
||||||
|
run: sudo apt-get update && sudo apt-get install -y autoconf automake gawk qemu-user-static
|
||||||
|
|
||||||
|
- name: Configure and build (${{ matrix.abi }})
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
NDK="${ANDROID_NDK_LATEST_HOME:-$ANDROID_NDK_ROOT}"
|
||||||
|
TC="$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin"
|
||||||
|
export CC="$TC/${{ matrix.triple }}${ANDROID_API}-clang"
|
||||||
|
export AR="$TC/llvm-ar" RANLIB="$TC/llvm-ranlib" STRIP="$TC/llvm-strip"
|
||||||
|
export CFLAGS="-O2" LDFLAGS="-static"
|
||||||
|
|
||||||
|
# Bionic doesn't declare lchmod()/lutimes() until API 36, but the
|
||||||
|
# symbols link, so configure mis-detects them -- force them off so
|
||||||
|
# rsync uses its fallbacks. The other cache vars restore values
|
||||||
|
# that configure can't probe when cross-compiling (Android runs a
|
||||||
|
# normal Linux kernel, so these match the native Linux result).
|
||||||
|
export ac_cv_func_lchmod=no ac_cv_func_lutimes=no \
|
||||||
|
rsync_cv_HAVE_SOCKETPAIR=yes \
|
||||||
|
rsync_cv_MKNOD_CREATES_FIFOS=yes \
|
||||||
|
rsync_cv_MKNOD_CREATES_SOCKETS=yes
|
||||||
|
|
||||||
|
# Self-contained build: drop optional external libraries so the
|
||||||
|
# static binary needs nothing at runtime. rsync keeps md5/md4
|
||||||
|
# checksums and its bundled zlib.
|
||||||
|
./configure --host=${{ matrix.triple }} --build=x86_64-pc-linux-gnu \
|
||||||
|
--enable-ipv6 \
|
||||||
|
--disable-zstd --disable-lz4 --disable-xxhash --disable-openssl \
|
||||||
|
--disable-iconv --disable-iconv-open \
|
||||||
|
--disable-acl-support --disable-xattr-support \
|
||||||
|
--disable-md2man --disable-roll-simd \
|
||||||
|
--with-included-popt --with-included-zlib
|
||||||
|
|
||||||
|
# Generate the awk-built headers serially first so the parallel
|
||||||
|
# build can't race on proto.h <- daemon-parm.h.
|
||||||
|
make proto.h
|
||||||
|
make -j"$(nproc)" rsync
|
||||||
|
"$STRIP" rsync
|
||||||
|
|
||||||
|
- name: Verify binary
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
file rsync
|
||||||
|
# Gate: must be a statically-linked executable (no interpreter).
|
||||||
|
file rsync | grep -q "statically linked"
|
||||||
|
if file rsync | grep -q "dynamically linked"; then
|
||||||
|
echo "ERROR: binary is not static" >&2; exit 1
|
||||||
|
fi
|
||||||
|
# Best-effort: confirm it actually runs under qemu-user.
|
||||||
|
${{ matrix.qemu }} ./rsync --version | head -3 || \
|
||||||
|
echo "WARNING: qemu smoke test did not run cleanly (check on a real device)"
|
||||||
|
|
||||||
|
- name: Package
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
VER=$(sed -n 's/.*RSYNC_VERSION "\([^"]*\)".*/\1/p' version.h)
|
||||||
|
out="rsync-${VER}-android-${{ matrix.abi }}"
|
||||||
|
mkdir -p dist
|
||||||
|
cp rsync "dist/$out"
|
||||||
|
( cd dist && sha256sum "$out" > "$out.sha256" )
|
||||||
|
echo "ARTIFACT_NAME=rsync-android-${{ matrix.abi }}" >>"$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ env.ARTIFACT_NAME }}
|
||||||
|
path: dist/
|
||||||
71
.github/workflows/coverage.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
name: Coverage (Ubuntu)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/workflows/*.yml'
|
||||||
|
- '!.github/workflows/coverage.yml'
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/workflows/*.yml'
|
||||||
|
- '!.github/workflows/coverage.yml'
|
||||||
|
schedule:
|
||||||
|
- cron: '42 9 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
coverage:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: gcov coverage
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: prep
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y acl libacl1-dev attr libattr1-dev liblz4-dev libzstd-dev libxxhash-dev python3-cmarkgfm openssl gcovr
|
||||||
|
echo "/usr/local/bin" >>$GITHUB_PATH
|
||||||
|
- name: configure
|
||||||
|
run: ./configure --enable-coverage --with-rrsync
|
||||||
|
- name: make
|
||||||
|
run: make
|
||||||
|
- name: info
|
||||||
|
run: rsync --version
|
||||||
|
# Two coverage runs: the default pipe transport, then a second pass over a
|
||||||
|
# real loopback rsyncd (--use-tcp) which also exercises the require_tcp-only
|
||||||
|
# tests. gcovr's --print-summary line/branch/decision totals go to the step
|
||||||
|
# log (and the job summary below), so the numbers are visible in CI.
|
||||||
|
# `make coverage` exits with the suite's status, so a regression fails CI.
|
||||||
|
- name: coverage (pipe transport)
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
sudo make coverage 2>&1 | tee cov-pipe.log
|
||||||
|
- name: coverage (TCP transport)
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
sudo make coverage-tcp 2>&1 | tee cov-tcp.log
|
||||||
|
- name: coverage summary
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
{
|
||||||
|
echo "## gcov coverage"
|
||||||
|
echo "### Pipe transport (\`make coverage\`)"
|
||||||
|
echo '```'
|
||||||
|
grep -E '^(lines|functions|branches|decisions):' cov-pipe.log || echo '(no summary -- see step log)'
|
||||||
|
echo '```'
|
||||||
|
echo "### TCP transport (\`make coverage-tcp\`)"
|
||||||
|
echo '```'
|
||||||
|
grep -E '^(lines|functions|branches|decisions):' cov-tcp.log || echo '(no summary -- see step log)'
|
||||||
|
echo '```'
|
||||||
|
} >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
- name: upload HTML reports
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: coverage-html
|
||||||
|
path: |
|
||||||
|
coverage
|
||||||
|
coverage-tcp
|
||||||
11
.github/workflows/cygwin-build.yml
vendored
@@ -39,7 +39,16 @@ jobs:
|
|||||||
- name: info
|
- name: info
|
||||||
run: bash -c '/usr/local/bin/rsync --version'
|
run: bash -c '/usr/local/bin/rsync --version'
|
||||||
- name: check
|
- name: check
|
||||||
run: bash -c 'RSYNC_EXPECT_SKIPPED=acls-default,acls,bare-do-open-symlink-race,chdir-symlink-race,chmod-symlink-race,chown,daemon-chroot-acl,devices,dir-sgid,open-noatime,protected-regular,sender-flist-symlink-leak,simd-checksum,symlink-dirlink-basis make check'
|
# chown-fake / devices-fake / xattrs / xattrs-hlink now RUN on Cygwin
|
||||||
|
# (rsyncfns.py drives xattrs via getfattr/setfattr from the `attr`
|
||||||
|
# package installed above), verified on a real Cygwin host. The real
|
||||||
|
# chown/devices tests still skip (need root/mknod), as do the
|
||||||
|
# RESOLVE_BENEATH symlink-race tests.
|
||||||
|
run: bash -c 'RSYNC_EXPECT_SKIPPED=acls-default,acls-depth,acls,bare-do-open-symlink-race,chdir-symlink-race,chown,daemon-access-ip,daemon-chroot-acl,devices,dir-sgid,open-noatime,protected-regular,proxy-response-line-too-long,sender-flist-symlink-leak,simd-checksum,symlink-dirlink-basis make check'
|
||||||
|
- name: check (TCP daemon transport)
|
||||||
|
# Second run with daemon tests over a real loopback rsyncd; the default
|
||||||
|
# 'make check' above uses the secure stdio-pipe transport.
|
||||||
|
run: bash -c './runtests.py --rsync-bin=`pwd`/rsync.exe --use-tcp -j 8'
|
||||||
- name: ssl file list
|
- name: ssl file list
|
||||||
run: bash -c 'PATH="/usr/local/bin:$PATH" rsync-ssl --no-motd download.samba.org::rsyncftp/ || true'
|
run: bash -c 'PATH="/usr/local/bin:$PATH" rsync-ssl --no-motd download.samba.org::rsyncftp/ || true'
|
||||||
- name: save artifact
|
- name: save artifact
|
||||||
|
|||||||
1
.github/workflows/freebsd-build.yml
vendored
@@ -35,6 +35,7 @@ jobs:
|
|||||||
make
|
make
|
||||||
./rsync --version
|
./rsync --version
|
||||||
make check
|
make check
|
||||||
|
./runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
|
||||||
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||||
- name: save artifact
|
- name: save artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
9
.github/workflows/macos-build.yml
vendored
@@ -41,7 +41,14 @@ jobs:
|
|||||||
- name: info
|
- name: info
|
||||||
run: rsync --version
|
run: rsync --version
|
||||||
- name: check
|
- name: check
|
||||||
run: sudo RSYNC_EXPECT_SKIPPED=acls-default,chmod-temp-dir,chown-fake,daemon-chroot-acl,devices-fake,dir-sgid,open-noatime,protected-regular,simd-checksum,xattrs-hlink,xattrs make check
|
# chown-fake / devices-fake / xattrs / xattrs-hlink now RUN on macOS
|
||||||
|
# (rsyncfns.py drives xattrs via the `xattr` command), verified on a
|
||||||
|
# real macOS host, so they're no longer in the skip set.
|
||||||
|
run: sudo RSYNC_EXPECT_SKIPPED=acls-default,acls-depth,chmod-temp-dir,daemon-access-ip,daemon-chroot-acl,dir-sgid,open-noatime,preallocate,protected-regular,proxy-response-line-too-long,simd-checksum,sparse make check
|
||||||
|
- name: check (TCP daemon transport)
|
||||||
|
# Second run with daemon tests over a real loopback rsyncd; the default
|
||||||
|
# 'make check' above uses the secure stdio-pipe transport.
|
||||||
|
run: sudo ./runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
|
||||||
- name: ssl file list
|
- name: ssl file list
|
||||||
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||||
- name: save artifact
|
- name: save artifact
|
||||||
|
|||||||
1
.github/workflows/netbsd-build.yml
vendored
@@ -36,6 +36,7 @@ jobs:
|
|||||||
make
|
make
|
||||||
./rsync --version
|
./rsync --version
|
||||||
make check
|
make check
|
||||||
|
./runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
|
||||||
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||||
- name: save artifact
|
- name: save artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
9
.github/workflows/openbsd-build.yml
vendored
@@ -37,6 +37,15 @@ jobs:
|
|||||||
make
|
make
|
||||||
./rsync --version
|
./rsync --version
|
||||||
make check
|
make check
|
||||||
|
# The --use-tcp daemon tests run at -j2 here (vs -j8 elsewhere): this
|
||||||
|
# job runs inside a nested VM, and at -j8 the many concurrent loopback
|
||||||
|
# daemons occasionally lose a connection-handshake timing race under
|
||||||
|
# that resource pressure, hanging one test to the 300s timeout. It is
|
||||||
|
# an environment artifact, not an rsync bug (the handshake is
|
||||||
|
# deadlock-free and unreproducible elsewhere, even pinned to 1 CPU at
|
||||||
|
# -j8); -j2 keeps the VM from over-subscribing. The pipe `make check`
|
||||||
|
# above stays at the default parallelism.
|
||||||
|
./runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 2
|
||||||
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||||
- name: save artifact
|
- name: save artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
1
.github/workflows/solaris-build.yml
vendored
@@ -35,6 +35,7 @@ jobs:
|
|||||||
make
|
make
|
||||||
./rsync --version
|
./rsync --version
|
||||||
make check
|
make check
|
||||||
|
./runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
|
||||||
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
./rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||||
- name: save artifact
|
- name: save artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
10
.github/workflows/ubuntu-22.04-build.yml
vendored
@@ -39,11 +39,15 @@ jobs:
|
|||||||
- name: info
|
- name: info
|
||||||
run: rsync --version
|
run: rsync --version
|
||||||
- name: check
|
- name: check
|
||||||
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check
|
run: sudo RSYNC_EXPECT_SKIPPED=crtimes,daemon-access-ip,daemon-chroot-acl,proxy-response-line-too-long make check
|
||||||
- name: check30
|
- name: check30
|
||||||
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check30
|
run: sudo RSYNC_EXPECT_SKIPPED=crtimes,daemon-access-ip,daemon-chroot-acl,proxy-response-line-too-long make check30
|
||||||
- name: check29
|
- name: check29
|
||||||
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check29
|
run: sudo RSYNC_EXPECT_SKIPPED=crtimes,daemon-access-ip,daemon-chroot-acl,proxy-response-line-too-long make check29
|
||||||
|
- name: check (TCP daemon transport)
|
||||||
|
# Second run with daemon tests over a real loopback rsyncd; the default
|
||||||
|
# 'make check' above uses the secure stdio-pipe transport.
|
||||||
|
run: sudo ./runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
|
||||||
- name: ssl file list
|
- name: ssl file list
|
||||||
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||||
- name: save artifact
|
- name: save artifact
|
||||||
|
|||||||
12
.github/workflows/ubuntu-build.yml
vendored
@@ -35,11 +35,17 @@ jobs:
|
|||||||
- name: info
|
- name: info
|
||||||
run: rsync --version
|
run: rsync --version
|
||||||
- name: check
|
- name: check
|
||||||
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check
|
run: sudo RSYNC_EXPECT_SKIPPED=crtimes,daemon-access-ip,daemon-chroot-acl,proxy-response-line-too-long make check
|
||||||
- name: check30
|
- name: check30
|
||||||
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check30
|
run: sudo RSYNC_EXPECT_SKIPPED=crtimes,daemon-access-ip,daemon-chroot-acl,proxy-response-line-too-long make check30
|
||||||
- name: check29
|
- name: check29
|
||||||
run: sudo RSYNC_EXPECT_SKIPPED=crtimes make check29
|
run: sudo RSYNC_EXPECT_SKIPPED=crtimes,daemon-access-ip,daemon-chroot-acl,proxy-response-line-too-long make check29
|
||||||
|
- name: check (TCP daemon transport)
|
||||||
|
# Second run with daemon tests over a real loopback rsyncd. The default
|
||||||
|
# 'make check' above uses the secure stdio-pipe transport (no listening
|
||||||
|
# sockets); this run exercises the real TCP accept/auth path. Skip-set
|
||||||
|
# is env-dependent here (chroot-acl), so leave RSYNC_EXPECT_SKIPPED unset.
|
||||||
|
run: sudo ./runtests.py --rsync-bin=`pwd`/rsync --use-tcp -j 8
|
||||||
- name: ssl file list
|
- name: ssl file list
|
||||||
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||||
- name: save artifact
|
- name: save artifact
|
||||||
|
|||||||
16
INSTALL.md
@@ -7,6 +7,22 @@ option to use if you want to just skip that feature. What follows are various
|
|||||||
support libraries that you may want to install to build rsync with the maximum
|
support libraries that you may want to install to build rsync with the maximum
|
||||||
features (the impatient can skip down to the package summary):
|
features (the impatient can skip down to the package summary):
|
||||||
|
|
||||||
|
## Ubuntu users: skip the build, use the PPA
|
||||||
|
|
||||||
|
If you are on a currently supported Ubuntu series (jammy 22.04 LTS, noble
|
||||||
|
24.04 LTS, questing 25.10, resolute 26.04 LTS) and just want the latest
|
||||||
|
upstream rsync, the rsync project maintains a Launchpad PPA that tracks
|
||||||
|
stable releases:
|
||||||
|
|
||||||
|
> sudo add-apt-repository ppa:rsyncproject/rsync
|
||||||
|
> sudo apt update && sudo apt install rsync
|
||||||
|
|
||||||
|
See [the PPA page][ppa] for current build status across architectures.
|
||||||
|
|
||||||
|
[ppa]: https://launchpad.net/~rsyncproject/+archive/ubuntu/rsync
|
||||||
|
|
||||||
|
The rest of this document covers building from source.
|
||||||
|
|
||||||
## The basic setup
|
## The basic setup
|
||||||
|
|
||||||
You need to have a C compiler installed and optionally a C++ compiler in order
|
You need to have a C compiler installed and optionally a C++ compiler in order
|
||||||
|
|||||||
120
Makefile.in
@@ -60,7 +60,8 @@ CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
|
|||||||
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) t_chmod_secure$(EXEEXT) \
|
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) t_chmod_secure$(EXEEXT) \
|
||||||
t_secure_relpath$(EXEEXT) wildtest$(EXEEXT) simdtest$(EXEEXT)
|
t_secure_relpath$(EXEEXT) wildtest$(EXEEXT) simdtest$(EXEEXT)
|
||||||
|
|
||||||
CHECK_SYMLINKS = testsuite/chown-fake.test testsuite/devices-fake.test testsuite/xattrs-hlink.test
|
CHECK_SYMLINKS = testsuite/chown-fake_test.py testsuite/devices-fake_test.py \
|
||||||
|
testsuite/xattrs-hlink_test.py testsuite/exclude-lsh_test.py
|
||||||
|
|
||||||
# Objects for CHECK_PROGS to clean
|
# Objects for CHECK_PROGS to clean
|
||||||
CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o t_chmod_secure.o t_secure_relpath.o trimslash.o wildtest.o
|
CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o t_chmod_secure.o t_secure_relpath.o trimslash.o wildtest.o
|
||||||
@@ -279,6 +280,8 @@ clean: cleantests
|
|||||||
rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) @MAKE_RRSYNC@ \
|
rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) @MAKE_RRSYNC@ \
|
||||||
git-version.h rounding rounding.h *.old rsync*.1 rsync*.5 @MAKE_RRSYNC_1@ \
|
git-version.h rounding rounding.h *.old rsync*.1 rsync*.5 @MAKE_RRSYNC_1@ \
|
||||||
*.html daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
|
*.html daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
|
||||||
|
rm -f *.gcno *.gcda lib/*.gcno lib/*.gcda zlib/*.gcno zlib/*.gcda popt/*.gcno popt/*.gcda
|
||||||
|
rm -rf coverage coverage-tcp coverage-all coverage-fallback
|
||||||
|
|
||||||
.PHONY: cleantests
|
.PHONY: cleantests
|
||||||
cleantests:
|
cleantests:
|
||||||
@@ -319,17 +322,109 @@ test: check
|
|||||||
# catch Bash-isms earlier even if we're running on GNU. Of course, we
|
# catch Bash-isms earlier even if we're running on GNU. Of course, we
|
||||||
# might lose in the future where POSIX diverges from old sh.
|
# might lose in the future where POSIX diverges from old sh.
|
||||||
|
|
||||||
|
# `make check` runs tests in parallel by default. Override with
|
||||||
|
# `make check CHECK_J=1` (serial) or any other value.
|
||||||
|
CHECK_J = 8
|
||||||
|
|
||||||
|
# Parallelism for `make coverage`. Defaults to the same as CHECK_J: the
|
||||||
|
# coverage build sets -fprofile-update=atomic (atomic in-memory counters) and
|
||||||
|
# gcc's libgcov serializes the per-source .gcda read-modify-write merge with a
|
||||||
|
# file lock, so concurrent rsync processes (incl. the forked sender/generator/
|
||||||
|
# receiver) accumulate exactly -- verified by a count-linearity check (a hot
|
||||||
|
# line accumulates identically at -j1 and -P16). Override with
|
||||||
|
# `make coverage COVERAGE_J=1` if your libgcov does not lock .gcda merges.
|
||||||
|
COVERAGE_J = $(CHECK_J)
|
||||||
|
|
||||||
|
# Output directory and extra runtests.py flags for `make coverage`. The
|
||||||
|
# `coverage-tcp` target reuses the coverage recipe with --use-tcp (real
|
||||||
|
# loopback rsyncd, which exercises the TCP accept/auth path and the
|
||||||
|
# require_tcp-only tests) and a separate output directory.
|
||||||
|
COVERAGE_DIR = coverage
|
||||||
|
COVERAGE_RUNFLAGS =
|
||||||
|
|
||||||
|
# Bundled third-party code that rsync ships but does not own; excluded from the
|
||||||
|
# coverage report so the percentages reflect rsync's own source. zlib/ and popt/
|
||||||
|
# are wholly vendored; the named lib/ files are PostgreSQL (getaddrinfo) and ISC
|
||||||
|
# (inet_ntop/inet_pton) / standalone (getpass) imports. The other lib/*.c
|
||||||
|
# (md5, mdfour, wildmatch, permstring, pool_alloc, snprintf, sysacls, sysxattrs,
|
||||||
|
# compat) are rsync's own and stay in the report.
|
||||||
|
COVERAGE_EXCLUDE = -e '(^|/)zlib/' -e '(^|/)popt/' \
|
||||||
|
-e '(^|/)lib/(getaddrinfo|getpass|inet_ntop|inet_pton)\.'
|
||||||
|
|
||||||
.PHONY: check
|
.PHONY: check
|
||||||
check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||||
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT)
|
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(CHECK_J)
|
||||||
|
|
||||||
.PHONY: check29
|
.PHONY: check29
|
||||||
check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||||
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) --protocol=29
|
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(CHECK_J) --protocol=29
|
||||||
|
|
||||||
.PHONY: check30
|
.PHONY: check30
|
||||||
check30: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
check30: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||||
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) --protocol=30
|
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(CHECK_J) --protocol=30
|
||||||
|
|
||||||
|
# Whole-suite gcov coverage report (HTML, with branch + decision coverage).
|
||||||
|
# Requires a build configured with --enable-coverage and the `gcovr` tool
|
||||||
|
# (pip install gcovr). Runs the suite in parallel (COVERAGE_J, default CHECK_J):
|
||||||
|
# this is safe because the coverage build uses -fprofile-update=atomic and
|
||||||
|
# libgcov locks the per-source .gcda during its merge, so concurrent rsync
|
||||||
|
# processes accumulate exactly (see COVERAGE_J above). Use COVERAGE_J=1 if your
|
||||||
|
# toolchain's libgcov does not lock .gcda merges.
|
||||||
|
.PHONY: coverage
|
||||||
|
coverage: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||||
|
@case '$(CFLAGS)' in *--coverage*) ;; \
|
||||||
|
*) echo "*** not a coverage build; reconfigure with --enable-coverage"; exit 1 ;; esac
|
||||||
|
@command -v gcovr >/dev/null 2>&1 || { echo "*** gcovr not found (pip install gcovr)"; exit 1; }
|
||||||
|
find . -name '*.gcda' -delete
|
||||||
|
@rc=0; $(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(COVERAGE_J) $(COVERAGE_RUNFLAGS) || rc=$$?; \
|
||||||
|
rm -rf $(COVERAGE_DIR) && mkdir -p $(COVERAGE_DIR); \
|
||||||
|
gcovr --root $(srcdir) $(COVERAGE_EXCLUDE) --decisions --print-summary \
|
||||||
|
--html-details -o $(COVERAGE_DIR)/index.html . || exit $$?; \
|
||||||
|
echo "Coverage report written to $(COVERAGE_DIR)/index.html"; \
|
||||||
|
if test $$rc != 0; then \
|
||||||
|
echo "*** test suite FAILED (status $$rc) -- coverage report still written above"; \
|
||||||
|
fi; \
|
||||||
|
exit $$rc
|
||||||
|
|
||||||
|
# Same as `make coverage` but with the daemon tests run over a real loopback
|
||||||
|
# rsyncd (--use-tcp), into a separate report directory.
|
||||||
|
.PHONY: coverage-tcp
|
||||||
|
coverage-tcp:
|
||||||
|
$(MAKE) coverage COVERAGE_RUNFLAGS=--use-tcp COVERAGE_DIR=coverage-tcp
|
||||||
|
|
||||||
|
# Comprehensive single report: run the suite under several configurations,
|
||||||
|
# accumulating into the shared .gcda counters (NOT cleared between runs), then
|
||||||
|
# emit one merged, rsync-scoped report. Covers the default (pipe) transport, the
|
||||||
|
# protocol-29/30 compat branches, and the real-TCP daemon path (which also runs
|
||||||
|
# the require_tcp-only tests). Run under sudo to additionally cover root-only
|
||||||
|
# paths (devices, chown, use-chroot, protected-regular). Local target -- CI uses
|
||||||
|
# the plain `coverage`/`coverage-tcp` targets.
|
||||||
|
.PHONY: coverage-all
|
||||||
|
coverage-all: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||||
|
@case '$(CFLAGS)' in *--coverage*) ;; \
|
||||||
|
*) echo "*** not a coverage build; reconfigure with --enable-coverage"; exit 1 ;; esac
|
||||||
|
@command -v gcovr >/dev/null 2>&1 || { echo "*** gcovr not found (pip install gcovr)"; exit 1; }
|
||||||
|
find . -name '*.gcda' -delete
|
||||||
|
@rc=0; \
|
||||||
|
for cfg in '' '--protocol=30' '--protocol=29' '--use-tcp'; do \
|
||||||
|
echo "===== coverage-all: runtests.py $$cfg ====="; \
|
||||||
|
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(COVERAGE_J) $$cfg || rc=$$?; \
|
||||||
|
done; \
|
||||||
|
rm -rf coverage-all && mkdir -p coverage-all; \
|
||||||
|
gcovr --root $(srcdir) $(COVERAGE_EXCLUDE) --decisions --print-summary \
|
||||||
|
--html-details -o coverage-all/index.html . || exit $$?; \
|
||||||
|
echo "Merged coverage report written to coverage-all/index.html"; \
|
||||||
|
if test $$rc != 0; then \
|
||||||
|
echo "*** some suite runs FAILED (status $$rc) -- report still written above"; \
|
||||||
|
fi; \
|
||||||
|
exit $$rc
|
||||||
|
|
||||||
|
# Coverage for the portable (non-openat2) resolver tier. Requires a SEPARATE
|
||||||
|
# build configured with --enable-coverage --disable-openat2: its .gcno differ
|
||||||
|
# from the openat2 build, so this report cannot be merged with the others.
|
||||||
|
.PHONY: coverage-fallback
|
||||||
|
coverage-fallback:
|
||||||
|
$(MAKE) coverage COVERAGE_DIR=coverage-fallback
|
||||||
|
|
||||||
wildtest.o: wildtest.c t_stub.o lib/wildmatch.c rsync.h config.h
|
wildtest.o: wildtest.c t_stub.o lib/wildmatch.c rsync.h config.h
|
||||||
wildtest$(EXEEXT): wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@
|
wildtest$(EXEEXT): wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@
|
||||||
@@ -343,14 +438,17 @@ simdtest$(EXEEXT): simd-checksum-x86_64.cpp $(HEADERS)
|
|||||||
touch $@; \
|
touch $@; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
testsuite/chown-fake.test:
|
testsuite/chown-fake_test.py:
|
||||||
ln -s chown.test $(srcdir)/testsuite/chown-fake.test
|
ln -s chown_test.py $(srcdir)/testsuite/chown-fake_test.py
|
||||||
|
|
||||||
testsuite/devices-fake.test:
|
testsuite/devices-fake_test.py:
|
||||||
ln -s devices.test $(srcdir)/testsuite/devices-fake.test
|
ln -s devices_test.py $(srcdir)/testsuite/devices-fake_test.py
|
||||||
|
|
||||||
testsuite/xattrs-hlink.test:
|
testsuite/xattrs-hlink_test.py:
|
||||||
ln -s xattrs.test $(srcdir)/testsuite/xattrs-hlink.test
|
ln -s xattrs_test.py $(srcdir)/testsuite/xattrs-hlink_test.py
|
||||||
|
|
||||||
|
testsuite/exclude-lsh_test.py:
|
||||||
|
ln -s exclude_test.py $(srcdir)/testsuite/exclude-lsh_test.py
|
||||||
|
|
||||||
# This does *not* depend on building or installing: you can use it to
|
# This does *not* depend on building or installing: you can use it to
|
||||||
# check a version installed from a binary or some other source tree,
|
# check a version installed from a binary or some other source tree,
|
||||||
@@ -358,7 +456,7 @@ testsuite/xattrs-hlink.test:
|
|||||||
|
|
||||||
.PHONY: installcheck
|
.PHONY: installcheck
|
||||||
installcheck: $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
installcheck: $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||||
$(srcdir)/runtests.py --rsync-bin="$(bindir)/rsync$(EXEEXT)" --srcdir="$(srcdir)" --tooldir=`pwd`
|
$(srcdir)/runtests.py --rsync-bin="$(bindir)/rsync$(EXEEXT)" --srcdir="$(srcdir)" --tooldir=`pwd` -j $(CHECK_J)
|
||||||
|
|
||||||
# TODO: Add 'dist' target; need to know which files will be included
|
# TODO: Add 'dist' target; need to know which files will be included
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,15 @@ details.
|
|||||||
[3]: https://rsync.samba.org/lists.html
|
[3]: https://rsync.samba.org/lists.html
|
||||||
|
|
||||||
|
|
||||||
|
DISCORD
|
||||||
|
-------
|
||||||
|
|
||||||
|
There is also an rsync [Discord server][d] for real-time chat about rsync
|
||||||
|
and its development.
|
||||||
|
|
||||||
|
[d]: https://discord.gg/Avfvy9zhdp
|
||||||
|
|
||||||
|
|
||||||
BUG REPORTS
|
BUG REPORTS
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|||||||
10
cleanup.c
@@ -269,8 +269,16 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (called_from_signal_handler)
|
if (called_from_signal_handler) {
|
||||||
|
#ifdef GCOV_COVERAGE
|
||||||
|
/* _exit() bypasses the gcov atexit flush; rsync's generator (and
|
||||||
|
* other processes) normally finish via the signal handler, so
|
||||||
|
* without this they would write no .gcda. Harmless otherwise. */
|
||||||
|
extern void __gcov_dump(void);
|
||||||
|
__gcov_dump();
|
||||||
|
#endif
|
||||||
_exit(exit_code);
|
_exit(exit_code);
|
||||||
|
}
|
||||||
exit(exit_code);
|
exit(exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
26
configure.ac
@@ -82,6 +82,32 @@ if test x"$enable_profile" = x"yes"; then
|
|||||||
CFLAGS="$CFLAGS -pg"
|
CFLAGS="$CFLAGS -pg"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl Coverage build (gcov) for `make coverage`. NOTE: --enable-profile above is
|
||||||
|
dnl gprof (-pg) and is NOT coverage. -O0 keeps branch coverage meaningful;
|
||||||
|
dnl -fprofile-update=atomic keeps the shared .gcda counters correct while the
|
||||||
|
dnl suite runs many rsync processes in parallel.
|
||||||
|
AC_ARG_ENABLE(coverage,
|
||||||
|
AS_HELP_STRING([--enable-coverage],[build with gcov instrumentation for `make coverage`]))
|
||||||
|
if test x"$enable_coverage" = x"yes"; then
|
||||||
|
CFLAGS="$CFLAGS --coverage -fprofile-update=atomic -O0"
|
||||||
|
CXXFLAGS="$CXXFLAGS --coverage -fprofile-update=atomic -O0"
|
||||||
|
LDFLAGS="$LDFLAGS --coverage"
|
||||||
|
AC_DEFINE([GCOV_COVERAGE], 1,
|
||||||
|
[Flush gcov counters at exit_cleanup: rsync's children exit via _exit(), which bypasses the gcov atexit handler, so without this no .gcda is written for the receiver/generator/daemon-worker processes.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl openat2(RESOLVE_BENEATH) is used on Linux 5.6+ for the secure resolver.
|
||||||
|
dnl --disable-openat2 forces the portable per-component O_NOFOLLOW fallback to
|
||||||
|
dnl run as the primary resolver on ordinary Linux, so that tier is exercised
|
||||||
|
dnl (and coverage-counted) without needing a pre-5.6 kernel. Behaviour-neutral
|
||||||
|
dnl by default (the knob only REMOVES a tier when explicitly disabled).
|
||||||
|
AC_ARG_ENABLE(openat2,
|
||||||
|
AS_HELP_STRING([--disable-openat2],[do not use Linux openat2(RESOLVE_BENEATH); force the portable resolver (for exercising the fallback tier)]))
|
||||||
|
if test x"$enable_openat2" != x"no"; then
|
||||||
|
AC_DEFINE([HAVE_OPENAT2], 1,
|
||||||
|
[Define to use Linux openat2(RESOLVE_BENEATH) in secure_relative_open where available.])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_MSG_CHECKING([if md2man can create manpages])
|
AC_MSG_CHECKING([if md2man can create manpages])
|
||||||
if test x"$ac_cv_path_PYTHON3" = x; then
|
if test x"$ac_cv_path_PYTHON3" = x; then
|
||||||
AC_MSG_RESULT(no - python3 not found)
|
AC_MSG_RESULT(no - python3 not found)
|
||||||
|
|||||||
5
main.c
@@ -1618,6 +1618,11 @@ static void sigusr2_handler(UNUSED(int val))
|
|||||||
if (!am_server)
|
if (!am_server)
|
||||||
output_summary();
|
output_summary();
|
||||||
close_all();
|
close_all();
|
||||||
|
#ifdef GCOV_COVERAGE
|
||||||
|
/* The receiver child is killed here via SIGUSR2 and exits with _exit(),
|
||||||
|
* bypassing the gcov atexit flush; without this it writes no .gcda. */
|
||||||
|
{ extern void __gcov_dump(void); __gcov_dump(); }
|
||||||
|
#endif
|
||||||
if (got_xfer_error)
|
if (got_xfer_error)
|
||||||
_exit(RERR_PARTIAL);
|
_exit(RERR_PARTIAL);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
|
|||||||
2
packaging/ftp.filt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
- /generated-files/
|
||||||
|
- /binaries/
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
# the rsync git checkout):
|
# the rsync git checkout):
|
||||||
#
|
#
|
||||||
# ../release/rsync-ftp/ mirror of samba.org:/home/ftp/pub/rsync
|
# ../release/rsync-ftp/ mirror of samba.org:/home/ftp/pub/rsync
|
||||||
# ../release/rsync-html/ git checkout of rsync-web (the html site)
|
# ../release/rsync-html/ release-time snapshot of the html site
|
||||||
# ../release/work/ scratch space for tarball / diff staging
|
# ../release/work/ scratch space for tarball / diff staging
|
||||||
# ../release/release-state.json info shared between steps
|
# ../release/release-state.json info shared between steps
|
||||||
#
|
#
|
||||||
@@ -35,10 +35,11 @@ HTML_DIR = os.path.join(RELEASE_DIR, 'rsync-html')
|
|||||||
WORK_DIR = os.path.join(RELEASE_DIR, 'work')
|
WORK_DIR = os.path.join(RELEASE_DIR, 'work')
|
||||||
STATE_FILE = os.path.join(RELEASE_DIR, 'release-state.json')
|
STATE_FILE = os.path.join(RELEASE_DIR, 'release-state.json')
|
||||||
|
|
||||||
# Local rsync-web checkout (sibling of rsync-git) is the source-of-truth for
|
# The rsync-web/ subdirectory in the rsync source tree is the source-of-truth
|
||||||
# the git-tracked html content. The maintainer pulls/commits/pushes there;
|
# for the git-tracked html content. step-1-fetch snapshots it into HTML_DIR
|
||||||
# step-1-fetch just snapshots it into HTML_DIR for the release flow.
|
# for the release flow, where it can be edited or augmented with server-side
|
||||||
HTML_SRC = os.path.realpath('../rsync-web')
|
# content before step-11-push-html sends it to samba.org.
|
||||||
|
HTML_SRC = os.path.realpath('rsync-web')
|
||||||
|
|
||||||
FTP_REMOTE_PATH = '/home/ftp/pub/rsync'
|
FTP_REMOTE_PATH = '/home/ftp/pub/rsync'
|
||||||
HTML_REMOTE_PATH = '/home/httpd/html/rsync'
|
HTML_REMOTE_PATH = '/home/httpd/html/rsync'
|
||||||
@@ -60,7 +61,7 @@ GEN_FILES = [
|
|||||||
# ---------- Step registry ----------
|
# ---------- Step registry ----------
|
||||||
|
|
||||||
STEPS = [
|
STEPS = [
|
||||||
('step-1-fetch', 'mirror ../release/rsync-ftp from samba.org and snapshot ../release/rsync-html from ../rsync-web'),
|
('step-1-fetch', 'mirror ../release/rsync-ftp from samba.org and snapshot ../release/rsync-html from rsync-web/'),
|
||||||
('step-2-prepare', 'gather release info interactively and write release-state.json'),
|
('step-2-prepare', 'gather release info interactively and write release-state.json'),
|
||||||
('step-3-tweak', 'update version.h, rsync.h, NEWS.md, and packaging/*.spec'),
|
('step-3-tweak', 'update version.h, rsync.h, NEWS.md, and packaging/*.spec'),
|
||||||
('step-4-build', 'run smart-make + make gen'),
|
('step-4-build', 'run smart-make + make gen'),
|
||||||
@@ -136,27 +137,29 @@ def step_1_fetch(args):
|
|||||||
section(f"Fetching ftp dir into {FTP_DIR}")
|
section(f"Fetching ftp dir into {FTP_DIR}")
|
||||||
if not os.path.isdir(FTP_DIR):
|
if not os.path.isdir(FTP_DIR):
|
||||||
os.makedirs(FTP_DIR)
|
os.makedirs(FTP_DIR)
|
||||||
# The .filt file lives in the ftp dir on the server; mirror down using the
|
# packaging/ftp.filt is the authoritative copy of the .filt filter file
|
||||||
# transmitted filter, falling back to no filter on the very first pull.
|
# that controls which subtrees rsync excludes from the FTP mirror.
|
||||||
|
# Seed FTP_DIR/.filt from it so the bundled version is what step-1's
|
||||||
|
# rsync uses here, and so step-10-push-ftp propagates it back to the
|
||||||
|
# server. --exclude=/.filt below stops the server's copy from
|
||||||
|
# overwriting our bundled one on the way down.
|
||||||
filt = os.path.join(FTP_DIR, '.filt')
|
filt = os.path.join(FTP_DIR, '.filt')
|
||||||
if os.path.exists(filt):
|
bundled_filt = os.path.realpath('packaging/ftp.filt')
|
||||||
opts = ['-aivOHP', f'-f:_{filt}']
|
if not os.path.isfile(bundled_filt):
|
||||||
else:
|
die(f"{bundled_filt} not found; cannot seed .filt for the FTP pull.")
|
||||||
opts = ['-aivOHP']
|
shutil.copyfile(bundled_filt, filt)
|
||||||
cmd_chk(['rsync', *opts, f'{host}:{FTP_REMOTE_PATH}/', f'{FTP_DIR}/'])
|
cmd_chk(['rsync', '-aivOHP', f'-f:_{filt}', '--exclude=/.filt',
|
||||||
|
f'{host}:{FTP_REMOTE_PATH}/', f'{FTP_DIR}/'])
|
||||||
|
|
||||||
section(f"Snapshotting html dir from {HTML_SRC} into {HTML_DIR}")
|
section(f"Snapshotting html dir from {HTML_SRC} into {HTML_DIR}")
|
||||||
if not os.path.isdir(HTML_SRC):
|
if not os.path.isdir(HTML_SRC):
|
||||||
die(f"{HTML_SRC} not found. Clone the rsync-web repo there first.")
|
die(f"{HTML_SRC} not found. This should be the in-tree rsync-web/ "
|
||||||
if not os.path.isdir(os.path.join(HTML_SRC, '.git')):
|
f"subdirectory; something is wrong with your checkout.")
|
||||||
die(f"{HTML_SRC} exists but is not a git checkout.")
|
|
||||||
print(f"(Make sure {HTML_SRC} is up to date — this script does not 'git pull' for you.)")
|
|
||||||
os.makedirs(HTML_DIR, exist_ok=True)
|
os.makedirs(HTML_DIR, exist_ok=True)
|
||||||
cmd_chk(['rsync', '-aiv', '--exclude=/.git',
|
cmd_chk(['rsync', '-aiv', f'{HTML_SRC}/', f'{HTML_DIR}/'])
|
||||||
f'{HTML_SRC}/', f'{HTML_DIR}/'])
|
|
||||||
|
|
||||||
# Then mirror non-git html content from the server (mirroring samba-rsync's
|
# Then mirror non-git html content from the server, skipping files that
|
||||||
# behavior: skip files that the html git already provides).
|
# the html git already provides (driven by the 'filt' file in HTML_DIR).
|
||||||
filt = os.path.join(HTML_DIR, 'filt')
|
filt = os.path.join(HTML_DIR, 'filt')
|
||||||
if os.path.exists(filt):
|
if os.path.exists(filt):
|
||||||
tmp_filt = os.path.join(HTML_DIR, 'tmp-filt')
|
tmp_filt = os.path.join(HTML_DIR, 'tmp-filt')
|
||||||
@@ -631,9 +634,8 @@ If you have a 'samba' remote configured (git.samba.org:/data/git/rsync.git):
|
|||||||
git push samba {master_branch}
|
git push samba {master_branch}
|
||||||
git push samba {v_ver}
|
git push samba {v_ver}
|
||||||
|
|
||||||
Then upload the tarball + .asc to the GitHub release for {v_ver}, run
|
Then upload the tarball + .asc to the GitHub release for {v_ver},
|
||||||
packaging/send-news (when convenient), and announce on rsync-announce@,
|
and announce on rsync-announce@, rsync@, and Discord.
|
||||||
rsync@, and Discord.
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# This script makes it easy to update the ftp & html directories on the samba.org server.
|
|
||||||
# It expects the 2 *_DEST directories to contain updated files that need to be sent to
|
|
||||||
# the remote server. If these directories don't exist yet, they will be copied from the
|
|
||||||
# remote server (while also making the html dir a git checkout).
|
|
||||||
|
|
||||||
FTP_SRC="$HOME/samba-rsync-ftp"
|
|
||||||
HTML_SRC="$HOME/samba-rsync-html"
|
|
||||||
|
|
||||||
FTP_DEST="/home/ftp/pub/rsync"
|
|
||||||
HTML_DEST="/home/httpd/html/rsync"
|
|
||||||
|
|
||||||
HTML_GIT='git.samba.org:/data/git/rsync-web.git'
|
|
||||||
|
|
||||||
export RSYNC_PARTIAL_DIR=''
|
|
||||||
|
|
||||||
case "$RSYNC_SAMBA_HOST" in
|
|
||||||
*.samba.org) ;;
|
|
||||||
*)
|
|
||||||
echo "You must set RSYNC_SAMBA_HOST in your environment to the samba hostname to use." >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
MODE=''
|
|
||||||
REVERSE=''
|
|
||||||
while (( $# )); do
|
|
||||||
case "$1" in
|
|
||||||
-R|--reverse) REVERSE=yes ;;
|
|
||||||
f|ftp) MODE=ftp ;;
|
|
||||||
h|html) MODE=html ;;
|
|
||||||
-h|--help)
|
|
||||||
echo "Usage: [-R] [f|ftp|h|html]"
|
|
||||||
echo "-R --reverse Copy the files from the server to the local host."
|
|
||||||
echo " The default is to update the remote files."
|
|
||||||
echo "-h --help Output this help message."
|
|
||||||
echo " "
|
|
||||||
echo "The script will prompt if ftp or html is not specified on the command line."
|
|
||||||
echo "Only one category can be copied at a time. When pulling html files, a git"
|
|
||||||
echo "checkout will be either created or updated prior to the rsync copy."
|
|
||||||
exit
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid option: $1" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
while [ ! "$MODE" ]; do
|
|
||||||
if [ "$REVERSE" = yes ]; then
|
|
||||||
DIRECTION=FROM
|
|
||||||
else
|
|
||||||
DIRECTION=TO
|
|
||||||
fi
|
|
||||||
echo -n "Copy which files $DIRECTION the server? ftp or html? "
|
|
||||||
read ans
|
|
||||||
case "$ans" in
|
|
||||||
f*) MODE=ftp ;;
|
|
||||||
h*) MODE=html ;;
|
|
||||||
'') exit 1 ;;
|
|
||||||
*) echo "You must answer f or h to copy the ftp or html data." ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$MODE" = ftp ]; then
|
|
||||||
SRC_DIR="$FTP_SRC"
|
|
||||||
DEST_DIR="$FTP_DEST"
|
|
||||||
FILT=".filt"
|
|
||||||
else
|
|
||||||
SRC_DIR="$HTML_SRC"
|
|
||||||
DEST_DIR="$HTML_DEST"
|
|
||||||
FILT="filt"
|
|
||||||
fi
|
|
||||||
|
|
||||||
function do_rsync {
|
|
||||||
rsync --dry-run "${@}" | grep -v 'is uptodate$'
|
|
||||||
echo ''
|
|
||||||
echo -n "Run without --dry-run? [n] "
|
|
||||||
read ans
|
|
||||||
case "$ans" in
|
|
||||||
y*) rsync "${@}" | grep -v 'is uptodate$' ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -d "$SRC_DIR" ]; then
|
|
||||||
REVERSE_RSYNC=do_rsync
|
|
||||||
else
|
|
||||||
echo "The directory $SRC_DIR does not exist yet."
|
|
||||||
echo -n "Do you want to create it? [n] "
|
|
||||||
read ans
|
|
||||||
case "$ans" in
|
|
||||||
y*) ;;
|
|
||||||
*) exit 1 ;;
|
|
||||||
esac
|
|
||||||
REVERSE=yes
|
|
||||||
REVERSE_RSYNC=rsync
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$REVERSE" = yes ]; then
|
|
||||||
OPTS='-aivOHP'
|
|
||||||
TMP_FILT="$SRC_DIR/tmp-filt"
|
|
||||||
echo "Copying files from $RSYNC_SAMBA_HOST to $SRC_DIR ..."
|
|
||||||
if [ "$MODE" = html ]; then
|
|
||||||
if [ $REVERSE_RSYNC = rsync ]; then
|
|
||||||
git clone "$HTML_GIT" "$SRC_DIR" || exit 1
|
|
||||||
else
|
|
||||||
cd "$SRC_DIR" || exit 1
|
|
||||||
git pull || exit 1
|
|
||||||
fi
|
|
||||||
sed -n -e 's/[-P]/H/p' "$SRC_DIR/$FILT" >"$TMP_FILT"
|
|
||||||
OPTS="${OPTS}f._$TMP_FILT"
|
|
||||||
else
|
|
||||||
OPTS="${OPTS}f:_$FILT"
|
|
||||||
fi
|
|
||||||
$REVERSE_RSYNC "$OPTS" "$RSYNC_SAMBA_HOST:$DEST_DIR/" "$SRC_DIR/"
|
|
||||||
rm -f "$TMP_FILT"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "$SRC_DIR" || exit 1
|
|
||||||
echo "Copying files from $SRC_DIR to $RSYNC_SAMBA_HOST ..."
|
|
||||||
do_rsync -aivOHP --chown=:rsync --del -f._$FILT . "$RSYNC_SAMBA_HOST:$DEST_DIR/"
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#!/bin/bash -e
|
|
||||||
|
|
||||||
# This script expects the ~/src/rsync directory to contain the rsync
|
|
||||||
# source that has been updated. It also expects the auto-build-save
|
|
||||||
# directory to have been created prior to the running of configure so
|
|
||||||
# that each branch has its own build directory underneath. This supports
|
|
||||||
# the maintainer workflow for the rsync-patches files maintenace.
|
|
||||||
|
|
||||||
FTP_SRC="$HOME/samba-rsync-ftp"
|
|
||||||
FTP_DEST="/home/ftp/pub/rsync"
|
|
||||||
MD_FILES="README.md INSTALL.md NEWS.md"
|
|
||||||
|
|
||||||
case "$RSYNC_SAMBA_HOST" in
|
|
||||||
*.samba.org) ;;
|
|
||||||
*)
|
|
||||||
echo "You must set RSYNC_SAMBA_HOST in your environment to the samba hostname to use." >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ ! -d "$FTP_SRC" ]; then
|
|
||||||
packaging/samba-rsync ftp # Ask to initialize the local ftp dir
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ~/src/rsync
|
|
||||||
|
|
||||||
make man
|
|
||||||
./md-convert --dest="$FTP_SRC" $MD_FILES
|
|
||||||
rsync -aiic $MD_FILES auto-build-save/master/*.?.html "$FTP_SRC"
|
|
||||||
|
|
||||||
cd "$FTP_SRC"
|
|
||||||
|
|
||||||
rsync -aiic README.* INSTALL.* NEWS.* *.?.html "$RSYNC_SAMBA_HOST:$FTP_DEST/"
|
|
||||||
57
receiver.c
@@ -83,6 +83,44 @@ static int updating_basis_or_equiv;
|
|||||||
#define MAX_UNIQUE_NUMBER 999999
|
#define MAX_UNIQUE_NUMBER 999999
|
||||||
#define MAX_UNIQUE_LOOP 100
|
#define MAX_UNIQUE_LOOP 100
|
||||||
|
|
||||||
|
/* Open a basis/output path that may legitimately be an operator-trusted
|
||||||
|
* ABSOLUTE path -- e.g. an absolute --partial-dir ("a directory reserved for
|
||||||
|
* partial-dir work") or --backup-dir. secure_relative_open() deliberately
|
||||||
|
* rejects an absolute relpath, so feeding it the whole absolute partialptr
|
||||||
|
* (with a NULL basedir) returns EINVAL: the basis fd is then -1, no basis is
|
||||||
|
* mapped, and receive_data() omits every matched block from the whole-file
|
||||||
|
* verification checksum -> a spurious "failed verification" that strands the
|
||||||
|
* (correct) data in the partial-dir forever.
|
||||||
|
*
|
||||||
|
* The operator's directory is trusted; only the leaf basename is peer-supplied.
|
||||||
|
* So when basedir is NULL and relpath is absolute, split it into its directory
|
||||||
|
* (trusted) and leaf and confine just the leaf -- exactly how secure_relative_
|
||||||
|
* open already trusts an absolute basedir while O_NOFOLLOW-confining the leaf.
|
||||||
|
* Anything else is a straight pass-through that preserves the strict contract. */
|
||||||
|
static int secure_basis_open(const char *basedir, const char *relpath, int flags, mode_t mode)
|
||||||
|
{
|
||||||
|
if (!basedir && relpath && *relpath == '/') {
|
||||||
|
const char *slash = strrchr(relpath, '/');
|
||||||
|
const char *leaf = slash + 1;
|
||||||
|
char dirbuf[MAXPATHLEN];
|
||||||
|
const char *dir;
|
||||||
|
if (slash == relpath)
|
||||||
|
dir = "/";
|
||||||
|
else {
|
||||||
|
size_t dlen = slash - relpath;
|
||||||
|
if (dlen >= sizeof dirbuf) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(dirbuf, relpath, dlen);
|
||||||
|
dirbuf[dlen] = '\0';
|
||||||
|
dir = dirbuf;
|
||||||
|
}
|
||||||
|
return secure_relative_open(dir, leaf, flags, mode);
|
||||||
|
}
|
||||||
|
return secure_relative_open(basedir, relpath, flags, mode);
|
||||||
|
}
|
||||||
|
|
||||||
/* get_tmpname() - create a tmp filename for a given filename
|
/* get_tmpname() - create a tmp filename for a given filename
|
||||||
*
|
*
|
||||||
* If a tmpdir is defined, use that as the directory to put it in. Otherwise,
|
* If a tmpdir is defined, use that as the directory to put it in. Otherwise,
|
||||||
@@ -364,6 +402,18 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
|||||||
|
|
||||||
stats.matched_data += len;
|
stats.matched_data += len;
|
||||||
|
|
||||||
|
/* A block match can only be honored if we actually mapped the
|
||||||
|
* basis. If we didn't (basis open failed), the sender should
|
||||||
|
* never have been told a basis existed -- treat it as a protocol
|
||||||
|
* inconsistency rather than silently omitting these bytes from
|
||||||
|
* the verification checksum (which yields a spurious failure) or
|
||||||
|
* leaving a hole in the output. */
|
||||||
|
if (!mapbuf) {
|
||||||
|
rprintf(FERROR, "got a block match with no basis file for %s [%s]\n",
|
||||||
|
full_fname(fname), who_am_i());
|
||||||
|
exit_cleanup(RERR_PROTOCOL);
|
||||||
|
}
|
||||||
|
|
||||||
if (DEBUG_GTE(DELTASUM, 3)) {
|
if (DEBUG_GTE(DELTASUM, 3)) {
|
||||||
rprintf(FINFO,
|
rprintf(FINFO,
|
||||||
"chunk[%d] of size %ld at %s offset=%s%s\n",
|
"chunk[%d] of size %ld at %s offset=%s%s\n",
|
||||||
@@ -793,8 +843,9 @@ int recv_files(int f_in, int f_out, char *local_name)
|
|||||||
fnamecmp = fname;
|
fnamecmp = fname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the file */
|
/* open the file (secure_basis_open tolerates an operator-trusted
|
||||||
fd1 = secure_relative_open(basedir, fnamecmp, O_RDONLY, 0);
|
* absolute fnamecmp, e.g. an absolute --partial-dir basis) */
|
||||||
|
fd1 = secure_basis_open(basedir, fnamecmp, O_RDONLY, 0);
|
||||||
|
|
||||||
if (fd1 == -1 && protocol_version < 29) {
|
if (fd1 == -1 && protocol_version < 29) {
|
||||||
if (fnamecmp != fname) {
|
if (fnamecmp != fname) {
|
||||||
@@ -884,7 +935,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
|||||||
* attacker could switch a directory to a symlink between
|
* attacker could switch a directory to a symlink between
|
||||||
* path validation and file open. */
|
* path validation and file open. */
|
||||||
if (use_secure_symlinks)
|
if (use_secure_symlinks)
|
||||||
fd2 = secure_relative_open(NULL, fnametmp, O_WRONLY|O_CREAT, 0600);
|
fd2 = secure_basis_open(NULL, fnametmp, O_WRONLY|O_CREAT, 0600);
|
||||||
else
|
else
|
||||||
fd2 = do_open(fnametmp, O_WRONLY|O_CREAT, 0600);
|
fd2 = do_open(fnametmp, O_WRONLY|O_CREAT, 0600);
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
|
|||||||
11
rsync-web/.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/.xvpics
|
||||||
|
/doxygen/
|
||||||
|
/tech_report/IMG_PARAMS.dir
|
||||||
|
/tech_report/IMG_PARAMS.pag
|
||||||
|
/upload
|
||||||
|
/netware
|
||||||
|
/pre-change
|
||||||
|
/index.html-*
|
||||||
|
/rsync-and-debian/rsync-and-debian.html
|
||||||
|
/rsync-and-debian/rsync-and-debian.ps
|
||||||
|
/badge.svg
|
||||||
674
rsync-web/COPYING.html
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <<a href="https://fsf.org/">https://fsf.org/</a>>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <<a href="https://www.gnu.org/licenses/">https://www.gnu.org/licenses/</a>>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<<a href="https://www.gnu.org/licenses/">https://www.gnu.org/licenses/</a>>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<<a href="https://www.gnu.org/philosophy/why-not-lgpl.html">https://www.gnu.org/philosophy/why-not-lgpl.html</a>>.
|
||||||
340
rsync-web/COPYING2.html
Normal file
@@ -0,0 +1,340 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
<hr>
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
<hr>
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
<hr>
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
<hr>
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
<hr>
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
||||||
284
rsync-web/FAQ.html
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync FAQ</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">Frequently Asked Questions</H2>
|
||||||
|
|
||||||
|
<table><tr valign=top><td><ul>
|
||||||
|
<li><a href="#1">the transfer fails to finish</a><br>
|
||||||
|
<li><a href="#2">rsync recopies the same files</a><br>
|
||||||
|
<li><a href="#3">is your shell clean</a><br>
|
||||||
|
<li><a href="#4">memory usage</a><br>
|
||||||
|
<li><a href="#5">out of memory</a><br>
|
||||||
|
<li><a href="#6">rsync through a firewall</a><br>
|
||||||
|
<li><a href="#7">rsync and cron</a><br>
|
||||||
|
</ul></td><td> </td><td><ul>
|
||||||
|
<li><a href="#8">rsync: Command not found</a><br>
|
||||||
|
<li><a href="#9">spaces in filenames</a><br>
|
||||||
|
<li><a href="#10">ignore "vanished files" warning</a><br>
|
||||||
|
<li><a href="#11">read-only file system</a><br>
|
||||||
|
<li><a href="#12">multiplexing overflow 101:7104843</a><br>
|
||||||
|
<li><a href="#13">inflate (token) returned -5</a><br>
|
||||||
|
</ul></td></tr></table>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=1>the transfer fails to finish</a></h3>
|
||||||
|
|
||||||
|
<p>If you get an error like one of these:
|
||||||
|
|
||||||
|
<pre>rsync: error writing 4 unbuffered bytes - exiting: Broken pipe
|
||||||
|
rsync error: error in rsync protocol data stream (code 12) at io.c(463)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>or
|
||||||
|
|
||||||
|
<pre>rsync: connection unexpectedly closed (24 bytes read so far)
|
||||||
|
rsync error: error in rsync protocol data stream (code 12) at io.c(342)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>please read the <a href="issues.html">issues and debugging page</a>
|
||||||
|
for details on how you can try to figure out what is going wrong.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=2>rsync recopies the same files</a></h3>
|
||||||
|
|
||||||
|
<p>Some people occasionally report that rsync copies too many files when
|
||||||
|
they expect it to copy only a few. In most cases the explanation is
|
||||||
|
that you forgot to include the --times (-t) option in the original copy,
|
||||||
|
so rsync is forced to (efficiently) transfer every file that differs in
|
||||||
|
its modified time to discover what data (if any) has changed.
|
||||||
|
|
||||||
|
<p>Another common cause involves sending files to an Microsoft filesystem:
|
||||||
|
if the file's modified time is an odd value but the receiving filesystem
|
||||||
|
can only store even values, then rsync will re-transfer too many files.
|
||||||
|
You can avoid this by specifying the --modify-window=1 option.
|
||||||
|
|
||||||
|
<p>Yet another periodic case can happen when daylight-savings time
|
||||||
|
changes if your OS+filesystem saves file times in local time instead of
|
||||||
|
UTC. For a full explanation of this and some suggestions on how to
|
||||||
|
avoid them problem, see <a href="daylight-savings.html">this document</a>.
|
||||||
|
|
||||||
|
<p>Something else that can trip up rsync is a filesystem changeing the
|
||||||
|
filename behind the scenes. This can happen when a filesystem changes
|
||||||
|
an all-uppercase name into lowercase, or when it decomposes UTF-8 behind
|
||||||
|
your back.
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
|
||||||
|
<p>An example of the latter can occur with HFS+ on Mac OS X: if you
|
||||||
|
copy a directory with a file that has a UTF-8 character sequence in it,
|
||||||
|
say a 2-byte umlaut-u (\0303\0274), the file will get that character
|
||||||
|
stored by the filesystem using 3 bytes (\0165\0314\0210), and rsync will
|
||||||
|
not know that these differing filenames are the same file (it will, in
|
||||||
|
fact, remove a prior copy of the file if --delete is enabled, and then
|
||||||
|
recreate it).
|
||||||
|
|
||||||
|
<p>You can avoid a charset problem by passing an appropriate --iconv
|
||||||
|
option to rsync that tells it what character-set the source files are,
|
||||||
|
and what character-set the destination files get stored in. For
|
||||||
|
instance, the above Mac OS X problem would be dealt with by using
|
||||||
|
--iconv=UTF-8,UTF8-MAC (UTF8-MAC is a pseudo-charset recognized by Mac
|
||||||
|
OS X iconv in which all characters are decomposed).
|
||||||
|
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<p>If you think that rsync is copying too many files, look at the
|
||||||
|
itemized output (-i) to see why rsync is doing the update (e.g. the 't'
|
||||||
|
flag indicates that the time differs, or all pluses indicates that rsync
|
||||||
|
thinks the file doesn't exist). You can also look at the stats produced
|
||||||
|
with -v and see if rsync is really sending all the data. See also the
|
||||||
|
--checksum (-c) option for one way to avoid the extra copying of files
|
||||||
|
that don't have synchronized modified times (but keep in mind that the
|
||||||
|
-c option eats lots of disk I/O, and can be rather slow).
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=3>is your shell clean</a></h3>
|
||||||
|
|
||||||
|
<p>The "is your shell clean" message and the "protocol mismatch" message
|
||||||
|
are usually caused by having some sort of program in your .cshrc, .profile,
|
||||||
|
.bashrc or equivalent file that writes a message every time you connect
|
||||||
|
using a remote-shell program (such as ssh or rsh). Data written in this
|
||||||
|
way corrupts the rsync data stream. rsync detects this at startup and
|
||||||
|
produces those error messages. However, if you are using rsync-daemon
|
||||||
|
syntax (host::path or rsync://) without using a remote-shell program (no
|
||||||
|
--rsh or -e option), there is not remote-shell program involved, and the
|
||||||
|
problem is probably caused by an error on the daemon side (so check the
|
||||||
|
daemon logs).
|
||||||
|
|
||||||
|
<p>A good way to test if your remote-shell connection is clean is to try
|
||||||
|
something like this (use ssh or rsh, as appropriate):
|
||||||
|
|
||||||
|
<blockquote><pre>ssh remotesystem /bin/true > test.dat</pre></blockquote>
|
||||||
|
|
||||||
|
<p>That should create a file called test.dat with nothing in it. If
|
||||||
|
test.dat is not of zero length then your shell is not clean. Look at the
|
||||||
|
contents of test.dat to see what was sent. Look at all the startup files on
|
||||||
|
remotesystem to try and find the problem.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=4>memory usage</a></h3>
|
||||||
|
|
||||||
|
<p>Rsync versions before 3.0.0 always build the entire list of files to be
|
||||||
|
transferred at the beginning and hold it in memory for the entire run. Rsync
|
||||||
|
needs about 100 bytes to store all the relevant information for one file,
|
||||||
|
so (for example) a run with 800,000 files would consume about 80M of
|
||||||
|
memory. -H and --delete increase the memory usage further.
|
||||||
|
|
||||||
|
<p>Version 3.0.0 slightly reduced the memory used per file by not storing fields
|
||||||
|
not needed for a particular file. It also introduced an incremental recursion
|
||||||
|
mode that builds the file list in chunks and holds each chunk in memory only as
|
||||||
|
long as it is needed. This mode dramatically reduces memory usage, but it
|
||||||
|
only works provided that both sides are 3.0.0 or newer and certain options that
|
||||||
|
rsync currently can't handle in this mode are not being used.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=5>out of memory</a></h3>
|
||||||
|
|
||||||
|
<p>The usual reason for "out of memory" when running rsync is that you are
|
||||||
|
transferring a _very_ large number of files. The size of the files doesn't
|
||||||
|
matter, only the total number of files. If memory is a problem, first try to
|
||||||
|
use the incremental recursion mode: upgrade both sides to rsync 3.0.0 or
|
||||||
|
newer and avoid options that disable incremental recursion (e.g., use
|
||||||
|
<tt>--delete-delay</tt> instead of <tt>--delete-after</tt>). If this is not
|
||||||
|
possible, you can break the rsync run into smaller chunks operating on
|
||||||
|
individual subdirectories using <tt>--relative</tt> and/or exclude rules.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=6>rsync through a firewall</a></h3>
|
||||||
|
|
||||||
|
<p>If you have a setup where there is no way to directly connect two
|
||||||
|
systems for an rsync transfer, there are several ways to get a firewall
|
||||||
|
system to act as an intermediary in the transfer. You'll find full details
|
||||||
|
on the <a href="firewall.html">firewall methods</a> page.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=7>rsync and cron</a></h3>
|
||||||
|
|
||||||
|
<p>On some systems (notably SunOS4) cron supplies what looks like a socket
|
||||||
|
to rsync, so rsync thinks that stdin is a socket. This means that if you
|
||||||
|
start rsync with the --daemon switch from a cron job you end up rsync
|
||||||
|
thinking it has been started from inetd. The fix is simple—just
|
||||||
|
redirect stdin from /dev/null in your cron job.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=8>rsync: Command not found</a></h3>
|
||||||
|
|
||||||
|
<p>This error is produced when the remote shell is unable to locate the rsync
|
||||||
|
binary in your path. There are 3 possible solutions:
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
|
||||||
|
<li>install rsync in a "standard" location that is in your remote path.
|
||||||
|
|
||||||
|
<li>modify your .cshrc, .bashrc etc on the remote system to include the path
|
||||||
|
that rsync is in
|
||||||
|
|
||||||
|
<li>use the --rsync-path option to explicitly specify the path on the
|
||||||
|
remote system where rsync is installed
|
||||||
|
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p>You may echo find the command:
|
||||||
|
|
||||||
|
<blockquote><pre>ssh host 'echo $PATH'</pre></blockquote>
|
||||||
|
|
||||||
|
<p>for determining what your remote path is.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=9>spaces in filenames</a></h3>
|
||||||
|
|
||||||
|
<p>Can rsync copy files with spaces in them?
|
||||||
|
|
||||||
|
<p>Short answer: Yes, rsync can handle filenames with spaces.
|
||||||
|
|
||||||
|
<p>Long answer:
|
||||||
|
|
||||||
|
<p>Rsync handles spaces just like any other unix command line application.
|
||||||
|
Within the code spaces are treated just like any other character so a
|
||||||
|
filename with a space is no different from a filename with any other
|
||||||
|
character in it.
|
||||||
|
|
||||||
|
<p>The problem of spaces is in the argv processing done to interpret the
|
||||||
|
command line. As with any other unix application you have to escape spaces
|
||||||
|
in some way on the command line or they will be used to separate arguments.
|
||||||
|
|
||||||
|
<p>It is slightly trickier in rsync (and other remote-copy programs like
|
||||||
|
scp) because rsync sends a command line to the remote system to launch the
|
||||||
|
peer copy of rsync (this assumes that we're not talking about daemon mode,
|
||||||
|
which is not affected by this problem because no remote shell is involved
|
||||||
|
in the reception of the filenames). The command line is interpreted by the
|
||||||
|
remote shell and thus the spaces need to arrive on the remote system
|
||||||
|
escaped so that the shell doesn't split such filenames into multiple
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
<p>For example:
|
||||||
|
|
||||||
|
<blockquote><pre>rsync -av host:'a long filename' /tmp/</pre></blockquote>
|
||||||
|
|
||||||
|
<p>This is usually a request for rsync to copy 3 files from the remote
|
||||||
|
system, "a", "long", and "filename" (the only exception to this is for a
|
||||||
|
system running a shell that does not word-split arguments in its commands,
|
||||||
|
and that is exceedingly rare). If you wanted to request a single file with
|
||||||
|
spaces, you need to get some kind of space-quoting characters to the remote
|
||||||
|
shell that is running the remote rsync command. The following commands
|
||||||
|
should all work:
|
||||||
|
|
||||||
|
<blockquote><pre>rsync -av host:'"a long filename"' /tmp/
|
||||||
|
rsync -av host:'a\ long\ filename' /tmp/
|
||||||
|
rsync -av host:a\\\ long\\\ filename /tmp/</pre></blockquote>
|
||||||
|
|
||||||
|
<p>You might also like to use a '?' in place of a space as long as there
|
||||||
|
are no other matching filenames than the one with spaces (since '?' matches
|
||||||
|
any character):
|
||||||
|
|
||||||
|
<blockquote><pre>rsync -av host:a?long?filename /tmp/</pre></blockquote>
|
||||||
|
|
||||||
|
<p>As long as you know that the remote filenames on the command line
|
||||||
|
are interpreted by the remote shell then it all works fine.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=10>ignore "vanished files" warning</a></h3>
|
||||||
|
|
||||||
|
<p>Some folks would like to ignore the "vanished files" warning, which
|
||||||
|
manifests as an exit-code 24. The easiest way to do this is to create
|
||||||
|
a shell script wrapper. For instance, name this something like
|
||||||
|
"rsync-no24":
|
||||||
|
|
||||||
|
<blockquote><pre>#!/bin/sh
|
||||||
|
rsync "$@"
|
||||||
|
e=$?
|
||||||
|
if test $e = 24; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
exit $e</pre></blockquote>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=11>read-only file system</a></h3>
|
||||||
|
|
||||||
|
<p>If you get "Read-only file system" as an error when sending to a rsync
|
||||||
|
daemon then you probably forgot to set "read only = no" for that module.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=12>multiplexing overflow 101:7104843</a></h3>
|
||||||
|
|
||||||
|
<p>This mysterious error, or the similar "invalid message 101:7104843", can
|
||||||
|
happen if one of the rsync processes is killed for some reason and a message
|
||||||
|
beginning with the four characters "Kill" gets inserted into the protocol
|
||||||
|
stream as a result. To solve the problem, you'll need to figure out why rsync
|
||||||
|
is being killed.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h3><a name=13>inflate (token) returned -5</a></h3>
|
||||||
|
|
||||||
|
This error means that rsync failed to handle an expected error from the
|
||||||
|
compression code for a file that happened to be transferred with a block size
|
||||||
|
of 32816 bytes. You can avoid this issue for the affected file by transferring
|
||||||
|
it with a manually-set block size (e.g. --block-size=33000), or by upgrading
|
||||||
|
the receiving side to rsync 3.0.7.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
16
rsync-web/GPL.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync's license</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
Beginning with 3.0.0, rsync is available under the <b>GNU General Public
|
||||||
|
License version 3</b>. <i>(Older releases were available under the
|
||||||
|
<a href="GPL2.html">GPL version 2</a>.)</i>
|
||||||
|
|
||||||
|
<pre><small>
|
||||||
|
<!--#include virtual="COPYING.html" -->
|
||||||
|
</small></pre>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
15
rsync-web/GPL2.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync's license</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
Releases <b>prior</b> to 3.0.0 were released under the
|
||||||
|
<b>GNU General Public License version 2</b>:
|
||||||
|
|
||||||
|
<pre><small>
|
||||||
|
<!--#include virtual="COPYING2.html" -->
|
||||||
|
</small></pre>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
36
rsync-web/backup.txt
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This script does personal backups to a rsync backup server. You will end up
|
||||||
|
# with a 7 day rotating incremental backup. The incrementals will go
|
||||||
|
# into subdirectories named after the day of the week, and the current
|
||||||
|
# full backup goes into a directory called "current"
|
||||||
|
# tridge@linuxcare.com
|
||||||
|
|
||||||
|
# directory to backup
|
||||||
|
BDIR=/home/$USER
|
||||||
|
|
||||||
|
# excludes file - this contains a wildcard pattern per line of files to exclude
|
||||||
|
EXCLUDES=$HOME/cron/excludes
|
||||||
|
|
||||||
|
# the name of the backup machine
|
||||||
|
BSERVER=owl
|
||||||
|
|
||||||
|
# your password on the backup server
|
||||||
|
export RSYNC_PASSWORD=XXXXXX
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
BACKUPDIR=`date +%A`
|
||||||
|
OPTS="--force --ignore-errors --delete-excluded --exclude-from=$EXCLUDES
|
||||||
|
--delete --backup --backup-dir=/$BACKUPDIR -a"
|
||||||
|
|
||||||
|
export PATH=$PATH:/bin:/usr/bin:/usr/local/bin
|
||||||
|
|
||||||
|
# the following line clears the last weeks incremental directory
|
||||||
|
[ -d $HOME/emptydir ] || mkdir $HOME/emptydir
|
||||||
|
rsync --delete -a $HOME/emptydir/ $BSERVER::$USER/$BACKUPDIR/
|
||||||
|
rmdir $HOME/emptydir
|
||||||
|
|
||||||
|
# now the actual transfer
|
||||||
|
rsync $OPTS $BDIR $BSERVER::$USER/current
|
||||||
BIN
rsync-web/bar1.jpg
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
4
rsync-web/bin/badge-update
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
rm -f badge.svg
|
||||||
|
wget https://github.com/RsyncProject/rsync/workflows/build/badge.svg
|
||||||
|
rsync -aiic --inplace --remove-source-files badge.svg $SAMBA_HOST:/home/httpd/html/rsync/
|
||||||
7
rsync-web/bin/upload
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
if [ -d rsync-and-debian ]; then
|
||||||
|
rsync -aviOHFFc --del -f._filt . $SAMBA_HOST:/home/httpd/html/rsync/ "${@}"
|
||||||
|
else
|
||||||
|
echo "Run this from the root of the html hierarchy."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
69
rsync-web/bug-tracking.html
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync bug-tracking</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">rsync bug-tracking</H2>
|
||||||
|
|
||||||
|
<p> Please use this checklist combined with the help on the
|
||||||
|
<a href="issues.html">issues and debugging</a> page before
|
||||||
|
reporting a bug. Thanks!
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li> If you're not using the latest released version, please upgrade before
|
||||||
|
reporting a bug.
|
||||||
|
|
||||||
|
<li> If you're using the latest released version, consult the
|
||||||
|
<a href="https://github.com/RsyncProject/rsync/blob/master/NEWS.md">NEWS file from the git repository</a> to see if what
|
||||||
|
you're seeing has already been handled in the version under development.
|
||||||
|
|
||||||
|
<li> It is also helpful to search the bug reports at the
|
||||||
|
<a href="https://github.com/RsyncProject/rsync/issues?q=is%3Aissue">GitHub issues tracker</a>
|
||||||
|
to see if the problem is already known.
|
||||||
|
|
||||||
|
<li> See also the <a href="issues.html">issues and debugging</a> page to
|
||||||
|
help you figure out if what you're seeing is a known bug and perhaps to
|
||||||
|
help diagnose what is going wrong.
|
||||||
|
|
||||||
|
<li> Discuss the bug on the
|
||||||
|
<a href="https://lists.samba.org/mailman/listinfo/rsync">rsync mailing list</a>
|
||||||
|
(which is at <tt>rsync@lists.samba.org</tt>) to help you figure out if what
|
||||||
|
you're seeing is really a bug or a mistake.
|
||||||
|
|
||||||
|
<li>There are several patches for features that are under consideration that
|
||||||
|
can be found in the <a href="https://github.com/RsyncProject/rsync-patches">rsync-patches repo</a>.
|
||||||
|
|
||||||
|
<li> If you haven't already done so, please take a couple of minutes to read Simon Tatham's
|
||||||
|
<a href="https://www.chiark.greenend.org.uk/~sgtatham/bugs.html">advice on how to report bugs</a>.
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p> To report a bug or make suggestions, use one of these methods:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li> The mailing list (mentioned above) is a good resource for discussing
|
||||||
|
bugs and suggesting new features. It accepts patches (typically as MIME
|
||||||
|
attachments), but for fixes is often easier to attach a patch to an
|
||||||
|
appropriate GitHub issue report or use a pull request. Note that there is
|
||||||
|
no mandate to use pull requests for patches, as that can be a pretty high
|
||||||
|
bar of git know-how that not everyone needs to be familiar with.
|
||||||
|
|
||||||
|
<li> If you'd like to see a bug-report or feature-request get officially noted,
|
||||||
|
<a href="https://github.com/RsyncProject/rsync/issues">create an issue on GitHub</a>
|
||||||
|
(this does require that you have created a GitHub account). If you want to
|
||||||
|
stay abreast of what's going on with the issues, make use of the GitHub
|
||||||
|
subscriptions to pick and choose what kind of notifications you want to
|
||||||
|
receive (e.g. just a single issue, all issues, all rsync activity, etc.).
|
||||||
|
|
||||||
|
<li>For security issues please send email
|
||||||
|
to <a href="mailto:rsync.project@gmail.com">rsync.project@gmail.com</a>
|
||||||
|
with details of the issue
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p> Thanks for helping out!
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
7
rsync-web/bugtracking.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync bug-tracking</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
|
||||||
|
<meta http-equiv="refresh" content="0;URL='https://rsync.samba.org/bug-tracking.html'" />
|
||||||
7
rsync-web/bugzilla.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync bug-tracking</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
|
||||||
|
<meta http-equiv="refresh" content="0;URL='https://rsync.samba.org/bug-tracking.html'" />
|
||||||
11
rsync-web/convert-gpl
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
while (<>) {
|
||||||
|
s/&/&/g;
|
||||||
|
s/</</g;
|
||||||
|
s/>/>/g;
|
||||||
|
s//<hr>/;
|
||||||
|
s#(<)(https?:.*?)(>)#$1<a href="$2">$2</a>$3#g;
|
||||||
|
print $_;
|
||||||
|
}
|
||||||
183
rsync-web/daylight-savings.html
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<HTML><HEAD>
|
||||||
|
<TITLE>DST change and date comparisons</TITLE>
|
||||||
|
</HEAD><BODY>
|
||||||
|
|
||||||
|
<p><small><i>J.W. Schultz wrote the following text in a
|
||||||
|
<a href="http://www.cygwin.com/ml/cygwin/2003-10/msg00995.html">post</a>
|
||||||
|
to the cygwin mailing list. It has been slightly edited and beautified
|
||||||
|
for inclusion here.</i></small>
|
||||||
|
|
||||||
|
<h1>How the DST Change can adversely affect FAT filesystems</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The vernal and autumnal transitions to and from daylight-savings
|
||||||
|
time have important implications
|
||||||
|
for those with Microsoft systems and use utilities that
|
||||||
|
compare file timestamps on different filesystem types or
|
||||||
|
with filesystems on other operating systems that can lead to
|
||||||
|
a problem in how the file's date is handled.
|
||||||
|
This problem lies in the way FAT filesystems stores
|
||||||
|
timestamps and how Windows converts between local time and
|
||||||
|
UTC.
|
||||||
|
|
||||||
|
<h2>Background</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In UNIX and UNIX-like systems (such as Linux) file timestamps
|
||||||
|
are stored in UTC (universal time) and are only converted to
|
||||||
|
local-time by user-space programs for display purposes. At
|
||||||
|
the system call level all time values are in UTC and
|
||||||
|
utilities that compare timestamps do so in UTC. Also, the
|
||||||
|
standard UTC->local and local->UTC conversion functions are
|
||||||
|
aware of DST and conversions reflect this so that if a
|
||||||
|
timestamp was recorded during ST it will be converted using
|
||||||
|
the ST offset even when the current system time is DST.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In Windows things are not so simple. Windows operates in
|
||||||
|
local-time. Timestamps in the various FAT derived
|
||||||
|
filesystems are stored in local-time. Timestamps in NTFS
|
||||||
|
filesystems are stored in UTC. This inconsistency is
|
||||||
|
further complicated by the fact that the conversion routines
|
||||||
|
used are not DST aware. Instead of being DST aware the
|
||||||
|
system has a fixed offset to convert between local-time and
|
||||||
|
UTC regardless of the date in the timestamp. This fixed
|
||||||
|
offset is calculated at boot time and only changed when
|
||||||
|
systems transition to or from DST. As a result the apparent
|
||||||
|
modification time of a file on NTFS as reported in a windows
|
||||||
|
utility will change by one hour when reported in local-time
|
||||||
|
and FAT based files when reported in UTC.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The difficulty that this produces is that any utilities that
|
||||||
|
compare timestamps between FAT and NTFS filesystems or
|
||||||
|
between Windows and other platforms will view files that
|
||||||
|
have not changed as having a different modified time. Among other things
|
||||||
|
this will affect rsync, rdiff, unison, wget, and make. However,
|
||||||
|
for the purposes of this document, we will only discuss rsync.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
With the reduced cost of hard disks many newer backup
|
||||||
|
systems are using hard disk based storage and take advantage
|
||||||
|
of timestamp comparison to detect file changes for the sake
|
||||||
|
of efficiency. Rsync is probably premier in this role and
|
||||||
|
is used by a fair number of free and even commercial backup
|
||||||
|
systems as well as being the basis for many home-brew backup
|
||||||
|
solutions.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
With rsync and similar systems the effect of this is that
|
||||||
|
every file will appear to have been changed. The result is
|
||||||
|
any space savings associated with linking (--link-dest) or
|
||||||
|
with decremental backup approaches (--compare-dest and
|
||||||
|
--backup-dir) will be defeated. Perhaps worse, because
|
||||||
|
every file will appear to have changed the time required to
|
||||||
|
do a backup or a non-backup rsync will be much longer than
|
||||||
|
normal. In some cases backups that normally complete in
|
||||||
|
less than one hour can take several days.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
So what can be done about it? Several things, there are
|
||||||
|
ways to merely mitigate the problem, to correct it and finally
|
||||||
|
to prevent the problem entirely.
|
||||||
|
|
||||||
|
<h2>Mitigation</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Rsync has a --modify-window option. Many of you already use
|
||||||
|
--modify-window=1 to cope with the fact that windows often
|
||||||
|
stores timestamps with a two second resolution. Using a
|
||||||
|
--modify-window=3601 will cause rsync to ignore timestamp
|
||||||
|
differences of up to one hour.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This if often not particularly dangerous because a file would have to
|
||||||
|
be changed, synced and changed again without changing size
|
||||||
|
within a single hour and have no subsequent changes for this copy
|
||||||
|
to miss a file change. However, for some systems any such risk is
|
||||||
|
unacceptable, so other solutions are needed.
|
||||||
|
|
||||||
|
<h2>Correcting the Timestamps</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There are two ways to correct.
|
||||||
|
|
||||||
|
<p>For the first run after the time change, you can run rsync with the
|
||||||
|
--checksum option in order to ensure that only files that have a changed
|
||||||
|
checksum get transferred, and update the modified time on all unchanged
|
||||||
|
files. This option has the drawback that it increases disk I/O by
|
||||||
|
a large amount on both the sending and receiving side, slowing down the
|
||||||
|
copy.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The other way to correct things is to change the timestamps
|
||||||
|
on the files on the backup server before doing a copy after a
|
||||||
|
time change has occurred.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Included here is an example perl script that will change the
|
||||||
|
timestamps of files in a list on standard-input. Whether
|
||||||
|
you use a positive or negative shift will depend on which
|
||||||
|
end you decide to adjust.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This is an example of how to use the script:
|
||||||
|
|
||||||
|
<blockquote><pre>
|
||||||
|
touch -d '01:00 13-apr-03' /tmp/cmpfile
|
||||||
|
find . -type f ! -newer /tmp/cmpfile | shifttime.pl 3600
|
||||||
|
</pre></blockquote>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<pre>
|
||||||
|
#!/usr/bin/perl
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
my $offset = shift() + 0;
|
||||||
|
die "Usage: $0 OFFSET_SECONDS\n" unless $offset;
|
||||||
|
|
||||||
|
while (<>) {
|
||||||
|
chomp;
|
||||||
|
my $mtime = (stat $_)[9];
|
||||||
|
next unless $mtime;
|
||||||
|
$mtime += $offset;
|
||||||
|
utime $mtime, $mtime, $_;
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2>Prevention</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To prevent the problem in the first place you need to
|
||||||
|
prevent changing to DST. This can be done by either running
|
||||||
|
the windows system in UTC, by disabling DST and changing
|
||||||
|
the system time manually twice each year, or by avoiding the use
|
||||||
|
of the FAT filesystem (perhaps by switching to a different OS).
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Notes and References</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Here are some references that Wayne Piekarski collected
|
||||||
|
while researching this problem. They contain a lot of
|
||||||
|
information about the ways that Windows deals with
|
||||||
|
timestamps on NTFS and FAT filesystems.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="http://optics.ph.unimelb.edu.au/help/rsync/rsync_pc1.html#gotchas">http://optics.ph.unimelb.edu.au/help/rsync/rsync_pc1.html#gotchas</a></br>
|
||||||
|
<a href="http://list-archive.xemacs.org/xemacs-nt/199911/msg00130.html">http://list-archive.xemacs.org/xemacs-nt/199911/msg00130.html</a></br>
|
||||||
|
<a href="http://p2p.wrox.com/archive/c_plus_plus_programming/2001-06/53.asp">http://p2p.wrox.com/archive/c_plus_plus_programming/2001-06/53.asp</a></br>
|
||||||
|
<a href="http://www.codeproject.com/datetime/dstbugs.asp">http://www.codeproject.com/datetime/dstbugs.asp</a></br>
|
||||||
|
<a href="http://support.microsoft.com/default.aspx?scid=kb;[LN];158588">http://support.microsoft.com/default.aspx?scid=kb;[LN];158588</a>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I wish to thank Wayne Piekarski for having copiled the
|
||||||
|
references and also supplying some additional insights.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Permission is granted without reservation reprint and
|
||||||
|
distribute this in whole and in part to any interested
|
||||||
|
parties.
|
||||||
|
|
||||||
|
<p>—J.W. Schultz
|
||||||
15
rsync-web/doc-resources.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!-- This file gets included into the resources and documentation pages -->
|
||||||
|
|
||||||
|
<li> A nice tutorial on <a href="https://linuxize.com/post/how-to-setup-passwordless-ssh-login/">setting up ssh to avoid password prompts</a>.
|
||||||
|
|
||||||
|
<li> Karsten Thygesen has written a doc on how to setup
|
||||||
|
<A HREF="http://dslab.lzu.edu.cn:8080/members/wangbj/wangbaojun/howtos/rsync-mirror-HOWTO/">anonymous rsync servers</A>.
|
||||||
|
|
||||||
|
<li> Anthony Wesley has written a doc on
|
||||||
|
<A HREF="/win95.txt">how to build rsync for Windows95</A>.
|
||||||
|
|
||||||
|
<li> Mike McHenry has written up some info on how to get <a href="nt.html">rsync working under NT</a>.
|
||||||
|
|
||||||
|
<li> Michael Holve has written a very useful <a href="http://everythinglinux.org/rsync/">rsync tutorial</a>.
|
||||||
|
|
||||||
|
<li> Daniel Teklu has a detailed HOWTO on <a href="http://www.netbits.us/docs/stunnel_rsync.html">rsync and stunnel</a>.
|
||||||
54
rsync-web/documentation.html
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync documentation</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">documentation</H2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li> An html version of the <a href="https://download.samba.org/pub/rsync/rsync.1"><b>rsync</b>(1) manpage</a>.
|
||||||
|
|
||||||
|
<li> An html version of the
|
||||||
|
<a href="https://download.samba.org/pub/rsync/rsync-ssl.1"><b>rsync-ssl</b>(1) manpage</a>.
|
||||||
|
|
||||||
|
<li> An html version of the
|
||||||
|
<a href="https://download.samba.org/pub/rsync/rsyncd.conf.5"><b>rsyncd.conf</b>(5) manpage</a>.
|
||||||
|
|
||||||
|
<li> An html version of the
|
||||||
|
<a href="https://download.samba.org/pub/rsync/rrsync.1"><b>rrsync</b>(1) manpage</a>
|
||||||
|
|
||||||
|
<li> The <a href="FAQ.html">FAQ</a> (frequently asked questions list).
|
||||||
|
|
||||||
|
<!--#include virtual="doc-resources.html" -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<li>Cross-referenced
|
||||||
|
<a href="doxygen/head/files.html">rsync source code</a> produced by
|
||||||
|
<a href="http://doxygen.org/">Doxygen</a>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<li> A html version of the original
|
||||||
|
<a href="tech_report/">rsync technical report</a>.
|
||||||
|
|
||||||
|
<li> A copy of Andrew Tridgell's
|
||||||
|
<a href="http://samba.org/~tridge/phd_thesis.pdf">PhD thesis</a>
|
||||||
|
(which includes three chapters on rsync).
|
||||||
|
|
||||||
|
<li> A nice page on <a href="how-rsync-works.html">how rsync works</a>.
|
||||||
|
|
||||||
|
<li> A copy of John Langford's thesis on
|
||||||
|
<a href="http://www-2.cs.cmu.edu/~jcl/research/mrsync/mrsync.ps">Multiround rsync</a>,
|
||||||
|
which is not used in rsync, but is interesting none-the-less.
|
||||||
|
|
||||||
|
<li>A <a href="http://www.devshed.com/c/a/Administration/File-Synchronization-With-Rsync/">DevShed tutorial on rsync</a>.
|
||||||
|
|
||||||
|
<li> <a href="rsync-and-debian/">Notes on rsync and Debian mirrors</a>.
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p> <i>(Some of the above items are also listed on the <a href="resources.html">rsync resources page</a>.</i>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
127
rsync-web/download.html
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<TITLE>rsync download</TITLE>
|
||||||
|
</head>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<h2 align="center">rsync download</h2>
|
||||||
|
|
||||||
|
<div style="float: right">
|
||||||
|
<a href="https://github.com/RsyncProject/rsync/actions">
|
||||||
|
<img src="badge.svg">
|
||||||
|
</a></div>
|
||||||
|
|
||||||
|
<h2>Source-code releases</h2>
|
||||||
|
|
||||||
|
<p>You can grab the latest source code and other related files in a variety of ways:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li><p>The latest version is linked on the <a href="https://rsync.samba.org/">main page</a>.
|
||||||
|
|
||||||
|
<li><p>A directory listing of these latest files and various historical release and diff files
|
||||||
|
are available via <a href="https://download.samba.org/pub/rsync/">this web page</a> and
|
||||||
|
via <i>anonymous SSL rsync</i> using this command:
|
||||||
|
<p><code><small>rsync-ssl rsync://download.samba.org/rsyncftp/</small></code></p>
|
||||||
|
|
||||||
|
<li><p>You can also get .zip and .tar.gz versions of the various git repo's release
|
||||||
|
tags via the <a href="https://github.com/RsyncProject/rsync/tags">rsync GitHub tags page</a>
|
||||||
|
and the associated patches via the
|
||||||
|
<a href="https://github.com/RsyncProject/rsync-patches/tags">rsync-patches GitHub tags page</a>.
|
||||||
|
Keep in mind that these git-derived files do NOT come with the extra generated files that are included
|
||||||
|
in the official release tar files.
|
||||||
|
|
||||||
|
<li><p>You can browse the very latest source files, clone the source using git, or download a .zip file of the latest
|
||||||
|
master branch from <a href="https://github.com/RsyncProject/rsync">rsync's GitHub page</a>.
|
||||||
|
|
||||||
|
<li><p>The <a href="https://git.samba.org/?p=rsync.git">Samba git repo</a> is also available,
|
||||||
|
though it might lag behind the GitHub repo every now and then.
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
Once you have the source, read the <a
|
||||||
|
href="https://download.samba.org/pub/rsync/INSTALL">INSTALL.md</a> file for
|
||||||
|
details on some development libraries that you will need to build it.
|
||||||
|
|
||||||
|
<h2>The GPG Signing Key</h2>
|
||||||
|
|
||||||
|
The GPG signing key that is used to sign the release files is available from the public pgp key-server
|
||||||
|
network. If you have automatic key-fetching enabled, just running a normal
|
||||||
|
"gpg --verify" will grab my key automatically.
|
||||||
|
Or, feel free to grab <a href="https://opencoder.net/WayneDavison.key">the gpp
|
||||||
|
key for Wayne Davison</a> manually.<p>
|
||||||
|
|
||||||
|
From 3.4.0 and later releases will be signed by Andrew
|
||||||
|
Tridgell. Please fetch the key for andrew@tridgell.net from https://keys.openpgp.org/
|
||||||
|
|
||||||
|
<h2>Binaries</h2>
|
||||||
|
|
||||||
|
<p>Precompiled binaries are available in most modern OS distributions, so
|
||||||
|
you should first check if you can install an rsync package via your
|
||||||
|
standard package-install tools for your OS.
|
||||||
|
|
||||||
|
<h3>Ubuntu</h3>
|
||||||
|
|
||||||
|
<p>The rsync project maintains a Launchpad PPA that tracks upstream stable
|
||||||
|
releases for the currently supported Ubuntu series (jammy 22.04 LTS,
|
||||||
|
noble 24.04 LTS, questing 25.10, resolute 26.04 LTS). This is the
|
||||||
|
fastest way to get the latest upstream rsync on Ubuntu without waiting
|
||||||
|
for the distro to update its packaged version:
|
||||||
|
|
||||||
|
<p><code><small>sudo add-apt-repository ppa:rsyncproject/rsync<br>
|
||||||
|
sudo apt update && sudo apt install rsync</small></code>
|
||||||
|
|
||||||
|
<p>See the <a href="https://launchpad.net/~rsyncproject/+archive/ubuntu/rsync">PPA page on Launchpad</a>
|
||||||
|
for build status across architectures.
|
||||||
|
|
||||||
|
<p>The <a href="https://github.com/RsyncProject/rsync/actions">GitHub Actions
|
||||||
|
page</a> has build events that each generate a few binary artifact zip files
|
||||||
|
(just click through via the build's title to see them). The actions page is
|
||||||
|
also linked via the various green build-status icons on the web pages here.
|
||||||
|
These builds use the newest libraries, such as xxhash checksums and zstd
|
||||||
|
compression, and are dynamically linked, so you may need to install some
|
||||||
|
official library packages for your distribution. If you're curious how the
|
||||||
|
build was done, you can look at the build rules in the "Workflow file" tab.
|
||||||
|
See the <a href="https://download.samba.org/pub/rsync/INSTALL">INSTALL.md</a>
|
||||||
|
file for some package name hints, though you can use the non-devel versions of
|
||||||
|
the various lib packages and ignore the gcc/autoconf/awk packages.
|
||||||
|
|
||||||
|
<p>There are also packages available from some <b>3rd-parties</b> (note that we
|
||||||
|
cannot vouch for 3rd parties, so use a source that you trust):
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li><p><a href="https://www.cygwin.com/">Cygwin</a> is a Posix runtime for MS
|
||||||
|
Windows that includes rsync among their many packages.</p></li>
|
||||||
|
|
||||||
|
<li><p><a href="https://www.itefix.net/cwrsync">cwRsync</a> is a native
|
||||||
|
packaging of rsync for MS Windows (they appear to only provide paid releases,
|
||||||
|
though).</p></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Git source vs Release files</h2>
|
||||||
|
|
||||||
|
The release tar files come with a few generated files that are not checked in to git.
|
||||||
|
These mainly include the man pages and the configure related files. To make use of
|
||||||
|
the git-derived files you will need autoconf, autoheader, and a version of python3
|
||||||
|
that has the commonmark lib (OR cmarkgfm). If you have trouble with setting up the
|
||||||
|
those required files, you can try running "./prepare-source fetchgen" to grab the
|
||||||
|
very latest generated files that were created from the latest commit into the master
|
||||||
|
branch.
|
||||||
|
|
||||||
|
<p> <b>Note:</b> Since the source repository is a work in progress it may, at
|
||||||
|
times, not compile or fail in various ways, though it is usually pretty good.
|
||||||
|
|
||||||
|
<h2>Source repository patches</h2>
|
||||||
|
|
||||||
|
<p>There are also various patch files in the "rsync-patches" repository that
|
||||||
|
represent either some work-in-progress features or features that are considered
|
||||||
|
to be a little too fringe-interest for the main release. See the github link
|
||||||
|
above for how to look around at what is available, or snag a release tar file.
|
||||||
|
The maintainer like to put the rsync-patches dir into his rsync checkout as a
|
||||||
|
directory named "patches" and has some helper scripts for how to use local git
|
||||||
|
branches to test and update the diffs.
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
54
rsync-web/examples.html
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync examples</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">rsync examples</H2>
|
||||||
|
|
||||||
|
If you have an interesting example of how you use rsync then please
|
||||||
|
submit it to the
|
||||||
|
<A HREF="mailto:rsync-bugs@samba.org">rsync-bugs@samba.org</A>
|
||||||
|
for inclusion on this page.
|
||||||
|
|
||||||
|
<h2>backup to a central backup server with 7 day incremental</h2>
|
||||||
|
|
||||||
|
<pre><small>
|
||||||
|
<!--#include virtual="backup.txt" -->
|
||||||
|
</small></pre>
|
||||||
|
|
||||||
|
<H2>backup to a spare disk</H2>
|
||||||
|
|
||||||
|
<pre><small>
|
||||||
|
<!--#include virtual="horus.txt" -->
|
||||||
|
</small></pre>
|
||||||
|
|
||||||
|
<H2>mirroring vger CVS tree</H2>
|
||||||
|
|
||||||
|
<pre><small>
|
||||||
|
<!--#include virtual="vger.txt" -->
|
||||||
|
</small></pre>
|
||||||
|
|
||||||
|
<H2>automated backup at home</H2>
|
||||||
|
|
||||||
|
<pre><small>
|
||||||
|
<!--#include virtual="susan.txt" -->
|
||||||
|
</small></pre>
|
||||||
|
|
||||||
|
<H2>Fancy footwork with remote file lists</H2>
|
||||||
|
|
||||||
|
<pre><small>
|
||||||
|
One little known feature of rsync is the fact that when run over a
|
||||||
|
remote shell (such as rsh or ssh) you can give any shell command as
|
||||||
|
the remote file list. The shell command is expanded by your remote
|
||||||
|
shell before rsync is called. For example, see if you can work out
|
||||||
|
what this does:
|
||||||
|
|
||||||
|
rsync -avR remote:'`find /home -name "*.[ch]"`' /tmp/
|
||||||
|
|
||||||
|
note that that is backquotes enclosed by quotes (some browsers don't
|
||||||
|
show that correctly).
|
||||||
|
</small></pre>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
28
rsync-web/features.html
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync features</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">rsync features</H2>
|
||||||
|
|
||||||
|
rsync is a file transfer program for Unix systems. rsync uses the
|
||||||
|
"rsync algorithm" which provides a very fast method for bringing
|
||||||
|
remote files into sync. It does this by sending just the differences
|
||||||
|
in the files across the link, without requiring that both sets of
|
||||||
|
files are present at one of the ends of the link beforehand. <p>
|
||||||
|
|
||||||
|
Some features of rsync include
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li> can update whole directory trees and filesystems
|
||||||
|
<li> optionally preserves symbolic links, hard links, file ownership,
|
||||||
|
permissions, devices and times
|
||||||
|
<li> requires no special privileges to install
|
||||||
|
<li> internal pipelining reduces latency for multiple files
|
||||||
|
<li> can use rsh, ssh or direct sockets as the transport
|
||||||
|
<li> supports <A HREF="http://dslab.lzu.edu.cn:8080/members/wangbj/wangbaojun/howtos/rsync-mirror-HOWTO/rsync-mirroring02.html">anonymous rsync</A> which is ideal for mirroring
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
13
rsync-web/filt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
P /badge.svg
|
||||||
|
H /.git/
|
||||||
|
H /.gitignore
|
||||||
|
H /bin/
|
||||||
|
H /upload/
|
||||||
|
P /USE_THE_GIT_rsync-web_REPO_NOW
|
||||||
|
H /filt
|
||||||
|
H *.swp
|
||||||
|
- /netware/
|
||||||
|
- /pre-change
|
||||||
|
- /rsync-and-debian/
|
||||||
|
- /index.html-*
|
||||||
|
- *~
|
||||||
13
rsync-web/find.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync search</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">Search the rsync web pages</H2>
|
||||||
|
|
||||||
|
<p>Searching samba.org will find results in the main web pages and in the
|
||||||
|
archived mailing-list pages too.
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
189
rsync-web/firewall.html
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync firewall tunneling</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">Using rsync through a firewall</H2>
|
||||||
|
|
||||||
|
<p>If you have a setup where there is no way to directly connect two
|
||||||
|
systems for an rsync transfer, there are several ways to get a firewall
|
||||||
|
system to act as an intermediary in the transfer.
|
||||||
|
|
||||||
|
<p>This first method should work for any remote-shell (e.g. ssh, rsh, etc).
|
||||||
|
The other methods are all targeted at ssh (which has a lot of flexibility
|
||||||
|
in making a tunneled connection possible).
|
||||||
|
|
||||||
|
<h4>Method 1 -- should work with any remote-shell</h4>
|
||||||
|
|
||||||
|
<p>Use your remote shell (e.g. ssh) to access the middle system and have it
|
||||||
|
use a remote shell to hop over to the actual target system.
|
||||||
|
|
||||||
|
<p>To effect this extra hop, you'll need to make sure that the remote-shell
|
||||||
|
connection from the middle system to the target system does not involve any
|
||||||
|
tty-based user interaction (such as prompting for a password) because there
|
||||||
|
is no way for the middle system to access the local user's tty.
|
||||||
|
|
||||||
|
<p>One way that should work for all remote-shell programs is to enable host-based
|
||||||
|
authentication, which would allow all connections from the middle system to
|
||||||
|
the target system to succeed (when the username remains the same).
|
||||||
|
However, this may not be a desirable setup.
|
||||||
|
|
||||||
|
<p>A better method that works with ssh (and is very safe) is to setup an ssh
|
||||||
|
key (see the ssh-keygen manpage) and ensure that ssh-agent forwarding is turned
|
||||||
|
on in your ssh client config (e.g. "ForwardAgent yes"). You would put
|
||||||
|
the public version of your key onto the middle and target systems (in the
|
||||||
|
~/.ssh/authorized_keys file), and the private key on your local system (which
|
||||||
|
I recommend you encrypt). With this setup, a series of ssh connections that
|
||||||
|
starts from the system where your private key is available will auto-authorize
|
||||||
|
(after a pass-phrase prompt on the first system if your key is encrypted).
|
||||||
|
See also ssh-agent for a way to keep a public key unlocked in memory for an
|
||||||
|
extended time, and the keychain project for a way to manage a system-wide,
|
||||||
|
per-user ssh-agent.
|
||||||
|
|
||||||
|
<p>To test that you have things setup right, first test a series of
|
||||||
|
remote-shell connections outside of rsync. A command such as the following
|
||||||
|
should work without issuing multiple prompts (use the appropriate remote-shell
|
||||||
|
and the substitute the real hostnames for "middle" and "target", of course):
|
||||||
|
|
||||||
|
<blockquote><pre>ssh middle ssh target uptime</pre></blockquote>
|
||||||
|
|
||||||
|
<p>If you get a password/passphrase prompt to get into the first ("middle")
|
||||||
|
system that's fine, but the extra hop needs to occur without any extra user
|
||||||
|
interaction.
|
||||||
|
|
||||||
|
<p>Once that's done, you can do an rsync copy like this:
|
||||||
|
|
||||||
|
<blockquote><pre>rsync -av -e "ssh middle ssh" target:/src/ /dest/</pre></blockquote>
|
||||||
|
|
||||||
|
<h4>Method 2 -- requires ssh and nc (netcat)</h4>
|
||||||
|
|
||||||
|
<p>Assuming you're using ssh as your remote shell, you can configure ssh to
|
||||||
|
use a proxy command to get to the remote host you're interested in reaching.
|
||||||
|
Doing this will allow the multi-hop connection to work with rsync, even if
|
||||||
|
both hosts prompt for a password -- this is because both ssh connections
|
||||||
|
originate from the localhost, and thus both instances of ssh have access to
|
||||||
|
the local tty to use for an out-of-band password prompt.
|
||||||
|
|
||||||
|
<p>Here is an example config for your ~/.ssh/config file (substitute "target",
|
||||||
|
"target_user", and "middle" as appropriate):
|
||||||
|
|
||||||
|
<blockquote><pre>Host target
|
||||||
|
ProxyCommand nohup ssh middle nc -w1 %h %p
|
||||||
|
User target_user
|
||||||
|
</pre></blockquote>
|
||||||
|
|
||||||
|
<p>This proxy setup uses "ssh" to login to the firewall system ("middle") and
|
||||||
|
uses "nc" (netcat) to connect to the target host ("target") using the default
|
||||||
|
port number. The use of "nohup" silences a warning at the end of the run, and
|
||||||
|
the "-w1" option tells nc to shut down when the connection closes.
|
||||||
|
|
||||||
|
<p>With this done, you can run a normal-looking rsync command to "target" that
|
||||||
|
will run the proxy command to get through the firewall system:
|
||||||
|
|
||||||
|
<blockquote><pre>rsync -av /src/ target:/dest/</pre></blockquote>
|
||||||
|
|
||||||
|
<h4>Method 3 -- an alternate ssh method for those without nc (netcat)</h4>
|
||||||
|
|
||||||
|
<p>Assuming you're using ssh as your remote shell, you can configure ssh to
|
||||||
|
forward a local port through your middle system to the ssh port (22) on the
|
||||||
|
target system. This method does not require the use of nc (it uses only
|
||||||
|
ssh to effect the extra hop), but otherwise it is similar to, but slightly
|
||||||
|
less convenient than, method 2.
|
||||||
|
|
||||||
|
<p>The first thing we need is an ssh configuration that will allow us to
|
||||||
|
connect to the forwarded port as if we were connecting to the target
|
||||||
|
system, and we need ssh to know what we're doing so that it doesn't
|
||||||
|
complain about the host keys being wrong. We can do this by adding this
|
||||||
|
section to your ~/.ssh/config file (substitute "target" and "target_user"
|
||||||
|
as appropriate, but leave "localhost" unchanged):
|
||||||
|
|
||||||
|
<blockquote><pre>Host target
|
||||||
|
HostName localhost
|
||||||
|
Port 2222
|
||||||
|
HostKeyAlias target
|
||||||
|
User target_user
|
||||||
|
</pre></blockquote>
|
||||||
|
|
||||||
|
<p>Next, we need to enable the port forwarding:
|
||||||
|
|
||||||
|
<blockquote><pre>ssh -fN -l middle_user -L 2222:target:22 middle</pre></blockquote>
|
||||||
|
|
||||||
|
<p>What this does is cause a connection to port 2222 on the local system to
|
||||||
|
get tunneled to the middle system and then turn into a connection to the
|
||||||
|
target system's port 22. The -N option tells ssh not to start a shell on
|
||||||
|
the remote system, which works with modern ssh versions (you can run a
|
||||||
|
sleep command if -N doesn't work). The -f option tells ssh to put the
|
||||||
|
command in the background after any password/passphrase prompts.
|
||||||
|
|
||||||
|
<p>With this done, you could run a normal-looking rsync command to "target"
|
||||||
|
that would use a connection to port 2222 on localhost automatically:
|
||||||
|
|
||||||
|
<blockquote><pre>rsync -av target:/src/ /dest/</pre></blockquote>
|
||||||
|
|
||||||
|
<p><b>Note:</b> starting an ssh tunnel allows anyone on the source system
|
||||||
|
to connect to the localhost port 2222, not just you, but they'd still need
|
||||||
|
to be able to login to the target system using their own credentials.
|
||||||
|
|
||||||
|
<h4>Method 4 -- for using rsync in daemon-mode (requires nc)</h4>
|
||||||
|
|
||||||
|
<p>Install and configure an rsync daemon on the target and use ssh and nc
|
||||||
|
to send the socket data to the remote host.
|
||||||
|
|
||||||
|
<blockquote><pre>RSYNC_CONNECT_PROG='ssh -l middle_user middle nc %H 873' \
|
||||||
|
rsync daemonuser@target::module/src/ /dest/</pre></blockquote>
|
||||||
|
|
||||||
|
<p>(You can also export that variable into your environment if you want to
|
||||||
|
perform a series of daemon rsync commands through the same middle host.)
|
||||||
|
|
||||||
|
<p>This command takes advantage of the RSYNC_CONNECT_PROG environment
|
||||||
|
variable, which tells rsync to pipe its socket data to an external program
|
||||||
|
in place of making a direct socket connection. The command specifed above
|
||||||
|
uses ssh to run the nc (netcat) command on the middle host, which forwards
|
||||||
|
all socket data to port 873 on the target host (%H). The "%H" will be
|
||||||
|
substituted with the target host from the rsync command as long as you're
|
||||||
|
running rsync 3.0.0 or newer (you'll need to replace %H with the actual
|
||||||
|
target hostname for earlier rsync versions, which makes the hostname
|
||||||
|
specified in the rsync command superfluous).
|
||||||
|
|
||||||
|
<h4>Method 5 -- for using rsync in daemon-mode (for those without nc)</h4>
|
||||||
|
|
||||||
|
<p>Install and configure an rsync daemon on the target and use an ssh
|
||||||
|
tunnel to reach the rsync sever. This is similar to method 3, but it
|
||||||
|
tunnels the daemon port for those that prefer to use an rsync daemon.
|
||||||
|
|
||||||
|
<p>(Note that this method also works to tunnel a socket connection
|
||||||
|
directly to a destination system if you use "localhost" as the target
|
||||||
|
hostname and your destination system's name as the middle hostname.)
|
||||||
|
|
||||||
|
<p>Installing the rsync daemon is beyond the scope of this document, but
|
||||||
|
see the rsyncd.conf manpage for more information. Keep in mind that you
|
||||||
|
don't need to be root to run an rsync daemon as long as you don't use a
|
||||||
|
protected port.
|
||||||
|
|
||||||
|
<p>Once your rsync daemon is up and running, you build an ssh tunnel
|
||||||
|
through your middle system like this:
|
||||||
|
|
||||||
|
<blockquote><pre>ssh -fN -l middle_user -L 8873:target:873 middle</pre></blockquote>
|
||||||
|
|
||||||
|
<p>What this does is cause a connection to port 8873 on the local system to
|
||||||
|
turn into a connection from the middle system to the target system on port
|
||||||
|
873. (Port 873 is the normal port for an rsync daemon.) The -N option
|
||||||
|
tells ssh not to start a shell on the remote system, which works with
|
||||||
|
modern ssh versions (you can run a sleep command if -N doesn't work). The
|
||||||
|
-f option tells ssh to put the command in the background after any
|
||||||
|
password/passphrase prompts.
|
||||||
|
|
||||||
|
<p>Now when an rsync command is executed with a daemon-mode command-line
|
||||||
|
syntax to the local system, the conversation is directed to the target
|
||||||
|
system. For example:
|
||||||
|
|
||||||
|
<blockquote><pre>rsync -av --port 8873 localhost::module/src/ dest/
|
||||||
|
rsync -av rsync://localhost:8873/module/src/ dest/</pre></blockquote>
|
||||||
|
|
||||||
|
<p><b>Note:</b> starting an ssh tunnel allows anyone on the source system
|
||||||
|
to connect to the localhost port 8873, not just you, so you may want to
|
||||||
|
enable username/password restrictions on your rsync daemon.
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
19
rsync-web/footer.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<TR ALIGN="center">
|
||||||
|
<TD><BR><a name="search"></a><img src="bar1.jpg" WIDTH="493" HEIGHT="26" BORDER="0" alt="=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=">
|
||||||
|
|
||||||
|
<!-- SiteSearch Google -->
|
||||||
|
<form action="https://www.google.com/cse" id="cse-search-box"><div>
|
||||||
|
<input type="hidden" name="cx" value="partner-pub-1444957896811922:vxjk7n-bst5" />
|
||||||
|
<input type="hidden" name="ie" value="ISO-8859-1" />
|
||||||
|
<input type="text" name="q" size="31" />
|
||||||
|
<input type="submit" name="sa" value="Search" />
|
||||||
|
</div></form>
|
||||||
|
<script type="text/javascript" src="https://www.google.com/cse/brand?form=cse-search-box&lang=en"></script>
|
||||||
|
<!-- SiteSearch Google -->
|
||||||
|
|
||||||
|
</TD>
|
||||||
|
</TR>
|
||||||
|
</TABLE>
|
||||||
40
rsync-web/header.html
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<BODY BGCOLOR="#ffffff" TEXT="#000000"
|
||||||
|
style="margin-top: 0">
|
||||||
|
<TABLE BORDER=0 WIDTH="640" ALIGN="CENTER">
|
||||||
|
<tr VALIGN="middle">
|
||||||
|
<td ALIGN="left">
|
||||||
|
<ul>
|
||||||
|
<li><small><a href=".">home</a></small>
|
||||||
|
<li><small><a href="FAQ.html">FAQ</a></small>
|
||||||
|
<li><small><a href="resources.html">resources</a></small>
|
||||||
|
<li><small><a href="features.html">features</a></small>
|
||||||
|
<li><small><a href="examples.html">examples</a></small>
|
||||||
|
<li><small><a href="lists.html">mailing lists</a></small>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="."><img src="newrsynclogo.jpg" border="0" alt="rsync"></a>
|
||||||
|
</td>
|
||||||
|
<td align="left">
|
||||||
|
<ul>
|
||||||
|
<li><small><a href="bug-tracking.html">bug-tracking</a></small>
|
||||||
|
<li><small><a href="issues.html">current issues and debugging</a></small>
|
||||||
|
<li><small><a href="download.html">download</a></small>
|
||||||
|
<li><small><a href="documentation.html">documentation</a></small>
|
||||||
|
<li><small><a href="find.html">search</a></small>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<TR ALIGN="center">
|
||||||
|
<TD COLSPAN="3">
|
||||||
|
<img src="bar1.jpg" WIDTH="493" HEIGHT="26"
|
||||||
|
BORDER="0"
|
||||||
|
alt="=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=">
|
||||||
|
</TD>
|
||||||
|
</TR>
|
||||||
|
</TABLE>
|
||||||
|
|
||||||
|
<TABLE BORDER=0 WIDTH="640" ALIGN="CENTER">
|
||||||
|
<tr VALIGN="middle">
|
||||||
|
<td ALIGN="left">
|
||||||
28
rsync-web/horus.txt
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
I do local backups on several of my machines using rsync. I have an
|
||||||
|
extra disk installed that can hold all the contents of the main
|
||||||
|
disk. I then have a nightly cron job that backs up the main disk to
|
||||||
|
the backup. This is the script I use on one of those machines.
|
||||||
|
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export PATH=/usr/local/bin:/usr/bin:/bin
|
||||||
|
|
||||||
|
LIST="rootfs usr data data2"
|
||||||
|
|
||||||
|
for d in $LIST; do
|
||||||
|
mount /backup/$d
|
||||||
|
rsync -ax --exclude fstab --delete /$d/ /backup/$d/
|
||||||
|
umount /backup/$d
|
||||||
|
done
|
||||||
|
|
||||||
|
DAY=`date "+%A"`
|
||||||
|
|
||||||
|
rsync -a --delete /usr/local/apache /data2/backups/$DAY
|
||||||
|
rsync -a --delete /data/solid /data2/backups/$DAY
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The first part does the backup on the spare disk. The second part
|
||||||
|
backs up the critical parts to daily directories. I also backup the
|
||||||
|
critical parts using a rsync over ssh to a remote machine.
|
||||||
|
|
||||||
350
rsync-web/how-rsync-works.html
Normal file
@@ -0,0 +1,350 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>How Rsync Works</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 align="center">How Rsync Works<br>A Practical Overview</h1>
|
||||||
|
<h2 align="center">Foreword</h2>
|
||||||
|
<p>
|
||||||
|
The original
|
||||||
|
<a href="http://rsync.samba.org/tech_report/">Rsync technical report</a>
|
||||||
|
and
|
||||||
|
Andrew Tridgell's
|
||||||
|
<a href="http://samba.org/%7Etridge/phd_thesis.pdf">Phd thesis (pdf)</a>
|
||||||
|
Are both excellent documents for understanding the
|
||||||
|
theoretical mathematics and some of the mechanics of the rsync algorithm.
|
||||||
|
Unfortunately they are more about the theory than the
|
||||||
|
implementation of the rsync utility (hereafter referred to as
|
||||||
|
Rsync).
|
||||||
|
<p>
|
||||||
|
In this document I hope to describe...
|
||||||
|
<ul>
|
||||||
|
<li>A non-mathematical overview of the rsync algorithm.
|
||||||
|
<li>How that algorithm is implemented in the rsync utility.
|
||||||
|
<li>The protocol, in general terms, used by the rsync utility.
|
||||||
|
<li>The identifiable roles the rsync processes play.
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
This document be able to serve as a guide for programmers
|
||||||
|
needing something of an entré into the source code but the
|
||||||
|
primary purpose is to give the reader a foundation from
|
||||||
|
which he may understand
|
||||||
|
<ul>
|
||||||
|
<li>Why rsync behaves as it does.
|
||||||
|
<li>The limitations of rsync.
|
||||||
|
<li>Why a requested feature is unsuited to the code-base.
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
This document describes in general terms the construction
|
||||||
|
and behaviour of Rsync. In some cases details and exceptions
|
||||||
|
that would contribute to specific accuracy have
|
||||||
|
been sacrificed for the sake meeting the broader goals.
|
||||||
|
<h2 align="center">Processes and Roles</h2>
|
||||||
|
<p>
|
||||||
|
When we talk about Rsync we use specific terms to refer to
|
||||||
|
various processes and their roles in the task performed by
|
||||||
|
the utility. For effective communication it is important that we
|
||||||
|
all be speaking the same language; likewise it is important
|
||||||
|
that we mean the same things when we use certain terms in a
|
||||||
|
given context. On the rsync mailing list there is often
|
||||||
|
some confusion with regards to role and processes. For
|
||||||
|
these reasons I will define a few terms
|
||||||
|
used in the role and process contexts that will be used henceforth.
|
||||||
|
|
||||||
|
<table cellspacing="20"><tr valign="top">
|
||||||
|
<td>client
|
||||||
|
</td><td>role
|
||||||
|
</td><td>
|
||||||
|
The client initiates the synchronisation.
|
||||||
|
</td></tr><tr valign="top">
|
||||||
|
<td>server
|
||||||
|
</td><td>role
|
||||||
|
</td><td>
|
||||||
|
The remote rsync process or system to which the
|
||||||
|
client connects either within a local transfer, via
|
||||||
|
a remote shell or via a network socket.
|
||||||
|
<p>
|
||||||
|
This is a general term and should not be confused with the daemon.
|
||||||
|
</td></tr><tr valign="top">
|
||||||
|
<td>
|
||||||
|
</td><td>
|
||||||
|
</td><td bgcolor="#dddddd">
|
||||||
|
Once the connection between the client and server is established
|
||||||
|
the distinction between them is superseded by the
|
||||||
|
sender and receiver roles.
|
||||||
|
</td></tr><tr valign="top">
|
||||||
|
<td>daemon
|
||||||
|
</td><td>Role and process
|
||||||
|
</td><td>
|
||||||
|
An Rsync process that awaits connections from
|
||||||
|
clients. On a certain platform this would be called a
|
||||||
|
service.
|
||||||
|
</td></tr><tr valign="top">
|
||||||
|
<td>remote shell
|
||||||
|
</td><td>role and set of processes
|
||||||
|
</td><td>
|
||||||
|
One or more processes that provide connectivity
|
||||||
|
between an Rsync client and an Rsync server on a
|
||||||
|
remote system.
|
||||||
|
</td></tr><tr valign="top">
|
||||||
|
<td>sender
|
||||||
|
</td><td>role and process
|
||||||
|
</td><td>
|
||||||
|
The Rsync process that has access to the source
|
||||||
|
files being synchronised.
|
||||||
|
</td></tr><tr valign="top">
|
||||||
|
<td>receiver
|
||||||
|
</td><td>role and process
|
||||||
|
</td><td>
|
||||||
|
As a role the receiver is the destination system.
|
||||||
|
As a process the receiver is the process that
|
||||||
|
receives update data and writes it to disk.
|
||||||
|
</td></tr><tr valign="top">
|
||||||
|
<td>generator
|
||||||
|
</td><td>process
|
||||||
|
</td><td>
|
||||||
|
The generator process identifies changed files and
|
||||||
|
manages the file level logic.
|
||||||
|
</td></tr></table>
|
||||||
|
<p>
|
||||||
|
<h2 align="center">Process Startup</h2>
|
||||||
|
<p>
|
||||||
|
When an Rsync client is started it will first establish a
|
||||||
|
connection with a server process. This connection may be
|
||||||
|
through pipes or over a network socket.
|
||||||
|
<p>
|
||||||
|
When Rsync communicates with a remote non-daemon server via
|
||||||
|
a remote shell the startup method is to fork the remote
|
||||||
|
shell which will start an Rsync server on the remote system.
|
||||||
|
Both the Rsync client and server are communicating via pipes
|
||||||
|
through the remote shell. As far as the rsync processes are
|
||||||
|
concerned there is no network.
|
||||||
|
In this mode the rsync options for the server process are
|
||||||
|
passed on the command-line that is used to start the remote
|
||||||
|
shell.
|
||||||
|
<p>
|
||||||
|
When Rsync is communicating with a daemon it is
|
||||||
|
communicating directly with a network socket. This is the
|
||||||
|
only sort of Rsync communication that could be called
|
||||||
|
network aware.
|
||||||
|
In this mode the rsync options must be sent over the socket, as
|
||||||
|
described below.
|
||||||
|
<p>
|
||||||
|
At the very start of the communication between the client
|
||||||
|
and the server, they each send the maximum protocol version
|
||||||
|
they support to the other side.
|
||||||
|
Each side then uses the minimum value as the the protocol
|
||||||
|
level for the transfer.
|
||||||
|
If this is a daemon-mode connection, rsync options are sent
|
||||||
|
from the client to the server. Then, the exclude list is
|
||||||
|
transmitted. From this point onward the
|
||||||
|
client-server relationship is relevant only with regards
|
||||||
|
to error and log message delivery.
|
||||||
|
<p>
|
||||||
|
Local Rsync jobs (when the source and destination are both on locally
|
||||||
|
mounted filesystems) are done exactly like a push. The
|
||||||
|
client, which becomes the sender, forks a server process to
|
||||||
|
fulfill the receiver role. The client/sender and
|
||||||
|
server/receiver communicate with each other over pipes.
|
||||||
|
<h2 align="center">The File List</h2>
|
||||||
|
The file list includes not only the pathnames but also
|
||||||
|
ownership, mode, permissions, size and modtime.
|
||||||
|
If the --checksum option has been specified it also includes
|
||||||
|
the file checksums.
|
||||||
|
<p>
|
||||||
|
The first thing that happens once the startup has completed
|
||||||
|
is that the sender will create the file list.
|
||||||
|
While it is being built, each entry is transmitted to the
|
||||||
|
receiving side in a network-optimised way.
|
||||||
|
<p>
|
||||||
|
When this is done, each side sorts the file list lexicographically by path
|
||||||
|
relative to the base directory of the transfer.
|
||||||
|
(The exact sorting algorithm varies depending on what protocol
|
||||||
|
version is in effect for the transfer.)
|
||||||
|
Once that has happened all references to files
|
||||||
|
will be done by their index in the file list.
|
||||||
|
<p>
|
||||||
|
If necessary the sender follows the file list with id→name
|
||||||
|
tables for users and groups which the receiver will use to
|
||||||
|
do a id→name→id translation for every file in the file
|
||||||
|
list.
|
||||||
|
<p>
|
||||||
|
After the file list has been received by the receiver, it
|
||||||
|
will fork to become the generator and receiver pair
|
||||||
|
completing the pipeline.
|
||||||
|
<h2 align="center">The Pipeline</h2>
|
||||||
|
Rsync is heavily pipelined. This means that it is a set of
|
||||||
|
processes that communicate in a (largely) unidirectional
|
||||||
|
way. Once the file list has been shared the pipeline
|
||||||
|
behaves like this:
|
||||||
|
<blockquote>
|
||||||
|
generator → sender → receiver
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
The output of the generator is input for the sender and the
|
||||||
|
output of the sender is input for the receiver.
|
||||||
|
Each process runs independently and is delayed only when the
|
||||||
|
pipelines stall or when waiting for disk I/O or CPU resources.
|
||||||
|
<h2 align="center">The Generator</h2>
|
||||||
|
<p>
|
||||||
|
The generator process compares the file list with its local
|
||||||
|
directory tree. Prior to beginning its primary function, if
|
||||||
|
--delete has been specified, it will first identify local
|
||||||
|
files not on the sender and delete them on the receiver.
|
||||||
|
<p>
|
||||||
|
The generator will then start walking the file list. Each
|
||||||
|
file will be checked to see if it can be skipped. In the
|
||||||
|
most common mode of operation files are not skipped if the
|
||||||
|
modification time or size differs. If --checksum was
|
||||||
|
specified a file-level checksum will be created and
|
||||||
|
compared. Directories, device nodes and symlinks are not
|
||||||
|
skipped. Missing directories will be created.
|
||||||
|
<p>
|
||||||
|
If a file is not to be skipped, any existing version on the
|
||||||
|
receiving side becomes the "basis file" for the transfer, and is
|
||||||
|
used as a data source that will help to eliminate matching data
|
||||||
|
from having to be sent by the sender. To effect this remote
|
||||||
|
matching of data, block checksums are created for the basis file
|
||||||
|
and sent to the sender immediately following the file's index
|
||||||
|
number.
|
||||||
|
An empty block checksum set is sent for new files and if
|
||||||
|
--whole-file was specified.
|
||||||
|
<p>
|
||||||
|
The block size and, in later versions, the size of the
|
||||||
|
block checksum are calculated on a per file basis according
|
||||||
|
to the size of that file.
|
||||||
|
<h2 align="center">The Sender</h2>
|
||||||
|
The sender process reads the file index numbers and associated
|
||||||
|
block checksum sets one at a time from the generator.
|
||||||
|
<p>
|
||||||
|
For each file id the generator sends it will store the
|
||||||
|
block checksums and build a hash index of them for rapid lookup.
|
||||||
|
<p>
|
||||||
|
Then the local file is read and a checksum is
|
||||||
|
generated for the block beginning with the first byte of the
|
||||||
|
local file. This block checksum is looked for in the
|
||||||
|
set that was sent by the generator, and if no match is found,
|
||||||
|
the non-matching byte will be appended to the non-matching data
|
||||||
|
and the block starting at the next byte will be compared.
|
||||||
|
This is what
|
||||||
|
is referred to as the “rolling checksum”
|
||||||
|
<p>
|
||||||
|
If a block checksum match is found it is considered a
|
||||||
|
matching block and any accumulated non-matching data will be
|
||||||
|
sent to the receiver followed by the offset and length in
|
||||||
|
the receiver's file of the matching block and the block
|
||||||
|
checksum generator will be advanced to the next byte after
|
||||||
|
the matching block.
|
||||||
|
<p>
|
||||||
|
Matching blocks can be identified in this way even if
|
||||||
|
the blocks are reordered or at different offsets.
|
||||||
|
This process is the very heart of the rsync algorithm.
|
||||||
|
<p>
|
||||||
|
In this way, the sender will give the receiver instructions for
|
||||||
|
how to reconstruct the source file into a new destination file.
|
||||||
|
These instructions detail all the matching data that can be
|
||||||
|
copied from the basis file (if one exists for the transfe),
|
||||||
|
and includes any raw data that was not available locally.
|
||||||
|
At the end of each file's processing a whole-file
|
||||||
|
checksum is sent and the sender proceeds with the next
|
||||||
|
file.
|
||||||
|
<p>
|
||||||
|
Generating the rolling checksums and searching for matches
|
||||||
|
in the checksum set sent by the generator require a good
|
||||||
|
deal of CPU power. Of all the rsync processes it is the
|
||||||
|
sender that is the most CPU intensive.
|
||||||
|
<h2 align="center">The Receiver</h2>
|
||||||
|
<p>
|
||||||
|
The receiver will read from the sender data for each file
|
||||||
|
identified by the file index number. It will open the local
|
||||||
|
file (called the basis) and will create a temporary file.
|
||||||
|
<p>
|
||||||
|
The receiver will expect to read non-matched data and/or to match
|
||||||
|
records all in sequence for the final file contents. When
|
||||||
|
non-matched data is read it will be written to the
|
||||||
|
temp-file. When a block match record is received the
|
||||||
|
receiver will seek to the block offset in the basis file
|
||||||
|
and copy the block to the temp-file. In this way the
|
||||||
|
temp-file is built from beginning to end.
|
||||||
|
<p>
|
||||||
|
The file's checksum is generated as the temp-file is built.
|
||||||
|
At the end of the file, this checksum is compared with the
|
||||||
|
file checksum from the sender. If the file checksums do not
|
||||||
|
match the temp-file is deleted. If the file fails once it
|
||||||
|
will be reprocessed in a second phase, and if it fails twice
|
||||||
|
an error is reported.
|
||||||
|
<p>
|
||||||
|
After the temp-file has been completed, its ownership and
|
||||||
|
permissions and modification time are set. It is then
|
||||||
|
renamed to replace the basis file.
|
||||||
|
<p>
|
||||||
|
Copying data from the basis file to the temp-file make the
|
||||||
|
receiver the most disk intensive of all the rsync processes.
|
||||||
|
Small files may still be in disk cache mitigating this but
|
||||||
|
for large files the cache may thrash as the generator has
|
||||||
|
moved on to other files and there is further latency caused
|
||||||
|
by the sender. As
|
||||||
|
data is read possibly at random from one file and written to
|
||||||
|
another, if the working set is larger than the disk cache,
|
||||||
|
then what is called a seek storm can occur, further
|
||||||
|
hurting performance.
|
||||||
|
<h2 align="center">The Daemon</h2>
|
||||||
|
The daemon process, like many daemons, forks for every
|
||||||
|
connection. On startup, it parses the rsyncd.conf file
|
||||||
|
to determine what modules exist and to set the global options.
|
||||||
|
<p>
|
||||||
|
When a connection is received for a defined module the
|
||||||
|
daemon forks a new child process to handle the connection.
|
||||||
|
That child process then reads the rsyncd.conf file to set
|
||||||
|
the options for the requested module, which may chroot to the
|
||||||
|
module path and may drop setuid and setgid for the
|
||||||
|
process. After that it will behave just like any other
|
||||||
|
rsync server process adopting either a sender or receiver
|
||||||
|
role.
|
||||||
|
<h2 align="center">The Rsync Protocol</h2>
|
||||||
|
<p>
|
||||||
|
A well-designed communications protocol has a number of
|
||||||
|
characteristics.
|
||||||
|
<ul>
|
||||||
|
<li>Everything is sent in well defined packets with
|
||||||
|
a header and an optional body or data payload.
|
||||||
|
<li>In each packet's header a type and or command
|
||||||
|
specified.
|
||||||
|
<li>Each packet has a definite length.
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
In addition to these characteristics, protocols have varying degrees of
|
||||||
|
statefulness, inter-packet independence, human readability,
|
||||||
|
and the ability to reestablish a disconnected session.
|
||||||
|
<p>
|
||||||
|
Rsync's protocol has none of these good characteristics. The data is
|
||||||
|
transferred as an unbroken stream of bytes. With the
|
||||||
|
exception of the unmatched file-data, there are no length
|
||||||
|
specifiers nor counts. Instead the meaning of each byte is
|
||||||
|
dependent on its context as defined by the protocol level.
|
||||||
|
<p>
|
||||||
|
As an example, when the sender is sending the file list it
|
||||||
|
simply sends each file list entry and terminates the list
|
||||||
|
with a null byte. Within the file list entries, a bitfield
|
||||||
|
indicates which fields of the structure to expect and those
|
||||||
|
that are variable length strings are simply null terminated.
|
||||||
|
The generator sending file numbers and block checksum sets
|
||||||
|
works the same way.
|
||||||
|
<p>
|
||||||
|
This method of communication works quite well on reliable
|
||||||
|
connections and it certainly has less data overhead than the
|
||||||
|
formal protocols. It unfortunately makes the protocol
|
||||||
|
extremely difficult to document, debug or extend.
|
||||||
|
Each version of the protocol will have subtle differences on
|
||||||
|
the wire that can only be anticipated by knowing the exact
|
||||||
|
protocol version.
|
||||||
|
<h2 align="center">notes</h2>
|
||||||
|
This document is a work in progress. The author expects
|
||||||
|
that it has some glaring oversights and some portions that may be
|
||||||
|
more confusing than enlightening for some readers. It is
|
||||||
|
hoped that this could evolve into a useful reference.
|
||||||
|
<p>
|
||||||
|
Specific suggestions for improvement are welcome, as would be a
|
||||||
|
complete rewrite.
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
528
rsync-web/index.html
Normal file
@@ -0,0 +1,528 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync</TITLE>
|
||||||
|
<style>
|
||||||
|
.security { color: red; }
|
||||||
|
h3 { margin-bottom: 0px; }
|
||||||
|
.date { color: #D25A0B; }
|
||||||
|
</style>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">Welcome to the rsync web pages</H2>
|
||||||
|
|
||||||
|
rsync is an <A HREF="https://www.opensource.org/">open source</A>
|
||||||
|
utility that provides fast incremental file transfer. rsync is freely
|
||||||
|
available under the <A HREF="GPL.html">GNU General Public
|
||||||
|
License</A> and is currently being maintained by
|
||||||
|
<a href="email:<tridge@samba.org>">Andrew Tridgell</a>.
|
||||||
|
|
||||||
|
<p>A full changelog of all the releases, including upcoming releases, is in the
|
||||||
|
<a href="https://download.samba.org/pub/rsync/NEWS">NEWS file</a>.
|
||||||
|
|
||||||
|
<div style="float: right">
|
||||||
|
<a href="https://github.com/RsyncProject/rsync/actions">
|
||||||
|
<img src="badge.svg">
|
||||||
|
</a></div>
|
||||||
|
|
||||||
|
<h3>Rsync version 3.4.3 released</h3>
|
||||||
|
<i class=date>May 20th, 2026</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.4.3 has been released. This is a major security release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.4.3">3.4.3 NEWS</a> for a detailed changelog.
|
||||||
|
The latest manpages are also available for:<ul>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rsync.1"><b>rsync</b>(1)</a>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rsync-ssl.1"><b>rsync-ssl</b>(1)</a>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rsyncd.conf.5"><b>rsyncd.conf</b>(5)</a>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rrsync.1"><b>rrsync</b>(1)</a>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>The source tar is available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-3.4.3.tar.gz">rsync-3.4.3.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-3.4.3.tar.gz.asc">signature</a>)</b>,
|
||||||
|
and the diffs from version 3.4.2 are available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.4.2-3.4.3.diffs.gz">rsync-3.4.2-3.4.3.diffs.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.4.2-3.4.3.diffs.gz.asc">signature</a>)</b>.
|
||||||
|
|
||||||
|
<h3>Rsync version 3.4.2 released</h3>
|
||||||
|
<i class=date>April 28th, 2026</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.4.2 has been released.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.4.2">3.4.2 NEWS</a> for a detailed changelog.
|
||||||
|
The latest manpages are also available for:<ul>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rsync.1"><b>rsync</b>(1)</a>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rsync-ssl.1"><b>rsync-ssl</b>(1)</a>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rsyncd.conf.5"><b>rsyncd.conf</b>(5)</a>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rrsync.1"><b>rrsync</b>(1)</a>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>The source tar is available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-3.4.2.tar.gz">rsync-3.4.2.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-3.4.2.tar.gz.asc">signature</a>)</b>,
|
||||||
|
and the diffs from version 3.4.1 are available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.4.1-3.4.2.diffs.gz">rsync-3.4.1-3.4.2.diffs.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.4.1-3.4.2.diffs.gz.asc">signature</a>)</b>.
|
||||||
|
|
||||||
|
<h3>Rsync version 3.4.1 released</h3>
|
||||||
|
<i class=date>January 15th, 2025</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.4.1 has been released.
|
||||||
|
This is a fix for some regressions in 3.4.0
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.4.1">3.4.1 NEWS</a> for a detailed changelog.
|
||||||
|
The latest manpages are also available for:<ul>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rsync.1"><b>rsync</b>(1)</a>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rsync-ssl.1"><b>rsync-ssl</b>(1)</a>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rsyncd.conf.5"><b>rsyncd.conf</b>(5)</a>
|
||||||
|
<li><a href="https://download.samba.org/pub/rsync/rrsync.1"><b>rrsync</b>(1)</a>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>The source tar is available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-3.4.1.tar.gz">rsync-3.4.1.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-3.4.1.tar.gz.asc">signature</a>)</b>,
|
||||||
|
with a tar file of the "rsync-patches" repository released in a separate file:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.4.1.tar.gz">rsync-patches-3.4.1.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.4.1.tar.gz.asc">signature</a>)</b>,
|
||||||
|
and the diffs from version 3.4.0 are available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.4.0-3.4.1.diffs.gz">rsync-3.4.0-3.4.1.diffs.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.4.0-3.4.1.diffs.gz.asc">signature</a>)</b>.
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Rsync version 3.4.0 released</h3>
|
||||||
|
<i class=date>January 14th, 2025</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.4.0 has been released.
|
||||||
|
This is a security release, fixing several important security vulnerabilities.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.4.0">3.4.0 NEWS</a> for a detailed changelog.
|
||||||
|
|
||||||
|
<p>The source tar is available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-3.4.0.tar.gz">rsync-3.4.0.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-3.4.0.tar.gz.asc">signature</a>)</b>,
|
||||||
|
with a tar file of the "rsync-patches" repository released in a separate file:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.4.0.tar.gz">rsync-patches-3.4.0.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.4.0.tar.gz.asc">signature</a>)</b>,
|
||||||
|
and the diffs from version 3.3.0 are available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.3.0-3.4.0.diffs.gz">rsync-3.3.0-3.4.0.diffs.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.3.0-3.4.0.diffs.gz.asc">signature</a>)</b>.
|
||||||
|
|
||||||
|
<h3>Rsync version 3.3.0 released</h3>
|
||||||
|
<i class=date>April 6th, 2024</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.3.0 has been released.
|
||||||
|
This is a bug-fix release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.3.0">3.3.0 NEWS</a> for a detailed changelog.
|
||||||
|
|
||||||
|
<p>The source tar is available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-3.3.0.tar.gz">rsync-3.3.0.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-3.3.0.tar.gz.asc">signature</a>)</b>,
|
||||||
|
with a tar file of the "rsync-patches" repository released in a separate file:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.3.0.tar.gz">rsync-patches-3.3.0.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.3.0.tar.gz.asc">signature</a>)</b>,
|
||||||
|
and the diffs from version 3.2.2 are available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.2.7-3.3.0.diffs.gz">rsync-3.2.7-3.3.0.diffs.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.2.7-3.3.0.diffs.gz.asc">signature</a>)</b>.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.2.7 released</h3>
|
||||||
|
<i class=date>October 20th, 2022</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.2.7 has been released.
|
||||||
|
This has some new features & fixes, including various bug fixes for arg validation & filter-rule validation.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.2.7">3.2.7 NEWS</a> for a detailed changelog.
|
||||||
|
|
||||||
|
<p>The source tar is available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-3.2.7.tar.gz">rsync-3.2.7.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-3.2.7.tar.gz.asc">signature</a>)</b>,
|
||||||
|
with a tar file of the "rsync-patches" repository released in a separate file:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.2.7.tar.gz">rsync-patches-3.2.7.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.2.7.tar.gz.asc">signature</a>)</b>,
|
||||||
|
and the diffs from version 3.2.2 are available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.2.6-3.2.7.diffs.gz">rsync-3.2.6-3.2.7.diffs.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.2.6-3.2.7.diffs.gz.asc">signature</a>)</b>.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.2.6 released</h3>
|
||||||
|
<i class=date>September 9th, 2022</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.2.6 has been released.
|
||||||
|
This is a bug-fix release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.2.6">3.2.6 NEWS</a> for a detailed changelog.
|
||||||
|
|
||||||
|
<p>The source tar is available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-3.2.6.tar.gz">rsync-3.2.6.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-3.2.6.tar.gz.asc">signature</a>)</b>,
|
||||||
|
with a tar file of the "rsync-patches" repository released in a separate file:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.2.6.tar.gz">rsync-patches-3.2.6.tar.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src/rsync-patches-3.2.6.tar.gz.asc">signature</a>)</b>,
|
||||||
|
and the diffs from version 3.2.2 are available here:
|
||||||
|
<b><a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.2.5-3.2.6.diffs.gz">rsync-3.2.5-3.2.6.diffs.gz</a>
|
||||||
|
(<a href="https://download.samba.org/pub/rsync/src-diffs/rsync-3.2.5-3.2.6.diffs.gz.asc">signature</a>)</b>.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.2.5 released</h3>
|
||||||
|
<i class=date>August 14th, 2022</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.2.5 has been released.
|
||||||
|
This is a bug-fix and <a href="security.html" class=security>security</a> release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.2.5">3.2.5 NEWS</a> for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.2.4 released</h3>
|
||||||
|
<i class=date>April 15th, 2022</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.2.4 has been released.
|
||||||
|
Another typical release with both bug fixes and some enhancements. It also contains a
|
||||||
|
<a href="security.html#s3_2_4" class=security>security fix</a>
|
||||||
|
for the bundled zlib 1.2.8, which may or may not be used in your particular build configuration.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.2.4">3.2.4 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.2.3 released</h3>
|
||||||
|
<i class=date>August 6th, 2020</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.2.3 has been released.
|
||||||
|
It contains a smattering of bug fixes and various enhancements.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.2.3">3.2.3 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.2.2 released</h3>
|
||||||
|
<i class=date>July 4th, 2020</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.2.2 has been released.
|
||||||
|
This is a few more portability fixes, some improvements to the newest features, and some
|
||||||
|
other simple changes. Hopefully this will be the last of these recent touch-up releases.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.2.2">3.2.2 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.2.1 released</h3>
|
||||||
|
<i class=date>June 22th, 2020</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.2.1 has been released.
|
||||||
|
This is mainly a few fixes for some release issues and portability problems.
|
||||||
|
There's also a couple new features, just for good measure.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.2.1">3.2.1 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.2.0 released</h3>
|
||||||
|
<i class=date>June 19th, 2020</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.2.0 has been released.
|
||||||
|
This release has a good number of a few new features and various bug fixes.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.2.0">3.2.0 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.1.3 released</h3>
|
||||||
|
<i class=date>January 28th, 2018</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.1.3 has been released.
|
||||||
|
This release has a
|
||||||
|
<a href="security.html#s3_1_3" class=security>couple security fixes</a>,
|
||||||
|
a few new features, and various bug fixes.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.1.3">3.1.3 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.1.2 released</h3>
|
||||||
|
<i class=date>December 21st, 2015</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.1.2 has been released. This is a bug-fix release.
|
||||||
|
It includes a <a href="security.html#s3_1_2" class=security>security fix</a>
|
||||||
|
for a transfer from a sender that you don't fully trust.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.1.2">3.1.2 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.1.1 released</h3>
|
||||||
|
<i class=date>June 22nd, 2014</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.1.1 has been released. This is a bug-fix release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.1.1">3.1.1 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.1.0 released</h3>
|
||||||
|
<i class=date>September 28th, 2013</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.1.0 has been released. This is a
|
||||||
|
feature release that improves performance, provides several new options, and
|
||||||
|
fixes a few bugs along the way.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.1.0">3.1.0 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.9 released</h3>
|
||||||
|
<i class=date>September 23th, 2011</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.9 has been released. This is a bug-fix release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.9">3.0.9 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.8 released</h3>
|
||||||
|
<i class=date>March 26th, 2011</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.8 has been released. This is a bug-fix release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.8">3.0.8 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.7 released</h3>
|
||||||
|
<i class=date>December 31th, 2009</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.7 has been released. This is a bug-fix release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.7">3.0.7 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.6 released</h3>
|
||||||
|
<i class=date>May 8th, 2009</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.6 has been released. This is a bug-fix release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.6">3.0.6 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.5 released</h3>
|
||||||
|
<i class=date>December 28th, 2008</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.5 has been released. This is another bug-fix release.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.5">3.0.5 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.4 released</h3>
|
||||||
|
<i class=date>September 6th, 2008</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.4 has been released. This is a bug-fix release with the
|
||||||
|
only enhancement being the adding of a way to interact with an
|
||||||
|
overly-restrictive server that refuses rsync's behind-the-scenes use of the -e
|
||||||
|
option.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.4">3.0.4 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.3 released</h3>
|
||||||
|
<i class=date>June 29th, 2008</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.3 has been released. This is a bug-fix release that has
|
||||||
|
no new features (though it does have one new script in the support directory).
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.3">3.0.3 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.2 released</h3>
|
||||||
|
<i class=date>April 8th, 2008</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.2 has been released. This is a
|
||||||
|
<a href="security.html#s3_0_2" class=security>security release</a>
|
||||||
|
that fixes a potential buffer-overflow issue.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.2">3.0.2 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.1 released</h3>
|
||||||
|
<i class=date>April 3rd, 2008</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.1 has been released. This is a bug-fix release, which also
|
||||||
|
includes fixes/improvements for several issues in the daemon-exclude code.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.1">3.0.1 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 3.0.0 released</h3>
|
||||||
|
<i class=date>March 1st, 2008</i>
|
||||||
|
|
||||||
|
<p>Rsync version 3.0.0 is finally here! This is a feature release that
|
||||||
|
also includes quite a few bug fixes.
|
||||||
|
|
||||||
|
<p>The 3.0.0 version number is such a large bump up from 2.6.9 due to the
|
||||||
|
addition of an
|
||||||
|
incremental recursion scan (which helps a lot with large transfers) and the
|
||||||
|
official arrival of several other new features, including ACL support, extended
|
||||||
|
attribute support, filename character-set conversion, etc.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#3.0.0">3.0.0 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 2.6.9 released</h3>
|
||||||
|
<i class=date>November 6th, 2006</i>
|
||||||
|
|
||||||
|
<p>Rsync version 2.6.9 has been released. This is primarily a bug-fix
|
||||||
|
release with a few minor new features.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#2.6.9">2.6.9 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync version 2.6.8 released</h3>
|
||||||
|
<i class=date>April 22th, 2006</i>
|
||||||
|
|
||||||
|
<p>Rsync version 2.6.8 has been released. This is a bug-fix release that
|
||||||
|
primarily addresses an exclude problem that affected the --relative option,
|
||||||
|
but also includes a <a href="security.html#s2_6_8" class=security>security fix</a> for
|
||||||
|
the xattrs.diff patch (which is not an
|
||||||
|
official part of rsync, but some packagers include it in their release).
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#2.6.8">2.6.8 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync 2.6.7 released</h3>
|
||||||
|
<i class=date>March 11th, 2006</i>
|
||||||
|
|
||||||
|
<p>Rsync version 2.6.7 has been released. This release has both several new
|
||||||
|
features and the usual accompaniment of bug fixes.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#2.6.7">2.6.7 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync 2.6.6 released</h3>
|
||||||
|
<i class=date>July 28th, 2005</i>
|
||||||
|
|
||||||
|
<p>Rsync version 2.6.6 has been released. This release is a bug-fix release
|
||||||
|
which contains a <a href="security.html#s2_6_6" class=security>security fix</a>
|
||||||
|
to handle a null-pointer bug that turned up in rsync's version of zlib
|
||||||
|
1.1.4 (this is not the recent zlib 1.2.2 security fix, which did not
|
||||||
|
affect rsync) and to squash a few other minor bugs. To deal with the
|
||||||
|
zlib issue, rsync has been upgraded to include zlib 1.2.3.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#2.6.6">2.6.6 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync 2.6.5 released</h3>
|
||||||
|
<i class=date>June 1st, 2005</i>
|
||||||
|
|
||||||
|
<p>Rsync version 2.6.5 has been released. This release is primarily a bug-fix
|
||||||
|
release to squash some annoying problems that made it into the (feature-filled)
|
||||||
|
release of 2.6.4, plus a few minor enhancements.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#2.6.5">2.6.5 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync 2.6.4 released</h3>
|
||||||
|
<i class=date>March 30th, 2005</i>
|
||||||
|
|
||||||
|
<p>Rsync version 2.6.4 has been released. This release combines quite a
|
||||||
|
few new features, some improved delete efficiency, and the usual array of
|
||||||
|
bug fixes.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#2.6.4">2.6.4 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync 2.6.3 released</h3>
|
||||||
|
<i class=date>September 30th, 2004</i>
|
||||||
|
|
||||||
|
<p>Rsync version 2.6.3 has been released. It contains several new features
|
||||||
|
and quite a few bug fixes, including a <a href="security.html#s2_6_3" class=security>security
|
||||||
|
fix</a> for a patch-sanitizing bug in the daemon code.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#2.6.3">2.6.3 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync 2.6.2 released</h3>
|
||||||
|
<i class=date>April 30th, 2004</i>
|
||||||
|
|
||||||
|
<p>Rsync version 2.6.2 has been released. It is a bug-fix release that mainly
|
||||||
|
fixes <b>a bug with the --relative option (-R) in 2.6.1</b>
|
||||||
|
that could cause files to be transferred incorrectly. This only affected a
|
||||||
|
source right at the root of the filesystem, such as "/" or "/*" (if you
|
||||||
|
first "cd /" and then copy from ".", it would not tickle the bug).
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#2.6.2">2.6.2 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync 2.6.1 released</h3>
|
||||||
|
<i class=date>April 26th, 2004</i>
|
||||||
|
|
||||||
|
<p>Rsync version 2.6.1 has been released. It is primarily a performance
|
||||||
|
release that requires less memory to run, makes fewer write calls to the socket
|
||||||
|
(lowering the system CPU time), does less string copying (lowering the user CPU
|
||||||
|
time), and also reduces the amount of data that is transmitted over the wire.
|
||||||
|
There have also been quite a few bug fixes, including a
|
||||||
|
<a href="security.html#s2_6_1" class=security>security fix</a> for a daemon problem when chroot
|
||||||
|
is not enabled. See the
|
||||||
|
<a href="https://download.samba.org/pub/rsync/NEWS#2.6.1">2.6.1 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>One Cygwin hang-problem resolved</h3>
|
||||||
|
|
||||||
|
<p>The problem with rsync hanging at the end of the transfer on
|
||||||
|
<a href="https://www.cygwin.com/">Cygwin</a> had been previously traced to a
|
||||||
|
signal-handling bug in their compatibility DLL. This bug appears to now be
|
||||||
|
fixed in DLL version 1.5.7-1, and Cygwin users are reporting that upgrading the
|
||||||
|
DLL removes the hang-at-end-of-transfer problem for their existing rsync executable.
|
||||||
|
(Note that this doesn't solve a hang that some folks see in the middle of a
|
||||||
|
transfer -- using daemon mode instead of ssh can work around that one.)
|
||||||
|
|
||||||
|
<p><hr>
|
||||||
|
<h3>Rsync 2.6.0 released</h3>
|
||||||
|
<i class=date>January 1st, 2004</i>
|
||||||
|
|
||||||
|
<P> Two important things to note in the new release:
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
|
||||||
|
<li>The default remote shell is now "ssh" unless you tell configure you want to
|
||||||
|
make something else the default.
|
||||||
|
|
||||||
|
<li>Some bug fixes in the include/exclude code, while making things work
|
||||||
|
properly, have resulted in some user-visible changes for certain wildcard
|
||||||
|
strings. Read the BUG FIXES section in the
|
||||||
|
<a href="https://download.samba.org/pub/rsync/NEWS#2.6.0">2.6.0 NEWS</a>
|
||||||
|
to see if any of these changes apply to you.
|
||||||
|
(Most people should be unaffected.)
|
||||||
|
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p>One other item of note is that the oft-requested option "--files-from" is now
|
||||||
|
available. This option lets you specify a list of files to transfer, and can
|
||||||
|
be much more efficient than a recursive descent using include/exclude
|
||||||
|
statements (if you know in advance what files you want to transfer). The list
|
||||||
|
of files can come from either side of the connection, so it is possible for a
|
||||||
|
server to provide the file-list that lets someone grab a server-specified set of
|
||||||
|
files, for example. See the <a href="https://download.samba.org/pub/rsync/rsync.1">rsync man page</a>
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
<p>See the <a href="https://download.samba.org/pub/rsync/NEWS#2.6.0">2.6.0 NEWS</a>
|
||||||
|
for a detailed changelog.
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
210
rsync-web/issues.html
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync current issues</TITLE>
|
||||||
|
<style>
|
||||||
|
code {
|
||||||
|
font-family: monospace;
|
||||||
|
font-weight: bold;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
display: block;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
blockquote pre code {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">current issues and debugging</H2>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
|
||||||
|
<li><p><b>Q:</b>
|
||||||
|
|
||||||
|
Rsync appears hung -- what should I do?
|
||||||
|
|
||||||
|
<p><b>A:</b>
|
||||||
|
|
||||||
|
When experiencing a hang or freeze <b>please</b> gather the following
|
||||||
|
information before killing the rsync process:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li> The state of the send/receive queues shown with netstat on the two ends.
|
||||||
|
|
||||||
|
<li> The system call that each of the 3 processes is stuck in (use truss on
|
||||||
|
solaris, strace on Linux, etc.).
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>Try telling rsync on both sides of the connection to send messages to
|
||||||
|
stderr, which might make the failure message visible. i.e., use:
|
||||||
|
|
||||||
|
<blockquote<pre><code>
|
||||||
|
--msgs2stderr -M--msgs2stderr
|
||||||
|
</code></pre></blockquote>
|
||||||
|
|
||||||
|
<p>That alone might get rsync to stop hanging. Also, if you're using more than
|
||||||
|
one <code>--verbose</code> (<code>-v</code>) option then I have 2 simple words
|
||||||
|
for you: stop it. If you need more info on what rsync is changing, using the
|
||||||
|
<code>--itemize-changes</code> option (<code>-i</code>) and repeat it if you
|
||||||
|
need to see unchanged files. This is a much better way to go that doesn't fill
|
||||||
|
up the communication pipeline with a large quanity of debug messages.
|
||||||
|
|
||||||
|
<p>See the "rsync-debug" script below for an example of how to grab strace
|
||||||
|
information from the remote rsync process(es). If you need help, send email to
|
||||||
|
the mailing list.
|
||||||
|
|
||||||
|
<li><p><b>Q:</b>
|
||||||
|
|
||||||
|
Why does my chrooted rsync daemon crash when doing an LDAP lookup for a user or
|
||||||
|
group?
|
||||||
|
|
||||||
|
<p><b>A:</b>
|
||||||
|
|
||||||
|
There is a bug in some LDAP libraries (e.g. Fedora Core 3) where it crashes
|
||||||
|
when someone looks up a name from inside a chrooted process (one that does not
|
||||||
|
contain copies of the libraries to perform the lookup). This is a bug that the
|
||||||
|
LDAP libraries will need to fix, and is out of rsync's hands. You can work
|
||||||
|
around the problem by using the <code>--numeric-ids</code> option, turning
|
||||||
|
chroot off, or getting rid of LDAP lookups.
|
||||||
|
|
||||||
|
<li><p><b>Q:</b>
|
||||||
|
|
||||||
|
Why does my transfer die with something like the following error?
|
||||||
|
|
||||||
|
<blockquote><pre><code>
|
||||||
|
rsync: error writing 4 unbuffered bytes - exiting: Broken pipe
|
||||||
|
rsync error: error in rsync protocol data stream (code 12) at io.c(463)
|
||||||
|
</code></pre></blockquote>
|
||||||
|
|
||||||
|
<p>or
|
||||||
|
|
||||||
|
<blockquote><pre><code>
|
||||||
|
rsync: connection unexpectedly closed (24 bytes read so far)
|
||||||
|
rsync error: error in rsync protocol data stream (code 12) at io.c(342)
|
||||||
|
</code></pre></blockquote>
|
||||||
|
|
||||||
|
<p><b>A:</b>
|
||||||
|
|
||||||
|
This error tells you that the local rsync was trying to talk to the remote
|
||||||
|
rsync, but the connection to that rsync is now gone. The thing you must
|
||||||
|
figure out is <b>why</b>, and that can involve some investigative work.
|
||||||
|
|
||||||
|
<p>It is a good idea use the <code>--msgs2stderr</code> options mentioned at
|
||||||
|
the top of this page to get rsync to output any errors it encounters to stderr
|
||||||
|
instead of trying to write them down the failing pipeline.
|
||||||
|
|
||||||
|
<p>If the connection is via ssh (or other remote-shell command) then you should
|
||||||
|
run some tests to make sure that you can actually run the remote rsync and that
|
||||||
|
your shell isn't injecting extraneous output into the rsync stream. For instance,
|
||||||
|
try running these two commands using whatever HOST (and user) options you need:
|
||||||
|
|
||||||
|
<blockquote><pre><code>
|
||||||
|
echo hi | ssh HOST cat
|
||||||
|
ssh HOST rsync --version
|
||||||
|
</code></pre></blockquote>
|
||||||
|
|
||||||
|
<p>The first command should output just the string "hi" and nothing else. The
|
||||||
|
second command should successfully start the remote rsync and report its version.
|
||||||
|
|
||||||
|
<p>If the remote rsync is a daemon, your first step should be to look at the
|
||||||
|
daemon's log file to see if it logged an error explaining why it aborted the
|
||||||
|
transfer. Also double-check to ensure that the log file is setup right, as a
|
||||||
|
wrong "log file" setting in your rsyncd.conf file can also cause this problem.
|
||||||
|
You could also halt the daemon and run it interactively using the
|
||||||
|
<code>--no-detach</code> and <code>--msgs2stderr</code> options and look for
|
||||||
|
errors while someone tries the rsync copy in another window.
|
||||||
|
|
||||||
|
<p>As for the cause of the remote rsync going away, there are several
|
||||||
|
common issues that people run into:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>The destination disk is full (remember that you need at least the
|
||||||
|
size of the largest file that needs to be updated available in free
|
||||||
|
disk space for the transfer to succeed).
|
||||||
|
|
||||||
|
<li>An idle connection caused a router or remote-shell server to close
|
||||||
|
the connection.
|
||||||
|
|
||||||
|
<li>A network error caused the connection to be dropped.
|
||||||
|
|
||||||
|
<li>The remote rsync executable wasn't found.
|
||||||
|
|
||||||
|
<li>Your remote-shell setup isn't working right or isn't "clean"
|
||||||
|
(i.e. it is sending spurious text to rsync).
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>If you think the problem might be an idle connection getting closed, you
|
||||||
|
might be able to work around the problem by using a <code>--timeout</code>
|
||||||
|
option (newer rsyncs send keep-alive messages during lulls). You can also
|
||||||
|
configure ssh to send keep-alive messages when using Protocol 2 (look for
|
||||||
|
KeepAlive, ServerAliveInterval, ClientAliveInterval, ServerAliveCountMax, and
|
||||||
|
ClientAliveCountMax). You can also avoid some lulls by switching from
|
||||||
|
<code>--delete</code> (aka <code>--delete-before</code>) to <code>--del</code>
|
||||||
|
(aka <code>--delete-during</code>).
|
||||||
|
|
||||||
|
<p>If you can't figure out why the failure happened, there are steps
|
||||||
|
you can take to debug the situation. One way is to create a shell
|
||||||
|
script on the remote system such as
|
||||||
|
<a href="rsync-debug">this one named "rsync-debug"</a>.
|
||||||
|
You would use the script like this:
|
||||||
|
|
||||||
|
<blockquote><pre><code>
|
||||||
|
rsync -av --rsync-path=/some/path/rsync-debug HOST:SOURCE DEST
|
||||||
|
rsync -av --rsync-path=/some/path/rsync-debug SOURCE HOST:DEST
|
||||||
|
</code></pre></blockquote>
|
||||||
|
|
||||||
|
<p>This script enables core dumps and also logs all the OS system calls
|
||||||
|
that lead up to the failure to a file in the /tmp dir. You can use the
|
||||||
|
resulting files to help figure out why the remote rsync failed.
|
||||||
|
|
||||||
|
<p>If you are rsyncing directly to an rsync daemon (without using a
|
||||||
|
remote-shell transport), the above script won't have
|
||||||
|
any effect. Instead, halt the current daemon and run a debug version
|
||||||
|
with core-dumps enabled and (if desired) using a
|
||||||
|
system-call tracing utility such as <i>strace</i>, <i>truss</i>, or
|
||||||
|
<i>tusc</i>. For strace, you would do it like this (the -f option
|
||||||
|
tells strace to follow the child processes too):
|
||||||
|
|
||||||
|
<blockquote><pre><code>
|
||||||
|
ulimit -c unlimited
|
||||||
|
strace -f -t -s 1024 -o /tmp/rsync-$$.out rsync --daemon --no-detach
|
||||||
|
</code></pre></blockquote>
|
||||||
|
|
||||||
|
<p>Then, use a separate window to actually run the failing transfer, after
|
||||||
|
which you can kill the debug rsync daemon (pressing Ctrl-C should do it).
|
||||||
|
|
||||||
|
<p>If you are using rsync under inetd, I'd suggest temporarily disabling
|
||||||
|
that and using the above daemon approach to debug what is going on.
|
||||||
|
|
||||||
|
<li><p><b>Q:</b>
|
||||||
|
|
||||||
|
Why does my connection to an rsync daemon (using the "::" syntax)
|
||||||
|
fail immediately with an error like the following?
|
||||||
|
|
||||||
|
<blockquote><pre><code>
|
||||||
|
rsync: connection unexpectedly closed (24 bytes read so far)
|
||||||
|
rsync error: error in rsync protocol data stream (code 12) at io.c(342)
|
||||||
|
</code></pre></blockquote>
|
||||||
|
|
||||||
|
<p><b>A:</b>
|
||||||
|
|
||||||
|
Older rsync daemons (before 2.6.3) were unable to return errors that were
|
||||||
|
generated during the option-parsing phase of the transfer. Look in the
|
||||||
|
logfile on the server to see if an error was reported, such as a "refused"
|
||||||
|
option, an option that the server rsync doesn't support (e.g. perhaps
|
||||||
|
links are not supported by the server), or some other failure (such as
|
||||||
|
trying to send data to a read-only module). Upgrading the version of rsync
|
||||||
|
that is running as a daemon to at least 2.6.3 will allow these errors to
|
||||||
|
get returned to all rsync clients, old or new alike.
|
||||||
|
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
74
rsync-web/lists.html
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync mailing lists</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">rsync mailing lists</H2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There are three mailing lists for rsync. All are optionally
|
||||||
|
available in digest mode and also through web archives.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Since these lists can generate a lot of traffic we suggest that
|
||||||
|
you should not subscribe from a web-mail account such as Yahoo!
|
||||||
|
or Hotmail, because your mailbox is likely to overflow.
|
||||||
|
Instead, please read directly from the archives.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>rsync</b> is the main mailing lists for developers and
|
||||||
|
users. It sees between zero and twenty messages per day.
|
||||||
|
This is a good place to send questions about rsync, but please
|
||||||
|
<a
|
||||||
|
href="https://www.catb.org/~esr/faqs/smart-questions.html">read
|
||||||
|
this before posting</a>.
|
||||||
|
|
||||||
|
[<a href="https://www.mail-archive.com/rsync@lists.samba.org/">archive 1</a>,
|
||||||
|
<a href="https://lists.samba.org/archive/rsync/">archive 2</a>,
|
||||||
|
<a href="https://lists.samba.org/mailman/listinfo/rsync">subscriptions</a>]
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>rsync-announce</b> carries only messages from the
|
||||||
|
maintainer annoucing new releases, which happen at most a few
|
||||||
|
times per month.
|
||||||
|
|
||||||
|
[<a href="https://www.mail-archive.com/rsync-announce@lists.samba.org/">archive 1</a>,
|
||||||
|
<a href="https://lists.samba.org/archive/rsync-announce/">archive 2</a>,
|
||||||
|
<a href="https://lists.samba.org/mailman/listinfo/rsync-announce">subscriptions</a>]
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<b>rsync-cvs</b> carries messages are automatically generated
|
||||||
|
whenever a developer changes the source code, which can happen
|
||||||
|
many times per day. If you subscribe, you should probably
|
||||||
|
choose digest mode.
|
||||||
|
|
||||||
|
[<a href="https://www.mail-archive.com/rsync-cvs@lists.samba.org/maillist.html">archive 1</a>,
|
||||||
|
<a href="https://lists.samba.org/archive/rsync-cvs/">archive 2</a>,
|
||||||
|
<a href="https://lists.samba.org/mailman/listinfo/rsync-cvs">subscriptions</a>]
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please report problems with the lists to the <tt>postmaster</tt>
|
||||||
|
at <tt>samba.org</tt>, but note that you can control your own
|
||||||
|
subscription using the web interface.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<H2 align="center">rsync Discord server</H2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you prefer real-time chat, there is also an rsync
|
||||||
|
<a href="https://discord.gg/Avfvy9zhdp">Discord server</a> for
|
||||||
|
discussion about rsync and its development.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
BIN
rsync-web/newrsynclogo.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
rsync-web/newrsynclogo.xcf
Normal file
85
rsync-web/nt.html
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync on NT</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">rsync on NT</H2>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
From: "Mike McHenry" <mmchen@minn.net>
|
||||||
|
Subject: Rsync 2.3.1 WinNT binaries and instructions available
|
||||||
|
Date: Fri, 15 Oct 1999 02:53:30 +1000
|
||||||
|
|
||||||
|
Hello all,
|
||||||
|
|
||||||
|
I have created Windows NT binaries for rsync 2.3.1 and have decided to make
|
||||||
|
them available for others to download. These binaries have been tested on
|
||||||
|
Windows NT Server 4.0 SP5 and WILL run in daemon mode if you follow my
|
||||||
|
instructions below. I make no guarantees about these binaries, they have
|
||||||
|
however been working for me for weeks on several NT machines.
|
||||||
|
|
||||||
|
Binaries at ftp://ftp.minn.net/usr/mmchen/
|
||||||
|
|
||||||
|
Instructions for running in daemon mode:
|
||||||
|
|
||||||
|
1. You will need two files, rsync.exe and cygwin1.dll. Place rsync.exe
|
||||||
|
anywhere you like (I chose c:\program files\rsync\rsync.exe) and put
|
||||||
|
cygwin1.dll in c:\winnt\system32
|
||||||
|
|
||||||
|
2. You will need a program from the NT Server resource kit called
|
||||||
|
srvany.exe. This program allows you to run any executable as a service. If
|
||||||
|
you simply install the entire service pack it will be located in c:\ntreskit
|
||||||
|
|
||||||
|
3. Create a service for rsync by typing the following:
|
||||||
|
instsrv Rsync "C:\ntreskit\srvany.exe"
|
||||||
|
|
||||||
|
4. You should now have a new service called Rsync and you can verify by
|
||||||
|
looking in Start->Control Panel->Services DON'T START IT YET!
|
||||||
|
|
||||||
|
5. If you want to run rsync in daemon mode you will need a configuration
|
||||||
|
file. Here is the one I use, call it rsyncd.conf and place it in the same
|
||||||
|
directory as rsync (C:\Program files\rsync\rsyncd.conf)
|
||||||
|
use chroot = false
|
||||||
|
strict modes = false
|
||||||
|
hosts allow = *
|
||||||
|
|
||||||
|
[backup]
|
||||||
|
path = /
|
||||||
|
read only = yes
|
||||||
|
list = no
|
||||||
|
|
||||||
|
This example configuration will make one big anonymous anonymous rsync area
|
||||||
|
available, I use this to backup my NT machines from a central Unix machine.
|
||||||
|
This configuration might not be ideal for you, change to suit your tastes.
|
||||||
|
The first two lines are important for rsync to work on Windows NT however.
|
||||||
|
|
||||||
|
6. You are going to need to hack some keys in the registry to make it work.
|
||||||
|
Don't do this unless you are comfortable with the changes! Run regedit32 and
|
||||||
|
add the following keys and values (quotation marks ARE IMPORTANT):
|
||||||
|
HKEY_LOCAL_MACHINE->SYSTEM->CurrentControlSet->Services->Rsync
|
||||||
|
Edit->Add Key-> Key Name: Paramaters
|
||||||
|
Edit->Add Value-> Value Name: AppDirectory Value: "C:\programfiles\rsync"
|
||||||
|
Edit->Add Value-> Value Name: Application Value: "C:\programfiles\rsync\rsync.exe"
|
||||||
|
Edit->Add Value-> Value Name: AppParamters Value: --config="C:\programfiles\rsync\rsyncd.conf" --daemon
|
||||||
|
|
||||||
|
7. That's it, you should be able to start and stop the rsync service at will
|
||||||
|
using the Services Control Panel. When running with the above configuration
|
||||||
|
you should be able to test by attempting to telnet to port 873 from a remote
|
||||||
|
machine.
|
||||||
|
telnet rsync.server.com 873 (replacing rsync.server.com with your own
|
||||||
|
server's address)
|
||||||
|
You should get a connection to the rsync daemon running on your NT box.
|
||||||
|
|
||||||
|
8. If you have problems you are on your own, sorry, I have enough to do :) I
|
||||||
|
would suggest triple-checking your spelling on EVERYTHING (filenames,
|
||||||
|
configs, reg keys). If you have any comments or suggestions I would be happy
|
||||||
|
to hear them at mmchen@minn.net.
|
||||||
|
|
||||||
|
Mike McHenry
|
||||||
|
Systems Administrator
|
||||||
|
MinnNet Communications, Inc.
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
74
rsync-web/nt.txt
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
From: "Mike McHenry" <mmchen@minn.net>
|
||||||
|
Subject: Rsync 2.3.1 WinNT binaries and instructions available
|
||||||
|
Date: Fri, 15 Oct 1999 02:53:30 +1000
|
||||||
|
|
||||||
|
|
||||||
|
Hello all,
|
||||||
|
|
||||||
|
I have created Windows NT binaries for rsync 2.3.1 and have decided to make
|
||||||
|
them available for others to download. These binaries have been tested on
|
||||||
|
Windows NT Server 4.0 SP5 and WILL run in daemon mode if you follow my
|
||||||
|
instructions below. I make no guarantees about these binaries, they have
|
||||||
|
however been working for me for weeks on several NT machines.
|
||||||
|
|
||||||
|
Binaries at ftp://ftp.minn.net/usr/mmchen/
|
||||||
|
|
||||||
|
Instructions for running in daemon mode:
|
||||||
|
|
||||||
|
1. You will need two files, rsync.exe and cygwin1.dll. Place rsync.exe
|
||||||
|
anywhere you like (I chose c:\program files\rsync\rsync.exe) and put
|
||||||
|
cygwin1.dll in c:\winnt\system32
|
||||||
|
|
||||||
|
2. You will need a program from the NT Server resource kit called
|
||||||
|
srvany.exe. This program allows you to run any executable as a service. If
|
||||||
|
you simply install the entire service pack it will be located in c:\ntreskit
|
||||||
|
|
||||||
|
3. Create a service for rsync by typing the following:
|
||||||
|
instsrv Rsync "C:\ntreskit\srvany.exe"
|
||||||
|
|
||||||
|
4. You should now have a new service called Rsync and you can verify by
|
||||||
|
looking in Start->Control Panel->Services DON'T START IT YET!
|
||||||
|
|
||||||
|
5. If you want to run rsync in daemon mode you will need a configuration
|
||||||
|
file. Here is the one I use, call it rsyncd.conf and place it in the same
|
||||||
|
directory as rsync (C:\Program files\rsync\rsyncd.conf)
|
||||||
|
use chroot = false
|
||||||
|
strict modes = false
|
||||||
|
hosts allow = *
|
||||||
|
|
||||||
|
[backup]
|
||||||
|
path = /
|
||||||
|
read only = yes
|
||||||
|
list = no
|
||||||
|
|
||||||
|
This example configuration will make one big anonymous anonymous rsync area
|
||||||
|
available, I use this to backup my NT machines from a central Unix machine.
|
||||||
|
This configuration might not be ideal for you, change to suit your tastes.
|
||||||
|
The first two lines are important for rsync to work on Windows NT however.
|
||||||
|
|
||||||
|
6. You are going to need to hack some keys in the registry to make it work.
|
||||||
|
Don't do this unless you are comfortable with the changes! Run regedit32 and
|
||||||
|
add the following keys and values (quotation marks ARE IMPORTANT):
|
||||||
|
HKEY_LOCAL_MACHINE->SYSTEM->CurrentControlSet->Services->Rsync
|
||||||
|
Edit->Add Key-> Key Name: Paramaters
|
||||||
|
Edit->Add Value-> Value Name: AppDirectory Value: "C:\programfiles\rsync"
|
||||||
|
Edit->Add Value-> Value Name: Application Value: "C:\programfiles\rsync\rsync.exe"
|
||||||
|
Edit->Add Value-> Value Name: AppParamters Value: --config="C:\programfiles\rsync\rsyncd.conf" --daemon
|
||||||
|
|
||||||
|
7. That's it, you should be able to start and stop the rsync service at will
|
||||||
|
using the Services Control Panel. When running with the above configuration
|
||||||
|
you should be able to test by attempting to telnet to port 873 from a remote
|
||||||
|
machine.
|
||||||
|
telnet rsync.server.com 873 (replacing rsync.server.com with your own
|
||||||
|
server's address)
|
||||||
|
You should get a connection to the rsync daemon running on your NT box.
|
||||||
|
|
||||||
|
8. If you have problems you are on your own, sorry, I have enough to do :) I
|
||||||
|
would suggest triple-checking your spelling on EVERYTHING (filenames,
|
||||||
|
configs, reg keys). If you have any comments or suggestions I would be happy
|
||||||
|
to hear them at mmchen@minn.net.
|
||||||
|
|
||||||
|
Mike McHenry
|
||||||
|
Systems Administrator
|
||||||
|
MinnNet Communications, Inc.
|
||||||
|
|
||||||
127
rsync-web/resources.html
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync resources</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">rsync resources</H2>
|
||||||
|
|
||||||
|
Please <a href="lists.html">let us know</a> if you have any rsync-related
|
||||||
|
documents to add to this list:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<li>Be sure to search for the latest rsync info to get up-to-the-minute
|
||||||
|
results. You can use the search box at the top of the page for either
|
||||||
|
web searching or project searching (they are done via Google).
|
||||||
|
|
||||||
|
<li>
|
||||||
|
2002-05-15: rsync is not official GNU software, but we try to
|
||||||
|
work more or less in accordance with their <a
|
||||||
|
href="http://www.gnu.org/prep/maintain_toc.html">Guidelines for
|
||||||
|
Maintaining GNU Software</a>.
|
||||||
|
|
||||||
|
<li> 2002-04-10: A new tutorial on using rsync to create a system of <a
|
||||||
|
href="http://www.mikerubel.org/computers/rsync_snapshots/">rotating
|
||||||
|
backups</a>, by Mike Rubel.
|
||||||
|
|
||||||
|
<li>If you still don't know what rsync is, then take a look at the
|
||||||
|
<A HREF="https://download.samba.org/pub/rsync/README">README</A>.
|
||||||
|
|
||||||
|
<li>There is now a python script that implements
|
||||||
|
<a href="https://download.samba.org/pub/unpacked/rsync/support/atomic-rsync">an
|
||||||
|
atomic update</a> of the received files at the end of the transfer (when pulling).
|
||||||
|
|
||||||
|
<li> Brian Elliott Finley has put together a great Linux install system based
|
||||||
|
on rsync. You you read about it at <a href="http://thefinleys.com/SystemImager/">http://thefinleys.com/SystemImager/</a>
|
||||||
|
|
||||||
|
<li><a href="http://www.dirvish.com/">Dirvish</a> is a fast, disk based,
|
||||||
|
rotating network backup system that was originally written by JW Schultz.
|
||||||
|
|
||||||
|
<li><a href="http://backuppc.sourceforge.net/">BackupPC</a>: a backup
|
||||||
|
system using rsync. Hard-links all identical files (even between multiple
|
||||||
|
runs and multiple backup sources), compresses the files, provides an easy
|
||||||
|
interface to find and restore files, etc.
|
||||||
|
|
||||||
|
<li><a href="https://github.com/CharlesMAtkinson/bung">Bung</a>: (BackUp Next
|
||||||
|
Generation) backs up files, MariaDB, OpenLDAP, postgres, etc. via an extensible
|
||||||
|
templates system with git support. The rsync-based "rolling full" backup is
|
||||||
|
easy to browse and restore from using everyday tools.
|
||||||
|
|
||||||
|
<li><a href="http://hacks.dlux.hu/drsync/">drsync</a>: a wrapper for rsync
|
||||||
|
that remembers file sets between invocations so that a 2-way synchronization
|
||||||
|
of two systems is possible.
|
||||||
|
|
||||||
|
<li><a href="http://rsyncbackup.erlang.no/">rsyncbackup</a>: a helper
|
||||||
|
script that uses config files to setup multiple backup scenarios and
|
||||||
|
invokes rsync (or rsyncX on macOS).
|
||||||
|
|
||||||
|
<li>Users who use the new character-set conversion option of rsync (--iconv)
|
||||||
|
may want to check into the <a href="http://www.j3e.de/linux/convmv/man/">convmv</a>
|
||||||
|
package that lets you convert the names of already-transferred files into a
|
||||||
|
new characterset (for when you want to change or normalize the characterset
|
||||||
|
of a hierarchy of files).
|
||||||
|
|
||||||
|
<li>For those wanting to use launchd to run an rsync daemon (e.g. Mac
|
||||||
|
OS X Tiger users), Glen Scott provides the necessary
|
||||||
|
<a href="http://www.designsolution.co.uk/resources/rsync/">rsync.plist</a>
|
||||||
|
file.
|
||||||
|
|
||||||
|
<li>For the developer wanting to work on a branched rsync version based on
|
||||||
|
one of the diffs in the patches dir, you may want to check into Matt's
|
||||||
|
<a href="http://www.kepreon.com/~matt/myrsync/index.html#patchsync">patchsync</a>
|
||||||
|
script.
|
||||||
|
|
||||||
|
<!--#include virtual="doc-resources.html" -->
|
||||||
|
|
||||||
|
<li>There are a few choices for making rsync work with OS X's resource forks.
|
||||||
|
One is the official apple patch found on their opendarwin site, such as
|
||||||
|
<a href="http://darwinsource.opendarwin.org/10.4/rsync-20">this one</a>
|
||||||
|
(I've heard patch inefficiently transfers the entire resource fork information
|
||||||
|
for every file on every transfer.) Another choice is to use a third-party
|
||||||
|
adapted rsync, such as
|
||||||
|
<a href="http://archive.macosxlabs.org/rsyncx/rsyncx.html">rsyncx</a> or a
|
||||||
|
<a href="http://www.quesera.com/reynhout/misc/rsync+hfsmode">rsync+hfsmode
|
||||||
|
patch</a> by D Andrew Reynhout. For the future, I would like to see an rsync
|
||||||
|
that supports ACLs and Posix xattrs adapted to interact with resource forks in
|
||||||
|
a seamless way (if that's possible).
|
||||||
|
|
||||||
|
<li>Piero Orsoni wrote a GTK-based GUI for rsync called
|
||||||
|
<a href="http://www.opbyte.it/grsync/">grsync</a>.
|
||||||
|
|
||||||
|
<li>Those interested in using an rsync daemon over SSL may be interested in
|
||||||
|
<a href="http://dozzie.jarowit.net/trac/wiki/RsyncSSL">this wiki page</a>
|
||||||
|
that outlines a way to use a modern, simplified stunnel setup.
|
||||||
|
|
||||||
|
<li>Thomas Roessler has written an rsync wrapper for
|
||||||
|
<a href="ftp://riemann.iam.uni-bonn.de/pub/users/roessler/cvslock/">efficient,
|
||||||
|
safe CVS mirroring</a>.
|
||||||
|
|
||||||
|
<li>Rsync is distributed with the
|
||||||
|
<a href="https://download.samba.org/pub/unpacked/rsync/support/rrsync">rrsync python script</a>
|
||||||
|
that lets you restrict the rsync commands that can be run via ssh. (This is
|
||||||
|
a enhanced and reworked version of Joe Smith's original perl version.)
|
||||||
|
|
||||||
|
<li><a href="mailto:LEakin@Nostrum.COM">Lee Eakin</a> has written a <a href="rsync_wrapper.pl">perl wrapper for rsync</a>.
|
||||||
|
|
||||||
|
<li>A wire-compatible <a href="http://search.cpan.org/~cbarratt/">rsync implementation in perl</a>.
|
||||||
|
|
||||||
|
<li>A <a href="http://www.srehttp.org/apps/rxrsync/">REXX implementation of rsync</a>.
|
||||||
|
|
||||||
|
<li>An initial version of a <a href="http://www.kolosy.com/wordpress/?p=8">rewrite of rsync for .Net</a>.
|
||||||
|
|
||||||
|
<li>You might want to check out an encryption program that is being developed
|
||||||
|
to produce more rsync-friendly output:
|
||||||
|
<a href="http://rsyncrypto.lingnu.com/">rsyncrypto</a>.
|
||||||
|
|
||||||
|
<li>If you need a 2-way synchronization because both ends of the transfer may
|
||||||
|
be changing files, you may want to either look into a tool designed to do this
|
||||||
|
(e.g. <a href="http://freshmeat.net/projects/unison/">unison</a>), or you may
|
||||||
|
wish to use an external wrapper for rsync that keeps extra data about what was
|
||||||
|
in the last transfer so that it can figure out if a file is new or deleted
|
||||||
|
(e.g. <a href="http://freshmeat.net/projects/drsync/">drsync</a>).
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
2
rsync-web/rsync-and-debian/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
rsync-and-debian.html
|
||||||
|
rsync-and-debian.ps
|
||||||
869
rsync-web/rsync-and-debian/rsync-and-debian.sgml
Normal file
@@ -0,0 +1,869 @@
|
|||||||
|
<!doctype linuxdoc system>
|
||||||
|
<linuxdoc>
|
||||||
|
<article>
|
||||||
|
<titlepag>
|
||||||
|
<title>About integration of rsync and Debian</title>
|
||||||
|
<author>
|
||||||
|
<name>Martin Pool <tt>mbp@samba.org</tt></name>
|
||||||
|
</author>
|
||||||
|
<date>$Date: 2002/05/14 03:10:09 $</date>
|
||||||
|
</titlepag>
|
||||||
|
|
||||||
|
<toc>
|
||||||
|
|
||||||
|
<sect>
|
||||||
|
<heading>Introduction</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It seems like there is an rsync thread on <tt/debian-devel/
|
||||||
|
every month or two. Rather than going round in circles yet
|
||||||
|
again, I though I would summarise the issues in one place.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
By way of background, I have been the maintainer of rsync for
|
||||||
|
about a year, and I wrote the <tt/librsync/ and <tt/rproxy/
|
||||||
|
packages. Incidentally, I run Debian on most of the machines
|
||||||
|
I use, so I do care about the two projects working together
|
||||||
|
well.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I have tried to respond to all the issues raised on the list
|
||||||
|
recently, but possibly have missed some. After putting many
|
||||||
|
hours into rsync I suppose I am quite fond of it and may be a
|
||||||
|
little biased, but I think I also know its strengths and
|
||||||
|
problems more than most.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If there are issues ommitted by this document, or if you think
|
||||||
|
the answers are incomplete, unbalanced, or incorrect, then
|
||||||
|
please mail <tt/mbp@samba.org/, <tt/rsync@lists.samba.org/
|
||||||
|
and/or <tt/debian-devel@lists.debian.org/.
|
||||||
|
|
||||||
|
</sect>
|
||||||
|
|
||||||
|
|
||||||
|
<sect>
|
||||||
|
<heading>Background</heading>
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>The rsync algorithm</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync is really two independent but related ideas: the
|
||||||
|
<em/rsync algorithm/ for delta compression, and its
|
||||||
|
implementation in a mirroring program.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The rsync algorithm is described in detail in the ANU
|
||||||
|
Technical Report included with the distribution and on the
|
||||||
|
<htmlurl url="http://rsync.samba.org/" name="rsync.samba.org"> web site.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Briefly, the rsync algorithm provides an efficient means to
|
||||||
|
transfer a file <em/A/ from a source machine to a
|
||||||
|
destination machine, when a similar file <em/A'/ is already
|
||||||
|
present on the destination. The destination machine sends a
|
||||||
|
checksum of each consecutive block (of say 1kB) from <em/A'/
|
||||||
|
to the source machine. The source machine searches through
|
||||||
|
<em/A/ for matching blocks. Whatever does not match must be
|
||||||
|
different, and a description of these differences is sent to
|
||||||
|
the destination.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The algorithm could be embodied in other forms and uses than
|
||||||
|
the rsync program. Indeed, the algorithm has been
|
||||||
|
reimplemented in programs other than rsync itself: in other
|
||||||
|
languages (Rexx, CAML, Java), in a C library (<tt/librsync/)
|
||||||
|
and a derivative in xdelta. xdelta is a specialization of
|
||||||
|
the algorithm for the case where the two files are local and
|
||||||
|
can be directly compared to compute a minimal binary delta.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync deltas are much more efficient than diffs, for several
|
||||||
|
reasons: most importantly, useful diff formats include
|
||||||
|
context lines, which are wasted information. rsync gets the
|
||||||
|
same benefit of making sure that the change is applied to a
|
||||||
|
compatible version of the file, but in a much more efficient
|
||||||
|
way. diffs suffer from being human-readable and therefore
|
||||||
|
verbose, and cannot handle binary files. Both can be
|
||||||
|
transparently compressed. diffs are an invaluable tool for
|
||||||
|
software development, but not ideal for distribution of
|
||||||
|
deltas.
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/The rsync program/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The rsync mirroring program is similar in functionality to
|
||||||
|
other tools such as <tt/wget/, <tt/ftpmirror/, <tt/cvsup/
|
||||||
|
and <tt/rdist/. It has a number of functions that are
|
||||||
|
useful in association with file mirroring, such as bandwidth
|
||||||
|
limiting, access control, recursive mirroring, and selection
|
||||||
|
of files to copy in various ways.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In general, rsync is substantially faster than other
|
||||||
|
tools, because it uses delta compression, and because the
|
||||||
|
protocol is designed to be efficient both in traffic and
|
||||||
|
round trips. rsync can use <tt/zlib/ to compress traffic
|
||||||
|
(and introduce double-<tt/free()/ security holes :-), at the
|
||||||
|
option of the client. Compression may also be disabled by
|
||||||
|
the server administrator.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync has the important property that it is generally
|
||||||
|
idempotent: repeated runs of rsync, even if interrupted,
|
||||||
|
make the contents of the destination machine converge
|
||||||
|
towards those of the source machine.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Unlike wget and ftpmirror, rsync must be installed on both
|
||||||
|
the client and the server. It uses its own protocol, rather
|
||||||
|
than HTTP or FTP. This is probably the biggest practical
|
||||||
|
drawback at the moment: one cannot use rsync from arbitrary
|
||||||
|
web sites, but only from systems that have specifically
|
||||||
|
chosen to support it. On the other hand, many important
|
||||||
|
sites for free software do now support rsync, and the
|
||||||
|
developers see them as an important constituency to support.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync can tunnel through a proxy server that supports
|
||||||
|
<tt/HTTP CONNECT/, a SOCKS server (using <tt/socksify/), an
|
||||||
|
ssh tunnel, or various other methods.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync can run as a daemon, similar to an <tt/ftpd/, in which
|
||||||
|
it is controlled by the <tt>/etc/rsyncd.conf</tt> file. The
|
||||||
|
archetypal use is to offer public, anonymous, read-only
|
||||||
|
access to a software archive but as with <tt/ftpd/ other
|
||||||
|
configurations are possible and common.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync can also run across a tunnel program such as <tt/ssh/,
|
||||||
|
in which case it is very similar to <tt/scp/. This mode is
|
||||||
|
commonly used for making network backups, or uploading
|
||||||
|
information to a web server.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync may also be used locally, which is a degenerate case
|
||||||
|
with client and server connected across a unix-domain or
|
||||||
|
localhost socket.
|
||||||
|
</>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync runs on many varieties of Unix under both gcc and
|
||||||
|
native compilers, and also under Cygwin on Microsoft
|
||||||
|
platforms. There is somebody working on a VMS port.
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/librsync/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<tt/librsync/ is a library that reimplements the rsync
|
||||||
|
algorithm in a very flexible way, with the goal of allowing
|
||||||
|
any reasonable mode of operation, and integration with any
|
||||||
|
existing program. rsync does not currently link to
|
||||||
|
librsync, but it might do so in the long term.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<tt/librsync/ currently uses an encoding
|
||||||
|
format different to that of rsync 2.5, mostly because I did
|
||||||
|
not want to be constrained by historical code.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<tt/librsync/ is at version 0.9.5 and roughly as stable as
|
||||||
|
the version number suggests: it is used by Intermezzo and
|
||||||
|
some other projects, but is not yet really mature. The
|
||||||
|
<tt/librsync/ distribution comes with a tool <tt/rdiff/ that
|
||||||
|
exposes the functionality as a Unix tool to shell scripts,
|
||||||
|
etc. <tt/librsync/ is LGPL'd.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For example, you can imagine the server calculating and
|
||||||
|
caching the checksums, or the client calculating the delta
|
||||||
|
once and then sending it over UDP multicast to several
|
||||||
|
destinations, or uuencoded in email. Neither of these would
|
||||||
|
be straightforward to implement in the rsync codebase, but
|
||||||
|
all can be done with rdiff.
|
||||||
|
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/rproxy/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<tt/librsync/ is used in the <url
|
||||||
|
url="http://rproxy.samba.org/" name="rproxy"> program, which
|
||||||
|
is a prototype of transparent integration of delta
|
||||||
|
compression into HTTP.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rproxy implements delta compression of arbitrary HTTP
|
||||||
|
content, whether dynamic or static. For example, rproxy
|
||||||
|
gives very good compression on repeated visits to portal
|
||||||
|
sites such as Slashdot, since it can transmit only the
|
||||||
|
sections of the page modified since last time it was
|
||||||
|
viewed. Regular HTTP caches, by contrast, must either hit
|
||||||
|
on the whole page, or reload the whole page, and therefore
|
||||||
|
do poorly on template-based dynamic content.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rproxy adds compatible extensions to HTTP headers, and can
|
||||||
|
pass through HTTP caches. It requires upstream and
|
||||||
|
downstream support, which at the moment means two
|
||||||
|
installations of rproxy, but in the future could conceivably
|
||||||
|
be integrated into Mozilla, Squid, Apache and similar
|
||||||
|
programs.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rproxy is packaged in Debian and is moderately useful for
|
||||||
|
people with slow links.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rproxy is not HTML-specific, but HTML is by far the most
|
||||||
|
common case of dynamic HTTP content that can be
|
||||||
|
delta-compressed. However, HTML documents tend to be fairly
|
||||||
|
small, and as connectivity improves they're becoming of
|
||||||
|
decreasing interest as a compression problem.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
(My personal interest in this project declined significantly
|
||||||
|
when I went from a 56k6 modem to ADSL at home. I realize
|
||||||
|
many people in the world still have slow connections.)
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There are some Internet Drafts from Jeffrey Mogul and others
|
||||||
|
that add similar delta compression based on the server
|
||||||
|
storing all possible deltas. Last time I looked, there did
|
||||||
|
not seem much interest in wide adoption of these proposals.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Documenting a protocol extension to the standard expected by
|
||||||
|
an RFC can be a lot of work. A beginning on this work has
|
||||||
|
been made for rproxy, but more experiments with the
|
||||||
|
implementation are needed before proposal as a standard.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rproxy is not being actively developed at the moment.
|
||||||
|
Obviously I cannot answer why every programmer in the world
|
||||||
|
does not work on this. Personally I think that developing
|
||||||
|
rsync itself, and then librsync/rdiff, is likely to be more
|
||||||
|
useful; I suspect other people interested in working in this
|
||||||
|
area might have similar thoughts.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I don't think there are any problems in the code or project
|
||||||
|
that would actively prevent anybody from working on it. I'd
|
||||||
|
be happy to hand over maintenance to somebody else. Ben
|
||||||
|
Elliston has expressed interest in looking after it in the
|
||||||
|
last couple of months, and possibly it will be more active
|
||||||
|
in the future.
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>Introduction to Debian</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Debian is a free operating system developed by the
|
||||||
|
cooperation of people all over the world. The most
|
||||||
|
important relation of rsync to Debian is copying of software
|
||||||
|
packages from developers to distribution servers to end
|
||||||
|
users.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Many Debian users get their software by internet download
|
||||||
|
from a public server, rather than pre-installed on a machine
|
||||||
|
or on CD-ROM.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Debian software archives include both software source,
|
||||||
|
binary packages for various architectures, and index
|
||||||
|
metadata, primarily the <tt/Packages/ files.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Because of Debian's community development process, new
|
||||||
|
packages are released very often. On a typical day in
|
||||||
|
Debian's <tt/unstable/ release, there might be fifty new
|
||||||
|
uploads.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Debian is quite different from other software distributions
|
||||||
|
in shipping so many packages so frequently. The BSDs (as I
|
||||||
|
understand it) base most of their development out of a CVS
|
||||||
|
or CVSup tree, which inherently distributes coarse-grained
|
||||||
|
deltas. Proprietary systems make binary releases, but much
|
||||||
|
less frequently. Possibly the development branches of other
|
||||||
|
distributions, such as Redhat "Rawhide" and Mandrake
|
||||||
|
"Cooker" are similar.
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>apt-proxy</heading>
|
||||||
|
<p><label id="apt-proxy">
|
||||||
|
<url url="http://apt-proxy.sourceforge.net/" name="apt-proxy"> is a caching proxy for Debian archives. It appears as an HTTP
|
||||||
|
server to apt clients, and uses rsync, http, or ftp to connect
|
||||||
|
to an upstream server.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Because rsync is less efficient than HTTP for transferring
|
||||||
|
compressed files, <tt/apt-proxy/ can selectively use rsync for
|
||||||
|
uncompressed Packages and files and HTTP or FTP for <tt/.deb/
|
||||||
|
files.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<tt/apt-proxy/, unlike Squid, has domain knowledge about
|
||||||
|
Debian archives and can therefore perform functions such as
|
||||||
|
purging old packages from the cache.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The original apt-proxy was written by Paul 'Rusty' Russel.
|
||||||
|
The current maintainer is Chris Halls.
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
</sect>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect>
|
||||||
|
<heading>Open Issues</heading>
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/Compressed files cannot be differenced/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<tt/gzip/, like most compression algorithms has the property
|
||||||
|
that a change in the source file at one point will cause
|
||||||
|
cascading changes in the output file from that point
|
||||||
|
onwards, and therefore make delta compression more or less
|
||||||
|
useless.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Although delta compression is not possible, rsync is still a
|
||||||
|
very useful tool for mirroring compressed files. The
|
||||||
|
efficient network protocol mean that it will generally be
|
||||||
|
slightly faster and use less traffic than HTTP or FTP.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There is a patch called <tt/--rsyncable/ for gzip that fixes
|
||||||
|
this behaviour: gzip files are basically broken up into
|
||||||
|
blocks so that changes (including insertion or deletion) in
|
||||||
|
the input file affect only the corresponding blocks in the
|
||||||
|
output file. (The blocks are not of fixed size, but rather
|
||||||
|
delimited by marker patterns at which a checksum hits a
|
||||||
|
particular value, so they move as data is inserted or
|
||||||
|
removed.)
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I believe that this will merge into the upstream <tt/zlib/
|
||||||
|
soon and be on by default, at which point <tt/.deb/ files
|
||||||
|
will delta-compress well. This patch does seem to be
|
||||||
|
languishing, though, and it would be good to either get it
|
||||||
|
into the upstream, or into Debian's own version. Needless
|
||||||
|
to say it must be extremely thoroughly tested.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The scheme for containing changes is not specific to rsync,
|
||||||
|
and might also be useful with <tt/xdelta/, <tt/rdiff/, or
|
||||||
|
some other binary delta scheme invented in the future. It
|
||||||
|
also does not require a copy of the old file when
|
||||||
|
compressing the new one.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This scheme relies on the output file being determined only
|
||||||
|
by the input file. As far as I know compression schemes
|
||||||
|
like gzip, lzw, and bzip2 are deterministic in this way.
|
||||||
|
(GnuPG, for example, is not, since it uses a random session
|
||||||
|
key.)
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Incidentally this would allow more efficient deltas between
|
||||||
|
Debian ISO images.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Alternatively, you could distribute an uncompressed package
|
||||||
|
tree that would rsync efficiently, but since the gzip patch
|
||||||
|
should merge soon this seems unnecessary.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There is also the interesting possibility of using
|
||||||
|
<tt/dpkg-repack/ to generate something similar to the
|
||||||
|
previous <tt/.deb/ and then use it as the basis of an rsync
|
||||||
|
download.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It could be possible to make an equivalent patch to
|
||||||
|
<tt/bzip2/, but possibly the large block size would cause
|
||||||
|
trouble.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A patch to gzip which implements this behaviour is available
|
||||||
|
from rsync CVS.
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/rsync is too hard on servers/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If it is, then I think we should fix the problems, rather
|
||||||
|
than invent a new system from scratch. I think the
|
||||||
|
scalability problems are accidents of the current codebase,
|
||||||
|
rather than anything inherent in the design.
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/We should throw out the current code and start from
|
||||||
|
scratch/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Some projects (Apache 2.0, Mozilla, ...) choose to do this;
|
||||||
|
some concentrate on piecemeal improvement (Linux).
|
||||||
|
|
||||||
|
<p>
|
||||||
|
As Joel Spolsky recently observed, throwing the code out to
|
||||||
|
start from scratch always seems like a nice idea, but rarely
|
||||||
|
works out. Essentially you are opting for the devil you
|
||||||
|
don't know, but he definitely exists.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Having dealt with some fairly crufty old code I sometimes
|
||||||
|
feel like doing this in rsync, but I can also see the
|
||||||
|
arguments against it. Starting from a new codebase would
|
||||||
|
bring in plenty of new bugs (including security bugs),
|
||||||
|
orphan existing users, and halt progress until it caught up
|
||||||
|
to the same level. It would require carefully documenting
|
||||||
|
all the existing internal protocols and behaviours, which is
|
||||||
|
a nice idea but not clearly a good use of the developers'
|
||||||
|
time.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you throw out the code, you have the questions of whether
|
||||||
|
or not to keep the current network protocol, and whether or
|
||||||
|
not to keep the current command-line option.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Not being able to talk to old remote versions would be a
|
||||||
|
real pain, and would certainly slow adoption. (Think of how
|
||||||
|
unpopular SSH2 was when it wanted to be incompatible with
|
||||||
|
SSH1, but use the same TCP port.) On the other hand,
|
||||||
|
keeping the same network protocol limits your ability to
|
||||||
|
redesign things.
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There is some cruft in the command line syntax, but throwing
|
||||||
|
it out would also break everybody's scripts, mental maps,
|
||||||
|
and documentation.
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Possibly rsync 3.0 will be largely rewritten. <tt/librsync/
|
||||||
|
is a start in that direction. If you want to do this,
|
||||||
|
<tt/librsync/ might help you, but please think about it
|
||||||
|
before you begin hacking.
|
||||||
|
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/rsync development roadmap/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Debian's goals for rsync have to be balanced against the
|
||||||
|
requirements of other users (including the mirror sites that
|
||||||
|
distribute Debian) and the limited development resources.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
As of April 2002, the 2.5.5 release is current and 2.5.6 is
|
||||||
|
pending. These versions seem to work quite well and we
|
||||||
|
encourage people to upgrade from stable 2.4.6 and previous
|
||||||
|
versions. It is very important to the developers to
|
||||||
|
establish a stable base release before starting out on new
|
||||||
|
development.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A number of enhancements are planned for the 2.6 series.
|
||||||
|
Some of them are discussed below, and more details can be
|
||||||
|
found in the <tt/TODO/ file in the rsync distribution.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you want rsync to progress faster, the best thing you can
|
||||||
|
do is find reproducible failure cases and report them well,
|
||||||
|
or to help us write a regression test suite.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Nobody is very actively working on rproxy or librsync as far
|
||||||
|
as I know. Personally at the moment I feel supporting rsync
|
||||||
|
itself is more useful.
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/Goswin Brederlow's proposal to use the reverse rsync
|
||||||
|
algorithm over HTTP Range requests/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Goswin Brederlow has a nice proposal that allows rsync
|
||||||
|
compression using a regular HTTP server. It depends only
|
||||||
|
upon rsyncable archives, and development of new client and
|
||||||
|
support programs.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The idea, as I understand it, is that the checksums for each
|
||||||
|
package should be pre-calculated and stored on the HTTP
|
||||||
|
server along with the files they describe. (The checksum
|
||||||
|
files should be on the order of a thousand times smaller
|
||||||
|
than the archive file.)
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The client program will download the checksum file over HTTP
|
||||||
|
if it exists. The client can then search for common blocks
|
||||||
|
in the local file, and therefore determine what new regions
|
||||||
|
it must fetch from the server. The client then sends an
|
||||||
|
HTTP request using the optional <tt/Range/ header for the
|
||||||
|
relevant sections of the new file, and patches them onto the
|
||||||
|
old file. The checksum file ought to also include a
|
||||||
|
whole-file message digest which can be used to ensure that
|
||||||
|
reassembly was successful.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This scheme has the great advantage that the server is
|
||||||
|
entirely passive, and only needs to support standard HTTP.
|
||||||
|
The checksum files can be generated once for each package
|
||||||
|
either during upload, or by the administrator of a
|
||||||
|
particular server.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
(This is not the same as rproxy, which uses a different
|
||||||
|
encoding and requires upstream support, but can
|
||||||
|
transparently compress any request without requiring
|
||||||
|
signature files on the server.)
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This scheme could be fairly easily built on top of rdiff or
|
||||||
|
librsync.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I think this sounds like a very promising scheme. I think
|
||||||
|
rsync might still be better for people who want to copy
|
||||||
|
large trees, but for users apt-getting single packages this
|
||||||
|
would be a simple way to get delta-compression in, pending
|
||||||
|
only --rsyncable files.
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I'm not sure if all HTTP servers currently handle <tt/Range/
|
||||||
|
commands efficiently. This proposal would probably stress
|
||||||
|
them more than is common at the moment.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Because it requires a special client, and special checksum
|
||||||
|
files stored on the server it has a wider impact than just
|
||||||
|
using rsync. It ought to be done in a non-Debian-specific
|
||||||
|
way. Rather than adding knowledge about the deltas into
|
||||||
|
apt-get itself, we ought to make a separate tool which
|
||||||
|
downloads a delta over HTTP.
|
||||||
|
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>rsync only compares files with the exact same
|
||||||
|
name</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Even for uncompressed files, rsync will not currently try to
|
||||||
|
use <tt/linux-2.4.17.tar/ to do delta-compression against
|
||||||
|
<tt/linux-2.4.18.tar/, because it cannot guess from the
|
||||||
|
names that the two files are related.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Paul Russell has contributed a patch which adds a heuristic
|
||||||
|
to detect this. It will probably be merged in 2.6.
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/rsync uses too much memory/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync traverses the entire directory tree before it begins
|
||||||
|
copying files. On machines with little virtual memory and a
|
||||||
|
lot of files to copy this can be a problem.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Some problems in this area have been fixed in the 2.5
|
||||||
|
series. Other solutions involving internal restructuring of
|
||||||
|
the <tt/flist/ and <tt/hlink/ code will be attempted in 2.6,
|
||||||
|
and they should yield a substantial improvement.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
We are not likely to change the general approach of
|
||||||
|
traversing the tree up-front in the near future, because it
|
||||||
|
is tightly tied to the network protocol. It might be
|
||||||
|
attempted in the 3.0 timeframe, but it is not entirely clear
|
||||||
|
that it is really a problem.
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>rsync hangs?</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There were a number of deadlock bugs in the past. We
|
||||||
|
believe they are all fixed in 2.5.5, but would welcome good
|
||||||
|
bug reports to the contrary. Some of them were in fact
|
||||||
|
Linux and Solaris kernel bugs, but they've been fixed by the
|
||||||
|
relevant parties quite some time ago.
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>Reduced network usage is not justified by increased CPU
|
||||||
|
usage
|
||||||
|
</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The balance point will vary for each administrator. It is
|
||||||
|
hard to answer this universally. The balance is very
|
||||||
|
different in countries other than the US.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I suspect CPU cycles are falling in price faster than
|
||||||
|
network bandwidth, and for many people unused CPU cycles are
|
||||||
|
wasted but network packets cost money.
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading/rsync can't saturate a fast link/
|
||||||
|
|
||||||
|
<p>
|
||||||
|
rsync with <tt>--whole-file</tt> (to turn off the
|
||||||
|
delta algorithm and be more comparable to ftp) floods a
|
||||||
|
100Mbps link. If you have something faster than that to
|
||||||
|
your upstream Debian mirror, you're a lucky person.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It is not inherently impossible to make rsync use
|
||||||
|
<tt>sendfile()</tt> and <tt>mmap()</tt>; it's just that most
|
||||||
|
people don't need them. (Apache did not use them by default
|
||||||
|
either last time I looked, but that doesn't mean it's not
|
||||||
|
fast enough for most people.)
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>rsync is not actively developed</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This was a pretty fair accusation a year ago, but I don't
|
||||||
|
think it is true anymore. We have made five releases this
|
||||||
|
year, and the <tt/diff -u/ since 2.4.6, the last version
|
||||||
|
from the previous maintainer, is 38305 lines.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Mail is answered promptly. The web site has been revised
|
||||||
|
and cleaned. We're working on a regression test suite, code
|
||||||
|
cleanup and documentation, and other quality issues.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I'm the most active developer at the moment, but there are a
|
||||||
|
number of other people with experience in the code who
|
||||||
|
regularly commit changes or send patches.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The stability expectations of our users require a somewhat
|
||||||
|
disciplined approach to accepting patches, but I don't think
|
||||||
|
that's a bad thing. The goal is to iterate through
|
||||||
|
<em/freeze/ and <em/flow/ phases similar to the kernel.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The Debian rsync package maintainer, Phil Hands, has been
|
||||||
|
somewhat inactive, but apparently he's back now. Colin
|
||||||
|
Walters has been helping out.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you have patches that were dropped, please send them
|
||||||
|
through again.
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>Servers should cache deltas</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This also smells like premature optimization. It might be
|
||||||
|
useful, but it certainly seems less important than some
|
||||||
|
other tasks.
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>Possible patent on rsync?</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It has been suggested that some uses of rsync may conflict
|
||||||
|
with a US patent. I am not sure of the current situation so
|
||||||
|
I won't comment. I don't know of any suggestion that the
|
||||||
|
rsync program as it currently exists infringes any patent.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I do know that rsync has been in use for many years by large
|
||||||
|
and small organization with no complaints of patent
|
||||||
|
infringement.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I would point out that linked lists, mark-and-copy garbage
|
||||||
|
collection, and the Tab key are all patented too. Somebody
|
||||||
|
who always carefully checked first for software patents
|
||||||
|
would never write anything at all.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>Debian should store more metadata outside of
|
||||||
|
the package file</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I can see some reasons why this might be a good idea, but
|
||||||
|
it doesn't seem particularly relevant to rsync either way.
|
||||||
|
</p>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>Debian should distribute diffs or xdeltas
|
||||||
|
between different versions of their packages</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A problem with this is that Debian releases packages very
|
||||||
|
often, and so the number of delta files is large. This will
|
||||||
|
be a problem for mirror sites who cannot carry all of the
|
||||||
|
delta files for history, although of course the client could
|
||||||
|
fall back to directly fetching the new package if the
|
||||||
|
relevant deltas are not present.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Fetching a series of deltas which update the same area is
|
||||||
|
less efficient than calculating the deltas directly.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Although this idea does not seem very practical for people
|
||||||
|
using <em/unstable/, it could work well for <em/stable/
|
||||||
|
and other situations where there are relatively few
|
||||||
|
releases, or for people without network access. One could,
|
||||||
|
for example, distribute a CD-ROM of xdeltas. On the other
|
||||||
|
hand, since CD-ROMs are relatively large compared to the
|
||||||
|
distribution it might be simpler to just distribute the new
|
||||||
|
packages directly as is currently done.
|
||||||
|
</sect1>
|
||||||
|
|
||||||
|
<sect1>
|
||||||
|
<heading>rsync should be used by <tt/apt-get update/</heading>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Even if there are few gains from compressing <tt/.deb/s,
|
||||||
|
rsync might help in providing a more efficient transfer of
|
||||||
|
the <tt/Packages/ file, which has small but frequent
|
||||||
|
changes. This approach is used by <tt/apt-proxy/.
|
||||||
|
</sect1>
|
||||||
|
</sect>
|
||||||
|
|
||||||
|
|
||||||
|
<appendix>
|
||||||
|
<sect>
|
||||||
|
<heading>Revision history</heading>
|
||||||
|
|
||||||
|
|
||||||
|
<p><tscreen><verb>
|
||||||
|
$Log: rsync-and-debian.sgml,v $
|
||||||
|
Revision 1.10 2002/05/14 03:10:09 mbp
|
||||||
|
Add note about just transferring Package files.
|
||||||
|
|
||||||
|
Revision 1.9 2002/05/14 02:35:43 mbp
|
||||||
|
Update notes on apt-proxy based on mail from Chris Halls.
|
||||||
|
|
||||||
|
Revision 1.8 2002/04/12 02:04:15 mbp
|
||||||
|
More information about Goswin's idea, as I understand it.
|
||||||
|
|
||||||
|
Revision 1.7 2002/04/12 01:39:52 mbp
|
||||||
|
Lots more details about rproxy. Thanks to Brian May for prompting me
|
||||||
|
to do this.
|
||||||
|
|
||||||
|
Revision 1.6 2002/04/12 00:43:06 mbp
|
||||||
|
Fix revision history SGML stuff.
|
||||||
|
|
||||||
|
Revision 1.5 2002/04/12 00:24:50 mbp
|
||||||
|
Fix mailing list name.
|
||||||
|
Add revision history.
|
||||||
|
|
||||||
|
</verb></tscreen></p>
|
||||||
|
</sect>
|
||||||
|
</article>
|
||||||
|
</linuxdoc>
|
||||||
10
rsync-web/rsync-debug
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
ulimit -c unlimited
|
||||||
|
|
||||||
|
# Some systems have "truss" or "tusc" instead of "strace".
|
||||||
|
# The -f option tells strace to follow children too.
|
||||||
|
# The -t option asks for timestamps.
|
||||||
|
# The -s 1024 option increases the string decoding limit per function call.
|
||||||
|
# The -o option tells strace where to send its output.
|
||||||
|
strace -f -t -s 1024 -o /tmp/rsync-$$.out rsync "${@}"
|
||||||
471
rsync-web/rsync_wrapper.pl
Normal file
@@ -0,0 +1,471 @@
|
|||||||
|
# __
|
||||||
|
# /\ \ From the mind of
|
||||||
|
# / \ \
|
||||||
|
# / /\ \ \_____ Lee Eakin <LEakin@Nostrum.COM>
|
||||||
|
# / \ \ \______\ or <Lee@Eakin.ORG>
|
||||||
|
# / /\ \ \/____ /
|
||||||
|
# \ \ \ \____\/ / Wrapper module for the rsync program
|
||||||
|
# \ \ \/____ / rsync can be found at http://rsync.samba.org/rsync/
|
||||||
|
# \ \____\/ /
|
||||||
|
# \/______/
|
||||||
|
|
||||||
|
package Rsync;
|
||||||
|
require 5.004;
|
||||||
|
|
||||||
|
use FileHandle;
|
||||||
|
use IPC::Open3 qw(open3);
|
||||||
|
use Carp;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
Rsync - perl module interface to B<rsync> http://rsync.samba.org/rsync/
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
use Rsync;
|
||||||
|
|
||||||
|
$obj = Rsync->new(qw(-az C<-e> /usr/local/bin/ssh
|
||||||
|
--rsync-path /usr/local/bin/rsync));
|
||||||
|
|
||||||
|
$obj->exec(qw(localdir rhost:remdir))
|
||||||
|
or warn "rsync failed\n";
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
Perl Convenience wrapper for B<rsync> program. Written for B<rsync> 2.3.1 but
|
||||||
|
should perform properly with most versions.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
# options from the rsync man pae
|
||||||
|
###### Boolean flags ######
|
||||||
|
# -h, --help show this help screen
|
||||||
|
# -v, --verbose increase verbosity
|
||||||
|
# -q, --quiet decrease verbosity
|
||||||
|
# -c, --checksum always checksum
|
||||||
|
# -a, --archive archive mode
|
||||||
|
# -r, --recursive recurse into directories
|
||||||
|
# -R, --relative use relative path names
|
||||||
|
# -b, --backup make backups (default ~ suffix)
|
||||||
|
# -u, --update update only (don't overwrite newer files)
|
||||||
|
# -l, --links preserve soft links
|
||||||
|
# -L, --copy-links treat soft links like regular files
|
||||||
|
# --copy-unsafe-links copy links outside the source tree
|
||||||
|
# --safe-links ignore links outside the destination tree
|
||||||
|
# -H, --hard-links preserve hard links
|
||||||
|
# -p, --perms preserve permissions
|
||||||
|
# -o, --owner preserve owner (root only)
|
||||||
|
# -g, --group preserve group
|
||||||
|
# -D, --devices preserve devices (root only)
|
||||||
|
# -t, --times preserve times
|
||||||
|
# -S, --sparse handle sparse files efficiently
|
||||||
|
# -n, --dry-run show what would have been transferred
|
||||||
|
# -W, --whole-file copy whole files, no incremental checks
|
||||||
|
# -x, --one-file-system don't cross filesystem boundaries
|
||||||
|
# -C, --cvs-exclude auto ignore files in the same way CVS does
|
||||||
|
# RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS
|
||||||
|
# .make.state .nse_depinfo *~ #* .#* ,* *.old *.bak
|
||||||
|
# *.BAK *.orig *.rej .del-* *.a *.o *.obj *.so *.Z
|
||||||
|
# *.elc *.ln core
|
||||||
|
# --delete delete files that don't exist on the sending side
|
||||||
|
# --delete-excluded also delete excluded files on the receiving side
|
||||||
|
# --partial keep partially transferred files
|
||||||
|
# --force force deletion of directories even if not empty
|
||||||
|
# --numeric-ids don't map uid/gid values by user/group name
|
||||||
|
# -I, --ignore-times don't exclude files that match length and time
|
||||||
|
# --size-only only use file size when determining if a file
|
||||||
|
# should be transferred
|
||||||
|
# -z, --compress compress file data
|
||||||
|
# --version print version number
|
||||||
|
# --daemon run as a rsync daemon
|
||||||
|
# --stats give some file transfer stats
|
||||||
|
# --progress show progress during transfer
|
||||||
|
###### scalar values ######
|
||||||
|
# --csum-length=LENGTH <=16 bit md4 checksum size
|
||||||
|
# -B, --block-size=SIZE checksum blocking size (default 700)
|
||||||
|
# --timeout=TIME set IO timeout in seconds
|
||||||
|
# --port=PORT specify alternate rsyncd port number
|
||||||
|
# -e, --rsh=COMMAND specify rsh replacement
|
||||||
|
# -T, --temp-dir=DIR create temporary files in directory DIR
|
||||||
|
# --compare-dest=DIR also compare destination files relative to DIR
|
||||||
|
# --exclude-from=FILE exclude patterns listed in FILE
|
||||||
|
# --include-from=FILE don't exclude patterns listed in FILE
|
||||||
|
# --config=FILE specify alternate rsyncd.conf file
|
||||||
|
# --password-file=FILE get password from FILE
|
||||||
|
# --log-format=FORMAT log file transfers using specified format
|
||||||
|
# --suffix=SUFFIX override backup suffix
|
||||||
|
# --rsync-path=PATH specify path to rsync on the remote machine
|
||||||
|
###### array values ######
|
||||||
|
# --exclude=PATTERN exclude files matching PATTERN
|
||||||
|
# --include=PATTERN don't exclude files matching PATTERN
|
||||||
|
#
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item Rsync::new
|
||||||
|
|
||||||
|
$obj = new Rsync;
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$obj = Rsync->new;
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$obj = Rsync->new(@options);
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
Create an Rsync object. Any options passed at creation are stored in
|
||||||
|
the object as defaults for all future exec call on that object. Options
|
||||||
|
are the same as those in L<rsync> with the addition of
|
||||||
|
--path-to-rsync which can be used to override the hardcoded default of
|
||||||
|
/usr/local/bin/rsync, and --debug which causes the module functions to
|
||||||
|
print some debugging information to STDERR.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
my $class=shift;
|
||||||
|
|
||||||
|
# seed the options hash, booleans, scalars, excludes, data,
|
||||||
|
# status, stderr/stdout storage for last exec
|
||||||
|
my $self={
|
||||||
|
# the full path name to the rsync binary
|
||||||
|
'path-to-rsync' => '/usr/local/bin/rsync',
|
||||||
|
# these are the boolean flags to rsync, all default off, including them
|
||||||
|
# in the args list turns them on
|
||||||
|
'flag' => {qw(
|
||||||
|
--archive 0 --backup 0 --checksum 0
|
||||||
|
--compress 0 --copy-links 0 --copy-unsafe-links 0
|
||||||
|
--cvs-exclude 0 --daemon 0 --delete 0
|
||||||
|
--delete-excluded 0 --devices 0 --dry-run 0
|
||||||
|
--force 0 --group 0 --hard-links 0
|
||||||
|
--help 0 --ignore-times 0 --links 0
|
||||||
|
--numeric-ids 0 --one-file-system 0 --owner 0
|
||||||
|
--partial 0 --perms 0 --progress 0
|
||||||
|
--quiet 0 --recursive 0 --relative 0
|
||||||
|
--safe-links 0 --size-only 0 --sparse 0
|
||||||
|
--stats 0 --times 0 --update 0
|
||||||
|
--verbose 0 --version 0 --whole-file 0
|
||||||
|
)},
|
||||||
|
# these have simple scalar args we cannot easily check
|
||||||
|
'scalar' => {qw(
|
||||||
|
--block-size 0 --compare-dest 0 --config 0
|
||||||
|
--csum-length 0 --exclude-from 0 --include-from 0
|
||||||
|
--log-format 0 --password-file 0 --port 0
|
||||||
|
--rsh 0 --rsync-path 0 --suffix 0
|
||||||
|
--temp-dir 0 --timeout 0
|
||||||
|
)},
|
||||||
|
# these can be specified multiple times and are additive, the doc also
|
||||||
|
# specifies that it is an ordered list so we must preserve that order
|
||||||
|
'exclude' => [],
|
||||||
|
# source/destination path names and hostnames
|
||||||
|
'data' => [],
|
||||||
|
# return status from last exec
|
||||||
|
'status' => 0,
|
||||||
|
'realstatus' => 0,
|
||||||
|
# whether or not to print debug statements
|
||||||
|
'debug' => 0,
|
||||||
|
# stderr from last exec in array format (messages from remote rsync proc)
|
||||||
|
'err' => [],
|
||||||
|
# stdout from last exec in array format (messages from local rsync proc)
|
||||||
|
'out' => [],
|
||||||
|
};
|
||||||
|
if (@_) {
|
||||||
|
&defopts($self,@_) or return undef;
|
||||||
|
}
|
||||||
|
bless $self, $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item Rsync::defopts
|
||||||
|
|
||||||
|
defopts $obj @options;
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$obj->defopts(@options);
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
Set default options for future exec calls for the object. See L<rsync>
|
||||||
|
for a complete list of valid options. This is really the internal
|
||||||
|
function that B<new> calls but you can use it too. Presently there is no way
|
||||||
|
to turn off the boolean options short of creating another object, but if it is
|
||||||
|
needed and the B<rsync> guys don't use it, I may add hooks to let + and ++ or a
|
||||||
|
leading no- toggle it back off similar to B<Getopt::Long> (the GNU way).
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub defopts {
|
||||||
|
my $self=shift;
|
||||||
|
my @opts=@_;
|
||||||
|
|
||||||
|
# need a conversion table in case someone uses the short options
|
||||||
|
my %short=(qw(
|
||||||
|
-B --block-size -C --cvs-exclude -D --devices -H --hard-links
|
||||||
|
-I --ignore-times -L --copy-links -R --relative -T --temp-dir
|
||||||
|
-W --whole-file -a --archive -b --backup -c --checksum
|
||||||
|
-e --rsh -g --group -h --help -l --links
|
||||||
|
-n --dry-run -o --owner -p --perms -q --quiet
|
||||||
|
-r --recursive -s --sparse -t --times -u --update
|
||||||
|
-v --verbose -x --one-file-system -z --compress
|
||||||
|
));
|
||||||
|
while (my $opt=shift @opts) {
|
||||||
|
my $arg;
|
||||||
|
print(STDERR "setting debug flag\n"),$self->{debug}=1,next
|
||||||
|
if $opt eq '--debug';
|
||||||
|
print STDERR "processing option: $opt\n" if $self->{debug};
|
||||||
|
if ($opt=~/^-/) {
|
||||||
|
# handle short opts first
|
||||||
|
if ($opt=~/^-(\w+)$/) {
|
||||||
|
foreach (split '',$1) {
|
||||||
|
print STDERR "short option: -$_\n" if $self->{debug};
|
||||||
|
if (exists $short{'-'.$_}) {
|
||||||
|
$opt=$short{'-'.$_};
|
||||||
|
# convert it to the long form
|
||||||
|
$opt=$short{$opt} if exists $short{$opt};
|
||||||
|
# handle the 3 short opts that require args
|
||||||
|
$self->{scalar}{$opt}=shift(@opts),next if (/^[BeT]$/);
|
||||||
|
# handle the rest
|
||||||
|
$self->{flag}{$opt}=1,next if exists $self->{flag}{$opt};
|
||||||
|
}
|
||||||
|
carp "$opt - unknown option\n";
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# handle long opts with = args
|
||||||
|
if ($opt=~/^(--\w+[\w-]*)=(.*)$/) {
|
||||||
|
print STDERR "splitting longopt: $opt ($1 $2)\n" if $self->{debug};
|
||||||
|
($opt,$arg)=($1,$2);
|
||||||
|
}
|
||||||
|
# handle boolean flags
|
||||||
|
$self->{flag}{$opt}=1,next if exists $self->{flag}{$opt};
|
||||||
|
# handle simple scalars
|
||||||
|
$self->{scalar}{$opt}=($arg || shift @opts),next
|
||||||
|
if exists $self->{scalar}{$opt};
|
||||||
|
# handle excludes
|
||||||
|
if ($opt eq '--exclude') {
|
||||||
|
$arg||=shift @opts;
|
||||||
|
# if they sent a reset, we will too
|
||||||
|
$self->{exclude}=[],next if $arg eq '!';
|
||||||
|
# otherwise add it to the list
|
||||||
|
push @{$self->{exclude}},$arg;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
# to preserve order we store both includes and excludes in the same
|
||||||
|
# array. We use the leading '+ ' (plus space) trick from the man
|
||||||
|
# page to accomplish this.
|
||||||
|
if ($opt eq '--include') {
|
||||||
|
$arg||=shift @opts;
|
||||||
|
# first check to see if this is really an exclude
|
||||||
|
push(@{$self->{exclude}},$arg),next if $arg=~s/^- //;
|
||||||
|
# next see if they sent a reset, if they did, we will too
|
||||||
|
$self->{exclude}=[],next if $arg eq '!';
|
||||||
|
# if it really is an include, fix it first, since we use exclude
|
||||||
|
$arg='+ '.$arg unless $arg=~/^\+ /;
|
||||||
|
push @{$self->{exclude}},$arg;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
# handle our special case to override hard-coded path to rsync
|
||||||
|
$self->{'path-to-rsync'}=($arg || shift @opts),next
|
||||||
|
if $opt eq '--path-to-rsync';
|
||||||
|
# if we get this far nothing matched so it must be an error
|
||||||
|
carp "$opt - unknown option\n";
|
||||||
|
return undef;
|
||||||
|
} else { # must be data (source/destination info)
|
||||||
|
print STDERR "adding to data array: $opt\n" if $self->{debug};
|
||||||
|
push(@{$self->{data}},$opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
}
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item Rsunc::exec
|
||||||
|
|
||||||
|
exec $obj @options or warn "rsync failed\n";
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$obj->exec(@options) or warn "rsync failed\n";
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
This is the function that does the real work. Any options passed to this
|
||||||
|
routine are appended to any pre-set options and are not saved. They effect
|
||||||
|
the current execution of B<rsync> only. It returns 1 if the return status was
|
||||||
|
zero (or true), if the B<rsync> return status was non-zero it returns undef and
|
||||||
|
stores the return status. You can examine the return status from rsync and
|
||||||
|
any output to stdout and stderr with the functions listed below.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub exec {
|
||||||
|
my $self=shift;
|
||||||
|
my @cmd=($self->{'path-to-rsync'});
|
||||||
|
|
||||||
|
foreach (sort keys %{$self->{flag}}) {
|
||||||
|
push @cmd,$_ if $self->{flag}{$_};
|
||||||
|
}
|
||||||
|
foreach (sort keys %{$self->{scalar}}) {
|
||||||
|
push @cmd,$_.'='.$self->{scalar}{$_} if $self->{scalar}{$_};
|
||||||
|
}
|
||||||
|
foreach (@{$self->{exclude}}) {
|
||||||
|
push @cmd,'--exclude='.$_;
|
||||||
|
}
|
||||||
|
foreach (@{$self->{data}}) {
|
||||||
|
push @cmd,$_;
|
||||||
|
}
|
||||||
|
push @cmd,@_ if @_;
|
||||||
|
print STDERR "exec: @cmd\n" if $self->{debug};
|
||||||
|
my $in=FileHandle->new; my $out=FileHandle->new; my $err=FileHandle->new;
|
||||||
|
my $pid=eval{ open3 $in,$out,$err,@cmd };
|
||||||
|
if ($@) {
|
||||||
|
$self->{realstatus}=0;
|
||||||
|
$self->{status}=255;
|
||||||
|
$self->{err}=[$@,"Execution of rsync failed.\n"];
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
$in->close; # we don't use it and neither should rsync (at least not yet)
|
||||||
|
$self->{err}=[ $err->getlines ];
|
||||||
|
$self->{out}=[ $out->getlines ];
|
||||||
|
$err->close;
|
||||||
|
$out->close;
|
||||||
|
waitpid $pid,0;
|
||||||
|
$self->{realstatus}=$?;
|
||||||
|
$self->{status}=$?>>8;
|
||||||
|
return undef if $self->{status};
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item Rsync::status
|
||||||
|
|
||||||
|
$rval = status $obj;
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$rval = $obj->status;
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
Returns the status from last B<exec> call right shifted 8 bits.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub status {
|
||||||
|
my $self=shift;
|
||||||
|
return $self->{status};
|
||||||
|
}
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item Rsync::realstatus
|
||||||
|
|
||||||
|
$rval = realstatus $obj;
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$rval = $obj->realstatus;
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
Returns the real status from last B<exec> call (not right shifted).
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub realstatus {
|
||||||
|
my $self=shift;
|
||||||
|
return $self->{realstatus};
|
||||||
|
}
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item Rsync::err
|
||||||
|
|
||||||
|
$aref = err $obj;
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$aref = $obj->err;
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
Returns an array or a reference to the array containing all output to stderr
|
||||||
|
from the last B<exec> call. B<rsync> sends all messages from the remote
|
||||||
|
B<rsync> process to stderr. This functions purpose is to make it easier for
|
||||||
|
you to parse that output for appropriate information.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub err {
|
||||||
|
my $self=shift;
|
||||||
|
return(wantarray ? @{$self->{err}} : $self->{err});
|
||||||
|
}
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item Rsync::out
|
||||||
|
|
||||||
|
$aref = out $obj;
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$aref = $obj->out;
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
Similar to the B<err> function, this returns an array or a reference to the
|
||||||
|
array containing all output to stdout from the last B<exec> call. B<rsync>
|
||||||
|
sends all messages from the local B<rsync> process to stdout.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub out {
|
||||||
|
my $self=shift;
|
||||||
|
return(wantarray ? @{$self->{out}} : $self->{out});
|
||||||
|
}
|
||||||
|
|
||||||
|
=head1 Author
|
||||||
|
|
||||||
|
Lee Eakin E<lt>leakin@nostrum.comE<gt>
|
||||||
|
|
||||||
|
=head1 Credits
|
||||||
|
|
||||||
|
Gerard Hickey C<PGP::Pipe>
|
||||||
|
|
||||||
|
Russ Allbery C<PGP::Sign>
|
||||||
|
|
||||||
|
Graham Barr C<Net::*>
|
||||||
|
|
||||||
|
Andrew Tridgell and Paul Mackerras C<rsync(1)>
|
||||||
|
|
||||||
|
John Steele E<lt>steele@nostrum.comE<gt>
|
||||||
|
|
||||||
|
Philip Kizer E<lt>pckizer@nostrum.comE<gt>
|
||||||
|
|
||||||
|
Larry Wall C<perl(1)>
|
||||||
|
|
||||||
|
I borrowed many clues on wrapping an external program from the PGP modules,
|
||||||
|
and I would not have had such a useful tool to wrap except for the great work
|
||||||
|
of the B<rsync> authors. Thanks also to Graham Barr, the author of the libnet
|
||||||
|
modules and many others, for looking over this code. Of course I must mention
|
||||||
|
the other half of my brain, John Steele, and his good friend Philip Kizer for
|
||||||
|
finding B<rsync> and bringing it to my attention. And I would not have been
|
||||||
|
able to enjoy writing useful tools if not for the creator of the B<perl>
|
||||||
|
language.
|
||||||
|
|
||||||
|
=head1 Copyrights
|
||||||
|
|
||||||
|
Copyleft (l) 1999, by Lee Eakin
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
1;
|
||||||
284
rsync-web/security.html
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync</TITLE>
|
||||||
|
<style>
|
||||||
|
.security { color: red; }
|
||||||
|
h3 { margin-bottom: 0px; }
|
||||||
|
.date { color: #D25A0B; }
|
||||||
|
</style>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">Rsync Security Advisories</H2>
|
||||||
|
|
||||||
|
<p>You should install a security fix for rsync when the rync you are running is:<ol>
|
||||||
|
<li>older than 3.2.5 and pulling from an untrusted server
|
||||||
|
<li>older than 3.2.5 and using the bundled zlib
|
||||||
|
<li>older than 3.1.3 with --xattrs enabled
|
||||||
|
<li>older than 3.1.3 with a writable rsync daemon
|
||||||
|
<li>older than 2.6.6
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p><a name="s3_2_5"></a><hr>
|
||||||
|
<h3>Improved file-list validation in 3.2.5</h3>
|
||||||
|
<i class=date>August 14th, 2022</i>
|
||||||
|
|
||||||
|
<p>If you are running an rsync older than 3.2.5 and pulling files from an
|
||||||
|
untrusted server, upgrade to 3.2.5 to get some added file-list validation rules
|
||||||
|
that should prevent the sender from sneaking in extra top-level arguments
|
||||||
|
and/or including files/dirs that should have been filtered out by the client's
|
||||||
|
filter rules. Fixes CVE-2022-29154.
|
||||||
|
|
||||||
|
<p><a name="s3_2_5-2"></a><hr>
|
||||||
|
<h3>Zlib memory corruption bug in rsync 2.6.6 - 3.2.4</h3>
|
||||||
|
<i class=date>August 14th, 2022</i>
|
||||||
|
|
||||||
|
<p>If your rsync is configured to use the bundled zlib, you should upgrade to
|
||||||
|
3.2.5 which contains the official zlib fix for a buffer overrun bug that was
|
||||||
|
detailed in CVE-2022-37434. While you're at it, be sure to update your system's
|
||||||
|
zlib.
|
||||||
|
|
||||||
|
<p><a name="s3_2_4"></a><hr>
|
||||||
|
<h3>Zlib memory corruption bug in rsync 2.6.6 - 3.2.3</h3>
|
||||||
|
<i class=date>April 15th, 2022</i>
|
||||||
|
|
||||||
|
<p>If your rsync is configured to use the bundled zlib, you should upgrade to
|
||||||
|
3.2.4 which contains the official zlib fix for a memory corruption bug that was
|
||||||
|
detailed in CVE-2018-25032. While you're at it, be sure to update your system's
|
||||||
|
zlib.
|
||||||
|
|
||||||
|
<p><a name="s3_1_3"></a><hr>
|
||||||
|
<h3>File-list validation in 3.1.3</h3>
|
||||||
|
<i class=date>January 28st, 2018</i>
|
||||||
|
|
||||||
|
<p>If you are using a version of rsync older than 3.1.3 as a client and
|
||||||
|
receiving xattrs from an rsync server that you might not fully trust, a
|
||||||
|
malicious (modified) server could send a non-null-terminated xattr name to
|
||||||
|
overflow the xattr read buffer.
|
||||||
|
|
||||||
|
<p>If you are running a writable rsync daemon older than 3.1.3, you should add
|
||||||
|
a rule "refuse options = protect-args" if you don't fully trust the users who
|
||||||
|
are sending you files.
|
||||||
|
|
||||||
|
<p><a name="s3_1_2"></a><hr>
|
||||||
|
<h3>File-list validation in 3.1.2</h3>
|
||||||
|
<i class=date>December 21st, 2015</i>
|
||||||
|
|
||||||
|
<p>If you're using a version of rsync older than 3.1.2 as a client and
|
||||||
|
receiving files from an rsync server that you might not fully trust, this
|
||||||
|
version adds extra checking to the file list to prevent the sender from
|
||||||
|
tweaking the paths and/or the transfer requests in a way that could cause
|
||||||
|
a file to be received outside the transfer destination.
|
||||||
|
|
||||||
|
<p><a name="s3_0_2"></a><hr>
|
||||||
|
<h3>Xattr security fix in 3.0.2</h3>
|
||||||
|
<i class=date>April 8th, 2008</i>
|
||||||
|
|
||||||
|
<p>If you're using a version of rsync from 2.6.9 to 3.0.1 that has extended
|
||||||
|
attribute (xattr) support enabled, you should upgrade to 3.0.2 to avoid a
|
||||||
|
potential buffer overflow problem. All 3.x versions have the potential to
|
||||||
|
support xattrs (depending on OS availability and the configure options used),
|
||||||
|
but version 2.6.9 had to be patched for this support. You can run the command
|
||||||
|
"rsync --version" and look for the string "xattrs" (as long as it is not
|
||||||
|
"no xattrs") to see if your rsync is affected.
|
||||||
|
|
||||||
|
<p>For those running affected versions, there is
|
||||||
|
<a href="https://download.samba.org/pub/rsync/security/rsync-3.0.1-xattr-alloc.diff">a
|
||||||
|
patch with the fix available</a>.
|
||||||
|
|
||||||
|
<p>Those running a writable rsync daemon can opt to refuse the "xattrs" option
|
||||||
|
as a way to avoid the problem without an upgrade:
|
||||||
|
|
||||||
|
<blockquote><pre>refuse options = xattrs</pre></blockquote>
|
||||||
|
|
||||||
|
<p>(If you already refuse options, be sure to append "xattrs" to your existing
|
||||||
|
config parameter rather than adding another refuse directive.)
|
||||||
|
|
||||||
|
<p><a name="s3_0_0"></a><hr>
|
||||||
|
<h3>Daemon security fixes in 3.0.0 (with patches for 2.6.9)</h3>
|
||||||
|
<i class=date>First published on November 28th, 2007;<br>
|
||||||
|
Updated on December 16th, 2007;<br>
|
||||||
|
Item 3 added on February 15th, 2008</i>
|
||||||
|
|
||||||
|
<p>Three security advisories affect people who run a <b>writable</b> rsync
|
||||||
|
daemon: The first affects only those with "use chroot = no" (which is not a
|
||||||
|
very safe combination in general), the second affects a daemon that has
|
||||||
|
daemon-excluded files that are being hidden in a module's hierarchy, and
|
||||||
|
the third affects only those with "use chroot = yes".
|
||||||
|
Included are simple config-change suggestions that should help you to
|
||||||
|
avoid the security issues and patches that make things safer.
|
||||||
|
These advisories affect all rsync versions.
|
||||||
|
|
||||||
|
<h4>1. Daemon advisory for "use chroot = no"</h4>
|
||||||
|
|
||||||
|
<p>If you are running a writable rsync daemon with "use chroot = no", there
|
||||||
|
is at least one way for someone to trick rsync into creating a symlink
|
||||||
|
that points outside of the module's hierarchy.
|
||||||
|
|
||||||
|
<p>This means that if you are allowing access from users who you don't
|
||||||
|
trust, that you should either figure out a way to turn on "use chroot",
|
||||||
|
or configure the daemon to refuse the "links" option (see "refuse
|
||||||
|
options" in the rsyncd.conf manpage) which will disable the ability of
|
||||||
|
the rsync module to receive symlinks. After doing so, you should also
|
||||||
|
check that any existing symlinks in the daemon hierarchy are safe.
|
||||||
|
|
||||||
|
<p>Starting with the 3.0.0-pre6 release, there is a new daemon parameter
|
||||||
|
available: "munge symlinks". This allows an rsync daemon to accept
|
||||||
|
symlinks and return them intact (with even a leading slash still there,
|
||||||
|
which is new for a non-chroot daemon), but will not allow the symlinks
|
||||||
|
to be used while they are in the daemon's hierarchy.
|
||||||
|
|
||||||
|
<p>For those running
|
||||||
|
2.6.9, there is
|
||||||
|
<a href="https://download.samba.org/pub/rsync/security/rsync-2.6.9-munge-symlinks.diff">a
|
||||||
|
patch for 2.6.9 to implement this parameter</a>.
|
||||||
|
|
||||||
|
<p>Any admin applying that patch should read the "munge symlinks" section
|
||||||
|
of the modified rsyncd.conf manpage for more information. You can also
|
||||||
|
read about this parameter in the
|
||||||
|
<a href="https://download.samba.org/pub/rsync/rsyncd.conf.html">rsyncd.conf
|
||||||
|
manpage from a 3.x version</a>.
|
||||||
|
|
||||||
|
<h4>2. Daemon advisory for daemon excludes</h4>
|
||||||
|
|
||||||
|
<p>If you are running a writable rsync daemon that is using one of the
|
||||||
|
"exclude", "exclude from", or "filter" parameters in the rsyncd.conf file
|
||||||
|
to hide data from your users, you should be aware that there are tricks
|
||||||
|
that a user can play with symlinks and/or certain options that can allow
|
||||||
|
a user that knows the name of a hidden file to access it or overwrite it
|
||||||
|
(if file permissions allow that).
|
||||||
|
|
||||||
|
<p>You can avoid the symlink problem using the suggestions in the advisory
|
||||||
|
above.
|
||||||
|
|
||||||
|
<p>When a daemon has "use chroot = no" set , there was some buggy
|
||||||
|
exclude-checking for these options: <code>--compare-dest</code>,
|
||||||
|
<code>--link-dest</code>, <code>--copy-dest</code>, <code>--partial-dir</code>,
|
||||||
|
<code>--backup-dir</code>, <code>--temp-dir</code>, and
|
||||||
|
<code>--files-from</code>. These are fixed in the 3.0.0pre7 release. For
|
||||||
|
those running 2.6.9, there is <a
|
||||||
|
href="https://download.samba.org/pub/rsync/security/rsync-2.6.9-daemon-exclude.diff">a patch for
|
||||||
|
2.6.9</a> to fix these checks.
|
||||||
|
|
||||||
|
<p>Some of the above options can still cause problems if an excluded
|
||||||
|
sub-directory or filename is inside the option's directory hierarchy and the
|
||||||
|
names of a transferred file clashes with it. The affected options are the
|
||||||
|
various <code>--*-dest</code> options (of which only <code>--link-dest</code>
|
||||||
|
is particularly worrisome),
|
||||||
|
<code>--backup-dir</code>, and <code>--partial-dir</code>.
|
||||||
|
|
||||||
|
<p>You can avoid these sub-path problems by putting the following "refuse
|
||||||
|
options" setting into your rsyncd.conf file:
|
||||||
|
|
||||||
|
<blockquote><pre>refuse options = link-dest backup-dir partial-dir</pre></blockquote>
|
||||||
|
|
||||||
|
<p>Those who aren't using an rsync with the latest exclude fixes may want to add
|
||||||
|
some of the other affected options as well.
|
||||||
|
|
||||||
|
<h4>3. Daemon advisory for "use chroot = yes"</h4>
|
||||||
|
|
||||||
|
<p>If you are running a writable rsync daemon with "use chroot = yes", you
|
||||||
|
should take care that users cannot upload their own library files and attempt
|
||||||
|
to load them.
|
||||||
|
|
||||||
|
<p>Beginning with rsync 3.0.0pre10, you can specify an inside-chroot path that
|
||||||
|
makes the top of the transfer a subdirectory inside the chroot area, and that
|
||||||
|
automatically makes library loading occur outside the transfer area (assuming
|
||||||
|
you didn't pick an unwise subdirectory name for the transfer area and you
|
||||||
|
don't have symlinks that point outside the transfer area).
|
||||||
|
|
||||||
|
<p>If that solution is not good for you, the easiest way to protect your daemon
|
||||||
|
is to create some appropriate directories in the top of your module's path
|
||||||
|
hierarchy, such as "/etc", "/lib", and "/usr" (and any other top-level dirs
|
||||||
|
that might be in the load path), chown those directories to some other user
|
||||||
|
than the one that the module runs as (so that rsync will not be able to write
|
||||||
|
files there, assuming that it is not run as root), and then hide the dirs using
|
||||||
|
an exclude directive (either add a new one or extend your existing one):
|
||||||
|
|
||||||
|
<blockquote><pre>exclude = /etc /lib /usr</pre></blockquote>
|
||||||
|
|
||||||
|
<p>Doing all that will assure you that no user will be able to use rsync to
|
||||||
|
upload a library that can be potentially loaded while rsync is attempting to
|
||||||
|
perform an action, such as translating a username. You can feel free to put
|
||||||
|
trusted libraries that you want rsync to access in the protected hierarchies,
|
||||||
|
as desired.
|
||||||
|
|
||||||
|
<p>Also available in rsync 3.0.0pre10 is a new daemon parameter that allows you
|
||||||
|
to avoid the accessing of user/group-name translation libraries by a chrooted
|
||||||
|
rsync: the "numeric ids" daemon parameter lets you turn on a forced
|
||||||
|
numeric-only mode. The default for a chroot module is to enable this
|
||||||
|
parameter, while the default for a non-chroot module is to disable it.
|
||||||
|
|
||||||
|
<p>For those running 2.6.9, there is <a
|
||||||
|
href="https://download.samba.org/pub/rsync/security/rsync-2.6.9-daemon-ids.diff">a patch for
|
||||||
|
2.6.9</a> to add the "numeric ids" daemon config parameter. (The patch will
|
||||||
|
only apply cleanly if you've already applied the munge-symlinks diff mentioned
|
||||||
|
above.)
|
||||||
|
|
||||||
|
<p><a name="s2_6_8"></a><hr>
|
||||||
|
<h3>Xattr security fix in 2.6.8</h3>
|
||||||
|
<i class=date>April 22th, 2006</i>
|
||||||
|
|
||||||
|
<p>If you're using a version of rsync prior to 2.6.8 that was patched to
|
||||||
|
include extended attribute (xattr) support, you should upgrade to 2.6.8 or
|
||||||
|
later to avoid a potential buffer overflow problem.
|
||||||
|
|
||||||
|
<p><a name="s2_6_6"></a><hr>
|
||||||
|
<h3>Zlib security fix in 2.6.6</h3>
|
||||||
|
<i class=date>July 28th, 2005</i>
|
||||||
|
|
||||||
|
<p>If you're using a version of rsync prior to 2.6.6, there is a potential
|
||||||
|
null-pointer security bug in the zlib code. You can avoid its affect in an
|
||||||
|
rsync daemon situation by configuring rsync to refuse the "compress" option.
|
||||||
|
|
||||||
|
<p><a name="s2_6_3"></a><hr>
|
||||||
|
<h3>Daemon path-sanitizing fix in 2.6.3</h3>
|
||||||
|
<i class=date>August 12th, 2004</i>
|
||||||
|
|
||||||
|
<p>There is a path-sanitizing bug that affects daemon-mode in
|
||||||
|
rsync versions prior to 2.6.3, but only if "use chroot" is disabled. It
|
||||||
|
does <b>not</b> affect the normal send/receive filenames that specify what
|
||||||
|
files should be transferred (this is because these names happen to get
|
||||||
|
sanitized twice, and thus the second call removes any lingering leading
|
||||||
|
slash(es) that the first call left behind). It does affect certain
|
||||||
|
option paths that cause auxiliary files to be read or written.
|
||||||
|
|
||||||
|
<p>One potential fix that doesn't require recompiling rsync is to set
|
||||||
|
"use chroot = true" for all the modules in the rsyncd.conf file.
|
||||||
|
|
||||||
|
<p><a name="s2_6_1"></a><hr>
|
||||||
|
<h3>Daemon security fix in 2.6.1</h3>
|
||||||
|
<i class=date>April 26th, 2004</i>
|
||||||
|
|
||||||
|
<p>There is a security problem in all versions prior to 2.6.1 that affects only
|
||||||
|
people running a read/write daemon with "use chroot" disabled. If the user privs
|
||||||
|
of a module in the daemon config is anything above "nobody", you are at risk
|
||||||
|
of someone crafting an attack that could write a file outside of the module's
|
||||||
|
"path" setting (where all its files should be stored). Please either enable
|
||||||
|
chroot or upgrade to 2.6.1. People not running a daemon, running a read-only
|
||||||
|
daemon, or running a chrooted daemon are totally unaffected.
|
||||||
|
|
||||||
|
<p><a name="s2_5_7"></a><hr>
|
||||||
|
<h3>Memory overflow fix in 2.5.7</h3>
|
||||||
|
<i class=date>December 4th, 2003</i>
|
||||||
|
|
||||||
|
<p>Rsync versions prior to 2.5.7 contain a heap overflow vulnerability that
|
||||||
|
could be used to remotely run arbitrary code, but this only affects the use of
|
||||||
|
rsync as an "rsync daemon" (where rsync handles incoming socket connections,
|
||||||
|
typically on port 873).
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
31
rsync-web/susan.txt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
I use rsync to backup my wifes home directory across a modem link each
|
||||||
|
night. The cron job looks like this
|
||||||
|
|
||||||
|
#!/bin/sh
|
||||||
|
cd ~susan
|
||||||
|
{
|
||||||
|
echo
|
||||||
|
date
|
||||||
|
dest=~/backup/`date +%A`
|
||||||
|
mkdir $dest.new
|
||||||
|
find . -xdev -type f \( -mtime 0 -or -mtime 1 \) -exec cp -aPv "{}"
|
||||||
|
$dest.new \;
|
||||||
|
cnt=`find $dest.new -type f | wc -l`
|
||||||
|
if [ $cnt -gt 0 ]; then
|
||||||
|
rm -rf $dest
|
||||||
|
mv $dest.new $dest
|
||||||
|
fi
|
||||||
|
rm -rf $dest.new
|
||||||
|
rsync -Cavze ssh . samba:backup
|
||||||
|
} >> ~/backup/backup.log 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
note that most of this script isn't anything to do with rsync, it just
|
||||||
|
creates a daily backup of Susans work in a ~susan/backup/ directory so
|
||||||
|
she can retrieve any version from the last week. The last line does
|
||||||
|
the rsync of her directory across the modem link to the host
|
||||||
|
samba. Note that I am using the -C option which allows me to add
|
||||||
|
entries to .cvsignore for stuff that doesn't need to be backed up.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
134
rsync-web/tech_report/footnode.html
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Footnotes</TITLE>
|
||||||
|
<META NAME="description" CONTENT="Footnotes">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="previous" HREF="node7.html">
|
||||||
|
<LINK REL="up" HREF="tech_report.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
|
||||||
|
<DL>
|
||||||
|
<DT><A NAME="foot10">... bytes</A><A NAME="foot10"
|
||||||
|
HREF="node2.html#tex2html1"><SUP>1</SUP></A>
|
||||||
|
<DD>We have found that
|
||||||
|
values of S between 500 and 1000 are quite good for most purposes
|
||||||
|
<PRE>.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
</PRE>
|
||||||
|
<DT><A NAME="foot24">... size.</A><A NAME="foot24"
|
||||||
|
HREF="node6.html#tex2html2"><SUP>2</SUP></A>
|
||||||
|
<DD>All the tests in this section were
|
||||||
|
carried out using rsync version 0.5
|
||||||
|
<PRE>.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
</PRE>
|
||||||
|
<DT><A NAME="foot40">... files.</A><A NAME="foot40"
|
||||||
|
HREF="node6.html#tex2html3"><SUP>3</SUP></A>
|
||||||
|
<DD>The wall
|
||||||
|
clock time was approximately 2 minutes per run on a 50 MHz SPARC 10
|
||||||
|
running SunOS, using rsh over loopback for communication. GNU diff
|
||||||
|
took about 4 minutes.
|
||||||
|
<PRE>.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
</PRE>
|
||||||
|
</DL><ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
1
rsync-web/tech_report/images.aux
Normal file
@@ -0,0 +1 @@
|
|||||||
|
\relax
|
||||||
106
rsync-web/tech_report/images.log
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
This is TeX, Version 3.14159 (C version 6.1) (format=latex 97.10.16) 9 NOV 1998 20:10
|
||||||
|
**./images.tex
|
||||||
|
(images.tex
|
||||||
|
LaTeX2e <1996/12/01> patch level 1
|
||||||
|
Babel <v3.6h> and hyphenation patterns for american, german, loaded.
|
||||||
|
|
||||||
|
(/usr/lib/texmf/texmf/tex/latex/base/article.cls
|
||||||
|
Document Class: article 1996/10/31 v1.3u Standard LaTeX document class
|
||||||
|
(/usr/lib/texmf/texmf/tex/latex/base/size10.clo
|
||||||
|
File: size10.clo 1996/10/31 v1.3u Standard LaTeX file (size option)
|
||||||
|
)
|
||||||
|
\c@part=\count79
|
||||||
|
\c@section=\count80
|
||||||
|
\c@subsection=\count81
|
||||||
|
\c@subsubsection=\count82
|
||||||
|
\c@paragraph=\count83
|
||||||
|
\c@subparagraph=\count84
|
||||||
|
\c@figure=\count85
|
||||||
|
\c@table=\count86
|
||||||
|
\abovecaptionskip=\skip41
|
||||||
|
\belowcaptionskip=\skip42
|
||||||
|
\bibindent=\dimen102
|
||||||
|
) (/usr/lib/texmf/texmf/tex/latex/graphics/color.sty
|
||||||
|
Package: color 1997/01/07 v1.0d Standard LaTeX Color (DPC)
|
||||||
|
(/usr/lib/texmf/texmf/tex/latex/config/color.cfg)
|
||||||
|
Package color Info: Driver file: dvips.def on input line 128.
|
||||||
|
(/usr/lib/texmf/texmf/tex/latex/graphics/dvips.def
|
||||||
|
File: dvips.def 1996/12/12 v3.0d Driver-dependant file (DPC,SPQR)
|
||||||
|
) (/usr/lib/texmf/texmf/tex/latex/graphics/dvipsnam.def
|
||||||
|
File: dvipsnam.def 1996/12/12 v3.0d Driver-dependant file (DPC,SPQR)
|
||||||
|
))
|
||||||
|
\sizebox=\box26
|
||||||
|
\lthtmlwrite=\write3
|
||||||
|
No file images.aux.
|
||||||
|
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 74.
|
||||||
|
LaTeX Font Info: ... okay on input line 74.
|
||||||
|
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 74.
|
||||||
|
LaTeX Font Info: ... okay on input line 74.
|
||||||
|
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 74.
|
||||||
|
LaTeX Font Info: ... okay on input line 74.
|
||||||
|
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 74.
|
||||||
|
LaTeX Font Info: ... okay on input line 74.
|
||||||
|
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 74.
|
||||||
|
LaTeX Font Info: ... okay on input line 74.
|
||||||
|
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 74.
|
||||||
|
LaTeX Font Info: ... okay on input line 74.
|
||||||
|
latex2htmlLength hsize=349.0pt
|
||||||
|
latex2htmlLength vsize=682.0pt
|
||||||
|
latex2htmlLength hoffset=0.0pt
|
||||||
|
latex2htmlLength voffset=0.0pt
|
||||||
|
latex2htmlLength topmargin=0.0pt
|
||||||
|
latex2htmlLength topskip=0.00003pt
|
||||||
|
latex2htmlLength headheight=0.0pt
|
||||||
|
latex2htmlLength headsep=0.0pt
|
||||||
|
latex2htmlLength parskip=0.0pt plus 1.0pt
|
||||||
|
latex2htmlLength oddsidemargin=53.0pt
|
||||||
|
latex2htmlLength evensidemargin=53.0pt
|
||||||
|
LaTeX Font Info: External font `cmex10' loaded for size
|
||||||
|
(Font) <7> on input line 94.
|
||||||
|
LaTeX Font Info: External font `cmex10' loaded for size
|
||||||
|
(Font) <5> on input line 94.
|
||||||
|
l2hSize :tex2html_wrap_inline88:6.45831pt::0.0pt::6.43404pt.
|
||||||
|
[1
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
l2hSize :tex2html_wrap_inline90:7.44444pt::7.44444pt::6.18402pt.
|
||||||
|
[2
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
l2hSize :displaymath158:32.38896pt::0.0pt::349.0pt.
|
||||||
|
[3
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
l2hSize :displaymath160:32.38896pt::0.0pt::349.0pt.
|
||||||
|
[4
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
l2hSize :tex2html_wrap_inline166:7.33331pt::7.33331pt::39.55894pt.
|
||||||
|
[5
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
l2hSize :displaymath170:14.5pt::0.0pt::349.0pt.
|
||||||
|
[6
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
l2hSize :displaymath172:14.5pt::0.0pt::349.0pt.
|
||||||
|
[7
|
||||||
|
|
||||||
|
|
||||||
|
] (images.aux) )
|
||||||
|
Here is how much of TeX's memory you used:
|
||||||
|
518 strings out of 10906
|
||||||
|
6196 string characters out of 72186
|
||||||
|
46914 words of memory out of 262141
|
||||||
|
3454 multiletter control sequences out of 9500
|
||||||
|
3640 words of font info for 14 fonts, out of 150000 for 255
|
||||||
|
14 hyphenation exceptions out of 607
|
||||||
|
23i,5n,19p,182b,215s stack positions out of 300i,40n,60p,3000b,4000s
|
||||||
|
|
||||||
|
Output written on images.dvi (7 pages, 2296 bytes).
|
||||||
48
rsync-web/tech_report/images.pl
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
# Associate images original text with physical files.
|
||||||
|
|
||||||
|
|
||||||
|
$key = q/{inline}alpha{inline}MSF=1.6;AAT;/;
|
||||||
|
$cached_env_img{$key} = q|<IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">|;
|
||||||
|
|
||||||
|
$key = q/{displaymath}a(k+1,l+1)=(a(k,l)-X_k+X_l+1)bmodM{displaymath}MSF=1.6;AAT;/;
|
||||||
|
$cached_env_img{$key} = q|<IMG
|
||||||
|
WIDTH="322" HEIGHT="28"
|
||||||
|
SRC="img6.gif"
|
||||||
|
ALT="\begin{displaymath}a(k+1,l+1) = (a(k,l) - X_k + X_{l+1}) \bmod M \end{displaymath}">|;
|
||||||
|
|
||||||
|
$key = q/{displaymath}a(k,l)=(sum_i=k^lX_i)bmodM{displaymath}MSF=1.6;AAT;/;
|
||||||
|
$cached_env_img{$key} = q|<IMG
|
||||||
|
WIDTH="176" HEIGHT="56"
|
||||||
|
SRC="img3.gif"
|
||||||
|
ALT="\begin{displaymath}a(k,l) = (\sum_{i=k}^l X_i) \bmod M \end{displaymath}">|;
|
||||||
|
|
||||||
|
$key = q/{displaymath}b(k,l)=(sum_i=k^l(l-i+1)X_i)bmodM{displaymath}MSF=1.6;AAT;/;
|
||||||
|
$cached_env_img{$key} = q|<IMG
|
||||||
|
WIDTH="240" HEIGHT="56"
|
||||||
|
SRC="img4.gif"
|
||||||
|
ALT="\begin{displaymath}b(k,l) = (\sum_{i=k}^l (l-i+1)X_i) \bmod M \end{displaymath}">|;
|
||||||
|
|
||||||
|
$key = q/{inline}X_kldotsX_l{inline}MSF=1.6;AAT;/;
|
||||||
|
$cached_env_img{$key} = q|<IMG
|
||||||
|
WIDTH="67" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img5.gif"
|
||||||
|
ALT="$X_k \ldots X_l$">|;
|
||||||
|
|
||||||
|
$key = q/{displaymath}b(k+1,l+1)=(b(k,l)-(l-k+1)X_k+a(k+1,l+1))bmodM{displaymath}MSF=1.6;AAT;/;
|
||||||
|
$cached_env_img{$key} = q|<IMG
|
||||||
|
WIDTH="454" HEIGHT="28"
|
||||||
|
SRC="img7.gif"
|
||||||
|
ALT="\begin{displaymath}b(k+1,l+1) = (b(k,l) - (l-k+1) X_k + a(k+1,l+1)) \bmod M \end{displaymath}">|;
|
||||||
|
|
||||||
|
$key = q/{inline}beta{inline}MSF=1.6;AAT;/;
|
||||||
|
$cached_env_img{$key} = q|<IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">|;
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
140
rsync-web/tech_report/images.tex
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
\batchmode
|
||||||
|
\documentclass[a4paper]{article}
|
||||||
|
\makeatletter
|
||||||
|
\usepackage[dvips]{color}
|
||||||
|
\pagecolor[gray]{.7}
|
||||||
|
|
||||||
|
|
||||||
|
\makeatletter
|
||||||
|
\count@=\the\catcode`\_ \catcode`\_=8
|
||||||
|
\newenvironment{tex2html_wrap}{}{} \catcode`\_=\count@
|
||||||
|
\makeatother
|
||||||
|
\let\mathon=$
|
||||||
|
\let\mathoff=$
|
||||||
|
\ifx\AtBeginDocument\undefined \newcommand{\AtBeginDocument}[1]{}\fi
|
||||||
|
\newbox\sizebox
|
||||||
|
\setlength{\hoffset}{0pt}\setlength{\voffset}{0pt}
|
||||||
|
\addtolength{\textheight}{\footskip}\setlength{\footskip}{0pt}
|
||||||
|
\addtolength{\textheight}{\topmargin}\setlength{\topmargin}{0pt}
|
||||||
|
\addtolength{\textheight}{\headheight}\setlength{\headheight}{0pt}
|
||||||
|
\addtolength{\textheight}{\headsep}\setlength{\headsep}{0pt}
|
||||||
|
\setlength{\textwidth}{349pt}
|
||||||
|
\newwrite\lthtmlwrite
|
||||||
|
\makeatletter
|
||||||
|
\let\realnormalsize=\normalsize
|
||||||
|
\global\topskip=2sp
|
||||||
|
\def\preveqno{}\let\real@float=\@float \let\realend@float=\end@float
|
||||||
|
\def\@float{\let\@savefreelist\@freelist\real@float}
|
||||||
|
\def\end@float{\realend@float\global\let\@freelist\@savefreelist}
|
||||||
|
\let\real@dbflt=\@dbflt \let\end@dblfloat=\end@float
|
||||||
|
\let\@largefloatcheck=\relax
|
||||||
|
\def\@dbflt{\let\@savefreelist\@freelist\real@dbflt}
|
||||||
|
\def\adjustnormalsize{\def\normalsize{\mathsurround=0pt \realnormalsize
|
||||||
|
\parindent=0pt\abovedisplayskip=0pt\belowdisplayskip=0pt}\normalsize}%
|
||||||
|
\def\lthtmltypeout#1{{\let\protect\string\immediate\write\lthtmlwrite{#1}}}%
|
||||||
|
\newcommand\lthtmlhboxmathA{\adjustnormalsize\setbox\sizebox=\hbox\bgroup}%
|
||||||
|
\newcommand\lthtmlvboxmathA{\adjustnormalsize\setbox\sizebox=\vbox\bgroup%
|
||||||
|
\let\ifinner=\iffalse }%
|
||||||
|
\newcommand\lthtmlboxmathZ{\@next\next\@currlist{}{\def\next{\voidb@x}}%
|
||||||
|
\expandafter\box\next\egroup}%
|
||||||
|
\newcommand\lthtmlmathtype[1]{\def\lthtmlmathenv{#1}}%
|
||||||
|
\newcommand\lthtmllogmath{\lthtmltypeout{l2hSize %
|
||||||
|
:\lthtmlmathenv:\the\ht\sizebox::\the\dp\sizebox::\the\wd\sizebox.\preveqno}}%
|
||||||
|
\newcommand\lthtmlfigureA[1]{\let\@savefreelist\@freelist
|
||||||
|
\lthtmlmathtype{#1}\lthtmlvboxmathA}%
|
||||||
|
\newcommand\lthtmlfigureZ{\lthtmlboxmathZ\lthtmllogmath\copy\sizebox
|
||||||
|
\global\let\@freelist\@savefreelist}%
|
||||||
|
\newcommand\lthtmldisplayA[1]{\lthtmlmathtype{#1}\lthtmlvboxmathA}%
|
||||||
|
\newcommand\lthtmldisplayB[1]{\edef\preveqno{(\theequation)}%
|
||||||
|
\lthtmldisplayA{#1}\let\@eqnnum\relax}%
|
||||||
|
\newcommand\lthtmldisplayZ{\lthtmlboxmathZ\lthtmllogmath\lthtmlsetmath}%
|
||||||
|
\newcommand\lthtmlinlinemathA[1]{\lthtmlmathtype{#1}\lthtmlhboxmathA \vrule height1.5ex width0pt }%
|
||||||
|
\newcommand\lthtmlinlineA[1]{\lthtmlmathtype{#1}\lthtmlhboxmathA}%
|
||||||
|
\newcommand\lthtmlinlineZ{\egroup\expandafter\ifdim\dp\sizebox>0pt %
|
||||||
|
\expandafter\centerinlinemath\fi\lthtmllogmath\lthtmlsetinline}
|
||||||
|
\newcommand\lthtmlinlinemathZ{\egroup\expandafter\ifdim\dp\sizebox>0pt %
|
||||||
|
\expandafter\centerinlinemath\fi\lthtmllogmath\lthtmlsetmath}
|
||||||
|
\def\lthtmlsetinline{\hbox{\vrule width.1em\vtop{\vbox{%
|
||||||
|
\kern.1em\copy\sizebox}\ifdim\dp\sizebox>0pt\kern.1em\else\kern.3pt\fi
|
||||||
|
\ifdim\hsize>\wd\sizebox \hrule depth1pt\fi}}}
|
||||||
|
\def\lthtmlsetmath{\hbox{\vrule width.1em\vtop{\vbox{%
|
||||||
|
\kern.1em\kern0.8 pt\hbox{\hglue.17em\copy\sizebox\hglue0.8 pt}}\kern.3pt%
|
||||||
|
\ifdim\dp\sizebox>0pt\kern.1em\fi \kern0.8 pt%
|
||||||
|
\ifdim\hsize>\wd\sizebox \hrule depth1pt\fi}}}
|
||||||
|
\def\centerinlinemath{%\dimen1=\ht\sizebox
|
||||||
|
\dimen1=\ifdim\ht\sizebox<\dp\sizebox \dp\sizebox\else\ht\sizebox\fi
|
||||||
|
\advance\dimen1by.5pt \vrule width0pt height\dimen1 depth\dimen1
|
||||||
|
\dp\sizebox=\dimen1\ht\sizebox=\dimen1\relax}
|
||||||
|
|
||||||
|
\def\lthtmlcheckvsize{\ifdim\ht\sizebox<\vsize\expandafter\vfill
|
||||||
|
\else\expandafter\vss\fi}%
|
||||||
|
\makeatletter \tracingstats = 1
|
||||||
|
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\pagestyle{empty}\thispagestyle{empty}%
|
||||||
|
\lthtmltypeout{latex2htmlLength hsize=\the\hsize}%
|
||||||
|
\lthtmltypeout{latex2htmlLength vsize=\the\vsize}%
|
||||||
|
\lthtmltypeout{latex2htmlLength hoffset=\the\hoffset}%
|
||||||
|
\lthtmltypeout{latex2htmlLength voffset=\the\voffset}%
|
||||||
|
\lthtmltypeout{latex2htmlLength topmargin=\the\topmargin}%
|
||||||
|
\lthtmltypeout{latex2htmlLength topskip=\the\topskip}%
|
||||||
|
\lthtmltypeout{latex2htmlLength headheight=\the\headheight}%
|
||||||
|
\lthtmltypeout{latex2htmlLength headsep=\the\headsep}%
|
||||||
|
\lthtmltypeout{latex2htmlLength parskip=\the\parskip}%
|
||||||
|
\lthtmltypeout{latex2htmlLength oddsidemargin=\the\oddsidemargin}%
|
||||||
|
\makeatletter
|
||||||
|
\if@twoside\lthtmltypeout{latex2htmlLength evensidemargin=\the\evensidemargin}%
|
||||||
|
\else\lthtmltypeout{latex2htmlLength evensidemargin=\the\oddsidemargin}\fi%
|
||||||
|
\makeatother
|
||||||
|
\stepcounter{section}
|
||||||
|
\stepcounter{section}
|
||||||
|
{\newpage\clearpage
|
||||||
|
\lthtmlinlinemathA{tex2html_wrap_inline88}%
|
||||||
|
$\alpha$%
|
||||||
|
\lthtmlinlinemathZ
|
||||||
|
\hfill\lthtmlcheckvsize\clearpage}
|
||||||
|
|
||||||
|
{\newpage\clearpage
|
||||||
|
\lthtmlinlinemathA{tex2html_wrap_inline90}%
|
||||||
|
$\beta$%
|
||||||
|
\lthtmlinlinemathZ
|
||||||
|
\hfill\lthtmlcheckvsize\clearpage}
|
||||||
|
|
||||||
|
\stepcounter{section}
|
||||||
|
{\newpage\clearpage
|
||||||
|
\lthtmldisplayA{displaymath158}%
|
||||||
|
\begin{displaymath}a(k,l) = (\sum_{i=k}^l X_i) \bmod M \end{displaymath}%
|
||||||
|
\lthtmldisplayZ
|
||||||
|
\hfill\lthtmlcheckvsize\clearpage}
|
||||||
|
|
||||||
|
{\newpage\clearpage
|
||||||
|
\lthtmldisplayA{displaymath160}%
|
||||||
|
\begin{displaymath}b(k,l) = (\sum_{i=k}^l (l-i+1)X_i) \bmod M \end{displaymath}%
|
||||||
|
\lthtmldisplayZ
|
||||||
|
\hfill\lthtmlcheckvsize\clearpage}
|
||||||
|
|
||||||
|
{\newpage\clearpage
|
||||||
|
\lthtmlinlinemathA{tex2html_wrap_inline166}%
|
||||||
|
$X_k \ldots X_l$%
|
||||||
|
\lthtmlinlinemathZ
|
||||||
|
\hfill\lthtmlcheckvsize\clearpage}
|
||||||
|
|
||||||
|
{\newpage\clearpage
|
||||||
|
\lthtmldisplayA{displaymath170}%
|
||||||
|
\begin{displaymath}a(k+1,l+1) = (a(k,l) - X_k + X_{l+1}) \bmod M \end{displaymath}%
|
||||||
|
\lthtmldisplayZ
|
||||||
|
\hfill\lthtmlcheckvsize\clearpage}
|
||||||
|
|
||||||
|
{\newpage\clearpage
|
||||||
|
\lthtmldisplayA{displaymath172}%
|
||||||
|
\begin{displaymath}b(k+1,l+1) = (b(k,l) - (l-k+1) X_k + a(k+1,l+1)) \bmod M \end{displaymath}%
|
||||||
|
\lthtmldisplayZ
|
||||||
|
\hfill\lthtmlcheckvsize\clearpage}
|
||||||
|
|
||||||
|
\stepcounter{section}
|
||||||
|
\stepcounter{section}
|
||||||
|
\stepcounter{section}
|
||||||
|
\stepcounter{section}
|
||||||
|
|
||||||
|
\end{document}
|
||||||
BIN
rsync-web/tech_report/img1.gif
Normal file
|
After Width: | Height: | Size: 68 B |
BIN
rsync-web/tech_report/img2.gif
Normal file
|
After Width: | Height: | Size: 82 B |
BIN
rsync-web/tech_report/img3.gif
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
rsync-web/tech_report/img4.gif
Normal file
|
After Width: | Height: | Size: 599 B |
BIN
rsync-web/tech_report/img5.gif
Normal file
|
After Width: | Height: | Size: 156 B |
BIN
rsync-web/tech_report/img6.gif
Normal file
|
After Width: | Height: | Size: 586 B |
BIN
rsync-web/tech_report/img7.gif
Normal file
|
After Width: | Height: | Size: 780 B |
94
rsync-web/tech_report/index.html
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>The rsync algorithm</TITLE>
|
||||||
|
<META NAME="description" CONTENT="The rsync algorithm">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="next" HREF="node1.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html4"
|
||||||
|
HREF="node1.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif">
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html5"
|
||||||
|
HREF="node1.html">The problem</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H1 ALIGN="CENTER">The rsync algorithm</H1>
|
||||||
|
<P ALIGN="CENTER"><STRONG>Andrew Tridgell Paul Mackerras
|
||||||
|
<BR>
|
||||||
|
Department of Computer Science <BR>
|
||||||
|
Australian National University <BR>
|
||||||
|
Canberra, ACT 0200, Australia</STRONG></P>
|
||||||
|
<P ALIGN="LEFT"></P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
|
||||||
|
<H3>Abstract:</H3>
|
||||||
|
<DIV>
|
||||||
|
This report presents an algorithm for updating a file on one machine
|
||||||
|
to be identical to a file on another machine. We assume that the
|
||||||
|
two machines are connected by a low-bandwidth high-latency
|
||||||
|
bi-directional communications link. The algorithm identifies parts
|
||||||
|
of the source file which are identical to some part of the
|
||||||
|
destination file, and only sends those parts which cannot be matched
|
||||||
|
in this way. Effectively, the algorithm computes a set of
|
||||||
|
differences without having both files on the same machine. The
|
||||||
|
algorithm works best when the files are similar, but will also
|
||||||
|
function correctly and reasonably efficiently when the files are
|
||||||
|
quite different.
|
||||||
|
</DIV>
|
||||||
|
<P>
|
||||||
|
<P>
|
||||||
|
<BR><HR>
|
||||||
|
<!--Table of Child-Links-->
|
||||||
|
<A NAME="CHILD_LINKS"> </A>
|
||||||
|
<UL>
|
||||||
|
<LI><A NAME="tex2html6"
|
||||||
|
HREF="node1.html">The problem</A>
|
||||||
|
<LI><A NAME="tex2html7"
|
||||||
|
HREF="node2.html">The rsync algorithm</A>
|
||||||
|
<LI><A NAME="tex2html8"
|
||||||
|
HREF="node3.html">Rolling checksum</A>
|
||||||
|
<LI><A NAME="tex2html9"
|
||||||
|
HREF="node4.html">Checksum searching</A>
|
||||||
|
<LI><A NAME="tex2html10"
|
||||||
|
HREF="node5.html">Pipelining</A>
|
||||||
|
<LI><A NAME="tex2html11"
|
||||||
|
HREF="node6.html">Results</A>
|
||||||
|
<LI><A NAME="tex2html12"
|
||||||
|
HREF="node7.html">Availability</A>
|
||||||
|
<LI><A NAME="tex2html13"
|
||||||
|
HREF="node8.html">About this document ... </A>
|
||||||
|
</UL>
|
||||||
|
<!--End of Table of Child-Links-->
|
||||||
|
<BR><HR>
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
6
rsync-web/tech_report/labels.pl
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
# Associate labels original text with physical files.
|
||||||
|
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
BIN
rsync-web/tech_report/next.gif
Normal file
|
After Width: | Height: | Size: 172 B |
119
rsync-web/tech_report/node1.html
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>The problem</TITLE>
|
||||||
|
<META NAME="description" CONTENT="The problem">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="next" HREF="node2.html">
|
||||||
|
<LINK REL="previous" HREF="tech_report.html">
|
||||||
|
<LINK REL="up" HREF="tech_report.html">
|
||||||
|
<LINK REL="next" HREF="node2.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html22"
|
||||||
|
HREF="node2.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html20"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html14"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html23"
|
||||||
|
HREF="node2.html">The rsync algorithm</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html21"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html15"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<H1><A NAME="SECTION00010000000000000000">
|
||||||
|
The problem</A>
|
||||||
|
</H1>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Imagine you have two files, <I>A</I> and <I>B</I>, and you wish to update <I>B</I> to be
|
||||||
|
the same as <I>A</I>. The obvious method is to copy <I>A</I> onto <I>B</I>.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Now imagine that the two files are on machines connected by a slow
|
||||||
|
communications link, for example a dial up IP link. If <I>A</I> is large,
|
||||||
|
copying <I>A</I> onto <I>B</I> will be slow. To make it faster you could
|
||||||
|
compress <I>A</I> before sending it, but that will usually only gain a
|
||||||
|
factor of 2 to 4.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Now assume that <I>A</I> and <I>B</I> are quite similar, perhaps both derived
|
||||||
|
from the same original file. To really speed things up you would need
|
||||||
|
to take advantage of this similarity. A common method is to send just
|
||||||
|
the differences between <I>A</I> and <I>B</I> down the link and then use this
|
||||||
|
list of differences to reconstruct the file.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The problem is that the normal methods for creating a set of
|
||||||
|
differences between two files rely on being able to read both files.
|
||||||
|
Thus they require that both files are available beforehand at one end
|
||||||
|
of the link. If they are not both available on the same machine,
|
||||||
|
these algorithms cannot be used (once you had copied the file over,
|
||||||
|
you wouldn't need the differences). This is the problem that rsync
|
||||||
|
addresses.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The rsync algorithm efficiently computes which parts of a source file
|
||||||
|
match some part of an existing destination file. These parts need not
|
||||||
|
be sent across the link; all that is needed is a reference to the part
|
||||||
|
of the destination file. Only parts of the source file which are not
|
||||||
|
matched in this way need to be sent verbatim. The receiver can then
|
||||||
|
construct a copy of the source file using the references to parts of
|
||||||
|
the existing destination file and the verbatim material.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Trivially, the data sent to the receiver can be compressed using any
|
||||||
|
of a range of common compression algorithms, for further speed
|
||||||
|
improvements.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<HR>
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html22"
|
||||||
|
HREF="node2.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html20"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html14"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html23"
|
||||||
|
HREF="node2.html">The rsync algorithm</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html21"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html15"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
183
rsync-web/tech_report/node2.html
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>The rsync algorithm</TITLE>
|
||||||
|
<META NAME="description" CONTENT="The rsync algorithm">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="next" HREF="node3.html">
|
||||||
|
<LINK REL="previous" HREF="node1.html">
|
||||||
|
<LINK REL="up" HREF="tech_report.html">
|
||||||
|
<LINK REL="next" HREF="node3.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html32"
|
||||||
|
HREF="node3.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html30"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html24"
|
||||||
|
HREF="node1.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html33"
|
||||||
|
HREF="node3.html">Rolling checksum</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html31"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html25"
|
||||||
|
HREF="node1.html">The problem</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<H1><A NAME="SECTION00020000000000000000">
|
||||||
|
The rsync algorithm</A>
|
||||||
|
</H1>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Suppose we have two general purpose computers <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
and <IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">.
|
||||||
|
Computer <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
has access to a file <I>A</I> and <IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">
|
||||||
|
has access to
|
||||||
|
file <I>B</I>, where <I>A</I> and <I>B</I> are ``similar''. There is a slow
|
||||||
|
communications link between <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
and <IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The rsync algorithm consists of the following steps:
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<DL COMPACT>
|
||||||
|
<DT>1.
|
||||||
|
<DD><IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">
|
||||||
|
splits the file <I>B</I> into a series of non-overlapping
|
||||||
|
fixed-sized blocks of size S bytes<A NAME="tex2html1"
|
||||||
|
HREF="footnode.html#foot10"><SUP>1</SUP></A>.
|
||||||
|
The last block may be shorter than <I>S</I> bytes.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<DT>2.
|
||||||
|
<DD>For each of these blocks <IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">
|
||||||
|
calculates two checksums:
|
||||||
|
a weak ``rolling'' 32-bit checksum (described below) and a strong
|
||||||
|
128-bit MD4 checksum.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<DT>3.
|
||||||
|
<DD><IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">
|
||||||
|
sends these checksums to <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">.
|
||||||
|
|
||||||
|
<DT>4.
|
||||||
|
<DD><IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
searches through <I>A</I> to find all blocks of length <I>S</I> bytes (at any offset, not just multiples of <I>S</I>) that have the same
|
||||||
|
weak and strong checksum as one of the blocks of <I>B</I>. This can be
|
||||||
|
done in a single pass very quickly using a special property of the
|
||||||
|
rolling checksum described below.
|
||||||
|
|
||||||
|
<DT>5.
|
||||||
|
<DD><IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
sends <IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">
|
||||||
|
a sequence of instructions for
|
||||||
|
constructing a copy of <I>A</I>. Each instruction is either a reference
|
||||||
|
to a block of <I>B</I>, or literal data. Literal data is sent only for
|
||||||
|
those sections of <I>A</I> which did not match any of the blocks of <I>B</I>.
|
||||||
|
</DL>
|
||||||
|
<P>
|
||||||
|
The end result is that <IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">
|
||||||
|
gets a copy of <I>A</I>, but only the pieces
|
||||||
|
of <I>A</I> that are not found in <I>B</I> (plus a small amount of data for
|
||||||
|
checksums and block indexes) are sent over the link. The algorithm
|
||||||
|
also only requires one round trip, which minimises the impact of the
|
||||||
|
link latency.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The most important details of the algorithm are the rolling checksum
|
||||||
|
and the associated multi-alternate search mechanism which allows the
|
||||||
|
all-offsets checksum search to proceed very quickly. These will be
|
||||||
|
discussed in greater detail below.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<HR>
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html32"
|
||||||
|
HREF="node3.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html30"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html24"
|
||||||
|
HREF="node1.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html33"
|
||||||
|
HREF="node3.html">Rolling checksum</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html31"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html25"
|
||||||
|
HREF="node1.html">The problem</A>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
187
rsync-web/tech_report/node3.html
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Rolling checksum</TITLE>
|
||||||
|
<META NAME="description" CONTENT="Rolling checksum">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="next" HREF="node4.html">
|
||||||
|
<LINK REL="previous" HREF="node2.html">
|
||||||
|
<LINK REL="up" HREF="tech_report.html">
|
||||||
|
<LINK REL="next" HREF="node4.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html42"
|
||||||
|
HREF="node4.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html40"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html34"
|
||||||
|
HREF="node2.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html43"
|
||||||
|
HREF="node4.html">Checksum searching</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html41"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html35"
|
||||||
|
HREF="node2.html">The rsync algorithm</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<H1><A NAME="SECTION00030000000000000000">
|
||||||
|
Rolling checksum</A>
|
||||||
|
</H1>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The weak rolling checksum used in the rsync algorithm needs to have
|
||||||
|
the property that it is very cheap to calculate the checksum of a
|
||||||
|
buffer
|
||||||
|
<!-- MATH: $X_2 .. X_{n+1}$ -->
|
||||||
|
<I>X</I><SUB>2</SUB> .. <I>X</I><SUB><I>n</I>+1</SUB> given the checksum of buffer
|
||||||
|
<!-- MATH: $X_1 .. X_n$ -->
|
||||||
|
<I>X</I><SUB>1</SUB> .. <I>X</I><SUB><I>n</I></SUB> and
|
||||||
|
the values of the bytes <I>X</I><SUB>1</SUB> and <I>X</I><SUB><I>n</I>+1</SUB>.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The weak checksum algorithm we used in our implementation was inspired
|
||||||
|
by Mark Adler's adler-32 checksum. Our checksum is defined by
|
||||||
|
<BR><P></P>
|
||||||
|
<DIV ALIGN="CENTER">
|
||||||
|
<!-- MATH: \begin{displaymath}
|
||||||
|
a(k,l) = (\sum_{i=k}^l X_i) \bmod M
|
||||||
|
\end{displaymath} -->
|
||||||
|
|
||||||
|
|
||||||
|
<IMG
|
||||||
|
WIDTH="176" HEIGHT="56"
|
||||||
|
SRC="img3.gif"
|
||||||
|
ALT="\begin{displaymath}a(k,l) = (\sum_{i=k}^l X_i) \bmod M \end{displaymath}">
|
||||||
|
</DIV>
|
||||||
|
<BR CLEAR="ALL">
|
||||||
|
<P></P>
|
||||||
|
<BR><P></P>
|
||||||
|
<DIV ALIGN="CENTER">
|
||||||
|
<!-- MATH: \begin{displaymath}
|
||||||
|
b(k,l) = (\sum_{i=k}^l (l-i+1)X_i) \bmod M
|
||||||
|
\end{displaymath} -->
|
||||||
|
|
||||||
|
|
||||||
|
<IMG
|
||||||
|
WIDTH="240" HEIGHT="56"
|
||||||
|
SRC="img4.gif"
|
||||||
|
ALT="\begin{displaymath}b(k,l) = (\sum_{i=k}^l (l-i+1)X_i) \bmod M \end{displaymath}">
|
||||||
|
</DIV>
|
||||||
|
<BR CLEAR="ALL">
|
||||||
|
<P></P>
|
||||||
|
<BR><P></P>
|
||||||
|
<DIV ALIGN="CENTER">
|
||||||
|
<!-- MATH: \begin{displaymath}
|
||||||
|
s(k,l) = a(k,l) + 2^{16} b(k,l)
|
||||||
|
\end{displaymath} -->
|
||||||
|
|
||||||
|
|
||||||
|
<I>s</I>(<I>k</I>,<I>l</I>) = <I>a</I>(<I>k</I>,<I>l</I>) + 2<SUP>16</SUP> <I>b</I>(<I>k</I>,<I>l</I>)
|
||||||
|
</DIV>
|
||||||
|
<BR CLEAR="ALL">
|
||||||
|
<P></P>
|
||||||
|
<P>
|
||||||
|
where <I>s</I>(<I>k</I>,<I>l</I>) is the rolling checksum of the bytes
|
||||||
|
<!-- MATH: $X_k \ldots X_l$ -->
|
||||||
|
<IMG
|
||||||
|
WIDTH="67" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img5.gif"
|
||||||
|
ALT="$X_k \ldots X_l$">.
|
||||||
|
For simplicity and speed, we use
|
||||||
|
<!-- MATH: $M = 2^{16}$ -->
|
||||||
|
<I>M</I> = 2<SUP>16</SUP>.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The important property of this checksum is that successive values can
|
||||||
|
be computed very efficiently using the recurrence relations
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<BR><P></P>
|
||||||
|
<DIV ALIGN="CENTER">
|
||||||
|
<!-- MATH: \begin{displaymath}
|
||||||
|
a(k+1,l+1) = (a(k,l) - X_k + X_{l+1}) \bmod M
|
||||||
|
\end{displaymath} -->
|
||||||
|
|
||||||
|
|
||||||
|
<IMG
|
||||||
|
WIDTH="322" HEIGHT="28"
|
||||||
|
SRC="img6.gif"
|
||||||
|
ALT="\begin{displaymath}a(k+1,l+1) = (a(k,l) - X_k + X_{l+1}) \bmod M \end{displaymath}">
|
||||||
|
</DIV>
|
||||||
|
<BR CLEAR="ALL">
|
||||||
|
<P></P>
|
||||||
|
<BR><P></P>
|
||||||
|
<DIV ALIGN="CENTER">
|
||||||
|
<!-- MATH: \begin{displaymath}
|
||||||
|
b(k+1,l+1) = (b(k,l) - (l-k+1) X_k + a(k+1,l+1)) \bmod M
|
||||||
|
\end{displaymath} -->
|
||||||
|
|
||||||
|
|
||||||
|
<IMG
|
||||||
|
WIDTH="454" HEIGHT="28"
|
||||||
|
SRC="img7.gif"
|
||||||
|
ALT="\begin{displaymath}b(k+1,l+1) = (b(k,l) - (l-k+1) X_k + a(k+1,l+1)) \bmod M \end{displaymath}">
|
||||||
|
</DIV>
|
||||||
|
<BR CLEAR="ALL">
|
||||||
|
<P></P>
|
||||||
|
<P>
|
||||||
|
Thus the checksum can be calculated for blocks of length S at all
|
||||||
|
possible offsets within a file in a ``rolling'' fashion, with very
|
||||||
|
little computation at each point.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Despite its simplicity, this checksum was found to be quite adequate as
|
||||||
|
a first level check for a match of two file blocks. We have found in
|
||||||
|
practice that the probability of this checksum matching when the
|
||||||
|
blocks are not equal is quite low. This is important because the much
|
||||||
|
more expensive strong checksum must be calculated for each block where
|
||||||
|
the weak checksum matches.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<HR>
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html42"
|
||||||
|
HREF="node4.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html40"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html34"
|
||||||
|
HREF="node2.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html43"
|
||||||
|
HREF="node4.html">Checksum searching</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html41"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html35"
|
||||||
|
HREF="node2.html">The rsync algorithm</A>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
145
rsync-web/tech_report/node4.html
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Checksum searching</TITLE>
|
||||||
|
<META NAME="description" CONTENT="Checksum searching">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="next" HREF="node5.html">
|
||||||
|
<LINK REL="previous" HREF="node3.html">
|
||||||
|
<LINK REL="up" HREF="tech_report.html">
|
||||||
|
<LINK REL="next" HREF="node5.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html52"
|
||||||
|
HREF="node5.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html50"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html44"
|
||||||
|
HREF="node3.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html53"
|
||||||
|
HREF="node5.html">Pipelining</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html51"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html45"
|
||||||
|
HREF="node3.html">Rolling checksum</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<H1><A NAME="SECTION00040000000000000000">
|
||||||
|
Checksum searching</A>
|
||||||
|
</H1>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Once <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
has received the list of checksums of the blocks of <I>B</I>,
|
||||||
|
it must search <I>A</I> for any blocks at any offset that match the
|
||||||
|
checksum of some block of <I>B</I>. The basic strategy is to compute the
|
||||||
|
32-bit rolling checksum for a block of length <I>S</I> starting at each
|
||||||
|
byte of <I>A</I> in turn, and for each checksum, search the list for a
|
||||||
|
match. To do this our implementation uses a
|
||||||
|
simple 3 level searching scheme.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The first level uses a 16-bit hash of the 32-bit rolling checksum and
|
||||||
|
a 2<SUP>16</SUP> entry hash table. The list of checksum values (i.e., the
|
||||||
|
checksums from the blocks of <I>B</I>) is sorted according to the 16-bit
|
||||||
|
hash of the 32-bit rolling checksum. Each entry in the hash table
|
||||||
|
points to the first element of the list for that hash value, or
|
||||||
|
contains a null value if no element of the list has that hash value.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
At each offset in the file the 32-bit rolling checksum and its 16-bit
|
||||||
|
hash are calculated. If the hash table entry for that hash value is
|
||||||
|
not a null value, the second level check is invoked.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The second level check involves scanning the sorted checksum list
|
||||||
|
starting with the entry pointed to by the hash table entry, looking
|
||||||
|
for an entry whose 32-bit rolling checksum matches the current value.
|
||||||
|
The scan terminates when it reaches an entry whose 16-bit hash
|
||||||
|
differs. If this search finds a match, the third level check is
|
||||||
|
invoked.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The third level check involves calculating the strong checksum for the
|
||||||
|
current offset in the file and comparing it with the strong checksum
|
||||||
|
value in the current list entry. If the two strong checksums match,
|
||||||
|
we assume that we have found a block of <I>A</I> which matches a block of
|
||||||
|
<I>B</I>. In fact the blocks could be different, but the probability of
|
||||||
|
this is microscopic, and in practice this is a reasonable assumption.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
When a match is found, <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
sends <IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">
|
||||||
|
the data in <I>A</I> between
|
||||||
|
the current file offset and the end of the previous match, followed by
|
||||||
|
the index of the block in <I>B</I> that matched. This data is sent
|
||||||
|
immediately a match is found, which allows us to overlap the
|
||||||
|
communication with further computation.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
If no match is found at a given offset in the file, the rolling
|
||||||
|
checksum is updated to the next offset and the search proceeds. If a
|
||||||
|
match is found, the search is restarted at the end of the matched
|
||||||
|
block. This strategy saves a considerable amount of computation for
|
||||||
|
the common case where the two files are nearly identical. In
|
||||||
|
addition, it would be a simple matter to encode the block indexes as
|
||||||
|
runs, for the common case where a portion of <I>A</I> matches a series of
|
||||||
|
blocks of <I>B</I> in order.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<HR>
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html52"
|
||||||
|
HREF="node5.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html50"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html44"
|
||||||
|
HREF="node3.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html53"
|
||||||
|
HREF="node5.html">Pipelining</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html51"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html45"
|
||||||
|
HREF="node3.html">Rolling checksum</A>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
85
rsync-web/tech_report/node5.html
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Pipelining</TITLE>
|
||||||
|
<META NAME="description" CONTENT="Pipelining">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="next" HREF="node6.html">
|
||||||
|
<LINK REL="previous" HREF="node4.html">
|
||||||
|
<LINK REL="up" HREF="tech_report.html">
|
||||||
|
<LINK REL="next" HREF="node6.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html62"
|
||||||
|
HREF="node6.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html60"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html54"
|
||||||
|
HREF="node4.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html63"
|
||||||
|
HREF="node6.html">Results</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html61"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html55"
|
||||||
|
HREF="node4.html">Checksum searching</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<H1><A NAME="SECTION00050000000000000000">
|
||||||
|
Pipelining</A>
|
||||||
|
</H1>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The above sections describe the process for constructing a copy of one
|
||||||
|
file on a remote system. If we have a several files to copy, we can
|
||||||
|
gain a considerable latency advantage by pipelining the process.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
This involves <IMG
|
||||||
|
WIDTH="14" HEIGHT="29" ALIGN="MIDDLE" BORDER="0"
|
||||||
|
SRC="img2.gif"
|
||||||
|
ALT="$\beta$">
|
||||||
|
initiating two independent processes. One of the
|
||||||
|
processes generates and sends the checksums to <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
while the
|
||||||
|
other receives the difference information from <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
and
|
||||||
|
reconstructs the files.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
If the communications link is buffered then these two processes can
|
||||||
|
proceed independently and the link should be kept fully utilised in
|
||||||
|
both directions for most of the time.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<BR><HR>
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
299
rsync-web/tech_report/node6.html
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Results</TITLE>
|
||||||
|
<META NAME="description" CONTENT="Results">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="next" HREF="node7.html">
|
||||||
|
<LINK REL="previous" HREF="node5.html">
|
||||||
|
<LINK REL="up" HREF="tech_report.html">
|
||||||
|
<LINK REL="next" HREF="node7.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html72"
|
||||||
|
HREF="node7.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html70"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html64"
|
||||||
|
HREF="node5.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html73"
|
||||||
|
HREF="node7.html">Availability</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html71"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html65"
|
||||||
|
HREF="node5.html">Pipelining</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<H1><A NAME="SECTION00060000000000000000">
|
||||||
|
Results</A>
|
||||||
|
</H1>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
To test the algorithm, tar files were created of the Linux kernel
|
||||||
|
sources for two versions of the kernel. The two kernel versions were
|
||||||
|
1.99.10 and 2.0.0. These tar files are approximately 24MB in size and
|
||||||
|
are separated by 5 released patch levels.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Out of the 2441 files in the 1.99.10 release, 291 files had changed in
|
||||||
|
the 2.0.0 release, 19 files had been removed and 25 files had been
|
||||||
|
added.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
A ``diff'' of the two tar files using the standard GNU diff utility
|
||||||
|
produced over 32 thousand lines of output totalling 2.1 MB.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The following table shows the results for rsync between the two files
|
||||||
|
with a varying block size.<A NAME="tex2html2"
|
||||||
|
HREF="footnode.html#foot24"><SUP>2</SUP></A>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<TABLE CELLPADDING=3 BORDER="1">
|
||||||
|
<TR><TD ALIGN="LEFT"><B> block</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> matches</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> tag</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> false</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> data</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> written</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> read</B></TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT"><B> size</B></TD>
|
||||||
|
<TD ALIGN="LEFT"> </TD>
|
||||||
|
<TD ALIGN="LEFT"><B> hits</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> alarms</B></TD>
|
||||||
|
<TD ALIGN="LEFT"> </TD>
|
||||||
|
<TD ALIGN="LEFT"> </TD>
|
||||||
|
<TD ALIGN="LEFT"> </TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT"><P>
|
||||||
|
300</TD>
|
||||||
|
<TD ALIGN="LEFT">64247</TD>
|
||||||
|
<TD ALIGN="LEFT">3817434</TD>
|
||||||
|
<TD ALIGN="LEFT">948</TD>
|
||||||
|
<TD ALIGN="LEFT">5312200</TD>
|
||||||
|
<TD ALIGN="LEFT">5629158</TD>
|
||||||
|
<TD ALIGN="LEFT">1632284</TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT">500</TD>
|
||||||
|
<TD ALIGN="LEFT">46989</TD>
|
||||||
|
<TD ALIGN="LEFT">620013</TD>
|
||||||
|
<TD ALIGN="LEFT">64</TD>
|
||||||
|
<TD ALIGN="LEFT">1091900</TD>
|
||||||
|
<TD ALIGN="LEFT">1283906</TD>
|
||||||
|
<TD ALIGN="LEFT">979384</TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT">700</TD>
|
||||||
|
<TD ALIGN="LEFT">33255</TD>
|
||||||
|
<TD ALIGN="LEFT">571970</TD>
|
||||||
|
<TD ALIGN="LEFT">22</TD>
|
||||||
|
<TD ALIGN="LEFT">1307800</TD>
|
||||||
|
<TD ALIGN="LEFT">1444346</TD>
|
||||||
|
<TD ALIGN="LEFT">699564</TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT">900</TD>
|
||||||
|
<TD ALIGN="LEFT">25686</TD>
|
||||||
|
<TD ALIGN="LEFT">525058</TD>
|
||||||
|
<TD ALIGN="LEFT">24</TD>
|
||||||
|
<TD ALIGN="LEFT">1469500</TD>
|
||||||
|
<TD ALIGN="LEFT">1575438</TD>
|
||||||
|
<TD ALIGN="LEFT">544124</TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT">1100</TD>
|
||||||
|
<TD ALIGN="LEFT">20848</TD>
|
||||||
|
<TD ALIGN="LEFT">496844</TD>
|
||||||
|
<TD ALIGN="LEFT">21</TD>
|
||||||
|
<TD ALIGN="LEFT">1654500</TD>
|
||||||
|
<TD ALIGN="LEFT">1740838</TD>
|
||||||
|
<TD ALIGN="LEFT">445204</TD>
|
||||||
|
</TR>
|
||||||
|
</TABLE>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
In each case, the CPU time taken was less than the
|
||||||
|
time it takes to run ``diff'' on the two files.<A NAME="tex2html3"
|
||||||
|
HREF="footnode.html#foot40"><SUP>3</SUP></A>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The columns in the table are as follows:
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<DL>
|
||||||
|
<DT><STRONG>block size</STRONG>
|
||||||
|
<DD>The size in bytes of the checksummed blocks.
|
||||||
|
<DT><STRONG>matches</STRONG>
|
||||||
|
<DD>The number of times a block of <I>B</I> was found in <I>A</I>.
|
||||||
|
<DT><STRONG>tag hits</STRONG>
|
||||||
|
<DD>The number of times the 16 bit hash of the rolling
|
||||||
|
checksum matched a hash of one of the checksums from <I>B</I>.
|
||||||
|
<DT><STRONG>false alarms</STRONG>
|
||||||
|
<DD>The number of times the 32 bit rolling checksum
|
||||||
|
matched but the strong checksum didn't.
|
||||||
|
<DT><STRONG>data</STRONG>
|
||||||
|
<DD>The amount of file data transferred verbatim, in bytes.
|
||||||
|
<DT><STRONG>written</STRONG>
|
||||||
|
<DD>The total number of bytes written by <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
including protocol overheads. This is almost all file data.
|
||||||
|
<DT><STRONG>read</STRONG>
|
||||||
|
<DD>The total number of bytes read by <IMG
|
||||||
|
WIDTH="15" HEIGHT="13" ALIGN="BOTTOM" BORDER="0"
|
||||||
|
SRC="img1.gif"
|
||||||
|
ALT="$\alpha$">
|
||||||
|
including
|
||||||
|
protocol overheads. This is almost all checksum information.
|
||||||
|
</DL>
|
||||||
|
<P>
|
||||||
|
The results demonstrate that for block sizes above 300 bytes, only a
|
||||||
|
small fraction (around 5%) of the file was transferred. The amount
|
||||||
|
transferred was also considerably less than the size of the diff file
|
||||||
|
that would have been transferred if the diff/patch method of updating
|
||||||
|
a remote file was used.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The checksums themselves took up a considerable amount of space,
|
||||||
|
although much less than the size of the data transferred in each
|
||||||
|
case. Each pair of checksums consumes 20 bytes: 4 bytes for the
|
||||||
|
rolling checksum plus 16 bytes for the 128-bit MD4 checksum.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The number of false alarms was less than 1/1000 of the number of
|
||||||
|
true matches, indicating that the 32 bit rolling checksum is quite
|
||||||
|
good at screening out false matches.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The number of tag hits indicates that the second level of the
|
||||||
|
checksum search algorithm was invoked about once every 50
|
||||||
|
characters. This is quite high because the total number of blocks in
|
||||||
|
the file is a large fraction of the size of the tag hash table. For
|
||||||
|
smaller files we would expect the tag hit rate to be much closer to
|
||||||
|
the number of matches. For extremely large files, we should probably
|
||||||
|
increase the size of the hash table.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
The next table shows similar results for a much smaller set of files.
|
||||||
|
In this case the files were not packed into a tar file first. Rather,
|
||||||
|
rsync was invoked with an option to recursively descend the directory
|
||||||
|
tree. The files used were from two source releases of another software
|
||||||
|
package called Samba. The total source code size is 1.7 MB and the
|
||||||
|
diff between the two releases is 4155 lines long totalling 120 kB.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<TABLE CELLPADDING=3 BORDER="1">
|
||||||
|
<TR><TD ALIGN="LEFT"><B> block</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> matches</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> tag</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> false</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> data</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> written</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> read</B></TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT"><B> size</B></TD>
|
||||||
|
<TD ALIGN="LEFT"> </TD>
|
||||||
|
<TD ALIGN="LEFT"><B> hits</B></TD>
|
||||||
|
<TD ALIGN="LEFT"><B> alarms</B></TD>
|
||||||
|
<TD ALIGN="LEFT"> </TD>
|
||||||
|
<TD ALIGN="LEFT"> </TD>
|
||||||
|
<TD ALIGN="LEFT"> </TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT"><P>
|
||||||
|
300</TD>
|
||||||
|
<TD ALIGN="LEFT">3727</TD>
|
||||||
|
<TD ALIGN="LEFT">3899</TD>
|
||||||
|
<TD ALIGN="LEFT">0</TD>
|
||||||
|
<TD ALIGN="LEFT">129775</TD>
|
||||||
|
<TD ALIGN="LEFT">153999</TD>
|
||||||
|
<TD ALIGN="LEFT">83948</TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT">500</TD>
|
||||||
|
<TD ALIGN="LEFT">2158</TD>
|
||||||
|
<TD ALIGN="LEFT">2325</TD>
|
||||||
|
<TD ALIGN="LEFT">0</TD>
|
||||||
|
<TD ALIGN="LEFT">171574</TD>
|
||||||
|
<TD ALIGN="LEFT">189330</TD>
|
||||||
|
<TD ALIGN="LEFT">50908</TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT">700</TD>
|
||||||
|
<TD ALIGN="LEFT">1517</TD>
|
||||||
|
<TD ALIGN="LEFT">1649</TD>
|
||||||
|
<TD ALIGN="LEFT">0</TD>
|
||||||
|
<TD ALIGN="LEFT">195024</TD>
|
||||||
|
<TD ALIGN="LEFT">210144</TD>
|
||||||
|
<TD ALIGN="LEFT">36828</TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT">900</TD>
|
||||||
|
<TD ALIGN="LEFT">1156</TD>
|
||||||
|
<TD ALIGN="LEFT">1281</TD>
|
||||||
|
<TD ALIGN="LEFT">0</TD>
|
||||||
|
<TD ALIGN="LEFT">222847</TD>
|
||||||
|
<TD ALIGN="LEFT">236471</TD>
|
||||||
|
<TD ALIGN="LEFT">29048</TD>
|
||||||
|
</TR>
|
||||||
|
<TR><TD ALIGN="LEFT">1100</TD>
|
||||||
|
<TD ALIGN="LEFT">921</TD>
|
||||||
|
<TD ALIGN="LEFT">1049</TD>
|
||||||
|
<TD ALIGN="LEFT">0</TD>
|
||||||
|
<TD ALIGN="LEFT">250073</TD>
|
||||||
|
<TD ALIGN="LEFT">262725</TD>
|
||||||
|
<TD ALIGN="LEFT">23988</TD>
|
||||||
|
</TR>
|
||||||
|
</TABLE>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<HR>
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html72"
|
||||||
|
HREF="node7.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html70"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html64"
|
||||||
|
HREF="node5.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html73"
|
||||||
|
HREF="node7.html">Availability</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html71"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html65"
|
||||||
|
HREF="node5.html">Pipelining</A>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
62
rsync-web/tech_report/node7.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>Availability</TITLE>
|
||||||
|
<META NAME="description" CONTENT="Availability">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="next" HREF="node8.html">
|
||||||
|
<LINK REL="previous" HREF="node6.html">
|
||||||
|
<LINK REL="up" HREF="tech_report.html">
|
||||||
|
<LINK REL="next" HREF="node8.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html82"
|
||||||
|
HREF="node8.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<A NAME="tex2html80"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html74"
|
||||||
|
HREF="node6.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html83"
|
||||||
|
HREF="node8.html">About this document ...</A>
|
||||||
|
<B> Up:</B> <A NAME="tex2html81"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html75"
|
||||||
|
HREF="node6.html">Results</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<H1><A NAME="SECTION00070000000000000000">
|
||||||
|
Availability</A>
|
||||||
|
</H1>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
An implementation of rsync which provides a convenient interface
|
||||||
|
similar to the common UNIX command rcp has been written and is
|
||||||
|
available for download from ftp://rsync.samba.org/pub/rsync.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<BR><HR>
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
61
rsync-web/tech_report/node8.html
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>About this document ... </TITLE>
|
||||||
|
<META NAME="description" CONTENT="About this document ... ">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="previous" HREF="node7.html">
|
||||||
|
<LINK REL="up" HREF="tech_report.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif">
|
||||||
|
<A NAME="tex2html88"
|
||||||
|
HREF="tech_report.html">
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif"></A>
|
||||||
|
<A NAME="tex2html84"
|
||||||
|
HREF="node7.html">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif"></A>
|
||||||
|
<BR>
|
||||||
|
<B> Up:</B> <A NAME="tex2html89"
|
||||||
|
HREF="tech_report.html">The rsync algorithm</A>
|
||||||
|
<B> Previous:</B> <A NAME="tex2html85"
|
||||||
|
HREF="node7.html">Availability</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<H1><A NAME="SECTION00080000000000000000">
|
||||||
|
About this document ... </A>
|
||||||
|
</H1>
|
||||||
|
<STRONG>The rsync algorithm</STRONG><P>
|
||||||
|
This document was generated using the
|
||||||
|
<A HREF="http://www-dsed.llnl.gov/files/programs/unix/latex2html/manual/"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A> translator Version 98.1p1 release (March 2nd, 1998)
|
||||||
|
<P>
|
||||||
|
Copyright © 1993, 1994, 1995, 1996, 1997,
|
||||||
|
<A HREF="http://cbl.leeds.ac.uk/nikos/personal.html">Nikos Drakos</A>,
|
||||||
|
Computer Based Learning Unit, University of Leeds.
|
||||||
|
<P>
|
||||||
|
The command line arguments were: <BR>
|
||||||
|
<STRONG>latex2html</STRONG> <tt>tech_report.tex</tt>.
|
||||||
|
<P>
|
||||||
|
The translation was initiated by Andrew Tridgell on 1998-11-09
|
||||||
|
<BR><HR>
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
BIN
rsync-web/tech_report/previous.gif
Normal file
|
After Width: | Height: | Size: 220 B |
19
rsync-web/tech_report/tech_report.css
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */
|
||||||
|
.MATH { font-family: "Century Schoolbook", serif; }
|
||||||
|
.MATH I { font-family: "Century Schoolbook", serif; font-weight: bold }
|
||||||
|
.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold }
|
||||||
|
|
||||||
|
/* implement both fixed-size and relative sizes */
|
||||||
|
SMALL.XTINY { font-size : xx-small }
|
||||||
|
SMALL.TINY { font-size : x-small }
|
||||||
|
SMALL.SCRIPTSIZE { font-size : smaller }
|
||||||
|
SMALL.FOOTNOTESIZE { font-size : small }
|
||||||
|
SMALL.SMALL { }
|
||||||
|
BIG.LARGE { }
|
||||||
|
BIG.XLARGE { font-size : large }
|
||||||
|
BIG.XXLARGE { font-size : x-large }
|
||||||
|
BIG.HUGE { font-size : larger }
|
||||||
|
BIG.XHUGE { font-size : xx-large }
|
||||||
|
|
||||||
|
/* document-specific styles come next */
|
||||||
94
rsync-web/tech_report/tech_report.html
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<!--Converted with LaTeX2HTML 98.1p1 release (March 2nd, 1998)
|
||||||
|
originally by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds
|
||||||
|
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
|
||||||
|
* with significant contributions from:
|
||||||
|
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>The rsync algorithm</TITLE>
|
||||||
|
<META NAME="description" CONTENT="The rsync algorithm">
|
||||||
|
<META NAME="keywords" CONTENT="tech_report">
|
||||||
|
<META NAME="resource-type" CONTENT="document">
|
||||||
|
<META NAME="distribution" CONTENT="global">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
<LINK REL="STYLESHEET" HREF="tech_report.css">
|
||||||
|
<LINK REL="next" HREF="node1.html">
|
||||||
|
</HEAD>
|
||||||
|
<BODY >
|
||||||
|
<!--Navigation Panel-->
|
||||||
|
<A NAME="tex2html4"
|
||||||
|
HREF="node1.html">
|
||||||
|
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next"
|
||||||
|
SRC="next.gif"></A>
|
||||||
|
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up"
|
||||||
|
SRC="up.gif">
|
||||||
|
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous"
|
||||||
|
SRC="previous.gif">
|
||||||
|
<BR>
|
||||||
|
<B> Next:</B> <A NAME="tex2html5"
|
||||||
|
HREF="node1.html">The problem</A>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<!--End of Navigation Panel-->
|
||||||
|
|
||||||
|
<P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<H1 ALIGN="CENTER">The rsync algorithm</H1>
|
||||||
|
<P ALIGN="CENTER"><STRONG>Andrew Tridgell Paul Mackerras
|
||||||
|
<BR>
|
||||||
|
Department of Computer Science <BR>
|
||||||
|
Australian National University <BR>
|
||||||
|
Canberra, ACT 0200, Australia</STRONG></P>
|
||||||
|
<P ALIGN="LEFT"></P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
|
||||||
|
<H3>Abstract:</H3>
|
||||||
|
<DIV>
|
||||||
|
This report presents an algorithm for updating a file on one machine
|
||||||
|
to be identical to a file on another machine. We assume that the
|
||||||
|
two machines are connected by a low-bandwidth high-latency
|
||||||
|
bi-directional communications link. The algorithm identifies parts
|
||||||
|
of the source file which are identical to some part of the
|
||||||
|
destination file, and only sends those parts which cannot be matched
|
||||||
|
in this way. Effectively, the algorithm computes a set of
|
||||||
|
differences without having both files on the same machine. The
|
||||||
|
algorithm works best when the files are similar, but will also
|
||||||
|
function correctly and reasonably efficiently when the files are
|
||||||
|
quite different.
|
||||||
|
</DIV>
|
||||||
|
<P>
|
||||||
|
<P>
|
||||||
|
<BR><HR>
|
||||||
|
<!--Table of Child-Links-->
|
||||||
|
<A NAME="CHILD_LINKS"> </A>
|
||||||
|
<UL>
|
||||||
|
<LI><A NAME="tex2html6"
|
||||||
|
HREF="node1.html">The problem</A>
|
||||||
|
<LI><A NAME="tex2html7"
|
||||||
|
HREF="node2.html">The rsync algorithm</A>
|
||||||
|
<LI><A NAME="tex2html8"
|
||||||
|
HREF="node3.html">Rolling checksum</A>
|
||||||
|
<LI><A NAME="tex2html9"
|
||||||
|
HREF="node4.html">Checksum searching</A>
|
||||||
|
<LI><A NAME="tex2html10"
|
||||||
|
HREF="node5.html">Pipelining</A>
|
||||||
|
<LI><A NAME="tex2html11"
|
||||||
|
HREF="node6.html">Results</A>
|
||||||
|
<LI><A NAME="tex2html12"
|
||||||
|
HREF="node7.html">Availability</A>
|
||||||
|
<LI><A NAME="tex2html13"
|
||||||
|
HREF="node8.html">About this document ... </A>
|
||||||
|
</UL>
|
||||||
|
<!--End of Table of Child-Links-->
|
||||||
|
<BR><HR>
|
||||||
|
<ADDRESS>
|
||||||
|
<I>Andrew Tridgell</I>
|
||||||
|
<BR><I>1998-11-09</I>
|
||||||
|
</ADDRESS>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
||||||
BIN
rsync-web/tech_report/up.gif
Normal file
|
After Width: | Height: | Size: 145 B |
35
rsync-web/vger.txt
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
The vger.rutgers.edu cvs tree is mirrored onto cvs.samba.org via
|
||||||
|
anonymous rsync using the following script.
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd /var/www/cvs/vger/
|
||||||
|
PATH=/usr/local/bin:/usr/freeware/bin:/usr/bin:/bin
|
||||||
|
|
||||||
|
RUN=`lps x | grep rsync | grep -v grep | wc -l`
|
||||||
|
if [ "$RUN" -gt 0 ]; then
|
||||||
|
echo already running
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
rsync -az vger.rutgers.edu::cvs/CVSROOT/ChangeLog $HOME/ChangeLog
|
||||||
|
|
||||||
|
sum1=`sum $HOME/ChangeLog`
|
||||||
|
sum2=`sum /var/www/cvs/vger/CVSROOT/ChangeLog`
|
||||||
|
|
||||||
|
if [ "$sum1" = "$sum2" ]; then
|
||||||
|
echo nothing to do
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
rsync -az --delete --force vger.rutgers.edu::cvs/ /var/www/cvs/vger/
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
Note in particular the initial rsync of the ChangeLog to determine if
|
||||||
|
anything has changed. This could be omitted but it would mean that the
|
||||||
|
rsyncd on vger would have to build a complete listing of the cvs area
|
||||||
|
at each run. As most of the time nothing will have changed I wanted to
|
||||||
|
save the time on vger by only doing a full rsync if the ChangeLog has
|
||||||
|
changed. This helped quite a lot because vger is low on memory and
|
||||||
|
generally quite heavily loaded, so doing a listing on such a large
|
||||||
|
tree every hour would have been excessive.
|
||||||
110
rsync-web/win95.txt
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
Compiling rsync for MS Windows 95
|
||||||
|
=================================
|
||||||
|
|
||||||
|
Caveat:
|
||||||
|
There are no doubt other ways to do this, but I have not tried them.
|
||||||
|
|
||||||
|
This will produce an rsync binary which runs under win95/NT which can _send_
|
||||||
|
data to a UNIX rsync host but not receive. This is suitable for my requirements
|
||||||
|
as I am backing up a bunch of win95 machines to a linux server, but it may
|
||||||
|
not be what _you_ require.
|
||||||
|
|
||||||
|
NOTE: I am now told (by patl@curl.com) that receiving as well as
|
||||||
|
sending works with the current cygwin32 toolkit.
|
||||||
|
|
||||||
|
|
||||||
|
Step 1. Get the Cygnus development kit
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
If you do not already know about this wonderful project undertaken by cygnus,
|
||||||
|
grab the latest copy of the gnu-win32 runtime system from
|
||||||
|
|
||||||
|
http://www.cygnus.com/misc/gnu-win32/
|
||||||
|
|
||||||
|
You will want the CDK-B19.EXE self-installing binary (be warned - it's 12M
|
||||||
|
in size) which contains gcc+binutils+DLLs required by the system. Read the
|
||||||
|
instructions about this and install it. You will then have something which
|
||||||
|
looks _very_ close to a UNIX box as far as any UNIX software ic concerned.
|
||||||
|
|
||||||
|
Also grab the updated version (B19.1) of the DLL as this fixes some problems
|
||||||
|
(it's pretty small at ~190k).
|
||||||
|
|
||||||
|
Take a bit of time to play with this stuff - have a look at the registry
|
||||||
|
entries that define mount points etc so you know where/how your windows
|
||||||
|
directories are mapped.
|
||||||
|
|
||||||
|
Step 2. Compile rsync
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Once the magic BASH$ prompt appears in your cygnus dos box, you can download
|
||||||
|
and compile rsync right out of the box. You might want to do this:
|
||||||
|
|
||||||
|
tar xvzf rsync-2.0.17.tar.gz (or whatever version...)
|
||||||
|
cd rsync-2.0.17
|
||||||
|
chmod +x configure (exec is not set automatically)
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
|
||||||
|
and you will have a working RSYNC.EXE
|
||||||
|
|
||||||
|
Before you can do a "make install" you must edit the Makefile so that
|
||||||
|
it knows about "rsync.exe" rather than "rsync".
|
||||||
|
|
||||||
|
Step 3 (optional) - compile and install SSH
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
If you want to use ssh as the transport then you better grab a copy and compile
|
||||||
|
it - again, no surprises. It compiles ok under gnuwin32, and you can generate
|
||||||
|
keys etc in the normal way.
|
||||||
|
|
||||||
|
Problems
|
||||||
|
--------
|
||||||
|
|
||||||
|
Well, it _almost_ works seamlessly. Here are a couple of problems I have
|
||||||
|
encountered so far - I do not know why these symptoms occur, and they are
|
||||||
|
probably nothing to do with rsync, but if you follow this course then you
|
||||||
|
will probably run into these things also...
|
||||||
|
|
||||||
|
1. rsync will not _receive_ data onto a windows box. It seems to do everything
|
||||||
|
ok, but then hangs at the last step and no files actually appear. When
|
||||||
|
transferring via my modem, I can see data being received, but it never
|
||||||
|
appears in my directory.
|
||||||
|
|
||||||
|
NOTE: This now appears to be fixed.
|
||||||
|
|
||||||
|
2. rsync, ssh and other gnuwin32-compiled programs can be called directly from
|
||||||
|
a DOS prompt, but argument passing seems to be broken. This means that
|
||||||
|
starting SSH directly is difficult.
|
||||||
|
|
||||||
|
After a bit of experimenting I found a workaround, which is not pretty
|
||||||
|
but worked for me :-)
|
||||||
|
|
||||||
|
Lets say you want to call ssh from a normal DOS prompt. Set up a batch
|
||||||
|
file called "SSH.BAT" which sets up the cygnus environment and calls bash
|
||||||
|
with the argument "ssh.sh %1 %2 %3 %4 %5 %6 %7 %8 %9". You can copy the
|
||||||
|
cygnus.bat file and use it as a template if you like. here is my ssh.bat:
|
||||||
|
|
||||||
|
|
||||||
|
@ECHO OFF
|
||||||
|
SET TERM=ansi
|
||||||
|
SET MAKE_MODE=unix
|
||||||
|
SET CYGFS=e:/apps/cygnus
|
||||||
|
SET GCC_EXEC_PREFIX=/lib\gcc-lib\
|
||||||
|
SET TCL_LIBRARY=%CYGROOT%\share\tcl8.0\
|
||||||
|
SET HOME=/home/awesley
|
||||||
|
SET GDBTK_LIBRARY=%CYGFS%/share/gdbtcl
|
||||||
|
bash /scripts/ssh.sh %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||||
|
|
||||||
|
|
||||||
|
Create a shell script called ssh.sh containing:
|
||||||
|
|
||||||
|
/usr/local/bin/ssh $*
|
||||||
|
|
||||||
|
which is then run by bash and calls the ssh binary (wherever you have
|
||||||
|
installed it).
|
||||||
|
|
||||||
|
I suspect that there is a better way, but I have not yet had time to
|
||||||
|
look for it.
|
||||||
|
|
||||||
|
|
||||||
|
Cheers, Anthony Wesley
|
||||||
24
rsync-web/y2k.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>rsync y2k issues</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<!--#include virtual="header.html" -->
|
||||||
|
|
||||||
|
<H2 align="center">Year 2000 Issues</H2>
|
||||||
|
|
||||||
|
We are starting to get a lot of Y2K compliance questions. The answer
|
||||||
|
is that rsync has no Y2K problems. rsync uses 32 bit "seconds since
|
||||||
|
1970" date formats and thus has no problems with the turn of the
|
||||||
|
century.<p>
|
||||||
|
|
||||||
|
You must remember though that rsync is part of a larger system. It
|
||||||
|
relies on a transport mechanism (rsh, ssh etc) and many operating
|
||||||
|
systems services (such as inetd, syslog etc). If any of these other
|
||||||
|
parts fail then rsync will of course be affected.<p>
|
||||||
|
|
||||||
|
Also remember that rsync comes with absolutely no warranty. It is up
|
||||||
|
to you to test whether rsync is suitable in your computing environment,
|
||||||
|
both before and after the turn of the century.
|
||||||
|
|
||||||
|
<!--#include virtual="footer.html" -->
|
||||||
85
runtests.py
@@ -61,6 +61,12 @@ def parse_args():
|
|||||||
help='Force protocol version (adds --protocol=VER to rsync)')
|
help='Force protocol version (adds --protocol=VER to rsync)')
|
||||||
p.add_argument('--expect-skipped', default=None, metavar='LIST',
|
p.add_argument('--expect-skipped', default=None, metavar='LIST',
|
||||||
help='Comma-separated list of expected-skipped tests')
|
help='Comma-separated list of expected-skipped tests')
|
||||||
|
p.add_argument('--use-tcp', action='store_true',
|
||||||
|
help='Run daemon tests against a real rsyncd bound to '
|
||||||
|
'127.0.0.1 (non-default). The default is the secure '
|
||||||
|
'stdio-pipe transport, which opens no listening '
|
||||||
|
'socket; --use-tcp exposes a loopback port for the '
|
||||||
|
'duration of each daemon test.')
|
||||||
return p.parse_args()
|
return p.parse_args()
|
||||||
|
|
||||||
|
|
||||||
@@ -151,17 +157,47 @@ def prep_scratch(scratchdir, srcdir, tooldir, setfacl_nodef):
|
|||||||
os.symlink(os.path.join(tooldir, srcdir), src_link)
|
os.symlink(os.path.join(tooldir, srcdir), src_link)
|
||||||
|
|
||||||
|
|
||||||
|
# Python tests are identified by a positive "_test.py" suffix so that
|
||||||
|
# helper modules (e.g. rsyncfns.py) sit in testsuite/ without being mistaken
|
||||||
|
# for tests.
|
||||||
|
_PY_TEST_SUFFIX = '_test.py'
|
||||||
|
|
||||||
|
|
||||||
|
def _is_test_path(path):
|
||||||
|
base = os.path.basename(path)
|
||||||
|
return base.endswith('.test') or base.endswith(_PY_TEST_SUFFIX)
|
||||||
|
|
||||||
|
|
||||||
|
def _testbase(path):
|
||||||
|
"""Strip the test extension to get the canonical test name."""
|
||||||
|
base = os.path.basename(path)
|
||||||
|
if base.endswith('.test'):
|
||||||
|
return base[:-len('.test')]
|
||||||
|
if base.endswith(_PY_TEST_SUFFIX):
|
||||||
|
return base[:-len(_PY_TEST_SUFFIX)]
|
||||||
|
return base
|
||||||
|
|
||||||
|
|
||||||
def collect_tests(suitedir, patterns):
|
def collect_tests(suitedir, patterns):
|
||||||
"""Collect test scripts matching the given patterns."""
|
"""Collect test scripts (.test or _test.py) matching the given patterns."""
|
||||||
if not patterns:
|
if not patterns:
|
||||||
tests = sorted(glob.glob(os.path.join(suitedir, '*.test')))
|
candidates = (glob.glob(os.path.join(suitedir, '*.test'))
|
||||||
|
+ glob.glob(os.path.join(suitedir, '*' + _PY_TEST_SUFFIX)))
|
||||||
|
tests = sorted(p for p in candidates if _is_test_path(p))
|
||||||
else:
|
else:
|
||||||
|
seen = set()
|
||||||
tests = []
|
tests = []
|
||||||
for pat in patterns:
|
for pat in patterns:
|
||||||
if not pat.endswith('.test'):
|
# Accept either bare name ("mkpath"), explicit extension, or glob.
|
||||||
pat = pat + '.test'
|
if pat.endswith('.test') or pat.endswith('.py'):
|
||||||
matches = sorted(glob.glob(os.path.join(suitedir, pat)))
|
pats = [pat]
|
||||||
tests.extend(matches)
|
else:
|
||||||
|
pats = [pat + '.test', pat + _PY_TEST_SUFFIX]
|
||||||
|
for p in pats:
|
||||||
|
for m in sorted(glob.glob(os.path.join(suitedir, p))):
|
||||||
|
if _is_test_path(m) and m not in seen:
|
||||||
|
seen.add(m)
|
||||||
|
tests.append(m)
|
||||||
return tests
|
return tests
|
||||||
|
|
||||||
|
|
||||||
@@ -203,11 +239,18 @@ def run_one_test(testscript, testbase, scratchdir, base_env, timeout,
|
|||||||
env = base_env.copy()
|
env = base_env.copy()
|
||||||
env['scratchdir'] = scratchdir
|
env['scratchdir'] = scratchdir
|
||||||
|
|
||||||
|
# Dispatch by extension: shell tests via /bin/sh -e, Python tests via
|
||||||
|
# the same python3 that's running this runner.
|
||||||
|
if testscript.endswith('.py'):
|
||||||
|
cmd = [sys.executable, testscript]
|
||||||
|
else:
|
||||||
|
cmd = ['sh', '-e', testscript]
|
||||||
|
|
||||||
logfile = os.path.join(scratchdir, 'test.log')
|
logfile = os.path.join(scratchdir, 'test.log')
|
||||||
try:
|
try:
|
||||||
with open(logfile, 'w') as log:
|
with open(logfile, 'w') as log:
|
||||||
proc = subprocess.run(
|
proc = subprocess.run(
|
||||||
['sh', '-e', testscript],
|
cmd,
|
||||||
stdout=log, stderr=subprocess.STDOUT,
|
stdout=log, stderr=subprocess.STDOUT,
|
||||||
env=env, timeout=timeout,
|
env=env, timeout=timeout,
|
||||||
cwd=env.get('TOOLDIR', '.')
|
cwd=env.get('TOOLDIR', '.')
|
||||||
@@ -329,6 +372,7 @@ def main():
|
|||||||
print(f' valgrind=enabled (logs in valgrind.*.log)')
|
print(f' valgrind=enabled (logs in valgrind.*.log)')
|
||||||
if args.parallel > 1:
|
if args.parallel > 1:
|
||||||
print(f' parallel={args.parallel}')
|
print(f' parallel={args.parallel}')
|
||||||
|
print(f' daemon_transport={"tcp (loopback)" if args.use_tcp else "pipe (secure default)"}')
|
||||||
print(f' scratchbase={scratchbase}')
|
print(f' scratchbase={scratchbase}')
|
||||||
|
|
||||||
# Build base environment for test scripts
|
# Build base environment for test scripts
|
||||||
@@ -336,6 +380,11 @@ def main():
|
|||||||
if os.path.isdir('/usr/xpg4/bin'):
|
if os.path.isdir('/usr/xpg4/bin'):
|
||||||
path = '/usr/xpg4/bin:' + path
|
path = '/usr/xpg4/bin:' + path
|
||||||
|
|
||||||
|
# Make the testsuite/ directory importable so Python tests can `import rsyncfns`.
|
||||||
|
pythonpath = suitedir
|
||||||
|
if os.environ.get('PYTHONPATH'):
|
||||||
|
pythonpath = suitedir + os.pathsep + os.environ['PYTHONPATH']
|
||||||
|
|
||||||
base_env = os.environ.copy()
|
base_env = os.environ.copy()
|
||||||
base_env.update({
|
base_env.update({
|
||||||
'PATH': path,
|
'PATH': path,
|
||||||
@@ -349,7 +398,12 @@ def main():
|
|||||||
'suitedir': suitedir,
|
'suitedir': suitedir,
|
||||||
'TESTRUN_TIMEOUT': str(args.timeout),
|
'TESTRUN_TIMEOUT': str(args.timeout),
|
||||||
'HOME': scratchbase,
|
'HOME': scratchbase,
|
||||||
|
'PYTHONPATH': pythonpath,
|
||||||
})
|
})
|
||||||
|
if args.use_tcp:
|
||||||
|
# Opt-in: daemon tests start a real rsyncd on a claimed loopback port.
|
||||||
|
# Default (unset) keeps the secure stdio-pipe transport.
|
||||||
|
base_env['RSYNC_TEST_USE_TCP'] = '1'
|
||||||
for k, v in shconfig.items():
|
for k, v in shconfig.items():
|
||||||
if v:
|
if v:
|
||||||
base_env[k] = v
|
base_env[k] = v
|
||||||
@@ -365,7 +419,7 @@ def main():
|
|||||||
full_run = len(args.tests) == 0
|
full_run = len(args.tests) == 0
|
||||||
|
|
||||||
# Record test order for consistent skipped-list output
|
# Record test order for consistent skipped-list output
|
||||||
test_order = {os.path.basename(t).replace('.test', ''): i for i, t in enumerate(tests)}
|
test_order = {_testbase(t): i for i, t in enumerate(tests)}
|
||||||
|
|
||||||
passed = 0
|
passed = 0
|
||||||
failed = 0
|
failed = 0
|
||||||
@@ -402,7 +456,7 @@ def main():
|
|||||||
with concurrent.futures.ThreadPoolExecutor(max_workers=args.parallel) as executor:
|
with concurrent.futures.ThreadPoolExecutor(max_workers=args.parallel) as executor:
|
||||||
futures = {}
|
futures = {}
|
||||||
for testscript in tests:
|
for testscript in tests:
|
||||||
testbase = os.path.basename(testscript).replace('.test', '')
|
testbase = _testbase(testscript)
|
||||||
scratchdir = os.path.join(scratchbase, testbase)
|
scratchdir = os.path.join(scratchbase, testbase)
|
||||||
timeout = 600 if 'hardlinks' in testbase else args.timeout
|
timeout = 600 if 'hardlinks' in testbase else args.timeout
|
||||||
f = executor.submit(
|
f = executor.submit(
|
||||||
@@ -423,7 +477,7 @@ def main():
|
|||||||
else:
|
else:
|
||||||
# Sequential execution
|
# Sequential execution
|
||||||
for testscript in tests:
|
for testscript in tests:
|
||||||
testbase = os.path.basename(testscript).replace('.test', '')
|
testbase = _testbase(testscript)
|
||||||
scratchdir = os.path.join(scratchbase, testbase)
|
scratchdir = os.path.join(scratchbase, testbase)
|
||||||
timeout = 600 if 'hardlinks' in testbase else args.timeout
|
timeout = 600 if 'hardlinks' in testbase else args.timeout
|
||||||
tr = run_one_test(
|
tr = run_one_test(
|
||||||
@@ -474,8 +528,15 @@ def main():
|
|||||||
print('-' * 60)
|
print('-' * 60)
|
||||||
|
|
||||||
exit_code = failed + vg_errors
|
exit_code = failed + vg_errors
|
||||||
if exit_code == 0 and skipped_str != args.expect_skipped:
|
if exit_code == 0:
|
||||||
exit_code = 1
|
# Compare the skipped set order-insensitively: which tests skipped is
|
||||||
|
# what matters, not the order runtests happened to collect them in
|
||||||
|
# (that order is just sorted filenames -- an easy thing to get subtly
|
||||||
|
# wrong when maintaining the per-platform expected lists).
|
||||||
|
got = set(s for s in skipped_str.split(',') if s)
|
||||||
|
want = set(s for s in args.expect_skipped.split(',') if s)
|
||||||
|
if got != want:
|
||||||
|
exit_code = 1
|
||||||
|
|
||||||
print(f'overall result is {exit_code}')
|
print(f'overall result is {exit_code}')
|
||||||
sys.exit(exit_code)
|
sys.exit(exit_code)
|
||||||
|
|||||||
30
socket.c
@@ -739,8 +739,12 @@ void set_socket_options(int fd, char *options)
|
|||||||
|
|
||||||
/* This is like socketpair but uses tcp. The function guarantees that nobody
|
/* This is like socketpair but uses tcp. The function guarantees that nobody
|
||||||
* else can attach to the socket, or if they do that this function fails and
|
* else can attach to the socket, or if they do that this function fails and
|
||||||
* the socket gets closed. Returns 0 on success, -1 on failure. The resulting
|
* the socket gets closed. The anti-hijack guarantee is enforced after the
|
||||||
* file descriptors are symmetrical. Currently only for RSYNC_CONNECT_PROG. */
|
* accept() below: a local attacker who races a connection in on the loopback
|
||||||
|
* listener before our own connect() lands would be detected by the peer-vs-
|
||||||
|
* local address comparison and the function fails. Returns 0 on success, -1
|
||||||
|
* on failure. The resulting file descriptors are symmetrical. Currently
|
||||||
|
* only for RSYNC_CONNECT_PROG. */
|
||||||
static int socketpair_tcp(int fd[2])
|
static int socketpair_tcp(int fd[2])
|
||||||
{
|
{
|
||||||
int listener;
|
int listener;
|
||||||
@@ -792,6 +796,28 @@ static int socketpair_tcp(int fd[2])
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Confirm that the connection we accepted is the one we just made, and
|
||||||
|
* not one a local attacker raced in on the loopback listener before our
|
||||||
|
* own connect() completed. The peer of the accepted end (fd[0]) must be
|
||||||
|
* the local address of our connecting end (fd[1]), and both must be
|
||||||
|
* loopback. If they differ, someone else connected first; fail closed. */
|
||||||
|
{
|
||||||
|
struct sockaddr_in accepted_peer, our_local;
|
||||||
|
socklen_t plen = sizeof accepted_peer;
|
||||||
|
socklen_t llen = sizeof our_local;
|
||||||
|
|
||||||
|
if (getpeername(fd[0], (struct sockaddr *)&accepted_peer, &plen) != 0
|
||||||
|
|| getsockname(fd[1], (struct sockaddr *)&our_local, &llen) != 0
|
||||||
|
|| accepted_peer.sin_family != AF_INET
|
||||||
|
|| our_local.sin_family != AF_INET
|
||||||
|
|| accepted_peer.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
|
||||||
|
|| our_local.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
|
||||||
|
|| accepted_peer.sin_port != our_local.sin_port) {
|
||||||
|
errno = EPERM;
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* all OK! */
|
/* all OK! */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
10
syscall.c
@@ -33,7 +33,7 @@
|
|||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) && defined(HAVE_OPENAT2)
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <linux/openat2.h>
|
#include <linux/openat2.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -1691,7 +1691,7 @@ static int path_has_dotdot_component(const char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) && defined(HAVE_OPENAT2)
|
||||||
static int secure_relative_open_linux(const char *basedir, const char *relpath, int flags, mode_t mode)
|
static int secure_relative_open_linux(const char *basedir, const char *relpath, int flags, mode_t mode)
|
||||||
{
|
{
|
||||||
struct open_how how;
|
struct open_how how;
|
||||||
@@ -1791,11 +1791,13 @@ int secure_relative_open(const char *basedir, const char *relpath, int flags, mo
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) && defined(HAVE_OPENAT2)
|
||||||
{
|
{
|
||||||
int fd = secure_relative_open_linux(basedir, relpath, flags, mode);
|
int fd = secure_relative_open_linux(basedir, relpath, flags, mode);
|
||||||
/* ENOSYS = kernel < 5.6 doesn't have the syscall even though
|
/* ENOSYS = kernel < 5.6 doesn't have the syscall even though
|
||||||
* glibc/kernel-headers do; fall through to the portable path. */
|
* glibc/kernel-headers do; fall through to the portable path.
|
||||||
|
* (Built unconditionally unless --disable-openat2, which forces
|
||||||
|
* the portable resolver below so that tier is exercised.) */
|
||||||
if (fd != -1 || errno != ENOSYS)
|
if (fd != -1 || errno != ENOSYS)
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,11 @@
|
|||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <linux/openat2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
int dry_run = 0;
|
int dry_run = 0;
|
||||||
int am_root = 0;
|
int am_root = 0;
|
||||||
int am_sender = 0;
|
int am_sender = 0;
|
||||||
@@ -30,6 +35,42 @@ short info_levels[COUNT_INFO], debug_levels[COUNT_DEBUG];
|
|||||||
|
|
||||||
static int errs = 0;
|
static int errs = 0;
|
||||||
|
|
||||||
|
/* Probe the running kernel for the RESOLVE_BENEATH-equivalent confinement
|
||||||
|
* that secure_relative_open() prefers over the per-component O_NOFOLLOW
|
||||||
|
* walk. Returns 1 if either openat2(RESOLVE_BENEATH) on Linux 5.6+ or
|
||||||
|
* openat(O_RESOLVE_BENEATH) on FreeBSD 13+ / macOS 15+ is honoured by
|
||||||
|
* the running kernel, 0 otherwise. The probe opens "." (a directory
|
||||||
|
* the helper has just chdir'd into) so it can't fail for any reason
|
||||||
|
* other than the kernel rejecting the requested confinement flag. */
|
||||||
|
static int kernel_resolve_beneath_supported(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
#ifdef __linux__
|
||||||
|
{
|
||||||
|
struct open_how how;
|
||||||
|
memset(&how, 0, sizeof how);
|
||||||
|
how.flags = O_RDONLY | O_DIRECTORY;
|
||||||
|
how.resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS;
|
||||||
|
fd = syscall(SYS_openat2, AT_FDCWD, ".", &how, sizeof how);
|
||||||
|
if (fd >= 0) {
|
||||||
|
close(fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* ENOSYS = kernel < 5.6. Fall through to the O_RESOLVE_BENEATH
|
||||||
|
* probe in case we're a Linux build running on a kernel that
|
||||||
|
* gained O_RESOLVE_BENEATH via some out-of-tree backport. */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef O_RESOLVE_BENEATH
|
||||||
|
fd = openat(AT_FDCWD, ".", O_RDONLY | O_DIRECTORY | O_RESOLVE_BENEATH);
|
||||||
|
if (fd >= 0) {
|
||||||
|
close(fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void check(const char *label, int actual_rc, int expect_ok,
|
static void check(const char *label, int actual_rc, int expect_ok,
|
||||||
const char *path, mode_t expected_mode)
|
const char *path, mode_t expected_mode)
|
||||||
{
|
{
|
||||||
@@ -87,10 +128,35 @@ int main(int argc, char **argv)
|
|||||||
* files to mode 0600 so we have a clean baseline to compare.
|
* files to mode 0600 so we have a clean baseline to compare.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Scenario A: legitimate parent dir-symlink, chmod must succeed. */
|
/* Scenario A: legitimate parent dir-symlink.
|
||||||
|
*
|
||||||
|
* On platforms whose kernel offers RESOLVE_BENEATH-equivalent
|
||||||
|
* confinement (Linux 5.6+ openat2, FreeBSD 13+ / macOS 15+
|
||||||
|
* O_RESOLVE_BENEATH), the within-tree symlink is followed and
|
||||||
|
* the chmod must succeed.
|
||||||
|
*
|
||||||
|
* On platforms that fall back to the per-component O_NOFOLLOW
|
||||||
|
* walk (OpenBSD, NetBSD, Solaris, older Cygwin, HPE NonStop,
|
||||||
|
* and pre-5.6 Linux), every symlink is rejected -- including
|
||||||
|
* this legitimate one. That's a real platform limitation (the
|
||||||
|
* same one that causes the #715 regression there) and the
|
||||||
|
* expected outcome is rejection.
|
||||||
|
*
|
||||||
|
* Detect at runtime and expect accordingly. The other three
|
||||||
|
* scenarios behave identically on both code paths and need no
|
||||||
|
* adjustment. */
|
||||||
|
int kernel_has_rb = kernel_resolve_beneath_supported();
|
||||||
|
fprintf(stderr, "INFO: kernel RESOLVE_BENEATH-equivalent confinement: %s\n",
|
||||||
|
kernel_has_rb ? "available" : "not available (per-component fallback)");
|
||||||
|
|
||||||
int rc = do_chmod_at("inside_link/sentinel", 0640);
|
int rc = do_chmod_at("inside_link/sentinel", 0640);
|
||||||
check("A: legit dir-symlink within tree",
|
if (kernel_has_rb) {
|
||||||
rc, 1, "realdir/sentinel", 0640);
|
check("A: legit dir-symlink within tree (kernel confined)",
|
||||||
|
rc, 1, "realdir/sentinel", 0640);
|
||||||
|
} else {
|
||||||
|
check("A: legit dir-symlink within tree (per-component fallback rejects)",
|
||||||
|
rc, 0, "realdir/sentinel", 0600);
|
||||||
|
}
|
||||||
|
|
||||||
/* Scenario B: parent symlink escapes the tree -- chmod must be
|
/* Scenario B: parent symlink escapes the tree -- chmod must be
|
||||||
* rejected and the outside file's mode must be unchanged. */
|
* rejected and the outside file's mode must be unchanged. */
|
||||||
|
|||||||
7
t_stub.c
@@ -36,7 +36,12 @@ int preserve_perms = 0;
|
|||||||
int preserve_executability = 0;
|
int preserve_executability = 0;
|
||||||
int omit_link_times = 0;
|
int omit_link_times = 0;
|
||||||
int open_noatime = 0;
|
int open_noatime = 0;
|
||||||
size_t max_alloc = 0; /* max_alloc is needed when combined with util2.o */
|
size_t max_alloc = (size_t)-1; /* test helpers are not memory-constrained;
|
||||||
|
* 0 here makes every my_alloc()/my_strdup() in
|
||||||
|
* util2.c trip the "exceeded --max-alloc=0"
|
||||||
|
* check, which any helper exercising the
|
||||||
|
* per-component fallback of secure_relative_open()
|
||||||
|
* hits at its first my_strdup() call. */
|
||||||
char *partial_dir;
|
char *partial_dir;
|
||||||
char *module_dir;
|
char *module_dir;
|
||||||
filter_rule_list daemon_filter_list;
|
filter_rule_list daemon_filter_list;
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Test some foundational things.
|
|
||||||
|
|
||||||
. "$suitedir/rsync.fns"
|
|
||||||
|
|
||||||
RSYNC_RSH="$scratchdir/src/support/lsh.sh"
|
|
||||||
export RSYNC_RSH
|
|
||||||
|
|
||||||
echo $0 running
|
|
||||||
|
|
||||||
$RSYNC --version || test_fail '--version output failed'
|
|
||||||
|
|
||||||
$RSYNC --info=help || test_fail '--info=help output failed'
|
|
||||||
|
|
||||||
$RSYNC --debug=help || test_fail '--debug=help output failed'
|
|
||||||
|
|
||||||
weird_name="A weird)name"
|
|
||||||
|
|
||||||
mkdir "$fromdir"
|
|
||||||
mkdir "$fromdir/$weird_name"
|
|
||||||
|
|
||||||
append_line() {
|
|
||||||
echo "$1"
|
|
||||||
echo "$1" >>"$fromdir/$weird_name/file"
|
|
||||||
}
|
|
||||||
|
|
||||||
append_line test1
|
|
||||||
checkit "$RSYNC -ai '$fromdir/' '$todir/'" "$fromdir" "$todir"
|
|
||||||
|
|
||||||
copy_weird() {
|
|
||||||
checkit "$RSYNC $1 --rsync-path='$RSYNC' '$2$fromdir/$weird_name/' '$3$todir/$weird_name'" "$fromdir" "$todir"
|
|
||||||
}
|
|
||||||
|
|
||||||
append_line test2
|
|
||||||
copy_weird '-ai' 'lh:' ''
|
|
||||||
|
|
||||||
append_line test3
|
|
||||||
copy_weird '-ai' '' 'lh:'
|
|
||||||
|
|
||||||
append_line test4
|
|
||||||
copy_weird '-ais' 'lh:' ''
|
|
||||||
|
|
||||||
append_line test5
|
|
||||||
copy_weird '-ais' '' 'lh:'
|
|
||||||
|
|
||||||
echo test6
|
|
||||||
|
|
||||||
touch "$fromdir/one" "$fromdir/two"
|
|
||||||
(cd "$fromdir" && $RSYNC -ai --old-args --rsync-path="$RSYNC" lh:'one two' "$todir/")
|
|
||||||
if [ ! -f "$todir/one" ] || [ ! -f "$todir/two" ]; then
|
|
||||||
test_fail "old-args copy of 'one two' failed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo test7
|
|
||||||
|
|
||||||
rm "$todir/one" "$todir/two"
|
|
||||||
(cd "$fromdir" && RSYNC_OLD_ARGS=1 $RSYNC -ai --rsync-path="$RSYNC" lh:'one two' "$todir/")
|
|
||||||
|
|
||||||
# The script would have aborted on error, so getting here means we've won.
|
|
||||||
exit 0
|
|
||||||