Imported Upstream version 3.2.7 upstream upstream/3.2.7
authorTizenOpenSource <tizenopensrc@samsung.com>
Mon, 22 Jan 2024 06:24:08 +0000 (15:24 +0900)
committerTizenOpenSource <tizenopensrc@samsung.com>
Mon, 22 Jan 2024 06:24:08 +0000 (15:24 +0900)
152 files changed:
.cirrus.yml
.gitignore
COPYING
INSTALL.md
Makefile.in
NEWS.md
README.md
SECURITY.md [new file with mode: 0644]
access.c
aclocal.m4
acls.c
authenticate.c
backup.c
batch.c
byteorder.h
checksum.c
clientname.c
clientserver.c
cmd-or-msg [moved from cmdormsg with 100% similarity]
compat.c
config.h.in
configure.ac
configure.sh
csprotocol.txt
daemon-parm.txt
exclude.c
flist.c
generator.c
hashtable.c
hlink.c
ifuncs.h
install-sh
io.c
itypes.h
latest-year.h
lib/md-defines.h
lib/md5-asm-x86_64.S
lib/md5.c
lib/mdigest.h
lib/pool_alloc.c
lib/snprintf.c
lib/sysacls.c
lib/sysacls.h
lib/sysxattrs.c
loadparm.c
log.c
m4/have_type.m4
main.c
match.c
maybe-make-man
md-convert [new file with mode: 0755]
md2man [changed from file to symlink]
mkgitver
options.c
packaging/auto-Makefile
packaging/cull-options [new file with mode: 0755]
packaging/cull_options [deleted file]
packaging/lsb/rsync.spec
packaging/md2html [deleted file]
packaging/openssl-rsync.cnf [new file with mode: 0644]
packaging/patch-update
packaging/pkglib.py
packaging/pre-push
packaging/prep-auto-dir
packaging/release-rsync
packaging/smart-make
packaging/systemd/rsync.service
packaging/var-checker
prepare-source
progress.c
receiver.c
rrsync.1 [new file with mode: 0644]
rrsync.1.html [new file with mode: 0644]
rsync-ssl
rsync-ssl.1
rsync-ssl.1.html
rsync-ssl.1.md
rsync.1
rsync.1.html
rsync.1.md
rsync.c
rsync.h
rsyncd.conf.5
rsyncd.conf.5.html
rsyncd.conf.5.md
runtests.sh
sender.c
simd-checksum-avx2.S [new file with mode: 0644]
simd-checksum-x86_64.cpp
support/atomic-rsync
support/git-set-file-times
support/json-rsync-version [new file with mode: 0755]
support/lsh
support/lsh.sh
support/munge-symlinks
support/rrsync [changed mode: 0644->0755]
support/rrsync.1.md [new file with mode: 0644]
support/rsync-no-vanished
support/rsync-slash-strip
syscall.c
t_stub.c
testsuite/00-hello.test
testsuite/README.testsuite
testsuite/acls-default.test [moved from testsuite/default-acls.test with 93% similarity]
testsuite/acls.test
testsuite/alt-dest.test [new file with mode: 0644]
testsuite/atimes.test
testsuite/backup.test
testsuite/batch-mode.test
testsuite/chgrp.test
testsuite/chmod-option.test
testsuite/chmod-temp-dir.test
testsuite/chmod.test
testsuite/chown.test
testsuite/compare-dest.test [deleted file]
testsuite/crtimes.test
testsuite/daemon.test
testsuite/delay-updates.test [new file with mode: 0644]
testsuite/delete.test
testsuite/devices.test
testsuite/dir-sgid.test
testsuite/duplicates.test
testsuite/exclude-lsh.test [new symlink]
testsuite/exclude.test
testsuite/executability.test
testsuite/fuzzy.test
testsuite/hardlinks.test
testsuite/itemize.test
testsuite/merge.test
testsuite/missing.test
testsuite/mkpath.test [changed mode: 0755->0644]
testsuite/protected-regular.test [new file with mode: 0644]
testsuite/relative.test
testsuite/rsync.fns
testsuite/ssh-basic.test
testsuite/symlink-ignore.test
testsuite/trimslash.test
testsuite/unsafe-byname.test
testsuite/unsafe-links.test
testsuite/wildmatch.test
testsuite/xattrs.test
tls.c
token.c
uidlist.c
usage.c
util1.c [moved from util.c with 94% similarity]
version.h
xattrs.c
zlib/deflate.c
zlib/deflate.h
zlib/inflate.c
zlib/trees.c

index 4150bf3..33e2685 100644 (file)
@@ -1,13 +1,14 @@
 freebsd_task:
   name: FreeBSD
   freebsd_instance:
-    image: freebsd-12-1-release-amd64
+    image_family: freebsd-13-1
   env:
     PATH: /usr/local/bin:$PATH
   prep_script:
     - dd if=/dev/zero of=/tmp/zpool bs=1M count=1024
     - zpool create -m `pwd`/testtmp zpool /tmp/zpool
-    - pkg install -y autotools xxhash zstd liblz4
+    - pkg install -y bash autotools m4 xxhash zstd liblz4 wget
+    - wget -O git-version.h https://gist.githubusercontent.com/WayneD/c11243fa374fc64d4e42f2855c8e3827/raw/rsync-git-version.h
   configure_script:
     - CPPFLAGS=-I/usr/local/include/ LDFLAGS=-L/usr/local/lib/ ./configure --disable-md2man
   make_script:
@@ -17,6 +18,6 @@ freebsd_task:
   info_script:
     - rsync --version
   test_script:
-    - RSYNC_MAX_SKIPPED=3 make check
+    - RSYNC_EXPECT_SKIPPED=acls-default,acls,crtimes,protected-regular make check
   ssl_file_list_script:
     - rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
index 47d75e9..9e59c9c 100644 (file)
@@ -15,9 +15,11 @@ config.status
 aclocal.m4
 /proto.h
 /proto.h-tstamp
-/rsync*.1
-/rsync*.5
+/rsync*.[15]
+/rrsync
+/rrsync*.1
 /rsync*.html
+/rrsync*.html
 /help-rsync*.h
 /default-cvsignore.h
 /default-dont-compress.h
@@ -28,6 +30,7 @@ aclocal.m4
 /conftest*
 /dox
 /getgroups
+/gists
 /gmon.out
 /rsync
 /stunnel-rsyncd.conf
diff --git a/COPYING b/COPYING
index 104c583..fb19ef2 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -1,7 +1,16 @@
+REGARDING OPENSSL AND XXHASH
+
+In addition, as a special exception, the copyright holders give
+permission to dynamically link rsync with the OpenSSL and xxhash
+libraries when those libraries are being distributed in compliance
+with their license terms, and to distribute a dynamically linked
+combination of rsync and these libraries.  This is also considered
+to be covered under the GPL's System Libraries exception.
+
                     GNU GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
@@ -645,7 +654,7 @@ the "copyright" line and a pointer to where the full notice is found.
     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 <http://www.gnu.org/licenses/>.
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 Also add information on how to contact you by electronic and paper mail.
 
@@ -664,20 +673,11 @@ 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
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
 
   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
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-
-REGARDING OPENSSL AND XXHASH
-
-In addition, as a special exception, the copyright holders give
-permission to dynamically link rsync with the OpenSSL and xxhash
-libraries when those libraries are being distributed in compliance
-with their license terms, and to distribute a dynamically linked
-combination of rsync and these libraries.  This is also considered
-to be covered under the GPL's System Libraries exception.
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
index 932acc2..1605ab4 100644 (file)
@@ -13,22 +13,22 @@ You need to have a C compiler installed and optionally a C++ compiler in order
 to try to build some hardware-accelerated checksum routines.  Rsync also needs
 a modern awk, which might be provided via gawk or nawk on some OSes.
 
-## Autoconf & man pages
+## Autoconf & manpages
 
 If you're installing from the git repo (instead of a release tar file) you'll
 also need the GNU autotools (autoconf & automake) and your choice of 2 python3
-markdown libraries: cmarkgfm or commonmark (needed to generate the man pages).
+markdown libraries: cmarkgfm or commonmark (needed to generate the manpages).
 If your OS doesn't provide a python3-cmarkgfm or python3-commonmark package,
 you can run the following to install the commonmark python library for your
 build user (after installing python3's pip package):
 
->     pip3 install --user commonmark
+>     python3 -mpip install --user commonmark
 
-You can test if you've got it fixed by running (from the src dir):
+You can test if you've got it fixed by running (from the rsync checkout):
 
->     ./md2man --test rsync-ssl.1.md
+>     ./md-convert --test rsync-ssl.1.md
 
-Alternately, you can avoid generating the man pages by fetching the very latest
+Alternately, you can avoid generating the manpages by fetching the very latest
 versions (that match the latest git source) from the [generated-files][6] dir.
 One way to do that is to run:
 
@@ -53,7 +53,8 @@ installed to manipulate xattrs and to run the rsync testsuite.
 The [xxHash library][1] provides extremely fast checksum functions that can
 make the "rsync algorithm" run much more quickly, especially when matching
 blocks in large files.  Installing this development library adds xxhash
-checksums as the default checksum algorithm.
+checksums as the default checksum algorithm.  You'll need at least v0.8.0
+if you want rsync to include the full range of its checksum algorithms.
 
 [1]: https://cyan4973.github.io/xxHash/
 
@@ -100,7 +101,7 @@ like.
     >     sudo apt install -y attr libattr1-dev
     >     sudo apt install -y libxxhash-dev
     >     sudo apt install -y libzstd-dev
-    >     sudo apt install -y libzlz4-dev
+    >     sudo apt install -y liblz4-dev
     >     sudo apt install -y libssl-dev
 
  -  For CentOS (use EPEL for python3-pip):
@@ -113,7 +114,7 @@ like.
     >     sudo yum -y install libzstd-devel
     >     sudo yum -y install lz4-devel
     >     sudo yum -y install openssl-devel
-    >     pip3 install --user commonmark
+    >     python3 -mpip install --user commonmark
 
  -  For Fedora 33:
 
@@ -141,12 +142,18 @@ like.
 
  -  For Cygwin (with all cygwin programs stopped, run the appropriate setup program from a cmd shell):
 
-    >     setup-x86_64 --quiet-mode -P make,gawk,autoconf,automake,gcc-core,python3,python36-commonmark
+    >     setup-x86_64 --quiet-mode -P make,gawk,autoconf,automake,gcc-core,python38,python38-pip
     >     setup-x86_64 --quiet-mode -P attr,libattr-devel
     >     setup-x86_64 --quiet-mode -P libzstd-devel
     >     setup-x86_64 --quiet-mode -P liblz4-devel
     >     setup-x86_64 --quiet-mode -P libssl-devel
 
+    Sometimes cygwin has commonmark packaged and sometimes it doesn't. Now that
+    its python38 has stabilized, you could install python38-commonmark. Or just
+    avoid the issue by running this from a bash shell as your build user:
+
+    >     python3 -mpip install --user commonmark
+
 ## Build and install
 
 After installing the various libraries, you need to configure, build, and
@@ -171,9 +178,9 @@ config.h, or just override them in your /etc/rsyncd.conf file.
 As of 2.4.7, rsync uses Eric Troan's popt option-parsing library.  A
 cut-down copy of a recent release is included in the rsync distribution,
 and will be used if there is no popt library on your build host, or if
-the --with-included-popt option is passed to ./configure.
+the `--with-included-popt` option is passed to ./configure.
 
-If you configure using --enable-maintainer-mode, then rsync will try
+If you configure using `--enable-maintainer-mode`, then rsync will try
 to pop up an xterm on DISPLAY=:0 if it crashes.  You might find this
 useful, but it should be turned off for production builds.
 
@@ -187,7 +194,7 @@ This is helpful when using the branch-from-patch and patch-update scripts
 to maintain the official rsync patches.  If you ever need to build from
 a "detached head" git position then you'll need to manually chdir into
 the build dir to run make.  I also like to create 2 more symlinks in the
-source dir:  ln -s build/rsync . ; ln -s build/testtmp .
+source dir:  `ln -s build/rsync . ; ln -s build/testtmp .`
 
 ## Make compatibility
 
@@ -221,7 +228,7 @@ Some versions of Mac OS X (Darwin) seem to have an IPv6 stack, but do
 not completely implement the "New Sockets" API.
 
 [This site][5] says that Apple started to support IPv6 in 10.2 (Jaguar).  If
-your build fails, try again after running configure with --disable-ipv6.
+your build fails, try again after running configure with `--disable-ipv6`.
 
 [5]: http://www.ipv6.org/impl/mac.html
 
index d935651..a1253e5 100644 (file)
@@ -6,6 +6,7 @@ exec_prefix=@exec_prefix@
 bindir=@bindir@
 libdir=@libdir@/rsync
 mandir=@mandir@
+with_rrsync=@with_rrsync@
 
 LIBS=@LIBS@
 CC=@CC@
@@ -29,28 +30,30 @@ SHELL=/bin/sh
 .SUFFIXES:
 .SUFFIXES: .c .o
 
-SIMD_x86_64=simd-checksum-x86_64.o
-ASM_x86_64=lib/md5-asm-x86_64.o
+ROLL_SIMD_x86_64=simd-checksum-x86_64.o
+ROLL_ASM_x86_64=simd-checksum-avx2.o
+MD5_ASM_x86_64=lib/md5-asm-x86_64.o
 
 GENFILES=configure.sh aclocal.m4 config.h.in rsync.1 rsync.1.html \
-        rsync-ssl.1 rsync-ssl.1.html rsyncd.conf.5 rsyncd.conf.5.html
+        rsync-ssl.1 rsync-ssl.1.html rsyncd.conf.5 rsyncd.conf.5.html \
+        @GEN_RRSYNC@
 HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h itypes.h inums.h \
-       lib/pool_alloc.h lib/mdigest.h lib/md-defines.h version.h
+       lib/pool_alloc.h lib/mdigest.h lib/md-defines.h
 LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o lib/md5.o \
        lib/permstring.o lib/pool_alloc.o lib/sysacls.o lib/sysxattrs.o @LIBOBJS@
 zlib_OBJS=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
        zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
 OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \
-       util.o util2.o main.o checksum.o match.o syscall.o log.o backup.o delete.o
+       util1.o util2.o main.o checksum.o match.o syscall.o log.o backup.o delete.o
 OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o \
        usage.o fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
-OBJS3=progress.o pipe.o @ASM@
+OBJS3=progress.o pipe.o @MD5_ASM@ @ROLL_SIMD@ @ROLL_ASM@
 DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
 popt_OBJS=popt/findme.o  popt/popt.o  popt/poptconfig.o \
        popt/popthelp.o popt/poptparse.o
-OBJS=$(OBJS1) $(OBJS2) $(OBJS3) @SIMD@ $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
+OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
 
-TLS_OBJ = tls.o syscall.o t_stub.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
+TLS_OBJ = tls.o syscall.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
 
 # Programs we must have to run the test cases
 CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
@@ -67,7 +70,9 @@ CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.
        $(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
 @OBJ_RESTORE@
 
-all: Makefile rsync$(EXEEXT) stunnel-rsyncd.conf @MAKE_MAN@
+# NOTE: consider running "packaging/smart-make" instead of "make" to auto-handle
+# any changes to configure.sh and the main Makefile prior to a "make all".
+all: Makefile rsync$(EXEEXT) stunnel-rsyncd.conf @MAKE_RRSYNC@ @MAKE_MAN@
 .PHONY: all
 
 .PHONY: install
@@ -80,6 +85,10 @@ install: all
        if test -f rsync.1; then $(INSTALLMAN) -m 644 rsync.1 $(DESTDIR)$(mandir)/man1; fi
        if test -f rsync-ssl.1; then $(INSTALLMAN) -m 644 rsync-ssl.1 $(DESTDIR)$(mandir)/man1; fi
        if test -f rsyncd.conf.5; then $(INSTALLMAN) -m 644 rsyncd.conf.5 $(DESTDIR)$(mandir)/man5; fi
+       if test "$(with_rrsync)" = yes; then \
+           $(INSTALLCMD) -m 755 rrsync $(DESTDIR)$(bindir); \
+           if test -f rrsync.1; then $(INSTALLMAN) -m 644 rrsync.1 $(DESTDIR)$(mandir)/man1; fi; \
+       fi
 
 install-ssl-daemon: stunnel-rsyncd.conf
        -$(MKDIR_P) $(DESTDIR)/etc/stunnel
@@ -96,10 +105,13 @@ install-strip:
 rsync$(EXEEXT): $(OBJS)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
 
+rrsync: support/rrsync
+       cp -p $(srcdir)/support/rrsync rrsync
+
 $(OBJS): $(HEADERS)
 $(CHECK_OBJS): $(HEADERS)
 tls.o xattrs.o: lib/sysxattrs.h
-usage.o: latest-year.h help-rsync.h help-rsyncd.h git-version.h default-cvsignore.h
+usage.o: version.h latest-year.h help-rsync.h help-rsyncd.h git-version.h default-cvsignore.h
 loadparm.o: default-dont-compress.h daemon-parm.h
 
 flist.o: rounding.h
@@ -131,17 +143,20 @@ rounding.h: rounding.c rsync.h proto.h
        fi
        @rm -f rounding.out
 
-# While $(wildcard ...) is a GNU make idiom, at least other makes should just turn it into an
-# empty string (we need something that will vanish if we're not building a git checkout).
-# If you want an updated git version w/o GNU make, remove git-version.h after a pull.
-git-version.h: mkgitver $(wildcard $(srcdir)/.git/logs/HEAD)
+git-version.h: ALWAYS_RUN
        $(srcdir)/mkgitver
 
+.PHONY: ALWAYS_RUN
+ALWAYS_RUN:
+
 simd-checksum-x86_64.o: simd-checksum-x86_64.cpp
-       @$(srcdir)/cmdormsg disable-simd $(CXX) -I. $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $(srcdir)/simd-checksum-x86_64.cpp
+       @$(srcdir)/cmd-or-msg disable-roll-simd $(CXX) -I. $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $(srcdir)/simd-checksum-x86_64.cpp
 
-lib/md5-asm-x86_64.o: lib/md5-asm-x86_64.S config.h lib/md-defines.h
-       @$(srcdir)/cmdormsg disable-asm $(CC) -I. @NOEXECSTACK@ -c -o $@ $(srcdir)/lib/md5-asm-x86_64.S
+simd-checksum-avx2.o: simd-checksum-avx2.S
+       @$(srcdir)/cmd-or-msg disable-roll-asm $(CC) $(CFLAGS) -I. @NOEXECSTACK@ -c -o $@ $(srcdir)/simd-checksum-avx2.S
+
+lib/md5-asm-x86_64.o: lib/md5-asm-x86_64.S lib/md-defines.h
+       @$(srcdir)/cmd-or-msg disable-md5-asm $(CC) -I. @NOEXECSTACK@ -c -o $@ $(srcdir)/lib/md5-asm-x86_64.S
 
 tls$(EXEEXT): $(TLS_OBJ)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
@@ -155,11 +170,11 @@ getgroups$(EXEEXT): getgroups.o
 getfsdev$(EXEEXT): getfsdev.o
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ getfsdev.o $(LIBS)
 
-TRIMSLASH_OBJ = trimslash.o syscall.o t_stub.o lib/compat.o lib/snprintf.o
+TRIMSLASH_OBJ = trimslash.o syscall.o util2.o t_stub.o lib/compat.o lib/snprintf.o
 trimslash$(EXEEXT): $(TRIMSLASH_OBJ)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)
 
-T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
+T_UNSAFE_OBJ = t_unsafe.o syscall.o util1.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
 t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
 
@@ -167,11 +182,15 @@ t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
 conf: configure.sh config.h.in
 
 .PHONY: gen
-gen: conf proto.h man
+gen: conf proto.h man git-version.h
 
 .PHONY: gensend
 gensend: gen
-       rsync -aic $(GENFILES) $${SAMBA_HOST-samba.org}:/home/ftp/pub/rsync/generated-files/
+       if ! diff git-version.h $(srcdir)/gists/rsync-git-version.h >/dev/null; then \
+           ./rsync -ai git-version.h $(srcdir)/gists/rsync-git-version.h && \
+           (cd $(srcdir)/gists && git commit --allow-empty-message -m '' rsync-git-version.h && git push) ; \
+       fi
+       rsync -aic $(GENFILES) git-version.h $${SAMBA_HOST-samba.org}:/home/ftp/pub/rsync/generated-files/ || true
 
 aclocal.m4: $(srcdir)/m4/*.m4
        aclocal -I $(srcdir)/m4
@@ -193,7 +212,7 @@ configure.sh config.h.in: configure.ac aclocal.m4
        else \
            echo "config.h.in has CHANGED."; \
        fi
-       @if test -f configure.sh.old -o -f config.h.in.old; then \
+       @if test -f configure.sh.old || test -f config.h.in.old; then \
            if test "$(MAKECMDGOALS)" = reconfigure; then \
                echo 'Continuing with "make reconfigure".'; \
            else \
@@ -240,22 +259,25 @@ proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c daemon-parm.h
        $(AWK) -f $(srcdir)/mkproto.awk $(srcdir)/*.c $(srcdir)/lib/compat.c daemon-parm.h
 
 .PHONY: man
-man: rsync.1 rsync-ssl.1 rsyncd.conf.5
+man: rsync.1 rsync-ssl.1 rsyncd.conf.5 @MAKE_RRSYNC_1@
+
+rsync.1: rsync.1.md md-convert version.h Makefile
+       @$(srcdir)/maybe-make-man rsync.1.md
 
-rsync.1: rsync.1.md md2man version.h Makefile
-       @$(srcdir)/maybe-make-man $(srcdir) rsync.1.md
+rsync-ssl.1: rsync-ssl.1.md md-convert version.h Makefile
+       @$(srcdir)/maybe-make-man rsync-ssl.1.md
 
-rsync-ssl.1: rsync-ssl.1.md md2man version.h Makefile
-       @$(srcdir)/maybe-make-man $(srcdir) rsync-ssl.1.md
+rsyncd.conf.5: rsyncd.conf.5.md md-convert version.h Makefile
+       @$(srcdir)/maybe-make-man rsyncd.conf.5.md
 
-rsyncd.conf.5: rsyncd.conf.5.md md2man version.h Makefile
-       @$(srcdir)/maybe-make-man $(srcdir) rsyncd.conf.5.md
+rrsync.1: support/rrsync.1.md md-convert Makefile
+       @$(srcdir)/maybe-make-man support/rrsync.1.md
 
 .PHONY: clean
 clean: cleantests
-       rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) \
-               rounding rounding.h *.old rsync*.1 rsync*.5 rsync*.html \
-               daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
+       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@ \
+               *.html daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
 
 .PHONY: cleantests
 cleantests:
diff --git a/NEWS.md b/NEWS.md
index a3e6b9b..fb65628 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,4 +1,480 @@
-<a name="3.2.3"></a>
+# NEWS for rsync 3.2.7 (20 Oct 2022)
+
+## Changes in this version:
+
+### BUG FIXES:
+
+- Fixed the client-side validating of the remote sender's filtering behavior.
+
+- More fixes for the "unrequested file-list name" name, including a copy of
+  "/" with `--relative` enabled and a copy with a lot of related paths with
+  `--relative` enabled (often derived from a `--files-from` list).
+
+- When rsync gets an unpack error on an ACL, mention the filename.
+
+- Avoid over-setting sanitize_paths when a daemon is serving "/" (even if
+  "use chroot" is false).
+
+### ENHANCEMENTS:
+
+- Added negotiated daemon-auth support that allows a stronger checksum digest
+  to be used to validate a user's login to the daemon.  Added SHA512, SHA256,
+  and SHA1 digests to MD5 & MD4.  These new digests are at the highest priority
+  in the new daemon-auth negotiation list.
+
+- Added support for the SHA1 digest in file checksums.  While this tends to be
+  overkill, it is available if someone really needs it.  This overly-long
+  checksum is at the lowest priority in the normal checksum negotiation list.
+  See [`--checksum-choice`](rsync.1#opt) (`--cc`) and the `RSYNC_CHECKSUM_LIST`
+  environment var for how to customize this.
+
+- Improved the xattr hash table to use a 64-bit key without slowing down the
+  key's computation.  This should make extra sure that a hash collision doesn't
+  happen.
+
+- If the `--version` option is repeated (e.g. `-VV`) then the information is
+  output in a (still readable) JSON format.  Client side only.
+
+- The script `support/json-rsync-version` is available to get the JSON style
+  version output from any rsync.  The script accepts either text on stdin
+  **or** an arg that specifies an rsync executable to run with a doubled
+  `--version` option.  If the text we get isn't already in JSON format, it is
+  converted. Newer rsync versions will provide more complete json info than
+  older rsync versions. Various tweaks are made to keep the flag names
+  consistent across versions.
+
+- The [`use chroot`](rsyncd.conf.5#) daemon parameter now defaults to "unset"
+  so that rsync can use chroot when it works and a sanitized copy when chroot
+  is not supported (e.g., for a non-root daemon).  Explicitly setting the
+  parameter to true or false (on or off) behaves the same way as before.
+
+- The `--fuzzy` option was optimized a bit to try to cut down on the amount of
+  computations when considering a big pool of files. The simple heuristic from
+  Kenneth Finnegan resuled in about a 2x speedup.
+
+- If rsync is forced to use protocol 29 or before (perhaps due to talking to an
+  rsync before 3.0.0), the modify time of a file is limited to 4-bytes.  Rsync
+  now interprets this value as an unsigned integer so that a current year past
+  2038 can continue to be represented. This does mean that years prior to 1970
+  cannot be represented in an older protocol, but this trade-off seems like the
+  right choice given that (1) 2038 is very rapidly approaching, and (2) newer
+  protocols support a much wider range of old and new dates.
+
+- The rsync client now treats an empty destination arg as an error, just like
+  it does for an empty source arg. This doesn't affect a `host:` arg (which is
+  treated the same as `host:.`) since the arg is not completely empty.  The use
+  of [`--old-args`](rsync.1#opt) (including via `RSYNC_OLD_ARGS`) allows the
+  prior behavior of treating an empty destination arg as a ".".
+
+### PACKAGING RELATED:
+
+- The checksum code now uses openssl's EVP methods, which gets rid of various
+  deprecation warnings and makes it easy to support more digest methods.  On
+  newer systems, the MD4 digest is marked as legacy in the openssl code, which
+  makes openssl refuse to support it via EVP.  You can choose to ignore this
+  and allow rsync's MD4 code to be used for older rsync connections (when
+  talking to an rsync prior to 3.0.0) or you can choose to configure rsync to
+  tell openssl to enable legacy algorithms (see below).
+
+- A simple openssl config file is supplied that can be installed for rsync to
+  use.  If you install packaging/openssl-rsync.cnf to a public spot (such as
+  `/etc/ssl/openssl-rsync.cnf`) and then run configure with the option
+  `--with-openssl-conf=/path/name.cnf`, this will cause rsync to export the
+  configured path in the OPENSSL_CONF environment variable (when the variable
+  is not already set).  This will enable openssl's MD4 code for rsync to use.
+
+- The packager may wish to include an explicit "use chroot = true" in the top
+  section of their supplied /etc/rsyncd.conf file if the daemon is being
+  installed to run as the root user (though rsync should behave the same even
+  with the value unset, a little extra paranoia doesn't hurt).
+
+- I've noticed that some packagers haven't installed support/nameconvert for
+  users to use in their chrooted rsync configs.  Even if it is not installed
+  as an executable script (to avoid a python3 dependency) it would be good to
+  install it with the other rsync-related support scripts.
+
+- It would be good to add support/json-rsync-version to the list of installed
+  support scripts.
+
+------------------------------------------------------------------------------
+
+# NEWS for rsync 3.2.6 (9 Sep 2022)
+
+## Changes in this version:
+
+### BUG FIXES:
+
+- More path-cleaning improvements in the file-list validation code to avoid
+  rejecting of valid args.
+
+- A file-list validation fix for a [`--files-from`](rsync.1#opt) file that ends
+  without a line-terminating character.
+
+- Added a safety check that prevents the sender from removing destination files
+  when a local copy using [`--remove-source-files`](rsync.1#opt) has some files
+  that are shared between the sending & receiving hierarchies, including the
+  case where the source dir & destination dir are identical.
+
+- Fixed a bug in the internal MD4 checksum code that could cause the digest
+  to be sporadically incorrect (the openssl version was/is fine).
+
+- A minor tweak to rrsync added "copy-devices" to the list of known args, but
+  left it disabled by default.
+
+### ENHANCEMENTS:
+
+- Rename `--protect-args` to [`--secluded-args`](rsync.1#opt) to make it
+  clearer how it differs from the default backslash-escaped arg-protecting
+  behavior of rsync.  The old option names are still accepted.  The
+  environment-variable override did not change its name.
+
+### PACKAGING RELATED:
+
+- The configure option `--with-protected-args` was renamed to
+  `--with-secluded-args`.  This option makes `--secluded-args` the default
+  rsync behavior instead of using backslash escaping for protecting args.
+
+- The mkgitver script now makes sure that a `.git` dir/file is in the top-level
+  source dir before calling `git describe`. It also runs a basic check on the
+  version value. This should avoid using an unrelated git description for
+  rsync's version.
+
+### DEVELOPER RELATED:
+
+- The configure script no longer sets the -pedantic-errors CFLAG (which it
+  used to try to do only for gcc).
+
+- The name_num_obj struct was modified to allow its dynamic name_num_item list
+  to be initialized in a better way.
+
+------------------------------------------------------------------------------
+
+# NEWS for rsync 3.2.5 (14 Aug 2022)
+
+## Changes in this version:
+
+### SECURITY FIXES:
+
+- Added some file-list safety checking that helps to ensure that a rogue
+  sending rsync can't add unrequested top-level names and/or include recursive
+  names that should have been excluded by the sender.  These extra safety
+  checks only require the receiver rsync to be updated.  When dealing with an
+  untrusted sending host, it is safest to copy into a dedicated destination
+  directory for the remote content (i.e. don't copy into a destination
+  directory that contains files that aren't from the remote host unless you
+  trust the remote host). Fixes CVE-2022-29154.
+
+ - A fix for CVE-2022-37434 in the bundled zlib (buffer overflow issue).
+
+### BUG FIXES:
+
+- Fixed the handling of filenames specified with backslash-quoted wildcards
+  when the default remote-arg-escaping is enabled.
+
+- Fixed the configure check for signed char that was causing a host that
+  defaults to unsigned characters to generate bogus rolling checksums. This
+  made rsync send mostly literal data for a copy instead of finding matching
+  data in the receiver's basis file (for a file that contains high-bit
+  characters).
+
+- Lots of manpage improvements, including an attempt to better describe how
+  include/exclude filters work.
+
+- If rsync is compiled with an xxhash 0.8 library and then moved to a system
+  with a dynamically linked xxhash 0.7 library, we now detect this and disable
+  the XX3 hashes (since these routines didn't stabilize until 0.8).
+
+### ENHANCEMENTS:
+
+- The [`--trust-sender`](rsync.1#opt) option was added as a way to bypass the
+  extra file-list safety checking (should that be required).
+
+### PACKAGING RELATED:
+
+- A note to those wanting to patch older rsync versions: the changes in this
+  release requires the quoted argument change from 3.2.4. Then, you'll want
+  every single code change from 3.2.5 since there is no fluff in this release.
+
+- The build date that goes into the manpages is now based on the developer's
+  release date, not on the build's local-timezone interpretation of the date.
+
+### DEVELOPER RELATED:
+
+- Configure now defaults GETGROUPS_T to gid_t when cross compiling.
+
+- Configure now looks for the bsd/string.h include file in order to fix the
+  build on a host that has strlcpy() in the main libc but not defined in the
+  main string.h file.
+
+------------------------------------------------------------------------------
+
+# NEWS for rsync 3.2.4 (15 Apr 2022)
+
+## Changes in this version:
+
+### BEHAVIOR CHANGES:
+
+ - A new form of arg protection was added that works similarly to the older
+   `--protect-args` ([`-s`](rsync.1#opt)) option but in a way that avoids
+   breaking things like rrsync (the restricted rsync script): rsync now uses
+   backslash escaping for sending "shell-active" characters to the remote
+   shell. This includes spaces, so fetching a remote file via a simple quoted
+   filename value now works by default without any extra quoting:
+
+   ```shell
+       rsync -aiv host:'a simple file.pdf' .
+   ```
+
+   Wildcards are not escaped in filename args, but they are escaped in options
+   like the [`--suffix`](rsync.1#opt) and [`--usermap`](rsync.1#opt) values.
+   If your rsync script depends on the old arg-splitting behavior, either run
+   it with the [`--old-args`](rsync.1#opt) option or `export RSYNC_OLD_ARGS=1`
+   in the script's environment.  See also the [ADVANCED USAGE](rsync.1#)
+   section of rsync's manpage for how to use a more modern arg style.
+
+ - A long-standing bug was preventing rsync from figuring out the current
+   locale's decimal point character, which made rsync always output numbers
+   using the "C" locale.  Since this is now fixed in 3.2.4, a script that
+   parses rsync's decimal numbers (e.g. from the verbose footer) may want to
+   setup the environment in a way that the output continues to be in the C
+   locale.  For instance, one of the following should work fine:
+
+   ```shell
+       export LC_ALL=C.UTF-8
+   ```
+
+   or if iconv translations are needed:
+
+   ```shell
+       if [ "${LC_ALL:-}" ]; then
+           export LANG="$LC_ALL"
+           export LC_CTYPE="$LC_ALL"
+           unset LC_ALL
+       fi
+       export LC_NUMERIC=C.UTF-8
+   ```
+
+### SECURITY FIXES:
+
+ - A fix for CVE-2018-25032 in the bundled zlib (memory corruption issue).
+
+### BUG FIXES:
+
+ - Fixed a bug with [`--inplace`](rsync.1#opt) + [`--sparse`](rsync.1#opt) (and
+   a lack of [`--whole-file`](rsync.1#opt)) where the destination file could
+   get reconstructed with bogus data.  Since the bug can also be avoided by
+   using (the seemingly redundant) [`--no-W`](rsync.1#opt) on the receiving
+   side, the latest rsync will now send `--no-W` to a remote receiver when this
+   option combination occurs.  If your client rsync is not new enough to do
+   this for you (or if you're just paranoid), you can manually specify `--no-W
+   -M--no-W` (when not using [`--whole-file`](rsync.1#opt)) to make sure the
+   bug is avoided.
+
+ - Fixed a bug with [`--mkpath`](rsync.1#opt) if a single-file copy specifies
+   an existing destination dir with a non-existing destination filename.
+
+ - Fixed `--update -vv` to output "is uptodate" instead of "is newer" messages
+   for files that are being skipped due to an identical modify time.  (This was
+   a new output quirk in 3.2.3.)
+
+ - When doing an append transfer, the sending side's file must not get shorter
+   or it is skipped. Fixes a crash that could occur when the size changes to 0
+   in the middle of the send negotiations.
+
+ - When dealing with special files (see [`--specials`](rsync.1#opt)) in an
+   alt-dest hierarchy, rsync now checks the non-permission mode bits to ensure
+   that the 2 special files are really the same before hard-linking them
+   together.
+
+ - Fixed a bug where [`--delay-updates`](rsync.1#opt) with stale partial data
+   could cause a file to fail to update.
+
+ - Fixed a few places that would output an INFO message with
+   [`--info=NAME`](rsync.1#opt) that should only have been output given
+   [`--verbose`](rsync.1#opt) or [`--itemize-changes`](rsync.1#opt).
+
+ - Avoid a weird failure if you run a local copy with a (useless)
+   [`--rsh`](rsync.1#opt) option that contains a `V` in the command.
+
+ - Fixed a long-standing compression bug where the compression level of the
+   first file transferred affected the level for all future files.  Also, the
+   per-file compression skipping has apparently never worked, so it is now
+   documented as being ineffective.
+
+ - Fixed a truncate error when a `--write-devices` copy wrote a file onto a
+   device that was shorter than the device.
+
+ - Made `--write-devices` support both `--checksum` and `--no-whole-file` when
+   copying to a device.
+
+ - Improved how the [`--stop-at`](rsync.1#opt), [`--stop-after`](rsync.1#opt),
+   and (the deprecated) [`--time-limit`](rsync.1#opt) options check to see if
+   the allowed time is over, which should make rsync exit more consistently.
+
+ - Tweak --progress to display "`??:??:??`" when the time-remaining value is so
+   large as to be meaningless.
+
+ - Silence some chmod warnings about symlinks when it looks like we have a
+   function to set their permissions but they can't really be set.
+
+ - Fixed a potential issue in git-set-file-times when handling commits with
+   high-bit characters in the description & when handling a description that
+   might mimic the git raw-commit deliniators.  (See the support dir.)
+
+ - The bundled systemd/rsync.service file now includes `Restart=on-failure`.
+
+### ENHANCEMENTS:
+
+ - Use openssl's `-verify_hostname` option in the rsync-ssl script.
+
+ - Added extra info to the "FILENAME exists" output of
+   [`--ignore-existing`](rsync.1#opt) when [`--info=skip2`](rsync.1#opt) is
+   used.  The skip message becomes "FILENAME exists (INFO)" where the INFO is
+   one of "type change", "sum change" (requires [`--checksum`](rsync.1#opt)),
+   "file change" (based on the quick check), "attr change", or "uptodate".
+   Prior versions only supported `--info=skip1`.
+
+ - Added the [`--fsync`](rsync.1#opt) option (promoted from the patches repo).
+
+ - Added the [`--copy-devices`](rsync.1#opt) option.  Compared to the
+   historical version from the rsync-patches repo, this version: properly
+   handles `--checksum`; fixes a truncation bug when doing an `--inplace` copy
+   onto a longer file; fixes several bugs in the `--itemize` output; and only
+   the sending side needs the enhanced rsync for the copy to work.
+
+ - Reduced memory usage for an incremental transfer that has a bunch of small
+   directories.
+
+ - The rsync daemon can now handle a client address with an implied "%scope"
+   suffix.
+
+ - Added support for [`--atimes`](rsync.1#opt) on macOS and fixed a bug where
+   it wouldn't work without [`--times`](rsync.1#opt).
+
+ - Rsync can now update the xattrs on a read-only file when your user can
+   temporarily add user-write permission to the file. (It always worked for a
+   root transfer.)
+
+ - Rsync can now work around an [`--inplace`](rsync.1#opt) update of a file
+   that is being refused due to the Linux fs.protected_regular sysctl setting.
+
+ - When [`--chown`](rsync.1#opt), [`--usermap`](rsync.1#opt), or
+   [`--groupmap`](rsync.1#opt) is specified, rsync now makes sure that the
+   appropriate [`--owner`](rsync.1#opt) and/or [`--group`](rsync.1#opt) options
+   are enabled.
+
+ - Added the [`--info=NONREG`](rsync.1#opt) setting to control if rsync should
+   warn about non-regular files in the transfer.  This is enabled by default
+   (keeping the behavior the same as before), so specifying `--info=nonreg0`
+   can be used to turn the warnings off.
+
+ - An optional asm optimization for the rolling checksum from Shark64. Enable
+   it with `./configure --enable-roll-asm`.
+
+ - Using `--debug=FILTER` now outputs a caution message if a filter rule
+   has trailing whitespace.
+
+ - Transformed rrsync into a python script with improvements:
+   - Security has been beefed up.
+   - The known rsync options were updated to include recent additions.
+   - Make rrsync reject [`--copy-links`](rsync.1#opt) (`-L`),
+     [`--copy-dirlinks`](rsync.1#opt) (`-k`), &
+     [`--keep-dirlinks`](rsync.1#opt) (`-K`) by default to make it harder to
+     exploit any out-of-subdir symlinks.
+   - A new rrsync option of [`-munge`](rrsync.1#opt) tells rrsync to always
+     enable rsync's [`--munge-links`](rsync.1#opt) option on the server side.
+   - A new rrsync option of [`-no-lock`](rrsync.1#opt) disables a new
+     single-use locking idiom that is the default when [`-ro`](rrsync.1#opt) is
+     not used (useful with [`-munge`](rrsync.1#opt)).
+   - A new rrsync option of [`-no-del`](rrsync.1#opt) disables all `--remove*`
+     and `--delete*` rsync options on the server side.
+   - The log format has been tweaked slightly to add seconds to the timestamp
+     and to output the command executed as a tuple (making the args clearer).
+   - An rrsync.1 manpage was added (in the support dir with rrsync).
+
+ - Added options to the lsh script to facilitate rrsync testing. (See the
+   support dir.)
+
+ - Transformed the atomic-rsync script into a python script and added the
+   ability to ignore one or more non-zero exit codes.  By default, it now
+   ignores code 24, the file-vanished exit code. (See the support dir.)
+
+ - Transformed the munge-symlinks script into python. (See the support dir.)
+
+ - Improved the rsync-no-vanished script to not join stdout & stderr together.
+   (See the support dir.)
+
+ - Work around a glibc bug where lchmod() breaks in a chroot w/o /proc mounted.
+
+ - Try to support a client that sent a remote rsync a wacko stderr file handle
+   (such as an older File::RsyncP perl library used by BackupPC).
+
+ - Lots of manpage improvements, including better HTML versions.
+
+### PACKAGING RELATED:
+
+ - Give configure the `--with-rrsync` option if you want `make install` to
+   install the (now python3) rrsync script and its new manpage.
+
+ - If the rrsync script is installed, its package should be changed to depend
+   on python3 and the (suggested but not mandatory) python3 braceexpand lib.
+
+ - When creating a package from a non-release version (w/o a git checkout), the
+   packager can elect to create git-version.h and define RSYNC_GITVER to the
+   string they want `--version` to output.  (The file is still auto-generated
+   using the output of `git describe` when building inside a non-shallow git
+   checkout, though.)
+
+ - Renamed configure's `--enable-simd` option to `--enable-roll-simd` and added
+   the option `--enable-roll-asm` to use the new asm version of the code.  Both
+   are x86_64/amd64 only.
+
+ - Renamed configure's `--enable-asm` option to `--enable-md5-asm` to avoid
+   confusion with the asm option for the rolling checksum.  It is also honored
+   even when openssl crypto is in use.  This allows: normal MD4 & MD5, normal
+   MD4 + asm MD5, openssl MD4 & MD5, or openssl MD4 + asm MD5 depending on the
+   configure options selected.
+
+ - Made SIMD & asm configure checks default to "no" on non-Linux hosts due to
+   various reports of problems on NetBSD & macOS hosts.  These were also
+   tweaked to allow enabling the feature on a host_cpu of amd64 (was only
+   allowed on x86_64 before).
+
+ - Fixed configure to not fail at the SIMD check when cross-compiling.
+
+ - Improved the IPv6 determination in configure.
+
+ - Compile the C files with `-pedantic-errors` (when possible) so that we will
+   get warned if a static initialization overflows in the future (among other
+   things).
+
+ - When linking with an external zlib, rsync renames its `read_buf()` function
+   to `read_buf_()` to avoid a symbol clash on an unpatched zlib.
+
+ - Added a SECURITY.md file.
+
+### DEVELOPER RELATED:
+
+ - Made it easier to write rsync tests that diff the output while also checking
+   the status code, and used the idiom to improve the existing tests. (See the
+   `checkdiff` and `checkdiff2` idioms in the `testsuite/*.test` files.
+
+ - The packaging scripts & related python lib got some minor enhancements.
+
+### INTERNAL
+
+ - Use setenv() instead of putenv() when it is available.
+
+ - Improve the logic in compat.c so that we don't need to try to remember to
+   sprinkle `!local_server` exceptions throughout the protocol logic.
+
+ - One more C99 Flexible Array improvement (started in the last release) and
+   make use of the C99 `%zd` format string when printing size_t values (when
+   possible).
+
+ - Use mallinfo2() instead of mallinfo(), when available.
+
+------------------------------------------------------------------------------
 
 # NEWS for rsync 3.2.3 (6 Aug 2020)
 
  - Fixed a bug in the xattr code that was not leaving room for the "rsync."
    prefix in some instances where it needed to be added.
 
- - Restored the ability to use `--bwlimit=0` to specify no bandwidth limit.  (It
-   was accidentally broken in 3.2.2.)
+ - Restored the ability to use [`--bwlimit=0`](rsync.1#opt) to specify no
+   bandwidth limit.  (It was accidentally broken in 3.2.2.)
 
- - Fix a bug when combining `--delete-missing-args` with `--no-implied-dirs` &
-   `-R` where rsync might create the destination path of a missing arg.  The
-   code also avoids some superfluous warnings for nested paths of removed args.
+ - Fixed a bug when combining [`--delete-missing-args`](rsync.1#opt) with
+   [`--no-implied-dirs`](rsync.1#opt) & [`-R`](rsync.1#opt) where rsync might
+   create the destination path of a missing arg.  The code also avoids some
+   superfluous warnings for nested paths of removed args.
 
  - Fixed an issue where hard-linked devices could cause the rdev_major value to
    get out of sync between the sender and the receiver, which could cause a
    device to get created with the wrong major value in its major,minor pair.
 
- - Rsync now complains about a missing `--temp-dir` before starting any file
-   transfers.
+ - Rsync now complains about a missing [`--temp-dir`](rsync.1#opt) before
+   starting any file transfers.
 
  - A completely empty source arg is now a fatal error.  This doesn't change
    the handling of implied dot-dir args such as "localhost:" and such.
 
 ### ENHANCEMENTS:
 
- - Allow `--max-alloc=0` to specify no limit to the alloc sanity check.
+ - Allow [`--max-alloc=0`](rsync.1#opt) to specify no limit to the alloc sanity
+   check.
 
- - Allow `--block-size=SIZE` to specify the size using units (e.g. "100K").
+ - Allow [`--block-size=SIZE`](rsync.1#opt) to specify the size using units
+   (e.g. "100K").
 
  - The name of the id-0 user & group are now sent to the receiver along with
    the other user/group names in the transfer (instead of assuming that both
    sides have the same id-0 names).
 
- - Added the `--stop-after=MINS` and `--stop-at=DATE_TIME` options (with the
-   `--time-limit=MINS` option accepted as an alias for `--stop-after`).  This
-   is an enhanced version of the time-limit patch from the patches repo.
-
- - Added the `name converter` daemon parameter to make it easier to convert
-   user & group names inside a chrooted daemon module.  This is based on the
-   nameconverter patch with some improvements, including a tweak to the request
-   protocol (so if you used this patch in the past, be sure to update your
-   converter script to use newlines instead of null chars).
-
- - Added `--crtimes` (`-N`) option for preserving the file's create time (I
-   believe that this is macOS only at the moment).
-
- - Added `--mkpath` option to tell rsync that it should create a non-existing
-   path component of the destination arg.
-
- - Added `--stderr=errors|all|client` to replace the `--msgs2stderr` and
-   `--no-msgs2stderr` options (which are still accepted).  The default use of
-   stderr was changed to be `--stderr=errors` where all the processes that have
-   stderr available output directly to stderr, which should help error messages
-   get to the user more quickly, especially when doing a push (which includes
-   local copying).  This also allows rsync to exit quickly when a receiver
-   failure occurs, since rsync doesn't need to try to keep the connection alive
-   long enough for the fatal error to go from the receiver to the generator to
-   the sender.  The old default can be requested via `--stderr=client`.  Also
-   changed is that a non-default stderr mode is conveyed to the remote rsync
-   (using the older option names) instead of requiring the user to use
-   `--remote-option` (`-M`) to tell the remote rsync what to do.
-
- - Added the ability to specify "@netgroup" names to the `hosts allow` and
-   `hosts deny` daemon parameters.  This is a finalized version of the
-   netgroup-auth patch from the patches repo.
-
- - Rsync can now hard-link symlinks on FreeBSD due to it making ues of the
+ - Added the [`--stop-after`](rsync.1#opt) and [`--stop-at`](rsync.1#opt)
+   options (with a [`--time-limit`](rsync.1#opt) alias for `--stop-after`).
+   This is an enhanced version of the time-limit patch from the patches repo.
+
+ - Added the [`name converter`](rsyncd.conf.5#opt) daemon parameter to make it
+   easier to convert user & group names inside a chrooted daemon module.  This
+   is based on the nameconverter patch with some improvements, including a
+   tweak to the request protocol (so if you used this patch in the past, be
+   sure to update your converter script to use newlines instead of null chars).
+
+ - Added [`--crtimes`](rsync.1#opt) (`-N`) option for preserving the file's
+   create time (I believe that this is macOS only at the moment).
+
+ - Added [`--mkpath`](rsync.1#opt) option to tell rsync that it should create a
+   non-existing path component of the destination arg.
+
+ - Added [`--stderr=errors|all|client`](rsync.1#opt) to replace the
+   `--msgs2stderr` and `--no-msgs2stderr` options (which are still accepted).
+   The default use of stderr was changed to be `--stderr=errors` where all the
+   processes that have stderr available output directly to stderr, which should
+   help error messages get to the user more quickly, especially when doing a
+   push (which includes local copying).  This also allows rsync to exit quickly
+   when a receiver failure occurs, since rsync doesn't need to try to keep the
+   connection alive long enough for the fatal error to go from the receiver to
+   the generator to the sender.  The old default can be requested via
+   `--stderr=client`.  Also changed is that a non-default stderr mode is
+   conveyed to the remote rsync (using the older option names) instead of
+   requiring the user to use [`--remote-option`](rsync.1#opt) (`-M`) to tell
+   the remote rsync what to do.
+
+ - Added the ability to specify "@netgroup" names to the [`hosts
+   allow`](rsyncd.conf.5#opt) and [`hosts deny`](rsyncd.conf.5#opt) daemon
+   parameters.  This is a finalized version of the netgroup-auth patch from the
+   patches repo.
+
+ - Rsync can now hard-link symlinks on FreeBSD due to it making use of the
    linkat() function when it is available.
 
  - Output file+line info on out-of-memory & overflow errors while also avoiding
    (with a fallback to the old 1-char string kluge for older compilers).
 
 ------------------------------------------------------------------------------
-<a name="3.2.2"></a>
 
 # NEWS for rsync 3.2.2 (4 Jul 2020)
 
 
  - Put optimizations into their own list in the `--version` output.
 
- - Improved the man page a bit more.
+ - Improved the manpage a bit more.
 
 ### PACKAGING RELATED:
 
    can create the interrelated structs and accessors that loadparm.c needs.
 
 ------------------------------------------------------------------------------
-<a name="3.2.1"></a>
 
 # NEWS for rsync 3.2.1 (22 Jun 2020)
 
  - Merged the OLDNEWS.md file into NEWS.md.
 
 ------------------------------------------------------------------------------
-<a name="3.2.0"></a>
 
 # NEWS for rsync 3.2.0 (19 Jun 2020)
 
  - The daemon now locks its pid file (when configured to use one) so that it
    will not fail to start when the file exists but no daemon is running.
 
- - Various man page improvements, including some html representations (that
+ - Various manpage improvements, including some html representations (that
    aren't installed by default).
 
  - Made `-V` the short option for `--version` and improved its information.
 
  - Add installed bash script: /usr/bin/rsync-ssl
 
- - Add installed man page: /usr/man/man1/rsync-ssl.1
+ - Add installed manpage: /usr/man/man1/rsync-ssl.1
 
  - Tweak auxiliary doc file names, such as: README.md, INSTALL.md, & NEWS.md.
 
    SIMD checksum optimizations.
 
  - Add _build_ dependency for _either_ python3-cmarkcfm or python3-commonmark
-   to allow for patching of man pages or building a git release.  This is not
-   required for a release-tar build, since it comes with pre-built man pages.
+   to allow for patching of manpages or building a git release.  This is not
+   required for a release-tar build, since it comes with pre-built manpages.
    Note that cmarkcfm is faster than commonmark, but they generate the same
    data.  The commonmark dependency is easiest to install since it's native
    python, and can even be installed via `pip3 install --user commonmark` if
  - Silenced some annoying warnings about major() & minor() by improving an
    autoconf include-file check.
 
- - Converted the man pages from yodl to markdown. They are now processed via a
+ - Converted the manpages from yodl to markdown. They are now processed via a
    simple python3 script using the cmarkgfm **or** commonmark library.  This
    should make it easier to package rsync, since yodl is rather obscure.
 
  - Some code typos were fixed (as pointed out by a Fossies run).
 
 ------------------------------------------------------------------------------
-<a name="3.1.3"></a>
 
 # NEWS for rsync 3.1.3 (28 Jan 2018)
 
 
  - Don't output about a new backup dir without appropriate info verbosity.
 
- - Fixed some issues with the sort functions in support/rsyncstats script.
+ - Fixed some issues with the sort functions in the rsyncstats script (in the
+   support dir).
 
  - Added a way to specify daemon config lists (e.g. users, groups, etc) that
    contain spaces (see `auth users` in the latest rsyncd.conf manpage).
 
 ### DEVELOPER RELATED:
 
- - Tweak the `make` output when yodl isn't around to create the man pages.
+ - Tweak the `make` output when yodl isn't around to create the manpages.
 
  - Changed an obsolete autoconf compile macro.
 
- - Support newer yodl versions when converting man pages.
+ - Support newer yodl versions when converting manpages.
 
 ------------------------------------------------------------------------------
-<a name="3.1.2"></a>
 
 # NEWS for rsync 3.1.2 (21 Dec 2015)
 
  - Improved the m4 generation rules and some autoconf idioms.
 
 ------------------------------------------------------------------------------
-<a name="3.1.1"></a>
 
 # NEWS for rsync 3.1.1 (22 Jun 2014)
 
    non-bundled zlib. See the `--new-compress` and `--old-compress` options in
    the manpage.
 
- - Added the support/rsync-no-vanished wrapper script.
+ - Added the rsync-no-vanished shell script. (See the support dir.)
 
  - Made configure more prominently mention when we failed to find yodl (in case
    the user wants to be able to generate manpages from `*.yo` files).
    and/or zlib code is put early in the CFLAGS.
 
 ------------------------------------------------------------------------------
-<a name="3.1.0"></a>
 
 # NEWS for rsync 3.1.0 (28 Sep 2013)
 
  - Fixed a bug in the iconv code when EINVAL or EILSEQ is returned with a full
    output buffer.
 
- - Fixed some rare bugs in `--iconv` processing that might cause a multibyte
+ - Fixed some rare bugs in `--iconv` processing that might cause a multi-byte
    character to get translated incorrectly.
 
  - Fixed a bogus `vanished file` error if some files were specified with `./`
    hard-link it into place so that the upcoming replacement of the destination
    file will be atomic (for the normal, non-inplace logic).
 
- - Added the ability to synchronize nano-second modified times.
+ - Added the ability to synchronize nanosecond modified times.
 
  - Added a few more default suffixes for the `dont compress` settings.
 
  - Fixed some build issues for Android and Minix.
 
 ------------------------------------------------------------------------------
-<a name="3.0.9"></a>
 
 # NEWS for rsync 3.0.9 (23 Sep 2011)
 
 
  - Avoid trying to reference `SO_BROADCAST` if the OS doesn't support it.
 
- - Fix some issues with the post-processing of the man pages.
+ - Fix some issues with the post-processing of the manpages.
 
- - Fixed the user home-dir handling in the support/lsh script.
+ - Fixed the user home-dir handling in the lsh script. (See the support dir.)
 
  - Some minor manpage improvements.
 
 ------------------------------------------------------------------------------
-<a name="3.0.8"></a>
 
 # NEWS for rsync 3.0.8 (26 Mar 2011)
 
    reject an attempt to supply one (can configure `--with-included-popt` if
    your system's popt library doesn't yet have this fix).
 
- - A couple minor option tweaks to the support/rrsync script, and also some
-   regex changes that make vim highlighting happier.
+ - A couple minor option tweaks to the rrsync script, and also some regex
+   changes that make vim highlighting happier. (See the support dir.)
 
- - Fixed some issues in the support/mnt-excl script.
+ - Fixed some issues in the mnt-excl script. (See the support dir.)
 
  - Various manpage improvements.
 
  - Fixed the testsuite/xattrs.test script on OS X.
 
 ------------------------------------------------------------------------------
-<a name="3.0.7"></a>
 
 # NEWS for rsync 3.0.7 (31 Dec 2009)
 
    that hasn't really been created.
 
  - Fixed a problem with `--compress` (`-z`) where the receiving side could
-   return the error "inflate (token) returned -5".
+   return the error "`inflate (token) returned -5`".
 
  - Fixed a bug where `--delete-during` could delete in a directory before it
    noticed that the sending side sent an I/O error for that directory (both
  - An absolute-path filter rule (i.e. with a '/' modifier) no longer loses its
    modifier when sending the filter rules to the remote rsync.
 
- - Improved the "--delete does not work without -r or -d" message.
+ - Improved the "`--delete does not work without -r or -d`" message.
 
  - Improved rsync's handling of `--timeout` to avoid a weird timeout case where
    the sender could timeout even though it has recently written data to the
  - The testsuite no longer uses `id -u`, so it works better on Solaris.
 
 ------------------------------------------------------------------------------
-<a name="3.0.6"></a>
 
 # NEWS for rsync 3.0.6 (8 May 2009)
 
  - Fixed an failure transferring special files from Solaris to Linux.
 
 ------------------------------------------------------------------------------
-<a name="3.0.5"></a>
 
 # NEWS for rsync 3.0.5 (28 Dec 2008)
 
 
 ### ENHANCEMENTS:
 
- - Made the support/atomic-rsync script able to perform a fully atomic update
-   of the copied hierarchy when the destination is setup using a particular
-   symlink idiom.
+ - Made the atomic-rsync script able to perform a fully atomic update of the
+   copied hierarchy when the destination is setup using a particular symlink
+   idiom. (See the support dir.)
 
 ------------------------------------------------------------------------------
-<a name="3.0.4"></a>
 
 # NEWS for rsync 3.0.4 (6 Sep 2008)
 
    even more consistency checks on the files.
 
 ------------------------------------------------------------------------------
-<a name="3.0.3"></a>
 
 # NEWS for rsync 3.0.3 (29 Jun 2008)
 
    of files, and the ensuring that daemon excludes can't affect a dot-dir arg.
 
  - Improved some build rules for those that build in a separate directory from
-   the source, including better install rules for the man pages, and the fixing
+   the source, including better install rules for the manpages, and the fixing
    of a proto.h-tstamp rule that could make the binaries get rebuild without
    cause.
 
- - Improved the testsuite to work around a problem with some utilities (e.g. cp
-   -p & touch -r) rounding sub-second timestamps.
+ - Improved the testsuite to work around a problem with some utilities (e.g.
+   `cp -p` & `touch -r`) rounding sub-second timestamps.
 
  - Ensure that the early patches don't cause any generated-file hunks to
    bleed-over into patches that follow.
 
 ------------------------------------------------------------------------------
-<a name="3.0.2"></a>
 
 # NEWS for rsync 3.0.2 (8 Apr 2008)
 
    packaging dir.
 
 ------------------------------------------------------------------------------
-<a name="3.0.1"></a>
 
 # NEWS for rsync 3.0.1 (3 Apr 2008)
 
 
  - Fixed the inclusion of per-dir merge files from implied dirs.
 
- - Fixed the support/rrsync script to work with the latest options that rsync
-   sends (including its flag-specifying use of `-e` to the server).
+ - Fixed the rrsync script to work with the latest options that rsync sends,
+   including its flag-specifying use of `-e` to the server. (See the support
+   dir.)
 
 ### ENHANCEMENTS:
 
  - Updated the build scripts to work with a revised FTP directory structure.
 
 ------------------------------------------------------------------------------
-<a name="3.0.0"></a>
 
 # NEWS for rsync 3.0.0 (1 Mar 2008)
 
    the 3.0.0 release.
 
 ------------------------------------------------------------------------------
-<a name="2.6.9"></a>
 
 # NEWS for rsync 2.6.9 (6 Nov 2006)
 
 
  - Added the `--log-file=FILE` and `--log-file-format=FORMAT` options. These
    can be used to tell any rsync to output what it is doing to a log file.
-   They work with a client rsync, a non-daemon server rsync (see the man page
+   They work with a client rsync, a non-daemon server rsync (see the manpage
    for instructions), and also allows the overriding of rsyncd.conf settings
    when starting a daemon.
 
    consistent opening comments.
 
 ------------------------------------------------------------------------------
-<a name="2.6.8"></a>
 
 # NEWS for rsync 2.6.8 (22 Apr 2006)
 
    actions to a file (something that only a daemon supports at present).
 
 ------------------------------------------------------------------------------
-<a name="2.6.7"></a>
 
 # NEWS for rsync 2.6.7 (11 Mar 2006)
 
    option, below.
 
  - The way rsync escapes unreadable characters has changed. First, rsync now
-   has support for recognizing valid multibyte character sequences in your
+   has support for recognizing valid multi-byte character sequences in your
    current locale, allowing it to escape fewer characters than before for a
    locale such as UTF-8. Second, it now uses an escape idiom of `\#123`, which
    is the literal string `\#` followed by exactly 3 octal digits. Rsync no
  - Added two config items to the rsyncd.conf parsing: `pre-xfer exec` and
    `post-xfer exec`. These allow a command to be specified on a per-module
    basis that will be run before and/or after a daemon-mode transfer. (See the
-   man page for a list of the environment variables that are set with
+   manpage for a list of the environment variables that are set with
    information about the transfer.)
 
  - When using the `--relative` option, you can now insert a dot dir in the
    ~/.popt.
 
 ------------------------------------------------------------------------------
-<a name="2.6.6"></a>
 
 # NEWS for rsync 2.6.6 (28 Jul 2005)
 
  - Made the `max verbosity` setting in the rsyncd.conf file settable on a
    per-module basis (which now matches the documentation).
 
- - The support/rrsync script has been upgraded to verify the args of options
-   that take args (instead of rejecting any such options). The script was also
-   changed to try to be more secure and to fix a problem in the parsing of a
-   pull operation that has multiple sources.
+ - The rrsync script has been upgraded to verify the args of options that take
+   args (instead of rejecting any such options). It was also changed to try to
+   be more secure and to fix a problem in the parsing of a pull operation that
+   has multiple source args. (See the support dir.)
 
  - Improved the documentation that explains the difference between a normal
    daemon transfer and a daemon-over remote-shell transfer.
    (log-format w/%i) and some double-verbose messages.
 
 ------------------------------------------------------------------------------
-<a name="2.6.5"></a>
 
 # NEWS for rsync 2.6.5 (1 Jun 2005)
 
    usually run with the `--no-detach` option that was necessary to see the
    error on stderr).
 
- - The man pages now consistently refer to an rsync daemon as a `daemon`
+ - The manpages now consistently refer to an rsync daemon as a `daemon`
    instead of a `server` (to distinguish it from the server process in a
    non-daemon transfer).
 
    enables the optional copying of extended attributes.
 
 ------------------------------------------------------------------------------
-<a name="2.6.4"></a>
 
 # NEWS for rsync 2.6.4 (30 March 2005)
 
  - Improved configure to better handle cross-compiling.
 
 ------------------------------------------------------------------------------
-<a name="2.6.3"></a>
 
 # NEWS for rsync 2.6.3 (30 Sep 2004)
 
    without using a temporary file. The matching of existing data in the
    destination file can be severely limited by this, but there are also cases
    where this is more efficient (such as appending data).  Use only when needed
-   (see the man page for more details).
+   (see the manpage for more details).
 
  - Added the `write only` option for the daemon's config file.
 
  - Added long-option names for `-4` and `-6` (namely `--ipv4` and `--ipv6`) and
-   documented all these options in the man page.
+   documented all these options in the manpage.
 
  - Improved the handling of the `--bwlimit` option so that it's less bursty,
    more accurate, and works properly over a larger range of values.
 ### BUILD CHANGES:
 
  - Added a `gen` target to rebuild most of the generated files, including
-   configure, config.h.in, the man pages, and proto.h.
+   configure, config.h.in, the manpages, and proto.h.
 
  - If `make proto` doesn't find some changes in the prototypes, the proto.h
    file is left untouched (its time-stamp used to always be updated).
    removed.
 
 ------------------------------------------------------------------------------
-<a name="2.6.2"></a>
 
 # NEWS for rsync 2.6.2 (30 Apr 2004)
 
  - Two new diffs were added to the patches dir.
 
 ------------------------------------------------------------------------------
-<a name="2.6.1"></a>
 
 # NEWS for rsync 2.6.1 (26 Apr 2004)
 
    applied, and rebuilt the rest.
 
 ------------------------------------------------------------------------------
-<a name="2.6.0"></a>
 
 # NEWS for rsync 2.6.0 (1 Jan 2004)
 
    other side (primarily for testing purposes).  (Wayne Davison)
 
 ------------------------------------------------------------------------------
-<a name="2.5.7"></a>
 
 # NEWS for rsync 2.5.7 (4 Dec 2003)
 
    Andrea Barisani)
 
 ------------------------------------------------------------------------------
-<a name="2.5.6"></a>
 
 # NEWS for rsync 2.5.6, aka "the dwd-between-jobs release" (26 Jan 2003)
 
    should build on more platforms. (Paul Green)
 
 ------------------------------------------------------------------------------
-<a name="2.5.5"></a>
 
 # NEWS for rsync 2.5.5, aka Snowy River (2 Apr 2002)
 
  - Improved network error handling. (Greg A. Woods)
 
 ------------------------------------------------------------------------------
-<a name="2.5.4"></a>
 
 # NEWS for rsync 2.5.4, aka "Imitation lizard skin" (13 Mar 2002)
 
  - Additional test cases for `--compress`. (Martin Pool)
 
 ------------------------------------------------------------------------------
-<a name="2.5.3"></a>
 
 # NEWS for rsync 2.5.3, aka "Happy 26" (11 Mar 2002)
 
  - Added `--no-whole-file` and `--no-blocking-io` options (Dave Dykstra)
 
  - Made the `--write-batch` and `--read-batch` options actually work and added
-   documentation in the man page (Jos Backus)
+   documentation in the manpage (Jos Backus)
 
  - If the daemon is unable to fork a child to accept a connection, print an
    error message. (Colin Walters)
 
 ------------------------------------------------------------------------------
-<a name="2.5.2"></a>
 
 # NEWS for rsync 2.5.2 (26 Jan 2002)
 
    Razor. (Debian #124286)
 
 ------------------------------------------------------------------------------
-<a name="2.5.1"></a>
 
 # NEWS for rsync 2.5.1 (3 Jan 2002)
 
  - Clearer error messages for some conditions.
 
 ------------------------------------------------------------------------------
-<a name="2.5.0"></a>
 
 # NEWS for rsync 2.5.0 (30 Nov 2001)
 
    - HP PA-RISC HP-UX 11.11 cc
    - IRIX 6.5 MIPS cc
    - IRIX 6.5 MIPS gcc
-   - Mac OS X PPC (--disable-ipv6) cc
+   - Mac OS X PPC (`--disable-ipv6`) cc
    - NetBSD 1.5 i386 gcc
    - NetBSD Current i386 cc
    - OpenBSD 2.5 Sparc gcc
 
 | RELEASE DATE | VER.   | DATE OF COMMIT\* | PROTOCOL    |
 |--------------|--------|------------------|-------------|
+| 20 Oct 2022  | 3.2.7  |                  | 31          |
+| 09 Sep 2022  | 3.2.6  |                  | 31          |
+| 14 Aug 2022  | 3.2.5  |                  | 31          |
+| 15 Apr 2022  | 3.2.4  |                  | 31          |
 | 06 Aug 2020  | 3.2.3  |                  | 31          |
 | 04 Jul 2020  | 3.2.2  |                  | 31          |
 | 22 Jun 2020  | 3.2.1  |                  | 31          |
 
 \* DATE OF COMMIT is the date the protocol change was committed to version
 control.
+
+@USE_GFM_PARSER@
index 45c3d74..a86c771 100644 (file)
--- a/README.md
+++ b/README.md
@@ -23,8 +23,9 @@ options.  To get a complete list of supported options type:
 
     rsync --help
 
-See the manpage for more detailed information.
+See the [manpage][0] for more detailed information.
 
+[0]: https://download.samba.org/pub/rsync/rsync.1
 
 BUILDING AND INSTALLING
 -----------------------
@@ -64,8 +65,8 @@ RSYNC DAEMONS
 -------------
 
 Rsync can also talk to "rsync daemons" which can provide anonymous or
-authenticated rsync.  See the rsyncd.conf(5) man page for details on how
-to setup an rsync daemon.  See the rsync(1) man page for info on how to
+authenticated rsync.  See the rsyncd.conf(5) manpage for details on how
+to setup an rsync daemon.  See the rsync(1) manpage for info on how to
 connect to an rsync daemon.
 
 
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644 (file)
index 0000000..c243574
--- /dev/null
@@ -0,0 +1,12 @@
+# Security Policy
+
+## Supported Versions
+
+Only the current release of the software is actively supported.  If you need
+help backporting fixes into an older release, feel free to ask.
+
+## Reporting a Vulnerability
+
+Email your vulnerability information to rsync's maintainer:
+
+  Wayne Davison <wayne@opencoder.net>
index 39a7752..b6afce3 100644 (file)
--- a/access.c
+++ b/access.c
@@ -2,7 +2,7 @@
  * Routines to authenticate access to a daemon (hosts allow/deny).
  *
  * Copyright (C) 1998 Andrew Tridgell
- * Copyright (C) 2004-2020 Wayne Davison
+ * Copyright (C) 2004-2022 Wayne Davison
  *
  * 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
@@ -20,6 +20,9 @@
 
 #include "rsync.h"
 #include "ifuncs.h"
+#ifdef HAVE_NETGROUP_H
+#include <netgroup.h>
+#endif
 
 static int allow_forward_dns;
 
index 9c6d413..62b3bc3 100644 (file)
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -12,6 +12,6 @@
 # PARTICULAR PURPOSE.
 
 m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
-m4_include([m4/have_type.m4])
-m4_include([m4/header_major_fixed.m4])
-m4_include([m4/socklen_t.m4])
+m4_include([../m4/have_type.m4])
+m4_include([../m4/header_major_fixed.m4])
+m4_include([../m4/socklen_t.m4])
diff --git a/acls.c b/acls.c
index 4303c2a..3cf12ee 100644 (file)
--- a/acls.c
+++ b/acls.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
- * Copyright (C) 2006-2020 Wayne Davison
+ * Copyright (C) 2006-2022 Wayne Davison
  *
  * 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
@@ -519,6 +519,7 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl,
 
                sys_acl_free_acl(sacl);
                if (!ok) {
+                       rsyserr(FERROR_XFER, errno, "get_acl: unpack_smb_acl(%s)", fname);
                        return -1;
                }
        } else if (no_acl_syscall_error(errno)) {
@@ -763,6 +764,7 @@ static int recv_rsync_acl(int f, item_list *racl_list, SMB_ACL_TYPE_T type, mode
 #ifdef HAVE_OSX_ACLS
        /* If we received a superfluous mask, throw it away. */
        duo_item->racl.mask_obj = NO_ENTRY;
+       (void)mode;
 #else
        if (duo_item->racl.names.count && duo_item->racl.mask_obj == NO_ENTRY) {
                /* Mask must be non-empty with lists. */
index 4306d16..b7f6ead 100644 (file)
@@ -2,7 +2,7 @@
  * Support rsync daemon authentication.
  *
  * Copyright (C) 1998-2000 Andrew Tridgell
- * Copyright (C) 2002-2020 Wayne Davison
+ * Copyright (C) 2002-2022 Wayne Davison
  *
  * 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
@@ -24,6 +24,7 @@
 
 extern int read_only;
 extern char *password_file;
+extern struct name_num_obj valid_auth_checksums;
 
 /***************************************************************************
 encode a buffer using base64 - simple and slow algorithm. null terminates
@@ -72,9 +73,9 @@ static void gen_challenge(const char *addr, char *challenge)
        SIVAL(input, 20, tv.tv_usec);
        SIVAL(input, 24, getpid());
 
-       sum_init(-1, 0);
+       len = sum_init(valid_auth_checksums.negotiated_nni, 0);
        sum_update(input, sizeof input);
-       len = sum_end(digest);
+       sum_end(digest);
 
        base64_encode(digest, len, challenge, 0);
 }
@@ -86,10 +87,10 @@ static void generate_hash(const char *in, const char *challenge, char *out)
        char buf[MAX_DIGEST_LEN];
        int len;
 
-       sum_init(-1, 0);
+       len = sum_init(valid_auth_checksums.negotiated_nni, 0);
        sum_update(in, strlen(in));
        sum_update(challenge, strlen(challenge));
-       len = sum_end(buf);
+       sum_end(buf);
 
        base64_encode(buf, len, out, 0);
 }
@@ -238,6 +239,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
        if (!users || !*users)
                return "";
 
+       negotiate_daemon_auth(f_out, 0);
        gen_challenge(addr, challenge);
 
        io_printf(f_out, "%s%s\n", leader, challenge);
@@ -350,6 +352,7 @@ void auth_client(int fd, const char *user, const char *challenge)
 
        if (!user || !*user)
                user = "nobody";
+       negotiate_daemon_auth(-1, 1);
 
        if (!(pass = getpassf(password_file))
         && !(pass = getenv("RSYNC_PASSWORD"))) {
index be406be..686cb29 100644 (file)
--- a/backup.c
+++ b/backup.c
@@ -2,7 +2,7 @@
  * Backup handling code.
  *
  * Copyright (C) 1999 Andrew Tridgell
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -304,7 +304,8 @@ int make_backup(const char *fname, BOOL prefer_rename)
 #endif
 
        if (!ret && !S_ISREG(file->mode)) {
-               rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname);
+               if (INFO_GTE(NONREG, 1))
+                       rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname);
                unmake_file(file);
 #ifdef SUPPORT_ACLS
                uncache_tmp_acls();
diff --git a/batch.c b/batch.c
index a9711c5..accc4c6 100644 (file)
--- a/batch.c
+++ b/batch.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1999 Weiss
  * Copyright (C) 2004 Chris Shoemaker
- * Copyright (C) 2004-2020 Wayne Davison
+ * Copyright (C) 2004-2022 Wayne Davison
  *
  * 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
@@ -194,7 +194,7 @@ static int write_opt(const char *opt, const char *arg)
 {
        int len = strlen(opt);
        int err = write(batch_sh_fd, " ", 1) != 1;
-       err = write(batch_sh_fd, opt, len) != len ? 1 : 0; 
+       err = write(batch_sh_fd, opt, len) != len ? 1 : 0;
        if (arg) {
                err |= write(batch_sh_fd, "=", 1) != 1;
                err |= write_arg(arg);
index 525eaba..059cc70 100644 (file)
@@ -2,7 +2,7 @@
  * Simple byteorder handling.
  *
  * Copyright (C) 1992-1995 Andrew Tridgell
- * Copyright (C) 2007-2020 Wayne Davison
+ * Copyright (C) 2007-2022 Wayne Davison
  *
  * 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
@@ -129,4 +129,3 @@ SIVAL(char *buf, int pos, uint32 val)
 {
        SIVALu((uchar*)buf, pos, val);
 }
-
index 1ed7682..60de365 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
- * Copyright (C) 2004-2020 Wayne Davison
+ * Copyright (C) 2004-2022 Wayne Davison
  *
  * 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
@@ -42,41 +42,94 @@ extern int protocol_version;
 extern int proper_seed_order;
 extern const char *checksum_choice;
 
-struct name_num_obj valid_checksums = {
-       "checksum", NULL, NULL, 0, 0, {
+#define NNI_BUILTIN (1<<0)
+#define NNI_EVP (1<<1)
+#define NNI_EVP_OK (1<<2)
+
+struct name_num_item valid_checksums_items[] = {
 #ifdef SUPPORT_XXH3
-               { CSUM_XXH3_128, "xxh128", NULL },
-               { CSUM_XXH3_64, "xxh3", NULL },
+       { CSUM_XXH3_128, 0, "xxh128", NULL },
+       { CSUM_XXH3_64, 0, "xxh3", NULL },
 #endif
 #ifdef SUPPORT_XXHASH
-               { CSUM_XXH64, "xxh64", NULL },
-               { CSUM_XXH64, "xxhash", NULL },
+       { CSUM_XXH64, 0, "xxh64", NULL },
+       { CSUM_XXH64, 0, "xxhash", NULL },
 #endif
-               { CSUM_MD5, "md5", NULL },
-               { CSUM_MD4, "md4", NULL },
-               { CSUM_NONE, "none", NULL },
-               { 0, NULL, NULL }
-       }
+       { CSUM_MD5, NNI_BUILTIN|NNI_EVP, "md5", NULL },
+       { CSUM_MD4, NNI_BUILTIN|NNI_EVP, "md4", NULL },
+#ifdef SHA_DIGEST_LENGTH
+       { CSUM_SHA1, NNI_EVP, "sha1", NULL },
+#endif
+       { CSUM_NONE, 0, "none", NULL },
+       { 0, 0, NULL, NULL }
+};
+
+struct name_num_obj valid_checksums = {
+       "checksum", NULL, 0, 0, valid_checksums_items
+};
+
+struct name_num_item valid_auth_checksums_items[] = {
+#ifdef SHA512_DIGEST_LENGTH
+       { CSUM_SHA512, NNI_EVP, "sha512", NULL },
+#endif
+#ifdef SHA256_DIGEST_LENGTH
+       { CSUM_SHA256, NNI_EVP, "sha256", NULL },
+#endif
+#ifdef SHA_DIGEST_LENGTH
+       { CSUM_SHA1, NNI_EVP, "sha1", NULL },
+#endif
+       { CSUM_MD5, NNI_BUILTIN|NNI_EVP, "md5", NULL },
+       { CSUM_MD4, NNI_BUILTIN|NNI_EVP, "md4", NULL },
+       { 0, 0, NULL, NULL }
 };
 
-int xfersum_type = 0; /* used for the file transfer checksums */
-int checksum_type = 0; /* used for the pre-transfer (--checksum) checksums */
+struct name_num_obj valid_auth_checksums = {
+       "daemon auth checksum", NULL, 0, 0, valid_auth_checksums_items
+};
+
+/* These cannot make use of openssl, so they're marked just as built-in */
+struct name_num_item implied_checksum_md4 =
+    { CSUM_MD4, NNI_BUILTIN, "md4", NULL };
+struct name_num_item implied_checksum_md5 =
+    { CSUM_MD5, NNI_BUILTIN, "md5", NULL };
+
+struct name_num_item *xfer_sum_nni; /* used for the transfer checksum2 computations */
+int xfer_sum_len;
+struct name_num_item *file_sum_nni; /* used for the pre-transfer --checksum computations */
+int file_sum_len, file_sum_extra_cnt;
+
+#ifdef USE_OPENSSL
+const EVP_MD *xfer_sum_evp_md;
+const EVP_MD *file_sum_evp_md;
+EVP_MD_CTX *ctx_evp = NULL;
+#endif
 
-int parse_csum_name(const char *name, int len)
+static int initialized_choices = 0;
+
+struct name_num_item *parse_csum_name(const char *name, int len)
 {
        struct name_num_item *nni;
 
        if (len < 0 && name)
                len = strlen(name);
 
+       init_checksum_choices();
+
        if (!name || (len == 4 && strncasecmp(name, "auto", 4) == 0)) {
-               if (protocol_version >= 30)
-                       return CSUM_MD5;
-               if (protocol_version >= 27)
-                       return CSUM_MD4_OLD;
-               if (protocol_version >= 21)
-                       return CSUM_MD4_BUSTED;
-               return CSUM_MD4_ARCHAIC;
+               if (protocol_version >= 30) {
+                       if (!proper_seed_order)
+                               return &implied_checksum_md5;
+                       name = "md5";
+                       len = 3;
+               } else {
+                       if (protocol_version >= 27)
+                               implied_checksum_md4.num = CSUM_MD4_OLD;
+                       else if (protocol_version >= 21)
+                               implied_checksum_md4.num = CSUM_MD4_BUSTED;
+                       else
+                               implied_checksum_md4.num = CSUM_MD4_ARCHAIC;
+                       return &implied_checksum_md4;
+               }
        }
 
        nni = get_nni_by_name(&valid_checksums, name, len);
@@ -86,44 +139,74 @@ int parse_csum_name(const char *name, int len)
                exit_cleanup(RERR_UNSUPPORTED);
        }
 
-       return nni->num;
+       return nni;
 }
 
-static const char *checksum_name(int num)
+#ifdef USE_OPENSSL
+static const EVP_MD *csum_evp_md(struct name_num_item *nni)
 {
-       struct name_num_item *nni = get_nni_by_num(&valid_checksums, num);
-
-       return nni ? nni->name : num < CSUM_MD4 ? "md4" : "UNKNOWN";
+       const EVP_MD *emd;
+       if (!(nni->flags & NNI_EVP))
+               return NULL;
+
+#ifdef USE_MD5_ASM
+       if (nni->num == CSUM_MD5)
+               emd = NULL;
+       else
+#endif
+               emd = EVP_get_digestbyname(nni->name);                                               
+       if (emd && !(nni->flags & NNI_EVP_OK)) { /* Make sure it works before we advertise it */
+               if (!ctx_evp && !(ctx_evp = EVP_MD_CTX_create()))
+                       out_of_memory("csum_evp_md");
+               /* Some routines are marked as legacy and are not enabled in the openssl.cnf file.
+                * If we can't init the emd, we'll fall back to our built-in code. */
+               if (EVP_DigestInit_ex(ctx_evp, emd, NULL) == 0)
+                       emd = NULL;
+               else
+                       nni->flags = (nni->flags & ~NNI_BUILTIN) | NNI_EVP_OK;
+       }
+       if (!emd)
+               nni->flags &= ~NNI_EVP;
+       return emd;
 }
+#endif
 
 void parse_checksum_choice(int final_call)
 {
-       if (valid_checksums.negotiated_name)
-               xfersum_type = checksum_type = valid_checksums.negotiated_num;
+       if (valid_checksums.negotiated_nni)
+               xfer_sum_nni = file_sum_nni = valid_checksums.negotiated_nni;
        else {
                char *cp = checksum_choice ? strchr(checksum_choice, ',') : NULL;
                if (cp) {
-                       xfersum_type = parse_csum_name(checksum_choice, cp - checksum_choice);
-                       checksum_type = parse_csum_name(cp+1, -1);
+                       xfer_sum_nni = parse_csum_name(checksum_choice, cp - checksum_choice);
+                       file_sum_nni = parse_csum_name(cp+1, -1);
                } else
-                       xfersum_type = checksum_type = parse_csum_name(checksum_choice, -1);
+                       xfer_sum_nni = file_sum_nni = parse_csum_name(checksum_choice, -1);
                if (am_server && checksum_choice)
-                       validate_choice_vs_env(NSTR_CHECKSUM, xfersum_type, checksum_type);
+                       validate_choice_vs_env(NSTR_CHECKSUM, xfer_sum_nni->num, file_sum_nni->num);
        }
+       xfer_sum_len = csum_len_for_type(xfer_sum_nni->num, 0);
+       file_sum_len = csum_len_for_type(file_sum_nni->num, 0);
+#ifdef USE_OPENSSL
+       xfer_sum_evp_md = csum_evp_md(xfer_sum_nni);
+       file_sum_evp_md = csum_evp_md(file_sum_nni);
+#endif
+
+       file_sum_extra_cnt = (file_sum_len + EXTRA_LEN - 1) / EXTRA_LEN;
 
-       if (xfersum_type == CSUM_NONE)
+       if (xfer_sum_nni->num == CSUM_NONE)
                whole_file = 1;
 
        /* Snag the checksum name for both write_batch's option output & the following debug output. */
-       if (valid_checksums.negotiated_name)
-               checksum_choice = valid_checksums.negotiated_name;
+       if (valid_checksums.negotiated_nni)
+               checksum_choice = valid_checksums.negotiated_nni->name;
        else if (checksum_choice == NULL)
-               checksum_choice = checksum_name(xfersum_type);
+               checksum_choice = xfer_sum_nni->name;
 
        if (final_call && DEBUG_GTE(NSTR, am_server ? 3 : 1)) {
                rprintf(FINFO, "%s%s checksum: %s\n",
                        am_server ? "Server" : "Client",
-                       valid_checksums.negotiated_name ? " negotiated" : "",
+                       valid_checksums.negotiated_nni ? " negotiated" : "",
                        checksum_choice);
        }
 }
@@ -143,6 +226,18 @@ int csum_len_for_type(int cst, BOOL flist_csum)
                return MD4_DIGEST_LEN;
          case CSUM_MD5:
                return MD5_DIGEST_LEN;
+#ifdef SHA_DIGEST_LENGTH
+         case CSUM_SHA1:
+               return SHA_DIGEST_LENGTH;
+#endif
+#ifdef SHA256_DIGEST_LENGTH
+         case CSUM_SHA256:
+               return SHA256_DIGEST_LENGTH;
+#endif
+#ifdef SHA512_DIGEST_LENGTH
+         case CSUM_SHA512:
+               return SHA512_DIGEST_LENGTH;
+#endif
          case CSUM_XXH64:
          case CSUM_XXH3_64:
                return 64/8;
@@ -168,6 +263,9 @@ int canonical_checksum(int csum_type)
                break;
          case CSUM_MD4:
          case CSUM_MD5:
+         case CSUM_SHA1:
+         case CSUM_SHA256:
+         case CSUM_SHA512:
                return -1;
          case CSUM_XXH64:
          case CSUM_XXH3_64:
@@ -179,7 +277,7 @@ int canonical_checksum(int csum_type)
        return 0;
 }
 
-#ifndef HAVE_SIMD /* See simd-checksum-*.cpp. */
+#ifndef USE_ROLL_SIMD /* See simd-checksum-*.cpp. */
 /*
   a simple 32 bit checksum that can be updated from either end
   (inspired by Mark Adler's Adler-32 checksum)
@@ -204,7 +302,22 @@ uint32 get_checksum1(char *buf1, int32 len)
 
 void get_checksum2(char *buf, int32 len, char *sum)
 {
-       switch (xfersum_type) {
+#ifdef USE_OPENSSL
+       if (xfer_sum_evp_md) {
+               static EVP_MD_CTX *evp = NULL;
+               uchar seedbuf[4];
+               if (!evp && !(evp = EVP_MD_CTX_create()))
+                       out_of_memory("get_checksum2");
+               EVP_DigestInit_ex(evp, xfer_sum_evp_md, NULL);
+               if (checksum_seed) {
+                       SIVALu(seedbuf, 0, checksum_seed);
+                       EVP_DigestUpdate(evp, seedbuf, 4);
+               }
+               EVP_DigestUpdate(evp, (uchar *)buf, len);
+               EVP_DigestFinal_ex(evp, (uchar *)sum, NULL);
+       } else
+#endif
+       switch (xfer_sum_nni->num) {
 #ifdef SUPPORT_XXHASH
          case CSUM_XXH64:
                SIVAL64(sum, 0, XXH64(buf, len, checksum_seed));
@@ -222,40 +335,26 @@ void get_checksum2(char *buf, int32 len, char *sum)
          }
 #endif
          case CSUM_MD5: {
-               MD5_CTX m5;
+               md_context m5;
                uchar seedbuf[4];
-               MD5_Init(&m5);
+               md5_begin(&m5);
                if (proper_seed_order) {
                        if (checksum_seed) {
                                SIVALu(seedbuf, 0, checksum_seed);
-                               MD5_Update(&m5, seedbuf, 4);
+                               md5_update(&m5, seedbuf, 4);
                        }
-                       MD5_Update(&m5, (uchar *)buf, len);
+                       md5_update(&m5, (uchar *)buf, len);
                } else {
-                       MD5_Update(&m5, (uchar *)buf, len);
+                       md5_update(&m5, (uchar *)buf, len);
                        if (checksum_seed) {
                                SIVALu(seedbuf, 0, checksum_seed);
-                               MD5_Update(&m5, seedbuf, 4);
+                               md5_update(&m5, seedbuf, 4);
                        }
                }
-               MD5_Final((uchar *)sum, &m5);
+               md5_result(&m5, (uchar *)sum);
                break;
          }
          case CSUM_MD4:
-#ifdef USE_OPENSSL
-         {
-               MD4_CTX m4;
-               MD4_Init(&m4);
-               MD4_Update(&m4, (uchar *)buf, len);
-               if (checksum_seed) {
-                       uchar seedbuf[4];
-                       SIVALu(seedbuf, 0, checksum_seed);
-                       MD4_Update(&m4, seedbuf, 4);
-               }
-               MD4_Final((uchar *)sum, &m4);
-               break;
-         }
-#endif
          case CSUM_MD4_OLD:
          case CSUM_MD4_BUSTED:
          case CSUM_MD4_ARCHAIC: {
@@ -288,7 +387,7 @@ void get_checksum2(char *buf, int32 len, char *sum)
                 * are multiples of 64.  This is fixed by calling mdfour_update()
                 * even when there are no more bytes.
                 */
-               if (len - i > 0 || xfersum_type > CSUM_MD4_BUSTED)
+               if (len - i > 0 || xfer_sum_nni->num > CSUM_MD4_BUSTED)
                        mdfour_update(&m, (uchar *)(buf1+i), len-i);
 
                mdfour_result(&m, (uchar *)sum);
@@ -306,15 +405,33 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
        int32 remainder;
        int fd;
 
-       memset(sum, 0, MAX_DIGEST_LEN);
-
        fd = do_open(fname, O_RDONLY, 0);
-       if (fd == -1)
+       if (fd == -1) {
+               memset(sum, 0, file_sum_len);
                return;
+       }
 
        buf = map_file(fd, len, MAX_MAP_SIZE, CHUNK_SIZE);
 
-       switch (checksum_type) {
+#ifdef USE_OPENSSL
+       if (file_sum_evp_md) {
+               static EVP_MD_CTX *evp = NULL;
+               if (!evp && !(evp = EVP_MD_CTX_create()))
+                       out_of_memory("file_checksum");
+
+               EVP_DigestInit_ex(evp, file_sum_evp_md, NULL);
+
+               for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
+                       EVP_DigestUpdate(evp, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
+
+               remainder = (int32)(len - i);
+               if (remainder > 0)
+                       EVP_DigestUpdate(evp, (uchar *)map_ptr(buf, i, remainder), remainder);
+
+               EVP_DigestFinal_ex(evp, (uchar *)sum, NULL);
+       } else
+#endif
+       switch (file_sum_nni->num) {
 #ifdef SUPPORT_XXHASH
          case CSUM_XXH64: {
                static XXH64_state_t* state = NULL;
@@ -374,38 +491,21 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
          }
 #endif
          case CSUM_MD5: {
-               MD5_CTX m5;
+               md_context m5;
 
-               MD5_Init(&m5);
+               md5_begin(&m5);
 
                for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
-                       MD5_Update(&m5, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
+                       md5_update(&m5, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
 
                remainder = (int32)(len - i);
                if (remainder > 0)
-                       MD5_Update(&m5, (uchar *)map_ptr(buf, i, remainder), remainder);
+                       md5_update(&m5, (uchar *)map_ptr(buf, i, remainder), remainder);
 
-               MD5_Final((uchar *)sum, &m5);
+               md5_result(&m5, (uchar *)sum);
                break;
          }
          case CSUM_MD4:
-#ifdef USE_OPENSSL
-         {
-               MD4_CTX m4;
-
-               MD4_Init(&m4);
-
-               for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
-                       MD4_Update(&m4, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
-
-               remainder = (int32)(len - i);
-               if (remainder > 0)
-                       MD4_Update(&m4, (uchar *)map_ptr(buf, i, remainder), remainder);
-
-               MD4_Final((uchar *)sum, &m4);
-               break;
-         }
-#endif
          case CSUM_MD4_OLD:
          case CSUM_MD4_BUSTED:
          case CSUM_MD4_ARCHAIC: {
@@ -413,15 +513,15 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
 
                mdfour_begin(&m);
 
-               for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
-                       mdfour_update(&m, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
+               for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK)
+                       mdfour_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK), CSUM_CHUNK);
 
                /* Prior to version 27 an incorrect MD4 checksum was computed
                 * by failing to call mdfour_tail() for block sizes that
                 * are multiples of 64.  This is fixed by calling mdfour_update()
                 * even when there are no more bytes. */
                remainder = (int32)(len - i);
-               if (remainder > 0 || checksum_type > CSUM_MD4_BUSTED)
+               if (remainder > 0 || file_sum_nni->num > CSUM_MD4_BUSTED)
                        mdfour_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
 
                mdfour_result(&m, (uchar *)sum);
@@ -429,7 +529,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
          }
          default:
                rprintf(FERROR, "Invalid checksum-choice for --checksum: %s (%d)\n",
-                       checksum_name(checksum_type), checksum_type);
+                       file_sum_nni->name, file_sum_nni->num);
                exit_cleanup(RERR_UNSUPPORTED);
        }
 
@@ -438,30 +538,43 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
 }
 
 static int32 sumresidue;
-static union {
-       md_context md;
-#ifdef USE_OPENSSL
-       MD4_CTX m4;
-#endif
-       MD5_CTX m5;
-} ctx;
+static md_context ctx_md;
 #ifdef SUPPORT_XXHASH
 static XXH64_state_t* xxh64_state;
 #endif
 #ifdef SUPPORT_XXH3
 static XXH3_state_t* xxh3_state;
 #endif
-static int cursum_type;
+static struct name_num_item *cur_sum_nni;
+int cur_sum_len;
+
+#ifdef USE_OPENSSL
+static const EVP_MD *cur_sum_evp_md;
+#endif
 
-void sum_init(int csum_type, int seed)
+/* Initialize a hash digest accumulator.  Data is supplied via
+ * sum_update() and the resulting binary digest is retrieved via
+ * sum_end().  This only supports one active sum at a time. */
+int sum_init(struct name_num_item *nni, int seed)
 {
        char s[4];
 
-       if (csum_type < 0)
-               csum_type = parse_csum_name(NULL, 0);
-       cursum_type = csum_type;
+       if (!nni)
+               nni = parse_csum_name(NULL, 0);
+       cur_sum_nni = nni;
+       cur_sum_len = csum_len_for_type(nni->num, 0);
+#ifdef USE_OPENSSL
+       cur_sum_evp_md = csum_evp_md(nni);
+#endif
 
-       switch (csum_type) {
+#ifdef USE_OPENSSL
+       if (cur_sum_evp_md) {
+               if (!ctx_evp && !(ctx_evp = EVP_MD_CTX_create()))
+                       out_of_memory("file_checksum");
+               EVP_DigestInit_ex(ctx_evp, cur_sum_evp_md, NULL);
+       } else
+#endif
+       switch (cur_sum_nni->num) {
 #ifdef SUPPORT_XXHASH
          case CSUM_XXH64:
                if (!xxh64_state && !(xxh64_state = XXH64_createState()))
@@ -482,20 +595,16 @@ void sum_init(int csum_type, int seed)
                break;
 #endif
          case CSUM_MD5:
-               MD5_Init(&ctx.m5);
+               md5_begin(&ctx_md);
                break;
          case CSUM_MD4:
-#ifdef USE_OPENSSL
-               MD4_Init(&ctx.m4);
-#else
-               mdfour_begin(&ctx.md);
+               mdfour_begin(&ctx_md);
                sumresidue = 0;
-#endif
                break;
          case CSUM_MD4_OLD:
          case CSUM_MD4_BUSTED:
          case CSUM_MD4_ARCHAIC:
-               mdfour_begin(&ctx.md);
+               mdfour_begin(&ctx_md);
                sumresidue = 0;
                SIVAL(s, 0, seed);
                sum_update(s, 4);
@@ -505,19 +614,19 @@ void sum_init(int csum_type, int seed)
          default: /* paranoia to prevent missing case values */
                exit_cleanup(RERR_UNSUPPORTED);
        }
+
+       return cur_sum_len;
 }
 
-/**
- * Feed data into an MD4 accumulator, md.  The results may be
- * retrieved using sum_end().  md is used for different purposes at
- * different points during execution.
- *
- * @todo Perhaps get rid of md and just pass in the address each time.
- * Very slightly clearer and slower.
- **/
+/* Feed data into a hash digest accumulator. */
 void sum_update(const char *p, int32 len)
 {
-       switch (cursum_type) {
+#ifdef USE_OPENSSL
+       if (cur_sum_evp_md) {
+               EVP_DigestUpdate(ctx_evp, (uchar *)p, len);
+       } else
+#endif
+       switch (cur_sum_nni->num) {
 #ifdef SUPPORT_XXHASH
          case CSUM_XXH64:
                XXH64_update(xxh64_state, p, len);
@@ -532,39 +641,35 @@ void sum_update(const char *p, int32 len)
                break;
 #endif
          case CSUM_MD5:
-               MD5_Update(&ctx.m5, (uchar *)p, len);
+               md5_update(&ctx_md, (uchar *)p, len);
                break;
          case CSUM_MD4:
-#ifdef USE_OPENSSL
-               MD4_Update(&ctx.m4, (uchar *)p, len);
-               break;
-#endif
          case CSUM_MD4_OLD:
          case CSUM_MD4_BUSTED:
          case CSUM_MD4_ARCHAIC:
                if (len + sumresidue < CSUM_CHUNK) {
-                       memcpy(ctx.md.buffer + sumresidue, p, len);
+                       memcpy(ctx_md.buffer + sumresidue, p, len);
                        sumresidue += len;
                        break;
                }
 
                if (sumresidue) {
                        int32 i = CSUM_CHUNK - sumresidue;
-                       memcpy(ctx.md.buffer + sumresidue, p, i);
-                       mdfour_update(&ctx.md, (uchar *)ctx.md.buffer, CSUM_CHUNK);
+                       memcpy(ctx_md.buffer + sumresidue, p, i);
+                       mdfour_update(&ctx_md, (uchar *)ctx_md.buffer, CSUM_CHUNK);
                        len -= i;
                        p += i;
                }
 
                while (len >= CSUM_CHUNK) {
-                       mdfour_update(&ctx.md, (uchar *)p, CSUM_CHUNK);
+                       mdfour_update(&ctx_md, (uchar *)p, CSUM_CHUNK);
                        len -= CSUM_CHUNK;
                        p += CSUM_CHUNK;
                }
 
                sumresidue = len;
                if (sumresidue)
-                       memcpy(ctx.md.buffer, p, sumresidue);
+                       memcpy(ctx_md.buffer, p, sumresidue);
                break;
          case CSUM_NONE:
                break;
@@ -573,13 +678,18 @@ void sum_update(const char *p, int32 len)
        }
 }
 
-/* NOTE: all the callers of sum_end() pass in a pointer to a buffer that is
- * MAX_DIGEST_LEN in size, so even if the csum-len is shorter that that (i.e.
- * CSUM_MD4_ARCHAIC), we don't have to worry about limiting the data we write
- * into the "sum" buffer. */
-int sum_end(char *sum)
+/* The sum buffer only needs to be as long as the current checksum's digest
+ * len, not MAX_DIGEST_LEN. Note that for CSUM_MD4_ARCHAIC that is the full
+ * MD4_DIGEST_LEN even if the file-list code is going to ignore all but the
+ * first 2 bytes of it. */
+void sum_end(char *sum)
 {
-       switch (cursum_type) {
+#ifdef USE_OPENSSL
+       if (cur_sum_evp_md) {
+               EVP_DigestFinal_ex(ctx_evp, (uchar *)sum, NULL);
+       } else
+#endif
+       switch (cur_sum_nni->num) {
 #ifdef SUPPORT_XXHASH
          case CSUM_XXH64:
                SIVAL64(sum, 0, XXH64_digest(xxh64_state));
@@ -597,22 +707,18 @@ int sum_end(char *sum)
          }
 #endif
          case CSUM_MD5:
-               MD5_Final((uchar *)sum, &ctx.m5);
+               md5_result(&ctx_md, (uchar *)sum);
                break;
          case CSUM_MD4:
-#ifdef USE_OPENSSL
-               MD4_Final((uchar *)sum, &ctx.m4);
-               break;
-#endif
          case CSUM_MD4_OLD:
-               mdfour_update(&ctx.md, (uchar *)ctx.md.buffer, sumresidue);
-               mdfour_result(&ctx.md, (uchar *)sum);
+               mdfour_update(&ctx_md, (uchar *)ctx_md.buffer, sumresidue);
+               mdfour_result(&ctx_md, (uchar *)sum);
                break;
          case CSUM_MD4_BUSTED:
          case CSUM_MD4_ARCHAIC:
                if (sumresidue)
-                       mdfour_update(&ctx.md, (uchar *)ctx.md.buffer, sumresidue);
-               mdfour_result(&ctx.md, (uchar *)sum);
+                       mdfour_update(&ctx_md, (uchar *)ctx_md.buffer, sumresidue);
+               mdfour_result(&ctx_md, (uchar *)sum);
                break;
          case CSUM_NONE:
                *sum = '\0';
@@ -620,6 +726,74 @@ int sum_end(char *sum)
          default: /* paranoia to prevent missing case values */
                exit_cleanup(RERR_UNSUPPORTED);
        }
+}
+
+#if defined SUPPORT_XXH3 || defined USE_OPENSSL
+static void verify_digest(struct name_num_item *nni, BOOL check_auth_list)
+{
+#ifdef SUPPORT_XXH3
+       static int xxh3_result = 0;
+#endif
+#ifdef USE_OPENSSL
+       static int prior_num = 0, prior_flags = 0, prior_result = 0;
+#endif
+
+#ifdef SUPPORT_XXH3
+       if (nni->num == CSUM_XXH3_64 || nni->num == CSUM_XXH3_128) {
+               if (!xxh3_result) {
+                       char buf[32816];
+                       int j;
+                       for (j = 0; j < (int)sizeof buf; j++)
+                               buf[j] = ' ' + (j % 96);
+                       sum_init(nni, 0);
+                       sum_update(buf, 32816);
+                       sum_update(buf, 31152);
+                       sum_update(buf, 32474);
+                       sum_update(buf, 9322);
+                       xxh3_result = XXH3_64bits_digest(xxh3_state) != 0xadbcf16d4678d1de ? -1 : 1;
+               }
+               if (xxh3_result < 0)
+                       nni->num = CSUM_gone;
+               return;
+       }
+#endif
+
+#ifdef USE_OPENSSL
+       if (BITS_SETnUNSET(nni->flags, NNI_EVP, NNI_BUILTIN|NNI_EVP_OK)) {
+               if (nni->num == prior_num && nni->flags == prior_flags) {
+                       nni->flags = prior_result;
+                       if (!(nni->flags & NNI_EVP))
+                               nni->num = CSUM_gone;
+               } else {
+                       prior_num = nni->num;
+                       prior_flags = nni->flags;
+                       if (!csum_evp_md(nni))
+                               nni->num = CSUM_gone;
+                       prior_result = nni->flags;
+                       if (check_auth_list && (nni = get_nni_by_num(&valid_auth_checksums, prior_num)) != NULL)
+                               verify_digest(nni, False);
+               }
+       }
+#endif
+}
+#endif
+
+void init_checksum_choices()
+{
+#if defined SUPPORT_XXH3 || defined USE_OPENSSL
+       struct name_num_item *nni;
+#endif
+
+       if (initialized_choices)
+               return;
+
+#if defined SUPPORT_XXH3 || defined USE_OPENSSL
+       for (nni = valid_checksums.list; nni->name; nni++)
+               verify_digest(nni, True);
+
+       for (nni = valid_auth_checksums.list; nni->name; nni++)
+               verify_digest(nni, False);
+#endif
 
-       return csum_len_for_type(cursum_type, 0);
+       initialized_choices = 1;
 }
index 30e888c..ea94894 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2002-2020 Wayne Davison
+ * Copyright (C) 2002-2022 Wayne Davison
  *
  * 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
@@ -49,7 +49,7 @@ static char ipaddr_buf[100];
 
 static void client_sockaddr(int fd, struct sockaddr_storage *ss, socklen_t *ss_len);
 static int check_name(const char *ipaddr, const struct sockaddr_storage *ss, char *name_buf, size_t name_buf_size);
-static int valid_ipaddr(const char *s);
+static int valid_ipaddr(const char *s, int allow_scope);
 
 /* Return the IP addr of the client as a string. */
 char *client_addr(int fd)
@@ -73,7 +73,7 @@ char *client_addr(int fd)
                        if ((p = strchr(ipaddr_buf, ' ')) != NULL)
                                *p = '\0';
                }
-               if (valid_ipaddr(ipaddr_buf))
+               if (valid_ipaddr(ipaddr_buf, True))
                        return ipaddr_buf;
        }
 
@@ -213,12 +213,14 @@ int read_proxy_protocol_header(int fd)
                                if (size != sizeof hdr.v2.addr.ip4)
                                        return 0;
                                inet_ntop(AF_INET, hdr.v2.addr.ip4.src_addr, ipaddr_buf, sizeof ipaddr_buf);
-                               return valid_ipaddr(ipaddr_buf);
+                               return valid_ipaddr(ipaddr_buf, False);
+#ifdef INET6
                        case PROXY_FAM_TCPv6:
                                if (size != sizeof hdr.v2.addr.ip6)
                                        return 0;
                                inet_ntop(AF_INET6, hdr.v2.addr.ip6.src_addr, ipaddr_buf, sizeof ipaddr_buf);
-                               return valid_ipaddr(ipaddr_buf);
+                               return valid_ipaddr(ipaddr_buf, False);
+#endif
                        default:
                                break;
                        }
@@ -274,7 +276,7 @@ int read_proxy_protocol_header(int fd)
                if ((sp = strchr(p, ' ')) == NULL)
                        return 0;
                *sp = '\0';
-               if (!valid_ipaddr(p))
+               if (!valid_ipaddr(p, False))
                        return 0;
                strlcpy(ipaddr_buf, p, sizeof ipaddr_buf); /* It will always fit when valid. */
 
@@ -282,7 +284,7 @@ int read_proxy_protocol_header(int fd)
                if ((sp = strchr(p, ' ')) == NULL)
                        return 0;
                *sp = '\0';
-               if (!valid_ipaddr(p))
+               if (!valid_ipaddr(p, False))
                        return 0;
                /* Ignore destination address. */
 
@@ -464,7 +466,7 @@ static int check_name(const char *ipaddr, const struct sockaddr_storage *ss, cha
 }
 
 /* Returns 1 for a valid IPv4 or IPv6 addr, or 0 for a bad one. */
-static int valid_ipaddr(const char *s)
+static int valid_ipaddr(const char *s, int allow_scope)
 {
        int i;
 
@@ -482,6 +484,11 @@ static int valid_ipaddr(const char *s)
                for (count = 0; count < 8; count++) {
                        if (!*s)
                                return saw_double_colon;
+                       if (allow_scope && *s == '%') {
+                               if (saw_double_colon)
+                                       break;
+                               return 0;
+                       }
 
                        if (strchr(s, ':') == NULL && strchr(s, '.') != NULL) {
                                if ((!saw_double_colon && count != 6) || (saw_double_colon && count > 6))
@@ -507,8 +514,11 @@ static int valid_ipaddr(const char *s)
                        }
                }
 
-               if (!ipv4_at_end)
-                       return !*s;
+               if (!ipv4_at_end) {
+                       if (allow_scope && *s == '%')
+                               for (s++; isAlNum(s); s++) { }
+                       return !*s && s[-1] != '%';
+               }
        }
 
        /* IPv4 */
index 48c15a6..7c897ab 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
  * Copyright (C) 2001-2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2002-2020 Wayne Davison
+ * Copyright (C) 2002-2022 Wayne Davison
  *
  * 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
@@ -47,6 +47,7 @@ extern int protocol_version;
 extern int io_timeout;
 extern int no_detach;
 extern int write_batch;
+extern int old_style_args;
 extern int default_af_hint;
 extern int logfile_format_has_i;
 extern int logfile_format_has_o_or_i;
@@ -66,6 +67,7 @@ extern uid_t our_uid;
 extern gid_t our_gid;
 
 char *auth_user;
+char *daemon_auth_choices;
 int read_only = 0;
 int module_id = -1;
 int pid_file_fd = -1;
@@ -148,13 +150,9 @@ int start_socket_client(char *host, int remote_argc, char *remote_argv[],
 static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int am_client)
 {
        int remote_sub = -1;
-#if SUBPROTOCOL_VERSION != 0
-       int our_sub = protocol_version < PROTOCOL_VERSION ? 0 : SUBPROTOCOL_VERSION;
-#else
-       int our_sub = 0;
-#endif
+       int our_sub = get_subprotocol_version();
 
-       io_printf(f_out, "@RSYNCD: %d.%d\n", protocol_version, our_sub);
+       output_daemon_greeting(f_out, am_client);
        if (!am_client) {
                char *motd = lp_motd_file();
                if (motd && *motd) {
@@ -186,16 +184,30 @@ static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int
        }
 
        if (remote_sub < 0) {
-               if (remote_protocol == 30) {
+               if (remote_protocol >= 30) {
                        if (am_client)
-                               rprintf(FERROR, "rsync: server is speaking an incompatible beta of protocol 30\n");
+                               rprintf(FERROR, "rsync: the server omitted the subprotocol value: %s\n", buf);
                        else
-                               io_printf(f_out, "@ERROR: your client is speaking an incompatible beta of protocol 30\n");
+                               io_printf(f_out, "@ERROR: your client omitted the subprotocol value: %s\n", buf);
                        return -1;
                }
                remote_sub = 0;
        }
 
+       daemon_auth_choices = strchr(buf + 9, ' ');
+       if (daemon_auth_choices) {
+               char *cp;
+               daemon_auth_choices = strdup(daemon_auth_choices + 1);
+               if ((cp = strchr(daemon_auth_choices, '\n')) != NULL)
+                       *cp = '\0';
+       } else if (remote_protocol > 31) {
+               if (am_client)
+                       rprintf(FERROR, "rsync: the server omitted the digest name list: %s\n", buf);
+               else
+                       io_printf(f_out, "@ERROR: your client omitted the digest name list: %s\n", buf);
+               return -1;
+       }
+
        if (protocol_version > remote_protocol) {
                protocol_version = remote_protocol;
                if (remote_sub)
@@ -288,20 +300,45 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
 
        sargs[sargc++] = ".";
 
+       if (!old_style_args)
+               snprintf(line, sizeof line, " %.*s/", modlen, modname);
+
        while (argc > 0) {
                if (sargc >= MAX_ARGS - 1) {
                  arg_overflow:
                        rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
                        exit_cleanup(RERR_SYNTAX);
                }
-               if (strncmp(*argv, modname, modlen) == 0
-                && argv[0][modlen] == '\0')
+               if (strncmp(*argv, modname, modlen) == 0 && argv[0][modlen] == '\0')
                        sargs[sargc++] = modname; /* we send "modname/" */
-               else if (**argv == '-') {
-                       if (asprintf(sargs + sargc++, "./%s", *argv) < 0)
-                               out_of_memory("start_inband_exchange");
-               } else
-                       sargs[sargc++] = *argv;
+               else {
+                       char *arg = *argv;
+                       int extra_chars = *arg == '-' ? 2 : 0; /* a leading dash needs a "./" prefix. */
+                       /* If --old-args was not specified, make sure that the arg won't split at a mod name! */
+                       if (!old_style_args && (p = strstr(arg, line)) != NULL) {
+                               do {
+                                       extra_chars += 2;
+                               } while ((p = strstr(p+1, line)) != NULL);
+                       }
+                       if (extra_chars) {
+                               char *f = arg;
+                               char *t = arg = new_array(char, strlen(arg) + extra_chars + 1);
+                               if (*f == '-') {
+                                       *t++ = '.';
+                                       *t++ = '/';
+                               }
+                               while (*f) {
+                                       if (*f == ' ' && strncmp(f, line, modlen+2) == 0) {
+                                               *t++ = '[';
+                                               *t++ = *f++;
+                                               *t++ = ']';
+                                       } else
+                                               *t++ = *f++;
+                               }
+                               *t = '\0';
+                       }
+                       sargs[sargc++] = arg;
+               }
                argv++;
                argc--;
        }
@@ -355,7 +392,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
 
        if (rl_nulls) {
                for (i = 0; i < sargc; i++) {
-                       if (!sargs[i]) /* stop at --protect-args NULL */
+                       if (!sargs[i]) /* stop at --secluded-args NULL */
                                break;
                        write_sbuf(f_out, sargs[i]);
                        write_byte(f_out, 0);
@@ -380,7 +417,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
        return 0;
 }
 
-#ifdef HAVE_PUTENV
+#if defined HAVE_SETENV || defined HAVE_PUTENV
 static int read_arg_from_pipe(int fd, char *buf, int limit)
 {
        char *bp = buf, *eob = buf + limit - 1;
@@ -403,25 +440,59 @@ static int read_arg_from_pipe(int fd, char *buf, int limit)
 }
 #endif
 
-static void set_env_str(const char *var, const char *str)
+void set_env_str(const char *var, const char *str)
 {
+#ifdef HAVE_SETENV
+       if (setenv(var, str, 1) < 0)
+               out_of_memory("set_env_str");
+#else
 #ifdef HAVE_PUTENV
        char *mem;
        if (asprintf(&mem, "%s=%s", var, str) < 0)
                out_of_memory("set_env_str");
        putenv(mem);
+#else
+       (void)var;
+       (void)str;
+#endif
 #endif
 }
 
+#if defined HAVE_SETENV || defined HAVE_PUTENV
+
+static void set_envN_str(const char *var, int num, const char *str)
+{
+#ifdef HAVE_SETENV
+       char buf[128];
+       (void)snprintf(buf, sizeof buf, "%s%d", var, num);
+       if (setenv(buf, str, 1) < 0)
+               out_of_memory("set_env_str");
+#else
 #ifdef HAVE_PUTENV
+       char *mem;
+       if (asprintf(&mem, "%s%d=%s", var, num, str) < 0)
+               out_of_memory("set_envN_str");
+       putenv(mem);
+#endif
+#endif
+}
+
 void set_env_num(const char *var, long num)
 {
+#ifdef HAVE_SETENV
+       char val[64];
+       (void)snprintf(val, sizeof val, "%ld", num);
+       if (setenv(var, val, 1) < 0)
+               out_of_memory("set_env_str");
+#else
+#ifdef HAVE_PUTENV
        char *mem;
        if (asprintf(&mem, "%s=%ld", var, num) < 0)
                out_of_memory("set_env_num");
        putenv(mem);
-}
 #endif
+#endif
+}
 
 /* Used for "early exec", "pre-xfer exec", and the "name converter" script. */
 static pid_t start_pre_exec(const char *cmd, int *arg_fd_ptr, int *error_fd_ptr)
@@ -451,15 +522,13 @@ static pid_t start_pre_exec(const char *cmd, int *arg_fd_ptr, int *error_fd_ptr)
                set_env_str("RSYNC_REQUEST", buf);
 
                for (j = 0; ; j++) {
-                       char *p;
                        len = read_arg_from_pipe(arg_fd, buf, BIGPATHBUFLEN);
                        if (len <= 0) {
                                if (!len)
                                        break;
                                _exit(1);
                        }
-                       if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) >= 0)
-                               putenv(p);
+                       set_envN_str("RSYNC_ARG", j, buf);
                }
 
                dup2(arg_fd, STDIN_FILENO);
@@ -490,6 +559,8 @@ static pid_t start_pre_exec(const char *cmd, int *arg_fd_ptr, int *error_fd_ptr)
        return pid;
 }
 
+#endif
+
 static void write_pre_exec_args(int write_fd, char *request, char **early_argv, char **argv, int exec_type)
 {
        int j = 0;
@@ -630,7 +701,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
        int set_uid;
        char *p, *err_msg = NULL;
        char *name = lp_name(i);
-       int use_chroot = lp_use_chroot(i);
+       int use_chroot = lp_use_chroot(i); /* might be 1 (yes), 0 (no), or -1 (unset) */
        int ret, pre_exec_arg_fd = -1, pre_exec_error_fd = -1;
        int save_munge_symlinks;
        pid_t pre_exec_pid = 0;
@@ -755,6 +826,20 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
                io_printf(f_out, "@ERROR: no path setting.\n");
                return -1;
        }
+       if (use_chroot < 0) {
+               if (strstr(module_dir, "/./") != NULL)
+                       use_chroot = 1; /* The module is expecting a chroot inner & outer path. */
+               else if (chroot("/") < 0) {
+                       rprintf(FLOG, "chroot test failed: %s. "
+                                     "Switching 'use chroot' from unset to false.\n",
+                                     strerror(errno));
+                       use_chroot = 0;
+               } else {
+                       if (chdir("/") < 0)
+                           rsyserr(FLOG, errno, "chdir(\"/\") failed");
+                       use_chroot = 1;
+               }
+       }
        if (use_chroot) {
                if ((p = strstr(module_dir, "/./")) != NULL) {
                        *p = '\0'; /* Temporary... */
@@ -809,7 +894,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
 
        log_init(1);
 
-#ifdef HAVE_PUTENV
+#if defined HAVE_SETENV || defined HAVE_PUTENV
        if ((*lp_early_exec(module_id) || *lp_prexfer_exec(module_id)
          || *lp_postxfer_exec(module_id) || *lp_name_converter(module_id))
         && !getenv("RSYNC_NO_XFER_EXEC")) {
@@ -891,20 +976,8 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
        }
 
        if (use_chroot) {
-               /*
-                * XXX: The 'use chroot' flag is a fairly reliable
-                * source of confusion, because it fails under two
-                * important circumstances: running as non-root,
-                * running on Win32 (or possibly others).  On the
-                * other hand, if you are running as root, then it
-                * might be better to always use chroot.
-                *
-                * So, perhaps if we can't chroot we should just issue
-                * a warning, unless a "require chroot" flag is set,
-                * in which case we fail.
-                */
                if (chroot(module_chdir)) {
-                       rsyserr(FLOG, errno, "chroot %s failed", module_chdir);
+                       rsyserr(FLOG, errno, "chroot(\"%s\") failed", module_chdir);
                        io_printf(f_out, "@ERROR: chroot failed\n");
                        return -1;
                }
@@ -913,7 +986,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
 
        if (!change_dir(module_chdir, CD_NORMAL))
                return path_failure(f_out, module_chdir, True);
-       if (module_dirlen || (!use_chroot && !*lp_daemon_chroot()))
+       if (module_dirlen)
                sanitize_paths = 1;
 
        if ((munge_symlinks = lp_munge_symlinks(module_id)) < 0)
@@ -1228,8 +1301,12 @@ int start_daemon(int f_in, int f_out)
        p = lp_daemon_chroot();
        if (*p) {
                log_init(0); /* Make use we've initialized syslog before chrooting. */
-               if (chroot(p) < 0 || chdir("/") < 0) {
-                       rsyserr(FLOG, errno, "daemon chroot %s failed", p);
+               if (chroot(p) < 0) {
+                       rsyserr(FLOG, errno, "daemon chroot(\"%s\") failed", p);
+                       return -1;
+               }
+               if (chdir("/") < 0) {
+                       rsyserr(FLOG, errno, "daemon chdir(\"/\") failed");
                        return -1;
                }
        }
similarity index 100%
rename from cmdormsg
rename to cmd-or-msg
index bbabd11..a8a6afe 100644 (file)
--- a/compat.c
+++ b/compat.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) Andrew Tridgell 1996
  * Copyright (C) Paul Mackerras 1996
- * Copyright (C) 2004-2020 Wayne Davison
+ * Copyright (C) 2004-2022 Wayne Davison
  *
  * 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
@@ -21,6 +21,7 @@
 
 #include "rsync.h"
 #include "itypes.h"
+#include "ifuncs.h"
 
 extern int am_server;
 extern int am_sender;
@@ -51,19 +52,24 @@ extern int need_messages_from_generator;
 extern int delete_mode, delete_before, delete_during, delete_after;
 extern int do_compression;
 extern int do_compression_level;
+extern int saw_stderr_opt;
+extern int msgs2stderr;
 extern char *shell_cmd;
 extern char *partial_dir;
 extern char *files_from;
 extern char *filesfrom_host;
 extern const char *checksum_choice;
 extern const char *compress_choice;
+extern char *daemon_auth_choices;
 extern filter_rule_list filter_list;
 extern int need_unsorted_flist;
 #ifdef ICONV_OPTION
 extern iconv_t ic_send, ic_recv;
 extern char *iconv_opt;
 #endif
-extern struct name_num_obj valid_checksums;
+extern struct name_num_obj valid_checksums, valid_auth_checksums;
+
+extern struct name_num_item *xfer_sum_nni;
 
 int remote_protocol = 0;
 int file_extra_cnt = 0; /* count of file-list extras that everyone gets */
@@ -76,6 +82,9 @@ int inplace_partial = 0;
 int do_negotiated_strings = 0;
 int xmit_id0_names = 0;
 
+struct name_num_item *xattr_sum_nni;
+int xattr_sum_len = 0;
+
 /* These index values are for the file-list's extra-attribute array. */
 int pathname_ndx, depth_ndx, atimes_ndx, crtimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
 
@@ -88,19 +97,21 @@ int filesfrom_convert = 0;
 
 #define MAX_NSTR_STRLEN 256
 
-struct name_num_obj valid_compressions = {
-       "compress", NULL, NULL, 0, 0, {
+struct name_num_item valid_compressions_items[] = {
 #ifdef SUPPORT_ZSTD
-               { CPRES_ZSTD, "zstd", NULL },
+       { CPRES_ZSTD, 0, "zstd", NULL },
 #endif
 #ifdef SUPPORT_LZ4
-               { CPRES_LZ4, "lz4", NULL },
+       { CPRES_LZ4, 0, "lz4", NULL },
 #endif
-               { CPRES_ZLIBX, "zlibx", NULL },
-               { CPRES_ZLIB, "zlib", NULL },
-               { CPRES_NONE, "none", NULL },
-               { 0, NULL, NULL }
-       }
+       { CPRES_ZLIBX, 0, "zlibx", NULL },
+       { CPRES_ZLIB, 0, "zlib", NULL },
+       { CPRES_NONE, 0, "none", NULL },
+       { 0, 0, NULL, NULL }
+};
+
+struct name_num_obj valid_compressions = {
+       "compress", NULL, 0, 0, valid_compressions_items
 };
 
 #define CF_INC_RECURSE  (1<<0)
@@ -122,11 +133,7 @@ static void check_sub_protocol(void)
 {
        char *dot;
        int their_protocol, their_sub;
-#if SUBPROTOCOL_VERSION != 0
-       int our_sub = protocol_version < PROTOCOL_VERSION ? 0 : SUBPROTOCOL_VERSION;
-#else
-       int our_sub = 0;
-#endif
+       int our_sub = get_subprotocol_version();
 
        /* client_info starts with VER.SUB string if client is a pre-release. */
        if (!(their_protocol = atoi(client_info))
@@ -153,7 +160,13 @@ static void check_sub_protocol(void)
 
 void set_allow_inc_recurse(void)
 {
-       client_info = shell_cmd ? shell_cmd : "";
+       if (!local_server)
+               client_info = shell_cmd ? shell_cmd : "";
+       else if (am_server) {
+               char buf[64];
+               maybe_add_e_option(buf, sizeof buf);
+               client_info = *buf ? strdup(buf+1) : ""; /* The +1 skips the leading "e". */
+       }
 
        if (!recurse || use_qsort)
                allow_inc_recurse = 0;
@@ -161,15 +174,14 @@ void set_allow_inc_recurse(void)
         && (delete_before || delete_after
          || delay_updates || prune_empty_dirs))
                allow_inc_recurse = 0;
-       else if (am_server && !local_server
-        && (strchr(client_info, 'i') == NULL))
+       else if (am_server && strchr(client_info, 'i') == NULL)
                allow_inc_recurse = 0;
 }
 
 void parse_compress_choice(int final_call)
 {
-       if (valid_compressions.negotiated_name)
-               do_compression = valid_compressions.negotiated_num;
+       if (valid_compressions.negotiated_nni)
+               do_compression = valid_compressions.negotiated_nni->num;
        else if (compress_choice) {
                struct name_num_item *nni = get_nni_by_name(&valid_compressions, compress_choice, -1);
                if (!nni) {
@@ -191,8 +203,8 @@ void parse_compress_choice(int final_call)
                compress_choice = NULL;
 
        /* Snag the compression name for both write_batch's option output & the following debug output. */
-       if (valid_compressions.negotiated_name)
-               compress_choice = valid_compressions.negotiated_name;
+       if (valid_compressions.negotiated_nni)
+               compress_choice = valid_compressions.negotiated_nni->name;
        else if (compress_choice == NULL) {
                struct name_num_item *nni = get_nni_by_num(&valid_compressions, do_compression);
                compress_choice = nni ? nni->name : "UNKNOWN";
@@ -202,7 +214,7 @@ void parse_compress_choice(int final_call)
         && (do_compression != CPRES_NONE || do_compression_level != CLVL_NOT_SPECIFIED)) {
                rprintf(FINFO, "%s%s compress: %s (level %d)\n",
                        am_server ? "Server" : "Client",
-                       valid_compressions.negotiated_name ? " negotiated" : "",
+                       valid_compressions.negotiated_nni ? " negotiated" : "",
                        compress_choice, do_compression_level);
        }
 }
@@ -215,6 +227,8 @@ struct name_num_item *get_nni_by_name(struct name_num_obj *nno, const char *name
                len = strlen(name);
 
        for (nni = nno->list; nni->name; nni++) {
+               if (nni->num == CSUM_gone)
+                       continue;
                if (strncasecmp(name, nni->name, len) == 0 && nni->name[len] == '\0')
                        return nni;
        }
@@ -249,10 +263,12 @@ static void init_nno_saw(struct name_num_obj *nno, int val)
        if (!nno->saw) {
                nno->saw = new_array0(uchar, nno->saw_len);
 
-               /* We'll take this opportunity to make sure that the main_name values are set right. */
+               /* We'll take this opportunity to set the main_nni values for duplicates. */
                for (cnt = 1, nni = nno->list; nni->name; nni++, cnt++) {
+                       if (nni->num == CSUM_gone)
+                               continue;
                        if (nno->saw[nni->num])
-                               nni->main_name = nno->list[nno->saw[nni->num]-1].name;
+                               nni->main_nni = &nno->list[nno->saw[nni->num]-1];
                        else
                                nno->saw[nni->num] = cnt;
                }
@@ -278,8 +294,8 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
                                struct name_num_item *nni = get_nni_by_name(nno, tok, to - tok);
                                if (nni && !nno->saw[nni->num]) {
                                        nno->saw[nni->num] = ++cnt;
-                                       if (nni->main_name) {
-                                               to = tok + strlcpy(tok, nni->main_name, tobuf_len - (tok - tobuf));
+                                       if (nni->main_nni) {
+                                               to = tok + strlcpy(tok, nni->main_nni->name, tobuf_len - (tok - tobuf));
                                                if (to - tobuf >= tobuf_len) {
                                                        to = tok - 1;
                                                        break;
@@ -313,13 +329,44 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
        return to - tobuf;
 }
 
+static int parse_negotiate_str(struct name_num_obj *nno, char *tmpbuf)
+{
+       struct name_num_item *nni, *ret = NULL;
+       int best = nno->saw_len; /* We want best == 1 from the client list, so start with a big number. */
+       char *space, *tok = tmpbuf;
+       while (tok) {
+               while (*tok == ' ') tok++; /* Should be unneeded... */
+               if (!*tok)
+                       break;
+               if ((space = strchr(tok, ' ')) != NULL)
+                       *space = '\0';
+               nni = get_nni_by_name(nno, tok, -1);
+               if (space) {
+                       *space = ' ';
+                       tok = space + 1;
+               } else
+                       tok = NULL;
+               if (!nni || !nno->saw[nni->num] || best <= nno->saw[nni->num])
+                       continue;
+               ret = nni;
+               best = nno->saw[nni->num];
+               if (best == 1 || am_server) /* The server side stops at the first acceptable client choice */
+                       break;
+       }
+       if (ret) {
+               free(nno->saw);
+               nno->saw = NULL;
+               nno->negotiated_nni = ret->main_nni ? ret->main_nni : ret;
+               return 1;
+       }
+       return 0;
+}
+
 /* This routine is always called with a tmpbuf of MAX_NSTR_STRLEN length, but the
  * buffer may be pre-populated with a "len" length string to use OR a len of -1
  * to tell us to read a string from the fd. */
 static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf, int len)
 {
-       struct name_num_item *ret = NULL;
-
        if (len < 0)
                len = read_vstring(f_in, tmpbuf, MAX_NSTR_STRLEN);
 
@@ -330,37 +377,8 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf,
                        rprintf(FINFO, "Server %s list (on client): %s\n", nno->type, tmpbuf);
        }
 
-       if (len > 0) {
-               struct name_num_item *nni;
-               int best = nno->saw_len; /* We want best == 1 from the client list, so start with a big number. */
-               char *space, *tok = tmpbuf;
-               while (tok) {
-                       while (*tok == ' ') tok++; /* Should be unneeded... */
-                       if (!*tok)
-                               break;
-                       if ((space = strchr(tok, ' ')) != NULL)
-                               *space = '\0';
-                       nni = get_nni_by_name(nno, tok, -1);
-                       if (space) {
-                               *space = ' ';
-                               tok = space + 1;
-                       } else
-                               tok = NULL;
-                       if (!nni || !nno->saw[nni->num] || best <= nno->saw[nni->num])
-                               continue;
-                       ret = nni;
-                       best = nno->saw[nni->num];
-                       if (best == 1 || am_server) /* The server side stops at the first acceptable client choice */
-                               break;
-               }
-               if (ret) {
-                       free(nno->saw);
-                       nno->saw = NULL;
-                       nno->negotiated_name = ret->main_name ? ret->main_name : ret->name;
-                       nno->negotiated_num = ret->num;
-                       return;
-               }
-       }
+       if (len > 0 && parse_negotiate_str(nno, tmpbuf))
+               return;
 
        if (!am_server || !do_negotiated_strings) {
                char *cp = tmpbuf;
@@ -392,7 +410,7 @@ static const char *getenv_nstr(int ntype)
        const char *env_str = getenv(ntype == NSTR_COMPRESS ? "RSYNC_COMPRESS_LIST" : "RSYNC_CHECKSUM_LIST");
 
        /* When writing a batch file, we always negotiate an old-style choice. */
-       if (write_batch) 
+       if (write_batch)
                env_str = ntype == NSTR_COMPRESS ? "zlib" : protocol_version >= 30 ? "md5" : "md4";
 
        if (am_server && env_str) {
@@ -425,7 +443,7 @@ void validate_choice_vs_env(int ntype, int num1, int num2)
                nno->saw[CSUM_MD4_ARCHAIC] = nno->saw[CSUM_MD4_BUSTED] = nno->saw[CSUM_MD4_OLD] = nno->saw[CSUM_MD4];
 
        if (!nno->saw[num1] || (num2 >= 0 && !nno->saw[num2])) {
-               rprintf(FERROR, "Your --%s-choice value (%s) was refused by the server.\n", 
+               rprintf(FERROR, "Your --%s-choice value (%s) was refused by the server.\n",
                        ntype == NSTR_COMPRESS ? "compress" : "checksum",
                        ntype == NSTR_COMPRESS ? compress_choice : checksum_choice);
                exit_cleanup(RERR_UNSUPPORTED);
@@ -456,8 +474,10 @@ int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len,
        init_nno_saw(nno, 0);
 
        for (nni = nno->list, len = 0; nni->name; nni++) {
-               if (nni->main_name) {
-                       if (!dup_markup)
+               if (nni->num == CSUM_gone)
+                       continue;
+               if (nni->main_nni) {
+                       if (!dup_markup || nni->main_nni->num == CSUM_gone)
                                continue;
                        delim = dup_markup;
                }
@@ -515,6 +535,8 @@ static void negotiate_the_strings(int f_in, int f_out)
 {
        /* We send all the negotiation strings before we start to read them to help avoid a slow startup. */
 
+       init_checksum_choices();
+
        if (!checksum_choice)
                send_negotiate_str(f_out, &valid_checksums, NSTR_CHECKSUM);
 
@@ -544,7 +566,7 @@ static void negotiate_the_strings(int f_in, int f_out)
        /* If the other side is too old to negotiate, the above steps just made sure that
         * the env didn't disallow the old algorithm. Mark things as non-negotiated. */
        if (!do_negotiated_strings)
-               valid_checksums.negotiated_name = valid_compressions.negotiated_name = NULL;
+               valid_checksums.negotiated_nni = valid_compressions.negotiated_nni = NULL;
 }
 
 void setup_protocol(int f_out,int f_in)
@@ -558,7 +580,7 @@ void setup_protocol(int f_out,int f_in)
                atimes_ndx = (file_extra_cnt += EXTRA64_CNT);
        if (preserve_crtimes)
                crtimes_ndx = (file_extra_cnt += EXTRA64_CNT);
-       if (am_sender) /* This is most likely in the in64 union as well. */
+       if (am_sender) /* This is most likely in the file_extras64 union as well. */
                pathname_ndx = (file_extra_cnt += PTR_EXTRA_CNT);
        else
                depth_ndx = ++file_extra_cnt;
@@ -596,7 +618,7 @@ void setup_protocol(int f_out,int f_in)
        if (remote_protocol < MIN_PROTOCOL_VERSION
         || remote_protocol > MAX_PROTOCOL_VERSION) {
                rprintf(FERROR,"protocol version mismatch -- is your shell clean?\n");
-               rprintf(FERROR,"(see the rsync man page for an explanation)\n");
+               rprintf(FERROR,"(see the rsync manpage for an explanation)\n");
                exit_cleanup(RERR_PROTOCOL);
        }
        if (remote_protocol < OLD_PROTOCOL_VERSION) {
@@ -616,6 +638,9 @@ void setup_protocol(int f_out,int f_in)
        if (read_batch)
                check_batch_flags();
 
+       if (!saw_stderr_opt && protocol_version <= 28 && am_server)
+               msgs2stderr = 0; /* The client side may not have stderr setup for us. */
+
 #ifndef SUPPORT_PREALLOCATION
        if (preallocate_files && !am_sender) {
                rprintf(FERROR, "preallocation is not supported on this %s\n",
@@ -691,17 +716,17 @@ void setup_protocol(int f_out,int f_in)
 #ifdef ICONV_OPTION
                        compat_flags |= CF_SYMLINK_ICONV;
 #endif
-                       if (local_server || strchr(client_info, 'f') != NULL)
+                       if (strchr(client_info, 'f') != NULL)
                                compat_flags |= CF_SAFE_FLIST;
-                       if (local_server || strchr(client_info, 'x') != NULL)
+                       if (strchr(client_info, 'x') != NULL)
                                compat_flags |= CF_AVOID_XATTR_OPTIM;
-                       if (local_server || strchr(client_info, 'C') != NULL)
+                       if (strchr(client_info, 'C') != NULL)
                                compat_flags |= CF_CHKSUM_SEED_FIX;
-                       if (local_server || strchr(client_info, 'I') != NULL)
+                       if (strchr(client_info, 'I') != NULL)
                                compat_flags |= CF_INPLACE_PARTIAL_DIR;
-                       if (local_server || strchr(client_info, 'u') != NULL)
+                       if (strchr(client_info, 'u') != NULL)
                                compat_flags |= CF_ID0_NAMES;
-                       if (local_server || strchr(client_info, 'v') != NULL) {
+                       if (strchr(client_info, 'v') != NULL) {
                                do_negotiated_strings = 1;
                                compat_flags |= CF_VARINT_FLIST_FLAGS;
                        }
@@ -737,7 +762,7 @@ void setup_protocol(int f_out,int f_in)
 #endif
 #ifdef ICONV_OPTION
                sender_symlink_iconv = iconv_opt && (am_server
-                   ? local_server || strchr(client_info, 's') != NULL
+                   ? strchr(client_info, 's') != NULL
                    : !!(compat_flags & CF_SYMLINK_ICONV));
 #endif
                if (inc_recurse && !allow_inc_recurse) {
@@ -790,11 +815,73 @@ void setup_protocol(int f_out,int f_in)
                checksum_seed = read_int(f_in);
        }
 
-       parse_checksum_choice(1); /* Sets checksum_type & xfersum_type */
+       parse_checksum_choice(1); /* Sets file_sum_nni & xfer_sum_nni */
        parse_compress_choice(1); /* Sets do_compression */
 
+       /* TODO in the future allow this algorithm to be chosen somehow, but it can't get too
+        * long or the size starts to cause a problem in the xattr abbrev/non-abbrev code. */
+       xattr_sum_nni = parse_csum_name(NULL, 0);
+       xattr_sum_len = csum_len_for_type(xattr_sum_nni->num, 0);
+
        if (write_batch && !am_server)
                write_batch_shell_file();
 
        init_flist();
 }
+
+void output_daemon_greeting(int f_out, int am_client)
+{
+       char tmpbuf[MAX_NSTR_STRLEN];
+       int our_sub = get_subprotocol_version();
+
+       get_default_nno_list(&valid_auth_checksums, tmpbuf, MAX_NSTR_STRLEN, '\0');
+
+       io_printf(f_out, "@RSYNCD: %d.%d %s\n", protocol_version, our_sub, tmpbuf);
+
+       if (am_client && DEBUG_GTE(NSTR, 2))
+               rprintf(FINFO, "Client %s list (on client): %s\n", valid_auth_checksums.type, tmpbuf);
+}
+
+void negotiate_daemon_auth(int f_out, int am_client)
+{
+       char tmpbuf[MAX_NSTR_STRLEN];
+       int save_am_server = am_server;
+       int md4_is_old = 0;
+
+       if (!am_client)
+               am_server = 1;
+
+       if (daemon_auth_choices)
+               strlcpy(tmpbuf, daemon_auth_choices, MAX_NSTR_STRLEN);
+       else {
+               strlcpy(tmpbuf, protocol_version >= 30 ? "md5" : "md4", MAX_NSTR_STRLEN);
+               md4_is_old = 1;
+       }
+
+       if (am_client) {
+               recv_negotiate_str(-1, &valid_auth_checksums, tmpbuf, strlen(tmpbuf));
+               if (DEBUG_GTE(NSTR, 1)) {
+                       rprintf(FINFO, "Client negotiated %s: %s\n", valid_auth_checksums.type,
+                               valid_auth_checksums.negotiated_nni->name);
+               }
+       } else {
+               if (!parse_negotiate_str(&valid_auth_checksums, tmpbuf)) {
+                       get_default_nno_list(&valid_auth_checksums, tmpbuf, MAX_NSTR_STRLEN, '\0');
+                       io_printf(f_out, "@ERROR: your client does not support one of our daemon-auth checksums: %s\n",
+                                 tmpbuf);
+                       exit_cleanup(RERR_UNSUPPORTED);
+               }
+       }
+       am_server = save_am_server;
+       if (md4_is_old && valid_auth_checksums.negotiated_nni->num == CSUM_MD4)
+               valid_auth_checksums.negotiated_nni->num = CSUM_MD4_OLD;
+}
+
+int get_subprotocol_version()
+{
+#if SUBPROTOCOL_VERSION != 0
+       return protocol_version < PROTOCOL_VERSION ? 0 : SUBPROTOCOL_VERSION;
+#else
+       return 0;
+#endif
+}
index 1065294..a5fea77 100644 (file)
 /* Undefine if you do not want locale features. By default this is defined. */
 #undef CONFIG_LOCALE
 
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
-   systems. This function is required for `alloca.c' support on those systems.
-   */
-#undef CRAY_STACKSEG_END
-
-/* Define to 1 if using `alloca.c'. */
+/* Define to 1 if using 'alloca.c'. */
 #undef C_ALLOCA
 
 /* Define to 1 if using external zlib */
 /* true if you have AIX ACLs */
 #undef HAVE_AIX_ACLS
 
-/* Define to 1 if you have `alloca', as a function or macro. */
+/* Define to 1 if you have 'alloca', as a function or macro. */
 #undef HAVE_ALLOCA
 
-/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
-   */
+/* Define to 1 if <alloca.h> works. */
 #undef HAVE_ALLOCA_H
 
 /* Define to 1 if you have the <arpa/inet.h> header file. */
@@ -61,9 +55,6 @@
 /* Define to 1 if you have the <arpa/nameser.h> header file. */
 #undef HAVE_ARPA_NAMESER_H
 
-/* Define to 1 to enable ASM optimizations */
-#undef HAVE_ASM
-
 /* Define to 1 if you have the `asprintf' function. */
 #undef HAVE_ASPRINTF
 
@@ -76,6 +67,9 @@
 /* Define to 1 if readdir() is broken */
 #undef HAVE_BROKEN_READDIR
 
+/* Define to 1 if you have the <bsd/string.h> header file. */
+#undef HAVE_BSD_STRING_H
+
 /* Define to 1 if vsprintf has a C99-compatible return value */
 #undef HAVE_C99_VSNPRINTF
 
 /* Define to 1 if you have the `mallinfo' function. */
 #undef HAVE_MALLINFO
 
+/* Define to 1 if you have the `mallinfo2' function. */
+#undef HAVE_MALLINFO2
+
 /* Define to 1 if you have the <malloc.h> header file. */
 #undef HAVE_MALLOC_H
 
 /* Define to 1 if you have the `memmove' function. */
 #undef HAVE_MEMMOVE
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
 /* Define to 1 if you have the `mkfifo' function. */
 #undef HAVE_MKFIFO
 
 /* Define to 1 if you have the <netdb.h> header file. */
 #undef HAVE_NETDB_H
 
+/* Define to 1 if you have the <netgroup.h> header file. */
+#undef HAVE_NETGROUP_H
+
 /* Define to 1 if you have the <netinet/in_systm.h> header file. */
 #undef HAVE_NETINET_IN_SYSTM_H
 
 /* Define to 1 if you have the `setattrlist' function. */
 #undef HAVE_SETATTRLIST
 
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
 /* Define to 1 if you have the `seteuid' function. */
 #undef HAVE_SETEUID
 
 /* Define to 1 if you have the `sigprocmask' function. */
 #undef HAVE_SIGPROCMASK
 
-/* Define to 1 to enable SIMD optimizations */
-#undef HAVE_SIMD
-
 /* Define to 1 if the system has the type `size_t'. */
 #undef HAVE_SIZE_T
 
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
 /* true if you have UnixWare ACLs */
 #undef HAVE_UNIXWARE_ACLS
 
+/* Define to 1 if you have the `unsetenv' function. */
+#undef HAVE_UNSETENV
+
 /* Define to 1 if you have the `usleep' function. */
 #undef HAVE_USLEEP
 
 /* default -e command */
 #undef RSYNC_RSH
 
-/* Define to 1 if --protected-args should be the default */
-#undef RSYNC_USE_PROTECTED_ARGS
+/* Define to 1 if --secluded-args should be the default */
+#undef RSYNC_USE_SECLUDED_ARGS
 
 /* Define to 1 if sockets need to be shutdown */
 #undef SHUTDOWN_ALL_SOCKETS
        STACK_DIRECTION = 0 => direction of growth unknown */
 #undef STACK_DIRECTION
 
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
 
 /* Define to 1 to add support for ACLs */
    */
 #undef SUPPORT_ZSTD
 
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
 /* Define to 1 if you want rsync to make use of iconv_open() */
 #undef USE_ICONV_OPEN
 
+/* Define to 1 to enable MD5 ASM optimizations */
+#undef USE_MD5_ASM
+
 /* Undefine if you do not want to use openssl crypto library. By default this
    is defined. */
 #undef USE_OPENSSL
 
+/* Define to 1 to enable rolling-checksum ASM optimizations (requires
+   --enable-roll-simd) */
+#undef USE_ROLL_ASM
+
+/* Define to 1 to enable rolling-checksum SIMD optimizations */
+#undef USE_ROLL_SIMD
+
 /* String to pass to iconv() for the UTF-8 charset. */
 #undef UTF8_CHARSET
 
 # endif
 #endif
 
-/* Enable large inode numbers on Mac OS X 10.5.  */
-#ifndef _DARWIN_USE_64_BIT_INODE
-# define _DARWIN_USE_64_BIT_INODE 1
-#endif
-
 /* Number of bits in a file offset, on hosts where this is settable. */
 #undef _FILE_OFFSET_BITS
 
index 64d2e6d..a2c9955 100644 (file)
@@ -2,12 +2,27 @@ dnl Process this file with autoconf to produce a configure script.
 
 AC_INIT([rsync],[ ],[https://rsync.samba.org/bug-tracking.html])
 
+AC_C_BIGENDIAN
+AC_HEADER_DIRENT
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
+    unistd.h utime.h compat.h sys/param.h ctype.h sys/wait.h sys/stat.h \
+    sys/ioctl.h sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h grp.h \
+    sys/un.h sys/attr.h arpa/inet.h arpa/nameser.h locale.h sys/types.h \
+    netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h mcheck.h \
+    sys/acl.h acl/libacl.h attr/xattr.h sys/xattr.h sys/extattr.h dl.h \
+    popt.h popt/popt.h linux/falloc.h netinet/in_systm.h netgroup.h \
+    zlib.h xxhash.h openssl/md4.h openssl/md5.h zstd.h lz4.h sys/file.h \
+    bsd/string.h)
+AC_CHECK_HEADERS([netinet/ip.h], [], [], [[#include <netinet/in.h>]])
+AC_HEADER_MAJOR_FIXED
+
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_SRCDIR([byteorder.h])
-AC_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADERS([config.h])
 AC_PREREQ([2.69])
 
-PACKAGE_VERSION=`sed 's/.*"\(.*\)".*/\1/' <$srcdir/version.h`
+PACKAGE_VERSION=`sed -n 's/.*RSYNC_VERSION.*"\(.*\)".*/\1/p' <$srcdir/version.h`
 
 AC_MSG_NOTICE([Configuring rsync $PACKAGE_VERSION])
 
@@ -26,7 +41,7 @@ AC_CONFIG_LIBOBJ_DIR([lib])
 
 AC_MSG_CHECKING([whether to include debugging symbols])
 AC_ARG_ENABLE(debug,
-       AS_HELP_STRING([--disable-debug],[disable debugging symbols and features]))
+       AS_HELP_STRING([--disable-debug],[disable to omit debugging symbols and features]))
 
 if test x"$enable_debug" = x"no"; then
     AC_MSG_RESULT(no)
@@ -45,7 +60,6 @@ AC_PROG_AWK
 AC_PROG_EGREP
 AC_PROG_INSTALL
 AC_PROG_MKDIR_P
-AC_PROG_CC_STDC
 AC_SUBST(SHELL)
 AC_PATH_PROG([PERL], [perl])
 AC_PATH_PROG([PYTHON3], [python3])
@@ -63,12 +77,12 @@ nl='
 '
 
 AC_ARG_ENABLE(profile,
-       AS_HELP_STRING([--enable-profile],[turn on CPU profiling]))
+       AS_HELP_STRING([--enable-profile],[enable to turn on CPU profiling]))
 if test x"$enable_profile" = x"yes"; then
        CFLAGS="$CFLAGS -pg"
 fi
 
-AC_MSG_CHECKING([if md2man can create man pages])
+AC_MSG_CHECKING([if md2man can create manpages])
 if test x"$ac_cv_path_PYTHON3" = x; then
     AC_MSG_RESULT(no - python3 not found)
     md2man_works=no
@@ -86,7 +100,7 @@ fi
 
 AC_MSG_CHECKING([if we require man-page building])
 AC_ARG_ENABLE([md2man],
-       AS_HELP_STRING([--disable-md2man],[disable md2man for man page creation]))
+       AS_HELP_STRING([--disable-md2man],[disable to omit manpage creation]))
 if test x"$enable_md2man" != x"no"; then
     if test -f "$srcdir/rsync.1"; then
        AC_MSG_RESULT(optional)
@@ -94,7 +108,7 @@ if test x"$enable_md2man" != x"no"; then
        AC_MSG_RESULT(required)
        if test x"$md2man_works" = x"no"; then
            err_msg="$err_msg$nl- You need python3 and either the cmarkgfm OR commonmark python3 lib in order"
-           err_msg="$err_msg$nl  to build man pages based on the git source (man pages are included in the"
+           err_msg="$err_msg$nl  to build manpages based on the git source (manpages are included in the"
            err_msg="$err_msg$nl  official release tar files)."
            no_lib="$no_lib md2man"
        fi
@@ -102,12 +116,11 @@ if test x"$enable_md2man" != x"no"; then
     MAKE_MAN=man
 else
     AC_MSG_RESULT(no)
-    MAKE_MAN=''
 fi
 
 # Specifically, this turns on panic_action handling.
 AC_ARG_ENABLE(maintainer-mode,
-       AS_HELP_STRING([--enable-maintainer-mode],[turn on extra debug features]))
+       AS_HELP_STRING([--enable-maintainer-mode],[enable to turn on extra debug features]))
 if test x"$enable_maintainer_mode" = x"yes"; then
        CFLAGS="$CFLAGS -DMAINTAINER_MODE"
 fi
@@ -121,16 +134,37 @@ if test x"$GCC" = x"yes"; then
        CFLAGS="$CFLAGS -Wall -W"
 fi
 
+AC_ARG_WITH(openssl-conf,
+       AS_HELP_STRING([--with-openssl-conf=PATH],[set default OPENSSL_CONF path for rsync]))
+case "$with_openssl_conf" in
+    *[^-/a-zA-Z0-9.,=@+_]*) AC_MSG_ERROR([Invalid path given to --with-openssl-conf]) ;;
+    /*) CFLAGS="$CFLAGS -DSET_OPENSSL_CONF=$with_openssl_conf" ;;
+    no|'') ;;
+    yes) AC_MSG_ERROR([No path given to --with-openssl-conf]) ;;
+    *) AC_MSG_ERROR([Non absolute path given to --with-openssl-conf]) ;;
+esac
+
+AC_ARG_WITH(rrsync,
+        AS_HELP_STRING([--with-rrsync],[also install the rrsync script and its manpage]))
+if test x"$with_rrsync" != x"yes"; then
+    with_rrsync=no
+else
+    MAKE_RRSYNC='rrsync'
+    MAKE_RRSYNC_1='rrsync.1'
+    GEN_RRSYNC='rrsync.1 rrsync.1.html'
+fi
+AC_SUBST(with_rrsync)
+
 AC_ARG_WITH(included-popt,
         AS_HELP_STRING([--with-included-popt],[use bundled popt library, not from system]))
 
 AC_ARG_WITH(included-zlib,
         AS_HELP_STRING([--with-included-zlib],[use bundled zlib library, not from system]))
 
-AC_ARG_WITH(protected-args,
-        AS_HELP_STRING([--with-protected-args],[make --protected-args option the default]))
-if test x"$with_protected_args" = x"yes"; then
-       AC_DEFINE_UNQUOTED(RSYNC_USE_PROTECTED_ARGS, 1, [Define to 1 if --protected-args should be the default])
+AC_ARG_WITH(secluded-args,
+        AS_HELP_STRING([--with-secluded-args],[make --secluded-args option the default]))
+if test x"$with_secluded_args" = x"yes"; then
+       AC_DEFINE_UNQUOTED(RSYNC_USE_SECLUDED_ARGS, 1, [Define to 1 if --secluded-args should be the default])
 fi
 
 AC_ARG_WITH(rsync-path,
@@ -180,6 +214,11 @@ AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
 AC_PATH_PROG(SHELL_PATH, sh, /bin/sh, [/usr/xpg4/bin$PATH_SEPARATOR$PATH])
 AC_PATH_PROG(FAKEROOT_PATH, fakeroot, /usr/bin/fakeroot, [/usr/xpg4/bin$PATH_SEPARATOR$PATH])
 
+AC_ARG_WITH(nobody-user,
+    AS_HELP_STRING([--with-nobody-user=USER],[set the default unprivileged user (default nobody)]),
+    [ NOBODY_USER="$with_nobody_user" ],
+    [ NOBODY_USER="nobody" ])
+
 AC_ARG_WITH(nobody-group,
     AS_HELP_STRING([--with-nobody-group=GROUP],[set the default unprivileged group (default nobody or nogroup)]),
     [ NOBODY_GROUP="$with_nobody_group" ])
@@ -196,24 +235,22 @@ if test x"$with_nobody_group" = x; then
     AC_MSG_RESULT($NOBODY_GROUP)
 fi
 
-AC_DEFINE_UNQUOTED(NOBODY_USER, "nobody", [unprivileged user--e.g. nobody])
+AC_DEFINE_UNQUOTED(NOBODY_USER, "$NOBODY_USER", [unprivileged user--e.g. nobody])
 AC_DEFINE_UNQUOTED(NOBODY_GROUP, "$NOBODY_GROUP", [unprivileged group for unprivileged user])
 
-# SIMD optimizations
-SIMD=
+# rolling-checksum SIMD optimizations
+ROLL_SIMD=
 
-AC_MSG_CHECKING([whether to enable SIMD optimizations])
-AC_ARG_ENABLE(simd,
-    AS_HELP_STRING([--disable-simd],[disable SIMD optimizations (requires c++)]))
+AC_MSG_CHECKING([whether to enable rolling-checksum SIMD optimizations])
+AC_ARG_ENABLE(roll-simd,
+    AS_HELP_STRING([--enable-roll-simd],[enable/disable to control rolling-checksum SIMD optimizations (requires c++)]))
 
 # Clag is crashing with -g -O2, so we'll get rid of -g for now.
 CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-g //'`
-
-if test x"$enable_simd" != x"no"; then
-    # For x86-64 SIMD, g++ >=5 or clang++ >=7 is required
-    if test x"$build_cpu" = x"x86_64"; then
-       AC_LANG(C++)
-       AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
+m4_define(SIMD_X86_64_TEST, [[#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
 #include <immintrin.h>
 __attribute__ ((target("default"))) int test_ssse3(int x) { return x; }
 __attribute__ ((target("default"))) int test_sse2(int x) { return x; }
@@ -233,27 +270,45 @@ __attribute__ ((target("ssse3"))) void more_testing(char* buf, int len)
        in8_2 = _mm_lddqu_si128((__m128i_u*)&buf[i + 16]);
     }
 }
-]], [[if (test_ssse3(42) != 42 || test_sse2(42) != 42 || test_avx2(42) != 42) exit(1);]])],[CXX_OK=yes],[CXX_OK=no])
+]])
+
+if test x"$enable_roll_simd" = x""; then
+    case "$host_os" in
+       *linux*) ;;
+       *) enable_roll_simd=no ;;
+    esac
+fi
+
+if test x"$enable_roll_simd" != x"no"; then
+    # For x86-64 SIMD, g++ >=5 or clang++ >=7 is required
+    if test x"$host_cpu" = x"x86_64" || test x"$host_cpu" = x"amd64"; then
+       AC_LANG(C++)
+       if test x"$host" = x"$build"; then
+           AC_RUN_IFELSE([AC_LANG_PROGRAM([SIMD_X86_64_TEST],[[if (test_ssse3(42) != 42 || test_sse2(42) != 42 || test_avx2(42) != 42) exit(1);]])],
+               [CXX_OK=yes],[CXX_OK=no])
+       else
+           AC_COMPILE_IFELSE([AC_LANG_PROGRAM([SIMD_X86_64_TEST])],[CXX_OK=yes],[CXX_OK=no])
+       fi
        AC_LANG(C)
        if test x"$CXX_OK" = x"yes"; then
            # AC_MSG_RESULT() is called below.
-           SIMD="x86_64"
-       elif test x"$enable_simd" = x"yes"; then
+           ROLL_SIMD="$host_cpu"
+       elif test x"$enable_roll_simd" = x"yes"; then
            AC_MSG_RESULT(error)
-           AC_MSG_ERROR(The SIMD compilation test failed.
-Omit --enable-simd to continue without it.)
+           AC_MSG_ERROR(The rolling-checksum SIMD compilation test failed.
+Omit --enable-roll-simd to continue without it.)
        fi
-    elif test x"$enable_simd" = x"yes"; then
+    elif test x"$enable_roll_simd" = x"yes"; then
         AC_MSG_RESULT(unavailable)
-        AC_MSG_ERROR(The SIMD optimizations are currently x86_64 only.
-Omit --enable-simd to continue without it.)
+        AC_MSG_ERROR(The rolling-checksum SIMD optimizations are currently x86_64|amd64 only.
+Omit --enable-roll-simd to continue without it.)
     fi
 fi
 
-if test x"$SIMD" != x""; then
-    AC_MSG_RESULT([yes ($SIMD)])
-    AC_DEFINE(HAVE_SIMD, 1, [Define to 1 to enable SIMD optimizations])
-    SIMD='$(SIMD_'"$SIMD)"
+if test x"$ROLL_SIMD" != x""; then
+    AC_MSG_RESULT([yes ($ROLL_SIMD)])
+    AC_DEFINE(USE_ROLL_SIMD, 1, [Define to 1 to enable rolling-checksum SIMD optimizations])
+    ROLL_SIMD='$(ROLL_SIMD_'"$ROLL_SIMD)"
     # We only use c++ for its target attribute dispatching, disable unneeded bulky features
     CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-rtti"
     # Apple often has "g++" as a symlink for clang. Try to find out the truth.
@@ -265,7 +320,7 @@ else
     AC_MSG_RESULT(no)
 fi
 
-AC_SUBST(SIMD)
+AC_SUBST(ROLL_SIMD)
 
 AC_MSG_CHECKING([if assembler accepts noexecstack])
 OLD_CFLAGS="$CFLAGS"
@@ -276,43 +331,19 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[return 0;]])],
 CFLAGS="$OLD_CFLAGS"
 AC_SUBST(NOEXECSTACK)
 
-ASM=
-
-AC_MSG_CHECKING([whether to enable ASM optimizations])
-AC_ARG_ENABLE(asm,
-    AS_HELP_STRING([--disable-asm],[disable ASM optimizations]))
-
-if test x"$enable_asm" != x"no"; then
-    if test x"$build_cpu" = x"x86_64"; then
-       ASM="$build_cpu"
-    elif test x"$enable_asm" = x"yes"; then
-        AC_MSG_RESULT(unavailable)
-        AC_MSG_ERROR(The ASM optimizations are currently x86_64 only.
-Omit --enable-asm to continue without it.)
-    fi
-fi
-
-if test x"$ASM" != x""; then
-    AC_MSG_RESULT([yes ($ASM)])
-    AC_DEFINE(HAVE_ASM, 1, [Define to 1 to enable ASM optimizations])
-    ASM='$(ASM_'"$ASM)"
-else
-    AC_MSG_RESULT(no)
-fi
-
-AC_SUBST(ASM)
-
 # arrgh. libc in some old debian version screwed up the largefile
 # stuff, getting byte range locking wrong
 AC_CACHE_CHECK([for broken largefile support],rsync_cv_HAVE_BROKEN_LARGEFILE,[
 AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #define _FILE_OFFSET_BITS 64
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/types.h>
+$ac_includes_default
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#elif defined HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
-#if HAVE_UNISTD_H
-#include <unistd.h>
 #endif
 
 int main(void)
@@ -345,132 +376,39 @@ if test x"$rsync_cv_HAVE_BROKEN_LARGEFILE" != x"yes"; then
    AC_SYS_LARGEFILE
 fi
 
-ipv6type=unknown
-ipv6lib=none
-ipv6trylibc=yes
-
+AC_MSG_CHECKING([whether to enable ipv6])
 AC_ARG_ENABLE(ipv6,
-       AS_HELP_STRING([--disable-ipv6],[turn off IPv6 support]))
-if test x"$enable_ipv6" != x"no"; then
-       AC_MSG_CHECKING([ipv6 stack type])
-       for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta cygwin TANDEM; do
-               case $i in
-               inria)
-                       # http://www.kame.net/
-                       AC_EGREP_CPP(yes, [
-#include <netinet/in.h>
-#ifdef IPV6_INRIA_VERSION
-yes
-#endif],
-                               [ipv6type=$i;
-                               AC_DEFINE(INET6, 1, [true if you have IPv6])
-                               ])
-                       ;;
-               kame)
-                       # http://www.kame.net/
-                       AC_EGREP_CPP(yes, [
-#include <netinet/in.h>
-#ifdef __KAME__
-yes
-#endif],
-                               [ipv6type=$i;
-                               AC_DEFINE(INET6, 1, [true if you have IPv6])])
-                       ;;
-               linux-glibc)
-                       # http://www.v6.linux.or.jp/
-                       AC_EGREP_CPP(yes, [
-#include <features.h>
-#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
-yes
-#endif],
-                               [ipv6type=$i;
-AC_DEFINE(INET6, 1, [true if you have IPv6])])
-                       ;;
-               linux-inet6)
-                       # http://www.v6.linux.or.jp/
-                       if test -d /usr/inet6 -o -f /usr/inet6/lib/libinet6.a; then
-                               ipv6type=$i
-                               ipv6lib=inet6
-                               ipv6libdir=/usr/inet6/lib
-                               ipv6trylibc=yes;
-                               AC_DEFINE(INET6, 1, [true if you have IPv6])
-                               CFLAGS="-I/usr/inet6/include $CFLAGS"
-                       fi
-                       ;;
-               solaris)
-                       # http://www.sun.com
-                       AC_EGREP_CPP(yes, [
-#include <netinet/ip6.h>
-#ifdef __sun
-yes
-#endif],
-                               [ipv6type=$i;
-                               AC_DEFINE(INET6, 1, [true if you have IPv6])])
-                       ;;
-               toshiba)
-                       AC_EGREP_CPP(yes, [
-#include <sys/param.h>
-#ifdef _TOSHIBA_INET6
-yes
-#endif],
-                               [ipv6type=$i;
-                               ipv6lib=inet6;
-                               ipv6libdir=/usr/local/v6/lib;
-                               AC_DEFINE(INET6, 1, [true if you have IPv6])])
-                       ;;
-               v6d)
-                       AC_EGREP_CPP(yes, [
-#include </usr/local/v6/include/sys/v6config.h>
-#ifdef __V6D__
-yes
-#endif],
-                               [ipv6type=$i;
-                               ipv6lib=v6;
-                               ipv6libdir=/usr/local/v6/lib;
-                               AC_DEFINE(INET6, 1, [true if you have IPv6])])
-                       ;;
-               zeta)
-                       AC_EGREP_CPP(yes, [
-#include <sys/param.h>
-#ifdef _ZETA_MINAMI_INET6
-yes
-#endif],
-                               [ipv6type=$i;
-                               ipv6lib=inet6;
-                               ipv6libdir=/usr/local/v6/lib;
-                               AC_DEFINE(INET6, 1, [true if you have IPv6])])
-                       ;;
-               cygwin)
-                       AC_EGREP_CPP(yes, [
-#include <netinet/in.h>
-#ifdef _CYGWIN_IN6_H
-yes
-#endif],
-                               [ipv6type=$i;
-                               AC_DEFINE(INET6, 1, [true if you have IPv6])])
-                       ;;
-               TANDEM)
-                       AC_EGREP_CPP(yes, [
-#include <netinet/ip6.h>
-#ifdef __TANDEM
-yes
-#endif],
-                               [ipv6type=$i;
-                               AC_DEFINE(INET6, 1, [true if you have IPv6])])
-                       ;;
-               esac
-               if test "$ipv6type" != "unknown"; then
-                       break
-               fi
-       done
-       AC_MSG_RESULT($ipv6type)
+AS_HELP_STRING([--disable-ipv6],[disable to omit ipv6 support]),
+[ case "$enableval" in
+  no)
+       AC_MSG_RESULT(no)
+       ;;
+  *)   AC_MSG_RESULT(yes)
+       AC_DEFINE(INET6, 1, [true if you have IPv6])
+       ;;
+  esac ],
 
-       AC_SEARCH_LIBS(getaddrinfo, inet6)
-fi
+  AC_RUN_IFELSE([AC_LANG_SOURCE([[ /* AF_INET6 availability check */
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+main()
+{
+   if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
+     exit(1);
+   else
+     exit(0);
+}
+]])],
+  [AC_MSG_RESULT(yes)
+  AC_DEFINE(INET6, 1, true if you have IPv6)],
+  [AC_MSG_RESULT(no)],
+  [AC_MSG_RESULT(no)]
+))
 
 dnl Do you want to disable use of locale functions
 AC_ARG_ENABLE([locale],
-       AS_HELP_STRING([--disable-locale],[disable locale features]))
+       AS_HELP_STRING([--disable-locale],[disable to omit locale features]))
 AH_TEMPLATE([CONFIG_LOCALE],
 [Undefine if you do not want locale features.  By default this is defined.])
 if test x"$enable_locale" != x"no"; then
@@ -486,30 +424,17 @@ case $host_os in
               * ) AC_MSG_RESULT(no);;
 esac
 
-AC_C_BIGENDIAN
-AC_HEADER_DIRENT
-AC_HEADER_TIME
-AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
-    unistd.h utime.h grp.h compat.h sys/param.h ctype.h sys/wait.h \
-    sys/ioctl.h sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h \
-    sys/un.h sys/attr.h mcheck.h arpa/inet.h arpa/nameser.h locale.h \
-    netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h \
-    sys/acl.h acl/libacl.h attr/xattr.h sys/xattr.h sys/extattr.h dl.h \
-    popt.h popt/popt.h linux/falloc.h netinet/in_systm.h netinet/ip.h \
-    zlib.h xxhash.h openssl/md4.h openssl/md5.h zstd.h lz4.h sys/file.h)
-AC_HEADER_MAJOR_FIXED
-
 AC_MSG_CHECKING([whether to enable use of openssl crypto library])
 AC_ARG_ENABLE([openssl],
-       AS_HELP_STRING([--disable-openssl],[disable openssl crypto library]))
+       AS_HELP_STRING([--disable-openssl],[disable to omit openssl crypto library]))
 AH_TEMPLATE([USE_OPENSSL],
 [Undefine if you do not want to use openssl crypto library.  By default this is defined.])
 if test x"$enable_openssl" != x"no"; then
     if test x"$ac_cv_header_openssl_md4_h" = x"yes" && test x"$ac_cv_header_openssl_md5_h" = x"yes"; then
       AC_MSG_RESULT(yes)
       AC_SEARCH_LIBS(MD5_Init, crypto,
-          [AC_DEFINE(USE_OPENSSL)],
+          [AC_DEFINE(USE_OPENSSL)
+          enable_openssl=yes],
           [err_msg="$err_msg$nl- Failed to find MD5_Init function in openssl crypto lib.";
           no_lib="$no_lib openssl"])
     else
@@ -517,13 +442,70 @@ if test x"$enable_openssl" != x"no"; then
        err_msg="$err_msg$nl- Failed to find openssl/md4.h and openssl/md5.h for openssl crypto lib support."
        no_lib="$no_lib openssl"
     fi
+    if test x"$enable_md5_asm" != x"yes"; then
+       enable_md5_asm=no
+    fi
+else
+    AC_MSG_RESULT(no)
+fi
+
+MD5_ASM=
+
+AC_MSG_CHECKING([whether to enable MD5 ASM optimizations])
+AC_ARG_ENABLE(md5-asm,
+    AS_HELP_STRING([--enable-md5-asm],[enable/disable to control MD5 ASM optimizations]))
+
+if test x"$enable_md5_asm" = x""; then
+    case "$host_os" in
+       *linux*) ;;
+       *) enable_md5_asm=no ;;
+    esac
+fi
+
+if test x"$enable_md5_asm" != x"no"; then
+    if test x"$host_cpu" = x"x86_64" || test x"$host_cpu" = x"amd64"; then
+       MD5_ASM="$host_cpu"
+    elif test x"$enable_md5_asm" = x"yes"; then
+        AC_MSG_RESULT(unavailable)
+        AC_MSG_ERROR(The ASM optimizations are currently x86_64|amd64 only.
+Omit --enable-md5-asm to continue without it.)
+    fi
+fi
+
+if test x"$MD5_ASM" != x""; then
+    AC_MSG_RESULT([yes ($MD5_ASM)])
+    AC_DEFINE(USE_MD5_ASM, 1, [Define to 1 to enable MD5 ASM optimizations])
+    MD5_ASM='$(MD5_ASM_'"$MD5_ASM)"
 else
     AC_MSG_RESULT(no)
 fi
 
+AC_SUBST(MD5_ASM)
+
+ROLL_ASM=
+
+AC_MSG_CHECKING([whether to enable rolling-checksum ASM optimizations])
+AC_ARG_ENABLE(roll-asm,
+    AS_HELP_STRING([--enable-roll-asm],[enable/disable to control rolling-checksum ASM optimizations (requires --enable-roll-simd)]))
+
+if test x"$ROLL_SIMD" = x""; then
+    enable_roll_asm=no
+fi
+
+if test x"$enable_roll_asm" = x"yes"; then
+    ROLL_ASM="$host_cpu"
+    AC_MSG_RESULT([yes ($ROLL_ASM)])
+    AC_DEFINE(USE_ROLL_ASM, 1, [Define to 1 to enable rolling-checksum ASM optimizations (requires --enable-roll-simd)])
+    ROLL_ASM='$(ROLL_ASM_'"$ROLL_ASM)"
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_SUBST(ROLL_ASM)
+
 AC_MSG_CHECKING([whether to enable xxhash checksum support])
 AC_ARG_ENABLE([xxhash],
-       AS_HELP_STRING([--disable-xxhash],[disable xxhash checksums]))
+       AS_HELP_STRING([--disable-xxhash],[disable to omit xxhash checksums]))
 AH_TEMPLATE([SUPPORT_XXHASH],
 [Undefine if you do not want xxhash checksums.  By default this is defined.])
 if test x"$enable_xxhash" != x"no"; then
@@ -544,7 +526,7 @@ fi
 
 AC_MSG_CHECKING([whether to enable zstd compression])
 AC_ARG_ENABLE([zstd],
-        AC_HELP_STRING([--disable-zstd], [disable zstd compression]))
+        AS_HELP_STRING([--disable-zstd], [disable to omit zstd compression]))
 AH_TEMPLATE([SUPPORT_ZSTD],
 [Undefine if you do not want zstd compression.  By default this is defined.])
 if test x"$enable_zstd" != x"no"; then
@@ -565,7 +547,7 @@ fi
 
 AC_MSG_CHECKING([whether to enable LZ4 compression])
 AC_ARG_ENABLE([lz4],
-        AC_HELP_STRING([--disable-lz4], [disable LZ4 compression]))
+        AS_HELP_STRING([--disable-lz4], [disable to omit LZ4 compression]))
 AH_TEMPLATE([SUPPORT_LZ4],
 [Undefine if you do not want LZ4 compression.  By default this is defined.])
 if test x"$enable_lz4" != x"no"; then
@@ -590,7 +572,7 @@ if test x"$no_lib" != x; then
     echo "$err_msg"
     echo ""
     echo "See the INSTALL file for hints on how to install the missing libraries and/or"
-    echo "how to generate (or fetch) man pages:"
+    echo "how to generate (or fetch) manpages:"
     echo "    https://github.com/WayneD/rsync/blob/master/INSTALL.md"
     echo ""
     echo "To disable one or more features, the relevant configure options are:"
@@ -603,7 +585,9 @@ fi
 
 AC_CACHE_CHECK([if makedev takes 3 args],rsync_cv_MAKEDEV_TAKES_3_ARGS,[
 AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 #ifdef MAJOR_IN_MKDEV
 #include <sys/mkdev.h>
 # if !defined makedev && (defined mkdev || defined _WIN32 || defined __WIN32__)
@@ -649,7 +633,11 @@ fi
 
 AC_TYPE_UID_T
 AC_CHECK_TYPES([mode_t,off_t,size_t,pid_t,id_t])
-AC_TYPE_GETGROUPS
+if test "$cross_compiling" = no; then
+    AC_TYPE_GETGROUPS
+else
+    AC_DEFINE([GETGROUPS_T],[gid_t],[Define to the type of elements in the array set by `getgroups'. Usually this is either `int' or `gid_t'.])
+fi
 AC_CHECK_MEMBERS([struct stat.st_rdev,
                  struct stat.st_mtimensec,
                  struct stat.st_mtimespec.tv_nsec,
@@ -719,7 +707,9 @@ AC_SEARCH_LIBS(libiconv_open, iconv)
 AC_MSG_CHECKING([for iconv declaration])
 AC_CACHE_VAL(am_cv_proto_iconv, [
     AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if HAVE_STDLIB_H
 #include <stdlib.h>
+#endif
 #include <iconv.h>
 extern
 #ifdef __cplusplus
@@ -743,31 +733,47 @@ dnl AC_MSG_NOTICE([Looking in libraries: $LIBS])
 AC_REPLACE_FUNCS([inet_ntop inet_pton])
 
 AC_HAVE_TYPE([struct addrinfo], [#include <netdb.h>])
-AC_HAVE_TYPE([struct sockaddr_storage], [#include <sys/types.h>
-#include <sys/socket.h>])
+AC_HAVE_TYPE([struct sockaddr_storage], [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif])
 
 # Irix 6.5 has getaddrinfo but not the corresponding defines, so use
 #   builtin getaddrinfo if one of the defines don't exist
 AC_CACHE_CHECK([whether defines needed by getaddrinfo exist],
                rsync_cv_HAVE_GETADDR_DEFINES,[
                        AC_EGREP_CPP(yes, [
-                       #include <sys/types.h>
-                       #include <sys/socket.h>
-                       #include <netdb.h>
-                       #ifdef AI_PASSIVE
-                       yes
-                       #endif],
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef AI_PASSIVE
+yes
+#endif],
                        rsync_cv_HAVE_GETADDR_DEFINES=yes,
                        rsync_cv_HAVE_GETADDR_DEFINES=no)])
-AS_IF([test x"$rsync_cv_HAVE_GETADDR_DEFINES" = x"yes" -a x"$ac_cv_type_struct_addrinfo" = x"yes"],[
+AS_IF([test x"$rsync_cv_HAVE_GETADDR_DEFINES" = x"yes" && test x"$ac_cv_type_struct_addrinfo" = x"yes"],[
        # Tru64 UNIX has getaddrinfo() but has it renamed in libc as
        # something else so we must include <netdb.h> to get the
        # redefinition.
        AC_CHECK_FUNCS(getaddrinfo, ,
                [AC_MSG_CHECKING([for getaddrinfo by including <netdb.h>])
-               AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
-               #include <sys/socket.h>
-               #include <netdb.h>]], [[getaddrinfo(NULL, NULL, NULL, NULL);]])],[AC_MSG_RESULT([yes])
+               AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#include <netdb.h>]], [[getaddrinfo(NULL, NULL, NULL, NULL);]])],[AC_MSG_RESULT([yes])
                        AC_DEFINE(HAVE_GETADDRINFO, 1,
                                [Define to 1 if you have the "getaddrinfo" function and required types.])],[AC_MSG_RESULT([no])
                        AC_LIBOBJ([getaddrinfo])])])
@@ -777,16 +783,24 @@ AC_CHECK_MEMBER([struct sockaddr.sa_len],
                [ AC_DEFINE(HAVE_SOCKADDR_LEN, 1, [Do we have sockaddr.sa_len?]) ],
                [],
                [
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 ])
 
 AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
                [ AC_DEFINE(HAVE_SOCKADDR_IN_LEN, 1, [Do we have sockaddr_in.sin_len?]) ],
                [],
                [
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 #include <netinet/in.h>
 ])
 
@@ -794,8 +808,12 @@ AC_CHECK_MEMBER([struct sockaddr_un.sun_len],
                [ AC_DEFINE(HAVE_SOCKADDR_UN_LEN, 1, [Do we have sockaddr_un.sun_len?]) ],
                [],
                [
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 #include <netinet/in.h>
 ])
 
@@ -803,8 +821,12 @@ AC_CHECK_MEMBER([struct sockaddr_in6.sin6_scope_id],
                [ AC_DEFINE(HAVE_SOCKADDR_IN6_SCOPE_ID, 1, [Do we have sockaddr_in6.sin6_scope_id?]) ],
                [],
                [
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 #include <netinet/in.h>
 ])
 
@@ -848,11 +870,12 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd chown chmod lchmod mknod mkfifo \
     fchmod fstat ftruncate strchr readlink link utime utimes lutimes strftime \
     chflags getattrlist mktime innetgr linkat \
     memmove lchown vsnprintf snprintf vasprintf asprintf setsid strpbrk \
-    strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
+    strlcat strlcpy strtol mallinfo mallinfo2 getgroups setgroups geteuid getegid \
     setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
     seteuid strerror putenv iconv_open locale_charset nl_langinfo getxattr \
     extattr_get_link sigaction sigprocmask setattrlist getgrouplist \
-    initgroups utimensat posix_fallocate attropen setvbuf nanosleep usleep)
+    initgroups utimensat posix_fallocate attropen setvbuf nanosleep usleep \
+    setenv unsetenv)
 
 dnl cygwin iconv.h defines iconv_open as libiconv_open
 if test x"$ac_cv_func_iconv_open" != x"yes"; then
@@ -863,7 +886,9 @@ dnl Preallocation stuff (also fallocate, posix_fallocate function tests above):
 
 AC_CACHE_CHECK([for useable fallocate],rsync_cv_have_fallocate,[
 AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <fcntl.h>
-#include <sys/types.h>]], [[fallocate(0, 0, 0, 0);]])],[rsync_cv_have_fallocate=yes],[rsync_cv_have_fallocate=no])])
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif]], [[fallocate(0, 0, 0, 0);]])],[rsync_cv_have_fallocate=yes],[rsync_cv_have_fallocate=no])])
 if test x"$rsync_cv_have_fallocate" = x"yes"; then
     AC_DEFINE(HAVE_FALLOCATE, 1, [Define to 1 if you have the fallocate function and it compiles and links without error])
 fi
@@ -900,8 +925,12 @@ AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
 
 AC_CACHE_CHECK([for SYS_fallocate],rsync_cv_have_sys_fallocate,[
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/syscall.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#include <sys/types.h>]], [[syscall(SYS_fallocate, 0, 0, (loff_t)0, (loff_t)0);]])],[rsync_cv_have_sys_fallocate=yes],[rsync_cv_have_sys_fallocate=no])])
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif]], [[syscall(SYS_fallocate, 0, 0, (loff_t)0, (loff_t)0);]])],[rsync_cv_have_sys_fallocate=yes],[rsync_cv_have_sys_fallocate=no])])
 if test x"$rsync_cv_have_sys_fallocate" = x"yes"; then
     AC_DEFINE(HAVE_SYS_FALLOCATE, 1, [Define to 1 if you have the SYS_fallocate syscall number])
 fi
@@ -928,7 +957,7 @@ if test $ac_cv_func_getpgrp = yes; then
 fi
 
 AC_ARG_ENABLE(iconv-open,
-    AS_HELP_STRING([--disable-iconv-open],[disable all use of iconv_open() function]),
+    AS_HELP_STRING([--disable-iconv-open],[disable to avoid all use of iconv_open()]),
     [], [enable_iconv_open=$ac_cv_func_iconv_open])
 
 if test x"$enable_iconv_open" != x"no"; then
@@ -936,7 +965,7 @@ if test x"$enable_iconv_open" != x"no"; then
 fi
 
 AC_ARG_ENABLE(iconv,
-    AS_HELP_STRING([--disable-iconv],[disable rsync's --iconv option]),
+    AS_HELP_STRING([--disable-iconv],[disable to omit the --iconv option]),
     [], [enable_iconv=$enable_iconv_open])
 AH_TEMPLATE([ICONV_OPTION],
 [Define if you want the --iconv option.  Specifying a value will set the
@@ -1020,8 +1049,12 @@ fi
 
 AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
 AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 
 int main(void) {
        int fd[2];
@@ -1082,13 +1115,16 @@ else
 fi
 
 AC_CACHE_CHECK([for unsigned char],rsync_cv_SIGNED_CHAR_OK,[
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[signed char *s = ""]])],[rsync_cv_SIGNED_CHAR_OK=yes],[rsync_cv_SIGNED_CHAR_OK=no])])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[signed char *s = (signed char *)""]])],[rsync_cv_SIGNED_CHAR_OK=yes],[rsync_cv_SIGNED_CHAR_OK=no])])
 if test x"$rsync_cv_SIGNED_CHAR_OK" = x"yes"; then
     AC_DEFINE(SIGNED_CHAR_OK, 1, [Define to 1 if "signed char" is a valid type])
 fi
 
 AC_CACHE_CHECK([for broken readdir],rsync_cv_HAVE_BROKEN_READDIR,[
-AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <sys/types.h>
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
 #include <dirent.h>
 int main(void) { struct dirent *di; DIR *d = opendir("."); di = readdir(d);
 if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 &&
@@ -1098,7 +1134,10 @@ if test x"$rsync_cv_HAVE_BROKEN_READDIR" = x"yes"; then
 fi
 
 AC_CACHE_CHECK([for utimbuf],rsync_cv_HAVE_STRUCT_UTIMBUF,[
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
 #include <utime.h>]], [[struct utimbuf tbuf;  tbuf.actime = 0; tbuf.modtime = 1; return utime("foo.c",&tbuf);]])],[rsync_cv_HAVE_STRUCT_UTIMBUF=yes],[rsync_cv_HAVE_STRUCT_UTIMBUF=no])])
 if test x"$rsync_cv_HAVE_STRUCT_UTIMBUF" = x"yes"; then
     AC_DEFINE(HAVE_STRUCT_UTIMBUF, 1, [Define to 1 if you have the "struct utimbuf" type])
@@ -1106,17 +1145,23 @@ fi
 
 AC_CACHE_CHECK([if gettimeofday takes tz argument],rsync_cv_HAVE_GETTIMEOFDAY_TZ,[
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/time.h>
-#include <unistd.h>]], [[struct timeval tv; return gettimeofday(&tv, NULL);]])],[rsync_cv_HAVE_GETTIMEOFDAY_TZ=yes],[rsync_cv_HAVE_GETTIMEOFDAY_TZ=no])])
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif]], [[struct timeval tv; return gettimeofday(&tv, NULL);]])],[rsync_cv_HAVE_GETTIMEOFDAY_TZ=yes],[rsync_cv_HAVE_GETTIMEOFDAY_TZ=no])])
 if test x"$rsync_cv_HAVE_GETTIMEOFDAY_TZ" != x"no"; then
     AC_DEFINE(HAVE_GETTIMEOFDAY_TZ, 1, [Define to 1 if gettimeofday() takes a time-zone arg])
 fi
 
 AC_CACHE_CHECK([for C99 vsnprintf],rsync_cv_HAVE_C99_VSNPRINTF,[
 AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 #include <stdarg.h>
 #include <stdio.h>
+#if HAVE_STDLIB_H
 #include <stdlib.h>
+#endif
 #include <string.h>
 void foo(const char *format, ...) {
        va_list ap;
@@ -1139,9 +1184,13 @@ fi
 
 AC_CACHE_CHECK([for secure mkstemp],rsync_cv_HAVE_SECURE_MKSTEMP,[
 AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <stdlib.h>
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 #include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 int main(void) {
   struct stat st;
   char tpl[20]="/tmp/test.XXXXXX";
@@ -1230,6 +1279,9 @@ AC_SUBST(OBJ_RESTORE)
 AC_SUBST(CC_SHOBJ_FLAG)
 AC_SUBST(BUILD_POPT)
 AC_SUBST(BUILD_ZLIB)
+AC_SUBST(MAKE_RRSYNC)
+AC_SUBST(MAKE_RRSYNC_1)
+AC_SUBST(GEN_RRSYNC)
 AC_SUBST(MAKE_MAN)
 
 AC_CHECK_FUNCS(_acl __acl _facl __facl)
@@ -1238,7 +1290,7 @@ AC_CHECK_FUNCS(_acl __acl _facl __facl)
 
 AC_MSG_CHECKING([whether to support ACLs])
 AC_ARG_ENABLE(acl-support,
-       AS_HELP_STRING([--disable-acl-support],[disable ACL support]))
+       AS_HELP_STRING([--disable-acl-support],[disable to omit ACL support]))
 
 if test x"$enable_acl_support" = x"no"; then
     AC_MSG_RESULT(no)
@@ -1284,16 +1336,26 @@ else
        AC_MSG_RESULT(running tests:)
        AC_CHECK_LIB(acl,acl_get_file)
        AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[
-           AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
-#include <sys/acl.h>]], [[ acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);]])],[samba_cv_HAVE_POSIX_ACLS=yes],[samba_cv_HAVE_POSIX_ACLS=no])])
+           AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif]], [[ acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);]])],[samba_cv_HAVE_POSIX_ACLS=yes],[samba_cv_HAVE_POSIX_ACLS=no])])
        AC_MSG_CHECKING(ACL test results)
        if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then
            AC_MSG_RESULT(Using posix ACLs)
            AC_DEFINE(HAVE_POSIX_ACLS, 1, [true if you have posix ACLs])
            AC_DEFINE(SUPPORT_ACLS, 1)
            AC_CACHE_CHECK([for acl_get_perm_np],samba_cv_HAVE_ACL_GET_PERM_NP,[
-               AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
-#include <sys/acl.h>]], [[ acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm);]])],[samba_cv_HAVE_ACL_GET_PERM_NP=yes],[samba_cv_HAVE_ACL_GET_PERM_NP=no])])
+               AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif]], [[ acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm);]])],[samba_cv_HAVE_ACL_GET_PERM_NP=yes],[samba_cv_HAVE_ACL_GET_PERM_NP=no])])
            if test x"$samba_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
                AC_DEFINE(HAVE_ACL_GET_PERM_NP, 1, [true if you have acl_get_perm_np])
            fi
@@ -1312,7 +1374,7 @@ fi
 # check for extended attribute support
 AC_MSG_CHECKING(whether to support extended attributes)
 AC_ARG_ENABLE(xattr-support,
-    AS_HELP_STRING([--disable-xattr-support],[disable extended attributes]),
+    AS_HELP_STRING([--disable-xattr-support],[disable to omit extended attributes]),
     [], [case "$ac_cv_func_getxattr$ac_cv_func_extattr_get_link$ac_cv_func_attropen" in
        *yes*) enable_xattr_support=maybe ;;
        *) enable_xattr_support=no ;;
@@ -1358,7 +1420,7 @@ else
     esac
 fi
 
-if test x"$enable_acl_support" = x"no" -o x"$enable_xattr_support" = x"no" -o x"$enable_iconv" = x"no"; then
+if test x"$enable_acl_support" = x"no" || test x"$enable_xattr_support" = x"no" || test x"$enable_iconv" = x"no"; then
     AC_MSG_CHECKING([whether $CC supports -Wno-unused-parameter])
     OLD_CFLAGS="$CFLAGS"
     CFLAGS="$CFLAGS -Wno-unused-parameter"
index 2a165dd..00da71f 100755 (executable)
@@ -1,11 +1,12 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for rsync  .
+# Generated by GNU Autoconf 2.71 for rsync.
 #
 # Report bugs to <https://rsync.samba.org/bug-tracking.html>.
 #
 #
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
+# Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
-else
+else $as_nop
   case `(set -o) 2>/dev/null` in #(
   *posix*) :
     set -o posix ;; #(
@@ -33,46 +36,46 @@ esac
 fi
 
 
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
 as_nl='
 '
 export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-       expr "X$arg" : "X\\(.*\\)$as_nl";
-       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
+IFS=" ""       $as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
 
 # The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
+if ${PATH_SEPARATOR+false} :; then
   PATH_SEPARATOR=:
   (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
     (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -81,13 +84,6 @@ if test "${PATH_SEPARATOR+set}" != set; then
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""       $as_nl"
-
 # Find who we are.  Look in the path if we contain no directory separator.
 as_myself=
 case $0 in #((
@@ -96,8 +92,12 @@ case $0 in #((
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
   done
 IFS=$as_save_IFS
 
@@ -109,30 +109,10 @@ if test "x$as_myself" = x; then
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
   exit 1
 fi
 
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 # Use a proper internal environment variable to ensure we don't fall
   # into an infinite loop, continuously re-executing ourselves.
@@ -154,20 +134,22 @@ esac
 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
 # Admittedly, this is quite paranoid, since all the known shells bail
 # out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
   fi
   # We don't want this to propagate to other subprocesses.
           { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
-  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  as_bourne_compatible="as_nop=:
+if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '\${1+\"\$@\"}'='\"\$@\"'
   setopt NO_GLOB_SUBST
-else
+else \$as_nop
   case \`(set -o) 2>/dev/null\` in #(
   *posix*) :
     set -o posix ;; #(
@@ -187,42 +169,53 @@ as_fn_success || { exitcode=1; echo as_fn_success failed.; }
 as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
 as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
 as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+if ( set x; as_fn_ret_success y && test x = \"\$1\" )
+then :
 
-else
+else \$as_nop
   exitcode=1; echo positional parameters were not saved.
 fi
 test x\$exitcode = x0 || exit 1
+blah=\$(echo \$(echo blah))
+test x\"\$blah\" = xblah || exit 1
 test -x / || exit 1"
   as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
   test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
 test \$(( 1 + 1 )) = 2 || exit 1"
-  if (eval "$as_required") 2>/dev/null; then :
+  if (eval "$as_required") 2>/dev/null
+then :
   as_have_required=yes
-else
+else $as_nop
   as_have_required=no
 fi
-  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
+then :
 
-else
+else $as_nop
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 as_found=false
 for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
   as_found=:
   case $as_dir in #(
         /*)
           for as_base in sh bash ksh sh5; do
             # Try only shells that exist, to save several forks.
-            as_shell=$as_dir/$as_base
+            as_shell=$as_dir$as_base
             if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-                   { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+                   as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
   CONFIG_SHELL=$as_shell as_have_required=yes
-                  if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+                  if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
+then :
   break 2
 fi
 fi
@@ -230,14 +223,21 @@ fi
        esac
   as_found=false
 done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
-             { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
-  CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
 IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+             as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi
+fi
 
 
-      if test "x$CONFIG_SHELL" != x; then :
+      if test "x$CONFIG_SHELL" != x
+then :
   export CONFIG_SHELL
              # We cannot yet assume a decent shell, so we have to provide a
 # neutralization value for shells without unset; and this also
@@ -255,18 +255,19 @@ esac
 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
 # Admittedly, this is quite paranoid, since all the known shells bail
 # out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
 exit 255
 fi
 
-    if test x$as_have_required = xno; then :
-  $as_echo "$0: This script requires a shell more modern than all"
-  $as_echo "$0: the shells that I found on your system."
-  if test x${ZSH_VERSION+set} = xset ; then
-    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
-    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+    if test x$as_have_required = xno
+then :
+  printf "%s\n" "$0: This script requires a shell more modern than all"
+  printf "%s\n" "$0: the shells that I found on your system."
+  if test ${ZSH_VERSION+y} ; then
+    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
   else
-    $as_echo "$0: Please tell bug-autoconf@gnu.org and
+    printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and
 $0: https://rsync.samba.org/bug-tracking.html about your
 $0: system, including any error possibly output before this
 $0: message. Then install a modern shell, or manually run
@@ -294,6 +295,7 @@ as_fn_unset ()
 }
 as_unset=as_fn_unset
 
+
 # as_fn_set_status STATUS
 # -----------------------
 # Set $? to STATUS, without forking.
@@ -311,6 +313,14 @@ as_fn_exit ()
   as_fn_set_status $1
   exit $1
 } # as_fn_exit
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
 
 # as_fn_mkdir_p
 # -------------
@@ -325,7 +335,7 @@ as_fn_mkdir_p ()
     as_dirs=
     while :; do
       case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
       *) as_qdir=$as_dir;;
       esac
       as_dirs="'$as_qdir' $as_dirs"
@@ -334,7 +344,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$as_dir" : 'X\(//\)[^/]' \| \
         X"$as_dir" : 'X\(//\)$' \| \
         X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
+printf "%s\n" X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -373,12 +383,13 @@ as_fn_executable_p ()
 # advantage of any shell optimizations that allow amortized linear growth over
 # repeated appends, instead of the typical quadratic growth present in naive
 # implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
   eval 'as_fn_append ()
   {
     eval $1+=\$2
   }'
-else
+else $as_nop
   as_fn_append ()
   {
     eval $1=\$$1\$2
@@ -390,18 +401,27 @@ fi # as_fn_append
 # Perform arithmetic evaluation on the ARGs, and store the result in the
 # global $as_val. Take advantage of shells that can avoid forks. The arguments
 # must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
   eval 'as_fn_arith ()
   {
     as_val=$(( $* ))
   }'
-else
+else $as_nop
   as_fn_arith ()
   {
     as_val=`expr "$@" || test $? -eq 1`
   }
 fi # as_fn_arith
 
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
 
 # as_fn_error STATUS ERROR [LINENO LOG_FD]
 # ----------------------------------------
@@ -413,9 +433,9 @@ as_fn_error ()
   as_status=$1; test $as_status -eq 0 && as_status=1
   if test "$4"; then
     as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $2" >&2
+  printf "%s\n" "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -442,7 +462,7 @@ as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
         X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
+printf "%s\n" X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
            s//\1/
            q
@@ -486,7 +506,7 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
       s/-\n.*//
     ' >$as_me.lineno &&
   chmod +x "$as_me.lineno" ||
-    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
   # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
   # already done that, so ensure we don't try to do so again and fall
@@ -500,6 +520,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
   exit
 }
 
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
 ECHO_C= ECHO_N= ECHO_T=
 case `echo -n x` in #(((((
 -n*)
@@ -513,6 +537,13 @@ case `echo -n x` in #(((((
   ECHO_N='-n';;
 esac
 
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
@@ -580,52 +611,50 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='rsync'
 PACKAGE_TARNAME='rsync'
-PACKAGE_VERSION=' '
-PACKAGE_STRING='rsync  '
+PACKAGE_VERSION=''
+PACKAGE_STRING='rsync'
 PACKAGE_BUGREPORT='https://rsync.samba.org/bug-tracking.html'
 PACKAGE_URL=''
 
-ac_unique_file="byteorder.h"
-ac_config_libobj_dir=lib
 # Factoring default headers for most tests.
 ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
+#include <stddef.h>
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
 #endif
-#ifdef STDC_HEADERS
+#ifdef HAVE_STDLIB_H
 # include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
 #endif
 #ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-#  include <memory.h>
-# endif
 # include <string.h>
 #endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
 #ifdef HAVE_INTTYPES_H
 # include <inttypes.h>
 #endif
 #ifdef HAVE_STDINT_H
 # include <stdint.h>
 #endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif"
 
-ac_header_list=
+ac_header_c_list=
+ac_unique_file="byteorder.h"
+ac_config_libobj_dir=lib
 ac_subst_vars='LTLIBOBJS
 MAKE_MAN
+GEN_RRSYNC
+MAKE_RRSYNC_1
+MAKE_RRSYNC
 BUILD_ZLIB
 BUILD_POPT
 CC_SHOBJ_FLAG
@@ -633,12 +662,14 @@ OBJ_RESTORE
 OBJ_SAVE
 ALLOCA
 LIBOBJS
-ASM
+ROLL_ASM
+MD5_ASM
 NOEXECSTACK
-SIMD
+ROLL_SIMD
 FAKEROOT_PATH
 SHELL_PATH
 HAVE_REMSH
+with_rrsync
 PYTHON3
 PERL
 MKDIR_P
@@ -652,13 +683,6 @@ ac_ct_CXX
 CXXFLAGS
 CXX
 CPP
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
 host_os
 host_vendor
 host_cpu
@@ -667,6 +691,13 @@ build_os
 build_vendor
 build_cpu
 build
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
 target_alias
 host_alias
 build_alias
@@ -713,19 +744,23 @@ enable_debug
 enable_profile
 enable_md2man
 enable_maintainer_mode
+with_openssl_conf
+with_rrsync
 with_included_popt
 with_included_zlib
-with_protected_args
+with_secluded_args
 with_rsync_path
 with_rsyncd_conf
 with_rsh
+with_nobody_user
 with_nobody_group
-enable_simd
-enable_asm
+enable_roll_simd
 enable_largefile
 enable_ipv6
 enable_locale
 enable_openssl
+enable_md5_asm
+enable_roll_asm
 enable_xxhash
 enable_zstd
 enable_lz4
@@ -814,8 +849,6 @@ do
   *)    ac_optarg=yes ;;
   esac
 
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
   case $ac_dashdash$ac_option in
   --)
     ac_dashdash=yes ;;
@@ -856,9 +889,9 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "enable_$ac_useropt"
@@ -882,9 +915,9 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "enable_$ac_useropt"
@@ -1095,9 +1128,9 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "with_$ac_useropt"
@@ -1111,9 +1144,9 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "with_$ac_useropt"
@@ -1157,9 +1190,9 @@ Try \`$0 --help' for more information"
 
   *)
     # FIXME: should be removed in autoconf 3.0.
-    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
     : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
@@ -1175,7 +1208,7 @@ if test -n "$ac_unrecognized_opts"; then
   case $enable_option_checking in
     no) ;;
     fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
-    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
 fi
 
@@ -1239,7 +1272,7 @@ $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$as_myself" : 'X\(//\)[^/]' \| \
         X"$as_myself" : 'X\(//\)$' \| \
         X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
+printf "%s\n" X"$as_myself" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -1296,7 +1329,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures rsync   to adapt to many kinds of systems.
+\`configure' configures rsync to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1362,7 +1395,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of rsync  :";;
+     short | recursive ) echo "Configuration of rsync:";;
    esac
   cat <<\_ACEOF
 
@@ -1370,35 +1403,42 @@ Optional Features:
   --disable-option-checking  ignore unrecognized --enable/--with options
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --disable-debug         disable debugging symbols and features
-  --enable-profile        turn on CPU profiling
-  --disable-md2man        disable md2man for man page creation
+  --disable-debug         disable to omit debugging symbols and features
+  --enable-profile        enable to turn on CPU profiling
+  --disable-md2man        disable to omit manpage creation
   --enable-maintainer-mode
-                          turn on extra debug features
-  --disable-simd          disable SIMD optimizations (requires c++)
-  --disable-asm           disable ASM optimizations
+                          enable to turn on extra debug features
+  --enable-roll-simd      enable/disable to control rolling-checksum SIMD
+                          optimizations (requires c++)
   --disable-largefile     omit support for large files
-  --disable-ipv6          turn off IPv6 support
-  --disable-locale        disable locale features
-  --disable-openssl       disable openssl crypto library
-  --disable-xxhash        disable xxhash checksums
-  --disable-zstd          disable zstd compression
-  --disable-lz4           disable LZ4 compression
-  --disable-iconv-open    disable all use of iconv_open() function
-  --disable-iconv         disable rsync's --iconv option
-  --disable-acl-support   disable ACL support
-  --disable-xattr-support disable extended attributes
+  --disable-ipv6          disable to omit ipv6 support
+  --disable-locale        disable to omit locale features
+  --disable-openssl       disable to omit openssl crypto library
+  --enable-md5-asm        enable/disable to control MD5 ASM optimizations
+  --enable-roll-asm       enable/disable to control rolling-checksum ASM
+                          optimizations (requires --enable-roll-simd)
+  --disable-xxhash        disable to omit xxhash checksums
+  --disable-zstd          disable to omit zstd compression
+  --disable-lz4           disable to omit LZ4 compression
+  --disable-iconv-open    disable to avoid all use of iconv_open()
+  --disable-iconv         disable to omit the --iconv option
+  --disable-acl-support   disable to omit ACL support
+  --disable-xattr-support disable to omit extended attributes
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-openssl-conf=PATH
+                          set default OPENSSL_CONF path for rsync
+  --with-rrsync           also install the rrsync script and its manpage
   --with-included-popt    use bundled popt library, not from system
   --with-included-zlib    use bundled zlib library, not from system
-  --with-protected-args   make --protected-args option the default
+  --with-secluded-args    make --secluded-args option the default
   --with-rsync-path=PATH  set default --rsync-path to PATH (default: rsync)
   --with-rsyncd-conf=PATH set configuration file for rsync server to PATH
                           (default: /etc/rsyncd.conf)
   --with-rsh=CMD          set remote shell command to CMD (default: ssh)
+  --with-nobody-user=USER set the default unprivileged user (default nobody)
   --with-nobody-group=GROUP
                           set the default unprivileged group (default nobody
                           or nogroup)
@@ -1434,9 +1474,9 @@ if test "$ac_init_help" = "recursive"; then
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -1464,7 +1504,8 @@ esac
 ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
     cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
+    # Check for configure.gnu first; this name is used for a wrapper for
+    # Metaconfig's "Configure" on case-insensitive file systems.
     if test -f "$ac_srcdir/configure.gnu"; then
       echo &&
       $SHELL "$ac_srcdir/configure.gnu" --help=recursive
@@ -1472,7 +1513,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
       echo &&
       $SHELL "$ac_srcdir/configure" --help=recursive
     else
-      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi || ac_status=$?
     cd "$ac_pwd" || { ac_status=$?; break; }
   done
@@ -1482,9 +1523,9 @@ test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
 rsync configure
-generated by GNU Autoconf 2.69
+generated by GNU Autoconf 2.71
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1501,14 +1542,14 @@ fi
 ac_fn_c_try_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
+  rm -f conftest.$ac_objext conftest.beam
   if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1516,14 +1557,15 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
+       } && test -s conftest.$ac_objext
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
        ac_retval=1
@@ -1533,6 +1575,129 @@ fi
 
 } # ac_fn_c_try_compile
 
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
+# executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: program exited with status $ac_status" >&5
+       printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  eval "$3=yes"
+else $as_nop
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+        test "$cross_compiling" = yes ||
+        test -x conftest$ac_exeext
+       }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
 # ac_fn_c_try_cpp LINENO
 # ----------------------
 # Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -1545,7 +1710,7 @@ case "(($ac_try" in
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1553,14 +1718,15 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } > conftest.i && {
         test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
         test ! -s conftest.err
-       }; then :
+       }
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
     ac_retval=1
@@ -1576,14 +1742,14 @@ fi
 ac_fn_cxx_try_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
+  rm -f conftest.$ac_objext conftest.beam
   if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1591,14 +1757,15 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
         test -z "$ac_cxx_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
+       } && test -s conftest.$ac_objext
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
        ac_retval=1
@@ -1610,8 +1777,8 @@ fi
 
 # ac_fn_cxx_try_run LINENO
 # ------------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
+# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
+# executables *can* be run.
 ac_fn_cxx_try_run ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
@@ -1621,25 +1788,26 @@ case "(($ac_try" in
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
   { { case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_try") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: program exited with status $ac_status" >&5
+       printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
        ac_retval=$ac_status
 
 } # ac_fn_cxx_try_run
 
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=$ac_status
-fi
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
 
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       } && test -s conftest$ac_exeext && {
-        test "$cross_compiling" = yes ||
-        test -x conftest$ac_exeext
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=1
-fi
-  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
-  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
-  # interfere with the next link command; also delete a directory that is
-  # left behind by Apple's compiler.  We do this before executing the actions.
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_compile
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_header_compiler=yes
-else
-  ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  ac_header_preproc=yes
-else
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
-  yes:no: )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## -------------------------------------------------------- ##
-## Report this to https://rsync.samba.org/bug-tracking.html ##
-## -------------------------------------------------------- ##"
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
-# --------------------------------------------
-# Tries to find the compile-time value of EXPR in a program that includes
-# INCLUDES, setting VAR accordingly. Returns whether the value could be
-# computed
-ac_fn_c_compute_int ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if test "$cross_compiling" = yes; then
-    # Depending upon the size, compute the lo and hi bounds.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_lo=0 ac_mid=0
-  while :; do
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
 test_array [0] = 0;
@@ -1901,9 +1860,10 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_hi=$ac_mid; break
-else
+else $as_nop
   as_fn_arith $ac_mid + 1 && ac_lo=$as_val
                        if test $ac_lo -le $ac_mid; then
                          ac_lo= ac_hi=
@@ -1911,14 +1871,14 @@ else
                        fi
                        as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   done
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(($2) < 0)];
 test_array [0] = 0;
@@ -1928,14 +1888,15 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_hi=-1 ac_mid=-1
   while :; do
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(($2) >= $ac_mid)];
 test_array [0] = 0;
@@ -1945,9 +1906,10 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_lo=$ac_mid; break
-else
+else $as_nop
   as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
                        if test $ac_mid -le $ac_hi; then
                          ac_lo= ac_hi=
@@ -1955,14 +1917,14 @@ else
                        fi
                        as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   done
-else
+else $as_nop
   ac_lo= ac_hi=
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 # Binary search between lo and hi bounds.
 while test "x$ac_lo" != "x$ac_hi"; do
   as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
@@ -1970,7 +1932,7 @@ while test "x$ac_lo" != "x$ac_hi"; do
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
 test_array [0] = 0;
@@ -1980,12 +1942,13 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_hi=$ac_mid
-else
+else $as_nop
   as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 done
 case $ac_lo in #((
 ?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
@@ -1995,12 +1958,12 @@ esac
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
-static long int longval () { return $2; }
-static unsigned long int ulongval () { return $2; }
+static long int longval (void) { return $2; }
+static unsigned long int ulongval (void) { return $2; }
 #include <stdio.h>
 #include <stdlib.h>
 int
-main ()
+main (void)
 {
 
   FILE *f = fopen ("conftest.val", "w");
@@ -2028,9 +1991,10 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   echo >>conftest.val; read $3 <conftest.val; ac_retval=0
-else
+else $as_nop
   ac_retval=1
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -2050,17 +2014,18 @@ rm -f conftest.val
 ac_fn_c_check_type ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   eval "$3=no"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 if (sizeof ($2))
         return 0;
@@ -2068,12 +2033,13 @@ if (sizeof ($2))
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 int
-main ()
+main (void)
 {
 if (sizeof (($2)))
            return 0;
@@ -2081,18 +2047,19 @@ if (sizeof (($2)))
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
 
-else
+else $as_nop
   eval "$3=yes"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_type
@@ -2104,16 +2071,17 @@ $as_echo "$ac_res" >&6; }
 ac_fn_c_check_member ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
-$as_echo_n "checking for $2.$3... " >&6; }
-if eval \${$4+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+printf %s "checking for $2.$3... " >&6; }
+if eval test \${$4+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $5
 int
-main ()
+main (void)
 {
 static $2 ac_aggr;
 if (ac_aggr.$3)
@@ -2122,14 +2090,15 @@ return 0;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "$4=yes"
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $5
 int
-main ()
+main (void)
 {
 static $2 ac_aggr;
 if (sizeof ac_aggr.$3)
@@ -2138,18 +2107,19 @@ return 0;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "$4=yes"
-else
+else $as_nop
   eval "$4=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 eval ac_res=\$$4
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_member
@@ -2160,11 +2130,12 @@ $as_echo "$ac_res" >&6; }
 ac_fn_c_check_func ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 /* Define $2 to an innocuous variant, in case <limits.h> declares $2.
@@ -2172,16 +2143,9 @@ else
 #define $2 innocuous_$2
 
 /* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $2 (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+   which can conflict with char $2 (); below.  */
 
+#include <limits.h>
 #undef $2
 
 /* Override any GCC internal prototype to avoid an error.
@@ -2199,35 +2163,56 @@ choke me
 #endif
 
 int
-main ()
+main (void)
 {
 return $2 ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$3=yes"
-else
+else $as_nop
   eval "$3=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 fi
 eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_func
+ac_configure_args_raw=
+for ac_arg
+do
+  case $ac_arg in
+  *\'*)
+    ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  as_fn_append ac_configure_args_raw " '$ac_arg'"
+done
+
+case $ac_configure_args_raw in
+  *$as_nl*)
+    ac_safe_unquote= ;;
+  *)
+    ac_unsafe_z='|&;<>()$`\\"*?[ ''    ' # This string ends in space, tab.
+    ac_unsafe_a="$ac_unsafe_z#~"
+    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
+    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
+esac
+
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by rsync $as_me  , which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+It was created by rsync $as_me, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
 
-  $ $0 $@
+  $ $0$ac_configure_args_raw
 
 _ACEOF
 exec 5>>config.log
@@ -2260,8 +2245,12 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    $as_echo "PATH: $as_dir"
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    printf "%s\n" "PATH: $as_dir"
   done
 IFS=$as_save_IFS
 
@@ -2296,7 +2285,7 @@ do
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
     *\'*)
-      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
     1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
@@ -2331,11 +2320,13 @@ done
 # WARNING: Use '\'' to represent an apostrophe within the trap.
 # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
 trap 'exit_status=$?
+  # Sanitize IFS.
+  IFS=" ""     $as_nl"
   # Save into config.log some information that might help in debugging.
   {
     echo
 
-    $as_echo "## ---------------- ##
+    printf "%s\n" "## ---------------- ##
 ## Cache variables. ##
 ## ---------------- ##"
     echo
@@ -2346,8 +2337,8 @@ trap 'exit_status=$?
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
@@ -2371,7 +2362,7 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
 )
     echo
 
-    $as_echo "## ----------------- ##
+    printf "%s\n" "## ----------------- ##
 ## Output variables. ##
 ## ----------------- ##"
     echo
@@ -2379,14 +2370,14 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
     do
       eval ac_val=\$$ac_var
       case $ac_val in
-      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
       esac
-      $as_echo "$ac_var='\''$ac_val'\''"
+      printf "%s\n" "$ac_var='\''$ac_val'\''"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
-      $as_echo "## ------------------- ##
+      printf "%s\n" "## ------------------- ##
 ## File substitutions. ##
 ## ------------------- ##"
       echo
@@ -2394,15 +2385,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       do
        eval ac_val=\$$ac_var
        case $ac_val in
-       *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+       *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
        esac
-       $as_echo "$ac_var='\''$ac_val'\''"
+       printf "%s\n" "$ac_var='\''$ac_val'\''"
       done | sort
       echo
     fi
 
     if test -s confdefs.h; then
-      $as_echo "## ----------- ##
+      printf "%s\n" "## ----------- ##
 ## confdefs.h. ##
 ## ----------- ##"
       echo
@@ -2410,8 +2401,8 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       echo
     fi
     test "$ac_signal" != 0 &&
-      $as_echo "$as_me: caught signal $ac_signal"
-    $as_echo "$as_me: exit $exit_status"
+      printf "%s\n" "$as_me: caught signal $ac_signal"
+    printf "%s\n" "$as_me: exit $exit_status"
   } >&5
   rm -f core *.core core.conftest.* &&
     rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
@@ -2425,63 +2416,48 @@ ac_signal=0
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
 rm -f -r conftest* confdefs.h
 
-$as_echo "/* confdefs.h */" > confdefs.h
+printf "%s\n" "/* confdefs.h */" > confdefs.h
 
 # Predefined preprocessor variables.
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
+printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
+printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
+printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
+printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
+printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
+printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
 
 
 # Let the site file select an alternate cache file if it wants to.
 # Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  # We do not want a PATH search for config.site.
-  case $CONFIG_SITE in #((
-    -*)  ac_site_file1=./$CONFIG_SITE;;
-    */*) ac_site_file1=$CONFIG_SITE;;
-    *)   ac_site_file1=./$CONFIG_SITE;;
-  esac
+  ac_site_files="$CONFIG_SITE"
 elif test "x$prefix" != xNONE; then
-  ac_site_file1=$prefix/share/config.site
-  ac_site_file2=$prefix/etc/config.site
+  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
 else
-  ac_site_file1=$ac_default_prefix/share/config.site
-  ac_site_file2=$ac_default_prefix/etc/config.site
+  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
 fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+
+for ac_site_file in $ac_site_files
 do
-  test "x$ac_site_file" = xNONE && continue
-  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+  case $ac_site_file in #(
+  */*) :
+     ;; #(
+  *) :
+    ac_site_file=./$ac_site_file ;;
+esac
+  if test -f "$ac_site_file" && test -r "$ac_site_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
     . "$ac_site_file" \
-      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "failed to load site script $ac_site_file
 See \`config.log' for more details" "$LINENO" 5; }
   fi
@@ -2491,433 +2467,744 @@ if test -r "$cache_file"; then
   # Some versions of bash will fail to source /dev/null (special files
   # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
   if test /dev/null != "$cache_file" && test -f "$cache_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
       [\\/]* | ?:[\\/]* ) . "$cache_file";;
       *)                      . "./$cache_file";;
     esac
   fi
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
   >$cache_file
 fi
 
-as_fn_append ac_header_list " utime.h"
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
-  eval ac_old_set=\$ac_cv_env_${ac_var}_set
-  eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val=\$ac_cv_env_${ac_var}_value
-  eval ac_new_val=\$ac_env_${ac_var}_value
-  case $ac_old_set,$ac_new_set in
-    set,)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,set)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,);;
-    *)
-      if test "x$ac_old_val" != "x$ac_new_val"; then
-       # differences in whitespace do not lead to failure.
-       ac_old_val_w=`echo x $ac_old_val`
-       ac_new_val_w=`echo x $ac_new_val`
-       if test "$ac_old_val_w" != "$ac_new_val_w"; then
-         { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-         ac_cache_corrupted=:
-       else
-         { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
-         eval $ac_var=\$ac_old_val
-       fi
-       { $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
-$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
-       { $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
-$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
-      fi;;
-  esac
-  # Pass precious variables to config.status.
-  if test "$ac_new_set" = set; then
-    case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
-    *) ac_arg=$ac_var=$ac_new_val ;;
-    esac
-    case " $ac_configure_args " in
-      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
-      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
-    esac
-  fi
-done
-if $ac_cache_corrupted; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
+# Test code for whether the C compiler supports C89 (global declarations)
+ac_c_conftest_c89_globals='
+/* Does the compiler advertise C89 conformance?
+   Do not test the value of __STDC__, because some compilers set it to 0
+   while being otherwise adequately conformant. */
+#if !defined __STDC__
+# error "Compiler does not advertise C89 conformance"
+#endif
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+#include <stddef.h>
+#include <stdarg.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
+struct buf { int x; };
+struct buf * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
 
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not \xHH hex character constants.
+   These do not provoke an error unfortunately, instead are silently treated
+   as an "x".  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously \x00 != x always comes out true, for an
+   array size at least.  It is necessary to write \x00 == 0 to get something
+   that is true only with -std.  */
+int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
 
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) '\''x'\''
+int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
 
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
+               int, int);'
 
+# Test code for whether the C compiler supports C89 (body of main).
+ac_c_conftest_c89_main='
+ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
+'
 
-ac_config_headers="$ac_config_headers config.h"
+# Test code for whether the C compiler supports C99 (global declarations)
+ac_c_conftest_c99_globals='
+// Does the compiler advertise C99 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# error "Compiler does not advertise C99 conformance"
+#endif
 
+#include <stdbool.h>
+extern int puts (const char *);
+extern int printf (const char *, ...);
+extern int dprintf (int, const char *, ...);
+extern void *malloc (size_t);
 
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+// dprintf is used instead of fprintf to avoid needing to declare
+// FILE and stderr.
+#define debug(...) dprintf (2, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
 
-PACKAGE_VERSION=`sed 's/.*"\(.*\)".*/\1/' <$srcdir/version.h`
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  #error "your preprocessor is broken"
+#endif
+#if BIG_OK
+#else
+  #error "your preprocessor is broken"
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring rsync $PACKAGE_VERSION" >&5
-$as_echo "$as_me: Configuring rsync $PACKAGE_VERSION" >&6;}
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
 
-LDFLAGS=${LDFLAGS-""}
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
 
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
-fi
+typedef const char *ccp;
 
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
+    continue;
+  return 0;
+}
 
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
 
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+  const char *str = "";
+  int number = 0;
+  float fnumber = 0;
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if ${ac_cv_build+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
-  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
-  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+  while (*format)
+    {
+      switch (*format++)
+       {
+       case '\''s'\'': // string
+         str = va_arg (args_copy, const char *);
+         break;
+       case '\''d'\'': // int
+         number = va_arg (args_copy, int);
+         break;
+       case '\''f'\'': // float
+         fnumber = va_arg (args_copy, double);
+         break;
+       default:
+         break;
+       }
+    }
+  va_end (args_copy);
+  va_end (args);
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+  return *str && number && fnumber;
+}
+'
 
+# Test code for whether the C compiler supports C99 (body of main).
+ac_c_conftest_c99_main='
+  // Check bool.
+  _Bool success = false;
+  success |= (argc != 0);
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if ${ac_cv_host+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "x$host_alias" = x; then
-  ac_cv_host=$ac_cv_build
-else
-  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
-    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
-fi
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+  // Check varargs.
+  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
+  test_varargs_macros ();
 
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
 
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
 
+  ni.number = 58;
 
+  int dynamic_array[ni.number];
+  dynamic_array[0] = argv[0][0];
+  dynamic_array[ni.number - 1] = 543;
 
-# We must decide this before testing the compiler.
+  // work around unused variable warnings
+  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
+        || dynamic_array[ni.number - 1] != 543);
+'
 
-# Please allow this to default to yes, so that your users have more
-# chance of getting a useful stack trace if problems occur.
+# Test code for whether the C compiler supports C11 (global declarations)
+ac_c_conftest_c11_globals='
+// Does the compiler advertise C11 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
+# error "Compiler does not advertise C11 conformance"
+#endif
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include debugging symbols" >&5
-$as_echo_n "checking whether to include debugging symbols... " >&6; }
-# Check whether --enable-debug was given.
-if test "${enable_debug+set}" = set; then :
-  enableval=$enable_debug;
-fi
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
 
+// Check _Alignof.
+enum
+{
+  int_alignment = _Alignof (int),
+  int_array_alignment = _Alignof (int[100]),
+  char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
 
-if test x"$enable_debug" = x"no"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-    ac_cv_prog_cc_g=no
-else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-        # leave ac_cv_prog_cc_g alone; AC_PROG_CC will try to include -g if it can
-fi
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+// Check _Static_assert.
+struct test_static_assert
+{
+  int x;
+  _Static_assert (sizeof (int) <= sizeof (long int),
+                  "_Static_assert does not work in struct");
+  long int y;
+};
 
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
 
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
 
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+  union {
+    struct { int i; int j; };
+    struct { int k; long int l; } w;
+  };
+  int m;
+} v1;
+'
 
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+# Test code for whether the C compiler supports C11 (body of main).
+ac_c_conftest_c11_main='
+  _Static_assert ((offsetof (struct anonymous, i)
+                  == offsetof (struct anonymous, w.k)),
+                 "Anonymous union alignment botch");
+  v1.i = 2;
+  v1.w.k = 5;
+  ok |= v1.i != 5;
+'
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
+# Test code for whether the C compiler supports C11 (complete).
+ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+${ac_c_conftest_c11_globals}
 
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  ${ac_c_conftest_c11_main}
+  return ok;
+}
+"
 
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+# Test code for whether the C compiler supports C99 (complete).
+ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
 
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  return ok;
+}
+"
 
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
+# Test code for whether the C compiler supports C89 (complete).
+ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  return ok;
+}
+"
+
+as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
+as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
+as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
+as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
+as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
+as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
+as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
+as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
+as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
+# Test code for whether the C++ compiler supports C++98 (global declarations)
+ac_cxx_conftest_cxx98_globals='
+// Does the compiler advertise C++98 conformance?
+#if !defined __cplusplus || __cplusplus < 199711L
+# error "Compiler does not advertise C++98 conformance"
+#endif
+
+// These inclusions are to reject old compilers that
+// lack the unsuffixed header files.
+#include <cstdlib>
+#include <exception>
+
+// <cassert> and <cstring> are *not* freestanding headers in C++98.
+extern void assert (int);
+namespace std {
+  extern int strcmp (const char *, const char *);
+}
+
+// Namespaces, exceptions, and templates were all added after "C++ 2.0".
+using std::exception;
+using std::strcmp;
+
+namespace {
+
+void test_exception_syntax()
+{
+  try {
+    throw "test";
+  } catch (const char *s) {
+    // Extra parentheses suppress a warning when building autoconf itself,
+    // due to lint rules shared with more typical C programs.
+    assert (!(strcmp) (s, "test"));
+  }
+}
+
+template <typename T> struct test_template
+{
+  T const val;
+  explicit test_template(T t) : val(t) {}
+  template <typename U> T add(U u) { return static_cast<T>(u) + val; }
+};
+
+} // anonymous namespace
+'
+
+# Test code for whether the C++ compiler supports C++98 (body of main)
+ac_cxx_conftest_cxx98_main='
+  assert (argc);
+  assert (! argv[0]);
+{
+  test_exception_syntax ();
+  test_template<double> tt (2.0);
+  assert (tt.add (4) == 6.0);
+  assert (true && !false);
+}
+'
+
+# Test code for whether the C++ compiler supports C++11 (global declarations)
+ac_cxx_conftest_cxx11_globals='
+// Does the compiler advertise C++ 2011 conformance?
+#if !defined __cplusplus || __cplusplus < 201103L
+# error "Compiler does not advertise C++11 conformance"
+#endif
+
+namespace cxx11test
+{
+  constexpr int get_val() { return 20; }
+
+  struct testinit
+  {
+    int i;
+    double d;
+  };
+
+  class delegate
+  {
+  public:
+    delegate(int n) : n(n) {}
+    delegate(): delegate(2354) {}
+
+    virtual int getval() { return this->n; };
+  protected:
+    int n;
+  };
+
+  class overridden : public delegate
+  {
+  public:
+    overridden(int n): delegate(n) {}
+    virtual int getval() override final { return this->n * 2; }
+  };
+
+  class nocopy
+  {
+  public:
+    nocopy(int i): i(i) {}
+    nocopy() = default;
+    nocopy(const nocopy&) = delete;
+    nocopy & operator=(const nocopy&) = delete;
+  private:
+    int i;
+  };
+
+  // for testing lambda expressions
+  template <typename Ret, typename Fn> Ret eval(Fn f, Ret v)
+  {
+    return f(v);
+  }
+
+  // for testing variadic templates and trailing return types
+  template <typename V> auto sum(V first) -> V
+  {
+    return first;
+  }
+  template <typename V, typename... Args> auto sum(V first, Args... rest) -> V
+  {
+    return first + sum(rest...);
+  }
+}
+'
+
+# Test code for whether the C++ compiler supports C++11 (body of main)
+ac_cxx_conftest_cxx11_main='
+{
+  // Test auto and decltype
+  auto a1 = 6538;
+  auto a2 = 48573953.4;
+  auto a3 = "String literal";
+
+  int total = 0;
+  for (auto i = a3; *i; ++i) { total += *i; }
+
+  decltype(a2) a4 = 34895.034;
+}
+{
+  // Test constexpr
+  short sa[cxx11test::get_val()] = { 0 };
+}
+{
+  // Test initializer lists
+  cxx11test::testinit il = { 4323, 435234.23544 };
+}
+{
+  // Test range-based for
+  int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3,
+                 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
+  for (auto &x : array) { x += 23; }
+}
+{
+  // Test lambda expressions
+  using cxx11test::eval;
+  assert (eval ([](int x) { return x*2; }, 21) == 42);
+  double d = 2.0;
+  assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0);
+  assert (d == 5.0);
+  assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0);
+  assert (d == 5.0);
+}
+{
+  // Test use of variadic templates
+  using cxx11test::sum;
+  auto a = sum(1);
+  auto b = sum(1, 2);
+  auto c = sum(1.0, 2.0, 3.0);
+}
+{
+  // Test constructor delegation
+  cxx11test::delegate d1;
+  cxx11test::delegate d2();
+  cxx11test::delegate d3(45);
+}
+{
+  // Test override and final
+  cxx11test::overridden o1(55464);
+}
+{
+  // Test nullptr
+  char *c = nullptr;
+}
+{
+  // Test template brackets
+  test_template<::test_template<int>> v(test_template<int>(12));
+}
+{
+  // Unicode literals
+  char const *utf8 = u8"UTF-8 string \u2500";
+  char16_t const *utf16 = u"UTF-8 string \u2500";
+  char32_t const *utf32 = U"UTF-32 string \u2500";
+}
+'
+
+# Test code for whether the C compiler supports C++11 (complete).
+ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals}
+${ac_cxx_conftest_cxx11_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_cxx_conftest_cxx98_main}
+  ${ac_cxx_conftest_cxx11_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C++98 (complete).
+ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals}
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_cxx_conftest_cxx98_main}
+  return ok;
+}
+"
+
+as_fn_append ac_header_c_list " utime.h utime_h HAVE_UTIME_H"
+
+# Auxiliary files required by this configure script.
+ac_aux_files="install-sh config.guess config.sub"
+
+# Locations in which to look for auxiliary files.
+ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.."
+
+# Search for a directory containing all of the required auxiliary files,
+# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates.
+# If we don't find one directory that contains all the files we need,
+# we report the set of missing files from the *first* directory in
+# $ac_aux_dir_candidates and give up.
+ac_missing_aux_files=""
+ac_first_candidate=:
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5
 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+as_found=false
+for as_dir in $ac_aux_dir_candidates
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+  as_found=:
+
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}:  trying $as_dir" >&5
+  ac_aux_dir_found=yes
+  ac_install_sh=
+  for ac_aux in $ac_aux_files
+  do
+    # As a special case, if "install-sh" is required, that requirement
+    # can be satisfied by any of "install-sh", "install.sh", or "shtool",
+    # and $ac_install_sh is set appropriately for whichever one is found.
+    if test x"$ac_aux" = x"install-sh"
+    then
+      if test -f "${as_dir}install-sh"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install-sh found" >&5
+        ac_install_sh="${as_dir}install-sh -c"
+      elif test -f "${as_dir}install.sh"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install.sh found" >&5
+        ac_install_sh="${as_dir}install.sh -c"
+      elif test -f "${as_dir}shtool"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}shtool found" >&5
+        ac_install_sh="${as_dir}shtool install -c"
+      else
+        ac_aux_dir_found=no
+        if $ac_first_candidate; then
+          ac_missing_aux_files="${ac_missing_aux_files} install-sh"
+        else
+          break
+        fi
+      fi
+    else
+      if test -f "${as_dir}${ac_aux}"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}${ac_aux} found" >&5
+      else
+        ac_aux_dir_found=no
+        if $ac_first_candidate; then
+          ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}"
+        else
+          break
+        fi
+      fi
+    fi
+  done
+  if test "$ac_aux_dir_found" = yes; then
+    ac_aux_dir="$as_dir"
+    break
   fi
+  ac_first_candidate=false
+
+  as_found=false
 done
-  done
 IFS=$as_save_IFS
+if $as_found
+then :
 
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
+else $as_nop
+  as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5
 fi
+
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+if test -f "${ac_aux_dir}config.guess"; then
+  ac_config_guess="$SHELL ${ac_aux_dir}config.guess"
 fi
+if test -f "${ac_aux_dir}config.sub"; then
+  ac_config_sub="$SHELL ${ac_aux_dir}config.sub"
 fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+if test -f "$ac_aux_dir/configure"; then
+  ac_configure="$SHELL ${ac_aux_dir}configure"
 fi
 
-
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       # differences in whitespace do not lead to failure.
+       ac_old_val_w=`echo x $ac_old_val`
+       ac_new_val_w=`echo x $ac_new_val`
+       if test "$ac_old_val_w" != "$ac_new_val_w"; then
+         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+         ac_cache_corrupted=:
+       else
+         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+         eval $ac_var=\$ac_old_val
+       fi
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
+           and start over" "$LINENO" 5
 fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -2925,11 +3212,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -2940,28 +3231,25 @@ fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
-    test -n "$CC" && break
-  done
 fi
-if test -z "$CC"; then
+if test -z "$ac_cv_prog_CC"; then
   ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
@@ -2969,11 +3257,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-
-  test -n "$ac_ct_CC" && break
-done
-
   if test "x$ac_ct_CC" = x; then
     CC=""
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CC=$ac_ct_CC
   fi
+else
+  CC="$ac_cv_prog_CC"
 fi
 
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
-  { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+
+
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion -version; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -3037,7 +3649,7 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
   fi
   rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
 done
 
@@ -3045,7 +3657,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
@@ -3057,9 +3669,9 @@ ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+printf %s "checking whether the C compiler works... " >&6; }
+ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
 
 # The possible output files:
 ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
@@ -3080,11 +3692,12 @@ case "(($ac_try" in
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link_default") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
   # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
 # So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
 # in a Makefile.  We should not override ac_cv_exeext if it was cached,
@@ -3101,7 +3714,7 @@ do
        # certainly right.
        break;;
     *.* )
-       if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+       if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
        then :; else
           ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
        fi
@@ -3117,44 +3730,46 @@ do
 done
 test "$ac_cv_exeext" = no && ac_cv_exeext=
 
-else
+else $as_nop
   ac_file=''
 fi
-if test -z "$ac_file"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
+if test -z "$ac_file"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "C compiler cannot create executables
 See \`config.log' for more details" "$LINENO" 5; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+printf %s "checking for C compiler default output file name... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+printf "%s\n" "$ac_file" >&6; }
 ac_exeext=$ac_cv_exeext
 
 rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+printf %s "checking for suffix of executables... " >&6; }
 if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
   # If both `conftest.exe' and `conftest' are `present' (well, observable)
 # catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
 # work properly (i.e., refer to `conftest.exe'), while it won't with
@@ -3168,15 +3783,15 @@ for ac_file in conftest.exe conftest conftest.*; do
     * ) break;;
   esac
 done
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of executables: cannot compile and link
 See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+printf "%s\n" "$ac_cv_exeext" >&6; }
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
@@ -3185,7 +3800,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdio.h>
 int
-main ()
+main (void)
 {
 FILE *f = fopen ("conftest.out", "w");
  return ferror (f) || fclose (f) != 0;
@@ -3197,8 +3812,8 @@ _ACEOF
 ac_clean_files="$ac_clean_files conftest.out"
 # Check that the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+printf %s "checking whether we are cross compiling... " >&6; }
 if test "$cross_compiling" != yes; then
   { { ac_try="$ac_link"
 case "(($ac_try" in
@@ -3206,10 +3821,10 @@ case "(($ac_try" in
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
   if { ac_try='./conftest$ac_cv_exeext'
   { { case "(($ac_try" in
@@ -3217,39 +3832,40 @@ $as_echo "$ac_try_echo"; } >&5
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_try") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; }; then
     cross_compiling=no
   else
     if test "$cross_compiling" = maybe; then
        cross_compiling=yes
     else
-       { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
+       { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot run C compiled programs.
 If you meant to cross compile, use \`--host'.
 See \`config.log' for more details" "$LINENO" 5; }
     fi
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+printf "%s\n" "$cross_compiling" >&6; }
 
 rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
 ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+printf %s "checking for suffix of object files... " >&6; }
+if test ${ac_cv_objext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
@@ -3263,11 +3879,12 @@ case "(($ac_try" in
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
   for ac_file in conftest.o conftest.obj conftest.*; do
   test -f "$ac_file" || continue;
   case $ac_file in
@@ -3276,31 +3893,32 @@ $as_echo "$ac_try_echo"; } >&5
        break;;
   esac
 done
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of object files: cannot compile
 See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+printf "%s\n" "$ac_cv_objext" >&6; }
 OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 #ifndef __GNUC__
        choke me
@@ -3310,29 +3928,33 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_compiler_gnu=yes
-else
+else $as_nop
   ac_compiler_gnu=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
 if test $ac_compiler_gnu = yes; then
   GCC=yes
 else
   GCC=
 fi
-ac_test_CFLAGS=${CFLAGS+set}
+ac_test_CFLAGS=${CFLAGS+y}
 ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_save_c_werror_flag=$ac_c_werror_flag
    ac_c_werror_flag=yes
    ac_cv_prog_cc_g=no
@@ -3341,57 +3963,60 @@ else
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_g=yes
-else
+else $as_nop
   CFLAGS=""
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
 
-else
+else $as_nop
   ac_c_werror_flag=$ac_save_c_werror_flag
         CFLAGS="-g"
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_g=yes
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    ac_c_werror_flag=$ac_save_c_werror_flag
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
   if test "$GCC" = yes; then
@@ -3406,231 +4031,144 @@ else
     CFLAGS=
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
+ac_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c11=no
 ac_save_CC=$CC
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
+$ac_c_conftest_c11_program
 _ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+for ac_arg in '' -std=gnu11
 do
   CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c11=$ac_arg
 fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c11" != "xno" && break
 done
 rm -f conftest.$ac_ext
 CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+     CC="$CC $ac_cv_prog_cc_c11"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+  ac_prog_cc_stdc=c11
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <ac_nonexistent.h>
+$ac_c_conftest_c99_program
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c99=$ac_arg
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
 done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
 fi
 
-    done
-    ac_cv_prog_CPP=$CPP
-
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c99" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+     CC="$CC $ac_cv_prog_cc_c99"
 fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+  ac_prog_cc_stdc=c99
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <ac_nonexistent.h>
+$ac_c_conftest_c89_program
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c89=$ac_arg
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
 done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
 
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c89" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+     CC="$CC $ac_cv_prog_cc_c89"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+  ac_prog_cc_stdc=c89
+fi
 fi
 
 ac_ext=c
@@ -3639,2704 +4177,3606 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test -z "$CXX"; then
-  if test -n "$CCC"; then
-    CXX=$CCC
-  else
-    if test -n "$ac_tool_prefix"; then
-  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CXX"; then
-  ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+
+ac_header= ac_cache=
+for ac_item in $ac_header_c_list
 do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
+  if test $ac_cache; then
+    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
+    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
+      printf "%s\n" "#define $ac_item 1" >> confdefs.h
+    fi
+    ac_header= ac_cache=
+  elif test $ac_header; then
+    ac_cache=$ac_item
+  else
+    ac_header=$ac_item
   fi
 done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CXX=$ac_cv_prog_CXX
-if test -n "$CXX"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
-$as_echo "$CXX" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
 
 
-    test -n "$CXX" && break
-  done
-fi
-if test -z "$CXX"; then
-  ac_ct_CXX=$CXX
-  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CXX"; then
-  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CXX="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
 
-fi
-fi
-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
-if test -n "$ac_ct_CXX"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
-$as_echo "$ac_ct_CXX" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
 
 
-  test -n "$ac_ct_CXX" && break
-done
 
-  if test "x$ac_ct_CXX" = x; then
-    CXX="g++"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CXX=$ac_ct_CXX
-  fi
-fi
 
-  fi
-fi
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
-  { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    sed '10a\
-... rest of stderr output deleted ...
-         10q' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-  fi
-  rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-done
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
-$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
-if ${ac_cv_cxx_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
+then :
 
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
+printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+printf %s "checking whether byte ordering is bigendian... " >&6; }
+if test ${ac_cv_c_bigendian+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+              not a universal capable compiler
+            #endif
+            typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+       # Check for potential -arch flags.  It is not universal unless
+       # there are at least two -arch flags with different values.
+       ac_arch=
+       ac_prev=
+       for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+        if test -n "$ac_prev"; then
+          case $ac_word in
+            i?86 | x86_64 | ppc | ppc64)
+              if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+                ac_arch=$ac_word
+              else
+                ac_cv_c_bigendian=universal
+                break
+              fi
+              ;;
+          esac
+          ac_prev=
+        elif test "x$ac_word" = "x-arch"; then
+          ac_prev=arch
+        fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+            #include <sys/param.h>
+
+int
+main (void)
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+                    && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+                    && LITTLE_ENDIAN)
+             bogus endian macros
+            #endif
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_compiler_gnu=yes
-else
-  ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
-$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
-  GXX=yes
-else
-  GXX=
-fi
-ac_test_CXXFLAGS=${CXXFLAGS+set}
-ac_save_CXXFLAGS=$CXXFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
-$as_echo_n "checking whether $CXX accepts -g... " >&6; }
-if ${ac_cv_prog_cxx_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
-   ac_cxx_werror_flag=yes
-   ac_cv_prog_cxx_g=no
-   CXXFLAGS="-g"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+if ac_fn_c_try_compile "$LINENO"
+then :
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+#include <sys/types.h>
+               #include <sys/param.h>
 
 int
-main ()
+main (void)
 {
+#if BYTE_ORDER != BIG_ENDIAN
+                not big endian
+               #endif
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_cv_prog_cxx_g=yes
-else
-  CXXFLAGS=""
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_c_bigendian=yes
+else $as_nop
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+#include <limits.h>
 
 int
-main ()
+main (void)
 {
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+             bogus endian macros
+            #endif
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-
-else
-  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
-        CXXFLAGS="-g"
+if ac_fn_c_try_compile "$LINENO"
+then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+#include <limits.h>
 
 int
-main ()
+main (void)
 {
+#ifndef _BIG_ENDIAN
+                not big endian
+               #endif
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  ac_cv_prog_cxx_g=yes
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_c_bigendian=yes
+else $as_nop
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes
+then :
+  # Try to guess by grepping values from an object file.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+unsigned short int ascii_mm[] =
+                 { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+               unsigned short int ascii_ii[] =
+                 { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+               int use_ascii (int i) {
+                 return ascii_mm[i] + ascii_ii[i];
+               }
+               unsigned short int ebcdic_ii[] =
+                 { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+               unsigned short int ebcdic_mm[] =
+                 { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+               int use_ebcdic (int i) {
+                 return ebcdic_mm[i] + ebcdic_ii[i];
+               }
+               extern int foo;
+
+int
+main (void)
+{
+return use_ascii (foo) == use_ebcdic (foo);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+             ac_cv_c_bigendian=yes
+           fi
+           if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+             if test "$ac_cv_c_bigendian" = unknown; then
+               ac_cv_c_bigendian=no
+             else
+               # finding both strings is unlikely to happen, but who knows?
+               ac_cv_c_bigendian=unknown
+             fi
+           fi
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main (void)
+{
+
+            /* Are we little or big endian?  From Harbison&Steele.  */
+            union
+            {
+              long int l;
+              char c[sizeof (long int)];
+            } u;
+            u.l = 1;
+            return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"
+then :
+  ac_cv_c_bigendian=no
+else $as_nop
+  ac_cv_c_bigendian=yes
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
-$as_echo "$ac_cv_prog_cxx_g" >&6; }
-if test "$ac_test_CXXFLAGS" = set; then
-  CXXFLAGS=$ac_save_CXXFLAGS
-elif test $ac_cv_prog_cxx_g = yes; then
-  if test "$GXX" = yes; then
-    CXXFLAGS="-g -O2"
-  else
-    CXXFLAGS="-g"
-  fi
-else
-  if test "$GXX" = yes; then
-    CXXFLAGS="-O2"
-  else
-    CXXFLAGS=
-  fi
+
+    fi
 fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+printf "%s\n" "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     printf "%s\n" "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
 
-for ac_prog in gawk mawk nawk awk
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AWK+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$AWK"; then
-  ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_AWK="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
 
+     ;; #(
+   *)
+     as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`printf "%s\n" "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+printf %s "checking for $ac_hdr that defines DIR... " >&6; }
+if eval test \${$as_ac_Header+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main (void)
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  eval "$as_ac_Header=yes"
+else $as_nop
+  eval "$as_ac_Header=no"
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
-$as_echo "$AWK" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+eval ac_res=\$$as_ac_Header
+              { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
+then :
+  cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
 
+ac_header_dirent=$ac_hdr; break
+fi
 
-  test -n "$AWK" && break
 done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+printf %s "checking for library containing opendir... " >&6; }
+if test ${ac_cv_search_opendir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$GREP"; then
-  ac_path_GREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_GREP" || continue
-# Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_GREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main (void)
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' dir
+do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-else
-  ac_cv_path_GREP=$GREP
+  if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_search_opendir=$ac_res
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext
+  if test ${ac_cv_search_opendir+y}
+then :
+  break
+fi
+done
+if test ${ac_cv_search_opendir+y}
+then :
 
+else $as_nop
+  ac_cv_search_opendir=no
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+printf "%s\n" "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no
+then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
+fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
-  $as_echo_n "(cached) " >&6
 else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     if test -z "$EGREP"; then
-  ac_path_EGREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in egrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_EGREP" || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+printf %s "checking for library containing opendir... " >&6; }
+if test ${ac_cv_search_opendir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-      $ac_path_EGREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main (void)
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' x
+do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-else
-  ac_cv_path_EGREP=$EGREP
+  if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_search_opendir=$ac_res
 fi
-
-   fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext
+  if test ${ac_cv_search_opendir+y}
+then :
+  break
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
+done
+if test ${ac_cv_search_opendir+y}
+then :
 
+else $as_nop
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+printf "%s\n" "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no
+then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
-# Find a good install program.  We prefer a C program (faster),
-# so one script is as good as another.  But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# OS/2's system install, which has a completely different semantic
-# ./install, which can be erroneously created by make from ./install.sh.
-# Reject install programs that cannot install multiple files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
-$as_echo_n "checking for a BSD-compatible install... " >&6; }
-if test -z "$INSTALL"; then
-if ${ac_cv_path_install+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in #((
-  ./ | .// | /[cC]/* | \
-  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
-  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
-  /usr/ucb/* ) ;;
-  *)
-    # OSF1 and SCO ODT 3.0 have their own names for install.
-    # Don't use installbsd from OSF since it installs stuff as root
-    # by default.
-    for ac_prog in ginstall scoinst install; do
-      for ac_exec_ext in '' $ac_executable_extensions; do
-       if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
-         if test $ac_prog = install &&
-           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
-           # AIX install.  It has an incompatible calling convention.
-           :
-         elif test $ac_prog = install &&
-           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
-           # program-specific install script used by HP pwplus--don't use.
-           :
-         else
-           rm -rf conftest.one conftest.two conftest.dir
-           echo one > conftest.one
-           echo two > conftest.two
-           mkdir conftest.dir
-           if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
-             test -s conftest.one && test -s conftest.two &&
-             test -s conftest.dir/conftest.one &&
-             test -s conftest.dir/conftest.two
-           then
-             ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
-             break 3
-           fi
-         fi
-       fi
-      done
-    done
-    ;;
-esac
+fi
 
-  done
-IFS=$as_save_IFS
+fi
 
-rm -rf conftest.one conftest.two conftest.dir
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
+printf %s "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
+if test ${ac_cv_header_sys_wait_h+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
 
+int
+main (void)
+{
+  int s;
+  wait (&s);
+  s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_header_sys_wait_h=yes
+else $as_nop
+  ac_cv_header_sys_wait_h=no
 fi
-  if test "${ac_cv_path_install+set}" = set; then
-    INSTALL=$ac_cv_path_install
-  else
-    # As a last resort, use the slow shell script.  Don't cache a
-    # value for INSTALL within a source directory, because that will
-    # break other packages using the cache if that directory is
-    # removed, or if the value is a relative name.
-    INSTALL=$ac_install_sh
-  fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-$as_echo "$INSTALL" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
+printf "%s\n" "$ac_cv_header_sys_wait_h" >&6; }
+if test $ac_cv_header_sys_wait_h = yes; then
 
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+printf "%s\n" "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
 
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+fi
 
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+ac_fn_c_check_header_compile "$LINENO" "sys/fcntl.h" "ac_cv_header_sys_fcntl_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_fcntl_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_FCNTL_H 1" >>confdefs.h
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
-$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
-if test -z "$MKDIR_P"; then
-  if ${ac_cv_path_mkdir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in mkdir gmkdir; do
-        for ac_exec_ext in '' $ac_executable_extensions; do
-          as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
-          case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
-            'mkdir (GNU coreutils) '* | \
-            'mkdir (coreutils) '* | \
-            'mkdir (fileutils) '4.1*)
-              ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
-              break 3;;
-          esac
-        done
-       done
-  done
-IFS=$as_save_IFS
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_select_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_SELECT_H 1" >>confdefs.h
 
 fi
+ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default"
+if test "x$ac_cv_header_fcntl_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h
 
-  test -d ./--version && rmdir ./--version
-  if test "${ac_cv_path_mkdir+set}" = set; then
-    MKDIR_P="$ac_cv_path_mkdir -p"
-  else
-    # As a last resort, use the slow shell script.  Don't cache a
-    # value for MKDIR_P within a source directory, because that will
-    # break other packages using the cache if that directory is
-    # removed, or if the value is a relative name.
-    MKDIR_P="$ac_install_sh -d"
-  fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
-$as_echo "$MKDIR_P" >&6; }
+ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_time_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h
 
-   case $ac_cv_prog_cc_stdc in #(
-  no) :
-    ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #(
-  *) :
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
-$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
-if ${ac_cv_prog_cc_c99+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c99=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <stdio.h>
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/unistd.h" "ac_cv_header_sys_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_unistd_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_UNISTD_H 1" >>confdefs.h
 
-// Check varargs macros.  These examples are taken from C99 6.10.3.5.
-#define debug(...) fprintf (stderr, __VA_ARGS__)
-#define showlist(...) puts (#__VA_ARGS__)
-#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
-static void
-test_varargs_macros (void)
-{
-  int x = 1234;
-  int y = 5678;
-  debug ("Flag");
-  debug ("X = %d\n", x);
-  showlist (The first, second, and third items.);
-  report (x>y, "x is %d but y is %d", x, y);
-}
+fi
+ac_fn_c_check_header_compile "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_UNISTD_H 1" >>confdefs.h
 
-// Check long long types.
-#define BIG64 18446744073709551615ull
-#define BIG32 4294967295ul
-#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
-#if !BIG_OK
-  your preprocessor is broken;
-#endif
-#if BIG_OK
-#else
-  your preprocessor is broken;
-#endif
-static long long int bignum = -9223372036854775807LL;
-static unsigned long long int ubignum = BIG64;
+fi
+ac_fn_c_check_header_compile "$LINENO" "utime.h" "ac_cv_header_utime_h" "$ac_includes_default"
+if test "x$ac_cv_header_utime_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_UTIME_H 1" >>confdefs.h
 
-struct incomplete_array
-{
-  int datasize;
-  double data[];
-};
+fi
+ac_fn_c_check_header_compile "$LINENO" "compat.h" "ac_cv_header_compat_h" "$ac_includes_default"
+if test "x$ac_cv_header_compat_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_COMPAT_H 1" >>confdefs.h
 
-struct named_init {
-  int number;
-  const wchar_t *name;
-  double average;
-};
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_param_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_PARAM_H 1" >>confdefs.h
 
-typedef const char *ccp;
+fi
+ac_fn_c_check_header_compile "$LINENO" "ctype.h" "ac_cv_header_ctype_h" "$ac_includes_default"
+if test "x$ac_cv_header_ctype_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_CTYPE_H 1" >>confdefs.h
 
-static inline int
-test_restrict (ccp restrict text)
-{
-  // See if C++-style comments work.
-  // Iterate through items via the restricted pointer.
-  // Also check for declarations in for loops.
-  for (unsigned int i = 0; *(text+i) != '\0'; ++i)
-    continue;
-  return 0;
-}
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_wait_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
 
-// Check varargs and va_copy.
-static void
-test_varargs (const char *format, ...)
-{
-  va_list args;
-  va_start (args, format);
-  va_list args_copy;
-  va_copy (args_copy, args);
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_stat_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_STAT_H 1" >>confdefs.h
 
-  const char *str;
-  int number;
-  float fnumber;
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_ioctl_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_IOCTL_H 1" >>confdefs.h
 
-  while (*format)
-    {
-      switch (*format++)
-       {
-       case 's': // string
-         str = va_arg (args_copy, const char *);
-         break;
-       case 'd': // int
-         number = va_arg (args_copy, int);
-         break;
-       case 'f': // float
-         fnumber = va_arg (args_copy, double);
-         break;
-       default:
-         break;
-       }
-    }
-  va_end (args_copy);
-  va_end (args);
-}
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/filio.h" "ac_cv_header_sys_filio_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_filio_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_FILIO_H 1" >>confdefs.h
 
-int
-main ()
-{
+fi
+ac_fn_c_check_header_compile "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRING_H 1" >>confdefs.h
 
-  // Check bool.
-  _Bool success = false;
+fi
+ac_fn_c_check_header_compile "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_STDLIB_H 1" >>confdefs.h
 
-  // Check restrict.
-  if (test_restrict ("String literal") == 0)
-    success = true;
-  char *restrict newvar = "Another string";
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_socket_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h
 
-  // Check varargs.
-  test_varargs ("s, d' f .", "string", 65, 34.234);
-  test_varargs_macros ();
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/mode.h" "ac_cv_header_sys_mode_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mode_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_MODE_H 1" >>confdefs.h
 
-  // Check flexible array members.
-  struct incomplete_array *ia =
-    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
-  ia->datasize = 10;
-  for (int i = 0; i < ia->datasize; ++i)
-    ia->data[i] = i * 1.234;
+fi
+ac_fn_c_check_header_compile "$LINENO" "grp.h" "ac_cv_header_grp_h" "$ac_includes_default"
+if test "x$ac_cv_header_grp_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_GRP_H 1" >>confdefs.h
 
-  // Check named initializers.
-  struct named_init ni = {
-    .number = 34,
-    .name = L"Test wide string",
-    .average = 543.34343,
-  };
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_un_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_UN_H 1" >>confdefs.h
 
-  ni.number = 58;
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/attr.h" "ac_cv_header_sys_attr_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_attr_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_ATTR_H 1" >>confdefs.h
 
-  int dynamic_array[ni.number];
-  dynamic_array[ni.number - 1] = 543;
+fi
+ac_fn_c_check_header_compile "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default"
+if test "x$ac_cv_header_arpa_inet_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_ARPA_INET_H 1" >>confdefs.h
 
-  // work around unused variable warnings
-  return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
-         || dynamic_array[ni.number - 1] != 543);
+fi
+ac_fn_c_check_header_compile "$LINENO" "arpa/nameser.h" "ac_cv_header_arpa_nameser_h" "$ac_includes_default"
+if test "x$ac_cv_header_arpa_nameser_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_ARPA_NAMESER_H 1" >>confdefs.h
 
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
-do
-  CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c99=$ac_arg
 fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c99" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
+ac_fn_c_check_header_compile "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default"
+if test "x$ac_cv_header_locale_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_LOCALE_H 1" >>confdefs.h
 
 fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c99" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c99"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
-$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c99" != xno; then :
-  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
+ac_fn_c_check_header_compile "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_types_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_TYPES_H 1" >>confdefs.h
 
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+fi
+ac_fn_c_check_header_compile "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default"
+if test "x$ac_cv_header_netdb_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_NETDB_H 1" >>confdefs.h
 
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+fi
+ac_fn_c_check_header_compile "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_malloc_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_MALLOC_H 1" >>confdefs.h
 
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
 fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
+ac_fn_c_check_header_compile "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
+if test "x$ac_cv_header_float_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_FLOAT_H 1" >>confdefs.h
 
 fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
-else
-  ac_cv_prog_cc_stdc=no
+ac_fn_c_check_header_compile "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIMITS_H 1" >>confdefs.h
+
 fi
+ac_fn_c_check_header_compile "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default"
+if test "x$ac_cv_header_iconv_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_ICONV_H 1" >>confdefs.h
 
 fi
- ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5
-$as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; }
-  if ${ac_cv_prog_cc_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-
-  case $ac_cv_prog_cc_stdc in #(
-  no) :
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;; #(
-  '') :
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;; #(
-  *) :
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5
-$as_echo "$ac_cv_prog_cc_stdc" >&6; } ;;
-esac
+ac_fn_c_check_header_compile "$LINENO" "libcharset.h" "ac_cv_header_libcharset_h" "$ac_includes_default"
+if test "x$ac_cv_header_libcharset_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBCHARSET_H 1" >>confdefs.h
 
+fi
+ac_fn_c_check_header_compile "$LINENO" "langinfo.h" "ac_cv_header_langinfo_h" "$ac_includes_default"
+if test "x$ac_cv_header_langinfo_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_LANGINFO_H 1" >>confdefs.h
 
-# Extract the first word of "perl", so it can be a program name with args.
-set dummy perl; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PERL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $PERL in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+fi
+ac_fn_c_check_header_compile "$LINENO" "mcheck.h" "ac_cv_header_mcheck_h" "$ac_includes_default"
+if test "x$ac_cv_header_mcheck_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_MCHECK_H 1" >>confdefs.h
 
-  ;;
-esac
 fi
-PERL=$ac_cv_path_PERL
-if test -n "$PERL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
-$as_echo "$PERL" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+ac_fn_c_check_header_compile "$LINENO" "sys/acl.h" "ac_cv_header_sys_acl_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_acl_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_ACL_H 1" >>confdefs.h
+
 fi
+ac_fn_c_check_header_compile "$LINENO" "acl/libacl.h" "ac_cv_header_acl_libacl_h" "$ac_includes_default"
+if test "x$ac_cv_header_acl_libacl_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_ACL_LIBACL_H 1" >>confdefs.h
 
+fi
+ac_fn_c_check_header_compile "$LINENO" "attr/xattr.h" "ac_cv_header_attr_xattr_h" "$ac_includes_default"
+if test "x$ac_cv_header_attr_xattr_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_ATTR_XATTR_H 1" >>confdefs.h
 
-# Extract the first word of "python3", so it can be a program name with args.
-set dummy python3; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PYTHON3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $PYTHON3 in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_PYTHON3="$PYTHON3" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PYTHON3="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/xattr.h" "ac_cv_header_sys_xattr_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_xattr_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_XATTR_H 1" >>confdefs.h
 
-  ;;
-esac
 fi
-PYTHON3=$ac_cv_path_PYTHON3
-if test -n "$PYTHON3"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON3" >&5
-$as_echo "$PYTHON3" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+ac_fn_c_check_header_compile "$LINENO" "sys/extattr.h" "ac_cv_header_sys_extattr_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_extattr_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_EXTATTR_H 1" >>confdefs.h
+
 fi
+ac_fn_c_check_header_compile "$LINENO" "dl.h" "ac_cv_header_dl_h" "$ac_includes_default"
+if test "x$ac_cv_header_dl_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_DL_H 1" >>confdefs.h
 
+fi
+ac_fn_c_check_header_compile "$LINENO" "popt.h" "ac_cv_header_popt_h" "$ac_includes_default"
+if test "x$ac_cv_header_popt_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_POPT_H 1" >>confdefs.h
 
+fi
+ac_fn_c_check_header_compile "$LINENO" "popt/popt.h" "ac_cv_header_popt_popt_h" "$ac_includes_default"
+if test "x$ac_cv_header_popt_popt_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_POPT_POPT_H 1" >>confdefs.h
 
+fi
+ac_fn_c_check_header_compile "$LINENO" "linux/falloc.h" "ac_cv_header_linux_falloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_linux_falloc_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_LINUX_FALLOC_H 1" >>confdefs.h
 
-$as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+fi
+ac_fn_c_check_header_compile "$LINENO" "netinet/in_systm.h" "ac_cv_header_netinet_in_systm_h" "$ac_includes_default"
+if test "x$ac_cv_header_netinet_in_systm_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_NETINET_IN_SYSTM_H 1" >>confdefs.h
 
+fi
+ac_fn_c_check_header_compile "$LINENO" "netgroup.h" "ac_cv_header_netgroup_h" "$ac_includes_default"
+if test "x$ac_cv_header_netgroup_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_NETGROUP_H 1" >>confdefs.h
 
-if test x"$ac_cv_prog_cc_stdc" = x"no"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: rsync requires an ANSI C compiler and you do not seem to have one" >&5
-$as_echo "$as_me: WARNING: rsync requires an ANSI C compiler and you do not seem to have one" >&2;}
 fi
+ac_fn_c_check_header_compile "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h
 
-no_lib=''
-err_msg=''
-nl='
-'
+fi
+ac_fn_c_check_header_compile "$LINENO" "xxhash.h" "ac_cv_header_xxhash_h" "$ac_includes_default"
+if test "x$ac_cv_header_xxhash_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_XXHASH_H 1" >>confdefs.h
 
-# Check whether --enable-profile was given.
-if test "${enable_profile+set}" = set; then :
-  enableval=$enable_profile;
 fi
+ac_fn_c_check_header_compile "$LINENO" "openssl/md4.h" "ac_cv_header_openssl_md4_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_md4_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_OPENSSL_MD4_H 1" >>confdefs.h
 
-if test x"$enable_profile" = x"yes"; then
-       CFLAGS="$CFLAGS -pg"
 fi
+ac_fn_c_check_header_compile "$LINENO" "openssl/md5.h" "ac_cv_header_openssl_md5_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_md5_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_OPENSSL_MD5_H 1" >>confdefs.h
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if md2man can create man pages" >&5
-$as_echo_n "checking if md2man can create man pages... " >&6; }
-if test x"$ac_cv_path_PYTHON3" = x; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - python3 not found" >&5
-$as_echo "no - python3 not found" >&6; }
-    md2man_works=no
-else
-    md2man_out=`"$srcdir/md2man" --test "$srcdir/rsync-ssl.1.md" 2>&1`
-    if test $? = 0; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       md2man_works=yes
-    else
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-       md2man_works=no
-       echo "$md2man_out"
-    fi
 fi
+ac_fn_c_check_header_compile "$LINENO" "zstd.h" "ac_cv_header_zstd_h" "$ac_includes_default"
+if test "x$ac_cv_header_zstd_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_ZSTD_H 1" >>confdefs.h
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we require man-page building" >&5
-$as_echo_n "checking if we require man-page building... " >&6; }
-# Check whether --enable-md2man was given.
-if test "${enable_md2man+set}" = set; then :
-  enableval=$enable_md2man;
 fi
+ac_fn_c_check_header_compile "$LINENO" "lz4.h" "ac_cv_header_lz4_h" "$ac_includes_default"
+if test "x$ac_cv_header_lz4_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_LZ4_H 1" >>confdefs.h
 
-if test x"$enable_md2man" != x"no"; then
-    if test -f "$srcdir/rsync.1"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: optional" >&5
-$as_echo "optional" >&6; }
-    else
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: required" >&5
-$as_echo "required" >&6; }
-       if test x"$md2man_works" = x"no"; then
-           err_msg="$err_msg$nl- You need python3 and either the cmarkgfm OR commonmark python3 lib in order"
-           err_msg="$err_msg$nl  to build man pages based on the git source (man pages are included in the"
-           err_msg="$err_msg$nl  official release tar files)."
-           no_lib="$no_lib md2man"
-       fi
-    fi
-    MAKE_MAN=man
-else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-    MAKE_MAN=''
 fi
+ac_fn_c_check_header_compile "$LINENO" "sys/file.h" "ac_cv_header_sys_file_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_file_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_FILE_H 1" >>confdefs.h
 
-# Specifically, this turns on panic_action handling.
-# Check whether --enable-maintainer-mode was given.
-if test "${enable_maintainer_mode+set}" = set; then :
-  enableval=$enable_maintainer_mode;
 fi
+ac_fn_c_check_header_compile "$LINENO" "bsd/string.h" "ac_cv_header_bsd_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_bsd_string_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_BSD_STRING_H 1" >>confdefs.h
 
-if test x"$enable_maintainer_mode" = x"yes"; then
-       CFLAGS="$CFLAGS -DMAINTAINER_MODE"
 fi
 
-# This is needed for our included version of popt.  Kind of silly, but
-# I don't want our version too far out of sync.
-CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
+ac_fn_c_check_header_compile "$LINENO" "netinet/ip.h" "ac_cv_header_netinet_ip_h" "#include <netinet/in.h>
+"
+if test "x$ac_cv_header_netinet_ip_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_NETINET_IP_H 1" >>confdefs.h
 
-# If GCC, turn on warnings.
-if test x"$GCC" = x"yes"; then
-       CFLAGS="$CFLAGS -Wall -W"
 fi
 
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether sys/types.h defines makedev" >&5
+printf %s "checking whether sys/types.h defines makedev... " >&6; }
+if test ${ac_cv_header_sys_types_h_makedev+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main (void)
+{
+return makedev(0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  if grep sys/sysmacros.h conftest.err >/dev/null; then
+                  ac_cv_header_sys_types_h_makedev=no
+                else
+                  ac_cv_header_sys_types_h_makedev=yes
+                fi
+else $as_nop
+  ac_cv_header_sys_types_h_makedev=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
 
-# Check whether --with-included-popt was given.
-if test "${with_included_popt+set}" = set; then :
-  withval=$with_included_popt;
 fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_types_h_makedev" >&5
+printf "%s\n" "$ac_cv_header_sys_types_h_makedev" >&6; }
 
+if test $ac_cv_header_sys_types_h_makedev = no; then
+ac_fn_c_check_header_compile "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mkdev_h" = xyes
+then :
 
+printf "%s\n" "#define MAJOR_IN_MKDEV 1" >>confdefs.h
 
-# Check whether --with-included-zlib was given.
-if test "${with_included_zlib+set}" = set; then :
-  withval=$with_included_zlib;
 fi
 
 
+  if test $ac_cv_header_sys_mkdev_h = no; then
+    ac_fn_c_check_header_compile "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sysmacros_h" = xyes
+then :
+
+printf "%s\n" "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h
 
-# Check whether --with-protected-args was given.
-if test "${with_protected_args+set}" = set; then :
-  withval=$with_protected_args;
 fi
 
-if test x"$with_protected_args" = x"yes"; then
+  fi
+fi
 
-cat >>confdefs.h <<_ACEOF
-#define RSYNC_USE_PROTECTED_ARGS 1
-_ACEOF
 
-fi
 
 
-# Check whether --with-rsync-path was given.
-if test "${with_rsync_path+set}" = set; then :
-  withval=$with_rsync_path;  RSYNC_PATH="$with_rsync_path"
-else
-   RSYNC_PATH="rsync"
-fi
+ac_config_headers="$ac_config_headers config.h"
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define RSYNC_PATH "$RSYNC_PATH"
-_ACEOF
+PACKAGE_VERSION=`sed -n 's/.*RSYNC_VERSION.*"\(.*\)".*/\1/p' <$srcdir/version.h`
 
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Configuring rsync $PACKAGE_VERSION" >&5
+printf "%s\n" "$as_me: Configuring rsync $PACKAGE_VERSION" >&6;}
 
+LDFLAGS=${LDFLAGS-""}
 
-# Check whether --with-rsyncd-conf was given.
-if test "${with_rsyncd_conf+set}" = set; then :
-  withval=$with_rsyncd_conf;  if test ! -z "$with_rsyncd_conf" ; then
-               case $with_rsyncd_conf in
-                       yes|no)
-                               RSYNCD_SYSCONF="/etc/rsyncd.conf"
-                               ;;
-                       /*)
-                               RSYNCD_SYSCONF="$with_rsyncd_conf"
-                               ;;
-                       *)
-                                as_fn_error $? "You must specify an absolute path to --with-rsyncd-conf=PATH" "$LINENO" 5
-                               ;;
-               esac
-       else
-               RSYNCD_SYSCONF="/etc/rsyncd.conf"
-       fi
+
+
+
+  # Make sure we can run config.sub.
+$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+printf %s "checking build system type... " >&6; }
+if test ${ac_cv_build+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+printf "%s\n" "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+printf %s "checking host system type... " >&6; }
+if test ${ac_cv_host+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
 else
-   RSYNCD_SYSCONF="/etc/rsyncd.conf"
+  ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5
+fi
+
 fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+printf "%s\n" "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define RSYNCD_SYSCONF "$RSYNCD_SYSCONF"
-_ACEOF
 
 
+# We must decide this before testing the compiler.
 
-# Check whether --with-rsh was given.
-if test "${with_rsh+set}" = set; then :
-  withval=$with_rsh;
+# Please allow this to default to yes, so that your users have more
+# chance of getting a useful stack trace if problems occur.
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to include debugging symbols" >&5
+printf %s "checking whether to include debugging symbols... " >&6; }
+# Check whether --enable-debug was given.
+if test ${enable_debug+y}
+then :
+  enableval=$enable_debug;
 fi
 
 
-# Extract the first word of "remsh", so it can be a program name with args.
-set dummy remsh; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_HAVE_REMSH+:} false; then :
-  $as_echo_n "(cached) " >&6
+if test x"$enable_debug" = x"no"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+    ac_cv_prog_cc_g=no
 else
-  if test -n "$HAVE_REMSH"; then
-  ac_cv_prog_HAVE_REMSH="$HAVE_REMSH" # Let the user override the test.
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+        # leave ac_cv_prog_cc_g alone; AC_PROG_CC will try to include -g if it can
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
 else
 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_HAVE_REMSH="1"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
   done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_prog_HAVE_REMSH" && ac_cv_prog_HAVE_REMSH="0"
 fi
 fi
-HAVE_REMSH=$ac_cv_prog_HAVE_REMSH
-if test -n "$HAVE_REMSH"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_REMSH" >&5
-$as_echo "$HAVE_REMSH" >&6; }
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
-if test x$HAVE_REMSH = x1; then
-
-$as_echo "#define HAVE_REMSH 1" >>confdefs.h
-
-fi
-
-if test x"$with_rsh" != x; then
-       RSYNC_RSH="$with_rsh"
-else
-       RSYNC_RSH="ssh"
 fi
-
-cat >>confdefs.h <<_ACEOF
-#define RSYNC_RSH "$RSYNC_RSH"
-_ACEOF
-
-
-# Some programs on solaris are only found in /usr/xpg4/bin (or work better than others versions).
-# Extract the first word of "sh", so it can be a program name with args.
-set dummy sh; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_SHELL_PATH+:} false; then :
-  $as_echo_n "(cached) " >&6
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
-  case $SHELL_PATH in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_SHELL_PATH="$SHELL_PATH" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /usr/xpg4/bin$PATH_SEPARATOR$PATH
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_SHELL_PATH="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
   done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_path_SHELL_PATH" && ac_cv_path_SHELL_PATH="/bin/sh"
-  ;;
-esac
 fi
-SHELL_PATH=$ac_cv_path_SHELL_PATH
-if test -n "$SHELL_PATH"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHELL_PATH" >&5
-$as_echo "$SHELL_PATH" >&6; }
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
 
-# Extract the first word of "fakeroot", so it can be a program name with args.
-set dummy fakeroot; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_FAKEROOT_PATH+:} false; then :
-  $as_echo_n "(cached) " >&6
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  case $FAKEROOT_PATH in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_FAKEROOT_PATH="$FAKEROOT_PATH" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /usr/xpg4/bin$PATH_SEPARATOR$PATH
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_FAKEROOT_PATH="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
   done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_path_FAKEROOT_PATH" && ac_cv_path_FAKEROOT_PATH="/usr/bin/fakeroot"
-  ;;
-esac
 fi
-FAKEROOT_PATH=$ac_cv_path_FAKEROOT_PATH
-if test -n "$FAKEROOT_PATH"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FAKEROOT_PATH" >&5
-$as_echo "$FAKEROOT_PATH" >&6; }
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
-
-
-# Check whether --with-nobody-group was given.
-if test "${with_nobody_group+set}" = set; then :
-  withval=$with_nobody_group;  NOBODY_GROUP="$with_nobody_group"
+  fi
 fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-
-if test x"$with_nobody_group" = x; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking the group for user \"nobody\"" >&5
-$as_echo_n "checking the group for user \"nobody\"... " >&6; }
-    if grep '^nobody:' /etc/group >/dev/null 2>&1; then
-       NOBODY_GROUP=nobody
-    elif grep '^nogroup:' /etc/group >/dev/null 2>&1; then
-       NOBODY_GROUP=nogroup
-    else
-       NOBODY_GROUP=nobody # test for others?
-    fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NOBODY_GROUP" >&5
-$as_echo "$NOBODY_GROUP" >&6; }
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
+  fi
 fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define NOBODY_USER "nobody"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define NOBODY_GROUP "$NOBODY_GROUP"
-_ACEOF
-
-
-# SIMD optimizations
-SIMD=
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable SIMD optimizations" >&5
-$as_echo_n "checking whether to enable SIMD optimizations... " >&6; }
-# Check whether --enable-simd was given.
-if test "${enable_simd+set}" = set; then :
-  enableval=$enable_simd;
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
-# Clag is crashing with -g -O2, so we'll get rid of -g for now.
-CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-g //'`
-
-if test x"$enable_simd" != x"no"; then
-    # For x86-64 SIMD, g++ >=5 or clang++ >=7 is required
-    if test x"$build_cpu" = x"x86_64"; then
-       ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-if test "$cross_compiling" = yes; then :
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run test program while cross compiling
-See \`config.log' for more details" "$LINENO" 5; }
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdio.h>
-#include <immintrin.h>
-__attribute__ ((target("default"))) int test_ssse3(int x) { return x; }
-__attribute__ ((target("default"))) int test_sse2(int x) { return x; }
-__attribute__ ((target("default"))) int test_avx2(int x) { return x; }
-__attribute__ ((target("ssse3"))) int test_ssse3(int x) { return x; }
-__attribute__ ((target("sse2"))) int test_sse2(int x) { return x; }
-__attribute__ ((target("avx2"))) int test_avx2(int x) { return x; }
-typedef long long __m128i_u __attribute__((__vector_size__(16), __may_alias__, __aligned__(1)));
-typedef long long __m256i_u __attribute__((__vector_size__(32), __may_alias__, __aligned__(1)));
-__attribute__ ((target("default"))) void more_testing(char* buf, int len) { }
-__attribute__ ((target("ssse3"))) void more_testing(char* buf, int len)
-{
-    int i;
-    for (i = 0; i < (len-32); i+=32) {
-       __m128i in8_1, in8_2;
-       in8_1 = _mm_lddqu_si128((__m128i_u*)&buf[i]);
-       in8_2 = _mm_lddqu_si128((__m128i_u*)&buf[i + 16]);
-    }
-}
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-int
-main ()
-{
-if (test_ssse3(42) != 42 || test_sse2(42) != 42 || test_avx2(42) != 42) exit(1);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_run "$LINENO"; then :
-  CXX_OK=yes
-else
-  CXX_OK=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-
-       ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-       if test x"$CXX_OK" = x"yes"; then
-           # AC_MSG_RESULT() is called below.
-           SIMD="x86_64"
-       elif test x"$enable_simd" = x"yes"; then
-           { $as_echo "$as_me:${as_lineno-$LINENO}: result: error" >&5
-$as_echo "error" >&6; }
-           as_fn_error $? "The SIMD compilation test failed.
-Omit --enable-simd to continue without it." "$LINENO" 5
-       fi
-    elif test x"$enable_simd" = x"yes"; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: unavailable" >&5
-$as_echo "unavailable" >&6; }
-        as_fn_error $? "The SIMD optimizations are currently x86_64 only.
-Omit --enable-simd to continue without it." "$LINENO" 5
-    fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-if test x"$SIMD" != x""; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($SIMD)" >&5
-$as_echo "yes ($SIMD)" >&6; }
 
-$as_echo "#define HAVE_SIMD 1" >>confdefs.h
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-    SIMD='$(SIMD_'"$SIMD)"
-    # We only use c++ for its target attribute dispatching, disable unneeded bulky features
-    CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-rtti"
-    # Apple often has "g++" as a symlink for clang. Try to find out the truth.
-    CXX_VERSION=`$CXX --version 2>/dev/null | head -n 2`
-    case "$CXX_VERSION" in
-    *clang*) CXXFLAGS="$CXXFLAGS -fno-slp-vectorize" ;; # avoid a performance hit
-    esac
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
+  test -n "$ac_ct_CC" && break
+done
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if assembler accepts noexecstack" >&5
-$as_echo_n "checking if assembler accepts noexecstack... " >&6; }
-OLD_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS -Wa,--noexecstack"
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
 
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-int
-main ()
-{
-return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-   NOEXECSTACK='-Wa,--noexecstack' ; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-   NOEXECSTACK='' ; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-CFLAGS="$OLD_CFLAGS"
-
 
-ASM=
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable ASM optimizations" >&5
-$as_echo_n "checking whether to enable ASM optimizations... " >&6; }
-# Check whether --enable-asm was given.
-if test "${enable_asm+set}" = set; then :
-  enableval=$enable_asm;
 fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-
-if test x"$enable_asm" != x"no"; then
-    if test x"$build_cpu" = x"x86_64"; then
-       ASM="$build_cpu"
-    elif test x"$enable_asm" = x"yes"; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: unavailable" >&5
-$as_echo "unavailable" >&6; }
-        as_fn_error $? "The ASM optimizations are currently x86_64 only.
-Omit --enable-asm to continue without it." "$LINENO" 5
-    fi
 fi
-
-if test x"$ASM" != x""; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($ASM)" >&5
-$as_echo "yes ($ASM)" >&6; }
-
-$as_echo "#define HAVE_ASM 1" >>confdefs.h
-
-    ASM='$(ASM_'"$ASM)"
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-
-
-# arrgh. libc in some old debian version screwed up the largefile
-# stuff, getting byte range locking wrong
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken largefile support" >&5
-$as_echo_n "checking for broken largefile support... " >&6; }
-if ${rsync_cv_HAVE_BROKEN_LARGEFILE+:} false; then :
-  $as_echo_n "(cached) " >&6
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
 else
+  CC="$ac_cv_prog_CC"
+fi
 
-if test "$cross_compiling" = yes; then :
-  rsync_cv_HAVE_BROKEN_LARGEFILE=cross
-else
+fi
+
+
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion -version; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-#define _FILE_OFFSET_BITS 64
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#if HAVE_UNISTD_H
-#include <unistd.h>
+int
+main (void)
+{
+#ifndef __GNUC__
+       choke me
 #endif
 
-int main(void)
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_compiler_gnu=yes
+else $as_nop
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+y}
+ac_save_CFLAGS=$CFLAGS
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
 {
-       struct flock lock;
-       int status;
-       char tpl[32] = "/tmp/locktest.XXXXXX";
-       int fd = mkstemp(tpl);
-       if (fd < 0) {
-               strcpy(tpl, "conftest.dat");
-               fd = open(tpl, O_CREAT|O_RDWR, 0600);
-       }
 
-       lock.l_type = F_WRLCK;
-       lock.l_whence = SEEK_SET;
-       lock.l_start = 0;
-       lock.l_len = 1;
-       lock.l_pid = 0;
-       fcntl(fd,F_SETLK,&lock);
-       if (fork() == 0) {
-               lock.l_start = 1;
-               _exit(fcntl(fd,F_SETLK,&lock) == 0);
-       }
-       wait(&status);
-       unlink(tpl);
-       return WEXITSTATUS(status);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+else $as_nop
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
 }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  ac_c_werror_flag=$ac_save_c_werror_flag
+        CFLAGS="-g"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
 
+  ;
+  return 0;
+}
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  rsync_cv_HAVE_BROKEN_LARGEFILE=yes
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
 else
-  rsync_cv_HAVE_BROKEN_LARGEFILE=no
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
+ac_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c11=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c11_program
+_ACEOF
+for ac_arg in '' -std=gnu11
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
 fi
 
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+     CC="$CC $ac_cv_prog_cc_c11"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+  ac_prog_cc_stdc=c11
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c99_program
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c99=$ac_arg
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_BROKEN_LARGEFILE" >&5
-$as_echo "$rsync_cv_HAVE_BROKEN_LARGEFILE" >&6; }
-if test x"$rsync_cv_HAVE_BROKEN_LARGEFILE" != x"yes"; then
-   # Check whether --enable-largefile was given.
-if test "${enable_largefile+set}" = set; then :
-  enableval=$enable_largefile;
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
 fi
 
-if test "$enable_largefile" != no; then
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c99" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+     CC="$CC $ac_cv_prog_cc_c99"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+  ac_prog_cc_stdc=c99
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c89_program
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
-$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
-if ${ac_cv_sys_largefile_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_sys_largefile_CC=no
-     if test "$GCC" != yes; then
-       ac_save_CC=$CC
-       while :; do
-        # IRIX 6.2 and later do not support large files by default,
-        # so use the C compiler's -n32 option if that helps.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c89" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+     CC="$CC $ac_cv_prog_cc_c89"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+  ac_prog_cc_stdc=c89
+fi
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+printf %s "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test ${ac_cv_prog_CPP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+      # Double quotes because $CC needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
+#include <limits.h>
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+
+else $as_nop
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+  # Broken: success on invalid input.
+continue
+else $as_nop
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok
+then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+printf "%s\n" "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+
+else $as_nop
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+  # Broken: success on invalid input.
+continue
+else $as_nop
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok
+then :
+
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+printf "%s\n" "$CXX" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+printf "%s\n" "$ac_ct_CXX" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5
+printf %s "checking whether the compiler supports GNU C++... " >&6; }
+if test ${ac_cv_cxx_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+  ac_compiler_gnu=yes
+else $as_nop
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+y}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+printf %s "checking whether $CXX accepts -g... " >&6; }
+if test ${ac_cv_prog_cxx_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+  ac_cv_prog_cxx_g=yes
+else $as_nop
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+
+else $as_nop
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+        CXXFLAGS="-g"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+printf "%s\n" "$ac_cv_prog_cxx_g" >&6; }
+if test $ac_test_CXXFLAGS; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_prog_cxx_stdcxx=no
+if test x$ac_prog_cxx_stdcxx = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5
+printf %s "checking for $CXX option to enable C++11 features... " >&6; }
+if test ${ac_cv_prog_cxx_11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cxx_11=no
+ac_save_CXX=$CXX
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_cxx_conftest_cxx11_program
+_ACEOF
+for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA
+do
+  CXX="$ac_save_CXX $ac_arg"
+  if ac_fn_cxx_try_compile "$LINENO"
+then :
+  ac_cv_prog_cxx_cxx11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cxx_cxx11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CXX=$ac_save_CXX
+fi
+
+if test "x$ac_cv_prog_cxx_cxx11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cxx_cxx11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5
+printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; }
+     CXX="$CXX $ac_cv_prog_cxx_cxx11"
+fi
+  ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11
+  ac_prog_cxx_stdcxx=cxx11
+fi
+fi
+if test x$ac_prog_cxx_stdcxx = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5
+printf %s "checking for $CXX option to enable C++98 features... " >&6; }
+if test ${ac_cv_prog_cxx_98+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cxx_98=no
+ac_save_CXX=$CXX
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_cxx_conftest_cxx98_program
+_ACEOF
+for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA
+do
+  CXX="$ac_save_CXX $ac_arg"
+  if ac_fn_cxx_try_compile "$LINENO"
+then :
+  ac_cv_prog_cxx_cxx98=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cxx_cxx98" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CXX=$ac_save_CXX
+fi
+
+if test "x$ac_cv_prog_cxx_cxx98" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cxx_cxx98" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5
+printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; }
+     CXX="$CXX $ac_cv_prog_cxx_cxx98"
+fi
+  ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98
+  ac_prog_cxx_stdcxx=cxx98
+fi
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_AWK+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+printf "%s\n" "$AWK" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+printf %s "checking for grep that handles long lines and -e... " >&6; }
+if test ${ac_cv_path_GREP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in grep ggrep
+   do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  printf %s 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    printf "%s\n" 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+printf "%s\n" "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+printf %s "checking for egrep... " >&6; }
+if test ${ac_cv_path_EGREP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in egrep
+   do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  printf %s 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    printf "%s\n" 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+printf "%s\n" "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+
+  # Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+printf %s "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test ${ac_cv_path_install+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    # Account for fact that we put trailing slashes in our PATH walk.
+case $as_dir in #((
+  ./ | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           rm -rf conftest.one conftest.two conftest.dir
+           echo one > conftest.one
+           echo two > conftest.two
+           mkdir conftest.dir
+           if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" &&
+             test -s conftest.one && test -s conftest.two &&
+             test -s conftest.dir/conftest.one &&
+             test -s conftest.dir/conftest.two
+           then
+             ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c"
+             break 3
+           fi
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
 
-  ;
-  return 0;
-}
-_ACEOF
-        if ac_fn_c_try_compile "$LINENO"; then :
-  break
 fi
-rm -f core conftest.err conftest.$ac_objext
-        CC="$CC -n32"
-        if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_sys_largefile_CC=' -n32'; break
+  if test ${ac_cv_path_install+y}; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
 fi
-rm -f core conftest.err conftest.$ac_objext
-        break
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+printf "%s\n" "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5
+printf %s "checking for a race-free mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if test ${ac_cv_path_mkdir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in mkdir gmkdir; do
+        for ac_exec_ext in '' $ac_executable_extensions; do
+          as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue
+          case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #(
+            'mkdir ('*'coreutils) '* | \
+            'BusyBox '* | \
+            'mkdir (fileutils) '4.1*)
+              ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext
+              break 3;;
+          esac
+        done
        done
-       CC=$ac_save_CC
-       rm -f conftest.$ac_ext
-    fi
+  done
+IFS=$as_save_IFS
+
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
-$as_echo "$ac_cv_sys_largefile_CC" >&6; }
-  if test "$ac_cv_sys_largefile_CC" != no; then
-    CC=$CC$ac_cv_sys_largefile_CC
+
+  test -d ./--version && rmdir ./--version
+  if test ${ac_cv_path_mkdir+y}; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
   fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+printf "%s\n" "$MKDIR_P" >&6; }
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
-if ${ac_cv_sys_file_offset_bits+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  while :; do
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_sys_file_offset_bits=no; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_PERL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_PERL="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_sys_file_offset_bits=64; break
+  ;;
+esac
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  ac_cv_sys_file_offset_bits=unknown
-  break
-done
+PERL=$ac_cv_path_PERL
+if test -n "$PERL"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
+printf "%s\n" "$PERL" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
-$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
-case $ac_cv_sys_file_offset_bits in #(
-  no | unknown) ;;
+
+
+# Extract the first word of "python3", so it can be a program name with args.
+set dummy python3; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_PYTHON3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $PYTHON3 in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PYTHON3="$PYTHON3" # Let the user override the test with a path.
+  ;;
   *)
-cat >>confdefs.h <<_ACEOF
-#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
-_ACEOF
-;;
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_PYTHON3="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
 esac
-rm -rf conftest*
-  if test $ac_cv_sys_file_offset_bits = unknown; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
-$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
-if ${ac_cv_sys_large_files+:} false; then :
-  $as_echo_n "(cached) " >&6
+fi
+PYTHON3=$ac_cv_path_PYTHON3
+if test -n "$PYTHON3"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON3" >&5
+printf "%s\n" "$PYTHON3" >&6; }
 else
-  while :; do
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_sys_large_files=no; break
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#define _LARGE_FILES 1
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
-{
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_sys_large_files=1; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  ac_cv_sys_large_files=unknown
-  break
-done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
-$as_echo "$ac_cv_sys_large_files" >&6; }
-case $ac_cv_sys_large_files in #(
-  no | unknown) ;;
-  *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGE_FILES $ac_cv_sys_large_files
-_ACEOF
-;;
-esac
-rm -rf conftest*
-  fi
 
 
-fi
 
+printf "%s\n" "#define _GNU_SOURCE 1" >>confdefs.h
+
+
+if test x"$ac_cv_prog_cc_stdc" = x"no"; then
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: rsync requires an ANSI C compiler and you do not seem to have one" >&5
+printf "%s\n" "$as_me: WARNING: rsync requires an ANSI C compiler and you do not seem to have one" >&2;}
 fi
 
-ipv6type=unknown
-ipv6lib=none
-ipv6trylibc=yes
+no_lib=''
+err_msg=''
+nl='
+'
 
-# Check whether --enable-ipv6 was given.
-if test "${enable_ipv6+set}" = set; then :
-  enableval=$enable_ipv6;
+# Check whether --enable-profile was given.
+if test ${enable_profile+y}
+then :
+  enableval=$enable_profile;
 fi
 
-if test x"$enable_ipv6" != x"no"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking ipv6 stack type" >&5
-$as_echo_n "checking ipv6 stack type... " >&6; }
-       for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta cygwin TANDEM; do
-               case $i in
-               inria)
-                       # http://www.kame.net/
+if test x"$enable_profile" = x"yes"; then
+       CFLAGS="$CFLAGS -pg"
+fi
 
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if md2man can create manpages" >&5
+printf %s "checking if md2man can create manpages... " >&6; }
+if test x"$ac_cv_path_PYTHON3" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - python3 not found" >&5
+printf "%s\n" "no - python3 not found" >&6; }
+    md2man_works=no
+else
+    md2man_out=`"$srcdir/md2man" --test "$srcdir/rsync-ssl.1.md" 2>&1`
+    if test $? = 0; then
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       md2man_works=yes
+    else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       md2man_works=no
+       echo "$md2man_out"
+    fi
+fi
 
-#include <netinet/in.h>
-#ifdef IPV6_INRIA_VERSION
-yes
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
-  ipv6type=$i;
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we require man-page building" >&5
+printf %s "checking if we require man-page building... " >&6; }
+# Check whether --enable-md2man was given.
+if test ${enable_md2man+y}
+then :
+  enableval=$enable_md2man;
+fi
 
-$as_echo "#define INET6 1" >>confdefs.h
+if test x"$enable_md2man" != x"no"; then
+    if test -f "$srcdir/rsync.1"; then
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: optional" >&5
+printf "%s\n" "optional" >&6; }
+    else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: required" >&5
+printf "%s\n" "required" >&6; }
+       if test x"$md2man_works" = x"no"; then
+           err_msg="$err_msg$nl- You need python3 and either the cmarkgfm OR commonmark python3 lib in order"
+           err_msg="$err_msg$nl  to build manpages based on the git source (manpages are included in the"
+           err_msg="$err_msg$nl  official release tar files)."
+           no_lib="$no_lib md2man"
+       fi
+    fi
+    MAKE_MAN=man
+else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
 
+# Specifically, this turns on panic_action handling.
+# Check whether --enable-maintainer-mode was given.
+if test ${enable_maintainer_mode+y}
+then :
+  enableval=$enable_maintainer_mode;
+fi
 
+if test x"$enable_maintainer_mode" = x"yes"; then
+       CFLAGS="$CFLAGS -DMAINTAINER_MODE"
 fi
-rm -f conftest*
 
-                       ;;
-               kame)
-                       # http://www.kame.net/
-                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+# This is needed for our included version of popt.  Kind of silly, but
+# I don't want our version too far out of sync.
+CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
 
-#include <netinet/in.h>
-#ifdef __KAME__
-yes
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
-  ipv6type=$i;
+# If GCC, turn on warnings.
+if test x"$GCC" = x"yes"; then
+       CFLAGS="$CFLAGS -Wall -W"
+fi
 
-$as_echo "#define INET6 1" >>confdefs.h
 
+# Check whether --with-openssl-conf was given.
+if test ${with_openssl_conf+y}
+then :
+  withval=$with_openssl_conf;
 fi
-rm -f conftest*
 
-                       ;;
-               linux-glibc)
-                       # http://www.v6.linux.or.jp/
-                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+case "$with_openssl_conf" in
+    *^-/a-zA-Z0-9.,=@+_*) as_fn_error $? "Invalid path given to --with-openssl-conf" "$LINENO" 5 ;;
+    /*) CFLAGS="$CFLAGS -DSET_OPENSSL_CONF=$with_openssl_conf" ;;
+    no|'') ;;
+    yes) as_fn_error $? "No path given to --with-openssl-conf" "$LINENO" 5 ;;
+    *) as_fn_error $? "Non absolute path given to --with-openssl-conf" "$LINENO" 5 ;;
+esac
 
-#include <features.h>
-#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
-yes
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
-  ipv6type=$i;
 
-$as_echo "#define INET6 1" >>confdefs.h
+# Check whether --with-rrsync was given.
+if test ${with_rrsync+y}
+then :
+  withval=$with_rrsync;
+fi
 
+if test x"$with_rrsync" != x"yes"; then
+    with_rrsync=no
+else
+    MAKE_RRSYNC='rrsync'
+    MAKE_RRSYNC_1='rrsync.1'
+    GEN_RRSYNC='rrsync.1 rrsync.1.html'
 fi
-rm -f conftest*
 
-                       ;;
-               linux-inet6)
-                       # http://www.v6.linux.or.jp/
-                       if test -d /usr/inet6 -o -f /usr/inet6/lib/libinet6.a; then
-                               ipv6type=$i
-                               ipv6lib=inet6
-                               ipv6libdir=/usr/inet6/lib
-                               ipv6trylibc=yes;
 
-$as_echo "#define INET6 1" >>confdefs.h
 
-                               CFLAGS="-I/usr/inet6/include $CFLAGS"
-                       fi
-                       ;;
-               solaris)
-                       # http://www.sun.com
-                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+# Check whether --with-included-popt was given.
+if test ${with_included_popt+y}
+then :
+  withval=$with_included_popt;
+fi
 
-#include <netinet/ip6.h>
-#ifdef __sun
-yes
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
-  ipv6type=$i;
 
-$as_echo "#define INET6 1" >>confdefs.h
 
+# Check whether --with-included-zlib was given.
+if test ${with_included_zlib+y}
+then :
+  withval=$with_included_zlib;
 fi
-rm -f conftest*
-
-                       ;;
-               toshiba)
-                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-#include <sys/param.h>
-#ifdef _TOSHIBA_INET6
-yes
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
-  ipv6type=$i;
-                               ipv6lib=inet6;
-                               ipv6libdir=/usr/local/v6/lib;
 
-$as_echo "#define INET6 1" >>confdefs.h
 
+# Check whether --with-secluded-args was given.
+if test ${with_secluded_args+y}
+then :
+  withval=$with_secluded_args;
 fi
-rm -f conftest*
-
-                       ;;
-               v6d)
-                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-#include </usr/local/v6/include/sys/v6config.h>
-#ifdef __V6D__
-yes
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
-  ipv6type=$i;
-                               ipv6lib=v6;
-                               ipv6libdir=/usr/local/v6/lib;
+if test x"$with_secluded_args" = x"yes"; then
 
-$as_echo "#define INET6 1" >>confdefs.h
+printf "%s\n" "#define RSYNC_USE_SECLUDED_ARGS 1" >>confdefs.h
 
 fi
-rm -f conftest*
 
-                       ;;
-               zeta)
-                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-#include <sys/param.h>
-#ifdef _ZETA_MINAMI_INET6
-yes
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
-  ipv6type=$i;
-                               ipv6lib=inet6;
-                               ipv6libdir=/usr/local/v6/lib;
+# Check whether --with-rsync-path was given.
+if test ${with_rsync_path+y}
+then :
+  withval=$with_rsync_path;  RSYNC_PATH="$with_rsync_path"
+else $as_nop
+   RSYNC_PATH="rsync"
+fi
 
-$as_echo "#define INET6 1" >>confdefs.h
 
-fi
-rm -f conftest*
 
-                       ;;
-               cygwin)
-                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+printf "%s\n" "#define RSYNC_PATH \"$RSYNC_PATH\"" >>confdefs.h
 
-#include <netinet/in.h>
-#ifdef _CYGWIN_IN6_H
-yes
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
-  ipv6type=$i;
 
-$as_echo "#define INET6 1" >>confdefs.h
 
+# Check whether --with-rsyncd-conf was given.
+if test ${with_rsyncd_conf+y}
+then :
+  withval=$with_rsyncd_conf;  if test ! -z "$with_rsyncd_conf" ; then
+               case $with_rsyncd_conf in
+                       yes|no)
+                               RSYNCD_SYSCONF="/etc/rsyncd.conf"
+                               ;;
+                       /*)
+                               RSYNCD_SYSCONF="$with_rsyncd_conf"
+                               ;;
+                       *)
+                                as_fn_error $? "You must specify an absolute path to --with-rsyncd-conf=PATH" "$LINENO" 5
+                               ;;
+               esac
+       else
+               RSYNCD_SYSCONF="/etc/rsyncd.conf"
+       fi
+else $as_nop
+   RSYNCD_SYSCONF="/etc/rsyncd.conf"
 fi
-rm -f conftest*
 
-                       ;;
-               TANDEM)
-                       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-#include <netinet/ip6.h>
-#ifdef __TANDEM
-yes
-#endif
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
-  ipv6type=$i;
 
-$as_echo "#define INET6 1" >>confdefs.h
+printf "%s\n" "#define RSYNCD_SYSCONF \"$RSYNCD_SYSCONF\"" >>confdefs.h
+
+
 
+# Check whether --with-rsh was given.
+if test ${with_rsh+y}
+then :
+  withval=$with_rsh;
 fi
-rm -f conftest*
 
-                       ;;
-               esac
-               if test "$ipv6type" != "unknown"; then
-                       break
-               fi
-       done
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ipv6type" >&5
-$as_echo "$ipv6type" >&6; }
-
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getaddrinfo" >&5
-$as_echo_n "checking for library containing getaddrinfo... " >&6; }
-if ${ac_cv_search_getaddrinfo+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char getaddrinfo ();
-int
-main ()
-{
-return getaddrinfo ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' inet6; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+# Extract the first word of "remsh", so it can be a program name with args.
+set dummy remsh; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_HAVE_REMSH+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$HAVE_REMSH"; then
+  ac_cv_prog_HAVE_REMSH="$HAVE_REMSH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_HAVE_REMSH="1"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_getaddrinfo=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_getaddrinfo+:} false; then :
-  break
-fi
 done
-if ${ac_cv_search_getaddrinfo+:} false; then :
+  done
+IFS=$as_save_IFS
 
-else
-  ac_cv_search_getaddrinfo=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
+  test -z "$ac_cv_prog_HAVE_REMSH" && ac_cv_prog_HAVE_REMSH="0"
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getaddrinfo" >&5
-$as_echo "$ac_cv_search_getaddrinfo" >&6; }
-ac_res=$ac_cv_search_getaddrinfo
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
 fi
-
+HAVE_REMSH=$ac_cv_prog_HAVE_REMSH
+if test -n "$HAVE_REMSH"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $HAVE_REMSH" >&5
+printf "%s\n" "$HAVE_REMSH" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-# Check whether --enable-locale was given.
-if test "${enable_locale+set}" = set; then :
-  enableval=$enable_locale;
-fi
 
+if test x$HAVE_REMSH = x1; then
 
-if test x"$enable_locale" != x"no"; then
-       $as_echo "#define CONFIG_LOCALE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_REMSH 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to call shutdown on all sockets" >&5
-$as_echo_n "checking whether to call shutdown on all sockets... " >&6; }
-case $host_os in
-       *cygwin* ) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-$as_echo "#define SHUTDOWN_ALL_SOCKETS 1" >>confdefs.h
-
-                  ;;
-              * ) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; };;
-esac
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
+if test x"$with_rsh" != x; then
+       RSYNC_RSH="$with_rsh"
 else
-  ac_cv_header_stdc=no
+       RSYNC_RSH="ssh"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
+printf "%s\n" "#define RSYNC_RSH \"$RSYNC_RSH\"" >>confdefs.h
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
 
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
+# Some programs on solaris are only found in /usr/xpg4/bin (or work better than others versions).
+# Extract the first word of "sh", so it can be a program name with args.
+set dummy sh; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_SHELL_PATH+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $SHELL_PATH in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_SHELL_PATH="$SHELL_PATH" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /usr/xpg4/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_SHELL_PATH="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
+  test -z "$ac_cv_path_SHELL_PATH" && ac_cv_path_SHELL_PATH="/bin/sh"
+  ;;
+esac
+fi
+SHELL_PATH=$ac_cv_path_SHELL_PATH
+if test -n "$SHELL_PATH"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SHELL_PATH" >&5
+printf "%s\n" "$SHELL_PATH" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
+# Extract the first word of "fakeroot", so it can be a program name with args.
+set dummy fakeroot; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_FAKEROOT_PATH+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $FAKEROOT_PATH in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_FAKEROOT_PATH="$FAKEROOT_PATH" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /usr/xpg4/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_FAKEROOT_PATH="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-else
-  ac_cv_header_stdc=no
+  test -z "$ac_cv_path_FAKEROOT_PATH" && ac_cv_path_FAKEROOT_PATH="/usr/bin/fakeroot"
+  ;;
+esac
 fi
-rm -f conftest*
-
+FAKEROOT_PATH=$ac_cv_path_FAKEROOT_PATH
+if test -n "$FAKEROOT_PATH"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FAKEROOT_PATH" >&5
+printf "%s\n" "$FAKEROOT_PATH" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-                  (('a' <= (c) && (c) <= 'i') \
-                    || ('j' <= (c) && (c) <= 'r') \
-                    || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
 
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-       || toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
 
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
 
+# Check whether --with-nobody-user was given.
+if test ${with_nobody_user+y}
+then :
+  withval=$with_nobody_user;  NOBODY_USER="$with_nobody_user"
+else $as_nop
+   NOBODY_USER="nobody"
 fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
 
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
 
+
+# Check whether --with-nobody-group was given.
+if test ${with_nobody_group+y}
+then :
+  withval=$with_nobody_group;  NOBODY_GROUP="$with_nobody_group"
 fi
 
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-                 inttypes.h stdint.h unistd.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
 
+if test x"$with_nobody_group" = x; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the group for user \"nobody\"" >&5
+printf %s "checking the group for user \"nobody\"... " >&6; }
+    if grep '^nobody:' /etc/group >/dev/null 2>&1; then
+       NOBODY_GROUP=nobody
+    elif grep '^nogroup:' /etc/group >/dev/null 2>&1; then
+       NOBODY_GROUP=nogroup
+    else
+       NOBODY_GROUP=nobody # test for others?
+    fi
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NOBODY_GROUP" >&5
+printf "%s\n" "$NOBODY_GROUP" >&6; }
 fi
 
-done
 
+printf "%s\n" "#define NOBODY_USER \"$NOBODY_USER\"" >>confdefs.h
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
-$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if ${ac_cv_c_bigendian+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_c_bigendian=unknown
-    # See if we're dealing with a universal compiler.
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifndef __APPLE_CC__
-              not a universal capable compiler
-            #endif
-            typedef int dummy;
 
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+printf "%s\n" "#define NOBODY_GROUP \"$NOBODY_GROUP\"" >>confdefs.h
 
-       # Check for potential -arch flags.  It is not universal unless
-       # there are at least two -arch flags with different values.
-       ac_arch=
-       ac_prev=
-       for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
-        if test -n "$ac_prev"; then
-          case $ac_word in
-            i?86 | x86_64 | ppc | ppc64)
-              if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
-                ac_arch=$ac_word
-              else
-                ac_cv_c_bigendian=universal
-                break
-              fi
-              ;;
-          esac
-          ac_prev=
-        elif test "x$ac_word" = "x-arch"; then
-          ac_prev=arch
-        fi
-       done
+
+# rolling-checksum SIMD optimizations
+ROLL_SIMD=
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable rolling-checksum SIMD optimizations" >&5
+printf %s "checking whether to enable rolling-checksum SIMD optimizations... " >&6; }
+# Check whether --enable-roll-simd was given.
+if test ${enable_roll_simd+y}
+then :
+  enableval=$enable_roll_simd;
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    if test $ac_cv_c_bigendian = unknown; then
-      # See if sys/param.h defines the BYTE_ORDER macro.
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-            #include <sys/param.h>
 
-int
-main ()
-{
-#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
-                    && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
-                    && LITTLE_ENDIAN)
-             bogus endian macros
-            #endif
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  # It does; now see whether it defined to BIG_ENDIAN or not.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-               #include <sys/param.h>
+# Clag is crashing with -g -O2, so we'll get rid of -g for now.
+CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-g //'`
 
-int
-main ()
-{
-#if BYTE_ORDER != BIG_ENDIAN
-                not big endian
-               #endif
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_c_bigendian=yes
-else
-  ac_cv_c_bigendian=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+if test x"$enable_roll_simd" = x""; then
+    case "$host_os" in
+       *linux*) ;;
+       *) enable_roll_simd=no ;;
+    esac
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    fi
-    if test $ac_cv_c_bigendian = unknown; then
-      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <limits.h>
 
-int
-main ()
-{
-#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
-             bogus endian macros
-            #endif
+if test x"$enable_roll_simd" != x"no"; then
+    # For x86-64 SIMD, g++ >=5 or clang++ >=7 is required
+    if test x"$host_cpu" = x"x86_64" || test x"$host_cpu" = x"amd64"; then
+       ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  # It does; now see whether it defined to _BIG_ENDIAN or not.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+       if test x"$host" = x"$build"; then
+
+if test "$cross_compiling" = yes
+then :
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <limits.h>
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <immintrin.h>
+__attribute__ ((target("default"))) int test_ssse3(int x) { return x; }
+__attribute__ ((target("default"))) int test_sse2(int x) { return x; }
+__attribute__ ((target("default"))) int test_avx2(int x) { return x; }
+__attribute__ ((target("ssse3"))) int test_ssse3(int x) { return x; }
+__attribute__ ((target("sse2"))) int test_sse2(int x) { return x; }
+__attribute__ ((target("avx2"))) int test_avx2(int x) { return x; }
+typedef long long __m128i_u __attribute__((__vector_size__(16), __may_alias__, __aligned__(1)));
+typedef long long __m256i_u __attribute__((__vector_size__(32), __may_alias__, __aligned__(1)));
+__attribute__ ((target("default"))) void more_testing(char* buf, int len) { }
+__attribute__ ((target("ssse3"))) void more_testing(char* buf, int len)
+{
+    int i;
+    for (i = 0; i < (len-32); i+=32) {
+       __m128i in8_1, in8_2;
+       in8_1 = _mm_lddqu_si128((__m128i_u*)&buf[i]);
+       in8_2 = _mm_lddqu_si128((__m128i_u*)&buf[i + 16]);
+    }
+}
 
 int
-main ()
+main (void)
 {
-#ifndef _BIG_ENDIAN
-                not big endian
-               #endif
-
+if (test_ssse3(42) != 42 || test_sse2(42) != 42 || test_avx2(42) != 42) exit(1);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_c_bigendian=yes
-else
-  ac_cv_c_bigendian=no
+if ac_fn_cxx_try_run "$LINENO"
+then :
+  CXX_OK=yes
+else $as_nop
+  CXX_OK=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    fi
-    if test $ac_cv_c_bigendian = unknown; then
-      # Compile a test program.
-      if test "$cross_compiling" = yes; then :
-  # Try to guess by grepping values from an object file.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-short int ascii_mm[] =
-                 { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
-               short int ascii_ii[] =
-                 { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
-               int use_ascii (int i) {
-                 return ascii_mm[i] + ascii_ii[i];
-               }
-               short int ebcdic_ii[] =
-                 { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
-               short int ebcdic_mm[] =
-                 { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
-               int use_ebcdic (int i) {
-                 return ebcdic_mm[i] + ebcdic_ii[i];
-               }
-               extern int foo;
 
-int
-main ()
+       else
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <immintrin.h>
+__attribute__ ((target("default"))) int test_ssse3(int x) { return x; }
+__attribute__ ((target("default"))) int test_sse2(int x) { return x; }
+__attribute__ ((target("default"))) int test_avx2(int x) { return x; }
+__attribute__ ((target("ssse3"))) int test_ssse3(int x) { return x; }
+__attribute__ ((target("sse2"))) int test_sse2(int x) { return x; }
+__attribute__ ((target("avx2"))) int test_avx2(int x) { return x; }
+typedef long long __m128i_u __attribute__((__vector_size__(16), __may_alias__, __aligned__(1)));
+typedef long long __m256i_u __attribute__((__vector_size__(32), __may_alias__, __aligned__(1)));
+__attribute__ ((target("default"))) void more_testing(char* buf, int len) { }
+__attribute__ ((target("ssse3"))) void more_testing(char* buf, int len)
 {
-return use_ascii (foo) == use_ebcdic (foo);
-  ;
-  return 0;
+    int i;
+    for (i = 0; i < (len-32); i+=32) {
+       __m128i in8_1, in8_2;
+       in8_1 = _mm_lddqu_si128((__m128i_u*)&buf[i]);
+       in8_2 = _mm_lddqu_si128((__m128i_u*)&buf[i + 16]);
+    }
 }
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
-             ac_cv_c_bigendian=yes
-           fi
-           if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
-             if test "$ac_cv_c_bigendian" = unknown; then
-               ac_cv_c_bigendian=no
-             else
-               # finding both strings is unlikely to happen, but who knows?
-               ac_cv_c_bigendian=unknown
-             fi
-           fi
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$ac_includes_default
+
 int
-main ()
+main (void)
 {
 
-            /* Are we little or big endian?  From Harbison&Steele.  */
-            union
-            {
-              long int l;
-              char c[sizeof (long int)];
-            } u;
-            u.l = 1;
-            return u.c[sizeof (long int) - 1] == 1;
-
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  ac_cv_c_bigendian=no
-else
-  ac_cv_c_bigendian=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+  CXX_OK=yes
+else $as_nop
+  CXX_OK=no
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+       fi
+       ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+       if test x"$CXX_OK" = x"yes"; then
+           # AC_MSG_RESULT() is called below.
+           ROLL_SIMD="$host_cpu"
+       elif test x"$enable_roll_simd" = x"yes"; then
+           { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: error" >&5
+printf "%s\n" "error" >&6; }
+           as_fn_error $? "The rolling-checksum SIMD compilation test failed.
+Omit --enable-roll-simd to continue without it." "$LINENO" 5
+       fi
+    elif test x"$enable_roll_simd" = x"yes"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unavailable" >&5
+printf "%s\n" "unavailable" >&6; }
+        as_fn_error $? "The rolling-checksum SIMD optimizations are currently x86_64|amd64 only.
+Omit --enable-roll-simd to continue without it." "$LINENO" 5
     fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
-$as_echo "$ac_cv_c_bigendian" >&6; }
- case $ac_cv_c_bigendian in #(
-   yes)
-     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
-;; #(
-   no)
-      ;; #(
-   universal)
 
-$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+if test x"$ROLL_SIMD" != x""; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes ($ROLL_SIMD)" >&5
+printf "%s\n" "yes ($ROLL_SIMD)" >&6; }
 
-     ;; #(
-   *)
-     as_fn_error $? "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
- esac
+printf "%s\n" "#define USE_ROLL_SIMD 1" >>confdefs.h
 
-ac_header_dirent=no
-for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
-  as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
-$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
-if eval \${$as_ac_Header+:} false; then :
-  $as_echo_n "(cached) " >&6
+    ROLL_SIMD='$(ROLL_SIMD_'"$ROLL_SIMD)"
+    # We only use c++ for its target attribute dispatching, disable unneeded bulky features
+    CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-rtti"
+    # Apple often has "g++" as a symlink for clang. Try to find out the truth.
+    CXX_VERSION=`$CXX --version 2>/dev/null | head -n 2`
+    case "$CXX_VERSION" in
+    *clang*) CXXFLAGS="$CXXFLAGS -fno-slp-vectorize" ;; # avoid a performance hit
+    esac
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if assembler accepts noexecstack" >&5
+printf %s "checking if assembler accepts noexecstack... " >&6; }
+OLD_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Wa,--noexecstack"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <sys/types.h>
-#include <$ac_hdr>
 
 int
-main ()
+main (void)
 {
-if ((DIR *) 0)
 return 0;
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$as_ac_Header=yes"
-else
-  eval "$as_ac_Header=no"
+if ac_fn_c_try_compile "$LINENO"
+then :
+   NOEXECSTACK='-Wa,--noexecstack' ; { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+else $as_nop
+   NOEXECSTACK='' ; { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$as_ac_Header
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
-_ACEOF
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+CFLAGS="$OLD_CFLAGS"
 
-ac_header_dirent=$ac_hdr; break
-fi
 
-done
-# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
-if test $ac_header_dirent = dirent.h; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
-$as_echo_n "checking for library containing opendir... " >&6; }
-if ${ac_cv_search_opendir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+# arrgh. libc in some old debian version screwed up the largefile
+# stuff, getting byte range locking wrong
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken largefile support" >&5
+printf %s "checking for broken largefile support... " >&6; }
+if test ${rsync_cv_HAVE_BROKEN_LARGEFILE+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+
+if test "$cross_compiling" = yes
+then :
+  rsync_cv_HAVE_BROKEN_LARGEFILE=cross
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
+#define _FILE_OFFSET_BITS 64
+$ac_includes_default
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#elif defined HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
 #endif
-char opendir ();
-int
-main ()
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+int main(void)
 {
-return opendir ();
-  ;
-  return 0;
+       struct flock lock;
+       int status;
+       char tpl[32] = "/tmp/locktest.XXXXXX";
+       int fd = mkstemp(tpl);
+       if (fd < 0) {
+               strcpy(tpl, "conftest.dat");
+               fd = open(tpl, O_CREAT|O_RDWR, 0600);
+       }
+
+       lock.l_type = F_WRLCK;
+       lock.l_whence = SEEK_SET;
+       lock.l_start = 0;
+       lock.l_len = 1;
+       lock.l_pid = 0;
+       fcntl(fd,F_SETLK,&lock);
+       if (fork() == 0) {
+               lock.l_start = 1;
+               _exit(fcntl(fd,F_SETLK,&lock) == 0);
+       }
+       wait(&status);
+       unlink(tpl);
+       return WEXITSTATUS(status);
 }
+
 _ACEOF
-for ac_lib in '' dir; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_opendir=$ac_res
+if ac_fn_c_try_run "$LINENO"
+then :
+  rsync_cv_HAVE_BROKEN_LARGEFILE=yes
+else $as_nop
+  rsync_cv_HAVE_BROKEN_LARGEFILE=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_opendir+:} false; then :
-  break
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-done
-if ${ac_cv_search_opendir+:} false; then :
 
-else
-  ac_cv_search_opendir=no
 fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_BROKEN_LARGEFILE" >&5
+printf "%s\n" "$rsync_cv_HAVE_BROKEN_LARGEFILE" >&6; }
+if test x"$rsync_cv_HAVE_BROKEN_LARGEFILE" != x"yes"; then
+   # Check whether --enable-largefile was given.
+if test ${enable_largefile+y}
+then :
+  enableval=$enable_largefile;
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
-$as_echo "$ac_cv_search_opendir" >&6; }
-ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
-fi
+if test "$enable_largefile" != no; then
 
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
-$as_echo_n "checking for library containing opendir... " >&6; }
-if ${ac_cv_search_opendir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+printf %s "checking for special C compiler options needed for large files... " >&6; }
+if test ${ac_cv_sys_largefile_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_sys_largefile_CC=no
+     if test "$GCC" != yes; then
+       ac_save_CC=$CC
+       while :; do
+        # IRIX 6.2 and later do not support large files by default,
+        # so use the C compiler's -n32 option if that helps.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char opendir ();
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
 int
-main ()
+main (void)
 {
-return opendir ();
+
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' x; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_opendir=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_opendir+:} false; then :
+        if ac_fn_c_try_compile "$LINENO"
+then :
   break
 fi
-done
-if ${ac_cv_search_opendir+:} false; then :
-
-else
-  ac_cv_search_opendir=no
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+        CC="$CC -n32"
+        if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_sys_largefile_CC=' -n32'; break
 fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+        break
+       done
+       CC=$ac_save_CC
+       rm -f conftest.$ac_ext
+    fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
-$as_echo "$ac_cv_search_opendir" >&6; }
-ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+printf "%s\n" "$ac_cv_sys_largefile_CC" >&6; }
+  if test "$ac_cv_sys_largefile_CC" != no; then
+    CC=$CC$ac_cv_sys_largefile_CC
+  fi
 
-fi
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+printf %s "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if test ${ac_cv_sys_file_offset_bits+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  while :; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main (void)
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_sys_file_offset_bits=no; break
 fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
-$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if ${ac_cv_header_time+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+#define _FILE_OFFSET_BITS 64
 #include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
 int
-main ()
+main (void)
 {
-if ((struct tm *) 0)
-return 0;
+
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_time=yes
-else
-  ac_cv_header_time=no
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_sys_file_offset_bits=64; break
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+  ac_cv_sys_file_offset_bits=unknown
+  break
+done
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
-$as_echo "$ac_cv_header_time" >&6; }
-if test $ac_cv_header_time = yes; then
-
-$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+printf "%s\n" "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+  no | unknown) ;;
+  *)
+printf "%s\n" "#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits" >>confdefs.h
+;;
+esac
+rm -rf conftest*
+  if test $ac_cv_sys_file_offset_bits = unknown; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+printf %s "checking for _LARGE_FILES value needed for large files... " >&6; }
+if test ${ac_cv_sys_large_files+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  while :; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main (void)
+{
 
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_sys_large_files=no; break
 fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
-$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
-if ${ac_cv_header_sys_wait_h+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+#define _LARGE_FILES 1
 #include <sys/types.h>
-#include <sys/wait.h>
-#ifndef WEXITSTATUS
-# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
-#endif
-#ifndef WIFEXITED
-# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
-#endif
-
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
 int
-main ()
+main (void)
 {
-  int s;
-  wait (&s);
-  s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_sys_wait_h=yes
-else
-  ac_cv_header_sys_wait_h=no
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+  ac_cv_sys_large_files=unknown
+  break
+done
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+printf "%s\n" "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+  no | unknown) ;;
+  *)
+printf "%s\n" "#define _LARGE_FILES $ac_cv_sys_large_files" >>confdefs.h
+;;
+esac
+rm -rf conftest*
+  fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
-$as_echo "$ac_cv_header_sys_wait_h" >&6; }
-if test $ac_cv_header_sys_wait_h = yes; then
-
-$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
 
 fi
 
-for ac_header in sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
-    unistd.h utime.h grp.h compat.h sys/param.h ctype.h sys/wait.h \
-    sys/ioctl.h sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h \
-    sys/un.h sys/attr.h mcheck.h arpa/inet.h arpa/nameser.h locale.h \
-    netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h \
-    sys/acl.h acl/libacl.h attr/xattr.h sys/xattr.h sys/extattr.h dl.h \
-    popt.h popt/popt.h linux/falloc.h netinet/in_systm.h netinet/ip.h \
-    zlib.h xxhash.h openssl/md4.h openssl/md5.h zstd.h lz4.h sys/file.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable ipv6" >&5
+printf %s "checking whether to enable ipv6... " >&6; }
+# Check whether --enable-ipv6 was given.
+if test ${enable_ipv6+y}
+then :
+  enableval=$enable_ipv6;  case "$enableval" in
+  no)
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+       ;;
+  *)   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 
-fi
+printf "%s\n" "#define INET6 1" >>confdefs.h
 
-done
+       ;;
+  esac
+else $as_nop
+  if test "$cross_compiling" = yes
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sys/types.h defines makedev" >&5
-$as_echo_n "checking whether sys/types.h defines makedev... " >&6; }
-if ${ac_cv_header_sys_types_h_makedev+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+ /* AF_INET6 availability check */
+#include <stdlib.h>
 #include <sys/types.h>
-int
-main ()
+#include <sys/socket.h>
+main()
 {
-return makedev(0, 0);
-  ;
-  return 0;
+   if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
+     exit(1);
+   else
+     exit(0);
 }
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  if grep sys/sysmacros.h conftest.err >/dev/null; then
-                  ac_cv_header_sys_types_h_makedev=no
-                else
-                  ac_cv_header_sys_types_h_makedev=yes
-                fi
-else
-  ac_cv_header_sys_types_h_makedev=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_types_h_makedev" >&5
-$as_echo "$ac_cv_header_sys_types_h_makedev" >&6; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 
-if test $ac_cv_header_sys_types_h_makedev = no; then
-ac_fn_c_check_header_mongrel "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_mkdev_h" = xyes; then :
+printf "%s\n" "#define INET6 1" >>confdefs.h
 
-$as_echo "#define MAJOR_IN_MKDEV 1" >>confdefs.h
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
 
 fi
 
 
+# Check whether --enable-locale was given.
+if test ${enable_locale+y}
+then :
+  enableval=$enable_locale;
+fi
 
-  if test $ac_cv_header_sys_mkdev_h = no; then
-    ac_fn_c_check_header_mongrel "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_sysmacros_h" = xyes; then :
 
-$as_echo "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h
+if test x"$enable_locale" != x"no"; then
+       printf "%s\n" "#define CONFIG_LOCALE 1" >>confdefs.h
 
 fi
 
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to call shutdown on all sockets" >&5
+printf %s "checking whether to call shutdown on all sockets... " >&6; }
+case $host_os in
+       *cygwin* ) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 
-  fi
-fi
+printf "%s\n" "#define SHUTDOWN_ALL_SOCKETS 1" >>confdefs.h
 
+                  ;;
+              * ) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; };;
+esac
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable use of openssl crypto library" >&5
-$as_echo_n "checking whether to enable use of openssl crypto library... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable use of openssl crypto library" >&5
+printf %s "checking whether to enable use of openssl crypto library... " >&6; }
 # Check whether --enable-openssl was given.
-if test "${enable_openssl+set}" = set; then :
+if test ${enable_openssl+y}
+then :
   enableval=$enable_openssl;
 fi
 
 
 if test x"$enable_openssl" != x"no"; then
     if test x"$ac_cv_header_openssl_md4_h" = x"yes" && test x"$ac_cv_header_openssl_md5_h" = x"yes"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing MD5_Init" >&5
-$as_echo_n "checking for library containing MD5_Init... " >&6; }
-if ${ac_cv_search_MD5_Init+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing MD5_Init" >&5
+printf %s "checking for library containing MD5_Init... " >&6; }
+if test ${ac_cv_search_MD5_Init+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -6344,82 +7784,163 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char MD5_Init ();
 int
-main ()
+main (void)
 {
 return MD5_Init ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' crypto; do
+for ac_lib in '' crypto
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_MD5_Init=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_MD5_Init+:} false; then :
+  if test ${ac_cv_search_MD5_Init+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_MD5_Init+:} false; then :
+if test ${ac_cv_search_MD5_Init+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_MD5_Init=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_MD5_Init" >&5
-$as_echo "$ac_cv_search_MD5_Init" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_MD5_Init" >&5
+printf "%s\n" "$ac_cv_search_MD5_Init" >&6; }
 ac_res=$ac_cv_search_MD5_Init
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-  $as_echo "#define USE_OPENSSL 1" >>confdefs.h
+  printf "%s\n" "#define USE_OPENSSL 1" >>confdefs.h
 
-else
+          enable_openssl=yes
+else $as_nop
   err_msg="$err_msg$nl- Failed to find MD5_Init function in openssl crypto lib.";
           no_lib="$no_lib openssl"
 fi
 
     else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
        err_msg="$err_msg$nl- Failed to find openssl/md4.h and openssl/md5.h for openssl crypto lib support."
        no_lib="$no_lib openssl"
     fi
+    if test x"$enable_md5_asm" != x"yes"; then
+       enable_md5_asm=no
+    fi
+else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+MD5_ASM=
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable MD5 ASM optimizations" >&5
+printf %s "checking whether to enable MD5 ASM optimizations... " >&6; }
+# Check whether --enable-md5-asm was given.
+if test ${enable_md5_asm+y}
+then :
+  enableval=$enable_md5_asm;
+fi
+
+
+if test x"$enable_md5_asm" = x""; then
+    case "$host_os" in
+       *linux*) ;;
+       *) enable_md5_asm=no ;;
+    esac
+fi
+
+if test x"$enable_md5_asm" != x"no"; then
+    if test x"$host_cpu" = x"x86_64" || test x"$host_cpu" = x"amd64"; then
+       MD5_ASM="$host_cpu"
+    elif test x"$enable_md5_asm" = x"yes"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unavailable" >&5
+printf "%s\n" "unavailable" >&6; }
+        as_fn_error $? "The ASM optimizations are currently x86_64|amd64 only.
+Omit --enable-md5-asm to continue without it." "$LINENO" 5
+    fi
+fi
+
+if test x"$MD5_ASM" != x""; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes ($MD5_ASM)" >&5
+printf "%s\n" "yes ($MD5_ASM)" >&6; }
+
+printf "%s\n" "#define USE_MD5_ASM 1" >>confdefs.h
+
+    MD5_ASM='$(MD5_ASM_'"$MD5_ASM)"
+else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+
+ROLL_ASM=
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable rolling-checksum ASM optimizations" >&5
+printf %s "checking whether to enable rolling-checksum ASM optimizations... " >&6; }
+# Check whether --enable-roll-asm was given.
+if test ${enable_roll_asm+y}
+then :
+  enableval=$enable_roll_asm;
+fi
+
+
+if test x"$ROLL_SIMD" = x""; then
+    enable_roll_asm=no
+fi
+
+if test x"$enable_roll_asm" = x"yes"; then
+    ROLL_ASM="$host_cpu"
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes ($ROLL_ASM)" >&5
+printf "%s\n" "yes ($ROLL_ASM)" >&6; }
+
+printf "%s\n" "#define USE_ROLL_ASM 1" >>confdefs.h
+
+    ROLL_ASM='$(ROLL_ASM_'"$ROLL_ASM)"
 else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable xxhash checksum support" >&5
-$as_echo_n "checking whether to enable xxhash checksum support... " >&6; }
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable xxhash checksum support" >&5
+printf %s "checking whether to enable xxhash checksum support... " >&6; }
 # Check whether --enable-xxhash was given.
-if test "${enable_xxhash+set}" = set; then :
+if test ${enable_xxhash+y}
+then :
   enableval=$enable_xxhash;
 fi
 
 
 if test x"$enable_xxhash" != x"no"; then
     if test x"$ac_cv_header_xxhash_h" = x"yes"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing XXH64_createState" >&5
-$as_echo_n "checking for library containing XXH64_createState... " >&6; }
-if ${ac_cv_search_XXH64_createState+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing XXH64_createState" >&5
+printf %s "checking for library containing XXH64_createState... " >&6; }
+if test ${ac_cv_search_XXH64_createState+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -6427,82 +7948,86 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char XXH64_createState ();
 int
-main ()
+main (void)
 {
 return XXH64_createState ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' xxhash; do
+for ac_lib in '' xxhash
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_XXH64_createState=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_XXH64_createState+:} false; then :
+  if test ${ac_cv_search_XXH64_createState+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_XXH64_createState+:} false; then :
+if test ${ac_cv_search_XXH64_createState+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_XXH64_createState=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_XXH64_createState" >&5
-$as_echo "$ac_cv_search_XXH64_createState" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_XXH64_createState" >&5
+printf "%s\n" "$ac_cv_search_XXH64_createState" >&6; }
 ac_res=$ac_cv_search_XXH64_createState
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-  $as_echo "#define SUPPORT_XXHASH 1" >>confdefs.h
+  printf "%s\n" "#define SUPPORT_XXHASH 1" >>confdefs.h
 
-else
+else $as_nop
   err_msg="$err_msg$nl- Failed to find XXH64_createState function in xxhash lib.";
             no_lib="$no_lib xxhash"
 fi
 
     else
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
        err_msg="$err_msg$nl- Failed to find xxhash.h for xxhash checksum support.";
        no_lib="$no_lib xxhash"
     fi
 else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable zstd compression" >&5
-$as_echo_n "checking whether to enable zstd compression... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable zstd compression" >&5
+printf %s "checking whether to enable zstd compression... " >&6; }
 # Check whether --enable-zstd was given.
-if test "${enable_zstd+set}" = set; then :
+if test ${enable_zstd+y}
+then :
   enableval=$enable_zstd;
 fi
 
 
 if test x"$enable_zstd" != x"no"; then
     if test x"$ac_cv_header_zstd_h" = x"yes"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ZSTD_minCLevel" >&5
-$as_echo_n "checking for library containing ZSTD_minCLevel... " >&6; }
-if ${ac_cv_search_ZSTD_minCLevel+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing ZSTD_minCLevel" >&5
+printf %s "checking for library containing ZSTD_minCLevel... " >&6; }
+if test ${ac_cv_search_ZSTD_minCLevel+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -6510,82 +8035,86 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char ZSTD_minCLevel ();
 int
-main ()
+main (void)
 {
 return ZSTD_minCLevel ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' zstd; do
+for ac_lib in '' zstd
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_ZSTD_minCLevel=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_ZSTD_minCLevel+:} false; then :
+  if test ${ac_cv_search_ZSTD_minCLevel+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_ZSTD_minCLevel+:} false; then :
+if test ${ac_cv_search_ZSTD_minCLevel+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_ZSTD_minCLevel=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ZSTD_minCLevel" >&5
-$as_echo "$ac_cv_search_ZSTD_minCLevel" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ZSTD_minCLevel" >&5
+printf "%s\n" "$ac_cv_search_ZSTD_minCLevel" >&6; }
 ac_res=$ac_cv_search_ZSTD_minCLevel
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-  $as_echo "#define SUPPORT_ZSTD 1" >>confdefs.h
+  printf "%s\n" "#define SUPPORT_ZSTD 1" >>confdefs.h
 
-else
+else $as_nop
   err_msg="$err_msg$nl- Failed to find ZSTD_minCLevel function in zstd lib.";
             no_lib="$no_lib zstd"
 fi
 
     else
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
        err_msg="$err_msg$nl- Failed to find zstd.h for zstd compression support.";
        no_lib="$no_lib zstd"
     fi
 else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable LZ4 compression" >&5
-$as_echo_n "checking whether to enable LZ4 compression... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable LZ4 compression" >&5
+printf %s "checking whether to enable LZ4 compression... " >&6; }
 # Check whether --enable-lz4 was given.
-if test "${enable_lz4+set}" = set; then :
+if test ${enable_lz4+y}
+then :
   enableval=$enable_lz4;
 fi
 
 
 if test x"$enable_lz4" != x"no"; then
     if test x"$ac_cv_header_lz4_h" = x"yes"; then
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing LZ4_compress_default" >&5
-$as_echo_n "checking for library containing LZ4_compress_default... " >&6; }
-if ${ac_cv_search_LZ4_compress_default+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing LZ4_compress_default" >&5
+printf %s "checking for library containing LZ4_compress_default... " >&6; }
+if test ${ac_cv_search_LZ4_compress_default+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -6593,63 +8122,65 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char LZ4_compress_default ();
 int
-main ()
+main (void)
 {
 return LZ4_compress_default ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' lz4; do
+for ac_lib in '' lz4
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_LZ4_compress_default=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_LZ4_compress_default+:} false; then :
+  if test ${ac_cv_search_LZ4_compress_default+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_LZ4_compress_default+:} false; then :
+if test ${ac_cv_search_LZ4_compress_default+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_LZ4_compress_default=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_LZ4_compress_default" >&5
-$as_echo "$ac_cv_search_LZ4_compress_default" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_LZ4_compress_default" >&5
+printf "%s\n" "$ac_cv_search_LZ4_compress_default" >&6; }
 ac_res=$ac_cv_search_LZ4_compress_default
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-  $as_echo "#define SUPPORT_LZ4 1" >>confdefs.h
+  printf "%s\n" "#define SUPPORT_LZ4 1" >>confdefs.h
 
-else
+else $as_nop
   err_msg="$err_msg$nl- Failed to find LZ4_compress_default function in lz4 lib.";
             no_lib="$no_lib lz4"
 fi
 
     else
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
        err_msg="$err_msg$nl- Failed to find lz4.h for lz4 compression support."
        no_lib="$no_lib lz4"
     fi
 else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 if test x"$no_lib" != x; then
@@ -6658,7 +8189,7 @@ if test x"$no_lib" != x; then
     echo "$err_msg"
     echo ""
     echo "See the INSTALL file for hints on how to install the missing libraries and/or"
-    echo "how to generate (or fetch) man pages:"
+    echo "how to generate (or fetch) manpages:"
     echo "    https://github.com/WayneD/rsync/blob/master/INSTALL.md"
     echo ""
     echo "To disable one or more features, the relevant configure options are:"
@@ -6669,19 +8200,23 @@ if test x"$no_lib" != x; then
     as_fn_error $? "Aborting configure run" "$LINENO" 5
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if makedev takes 3 args" >&5
-$as_echo_n "checking if makedev takes 3 args... " >&6; }
-if ${rsync_cv_MAKEDEV_TAKES_3_ARGS+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if makedev takes 3 args" >&5
+printf %s "checking if makedev takes 3 args... " >&6; }
+if test ${rsync_cv_MAKEDEV_TAKES_3_ARGS+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = yes
+then :
   rsync_cv_MAKEDEV_TAKES_3_ARGS=no
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 #ifdef MAJOR_IN_MKDEV
 #include <sys/mkdev.h>
 # if !defined makedev && (defined mkdev || defined _WIN32 || defined __WIN32__)
@@ -6700,9 +8235,10 @@ int main(void)
 }
 
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_MAKEDEV_TAKES_3_ARGS=yes
-else
+else $as_nop
   rsync_cv_MAKEDEV_TAKES_3_ARGS=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -6710,11 +8246,11 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_MAKEDEV_TAKES_3_ARGS" >&5
-$as_echo "$rsync_cv_MAKEDEV_TAKES_3_ARGS" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_MAKEDEV_TAKES_3_ARGS" >&5
+printf "%s\n" "$rsync_cv_MAKEDEV_TAKES_3_ARGS" >&6; }
 if test x"$rsync_cv_MAKEDEV_TAKES_3_ARGS" = x"yes"; then
 
-$as_echo "#define MAKEDEV_TAKES_3_ARGS 1" >>confdefs.h
+printf "%s\n" "#define MAKEDEV_TAKES_3_ARGS 1" >>confdefs.h
 
 fi
 
@@ -6722,17 +8258,19 @@ fi
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
-$as_echo_n "checking size of int... " >&6; }
-if ${ac_cv_sizeof_int+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+printf %s "checking size of int... " >&6; }
+if test ${ac_cv_sizeof_int+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_int" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (int)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -6741,31 +8279,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
-$as_echo "$ac_cv_sizeof_int" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+printf "%s\n" "$ac_cv_sizeof_int" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT $ac_cv_sizeof_int
-_ACEOF
+printf "%s\n" "#define SIZEOF_INT $ac_cv_sizeof_int" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
-$as_echo_n "checking size of long... " >&6; }
-if ${ac_cv_sizeof_long+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+printf %s "checking size of long... " >&6; }
+if test ${ac_cv_sizeof_long+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_long" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (long)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -6774,31 +8312,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
-$as_echo "$ac_cv_sizeof_long" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+printf "%s\n" "$ac_cv_sizeof_long" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG $ac_cv_sizeof_long
-_ACEOF
+printf "%s\n" "#define SIZEOF_LONG $ac_cv_sizeof_long" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
-$as_echo_n "checking size of long long... " >&6; }
-if ${ac_cv_sizeof_long_long+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+printf %s "checking size of long long... " >&6; }
+if test ${ac_cv_sizeof_long_long+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_long_long" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (long long)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -6807,31 +8345,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
-$as_echo "$ac_cv_sizeof_long_long" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+printf "%s\n" "$ac_cv_sizeof_long_long" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
-_ACEOF
+printf "%s\n" "#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
-$as_echo_n "checking size of short... " >&6; }
-if ${ac_cv_sizeof_short+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
+printf %s "checking size of short... " >&6; }
+if test ${ac_cv_sizeof_short+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_short" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (short)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -6840,31 +8378,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
-$as_echo "$ac_cv_sizeof_short" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
+printf "%s\n" "$ac_cv_sizeof_short" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_SHORT $ac_cv_sizeof_short
-_ACEOF
+printf "%s\n" "#define SIZEOF_SHORT $ac_cv_sizeof_short" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int16_t" >&5
-$as_echo_n "checking size of int16_t... " >&6; }
-if ${ac_cv_sizeof_int16_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int16_t))" "ac_cv_sizeof_int16_t"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int16_t" >&5
+printf %s "checking size of int16_t... " >&6; }
+if test ${ac_cv_sizeof_int16_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int16_t))" "ac_cv_sizeof_int16_t"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_int16_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (int16_t)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -6873,31 +8411,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int16_t" >&5
-$as_echo "$ac_cv_sizeof_int16_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int16_t" >&5
+printf "%s\n" "$ac_cv_sizeof_int16_t" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT16_T $ac_cv_sizeof_int16_t
-_ACEOF
+printf "%s\n" "#define SIZEOF_INT16_T $ac_cv_sizeof_int16_t" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uint16_t" >&5
-$as_echo_n "checking size of uint16_t... " >&6; }
-if ${ac_cv_sizeof_uint16_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint16_t))" "ac_cv_sizeof_uint16_t"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of uint16_t" >&5
+printf %s "checking size of uint16_t... " >&6; }
+if test ${ac_cv_sizeof_uint16_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint16_t))" "ac_cv_sizeof_uint16_t"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_uint16_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (uint16_t)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -6906,31 +8444,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint16_t" >&5
-$as_echo "$ac_cv_sizeof_uint16_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint16_t" >&5
+printf "%s\n" "$ac_cv_sizeof_uint16_t" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_UINT16_T $ac_cv_sizeof_uint16_t
-_ACEOF
+printf "%s\n" "#define SIZEOF_UINT16_T $ac_cv_sizeof_uint16_t" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int32_t" >&5
-$as_echo_n "checking size of int32_t... " >&6; }
-if ${ac_cv_sizeof_int32_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int32_t))" "ac_cv_sizeof_int32_t"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int32_t" >&5
+printf %s "checking size of int32_t... " >&6; }
+if test ${ac_cv_sizeof_int32_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int32_t))" "ac_cv_sizeof_int32_t"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_int32_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (int32_t)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -6939,31 +8477,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int32_t" >&5
-$as_echo "$ac_cv_sizeof_int32_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int32_t" >&5
+printf "%s\n" "$ac_cv_sizeof_int32_t" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT32_T $ac_cv_sizeof_int32_t
-_ACEOF
+printf "%s\n" "#define SIZEOF_INT32_T $ac_cv_sizeof_int32_t" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uint32_t" >&5
-$as_echo_n "checking size of uint32_t... " >&6; }
-if ${ac_cv_sizeof_uint32_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint32_t))" "ac_cv_sizeof_uint32_t"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of uint32_t" >&5
+printf %s "checking size of uint32_t... " >&6; }
+if test ${ac_cv_sizeof_uint32_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint32_t))" "ac_cv_sizeof_uint32_t"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_uint32_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (uint32_t)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -6972,31 +8510,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint32_t" >&5
-$as_echo "$ac_cv_sizeof_uint32_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint32_t" >&5
+printf "%s\n" "$ac_cv_sizeof_uint32_t" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_UINT32_T $ac_cv_sizeof_uint32_t
-_ACEOF
+printf "%s\n" "#define SIZEOF_UINT32_T $ac_cv_sizeof_uint32_t" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int64_t" >&5
-$as_echo_n "checking size of int64_t... " >&6; }
-if ${ac_cv_sizeof_int64_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int64_t))" "ac_cv_sizeof_int64_t"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int64_t" >&5
+printf %s "checking size of int64_t... " >&6; }
+if test ${ac_cv_sizeof_int64_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int64_t))" "ac_cv_sizeof_int64_t"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_int64_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (int64_t)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -7005,31 +8543,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int64_t" >&5
-$as_echo "$ac_cv_sizeof_int64_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int64_t" >&5
+printf "%s\n" "$ac_cv_sizeof_int64_t" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT64_T $ac_cv_sizeof_int64_t
-_ACEOF
+printf "%s\n" "#define SIZEOF_INT64_T $ac_cv_sizeof_int64_t" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5
-$as_echo_n "checking size of off_t... " >&6; }
-if ${ac_cv_sizeof_off_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5
+printf %s "checking size of off_t... " >&6; }
+if test ${ac_cv_sizeof_off_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_off_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (off_t)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -7038,31 +8576,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5
-$as_echo "$ac_cv_sizeof_off_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5
+printf "%s\n" "$ac_cv_sizeof_off_t" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
-_ACEOF
+printf "%s\n" "#define SIZEOF_OFF_T $ac_cv_sizeof_off_t" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off64_t" >&5
-$as_echo_n "checking size of off64_t... " >&6; }
-if ${ac_cv_sizeof_off64_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off64_t))" "ac_cv_sizeof_off64_t"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of off64_t" >&5
+printf %s "checking size of off64_t... " >&6; }
+if test ${ac_cv_sizeof_off64_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off64_t))" "ac_cv_sizeof_off64_t"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_off64_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (off64_t)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -7071,31 +8609,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off64_t" >&5
-$as_echo "$ac_cv_sizeof_off64_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off64_t" >&5
+printf "%s\n" "$ac_cv_sizeof_off64_t" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_OFF64_T $ac_cv_sizeof_off64_t
-_ACEOF
+printf "%s\n" "#define SIZEOF_OFF64_T $ac_cv_sizeof_off64_t" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
-$as_echo_n "checking size of time_t... " >&6; }
-if ${ac_cv_sizeof_time_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
+printf %s "checking size of time_t... " >&6; }
+if test ${ac_cv_sizeof_time_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_time_t" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (time_t)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -7104,31 +8642,31 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
-$as_echo "$ac_cv_sizeof_time_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
+printf "%s\n" "$ac_cv_sizeof_time_t" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
-_ACEOF
+printf "%s\n" "#define SIZEOF_TIME_T $ac_cv_sizeof_time_t" >>confdefs.h
 
 
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
 # This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char*" >&5
-$as_echo_n "checking size of char*... " >&6; }
-if ${ac_cv_sizeof_charp+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char*))" "ac_cv_sizeof_charp"        "$ac_includes_default"; then :
-
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of char*" >&5
+printf %s "checking size of char*... " >&6; }
+if test ${ac_cv_sizeof_charp+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char*))" "ac_cv_sizeof_charp"        "$ac_includes_default"
+then :
+
+else $as_nop
   if test "$ac_cv_type_charp" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "cannot compute sizeof (char*)
 See \`config.log' for more details" "$LINENO" 5; }
    else
@@ -7137,43 +8675,43 @@ See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_charp" >&5
-$as_echo "$ac_cv_sizeof_charp" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_charp" >&5
+printf "%s\n" "$ac_cv_sizeof_charp" >&6; }
 
 
 
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_CHARP $ac_cv_sizeof_charp
-_ACEOF
+printf "%s\n" "#define SIZEOF_CHARP $ac_cv_sizeof_charp" >>confdefs.h
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
-$as_echo_n "checking for inline... " >&6; }
-if ${ac_cv_c_inline+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+printf %s "checking for inline... " >&6; }
+if test ${ac_cv_c_inline+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #ifndef __cplusplus
 typedef int foo_t;
-static $ac_kw foo_t static_foo () {return 0; }
-$ac_kw foo_t foo () {return 0; }
+static $ac_kw foo_t static_foo (void) {return 0; }
+$ac_kw foo_t foo (void) {return 0; }
 #endif
 
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_c_inline=$ac_kw
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
   test "$ac_cv_c_inline" != no && break
 done
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
-$as_echo "$ac_cv_c_inline" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+printf "%s\n" "$ac_cv_c_inline" >&6; }
 
 case $ac_cv_c_inline in
   inline | yes) ;;
@@ -7192,11 +8730,12 @@ esac
 
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double with more range or precision than double" >&5
-$as_echo_n "checking for long double with more range or precision than double... " >&6; }
-if ${ac_cv_type_long_double_wider+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for long double with more range or precision than double" >&5
+printf %s "checking for long double with more range or precision than double... " >&6; }
+if test ${ac_cv_type_long_double_wider+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <float.h>
@@ -7213,7 +8752,7 @@ else
            }
 
 int
-main ()
+main (void)
 {
 static int test_array [1 - 2 * !((0 < ((DBL_MAX_EXP < LDBL_MAX_EXP)
                   + (DBL_MANT_DIG < LDBL_MANT_DIG)
@@ -7228,112 +8767,114 @@ return test_array [0];
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_type_long_double_wider=yes
-else
+else $as_nop
   ac_cv_type_long_double_wider=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double_wider" >&5
-$as_echo "$ac_cv_type_long_double_wider" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double_wider" >&5
+printf "%s\n" "$ac_cv_type_long_double_wider" >&6; }
   if test $ac_cv_type_long_double_wider = yes; then
 
-$as_echo "#define HAVE_LONG_DOUBLE_WIDER 1" >>confdefs.h
+printf "%s\n" "#define HAVE_LONG_DOUBLE_WIDER 1" >>confdefs.h
 
   fi
 
 ac_cv_c_long_double=$ac_cv_type_long_double_wider
 if test $ac_cv_c_long_double = yes; then
 
-$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_LONG_DOUBLE 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
-$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
-if ${ac_cv_type_uid_t+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+printf %s "checking for uid_t in sys/types.h... " >&6; }
+if test ${ac_cv_type_uid_t+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/types.h>
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "uid_t" >/dev/null 2>&1; then :
+  $EGREP "uid_t" >/dev/null 2>&1
+then :
   ac_cv_type_uid_t=yes
-else
+else $as_nop
   ac_cv_type_uid_t=no
 fi
-rm -f conftest*
+rm -rf conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
-$as_echo "$ac_cv_type_uid_t" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+printf "%s\n" "$ac_cv_type_uid_t" >&6; }
 if test $ac_cv_type_uid_t = no; then
 
-$as_echo "#define uid_t int" >>confdefs.h
+printf "%s\n" "#define uid_t int" >>confdefs.h
 
 
-$as_echo "#define gid_t int" >>confdefs.h
+printf "%s\n" "#define gid_t int" >>confdefs.h
 
 fi
 
 ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
-if test "x$ac_cv_type_mode_t" = xyes; then :
+if test "x$ac_cv_type_mode_t" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_MODE_T 1
-_ACEOF
+printf "%s\n" "#define HAVE_MODE_T 1" >>confdefs.h
 
 
 fi
 ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
-if test "x$ac_cv_type_off_t" = xyes; then :
+if test "x$ac_cv_type_off_t" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_OFF_T 1
-_ACEOF
+printf "%s\n" "#define HAVE_OFF_T 1" >>confdefs.h
 
 
 fi
 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = xyes; then :
+if test "x$ac_cv_type_size_t" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_SIZE_T 1
-_ACEOF
+printf "%s\n" "#define HAVE_SIZE_T 1" >>confdefs.h
 
 
 fi
 ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = xyes; then :
+if test "x$ac_cv_type_pid_t" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_PID_T 1
-_ACEOF
+printf "%s\n" "#define HAVE_PID_T 1" >>confdefs.h
 
 
 fi
 ac_fn_c_check_type "$LINENO" "id_t" "ac_cv_type_id_t" "$ac_includes_default"
-if test "x$ac_cv_type_id_t" = xyes; then :
+if test "x$ac_cv_type_id_t" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_ID_T 1
-_ACEOF
+printf "%s\n" "#define HAVE_ID_T 1" >>confdefs.h
 
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking type of array argument to getgroups" >&5
-$as_echo_n "checking type of array argument to getgroups... " >&6; }
-if ${ac_cv_type_getgroups+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = no; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking type of array argument to getgroups" >&5
+printf %s "checking type of array argument to getgroups... " >&6; }
+if test ${ac_cv_type_getgroups+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "$cross_compiling" = yes
+then :
   ac_cv_type_getgroups=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 /* Thanks to Mike Rendell for this test.  */
@@ -7343,7 +8884,7 @@ $ac_includes_default
 #define MAX(x, y) ((x) > (y) ? (x) : (y))
 
 int
-main ()
+main (void)
 {
   gid_t gidset[NGID];
   int i, n;
@@ -7360,9 +8901,10 @@ main ()
   return n > 0 && gidset[n] != val.gval;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   ac_cv_type_getgroups=gid_t
-else
+else $as_nop
   ac_cv_type_getgroups=int
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -7376,23 +8918,27 @@ if test $ac_cv_type_getgroups = cross; then
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1; then :
+  $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1
+then :
   ac_cv_type_getgroups=gid_t
-else
+else $as_nop
   ac_cv_type_getgroups=int
 fi
-rm -f conftest*
+rm -rf conftest*
 
 fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_getgroups" >&5
-$as_echo "$ac_cv_type_getgroups" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_getgroups" >&5
+printf "%s\n" "$ac_cv_type_getgroups" >&6; }
+
+printf "%s\n" "#define GETGROUPS_T $ac_cv_type_getgroups" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define GETGROUPS_T $ac_cv_type_getgroups
-_ACEOF
 
+else
+
+printf "%s\n" "#define GETGROUPS_T gid_t" >>confdefs.h
 
+fi
 ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -7404,11 +8950,10 @@ ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat
 #include <unistd.h>
 #endif
 "
-if test "x$ac_cv_member_struct_stat_st_rdev" = xyes; then :
+if test "x$ac_cv_member_struct_stat_st_rdev" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_STAT_ST_RDEV 1
-_ACEOF
+printf "%s\n" "#define HAVE_STRUCT_STAT_ST_RDEV 1" >>confdefs.h
 
 
 fi
@@ -7423,11 +8968,10 @@ ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimensec" "ac_cv_member_struct
 #include <unistd.h>
 #endif
 "
-if test "x$ac_cv_member_struct_stat_st_mtimensec" = xyes; then :
+if test "x$ac_cv_member_struct_stat_st_mtimensec" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1
-_ACEOF
+printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1" >>confdefs.h
 
 
 fi
@@ -7442,11 +8986,10 @@ ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimespec.tv_nsec" "ac_cv_membe
 #include <unistd.h>
 #endif
 "
-if test "x$ac_cv_member_struct_stat_st_mtimespec_tv_nsec" = xyes; then :
+if test "x$ac_cv_member_struct_stat_st_mtimespec_tv_nsec" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
-_ACEOF
+printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1" >>confdefs.h
 
 
 fi
@@ -7461,11 +9004,10 @@ ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim.tv_nsec" "ac_cv_member_str
 #include <unistd.h>
 #endif
 "
-if test "x$ac_cv_member_struct_stat_st_mtim_tv_nsec" = xyes; then :
+if test "x$ac_cv_member_struct_stat_st_mtim_tv_nsec" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
-_ACEOF
+printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1" >>confdefs.h
 
 
 fi
@@ -7475,15 +9017,17 @@ fi
    ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include <sys/types.h>
 #include <sys/socket.h>
 "
-if test "x$ac_cv_type_socklen_t" = xyes; then :
+if test "x$ac_cv_type_socklen_t" = xyes
+then :
 
-else
+else $as_nop
 
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5
-$as_echo_n "checking for socklen_t equivalent... " >&6; }
-      if ${rsync_cv_socklen_t_equiv+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5
+printf %s "checking for socklen_t equivalent... " >&6; }
+      if test ${rsync_cv_socklen_t_equiv+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
          # Systems have either "struct sockaddr *" or
          # "void *" as the second argument to getpeername
@@ -7499,7 +9043,7 @@ else
                   int getpeername (int, $arg2 *, $t *);
 
 int
-main ()
+main (void)
 {
 
                   $t len;
@@ -7509,13 +9053,14 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
 
                   rsync_cv_socklen_t_equiv="$t"
                   break
 
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
             done
          done
 
@@ -7525,46 +9070,46 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 fi
 
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_socklen_t_equiv" >&5
-$as_echo "$rsync_cv_socklen_t_equiv" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_socklen_t_equiv" >&5
+printf "%s\n" "$rsync_cv_socklen_t_equiv" >&6; }
 
-cat >>confdefs.h <<_ACEOF
-#define socklen_t $rsync_cv_socklen_t_equiv
-_ACEOF
+printf "%s\n" "#define socklen_t $rsync_cv_socklen_t_equiv" >>confdefs.h
 
 fi
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for errno in errno.h" >&5
-$as_echo_n "checking for errno in errno.h... " >&6; }
-if ${rsync_cv_errno+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for errno in errno.h" >&5
+printf %s "checking for errno in errno.h... " >&6; }
+if test ${rsync_cv_errno+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <errno.h>
 int
-main ()
+main (void)
 {
 int i = errno
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   rsync_cv_errno=yes
-else
+else $as_nop
   rsync_cv_have_errno_decl=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_errno" >&5
-$as_echo "$rsync_cv_errno" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_errno" >&5
+printf "%s\n" "$rsync_cv_errno" >&6; }
 if test x"$rsync_cv_errno" = x"yes"; then
 
-$as_echo "#define HAVE_ERRNO_DECL 1" >>confdefs.h
+printf "%s\n" "#define HAVE_ERRNO_DECL 1" >>confdefs.h
 
 fi
 
@@ -7576,25 +9121,22 @@ fi
 # libsocket.so which has a bad implementation of gethostbyname (it
 # only looks in /etc/hosts), so we only look for -lsocket if we need
 # it.
-for ac_func in connect
-do :
-  ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
-if test "x$ac_cv_func_connect" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_CONNECT 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
+if test "x$ac_cv_func_connect" = xyes
+then :
+  printf "%s\n" "#define HAVE_CONNECT 1" >>confdefs.h
 
 fi
-done
 
 if test x"$ac_cv_func_connect" = x"no"; then
     case "$LIBS" in
     *-lnsl*) ;;
-    *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf in -lnsl_s" >&5
-$as_echo_n "checking for printf in -lnsl_s... " >&6; }
-if ${ac_cv_lib_nsl_s_printf+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for printf in -lnsl_s" >&5
+printf %s "checking for printf in -lnsl_s... " >&6; }
+if test ${ac_cv_lib_nsl_s_printf+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lnsl_s  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -7603,33 +9145,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char printf ();
 int
-main ()
+main (void)
 {
 return printf ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_nsl_s_printf=yes
-else
+else $as_nop
   ac_cv_lib_nsl_s_printf=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_s_printf" >&5
-$as_echo "$ac_cv_lib_nsl_s_printf" >&6; }
-if test "x$ac_cv_lib_nsl_s_printf" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBNSL_S 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_s_printf" >&5
+printf "%s\n" "$ac_cv_lib_nsl_s_printf" >&6; }
+if test "x$ac_cv_lib_nsl_s_printf" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBNSL_S 1" >>confdefs.h
 
   LIBS="-lnsl_s $LIBS"
 
@@ -7638,11 +9177,12 @@ fi
     esac
     case "$LIBS" in
     *-lnsl*) ;;
-    *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf in -lnsl" >&5
-$as_echo_n "checking for printf in -lnsl... " >&6; }
-if ${ac_cv_lib_nsl_printf+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for printf in -lnsl" >&5
+printf %s "checking for printf in -lnsl... " >&6; }
+if test ${ac_cv_lib_nsl_printf+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lnsl  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -7651,33 +9191,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char printf ();
 int
-main ()
+main (void)
 {
 return printf ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_nsl_printf=yes
-else
+else $as_nop
   ac_cv_lib_nsl_printf=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_printf" >&5
-$as_echo "$ac_cv_lib_nsl_printf" >&6; }
-if test "x$ac_cv_lib_nsl_printf" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBNSL 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_printf" >&5
+printf "%s\n" "$ac_cv_lib_nsl_printf" >&6; }
+if test "x$ac_cv_lib_nsl_printf" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBNSL 1" >>confdefs.h
 
   LIBS="-lnsl $LIBS"
 
@@ -7686,11 +9223,12 @@ fi
     esac
     case "$LIBS" in
     *-lsocket*) ;;
-    *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5
-$as_echo_n "checking for connect in -lsocket... " >&6; }
-if ${ac_cv_lib_socket_connect+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5
+printf %s "checking for connect in -lsocket... " >&6; }
+if test ${ac_cv_lib_socket_connect+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lsocket  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -7699,33 +9237,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char connect ();
 int
-main ()
+main (void)
 {
 return connect ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_socket_connect=yes
-else
+else $as_nop
   ac_cv_lib_socket_connect=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5
-$as_echo "$ac_cv_lib_socket_connect" >&6; }
-if test "x$ac_cv_lib_socket_connect" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBSOCKET 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5
+printf "%s\n" "$ac_cv_lib_socket_connect" >&6; }
+if test "x$ac_cv_lib_socket_connect" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBSOCKET 1" >>confdefs.h
 
   LIBS="-lsocket $LIBS"
 
@@ -7734,11 +9269,12 @@ fi
     esac
     case "$LIBS" in
     *-linet*) ;;
-    *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -linet" >&5
-$as_echo_n "checking for connect in -linet... " >&6; }
-if ${ac_cv_lib_inet_connect+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for connect in -linet" >&5
+printf %s "checking for connect in -linet... " >&6; }
+if test ${ac_cv_lib_inet_connect+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-linet  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -7747,33 +9283,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char connect ();
 int
-main ()
+main (void)
 {
 return connect ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_inet_connect=yes
-else
+else $as_nop
   ac_cv_lib_inet_connect=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_connect" >&5
-$as_echo "$ac_cv_lib_inet_connect" >&6; }
-if test "x$ac_cv_lib_inet_connect" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBINET 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_connect" >&5
+printf "%s\n" "$ac_cv_lib_inet_connect" >&6; }
+if test "x$ac_cv_lib_inet_connect" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBINET 1" >>confdefs.h
 
   LIBS="-linet $LIBS"
 
@@ -7785,16 +9318,17 @@ fi
         # ac_cv_func_connect=yes
         # don't!  it would cause AC_CHECK_FUNC to succeed next time configure is run
 
-$as_echo "#define HAVE_CONNECT 1" >>confdefs.h
+printf "%s\n" "#define HAVE_CONNECT 1" >>confdefs.h
 
     fi
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_ntop" >&5
-$as_echo_n "checking for library containing inet_ntop... " >&6; }
-if ${ac_cv_search_inet_ntop+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing inet_ntop" >&5
+printf %s "checking for library containing inet_ntop... " >&6; }
+if test ${ac_cv_search_inet_ntop+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -7802,46 +9336,48 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char inet_ntop ();
 int
-main ()
+main (void)
 {
 return inet_ntop ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' resolv; do
+for ac_lib in '' resolv
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_inet_ntop=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_inet_ntop+:} false; then :
+  if test ${ac_cv_search_inet_ntop+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_inet_ntop+:} false; then :
+if test ${ac_cv_search_inet_ntop+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_inet_ntop=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_ntop" >&5
-$as_echo "$ac_cv_search_inet_ntop" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_ntop" >&5
+printf "%s\n" "$ac_cv_search_inet_ntop" >&6; }
 ac_res=$ac_cv_search_inet_ntop
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
@@ -7850,11 +9386,12 @@ fi
 # For OS X, Solaris, HP-UX, etc.: figure out if -liconv is needed.  We'll
 # accept either iconv_open or libiconv_open, since some include files map
 # the former to the latter.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing iconv_open" >&5
-$as_echo_n "checking for library containing iconv_open... " >&6; }
-if ${ac_cv_search_iconv_open+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing iconv_open" >&5
+printf %s "checking for library containing iconv_open... " >&6; }
+if test ${ac_cv_search_iconv_open+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -7862,55 +9399,58 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char iconv_open ();
 int
-main ()
+main (void)
 {
 return iconv_open ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' iconv; do
+for ac_lib in '' iconv
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_iconv_open=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_iconv_open+:} false; then :
+  if test ${ac_cv_search_iconv_open+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_iconv_open+:} false; then :
+if test ${ac_cv_search_iconv_open+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_iconv_open=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_iconv_open" >&5
-$as_echo "$ac_cv_search_iconv_open" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_iconv_open" >&5
+printf "%s\n" "$ac_cv_search_iconv_open" >&6; }
 ac_res=$ac_cv_search_iconv_open
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing libiconv_open" >&5
-$as_echo_n "checking for library containing libiconv_open... " >&6; }
-if ${ac_cv_search_libiconv_open+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing libiconv_open" >&5
+printf %s "checking for library containing libiconv_open... " >&6; }
+if test ${ac_cv_search_libiconv_open+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -7918,61 +9458,66 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char libiconv_open ();
 int
-main ()
+main (void)
 {
 return libiconv_open ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' iconv; do
+for ac_lib in '' iconv
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_libiconv_open=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_libiconv_open+:} false; then :
+  if test ${ac_cv_search_libiconv_open+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_libiconv_open+:} false; then :
+if test ${ac_cv_search_libiconv_open+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_libiconv_open=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_libiconv_open" >&5
-$as_echo "$ac_cv_search_libiconv_open" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_libiconv_open" >&5
+printf "%s\n" "$ac_cv_search_libiconv_open" >&6; }
 ac_res=$ac_cv_search_libiconv_open
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5
-$as_echo_n "checking for iconv declaration... " >&6; }
-if ${am_cv_proto_iconv+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5
+printf %s "checking for iconv declaration... " >&6; }
+if test ${am_cv_proto_iconv+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
+#if HAVE_STDLIB_H
 #include <stdlib.h>
+#endif
 #include <iconv.h>
 extern
 #ifdef __cplusplus
@@ -7985,39 +9530,39 @@ size_t iconv();
 #endif
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   am_cv_proto_iconv_arg1=""
-else
+else $as_nop
   am_cv_proto_iconv_arg1="const"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
       am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"
 fi
 
     am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed 's/( /(/'`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_t:-
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${ac_t:-
          }$am_cv_proto_iconv" >&5
-$as_echo "${ac_t:-
+printf "%s\n" "${ac_t:-
          }$am_cv_proto_iconv" >&6; }
 
-cat >>confdefs.h <<_ACEOF
-#define ICONV_CONST $am_cv_proto_iconv_arg1
-_ACEOF
+printf "%s\n" "#define ICONV_CONST $am_cv_proto_iconv_arg1" >>confdefs.h
 
 
 
 ac_fn_c_check_func "$LINENO" "inet_ntop" "ac_cv_func_inet_ntop"
-if test "x$ac_cv_func_inet_ntop" = xyes; then :
-  $as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h
+if test "x$ac_cv_func_inet_ntop" = xyes
+then :
+  printf "%s\n" "#define HAVE_INET_NTOP 1" >>confdefs.h
 
-else
+else $as_nop
   case " $LIBOBJS " in
   *" inet_ntop.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS inet_ntop.$ac_objext"
@@ -8025,195 +9570,210 @@ else
 esac
 
 fi
-
 ac_fn_c_check_func "$LINENO" "inet_pton" "ac_cv_func_inet_pton"
-if test "x$ac_cv_func_inet_pton" = xyes; then :
-  $as_echo "#define HAVE_INET_PTON 1" >>confdefs.h
+if test "x$ac_cv_func_inet_pton" = xyes
+then :
+  printf "%s\n" "#define HAVE_INET_PTON 1" >>confdefs.h
 
-else
+else $as_nop
   case " $LIBOBJS " in
   *" inet_pton.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS inet_pton.$ac_objext"
  ;;
 esac
 
-fi
-
-
+fi
 
 
 
 cv=`echo "struct addrinfo" | sed 'y%./+- %__p__%'`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct addrinfo" >&5
-$as_echo_n "checking for struct addrinfo... " >&6; }
-if eval \${ac_cv_type_$cv+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct addrinfo" >&5
+printf %s "checking for struct addrinfo... " >&6; }
+if eval test \${ac_cv_type_$cv+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 $ac_includes_default
 #include <netdb.h>
 int
-main ()
+main (void)
 {
 struct addrinfo foo;
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "ac_cv_type_$cv=yes"
-else
+else $as_nop
   eval "ac_cv_type_$cv=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 ac_foo=`eval echo \\$ac_cv_type_$cv`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_foo" >&5
-$as_echo "$ac_foo" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_foo" >&5
+printf "%s\n" "$ac_foo" >&6; }
 if test "$ac_foo" = yes; then
   ac_tr_hdr=HAVE_`echo struct addrinfo | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
 if false; then
        ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "$ac_includes_default"
-if test "x$ac_cv_type_struct_addrinfo" = xyes; then :
+if test "x$ac_cv_type_struct_addrinfo" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_ADDRINFO 1
-_ACEOF
+printf "%s\n" "#define HAVE_STRUCT_ADDRINFO 1" >>confdefs.h
 
 
 fi
 
 fi
 
-cat >>confdefs.h <<_ACEOF
-#define $ac_tr_hdr 1
-_ACEOF
+printf "%s\n" "#define $ac_tr_hdr 1" >>confdefs.h
 
 fi
 
 
-
 cv=`echo "struct sockaddr_storage" | sed 'y%./+- %__p__%'`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr_storage" >&5
-$as_echo_n "checking for struct sockaddr_storage... " >&6; }
-if eval \${ac_cv_type_$cv+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr_storage" >&5
+printf %s "checking for struct sockaddr_storage... " >&6; }
+if eval test \${ac_cv_type_$cv+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 $ac_includes_default
+
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 int
-main ()
+main (void)
 {
 struct sockaddr_storage foo;
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "ac_cv_type_$cv=yes"
-else
+else $as_nop
   eval "ac_cv_type_$cv=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 ac_foo=`eval echo \\$ac_cv_type_$cv`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_foo" >&5
-$as_echo "$ac_foo" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_foo" >&5
+printf "%s\n" "$ac_foo" >&6; }
 if test "$ac_foo" = yes; then
   ac_tr_hdr=HAVE_`echo struct sockaddr_storage | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
 if false; then
        ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" "$ac_includes_default"
-if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then :
+if test "x$ac_cv_type_struct_sockaddr_storage" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_SOCKADDR_STORAGE 1
-_ACEOF
+printf "%s\n" "#define HAVE_STRUCT_SOCKADDR_STORAGE 1" >>confdefs.h
 
 
 fi
 
 fi
 
-cat >>confdefs.h <<_ACEOF
-#define $ac_tr_hdr 1
-_ACEOF
+printf "%s\n" "#define $ac_tr_hdr 1" >>confdefs.h
 
 fi
 
 
 # Irix 6.5 has getaddrinfo but not the corresponding defines, so use
 #   builtin getaddrinfo if one of the defines don't exist
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether defines needed by getaddrinfo exist" >&5
-$as_echo_n "checking whether defines needed by getaddrinfo exist... " >&6; }
-if ${rsync_cv_HAVE_GETADDR_DEFINES+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether defines needed by getaddrinfo exist" >&5
+printf %s "checking whether defines needed by getaddrinfo exist... " >&6; }
+if test ${rsync_cv_HAVE_GETADDR_DEFINES+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
                        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-                       #include <sys/types.h>
-                       #include <sys/socket.h>
-                       #include <netdb.h>
-                       #ifdef AI_PASSIVE
-                       yes
-                       #endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef AI_PASSIVE
+yes
+#endif
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
+  $EGREP "yes" >/dev/null 2>&1
+then :
   rsync_cv_HAVE_GETADDR_DEFINES=yes
-else
+else $as_nop
   rsync_cv_HAVE_GETADDR_DEFINES=no
 fi
-rm -f conftest*
+rm -rf conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_GETADDR_DEFINES" >&5
-$as_echo "$rsync_cv_HAVE_GETADDR_DEFINES" >&6; }
-if test x"$rsync_cv_HAVE_GETADDR_DEFINES" = x"yes" -a x"$ac_cv_type_struct_addrinfo" = x"yes"; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_GETADDR_DEFINES" >&5
+printf "%s\n" "$rsync_cv_HAVE_GETADDR_DEFINES" >&6; }
+if test x"$rsync_cv_HAVE_GETADDR_DEFINES" = x"yes" && test x"$ac_cv_type_struct_addrinfo" = x"yes"
+then :
 
        # Tru64 UNIX has getaddrinfo() but has it renamed in libc as
        # something else so we must include <netdb.h> to get the
        # redefinition.
-       for ac_func in getaddrinfo
+
+  for ac_func in getaddrinfo
 do :
   ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
-if test "x$ac_cv_func_getaddrinfo" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_GETADDRINFO 1
-_ACEOF
+if test "x$ac_cv_func_getaddrinfo" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETADDRINFO 1" >>confdefs.h
 
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo by including <netdb.h>" >&5
-$as_echo_n "checking for getaddrinfo by including <netdb.h>... " >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo by including <netdb.h>" >&5
+printf %s "checking for getaddrinfo by including <netdb.h>... " >&6; }
                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
-               #include <sys/socket.h>
-               #include <netdb.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#include <netdb.h>
 int
-main ()
+main (void)
 {
 getaddrinfo(NULL, NULL, NULL, NULL);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+if ac_fn_c_try_link "$LINENO"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 
-$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
+printf "%s\n" "#define HAVE_GETADDRINFO 1" >>confdefs.h
 
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
                        case " $LIBOBJS " in
   *" getaddrinfo.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
@@ -8221,13 +9781,13 @@ $as_echo "no" >&6; }
 esac
 
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 fi
-done
 
+done
 
-else
+else $as_nop
   case " $LIBOBJS " in
   *" getaddrinfo.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
@@ -8237,64 +9797,84 @@ esac
 fi
 
 ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" "
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 
 "
-if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes; then :
+if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes
+then :
 
-$as_echo "#define HAVE_SOCKADDR_LEN 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SOCKADDR_LEN 1" >>confdefs.h
 
 fi
 
 
 ac_fn_c_check_member "$LINENO" "struct sockaddr_in" "sin_len" "ac_cv_member_struct_sockaddr_in_sin_len" "
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 #include <netinet/in.h>
 
 "
-if test "x$ac_cv_member_struct_sockaddr_in_sin_len" = xyes; then :
+if test "x$ac_cv_member_struct_sockaddr_in_sin_len" = xyes
+then :
 
-$as_echo "#define HAVE_SOCKADDR_IN_LEN 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SOCKADDR_IN_LEN 1" >>confdefs.h
 
 fi
 
 
 ac_fn_c_check_member "$LINENO" "struct sockaddr_un" "sun_len" "ac_cv_member_struct_sockaddr_un_sun_len" "
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 #include <netinet/in.h>
 
 "
-if test "x$ac_cv_member_struct_sockaddr_un_sun_len" = xyes; then :
+if test "x$ac_cv_member_struct_sockaddr_un_sun_len" = xyes
+then :
 
-$as_echo "#define HAVE_SOCKADDR_UN_LEN 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SOCKADDR_UN_LEN 1" >>confdefs.h
 
 fi
 
 
 ac_fn_c_check_member "$LINENO" "struct sockaddr_in6" "sin6_scope_id" "ac_cv_member_struct_sockaddr_in6_sin6_scope_id" "
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 #include <netinet/in.h>
 
 "
-if test "x$ac_cv_member_struct_sockaddr_in6_sin6_scope_id" = xyes; then :
+if test "x$ac_cv_member_struct_sockaddr_in6_sin6_scope_id" = xyes
+then :
 
-$as_echo "#define HAVE_SOCKADDR_IN6_SCOPE_ID 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SOCKADDR_IN6_SCOPE_ID 1" >>confdefs.h
 
 fi
 
 
 
-
 cv=`echo "struct stat64" | sed 'y%./+- %__p__%'`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
-$as_echo_n "checking for struct stat64... " >&6; }
-if eval \${ac_cv_type_$cv+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
+printf %s "checking for struct stat64... " >&6; }
+if eval test \${ac_cv_type_$cv+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -8316,64 +9896,59 @@ $ac_includes_default
 #endif
 
 int
-main ()
+main (void)
 {
 struct stat64 foo;
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "ac_cv_type_$cv=yes"
-else
+else $as_nop
   eval "ac_cv_type_$cv=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 ac_foo=`eval echo \\$ac_cv_type_$cv`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_foo" >&5
-$as_echo "$ac_foo" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_foo" >&5
+printf "%s\n" "$ac_foo" >&6; }
 if test "$ac_foo" = yes; then
   ac_tr_hdr=HAVE_`echo struct stat64 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
 if false; then
        ac_fn_c_check_type "$LINENO" "struct stat64" "ac_cv_type_struct_stat64" "$ac_includes_default"
-if test "x$ac_cv_type_struct_stat64" = xyes; then :
+if test "x$ac_cv_type_struct_stat64" = xyes
+then :
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_STRUCT_STAT64 1
-_ACEOF
+printf "%s\n" "#define HAVE_STRUCT_STAT64 1" >>confdefs.h
 
 
 fi
 
 fi
 
-cat >>confdefs.h <<_ACEOF
-#define $ac_tr_hdr 1
-_ACEOF
+printf "%s\n" "#define $ac_tr_hdr 1" >>confdefs.h
 
 fi
 
 
 # if we can't find strcasecmp, look in -lresolv (for Unixware at least)
 #
-for ac_func in strcasecmp
-do :
-  ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp"
-if test "x$ac_cv_func_strcasecmp" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_STRCASECMP 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp"
+if test "x$ac_cv_func_strcasecmp" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRCASECMP 1" >>confdefs.h
 
 fi
-done
 
 if test x"$ac_cv_func_strcasecmp" = x"no"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strcasecmp in -lresolv" >&5
-$as_echo_n "checking for strcasecmp in -lresolv... " >&6; }
-if ${ac_cv_lib_resolv_strcasecmp+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for strcasecmp in -lresolv" >&5
+printf %s "checking for strcasecmp in -lresolv... " >&6; }
+if test ${ac_cv_lib_resolv_strcasecmp+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lresolv  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -8382,33 +9957,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char strcasecmp ();
 int
-main ()
+main (void)
 {
 return strcasecmp ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_resolv_strcasecmp=yes
-else
+else $as_nop
   ac_cv_lib_resolv_strcasecmp=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_strcasecmp" >&5
-$as_echo "$ac_cv_lib_resolv_strcasecmp" >&6; }
-if test "x$ac_cv_lib_resolv_strcasecmp" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBRESOLV 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_strcasecmp" >&5
+printf "%s\n" "$ac_cv_lib_resolv_strcasecmp" >&6; }
+if test "x$ac_cv_lib_resolv_strcasecmp" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBRESOLV 1" >>confdefs.h
 
   LIBS="-lresolv $LIBS"
 
@@ -8416,23 +9988,20 @@ fi
 
 fi
 
-for ac_func in aclsort
-do :
-  ac_fn_c_check_func "$LINENO" "aclsort" "ac_cv_func_aclsort"
-if test "x$ac_cv_func_aclsort" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_ACLSORT 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "aclsort" "ac_cv_func_aclsort"
+if test "x$ac_cv_func_aclsort" = xyes
+then :
+  printf "%s\n" "#define HAVE_ACLSORT 1" >>confdefs.h
 
 fi
-done
 
 if test x"$ac_cv_func_aclsort" = x"no"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for aclsort in -lsec" >&5
-$as_echo_n "checking for aclsort in -lsec... " >&6; }
-if ${ac_cv_lib_sec_aclsort+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for aclsort in -lsec" >&5
+printf %s "checking for aclsort in -lsec... " >&6; }
+if test ${ac_cv_lib_sec_aclsort+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lsec  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -8441,33 +10010,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char aclsort ();
 int
-main ()
+main (void)
 {
 return aclsort ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_sec_aclsort=yes
-else
+else $as_nop
   ac_cv_lib_sec_aclsort=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sec_aclsort" >&5
-$as_echo "$ac_cv_lib_sec_aclsort" >&6; }
-if test "x$ac_cv_lib_sec_aclsort" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBSEC 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sec_aclsort" >&5
+printf "%s\n" "$ac_cv_lib_sec_aclsort" >&6; }
+if test "x$ac_cv_lib_sec_aclsort" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBSEC 1" >>confdefs.h
 
   LIBS="-lsec $LIBS"
 
 
 
 
-
-  for ac_header in $ac_header_list
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether utime accepts a null argument" >&5
-$as_echo_n "checking whether utime accepts a null argument... " >&6; }
-if ${ac_cv_func_utime_null+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether utime accepts a null argument" >&5
+printf %s "checking whether utime accepts a null argument... " >&6; }
+if test ${ac_cv_func_utime_null+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   rm -f conftest.data; >conftest.data
 # Sequent interprets utime(file, 0) to mean use start of epoch.  Wrong.
-if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = yes
+then :
   ac_cv_func_utime_null='guessing yes'
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
@@ -8513,7 +10063,7 @@ $ac_includes_default
               # include <utime.h>
               #endif
 int
-main ()
+main (void)
 {
 struct stat s, t;
   return ! (stat ("conftest.data", &s) == 0
@@ -8525,9 +10075,10 @@ struct stat s, t;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   ac_cv_func_utime_null=yes
-else
+else $as_nop
   ac_cv_func_utime_null=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -8535,39 +10086,39 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_utime_null" >&5
-$as_echo "$ac_cv_func_utime_null" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_utime_null" >&5
+printf "%s\n" "$ac_cv_func_utime_null" >&6; }
 if test "x$ac_cv_func_utime_null" != xno; then
   ac_cv_func_utime_null=yes
 
-$as_echo "#define HAVE_UTIME_NULL 1" >>confdefs.h
+printf "%s\n" "#define HAVE_UTIME_NULL 1" >>confdefs.h
 
 fi
 rm -f conftest.data
 
 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = xyes; then :
+if test "x$ac_cv_type_size_t" = xyes
+then :
 
-else
+else $as_nop
 
-cat >>confdefs.h <<_ACEOF
-#define size_t unsigned int
-_ACEOF
+printf "%s\n" "#define size_t unsigned int" >>confdefs.h
 
 fi
 
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
-$as_echo_n "checking for working alloca.h... " >&6; }
-if ${ac_cv_working_alloca_h+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+printf %s "checking for working alloca.h... " >&6; }
+if test ${ac_cv_working_alloca_h+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <alloca.h>
 int
-main ()
+main (void)
 {
 char *p = (char *) alloca (2 * sizeof (int));
                          if (p) return 0;
@@ -8575,240 +10126,602 @@ char *p = (char *) alloca (2 * sizeof (int));
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_working_alloca_h=yes
-else
+else $as_nop
   ac_cv_working_alloca_h=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
-$as_echo "$ac_cv_working_alloca_h" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
+printf "%s\n" "$ac_cv_working_alloca_h" >&6; }
 if test $ac_cv_working_alloca_h = yes; then
 
-$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+printf "%s\n" "#define HAVE_ALLOCA_H 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
-$as_echo_n "checking for alloca... " >&6; }
-if ${ac_cv_func_alloca_works+:} false; then :
-  $as_echo_n "(cached) " >&6
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
+printf %s "checking for alloca... " >&6; }
+if test ${ac_cv_func_alloca_works+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test $ac_cv_working_alloca_h = yes; then
+  ac_cv_func_alloca_works=yes
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#ifdef __GNUC__
-# define alloca __builtin_alloca
-#else
-# ifdef _MSC_VER
+#include <stdlib.h>
+#include <stddef.h>
+#ifndef alloca
+# ifdef __GNUC__
+#  define alloca __builtin_alloca
+# elif defined _MSC_VER
 #  include <malloc.h>
 #  define alloca _alloca
 # else
-#  ifdef HAVE_ALLOCA_H
-#   include <alloca.h>
-#  else
-#   ifdef _AIX
- #pragma alloca
-#   else
-#    ifndef alloca /* predefined by HP cc +Olibcalls */
-void *alloca (size_t);
-#    endif
-#   endif
+#  ifdef  __cplusplus
+extern "C"
 #  endif
+void *alloca (size_t);
 # endif
 #endif
 
-int
-main ()
-{
-char *p = (char *) alloca (1);
-                                   if (p) return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_func_alloca_works=yes
-else
-  ac_cv_func_alloca_works=no
+int
+main (void)
+{
+char *p = (char *) alloca (1);
+                                   if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_func_alloca_works=yes
+else $as_nop
+  ac_cv_func_alloca_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
+printf "%s\n" "$ac_cv_func_alloca_works" >&6; }
+fi
+
+if test $ac_cv_func_alloca_works = yes; then
+
+printf "%s\n" "#define HAVE_ALLOCA 1" >>confdefs.h
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+
+printf "%s\n" "#define C_ALLOCA 1" >>confdefs.h
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
+printf %s "checking stack direction for C alloca... " >&6; }
+if test ${ac_cv_c_stack_direction+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "$cross_compiling" = yes
+then :
+  ac_cv_c_stack_direction=0
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+find_stack_direction (int *addr, int depth)
+{
+  int dir, dummy = 0;
+  if (! addr)
+    addr = &dummy;
+  *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
+  dir = depth ? find_stack_direction (addr, depth - 1) : 0;
+  return dir + dummy;
+}
+
+int
+main (int argc, char **argv)
+{
+  return find_stack_direction (0, argc + !argv + 20) < 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"
+then :
+  ac_cv_c_stack_direction=1
+else $as_nop
+  ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
+printf "%s\n" "$ac_cv_c_stack_direction" >&6; }
+printf "%s\n" "#define STACK_DIRECTION $ac_cv_c_stack_direction" >>confdefs.h
+
+
+fi
+
+ac_fn_c_check_func "$LINENO" "waitpid" "ac_cv_func_waitpid"
+if test "x$ac_cv_func_waitpid" = xyes
+then :
+  printf "%s\n" "#define HAVE_WAITPID 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "wait4" "ac_cv_func_wait4"
+if test "x$ac_cv_func_wait4" = xyes
+then :
+  printf "%s\n" "#define HAVE_WAIT4 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd"
+if test "x$ac_cv_func_getcwd" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETCWD 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "chown" "ac_cv_func_chown"
+if test "x$ac_cv_func_chown" = xyes
+then :
+  printf "%s\n" "#define HAVE_CHOWN 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "chmod" "ac_cv_func_chmod"
+if test "x$ac_cv_func_chmod" = xyes
+then :
+  printf "%s\n" "#define HAVE_CHMOD 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "lchmod" "ac_cv_func_lchmod"
+if test "x$ac_cv_func_lchmod" = xyes
+then :
+  printf "%s\n" "#define HAVE_LCHMOD 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "mknod" "ac_cv_func_mknod"
+if test "x$ac_cv_func_mknod" = xyes
+then :
+  printf "%s\n" "#define HAVE_MKNOD 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "mkfifo" "ac_cv_func_mkfifo"
+if test "x$ac_cv_func_mkfifo" = xyes
+then :
+  printf "%s\n" "#define HAVE_MKFIFO 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "fchmod" "ac_cv_func_fchmod"
+if test "x$ac_cv_func_fchmod" = xyes
+then :
+  printf "%s\n" "#define HAVE_FCHMOD 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "fstat" "ac_cv_func_fstat"
+if test "x$ac_cv_func_fstat" = xyes
+then :
+  printf "%s\n" "#define HAVE_FSTAT 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "ftruncate" "ac_cv_func_ftruncate"
+if test "x$ac_cv_func_ftruncate" = xyes
+then :
+  printf "%s\n" "#define HAVE_FTRUNCATE 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strchr" "ac_cv_func_strchr"
+if test "x$ac_cv_func_strchr" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRCHR 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "readlink" "ac_cv_func_readlink"
+if test "x$ac_cv_func_readlink" = xyes
+then :
+  printf "%s\n" "#define HAVE_READLINK 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "link" "ac_cv_func_link"
+if test "x$ac_cv_func_link" = xyes
+then :
+  printf "%s\n" "#define HAVE_LINK 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "utime" "ac_cv_func_utime"
+if test "x$ac_cv_func_utime" = xyes
+then :
+  printf "%s\n" "#define HAVE_UTIME 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes"
+if test "x$ac_cv_func_utimes" = xyes
+then :
+  printf "%s\n" "#define HAVE_UTIMES 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "lutimes" "ac_cv_func_lutimes"
+if test "x$ac_cv_func_lutimes" = xyes
+then :
+  printf "%s\n" "#define HAVE_LUTIMES 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
+if test "x$ac_cv_func_strftime" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRFTIME 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "chflags" "ac_cv_func_chflags"
+if test "x$ac_cv_func_chflags" = xyes
+then :
+  printf "%s\n" "#define HAVE_CHFLAGS 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "getattrlist" "ac_cv_func_getattrlist"
+if test "x$ac_cv_func_getattrlist" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETATTRLIST 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "mktime" "ac_cv_func_mktime"
+if test "x$ac_cv_func_mktime" = xyes
+then :
+  printf "%s\n" "#define HAVE_MKTIME 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "innetgr" "ac_cv_func_innetgr"
+if test "x$ac_cv_func_innetgr" = xyes
+then :
+  printf "%s\n" "#define HAVE_INNETGR 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "linkat" "ac_cv_func_linkat"
+if test "x$ac_cv_func_linkat" = xyes
+then :
+  printf "%s\n" "#define HAVE_LINKAT 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove"
+if test "x$ac_cv_func_memmove" = xyes
+then :
+  printf "%s\n" "#define HAVE_MEMMOVE 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "lchown" "ac_cv_func_lchown"
+if test "x$ac_cv_func_lchown" = xyes
+then :
+  printf "%s\n" "#define HAVE_LCHOWN 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf"
+if test "x$ac_cv_func_vsnprintf" = xyes
+then :
+  printf "%s\n" "#define HAVE_VSNPRINTF 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf"
+if test "x$ac_cv_func_snprintf" = xyes
+then :
+  printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf"
+if test "x$ac_cv_func_vasprintf" = xyes
+then :
+  printf "%s\n" "#define HAVE_VASPRINTF 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf"
+if test "x$ac_cv_func_asprintf" = xyes
+then :
+  printf "%s\n" "#define HAVE_ASPRINTF 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "setsid" "ac_cv_func_setsid"
+if test "x$ac_cv_func_setsid" = xyes
+then :
+  printf "%s\n" "#define HAVE_SETSID 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strpbrk" "ac_cv_func_strpbrk"
+if test "x$ac_cv_func_strpbrk" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRPBRK 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
+if test "x$ac_cv_func_strlcat" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRLCAT 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
+if test "x$ac_cv_func_strlcpy" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRLCPY 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol"
+if test "x$ac_cv_func_strtol" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRTOL 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "mallinfo" "ac_cv_func_mallinfo"
+if test "x$ac_cv_func_mallinfo" = xyes
+then :
+  printf "%s\n" "#define HAVE_MALLINFO 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "mallinfo2" "ac_cv_func_mallinfo2"
+if test "x$ac_cv_func_mallinfo2" = xyes
+then :
+  printf "%s\n" "#define HAVE_MALLINFO2 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "getgroups" "ac_cv_func_getgroups"
+if test "x$ac_cv_func_getgroups" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETGROUPS 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "setgroups" "ac_cv_func_setgroups"
+if test "x$ac_cv_func_setgroups" = xyes
+then :
+  printf "%s\n" "#define HAVE_SETGROUPS 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "geteuid" "ac_cv_func_geteuid"
+if test "x$ac_cv_func_geteuid" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETEUID 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "getegid" "ac_cv_func_getegid"
+if test "x$ac_cv_func_getegid" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETEGID 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale"
+if test "x$ac_cv_func_setlocale" = xyes
+then :
+  printf "%s\n" "#define HAVE_SETLOCALE 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "setmode" "ac_cv_func_setmode"
+if test "x$ac_cv_func_setmode" = xyes
+then :
+  printf "%s\n" "#define HAVE_SETMODE 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "open64" "ac_cv_func_open64"
+if test "x$ac_cv_func_open64" = xyes
+then :
+  printf "%s\n" "#define HAVE_OPEN64 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "lseek64" "ac_cv_func_lseek64"
+if test "x$ac_cv_func_lseek64" = xyes
+then :
+  printf "%s\n" "#define HAVE_LSEEK64 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "mkstemp64" "ac_cv_func_mkstemp64"
+if test "x$ac_cv_func_mkstemp64" = xyes
+then :
+  printf "%s\n" "#define HAVE_MKSTEMP64 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "mtrace" "ac_cv_func_mtrace"
+if test "x$ac_cv_func_mtrace" = xyes
+then :
+  printf "%s\n" "#define HAVE_MTRACE 1" >>confdefs.h
+
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
+ac_fn_c_check_func "$LINENO" "va_copy" "ac_cv_func_va_copy"
+if test "x$ac_cv_func_va_copy" = xyes
+then :
+  printf "%s\n" "#define HAVE_VA_COPY 1" >>confdefs.h
+
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
-$as_echo "$ac_cv_func_alloca_works" >&6; }
+ac_fn_c_check_func "$LINENO" "__va_copy" "ac_cv_func___va_copy"
+if test "x$ac_cv_func___va_copy" = xyes
+then :
+  printf "%s\n" "#define HAVE___VA_COPY 1" >>confdefs.h
 
-if test $ac_cv_func_alloca_works = yes; then
+fi
+ac_fn_c_check_func "$LINENO" "seteuid" "ac_cv_func_seteuid"
+if test "x$ac_cv_func_seteuid" = xyes
+then :
+  printf "%s\n" "#define HAVE_SETEUID 1" >>confdefs.h
 
-$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+fi
+ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror"
+if test "x$ac_cv_func_strerror" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRERROR 1" >>confdefs.h
 
-else
-  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
-# that cause trouble.  Some versions do not even contain alloca or
-# contain a buggy version.  If you still want to use their alloca,
-# use ar to extract alloca.o from them instead of compiling alloca.c.
+fi
+ac_fn_c_check_func "$LINENO" "putenv" "ac_cv_func_putenv"
+if test "x$ac_cv_func_putenv" = xyes
+then :
+  printf "%s\n" "#define HAVE_PUTENV 1" >>confdefs.h
 
-ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+fi
+ac_fn_c_check_func "$LINENO" "iconv_open" "ac_cv_func_iconv_open"
+if test "x$ac_cv_func_iconv_open" = xyes
+then :
+  printf "%s\n" "#define HAVE_ICONV_OPEN 1" >>confdefs.h
 
-$as_echo "#define C_ALLOCA 1" >>confdefs.h
+fi
+ac_fn_c_check_func "$LINENO" "locale_charset" "ac_cv_func_locale_charset"
+if test "x$ac_cv_func_locale_charset" = xyes
+then :
+  printf "%s\n" "#define HAVE_LOCALE_CHARSET 1" >>confdefs.h
 
+fi
+ac_fn_c_check_func "$LINENO" "nl_langinfo" "ac_cv_func_nl_langinfo"
+if test "x$ac_cv_func_nl_langinfo" = xyes
+then :
+  printf "%s\n" "#define HAVE_NL_LANGINFO 1" >>confdefs.h
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
-$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
-if ${ac_cv_os_cray+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#if defined CRAY && ! defined CRAY2
-webecray
-#else
-wenotbecray
-#endif
+fi
+ac_fn_c_check_func "$LINENO" "getxattr" "ac_cv_func_getxattr"
+if test "x$ac_cv_func_getxattr" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETXATTR 1" >>confdefs.h
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "webecray" >/dev/null 2>&1; then :
-  ac_cv_os_cray=yes
-else
-  ac_cv_os_cray=no
 fi
-rm -f conftest*
+ac_fn_c_check_func "$LINENO" "extattr_get_link" "ac_cv_func_extattr_get_link"
+if test "x$ac_cv_func_extattr_get_link" = xyes
+then :
+  printf "%s\n" "#define HAVE_EXTATTR_GET_LINK 1" >>confdefs.h
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
-$as_echo "$ac_cv_os_cray" >&6; }
-if test $ac_cv_os_cray = yes; then
-  for ac_func in _getb67 GETB67 getb67; do
-    as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ac_fn_c_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction"
+if test "x$ac_cv_func_sigaction" = xyes
+then :
+  printf "%s\n" "#define HAVE_SIGACTION 1" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define CRAY_STACKSEG_END $ac_func
-_ACEOF
+fi
+ac_fn_c_check_func "$LINENO" "sigprocmask" "ac_cv_func_sigprocmask"
+if test "x$ac_cv_func_sigprocmask" = xyes
+then :
+  printf "%s\n" "#define HAVE_SIGPROCMASK 1" >>confdefs.h
 
-    break
 fi
+ac_fn_c_check_func "$LINENO" "setattrlist" "ac_cv_func_setattrlist"
+if test "x$ac_cv_func_setattrlist" = xyes
+then :
+  printf "%s\n" "#define HAVE_SETATTRLIST 1" >>confdefs.h
 
-  done
 fi
+ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist"
+if test "x$ac_cv_func_getgrouplist" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETGROUPLIST 1" >>confdefs.h
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
-$as_echo_n "checking stack direction for C alloca... " >&6; }
-if ${ac_cv_c_stack_direction+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "$cross_compiling" = yes; then :
-  ac_cv_c_stack_direction=0
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$ac_includes_default
-int
-find_stack_direction (int *addr, int depth)
-{
-  int dir, dummy = 0;
-  if (! addr)
-    addr = &dummy;
-  *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
-  dir = depth ? find_stack_direction (addr, depth - 1) : 0;
-  return dir + dummy;
-}
+fi
+ac_fn_c_check_func "$LINENO" "initgroups" "ac_cv_func_initgroups"
+if test "x$ac_cv_func_initgroups" = xyes
+then :
+  printf "%s\n" "#define HAVE_INITGROUPS 1" >>confdefs.h
 
-int
-main (int argc, char **argv)
-{
-  return find_stack_direction (0, argc + !argv + 20) < 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  ac_cv_c_stack_direction=1
-else
-  ac_cv_c_stack_direction=-1
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
+ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat"
+if test "x$ac_cv_func_utimensat" = xyes
+then :
+  printf "%s\n" "#define HAVE_UTIMENSAT 1" >>confdefs.h
+
 fi
+ac_fn_c_check_func "$LINENO" "posix_fallocate" "ac_cv_func_posix_fallocate"
+if test "x$ac_cv_func_posix_fallocate" = xyes
+then :
+  printf "%s\n" "#define HAVE_POSIX_FALLOCATE 1" >>confdefs.h
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
-$as_echo "$ac_cv_c_stack_direction" >&6; }
-cat >>confdefs.h <<_ACEOF
-#define STACK_DIRECTION $ac_cv_c_stack_direction
-_ACEOF
+ac_fn_c_check_func "$LINENO" "attropen" "ac_cv_func_attropen"
+if test "x$ac_cv_func_attropen" = xyes
+then :
+  printf "%s\n" "#define HAVE_ATTROPEN 1" >>confdefs.h
 
+fi
+ac_fn_c_check_func "$LINENO" "setvbuf" "ac_cv_func_setvbuf"
+if test "x$ac_cv_func_setvbuf" = xyes
+then :
+  printf "%s\n" "#define HAVE_SETVBUF 1" >>confdefs.h
 
 fi
+ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep"
+if test "x$ac_cv_func_nanosleep" = xyes
+then :
+  printf "%s\n" "#define HAVE_NANOSLEEP 1" >>confdefs.h
 
-for ac_func in waitpid wait4 getcwd chown chmod lchmod mknod mkfifo \
-    fchmod fstat ftruncate strchr readlink link utime utimes lutimes strftime \
-    chflags getattrlist mktime innetgr linkat \
-    memmove lchown vsnprintf snprintf vasprintf asprintf setsid strpbrk \
-    strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
-    setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
-    seteuid strerror putenv iconv_open locale_charset nl_langinfo getxattr \
-    extattr_get_link sigaction sigprocmask setattrlist getgrouplist \
-    initgroups utimensat posix_fallocate attropen setvbuf nanosleep usleep
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+fi
+ac_fn_c_check_func "$LINENO" "usleep" "ac_cv_func_usleep"
+if test "x$ac_cv_func_usleep" = xyes
+then :
+  printf "%s\n" "#define HAVE_USLEEP 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv"
+if test "x$ac_cv_func_setenv" = xyes
+then :
+  printf "%s\n" "#define HAVE_SETENV 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
+if test "x$ac_cv_func_unsetenv" = xyes
+then :
+  printf "%s\n" "#define HAVE_UNSETENV 1" >>confdefs.h
 
 fi
-done
 
 
 if test x"$ac_cv_func_iconv_open" != x"yes"; then
     ac_fn_c_check_func "$LINENO" "libiconv_open" "ac_cv_func_libiconv_open"
-if test "x$ac_cv_func_libiconv_open" = xyes; then :
-  ac_cv_func_iconv_open=yes; $as_echo "#define HAVE_ICONV_OPEN 1" >>confdefs.h
+if test "x$ac_cv_func_libiconv_open" = xyes
+then :
+  ac_cv_func_iconv_open=yes; printf "%s\n" "#define HAVE_ICONV_OPEN 1" >>confdefs.h
 
 fi
 
 fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for useable fallocate" >&5
-$as_echo_n "checking for useable fallocate... " >&6; }
-if ${rsync_cv_have_fallocate+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for useable fallocate" >&5
+printf %s "checking for useable fallocate... " >&6; }
+if test ${rsync_cv_have_fallocate+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <fcntl.h>
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 int
-main ()
+main (void)
 {
 fallocate(0, 0, 0, 0);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   rsync_cv_have_fallocate=yes
-else
+else $as_nop
   rsync_cv_have_fallocate=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_have_fallocate" >&5
-$as_echo "$rsync_cv_have_fallocate" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_have_fallocate" >&5
+printf "%s\n" "$rsync_cv_have_fallocate" >&6; }
 if test x"$rsync_cv_have_fallocate" = x"yes"; then
 
-$as_echo "#define HAVE_FALLOCATE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_FALLOCATE 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FALLOC_FL_PUNCH_HOLE" >&5
-$as_echo_n "checking for FALLOC_FL_PUNCH_HOLE... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for FALLOC_FL_PUNCH_HOLE" >&5
+printf %s "checking for FALLOC_FL_PUNCH_HOLE... " >&6; }
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -8819,25 +10732,26 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
         #endif
 
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 
-$as_echo "#define HAVE_FALLOC_FL_PUNCH_HOLE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_FALLOC_FL_PUNCH_HOLE 1" >>confdefs.h
 
 
-else
+else $as_nop
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 
 fi
 rm -f conftest.err conftest.i conftest.$ac_ext
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FALLOC_FL_ZERO_RANGE" >&5
-$as_echo_n "checking for FALLOC_FL_ZERO_RANGE... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for FALLOC_FL_ZERO_RANGE" >&5
+printf %s "checking for FALLOC_FL_ZERO_RANGE... " >&6; }
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -8848,170 +10762,182 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
         #endif
 
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 
-$as_echo "#define HAVE_FALLOC_FL_ZERO_RANGE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_FALLOC_FL_ZERO_RANGE 1" >>confdefs.h
 
 
-else
+else $as_nop
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 
 
 fi
 rm -f conftest.err conftest.i conftest.$ac_ext
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYS_fallocate" >&5
-$as_echo_n "checking for SYS_fallocate... " >&6; }
-if ${rsync_cv_have_sys_fallocate+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SYS_fallocate" >&5
+printf %s "checking for SYS_fallocate... " >&6; }
+if test ${rsync_cv_have_sys_fallocate+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/syscall.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 int
-main ()
+main (void)
 {
 syscall(SYS_fallocate, 0, 0, (loff_t)0, (loff_t)0);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   rsync_cv_have_sys_fallocate=yes
-else
+else $as_nop
   rsync_cv_have_sys_fallocate=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_have_sys_fallocate" >&5
-$as_echo "$rsync_cv_have_sys_fallocate" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_have_sys_fallocate" >&5
+printf "%s\n" "$rsync_cv_have_sys_fallocate" >&6; }
 if test x"$rsync_cv_have_sys_fallocate" = x"yes"; then
 
-$as_echo "#define HAVE_SYS_FALLOCATE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SYS_FALLOCATE 1" >>confdefs.h
 
 fi
 
 if test x"$ac_cv_func_posix_fallocate" = x"yes"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether posix_fallocate is efficient" >&5
-$as_echo_n "checking whether posix_fallocate is efficient... " >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether posix_fallocate is efficient" >&5
+printf %s "checking whether posix_fallocate is efficient... " >&6; }
     case $host_os in
     *cygwin*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 
-$as_echo "#define HAVE_EFFICIENT_POSIX_FALLOCATE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_EFFICIENT_POSIX_FALLOCATE 1" >>confdefs.h
 
        ;;
     *)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
        ;;
     esac
 fi
 
 
-for ac_func in getpgrp tcgetpgrp
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "getpgrp" "ac_cv_func_getpgrp"
+if test "x$ac_cv_func_getpgrp" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETPGRP 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "tcgetpgrp" "ac_cv_func_tcgetpgrp"
+if test "x$ac_cv_func_tcgetpgrp" = xyes
+then :
+  printf "%s\n" "#define HAVE_TCGETPGRP 1" >>confdefs.h
 
 fi
-done
 
 if test $ac_cv_func_getpgrp = yes; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether getpgrp requires zero arguments" >&5
-$as_echo_n "checking whether getpgrp requires zero arguments... " >&6; }
-if ${ac_cv_func_getpgrp_void+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether getpgrp requires zero arguments" >&5
+printf %s "checking whether getpgrp requires zero arguments... " >&6; }
+if test ${ac_cv_func_getpgrp_void+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   # Use it with a single arg.
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
 int
-main ()
+main (void)
 {
 getpgrp (0);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_func_getpgrp_void=no
-else
+else $as_nop
   ac_cv_func_getpgrp_void=yes
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpgrp_void" >&5
-$as_echo "$ac_cv_func_getpgrp_void" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpgrp_void" >&5
+printf "%s\n" "$ac_cv_func_getpgrp_void" >&6; }
 if test $ac_cv_func_getpgrp_void = yes; then
 
-$as_echo "#define GETPGRP_VOID 1" >>confdefs.h
+printf "%s\n" "#define GETPGRP_VOID 1" >>confdefs.h
 
 fi
 
 fi
 
 # Check whether --enable-iconv-open was given.
-if test "${enable_iconv_open+set}" = set; then :
+if test ${enable_iconv_open+y}
+then :
   enableval=$enable_iconv_open;
-else
+else $as_nop
   enable_iconv_open=$ac_cv_func_iconv_open
 fi
 
 
 if test x"$enable_iconv_open" != x"no"; then
 
-$as_echo "#define USE_ICONV_OPEN 1" >>confdefs.h
+printf "%s\n" "#define USE_ICONV_OPEN 1" >>confdefs.h
 
 fi
 
 # Check whether --enable-iconv was given.
-if test "${enable_iconv+set}" = set; then :
+if test ${enable_iconv+y}
+then :
   enableval=$enable_iconv;
-else
+else $as_nop
   enable_iconv=$enable_iconv_open
 fi
 
 
 if test x"$enable_iconv" != x"no"; then
        if test x"$enable_iconv" = x"yes"; then
-               $as_echo "#define ICONV_OPTION NULL" >>confdefs.h
+               printf "%s\n" "#define ICONV_OPTION NULL" >>confdefs.h
 
        else
-               cat >>confdefs.h <<_ACEOF
-#define ICONV_OPTION "$enable_iconv"
-_ACEOF
+               printf "%s\n" "#define ICONV_OPTION \"$enable_iconv\"" >>confdefs.h
 
        fi
 
-$as_echo "#define UTF8_CHARSET \"UTF-8\"" >>confdefs.h
+printf "%s\n" "#define UTF8_CHARSET \"UTF-8\"" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether chown() modifies symlinks" >&5
-$as_echo_n "checking whether chown() modifies symlinks... " >&6; }
-if ${rsync_cv_chown_modifies_symlink+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether chown() modifies symlinks" >&5
+printf %s "checking whether chown() modifies symlinks... " >&6; }
+if test ${rsync_cv_chown_modifies_symlink+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-  if test "$cross_compiling" = yes; then :
+  if test "$cross_compiling" = yes
+then :
   rsync_cv_chown_modifies_symlink=no
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -9028,9 +10954,10 @@ int main(void) {
        return 0;
     }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_chown_modifies_symlink=yes
-else
+else $as_nop
   rsync_cv_chown_modifies_symlink=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -9038,23 +10965,25 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_chown_modifies_symlink" >&5
-$as_echo "$rsync_cv_chown_modifies_symlink" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_chown_modifies_symlink" >&5
+printf "%s\n" "$rsync_cv_chown_modifies_symlink" >&6; }
 if test $rsync_cv_chown_modifies_symlink = yes; then
 
-$as_echo "#define CHOWN_MODIFIES_SYMLINK 1" >>confdefs.h
+printf "%s\n" "#define CHOWN_MODIFIES_SYMLINK 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether link() can hard-link symlinks" >&5
-$as_echo_n "checking whether link() can hard-link symlinks... " >&6; }
-if ${rsync_cv_can_hardlink_symlink+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether link() can hard-link symlinks" >&5
+printf %s "checking whether link() can hard-link symlinks... " >&6; }
+if test ${rsync_cv_can_hardlink_symlink+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-  if test "$cross_compiling" = yes; then :
+  if test "$cross_compiling" = yes
+then :
   rsync_cv_can_hardlink_symlink=no
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -9081,9 +11010,10 @@ int main(void) {
        return 0;
     }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_can_hardlink_symlink=yes
-else
+else $as_nop
   rsync_cv_can_hardlink_symlink=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -9091,23 +11021,25 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_can_hardlink_symlink" >&5
-$as_echo "$rsync_cv_can_hardlink_symlink" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_can_hardlink_symlink" >&5
+printf "%s\n" "$rsync_cv_can_hardlink_symlink" >&6; }
 if test $rsync_cv_can_hardlink_symlink = yes; then
 
-$as_echo "#define CAN_HARDLINK_SYMLINK 1" >>confdefs.h
+printf "%s\n" "#define CAN_HARDLINK_SYMLINK 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether link() can hard-link special files" >&5
-$as_echo_n "checking whether link() can hard-link special files... " >&6; }
-if ${rsync_cv_can_hardlink_special+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether link() can hard-link special files" >&5
+printf %s "checking whether link() can hard-link special files... " >&6; }
+if test ${rsync_cv_can_hardlink_special+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-  if test "$cross_compiling" = yes; then :
+  if test "$cross_compiling" = yes
+then :
   rsync_cv_can_hardlink_special=no
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -9128,9 +11060,10 @@ int main(void) {
        return 0;
     }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_can_hardlink_special=yes
-else
+else $as_nop
   rsync_cv_can_hardlink_special=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -9138,37 +11071,44 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_can_hardlink_special" >&5
-$as_echo "$rsync_cv_can_hardlink_special" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_can_hardlink_special" >&5
+printf "%s\n" "$rsync_cv_can_hardlink_special" >&6; }
 if test $rsync_cv_can_hardlink_special = yes; then
 
-$as_echo "#define CAN_HARDLINK_SPECIAL 1" >>confdefs.h
+printf "%s\n" "#define CAN_HARDLINK_SPECIAL 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working socketpair" >&5
-$as_echo_n "checking for working socketpair... " >&6; }
-if ${rsync_cv_HAVE_SOCKETPAIR+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working socketpair" >&5
+printf %s "checking for working socketpair... " >&6; }
+if test ${rsync_cv_HAVE_SOCKETPAIR+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = yes
+then :
   rsync_cv_HAVE_SOCKETPAIR=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
 
 int main(void) {
        int fd[2];
        return (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_HAVE_SOCKETPAIR=yes
-else
+else $as_nop
   rsync_cv_HAVE_SOCKETPAIR=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -9176,19 +11116,20 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_SOCKETPAIR" >&5
-$as_echo "$rsync_cv_HAVE_SOCKETPAIR" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_SOCKETPAIR" >&5
+printf "%s\n" "$rsync_cv_HAVE_SOCKETPAIR" >&6; }
 if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
 
-$as_echo "#define HAVE_SOCKETPAIR 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SOCKETPAIR 1" >>confdefs.h
 
 fi
 
 ac_fn_c_check_func "$LINENO" "getpass" "ac_cv_func_getpass"
-if test "x$ac_cv_func_getpass" = xyes; then :
-  $as_echo "#define HAVE_GETPASS 1" >>confdefs.h
+if test "x$ac_cv_func_getpass" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETPASS 1" >>confdefs.h
 
-else
+else $as_nop
   case " $LIBOBJS " in
   *" getpass.$ac_objext "* ) ;;
   *) LIBOBJS="$LIBOBJS getpass.$ac_objext"
@@ -9198,13 +11139,13 @@ esac
 fi
 
 
-
 if test x"$with_included_popt" != x"yes"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for poptGetContext in -lpopt" >&5
-$as_echo_n "checking for poptGetContext in -lpopt... " >&6; }
-if ${ac_cv_lib_popt_poptGetContext+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for poptGetContext in -lpopt" >&5
+printf %s "checking for poptGetContext in -lpopt... " >&6; }
+if test ${ac_cv_lib_popt_poptGetContext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lpopt  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -9213,37 +11154,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char poptGetContext ();
 int
-main ()
+main (void)
 {
 return poptGetContext ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_popt_poptGetContext=yes
-else
+else $as_nop
   ac_cv_lib_popt_poptGetContext=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_popt_poptGetContext" >&5
-$as_echo "$ac_cv_lib_popt_poptGetContext" >&6; }
-if test "x$ac_cv_lib_popt_poptGetContext" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBPOPT 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_popt_poptGetContext" >&5
+printf "%s\n" "$ac_cv_lib_popt_poptGetContext" >&6; }
+if test "x$ac_cv_lib_popt_poptGetContext" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBPOPT 1" >>confdefs.h
 
   LIBS="-lpopt $LIBS"
 
-else
+else $as_nop
   with_included_popt=yes
 fi
 
@@ -9258,23 +11196,23 @@ elif test x"$ac_cv_header_popt_h" != x"yes"; then
     with_included_popt=yes
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use included libpopt" >&5
-$as_echo_n "checking whether to use included libpopt... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use included libpopt" >&5
+printf %s "checking whether to use included libpopt... " >&6; }
 if test x"$with_included_popt" = x"yes"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $srcdir/popt" >&5
-$as_echo "$srcdir/popt" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $srcdir/popt" >&5
+printf "%s\n" "$srcdir/popt" >&6; }
     BUILD_POPT='$(popt_OBJS)'
     CFLAGS="-I$srcdir/popt $CFLAGS"
     if test x"$ALLOCA" != x
     then
        # this can be removed when/if we add an included alloca.c;
        #  see autoconf documentation on AC_FUNC_ALLOCA
-       { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: included libpopt will use malloc, not alloca (which wastes a small amount of memory)" >&5
-$as_echo "$as_me: WARNING: included libpopt will use malloc, not alloca (which wastes a small amount of memory)" >&2;}
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: included libpopt will use malloc, not alloca (which wastes a small amount of memory)" >&5
+printf "%s\n" "$as_me: WARNING: included libpopt will use malloc, not alloca (which wastes a small amount of memory)" >&2;}
     fi
 else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 # We default to using our zlib unless --with-included-zlib=no is given.
@@ -9284,11 +11222,12 @@ elif test x"$ac_cv_header_zlib_h" != x"yes"; then
     with_included_zlib=yes
 fi
 if test x"$with_included_zlib" != x"yes"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflateParams in -lz" >&5
-$as_echo_n "checking for deflateParams in -lz... " >&6; }
-if ${ac_cv_lib_z_deflateParams+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for deflateParams in -lz" >&5
+printf %s "checking for deflateParams in -lz... " >&6; }
+if test ${ac_cv_lib_z_deflateParams+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lz  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -9297,109 +11236,114 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char deflateParams ();
 int
-main ()
+main (void)
 {
 return deflateParams ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_z_deflateParams=yes
-else
+else $as_nop
   ac_cv_lib_z_deflateParams=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflateParams" >&5
-$as_echo "$ac_cv_lib_z_deflateParams" >&6; }
-if test "x$ac_cv_lib_z_deflateParams" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBZ 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflateParams" >&5
+printf "%s\n" "$ac_cv_lib_z_deflateParams" >&6; }
+if test "x$ac_cv_lib_z_deflateParams" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBZ 1" >>confdefs.h
 
   LIBS="-lz $LIBS"
 
-else
+else $as_nop
   with_included_zlib=yes
 fi
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use included zlib" >&5
-$as_echo_n "checking whether to use included zlib... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use included zlib" >&5
+printf %s "checking whether to use included zlib... " >&6; }
 if test x"$with_included_zlib" = x"yes"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $srcdir/zlib" >&5
-$as_echo "$srcdir/zlib" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $srcdir/zlib" >&5
+printf "%s\n" "$srcdir/zlib" >&6; }
     BUILD_ZLIB='$(zlib_OBJS)'
     CFLAGS="-I$srcdir/zlib $CFLAGS"
 else
 
-$as_echo "#define EXTERNAL_ZLIB 1" >>confdefs.h
+printf "%s\n" "#define EXTERNAL_ZLIB 1" >>confdefs.h
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned char" >&5
-$as_echo_n "checking for unsigned char... " >&6; }
-if ${rsync_cv_SIGNED_CHAR_OK+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for unsigned char" >&5
+printf %s "checking for unsigned char... " >&6; }
+if test ${rsync_cv_SIGNED_CHAR_OK+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
-signed char *s = ""
+signed char *s = (signed char *)""
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   rsync_cv_SIGNED_CHAR_OK=yes
-else
+else $as_nop
   rsync_cv_SIGNED_CHAR_OK=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_SIGNED_CHAR_OK" >&5
-$as_echo "$rsync_cv_SIGNED_CHAR_OK" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_SIGNED_CHAR_OK" >&5
+printf "%s\n" "$rsync_cv_SIGNED_CHAR_OK" >&6; }
 if test x"$rsync_cv_SIGNED_CHAR_OK" = x"yes"; then
 
-$as_echo "#define SIGNED_CHAR_OK 1" >>confdefs.h
+printf "%s\n" "#define SIGNED_CHAR_OK 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken readdir" >&5
-$as_echo_n "checking for broken readdir... " >&6; }
-if ${rsync_cv_HAVE_BROKEN_READDIR+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken readdir" >&5
+printf %s "checking for broken readdir... " >&6; }
+if test ${rsync_cv_HAVE_BROKEN_READDIR+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = yes
+then :
   rsync_cv_HAVE_BROKEN_READDIR=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 #include <dirent.h>
 int main(void) { struct dirent *di; DIR *d = opendir("."); di = readdir(d);
 if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 &&
 di->d_name[0] == 0) return 0; return 1;}
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_HAVE_BROKEN_READDIR=yes
-else
+else $as_nop
   rsync_cv_HAVE_BROKEN_READDIR=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -9407,96 +11351,111 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_BROKEN_READDIR" >&5
-$as_echo "$rsync_cv_HAVE_BROKEN_READDIR" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_BROKEN_READDIR" >&5
+printf "%s\n" "$rsync_cv_HAVE_BROKEN_READDIR" >&6; }
 if test x"$rsync_cv_HAVE_BROKEN_READDIR" = x"yes"; then
 
-$as_echo "#define HAVE_BROKEN_READDIR 1" >>confdefs.h
+printf "%s\n" "#define HAVE_BROKEN_READDIR 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for utimbuf" >&5
-$as_echo_n "checking for utimbuf... " >&6; }
-if ${rsync_cv_HAVE_STRUCT_UTIMBUF+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for utimbuf" >&5
+printf %s "checking for utimbuf... " >&6; }
+if test ${rsync_cv_HAVE_STRUCT_UTIMBUF+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 #include <utime.h>
 int
-main ()
+main (void)
 {
 struct utimbuf tbuf;  tbuf.actime = 0; tbuf.modtime = 1; return utime("foo.c",&tbuf);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   rsync_cv_HAVE_STRUCT_UTIMBUF=yes
-else
+else $as_nop
   rsync_cv_HAVE_STRUCT_UTIMBUF=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_STRUCT_UTIMBUF" >&5
-$as_echo "$rsync_cv_HAVE_STRUCT_UTIMBUF" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_STRUCT_UTIMBUF" >&5
+printf "%s\n" "$rsync_cv_HAVE_STRUCT_UTIMBUF" >&6; }
 if test x"$rsync_cv_HAVE_STRUCT_UTIMBUF" = x"yes"; then
 
-$as_echo "#define HAVE_STRUCT_UTIMBUF 1" >>confdefs.h
+printf "%s\n" "#define HAVE_STRUCT_UTIMBUF 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if gettimeofday takes tz argument" >&5
-$as_echo_n "checking if gettimeofday takes tz argument... " >&6; }
-if ${rsync_cv_HAVE_GETTIMEOFDAY_TZ+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if gettimeofday takes tz argument" >&5
+printf %s "checking if gettimeofday takes tz argument... " >&6; }
+if test ${rsync_cv_HAVE_GETTIMEOFDAY_TZ+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/time.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 int
-main ()
+main (void)
 {
 struct timeval tv; return gettimeofday(&tv, NULL);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   rsync_cv_HAVE_GETTIMEOFDAY_TZ=yes
-else
+else $as_nop
   rsync_cv_HAVE_GETTIMEOFDAY_TZ=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_GETTIMEOFDAY_TZ" >&5
-$as_echo "$rsync_cv_HAVE_GETTIMEOFDAY_TZ" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_GETTIMEOFDAY_TZ" >&5
+printf "%s\n" "$rsync_cv_HAVE_GETTIMEOFDAY_TZ" >&6; }
 if test x"$rsync_cv_HAVE_GETTIMEOFDAY_TZ" != x"no"; then
 
-$as_echo "#define HAVE_GETTIMEOFDAY_TZ 1" >>confdefs.h
+printf "%s\n" "#define HAVE_GETTIMEOFDAY_TZ 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C99 vsnprintf" >&5
-$as_echo_n "checking for C99 vsnprintf... " >&6; }
-if ${rsync_cv_HAVE_C99_VSNPRINTF+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C99 vsnprintf" >&5
+printf %s "checking for C99 vsnprintf... " >&6; }
+if test ${rsync_cv_HAVE_C99_VSNPRINTF+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = yes
+then :
   rsync_cv_HAVE_C99_VSNPRINTF=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 #include <stdarg.h>
 #include <stdio.h>
+#if HAVE_STDLIB_H
 #include <stdlib.h>
+#endif
 #include <string.h>
 void foo(const char *format, ...) {
        va_list ap;
@@ -9513,9 +11472,10 @@ void foo(const char *format, ...) {
 int main(void) { foo("hello"); return 0; }
 
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_HAVE_C99_VSNPRINTF=yes
-else
+else $as_nop
   rsync_cv_HAVE_C99_VSNPRINTF=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -9523,30 +11483,36 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_C99_VSNPRINTF" >&5
-$as_echo "$rsync_cv_HAVE_C99_VSNPRINTF" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_C99_VSNPRINTF" >&5
+printf "%s\n" "$rsync_cv_HAVE_C99_VSNPRINTF" >&6; }
 if test x"$rsync_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
 
-$as_echo "#define HAVE_C99_VSNPRINTF 1" >>confdefs.h
+printf "%s\n" "#define HAVE_C99_VSNPRINTF 1" >>confdefs.h
 
 fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for secure mkstemp" >&5
-$as_echo_n "checking for secure mkstemp... " >&6; }
-if ${rsync_cv_HAVE_SECURE_MKSTEMP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for secure mkstemp" >&5
+printf %s "checking for secure mkstemp... " >&6; }
+if test ${rsync_cv_HAVE_SECURE_MKSTEMP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = yes
+then :
   rsync_cv_HAVE_SECURE_MKSTEMP=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdlib.h>
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
 #include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 int main(void) {
   struct stat st;
   char tpl[20]="/tmp/test.XXXXXX";
@@ -9558,9 +11524,10 @@ int main(void) {
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_HAVE_SECURE_MKSTEMP=yes
-else
+else $as_nop
   rsync_cv_HAVE_SECURE_MKSTEMP=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -9568,32 +11535,34 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_SECURE_MKSTEMP" >&5
-$as_echo "$rsync_cv_HAVE_SECURE_MKSTEMP" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_HAVE_SECURE_MKSTEMP" >&5
+printf "%s\n" "$rsync_cv_HAVE_SECURE_MKSTEMP" >&6; }
 if test x"$rsync_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then
     case $host_os in
     hpux*)
-                               { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Skipping broken HP-UX mkstemp() -- using mktemp() instead" >&5
-$as_echo "$as_me: WARNING: Skipping broken HP-UX mkstemp() -- using mktemp() instead" >&2;}
+                               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Skipping broken HP-UX mkstemp() -- using mktemp() instead" >&5
+printf "%s\n" "$as_me: WARNING: Skipping broken HP-UX mkstemp() -- using mktemp() instead" >&2;}
        ;;
     *)
 
-$as_echo "#define HAVE_SECURE_MKSTEMP 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SECURE_MKSTEMP 1" >>confdefs.h
 
        ;;
     esac
 fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if mknod creates FIFOs" >&5
-$as_echo_n "checking if mknod creates FIFOs... " >&6; }
-if ${rsync_cv_MKNOD_CREATES_FIFOS+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if mknod creates FIFOs" >&5
+printf %s "checking if mknod creates FIFOs... " >&6; }
+if test ${rsync_cv_MKNOD_CREATES_FIFOS+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = yes
+then :
   rsync_cv_MKNOD_CREATES_FIFOS=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -9608,9 +11577,10 @@ unlink(fn); rc = mknod(fn,S_IFIFO,0600); ec = errno; unlink(fn);
 if (rc) {printf("(%d %d) ",rc,ec); return ec;}
 return 0;}
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_MKNOD_CREATES_FIFOS=yes
-else
+else $as_nop
   rsync_cv_MKNOD_CREATES_FIFOS=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -9618,23 +11588,25 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_MKNOD_CREATES_FIFOS" >&5
-$as_echo "$rsync_cv_MKNOD_CREATES_FIFOS" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_MKNOD_CREATES_FIFOS" >&5
+printf "%s\n" "$rsync_cv_MKNOD_CREATES_FIFOS" >&6; }
 if test x"$rsync_cv_MKNOD_CREATES_FIFOS" = x"yes"; then
 
-$as_echo "#define MKNOD_CREATES_FIFOS 1" >>confdefs.h
+printf "%s\n" "#define MKNOD_CREATES_FIFOS 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if mknod creates sockets" >&5
-$as_echo_n "checking if mknod creates sockets... " >&6; }
-if ${rsync_cv_MKNOD_CREATES_SOCKETS+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if mknod creates sockets" >&5
+printf %s "checking if mknod creates sockets... " >&6; }
+if test ${rsync_cv_MKNOD_CREATES_SOCKETS+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = yes
+then :
   rsync_cv_MKNOD_CREATES_SOCKETS=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -9649,9 +11621,10 @@ unlink(fn); rc = mknod(fn,S_IFSOCK,0600); ec = errno; unlink(fn);
 if (rc) {printf("(%d %d) ",rc,ec); return ec;}
 return 0;}
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   rsync_cv_MKNOD_CREATES_SOCKETS=yes
-else
+else $as_nop
   rsync_cv_MKNOD_CREATES_SOCKETS=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -9659,22 +11632,23 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_MKNOD_CREATES_SOCKETS" >&5
-$as_echo "$rsync_cv_MKNOD_CREATES_SOCKETS" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_MKNOD_CREATES_SOCKETS" >&5
+printf "%s\n" "$rsync_cv_MKNOD_CREATES_SOCKETS" >&6; }
 if test x"$rsync_cv_MKNOD_CREATES_SOCKETS" = x"yes"; then
 
-$as_echo "#define MKNOD_CREATES_SOCKETS 1" >>confdefs.h
+printf "%s\n" "#define MKNOD_CREATES_SOCKETS 1" >>confdefs.h
 
 fi
 
 #
 # The following test was mostly taken from the tcl/tk plus patches
 #
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -c -o works" >&5
-$as_echo_n "checking whether -c -o works... " >&6; }
-if ${rsync_cv_DASHC_WORKS_WITH_DASHO+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -c -o works" >&5
+printf %s "checking whether -c -o works... " >&6; }
+if test ${rsync_cv_DASHC_WORKS_WITH_DASHO+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
 rm -rf conftest*
 cat > conftest.$ac_ext <<EOF
@@ -9689,8 +11663,8 @@ fi
 rm -rf conftest*
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_DASHC_WORKS_WITH_DASHO" >&5
-$as_echo "$rsync_cv_DASHC_WORKS_WITH_DASHO" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_cv_DASHC_WORKS_WITH_DASHO" >&5
+printf "%s\n" "$rsync_cv_DASHC_WORKS_WITH_DASHO" >&6; }
 if test x"$rsync_cv_DASHC_WORKS_WITH_DASHO" = x"yes"; then
     OBJ_SAVE="#"
     OBJ_RESTORE="#"
 
 
 
-for ac_func in _acl __acl _facl __facl
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+
+
+
+ac_fn_c_check_func "$LINENO" "_acl" "ac_cv_func__acl"
+if test "x$ac_cv_func__acl" = xyes
+then :
+  printf "%s\n" "#define HAVE__ACL 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "__acl" "ac_cv_func___acl"
+if test "x$ac_cv_func___acl" = xyes
+then :
+  printf "%s\n" "#define HAVE___ACL 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "_facl" "ac_cv_func__facl"
+if test "x$ac_cv_func__facl" = xyes
+then :
+  printf "%s\n" "#define HAVE__FACL 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "__facl" "ac_cv_func___facl"
+if test "x$ac_cv_func___facl" = xyes
+then :
+  printf "%s\n" "#define HAVE___FACL 1" >>confdefs.h
 
 fi
-done
 
 #################################################
 # check for ACL support
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support ACLs" >&5
-$as_echo_n "checking whether to support ACLs... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to support ACLs" >&5
+printf %s "checking whether to support ACLs... " >&6; }
 # Check whether --enable-acl-support was given.
-if test "${enable_acl_support+set}" = set; then :
+if test ${enable_acl_support+y}
+then :
   enableval=$enable_acl_support;
 fi
 
 
 if test x"$enable_acl_support" = x"no"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 else
     case "$host_os" in
     *sysv5*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using UnixWare ACLs" >&5
-$as_echo "Using UnixWare ACLs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using UnixWare ACLs" >&5
+printf "%s\n" "Using UnixWare ACLs" >&6; }
 
-$as_echo "#define HAVE_UNIXWARE_ACLS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_UNIXWARE_ACLS 1" >>confdefs.h
 
 
-$as_echo "#define SUPPORT_ACLS 1" >>confdefs.h
+printf "%s\n" "#define SUPPORT_ACLS 1" >>confdefs.h
 
        ;;
     solaris*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using solaris ACLs" >&5
-$as_echo "Using solaris ACLs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using solaris ACLs" >&5
+printf "%s\n" "Using solaris ACLs" >&6; }
 
-$as_echo "#define HAVE_SOLARIS_ACLS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SOLARIS_ACLS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_ACLS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_ACLS 1" >>confdefs.h
 
        ;;
     *irix*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using IRIX ACLs" >&5
-$as_echo "Using IRIX ACLs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using IRIX ACLs" >&5
+printf "%s\n" "Using IRIX ACLs" >&6; }
 
-$as_echo "#define HAVE_IRIX_ACLS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_IRIX_ACLS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_ACLS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_ACLS 1" >>confdefs.h
 
        ;;
     *aix*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using AIX ACLs" >&5
-$as_echo "Using AIX ACLs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using AIX ACLs" >&5
+printf "%s\n" "Using AIX ACLs" >&6; }
 
-$as_echo "#define HAVE_AIX_ACLS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_AIX_ACLS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_ACLS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_ACLS 1" >>confdefs.h
 
        ;;
     *osf*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using Tru64 ACLs" >&5
-$as_echo "Using Tru64 ACLs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using Tru64 ACLs" >&5
+printf "%s\n" "Using Tru64 ACLs" >&6; }
 
-$as_echo "#define HAVE_TRU64_ACLS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_TRU64_ACLS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_ACLS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_ACLS 1" >>confdefs.h
 
        LIBS="$LIBS -lpacl"
        ;;
     darwin*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using OS X ACLs" >&5
-$as_echo "Using OS X ACLs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using OS X ACLs" >&5
+printf "%s\n" "Using OS X ACLs" >&6; }
 
-$as_echo "#define HAVE_OSX_ACLS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_OSX_ACLS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_ACLS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_ACLS 1" >>confdefs.h
 
        ;;
     *hpux*|*nsk*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using HPUX ACLs" >&5
-$as_echo "Using HPUX ACLs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using HPUX ACLs" >&5
+printf "%s\n" "Using HPUX ACLs" >&6; }
 
-$as_echo "#define HAVE_HPUX_ACLS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_HPUX_ACLS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_ACLS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_ACLS 1" >>confdefs.h
 
        ;;
     *)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: running tests:" >&5
-$as_echo "running tests:" >&6; }
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acl_get_file in -lacl" >&5
-$as_echo_n "checking for acl_get_file in -lacl... " >&6; }
-if ${ac_cv_lib_acl_acl_get_file+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: running tests:" >&5
+printf "%s\n" "running tests:" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for acl_get_file in -lacl" >&5
+printf %s "checking for acl_get_file in -lacl... " >&6; }
+if test ${ac_cv_lib_acl_acl_get_file+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lacl  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -9817,115 +11809,126 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char acl_get_file ();
 int
-main ()
+main (void)
 {
 return acl_get_file ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_acl_acl_get_file=yes
-else
+else $as_nop
   ac_cv_lib_acl_acl_get_file=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_acl_acl_get_file" >&5
-$as_echo "$ac_cv_lib_acl_acl_get_file" >&6; }
-if test "x$ac_cv_lib_acl_acl_get_file" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBACL 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_acl_acl_get_file" >&5
+printf "%s\n" "$ac_cv_lib_acl_acl_get_file" >&6; }
+if test "x$ac_cv_lib_acl_acl_get_file" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBACL 1" >>confdefs.h
 
   LIBS="-lacl $LIBS"
 
 fi
 
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ACL support" >&5
-$as_echo_n "checking for ACL support... " >&6; }
-if ${samba_cv_HAVE_POSIX_ACLS+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ACL support" >&5
+printf %s "checking for ACL support... " >&6; }
+if test ${samba_cv_HAVE_POSIX_ACLS+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
 #include <sys/acl.h>
+#endif
 int
-main ()
+main (void)
 {
  acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   samba_cv_HAVE_POSIX_ACLS=yes
-else
+else $as_nop
   samba_cv_HAVE_POSIX_ACLS=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $samba_cv_HAVE_POSIX_ACLS" >&5
-$as_echo "$samba_cv_HAVE_POSIX_ACLS" >&6; }
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking ACL test results" >&5
-$as_echo_n "checking ACL test results... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $samba_cv_HAVE_POSIX_ACLS" >&5
+printf "%s\n" "$samba_cv_HAVE_POSIX_ACLS" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ACL test results" >&5
+printf %s "checking ACL test results... " >&6; }
        if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then
-           { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using posix ACLs" >&5
-$as_echo "Using posix ACLs" >&6; }
+           { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using posix ACLs" >&5
+printf "%s\n" "Using posix ACLs" >&6; }
 
-$as_echo "#define HAVE_POSIX_ACLS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_POSIX_ACLS 1" >>confdefs.h
 
-           $as_echo "#define SUPPORT_ACLS 1" >>confdefs.h
+           printf "%s\n" "#define SUPPORT_ACLS 1" >>confdefs.h
 
-           { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acl_get_perm_np" >&5
-$as_echo_n "checking for acl_get_perm_np... " >&6; }
-if ${samba_cv_HAVE_ACL_GET_PERM_NP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+           { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for acl_get_perm_np" >&5
+printf %s "checking for acl_get_perm_np... " >&6; }
+if test ${samba_cv_HAVE_ACL_GET_PERM_NP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+
+#ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
 #include <sys/acl.h>
+#endif
 int
-main ()
+main (void)
 {
  acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm);
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   samba_cv_HAVE_ACL_GET_PERM_NP=yes
-else
+else $as_nop
   samba_cv_HAVE_ACL_GET_PERM_NP=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $samba_cv_HAVE_ACL_GET_PERM_NP" >&5
-$as_echo "$samba_cv_HAVE_ACL_GET_PERM_NP" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $samba_cv_HAVE_ACL_GET_PERM_NP" >&5
+printf "%s\n" "$samba_cv_HAVE_ACL_GET_PERM_NP" >&6; }
            if test x"$samba_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
 
-$as_echo "#define HAVE_ACL_GET_PERM_NP 1" >>confdefs.h
+printf "%s\n" "#define HAVE_ACL_GET_PERM_NP 1" >>confdefs.h
 
            fi
        else
            if test x"$enable_acl_support" = x"yes"; then
                as_fn_error $? "Failed to find ACL support" "$LINENO" 5
            else
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: No ACL support found" >&5
-$as_echo "No ACL support found" >&6; }
+               { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No ACL support found" >&5
+printf "%s\n" "No ACL support found" >&6; }
            fi
        fi
        ;;
 
 #################################################
 # check for extended attribute support
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support extended attributes" >&5
-$as_echo_n "checking whether to support extended attributes... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to support extended attributes" >&5
+printf %s "checking whether to support extended attributes... " >&6; }
 # Check whether --enable-xattr-support was given.
-if test "${enable_xattr_support+set}" = set; then :
+if test ${enable_xattr_support+y}
+then :
   enableval=$enable_xattr_support;
-else
+else $as_nop
   case "$ac_cv_func_getxattr$ac_cv_func_extattr_get_link$ac_cv_func_attropen" in
        *yes*) enable_xattr_support=maybe ;;
        *) enable_xattr_support=no ;;
 
 
 if test x"$enable_xattr_support" = x"no"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 else
     case "$host_os" in
     *linux*|*netbsd*|*cygwin*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using Linux xattrs" >&5
-$as_echo "Using Linux xattrs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using Linux xattrs" >&5
+printf "%s\n" "Using Linux xattrs" >&6; }
 
-$as_echo "#define HAVE_LINUX_XATTRS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_LINUX_XATTRS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_XATTRS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_XATTRS 1" >>confdefs.h
 
 
-$as_echo "#define NO_SYMLINK_USER_XATTRS 1" >>confdefs.h
+printf "%s\n" "#define NO_SYMLINK_USER_XATTRS 1" >>confdefs.h
 
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getxattr in -lattr" >&5
-$as_echo_n "checking for getxattr in -lattr... " >&6; }
-if ${ac_cv_lib_attr_getxattr+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getxattr in -lattr" >&5
+printf %s "checking for getxattr in -lattr... " >&6; }
+if test ${ac_cv_lib_attr_getxattr+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lattr  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -9976,33 +11981,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char getxattr ();
 int
-main ()
+main (void)
 {
 return getxattr ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_attr_getxattr=yes
-else
+else $as_nop
   ac_cv_lib_attr_getxattr=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_attr_getxattr" >&5
-$as_echo "$ac_cv_lib_attr_getxattr" >&6; }
-if test "x$ac_cv_lib_attr_getxattr" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBATTR 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_attr_getxattr" >&5
+printf "%s\n" "$ac_cv_lib_attr_getxattr" >&6; }
+if test "x$ac_cv_lib_attr_getxattr" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBATTR 1" >>confdefs.h
 
   LIBS="-lattr $LIBS"
 
 
        ;;
     darwin*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using OS X xattrs" >&5
-$as_echo "Using OS X xattrs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using OS X xattrs" >&5
+printf "%s\n" "Using OS X xattrs" >&6; }
 
-$as_echo "#define HAVE_OSX_XATTRS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_OSX_XATTRS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_XATTRS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_XATTRS 1" >>confdefs.h
 
 
-$as_echo "#define NO_DEVICE_XATTRS 1" >>confdefs.h
+printf "%s\n" "#define NO_DEVICE_XATTRS 1" >>confdefs.h
 
 
-$as_echo "#define NO_SPECIAL_XATTRS 1" >>confdefs.h
+printf "%s\n" "#define NO_SPECIAL_XATTRS 1" >>confdefs.h
 
        ;;
     freebsd*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using FreeBSD extattrs" >&5
-$as_echo "Using FreeBSD extattrs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using FreeBSD extattrs" >&5
+printf "%s\n" "Using FreeBSD extattrs" >&6; }
 
-$as_echo "#define HAVE_FREEBSD_XATTRS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_FREEBSD_XATTRS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_XATTRS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_XATTRS 1" >>confdefs.h
 
        ;;
     solaris*)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using Solaris xattrs" >&5
-$as_echo "Using Solaris xattrs" >&6; }
+       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using Solaris xattrs" >&5
+printf "%s\n" "Using Solaris xattrs" >&6; }
 
-$as_echo "#define HAVE_SOLARIS_XATTRS 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SOLARIS_XATTRS 1" >>confdefs.h
 
-       $as_echo "#define SUPPORT_XATTRS 1" >>confdefs.h
+       printf "%s\n" "#define SUPPORT_XATTRS 1" >>confdefs.h
 
 
-$as_echo "#define NO_SYMLINK_XATTRS 1" >>confdefs.h
+printf "%s\n" "#define NO_SYMLINK_XATTRS 1" >>confdefs.h
 
        ;;
     *)
        if test x"$enable_xattr_support" = x"yes"; then
            as_fn_error $? "Failed to find extended attribute support" "$LINENO" 5
        else
-           { $as_echo "$as_me:${as_lineno-$LINENO}: result: No extended attribute support found" >&5
-$as_echo "No extended attribute support found" >&6; }
+           { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: No extended attribute support found" >&5
+printf "%s\n" "No extended attribute support found" >&6; }
        fi
        ;;
     esac
 fi
 
-if test x"$enable_acl_support" = x"no" -o x"$enable_xattr_support" = x"no" -o x"$enable_iconv" = x"no"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wno-unused-parameter" >&5
-$as_echo_n "checking whether $CC supports -Wno-unused-parameter... " >&6; }
+if test x"$enable_acl_support" = x"no" || test x"$enable_xattr_support" = x"no" || test x"$enable_iconv" = x"no"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wno-unused-parameter" >&5
+printf %s "checking whether $CC supports -Wno-unused-parameter... " >&6; }
     OLD_CFLAGS="$CFLAGS"
     CFLAGS="$CFLAGS -Wno-unused-parameter"
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdio.h>
 int
-main ()
+main (void)
 {
 printf("hello\n");
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   rsync_warn_flag=yes
-else
+else $as_nop
   rsync_warn_flag=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rsync_warn_flag" >&5
-$as_echo "$rsync_warn_flag" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $rsync_warn_flag" >&5
+printf "%s\n" "$rsync_warn_flag" >&6; }
     if test x"$rsync_warn_flag" = x"no"; then
        CFLAGS="$OLD_CFLAGS"
     fi
@@ -10089,7 +12092,7 @@ fi
 case "$CC" in
 ' checker'*|checker*)
 
-$as_echo "#define FORCE_FD_ZERO_MEMSET 1" >>confdefs.h
+printf "%s\n" "#define FORCE_FD_ZERO_MEMSET 1" >>confdefs.h
 
     ;;
 esac
@@ -10123,8 +12126,8 @@ _ACEOF
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
@@ -10154,15 +12157,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      /^ac_cv_env_/b end
      t clear
      :clear
-     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
      t end
      s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
     if test "x$cache_file" != "x/dev/null"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
       if test ! -f "$cache_file" || test -h "$cache_file"; then
        cat confcache >"$cache_file"
       else
@@ -10176,8 +12179,8 @@ $as_echo "$as_me: updating cache $cache_file" >&6;}
       fi
     fi
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
   fi
 fi
 rm -f confcache
@@ -10194,7 +12197,7 @@ U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
   # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
   #    will be set to the directory where LIBOBJS objects are built.
   as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
@@ -10211,8 +12214,8 @@ LTLIBOBJS=$ac_ltlibobjs
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
 as_write_fail=0
 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
 #! $SHELL
@@ -10235,14 +12238,16 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
-else
+else $as_nop
   case `(set -o) 2>/dev/null` in #(
   *posix*) :
     set -o posix ;; #(
@@ -10252,46 +12257,46 @@ esac
 fi
 
 
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
 as_nl='
 '
 export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-       expr "X$arg" : "X\\(.*\\)$as_nl";
-       arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
+IFS=" ""       $as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
 
 # The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
+if ${PATH_SEPARATOR+false} :; then
   PATH_SEPARATOR=:
   (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
     (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -10300,13 +12305,6 @@ if test "${PATH_SEPARATOR+set}" != set; then
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""       $as_nl"
-
 # Find who we are.  Look in the path if we contain no directory separator.
 as_myself=
 case $0 in #((
@@ -10315,8 +12313,12 @@ case $0 in #((
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
   done
 IFS=$as_save_IFS
 
@@ -10328,30 +12330,10 @@ if test "x$as_myself" = x; then
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
   exit 1
 fi
 
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 
 # as_fn_error STATUS ERROR [LINENO LOG_FD]
@@ -10364,13 +12346,14 @@ as_fn_error ()
   as_status=$1; test $as_status -eq 0 && as_status=1
   if test "$4"; then
     as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $2" >&2
+  printf "%s\n" "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
 
+
 # as_fn_set_status STATUS
 # -----------------------
 # Set $? to STATUS, without forking.
@@ -10397,18 +12380,20 @@ as_fn_unset ()
   { eval $1=; unset $1;}
 }
 as_unset=as_fn_unset
+
 # as_fn_append VAR VALUE
 # ----------------------
 # Append the text in VALUE to the end of the definition contained in VAR. Take
 # advantage of any shell optimizations that allow amortized linear growth over
 # repeated appends, instead of the typical quadratic growth present in naive
 # implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
   eval 'as_fn_append ()
   {
     eval $1+=\$2
   }'
-else
+else $as_nop
   as_fn_append ()
   {
     eval $1=\$$1\$2
@@ -10420,12 +12405,13 @@ fi # as_fn_append
 # Perform arithmetic evaluation on the ARGs, and store the result in the
 # global $as_val. Take advantage of shells that can avoid forks. The arguments
 # must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
   eval 'as_fn_arith ()
   {
     as_val=$(( $* ))
   }'
-else
+else $as_nop
   as_fn_arith ()
   {
     as_val=`expr "$@" || test $? -eq 1`
@@ -10456,7 +12442,7 @@ as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
         X"$0" : 'X\(//\)$' \| \
         X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
+printf "%s\n" X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
            s//\1/
            q
@@ -10478,6 +12464,10 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS
 as_cr_digits='0123456789'
 as_cr_alnum=$as_cr_Letters$as_cr_digits
 
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
 ECHO_C= ECHO_N= ECHO_T=
 case `echo -n x` in #(((((
 -n*)
@@ -10491,6 +12481,12 @@ case `echo -n x` in #(((((
   ECHO_N='-n';;
 esac
 
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
@@ -10532,7 +12528,7 @@ as_fn_mkdir_p ()
     as_dirs=
     while :; do
       case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
       *) as_qdir=$as_dir;;
       esac
       as_dirs="'$as_qdir' $as_dirs"
@@ -10541,7 +12537,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$as_dir" : 'X\(//\)[^/]' \| \
         X"$as_dir" : 'X\(//\)$' \| \
         X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
+printf "%s\n" X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -10603,8 +12599,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by rsync $as_me  , which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+This file was extended by rsync $as_me, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -10662,14 +12658,16 @@ $config_headers
 Report bugs to <https://rsync.samba.org/bug-tracking.html>."
 
 _ACEOF
+ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
+ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
 rsync config.status
-configured by $0, generated by GNU Autoconf 2.69,
+configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
   --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    $as_echo "$ac_cs_version"; exit ;;
+    printf "%s\n" "$ac_cs_version"; exit ;;
   --config | --confi | --conf | --con | --co | --c )
-    $as_echo "$ac_cs_config"; exit ;;
+    printf "%s\n" "$ac_cs_config"; exit ;;
   --debug | --debu | --deb | --de | --d | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
     case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
     '') as_fn_error $? "missing file argument" ;;
     esac
     as_fn_append CONFIG_FILES " '$ac_optarg'"
@@ -10725,7 +12723,7 @@ do
   --header | --heade | --head | --hea )
     $ac_shift
     case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     as_fn_append CONFIG_HEADERS " '$ac_optarg'"
     ac_need_defaults=false;;
@@ -10734,7 +12732,7 @@ do
     as_fn_error $? "ambiguous option: \`$1'
 Try \`$0 --help' for more information.";;
   --help | --hel | -h )
-    $as_echo "$ac_cs_usage"; exit ;;
+    printf "%s\n" "$ac_cs_usage"; exit ;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
@@ -10762,7 +12760,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
   set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
   shift
-  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
   CONFIG_SHELL='$SHELL'
   export CONFIG_SHELL
   exec "\$@"
@@ -10776,7 +12774,7 @@ exec 5>>config.log
   sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
 ## Running $as_me. ##
 _ASBOX
-  $as_echo "$ac_log"
+  printf "%s\n" "$ac_log"
 } >&5
 
 _ACEOF
@@ -10806,8 +12804,8 @@ done
 # We use the long form for the default assignment because of an extremely
 # bizarre bug on SunOS 4.1.3.
 if $ac_need_defaults; then
-  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
-  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files
+  test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
@@ -11143,7 +13141,7 @@ do
           esac ||
           as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
-      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
       as_fn_append ac_file_inputs " '$ac_f'"
     done
 
     # use $as_me), people would be surprised to read:
     #    /* config.h.  Generated by config.status.  */
     configure_input='Generated from '`
-         $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+         printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
        `' by configure.'
     if test x"$ac_file" != x-; then
       configure_input="$ac_file.  $configure_input"
-      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+printf "%s\n" "$as_me: creating $ac_file" >&6;}
     fi
     # Neutralize special characters interpreted by sed in replacement strings.
     case $configure_input in #(
     *\&* | *\|* | *\\* )
-       ac_sed_conf_input=`$as_echo "$configure_input" |
+       ac_sed_conf_input=`printf "%s\n" "$configure_input" |
        sed 's/[\\\\&|]/\\\\&/g'`;; #(
     *) ac_sed_conf_input=$configure_input;;
     esac
@@ -11178,7 +13176,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$ac_file" : 'X\(//\)[^/]' \| \
         X"$ac_file" : 'X\(//\)$' \| \
         X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
+printf "%s\n" X"$ac_file" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -11202,9 +13200,9 @@ $as_echo X"$ac_file" |
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -11266,8 +13264,8 @@ ac_sed_dataroot='
 case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
 *datarootdir*) ac_datarootdir_seen=yes;;
 *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
   ac_datarootdir_hack='
@@ -11311,9 +13309,9 @@ test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
   { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
   { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' \
       "$ac_tmp/out"`; test -z "$ac_out"; } &&
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&5
-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&2;}
 
   rm -f "$ac_tmp/stdin"
@@ -11329,20 +13327,20 @@ which seems to be undefined.  Please make sure it is defined" >&2;}
   #
   if test x"$ac_file" != x-; then
     {
-      $as_echo "/* $configure_input  */" \
+      printf "%s\n" "/* $configure_input  */" >&1 \
       && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
     } >"$ac_tmp/config.h" \
       || as_fn_error $? "could not create $ac_file" "$LINENO" 5
     if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}
     else
       rm -f "$ac_file"
       mv "$ac_tmp/config.h" "$ac_file" \
        || as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
   else
-    $as_echo "/* $configure_input  */" \
+    printf "%s\n" "/* $configure_input  */" >&1 \
       && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
       || as_fn_error $? "could not create -" "$LINENO" 5
   fi
@@ -11383,14 +13381,15 @@ if test "$no_create" != yes; then
   $ac_cs_success || as_fn_exit 1
 fi
 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
-$as_echo "" >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result:     rsync $PACKAGE_VERSION configuration successful" >&5
-$as_echo "    rsync $PACKAGE_VERSION configuration successful" >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
-$as_echo "" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: " >&5
+printf "%s\n" "" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result:     rsync $PACKAGE_VERSION configuration successful" >&5
+printf "%s\n" "    rsync $PACKAGE_VERSION configuration successful" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: " >&5
+printf "%s\n" "" >&6; }
+
index c8dadd4..7ba09ab 100644 (file)
@@ -7,39 +7,54 @@ basically a summary of clientserver.c and authenticate.c.
 This is the protocol used for rsync --daemon; i.e. connections to port
 873 rather than invocations over a remote shell.
 
-When the server accepts a connection, it prints a greeting
+When the server accepts a connection, it prints a newline-terminated
+greeting line:
 
-  @RSYNCD: <version>.<subprotocol>
+  @RSYNCD: <version>.<subprotocol> <digest1> <digestN>
 
-where <version> is the numeric version (see PROTOCOL_VERSION in rsync.h)
-'.' is a literal period, and <subprotocol> is the numeric subprotocol
-version (see SUBPROTOCOL_VERSION -- it will be 0 for final releases).
-Protocols prior to 30 only output <version> alone.  The daemon expects
-to see a similar greeting back from the client.  For protocols prior to
-30, an absent ".<subprotocol>" value is assumed to be 0.  For protocol
-30, an absent value is a fatal error.  The daemon then follows this line
-with a free-format text message-of-the-day (if any is defined).
+The <version> is the numeric version (see PROTOCOL_VERSION in rsync.h)
+The <subprotocol> is the numeric subprotocol version (which is 0 for a
+final protocol version, as the SUBPROTOCOL_VERSION define discusses).
+The <digestN> names are the authentication digest algorithms that the
+daemon supports, listed in order of preference.
+
+An rsync prior to 3.2.7 omits the digest names.  An rsync prior to 3.0.0
+also omits the period and the <subprotocol> value.  Since a final
+protocol has a subprotocol value of 0, a missing subprotocol value is
+assumed to be 0 for any protocol prior to 30.  It is considered a fatal
+error for protocol 30 and above to omit it.  It is considered a fatal
+error for protocol 32 and above to omit the digest name list (currently
+31 is the newest protocol).
+
+The daemon expects to see a similar greeting line back from the client.
+Once received, the daemon follows the opening line with a free-format
+text message-of-the-day (if any is defined).
 
 The server is now in the connected state.  The client can either send
-the command
+the command:
 
   #list
 
-to get a listing of modules, or the name of a module.  After this, the
+(to get a listing of modules) or the name of a module.  After this, the
 connection is now bound to a particular module.  Access per host for
 this module is now checked, as is per-module connection limits.
 
-If authentication is required to use this module, the server will say
+If authentication is required to use this module, the server will say:
 
   @RSYNCD: AUTHREQD <challenge>
 
 where <challenge> is a random string of base64 characters.  The client
-must respond with
+must respond with:
 
   <user> <response>
 
-where <user> is the username they claim to be, and <response> is the
-base64 form of the MD4 hash of challenge+password.
+The <user> is the username they claim to be. The <response> is the
+base64 form of the digest hash of the challenge+password string. The
+chosen digest method is the most preferred client method that is also in
+the server's list.  If no digest list was explicitly provided, the side
+expecting a list assumes the other side provided either the single name
+"md5" (for a negotiated protocol 30 or 31), or the single name "md4"
+(for an older protocol).
 
 At this point the server applies all remaining constraints before
 handing control to the client, including switching uid/gid, setting up
@@ -76,6 +91,13 @@ stay tuned (or write it yourself!).
 ------------
 Protocol version changes
 
+31     (2013-09-28, 3.1.0)
+
+       Initial release of protocol 31 had no changes.  Rsync 3.2.7
+       introduced the suffixed list of digest names on the greeting
+       line.  The presence of the list is allowed even if the greeting
+       indicates an older protocol version number.
+
 30     (2007-10-04, 3.0.0pre1)
 
        The use of a ".<subprotocol>" number was added to
index 3b438b0..6903417 100644 (file)
@@ -60,9 +60,9 @@ BOOL  read_only               True
 BOOL   reverse_lookup          True
 BOOL   strict_modes            True
 BOOL   transfer_logging        False
-BOOL   use_chroot              True
 BOOL   write_only              False
 
 BOOL3  munge_symlinks          Unset
 BOOL3  numeric_ids             Unset
 BOOL3  open_noatime            Unset
+BOOL3  use_chroot              Unset
index e095744..ffe55b1 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2002 Martin Pool
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
 
 extern int am_server;
 extern int am_sender;
+extern int am_generator;
 extern int eol_nulls;
 extern int io_error;
+extern int xfer_dirs;
+extern int recurse;
 extern int local_server;
 extern int prune_empty_dirs;
 extern int ignore_perishable;
+extern int relative_paths;
 extern int delete_mode;
 extern int delete_excluded;
 extern int cvs_exclude;
 extern int sanitize_paths;
 extern int protocol_version;
+extern int trust_sender_args;
 extern int module_id;
 
 extern char curr_dir[MAXPATHLEN];
@@ -44,8 +49,11 @@ extern unsigned int module_dirlen;
 filter_rule_list filter_list = { .debug_type = "" };
 filter_rule_list cvs_filter_list = { .debug_type = " [global CVS]" };
 filter_rule_list daemon_filter_list = { .debug_type = " [daemon]" };
+filter_rule_list implied_filter_list = { .debug_type = " [implied]" };
 
 int saw_xattr_filter = 0;
+int trust_sender_args = 0;
+int trust_sender_filter = 0;
 
 /* Need room enough for ":MODS " prefix plus some room to grow. */
 #define MAX_RULE_PREFIX (16)
@@ -70,6 +78,10 @@ static filter_rule **mergelist_parents;
 static int mergelist_cnt = 0;
 static int mergelist_size = 0;
 
+#define LOCAL_RULE   1
+#define REMOTE_RULE  2
+static uchar cur_elide_value = REMOTE_RULE;
+
 /* Each filter_list_struct describes a singly-linked list by keeping track
  * of both the head and tail pointers.  The list is slightly unusual in that
  * a parent-dir's content can be appended to the end of the local list in a
@@ -152,13 +164,17 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
 {
        const char *cp;
        unsigned int pre_len, suf_len, slash_cnt = 0;
+       char *mention_rule_suffix;
 
-       if (DEBUG_GTE(FILTER, 2)) {
-               rprintf(FINFO, "[%s] add_rule(%s%.*s%s)%s\n",
+       if (DEBUG_GTE(FILTER, 1) && pat_len && (pat[pat_len-1] == ' ' || pat[pat_len-1] == '\t'))
+               mention_rule_suffix = " -- CAUTION: trailing whitespace!";
+       else
+               mention_rule_suffix = DEBUG_GTE(FILTER, 2) ? "" : NULL;
+       if (mention_rule_suffix) {
+               rprintf(FINFO, "[%s] add_rule(%s%.*s%s)%s%s\n",
                        who_am_i(), get_rule_prefix(rule, pat, 0, NULL),
-                       (int)pat_len, pat,
-                       (rule->rflags & FILTRULE_DIRECTORY) ? "/" : "",
-                       listp->debug_type);
+                       (int)pat_len, pat, (rule->rflags & FILTRULE_DIRECTORY) ? "/" : "",
+                       listp->debug_type, mention_rule_suffix);
        }
 
        /* These flags also indicate that we're reading a list that
@@ -208,6 +224,7 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
                                slash_cnt++;
                }
        }
+       rule->elide = 0;
        strlcpy(rule->pattern + pre_len, pat, pat_len + 1);
        pat_len += pre_len;
        if (suf_len) {
@@ -288,6 +305,271 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
        }
 }
 
+/* If the wildcards failed, the remote shell might give us a file matching the literal
+ * wildcards.  Since "*" & "?" already match themselves, this just needs to deal with
+ * failed "[foo]" idioms.
+ */
+static void maybe_add_literal_brackets_rule(filter_rule const *based_on, int arg_len)
+{
+       filter_rule *rule;
+       const char *arg = based_on->pattern, *cp;
+       char *p;
+       int cnt = 0;
+
+       if (arg_len < 0)
+               arg_len = strlen(arg);
+
+       for (cp = arg; *cp; cp++) {
+               if (*cp == '\\' && cp[1]) {
+                       cp++;
+               } else if (*cp == '[')
+                       cnt++;
+       }
+       if (!cnt)
+               return;
+
+       rule = new0(filter_rule);
+       rule->rflags = based_on->rflags;
+       rule->u.slash_cnt = based_on->u.slash_cnt;
+       p = rule->pattern = new_array(char, arg_len + cnt + 1);
+       for (cp = arg; *cp; ) {
+               if (*cp == '\\' && cp[1]) {
+                       *p++ = *cp++;
+               } else if (*cp == '[')
+                       *p++ = '\\';
+               *p++ = *cp++;
+       }
+       *p++ = '\0';
+
+       rule->next = implied_filter_list.head;
+       implied_filter_list.head = rule;
+       if (DEBUG_GTE(FILTER, 3)) {
+               rprintf(FINFO, "[%s] add_implied_include(%s%s)\n", who_am_i(), rule->pattern,
+                       rule->rflags & FILTRULE_DIRECTORY ? "/" : "");
+       }
+}
+
+static char *partial_string_buf = NULL;
+static int partial_string_len = 0;
+void implied_include_partial_string(const char *s_start, const char *s_end)
+{
+       partial_string_len = s_end - s_start;
+       if (partial_string_len <= 0 || partial_string_len >= MAXPATHLEN) { /* too-large should be impossible... */
+               partial_string_len = 0;
+               return;
+       }
+       if (!partial_string_buf)
+               partial_string_buf = new_array(char, MAXPATHLEN);
+       memcpy(partial_string_buf, s_start, partial_string_len);
+}
+
+void free_implied_include_partial_string()
+{
+       if (partial_string_buf) {
+               if (partial_string_len)
+                       add_implied_include("", 0);
+               free(partial_string_buf);
+               partial_string_buf = NULL;
+       }
+       partial_string_len = 0; /* paranoia */
+}
+
+/* Each arg the client sends to the remote sender turns into an implied include
+ * that the receiver uses to validate the file list from the sender. */
+void add_implied_include(const char *arg, int skip_daemon_module)
+{
+       int arg_len, saw_wild = 0, saw_live_open_brkt = 0, backslash_cnt = 0;
+       int slash_cnt = 0;
+       const char *cp;
+       char *p;
+       if (trust_sender_args)
+               return;
+       if (partial_string_len) {
+               arg_len = strlen(arg);
+               if (partial_string_len + arg_len >= MAXPATHLEN) {
+                       partial_string_len = 0;
+                       return; /* Should be impossible... */
+               }
+               memcpy(partial_string_buf + partial_string_len, arg, arg_len + 1);
+               partial_string_len = 0;
+               arg = partial_string_buf;
+       }
+       if (skip_daemon_module) {
+               if ((cp = strchr(arg, '/')) != NULL)
+                       arg = cp + 1;
+               else
+                       arg = "";
+       }
+       if (relative_paths) {
+               if ((cp = strstr(arg, "/./")) != NULL)
+                       arg = cp + 3;
+       } else if ((cp = strrchr(arg, '/')) != NULL) {
+               arg = cp + 1;
+       }
+       if (*arg == '.' && arg[1] == '\0')
+               arg++;
+       arg_len = strlen(arg);
+       if (arg_len) {
+               char *new_pat;
+               if (strpbrk(arg, "*[?")) {
+                       /* We need to add room to escape backslashes if wildcard chars are present. */
+                       for (cp = arg; (cp = strchr(cp, '\\')) != NULL; cp++)
+                               arg_len++;
+                       saw_wild = 1;
+               }
+               arg_len++; /* Leave room for the prefixed slash */
+               p = new_pat = new_array(char, arg_len + 1);
+               *p++ = '/';
+               slash_cnt++;
+               for (cp = arg; *cp; ) {
+                       switch (*cp) {
+                         case '\\':
+                               if (cp[1] == ']') {
+                                       if (!saw_wild)
+                                               cp++; /* A \] in a non-wild filter causes a problem, so drop the \ . */
+                               } else if (!strchr("*[?", cp[1])) {
+                                       backslash_cnt++;
+                                       if (saw_wild)
+                                               *p++ = '\\';
+                               }
+                               *p++ = *cp++;
+                               break;
+                         case '/':
+                               if (p[-1] == '/') { /* This is safe because of the initial slash. */
+                                       if (*++cp == '\0') {
+                                               slash_cnt--;
+                                               p--;
+                                       }
+                               } else if (cp[1] == '\0') {
+                                       cp++;
+                               } else {
+                                       slash_cnt++;
+                                       *p++ = *cp++;
+                               }
+                               break;
+                         case '.':
+                               if (p[-1] == '/') {
+                                       if (cp[1] == '/') {
+                                               cp += 2;
+                                               if (!*cp) {
+                                                       slash_cnt--;
+                                                       p--;
+                                               }
+                                       } else if (cp[1] == '\0') {
+                                               cp++;
+                                               slash_cnt--;
+                                               p--;
+                                       } else
+                                               *p++ = *cp++;
+                               } else
+                                       *p++ = *cp++;
+                               break;
+                         case '[':
+                               saw_live_open_brkt = 1;
+                               *p++ = *cp++;
+                               break;
+                         default:
+                               *p++ = *cp++;
+                               break;
+                       }
+               }
+               *p = '\0';
+               arg_len = p - new_pat;
+               if (!arg_len)
+                       free(new_pat);
+               else {
+                       filter_rule *rule = new0(filter_rule);
+                       rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0);
+                       rule->u.slash_cnt = slash_cnt;
+                       arg = rule->pattern = new_pat;
+                       if (!implied_filter_list.head)
+                               implied_filter_list.head = implied_filter_list.tail = rule;
+                       else {
+                               rule->next = implied_filter_list.head;
+                               implied_filter_list.head = rule;
+                       }
+                       if (DEBUG_GTE(FILTER, 3))
+                               rprintf(FINFO, "[%s] add_implied_include(%s)\n", who_am_i(), arg);
+                       if (saw_live_open_brkt)
+                               maybe_add_literal_brackets_rule(rule, arg_len);
+                       if (relative_paths && slash_cnt) {
+                               int sub_slash_cnt = slash_cnt;
+                               while ((p = strrchr(new_pat, '/')) != NULL && p != new_pat) {
+                                       filter_rule const *ent;
+                                       filter_rule *R_rule;
+                                       int found = 0;
+                                       *p = '\0';
+                                       for (ent = implied_filter_list.head; ent; ent = ent->next) {
+                                               if (ent != rule && strcmp(ent->pattern, new_pat) == 0) {
+                                                       found = 1;
+                                                       break;
+                                               }
+                                       }
+                                       if (found) {
+                                               *p = '/';
+                                               break; /* We added all parent dirs already */
+                                       }
+                                       R_rule = new0(filter_rule);
+                                       R_rule->rflags = FILTRULE_INCLUDE | FILTRULE_DIRECTORY;
+                                       /* Check if our sub-path has wildcards or escaped backslashes */
+                                       if (saw_wild && strpbrk(new_pat, "*[?\\"))
+                                               R_rule->rflags |= FILTRULE_WILD;
+                                       R_rule->pattern = strdup(new_pat);
+                                       R_rule->u.slash_cnt = --sub_slash_cnt;
+                                       R_rule->next = implied_filter_list.head;
+                                       implied_filter_list.head = R_rule;
+                                       if (DEBUG_GTE(FILTER, 3)) {
+                                               rprintf(FINFO, "[%s] add_implied_include(%s/)\n",
+                                                       who_am_i(), R_rule->pattern);
+                                       }
+                                       if (saw_live_open_brkt)
+                                               maybe_add_literal_brackets_rule(R_rule, -1);
+                               }
+                               for (p = new_pat; sub_slash_cnt < slash_cnt; sub_slash_cnt++) {
+                                       p += strlen(p);
+                                       *p = '/';
+                               }
+                       }
+               }
+       }
+
+       if (recurse || xfer_dirs) {
+               /* Now create a rule with an added "/" & "**" or "*" at the end */
+               filter_rule *rule = new0(filter_rule);
+               rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD;
+               if (recurse)
+                       rule->rflags |= FILTRULE_WILD2;
+               /* We must leave enough room for / * * \0. */
+               if (!saw_wild && backslash_cnt) {
+                       /* We are appending a wildcard, so now the backslashes need to be escaped. */
+                       p = rule->pattern = new_array(char, arg_len + backslash_cnt + 3 + 1);
+                       for (cp = arg; *cp; ) { /* Note that arg_len != 0 because backslash_cnt > 0 */
+                               if (*cp == '\\')
+                                       *p++ = '\\';
+                               *p++ = *cp++;
+                       }
+               } else {
+                       p = rule->pattern = new_array(char, arg_len + 3 + 1);
+                       if (arg_len) {
+                               memcpy(p, arg, arg_len);
+                               p += arg_len;
+                       }
+               }
+               *p++ = '/';
+               *p++ = '*';
+               if (recurse)
+                       *p++ = '*';
+               *p = '\0';
+               rule->u.slash_cnt = slash_cnt + 1;
+               rule->next = implied_filter_list.head;
+               implied_filter_list.head = rule;
+               if (DEBUG_GTE(FILTER, 3))
+                       rprintf(FINFO, "[%s] add_implied_include(%s)\n", who_am_i(), rule->pattern);
+               if (saw_live_open_brkt)
+                       maybe_add_literal_brackets_rule(rule, p - rule->pattern);
+       }
+}
+
 /* This frees any non-inherited items, leaving just inherited items on the list. */
 static void pop_filter_list(filter_rule_list *listp)
 {
@@ -625,7 +907,7 @@ static int rule_matches(const char *fname, filter_rule *ex, int name_flags)
        const char *strings[16]; /* more than enough */
        const char *name = fname + (*fname == '/');
 
-       if (!*name)
+       if (!*name || ex->elide == cur_elide_value)
                return 0;
 
        if (!(name_flags & NAME_IS_XATTR) ^ !(ex->rflags & FILTRULE_XATTR))
@@ -702,11 +984,12 @@ static void report_filter_result(enum logcode code, char const *name,
                                 filter_rule const *ent,
                                 int name_flags, const char *type)
 {
+       int log_level = am_sender || am_generator ? 1 : 3;
+
        /* If a trailing slash is present to match only directories,
         * then it is stripped out by add_rule().  So as a special
-        * case we add it back in here. */
-
-       if (DEBUG_GTE(FILTER, 1)) {
+        * case we add it back in the log output. */
+       if (DEBUG_GTE(FILTER, log_level)) {
                static char *actions[2][2]
                    = { {"show", "hid"}, {"risk", "protect"} };
                const char *w = who_am_i();
@@ -714,7 +997,7 @@ static void report_filter_result(enum logcode code, char const *name,
                              : name_flags & NAME_IS_DIR ? "directory"
                              : "file";
                rprintf(code, "[%s] %sing %s %s because of pattern %s%s%s\n",
-                   w, actions[*w!='s'][!(ent->rflags & FILTRULE_INCLUDE)],
+                   w, actions[*w=='g'][!(ent->rflags & FILTRULE_INCLUDE)],
                    t, name, ent->pattern,
                    ent->rflags & FILTRULE_DIRECTORY ? "/" : "", type);
        }
@@ -740,6 +1023,15 @@ int name_is_excluded(const char *fname, int name_flags, int filter_level)
        return 0;
 }
 
+int check_server_filter(filter_rule_list *listp, enum logcode code, const char *name, int name_flags)
+{
+       int ret;
+       cur_elide_value = LOCAL_RULE;
+       ret = check_filter(listp, code, name, name_flags);
+       cur_elide_value = REMOTE_RULE;
+       return ret;
+}
+
 /* Return -1 if file "name" is defined to be excluded by the specified
  * exclude list, 1 if it is included, and 0 if it was not matched. */
 int check_filter(filter_rule_list *listp, enum logcode code,
@@ -886,6 +1178,7 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
                }
                switch (ch) {
                case ':':
+                       trust_sender_filter = 1;
                        rule->rflags |= FILTRULE_PERDIR_MERGE
                                      | FILTRULE_FINISH_SETUP;
                        /* FALL THROUGH */
@@ -1294,7 +1587,7 @@ char *get_rule_prefix(filter_rule *rule, const char *pat, int for_xfer,
 
 static void send_rules(int f_out, filter_rule_list *flp)
 {
-       filter_rule *ent, *prev = NULL;
+       filter_rule *ent;
 
        for (ent = flp->head; ent; ent = ent->next) {
                unsigned int len, plen, dlen;
@@ -1309,21 +1602,15 @@ static void send_rules(int f_out, filter_rule_list *flp)
                 * merge files as an optimization (since they can only have
                 * include/exclude rules). */
                if (ent->rflags & FILTRULE_SENDER_SIDE)
-                       elide = am_sender ? 1 : -1;
+                       elide = am_sender ? LOCAL_RULE : REMOTE_RULE;
                if (ent->rflags & FILTRULE_RECEIVER_SIDE)
-                       elide = elide ? 0 : am_sender ? -1 : 1;
+                       elide = elide ? 0 : am_sender ? REMOTE_RULE : LOCAL_RULE;
                else if (delete_excluded && !elide
                 && (!(ent->rflags & FILTRULE_PERDIR_MERGE)
                  || ent->rflags & FILTRULE_NO_PREFIXES))
-                       elide = am_sender ? 1 : -1;
-               if (elide < 0) {
-                       if (prev)
-                               prev->next = ent->next;
-                       else
-                               flp->head = ent->next;
-               } else
-                       prev = ent;
-               if (elide > 0)
+                       elide = am_sender ? LOCAL_RULE : REMOTE_RULE;
+               ent->elide = elide;
+               if (elide == LOCAL_RULE)
                        continue;
                if (ent->rflags & FILTRULE_CVS_IGNORE
                    && !(ent->rflags & FILTRULE_MERGE_FILE)) {
@@ -1351,7 +1638,6 @@ static void send_rules(int f_out, filter_rule_list *flp)
                if (dlen)
                        write_byte(f_out, '/');
        }
-       flp->tail = prev;
 }
 
 /* This is only called by the client. */
diff --git a/flist.c b/flist.c
index 5a1e424..65b459b 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2002-2020 Wayne Davison
+ * Copyright (C) 2002-2022 Wayne Davison
  *
  * 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
@@ -33,7 +33,6 @@ extern int am_sender;
 extern int am_generator;
 extern int inc_recurse;
 extern int always_checksum;
-extern int checksum_type;
 extern int module_id;
 extern int ignore_errors;
 extern int numeric_ids;
@@ -43,6 +42,7 @@ extern int use_qsort;
 extern int xfer_dirs;
 extern int filesfrom_fd;
 extern int one_file_system;
+extern int copy_devices;
 extern int copy_dirlinks;
 extern int preserve_uid;
 extern int preserve_gid;
@@ -72,18 +72,20 @@ extern int need_unsorted_flist;
 extern int sender_symlink_iconv;
 extern int output_needs_newline;
 extern int sender_keeps_checksum;
+extern int trust_sender_filter;
 extern int unsort_ndx;
 extern uid_t our_uid;
 extern struct stats stats;
 extern char *filesfrom_host;
 extern char *usermap, *groupmap;
 
+extern struct name_num_item *file_sum_nni;
+
 extern char curr_dir[MAXPATHLEN];
 
 extern struct chmod_mode_struct *chmod_modes;
 
-extern filter_rule_list filter_list;
-extern filter_rule_list daemon_filter_list;
+extern filter_rule_list filter_list, implied_filter_list, daemon_filter_list;
 
 #ifdef ICONV_OPTION
 extern int filesfrom_convert;
@@ -144,7 +146,8 @@ void init_flist(void)
                rprintf(FINFO, "FILE_STRUCT_LEN=%d, EXTRA_LEN=%d\n",
                        (int)FILE_STRUCT_LEN, (int)EXTRA_LEN);
        }
-       flist_csum_len = csum_len_for_type(checksum_type, 1);
+       /* Note that this isn't identical to file_sum_len in the case of CSUM_MD4_ARCHAIC: */
+       flist_csum_len = csum_len_for_type(file_sum_nni->num, 1);
 
        show_filelist_progress = INFO_GTE(FLIST, 1) && xfer_dirs && !am_server && !inc_recurse;
 }
@@ -295,6 +298,8 @@ static void flist_expand(struct file_list *flist, int extra)
                flist->malloced = FLIST_START;
        else if (flist->malloced >= FLIST_LINEAR)
                flist->malloced += FLIST_LINEAR;
+       else if (flist->malloced < FLIST_START_LARGE/16)
+               flist->malloced *= 4;
        else
                flist->malloced *= 2;
 
@@ -305,7 +310,7 @@ static void flist_expand(struct file_list *flist, int extra)
 
        new_ptr = realloc_array(flist->files, struct file_struct *, flist->malloced);
 
-       if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
+       if (DEBUG_GTE(FLIST, 1) && flist->files) {
                rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
                    who_am_i(),
                    big_num(sizeof flist->files[0] * flist->malloced),
@@ -698,6 +703,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        int alloc_len, basename_len, linkname_len;
        int extra_len = file_extra_cnt * EXTRA_LEN;
        int first_hlink_ndx = -1;
+       char real_ISREG_entry;
        int64 file_length;
 #ifdef CAN_SET_NSEC
        uint32 modtime_nsec;
@@ -750,7 +756,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        if (*thisname
         && (clean_fname(thisname, CFN_REFUSE_DOT_DOT_DIRS) < 0 || (!relative_paths && *thisname == '/'))) {
                rprintf(FERROR, "ABORTING due to unsafe pathname from sender: %s\n", thisname);
-               exit_cleanup(RERR_PROTOCOL);
+               exit_cleanup(RERR_UNSUPPORTED);
        }
 
        if (sanitize_paths)
@@ -812,6 +818,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                                linkname_len = strlen(F_SYMLINK(first)) + 1;
                        else
                                linkname_len = 0;
+                       real_ISREG_entry = S_ISREG(mode) ? 1 : 0;
                        goto create_object;
                }
        }
@@ -829,7 +836,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                        }
 #endif
                } else
-                       modtime = read_int(f);
+                       modtime = read_uint(f);
        }
        if (xflags & XMIT_MOD_NSEC)
 #ifndef CAN_SET_NSEC
@@ -939,10 +946,20 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
 #endif
                linkname_len = 0;
 
+       if (copy_devices && IS_DEVICE(mode)) {
+               /* This is impossible in the official release, but some pre-release patches
+                * didn't convert the device into a file before sending, so we'll do it here
+                * (even though the length is typically 0 and any checksum data is zeros). */
+               mode = S_IFREG | (mode & ACCESSPERMS);
+               modtime = time(NULL); /* The mtime on the device is not up-to-date, so set it to "now". */
+               real_ISREG_entry = 0;
+       } else
+               real_ISREG_entry = S_ISREG(mode) ? 1 : 0;
+
 #ifdef SUPPORT_HARD_LINKS
   create_object:
        if (preserve_hard_links) {
-               if (protocol_version < 28 && S_ISREG(mode))
+               if (protocol_version < 28 && real_ISREG_entry)
                        xflags |= XMIT_HLINKED;
                if (xflags & XMIT_HLINKED)
                        extra_len += (inc_recurse+1) * EXTRA_LEN;
@@ -971,6 +988,19 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                exit_cleanup(RERR_UNSUPPORTED);
        }
 
+       if (*thisname == '/' ? thisname[1] != '.' || thisname[2] != '\0' : *thisname != '.' || thisname[1] != '\0') {
+               int filt_flags = S_ISDIR(mode) ? NAME_IS_DIR : NAME_IS_FILE;
+               if (!trust_sender_filter /* a per-dir filter rule means we must trust the sender's filtering */
+                && filter_list.head && check_server_filter(&filter_list, FINFO, thisname, filt_flags) < 0) {
+                       rprintf(FERROR, "ERROR: rejecting excluded file-list name: %s\n", thisname);
+                       exit_cleanup(RERR_UNSUPPORTED);
+               }
+               if (implied_filter_list.head && check_filter(&implied_filter_list, FINFO, thisname, filt_flags) <= 0) {
+                       rprintf(FERROR, "ERROR: rejecting unrequested file-list name: %s\n", thisname);
+                       exit_cleanup(RERR_UNSUPPORTED);
+               }
+       }
+
        if (inc_recurse && S_ISDIR(mode)) {
                if (one_file_system) {
                        /* Room to save the dir's device for -x */
@@ -1158,8 +1188,8 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        }
 #endif
 
-       if (always_checksum && (S_ISREG(mode) || protocol_version < 28)) {
-               if (S_ISREG(mode))
+       if (always_checksum && (real_ISREG_entry || protocol_version < 28)) {
+               if (real_ISREG_entry)
                        bp = F_SUM(file);
                else {
                        /* Prior to 28, we get a useless set of nulls. */
@@ -1358,6 +1388,18 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
        linkname_len = 0;
 #endif
 
+       if (copy_devices && am_sender && IS_DEVICE(st.st_mode)) {
+               if (st.st_size == 0) {
+                       int fd = do_open(fname, O_RDONLY, 0);
+                       if (fd >= 0) {
+                               st.st_size = get_device_size(fd, fname);
+                               close(fd);
+                       }
+               }
+               st.st_mode = S_IFREG | (st.st_mode & ACCESSPERMS);
+               st.st_mtime = time(NULL); /* The mtime on the device is not up-to-date, so set it to "now". */
+       }
+
 #ifdef ST_MTIME_NSEC
        if (st.ST_MTIME_NSEC && protocol_version >= 31)
                extra_len += EXTRA_LEN;
@@ -1438,7 +1480,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                F_ATIME(file) = st.st_atime;
 #ifdef SUPPORT_CRTIMES
        if (crtimes_ndx)
-               F_CRTIME(file) = get_create_time(fname);
+               F_CRTIME(file) = get_create_time(fname, &st);
 #endif
 
        if (basename != thisname)
@@ -2186,8 +2228,10 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
 #endif
 
        flist = cur_flist = flist_new(0, "send_file_list");
+       flist_expand(flist, FLIST_START_LARGE);
        if (inc_recurse) {
                dir_flist = flist_new(FLIST_TEMP, "send_file_list");
+               flist_expand(dir_flist, FLIST_START_LARGE);
                flags |= FLAG_DIVERT_DIRS;
        } else
                dir_flist = cur_flist;
@@ -2541,10 +2585,13 @@ struct file_list *recv_file_list(int f, int dir_ndx)
 #endif
 
        flist = flist_new(0, "recv_file_list");
+       flist_expand(flist, FLIST_START_LARGE);
 
        if (inc_recurse) {
-               if (flist->ndx_start == 1)
+               if (flist->ndx_start == 1) {
                        dir_flist = flist_new(FLIST_TEMP, "recv_file_list");
+                       flist_expand(dir_flist, FLIST_START_LARGE);
+               }
                dstart = dir_flist->used;
        } else {
                dir_flist = flist;
@@ -2595,7 +2642,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
                                        rprintf(FERROR,
                                                "ABORTING due to invalid path from sender: %s/%s\n",
                                                cur_dir, file->basename);
-                                       exit_cleanup(RERR_PROTOCOL);
+                                       exit_cleanup(RERR_UNSUPPORTED);
                                }
                                good_dirname = cur_dir;
                        }
index f178083..21c4a59 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -35,16 +35,18 @@ extern int inc_recurse;
 extern int relative_paths;
 extern int implied_dirs;
 extern int keep_dirlinks;
+extern int write_devices;
 extern int preserve_acls;
 extern int preserve_xattrs;
 extern int preserve_links;
 extern int preserve_devices;
-extern int write_devices;
 extern int preserve_specials;
 extern int preserve_hard_links;
 extern int preserve_executability;
 extern int preserve_perms;
-extern int preserve_times;
+extern int preserve_mtimes;
+extern int omit_dir_times;
+extern int omit_link_times;
 extern int delete_mode;
 extern int delete_before;
 extern int delete_during;
@@ -112,10 +114,6 @@ static int need_retouch_dir_times;
 static int need_retouch_dir_perms;
 static const char *solo_file = NULL;
 
-enum nonregtype {
-       TYPE_DIR, TYPE_SPECIAL, TYPE_DEVICE, TYPE_SYMLINK
-};
-
 /* Forward declarations. */
 #ifdef SUPPORT_HARD_LINKS
 static void handle_skipped_hlink(struct file_struct *file, int itemizing,
@@ -186,7 +184,8 @@ static int remember_delete(struct file_struct *file, const char *fname, int flag
 static int read_delay_line(char *buf, int *flags_p)
 {
        static int read_pos = 0;
-       int j, len, mode;
+       unsigned int mode;
+       int j, len;
        char *bp, *past_space;
 
        while (1) {
@@ -270,7 +269,7 @@ static void do_delayed_deletions(char *delbuf)
  * MAXPATHLEN buffer with the name of the directory in it (the functions we
  * call will append names onto the end, but the old dir value will be restored
  * on exit). */
-static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t fs_dev)
 {
        static int already_warned = 0;
        static struct hashtable *dev_tbl;
@@ -305,12 +304,12 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
                if (!dev_tbl)
                        dev_tbl = hashtable_create(16, HT_KEY64);
                if (file->flags & FLAG_TOP_DIR) {
-                       hashtable_find(dev_tbl, *fs_dev+1, "");
-                       filesystem_dev = *fs_dev;
-               } else if (filesystem_dev != *fs_dev) {
-                       if (!hashtable_find(dev_tbl, *fs_dev+1, NULL))
+                       hashtable_find(dev_tbl, fs_dev+1, "");
+                       filesystem_dev = fs_dev;
+               } else if (filesystem_dev != fs_dev) {
+                       if (!hashtable_find(dev_tbl, fs_dev+1, NULL))
                                return;
-                       filesystem_dev = *fs_dev; /* it's a prior top-dir dev */
+                       filesystem_dev = fs_dev; /* it's a prior top-dir dev */
                }
        }
 
@@ -379,9 +378,9 @@ static void do_delete_pass(void)
                 || !S_ISDIR(st.st_mode))
                        continue;
 
-               delete_in_dir(fbuf, file, &st.st_dev);
+               delete_in_dir(fbuf, file, st.st_dev);
        }
-       delete_in_dir(NULL, NULL, &dev_zero);
+       delete_in_dir(NULL, NULL, dev_zero);
 
        if (INFO_GTE(FLIST, 2) && !am_server)
                rprintf(FINFO, "                    \r");
@@ -402,7 +401,7 @@ static inline int any_time_differs(stat_x *sxp, struct file_struct *file, UNUSED
 #ifdef SUPPORT_CRTIMES
        if (!differs && crtimes_ndx) {
                if (sxp->crtime == 0)
-                       sxp->crtime = get_create_time(fname);
+                       sxp->crtime = get_create_time(fname, &sxp->st);
                differs = !same_time(sxp->crtime, 0, F_CRTIME(file), 0);
        }
 #endif
@@ -463,7 +462,7 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
 {
        if (S_ISLNK(file->mode)) {
 #ifdef CAN_SET_SYMLINK_TIMES
-               if (preserve_times & PRESERVE_LINK_TIMES && any_time_differs(sxp, file, fname))
+               if (preserve_mtimes && !omit_link_times && any_time_differs(sxp, file, fname))
                        return 0;
 #endif
 #ifdef CAN_CHMOD_SYMLINK
@@ -483,7 +482,7 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
                        return 0;
 #endif
        } else {
-               if (preserve_times && any_time_differs(sxp, file, fname))
+               if (preserve_mtimes && any_time_differs(sxp, file, fname))
                        return 0;
                if (perms_differ(file, sxp))
                        return 0;
@@ -507,9 +506,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
             const char *xname)
 {
        if (statret >= 0) { /* A from-dest-dir statret can == 1! */
-               int keep_time = !preserve_times ? 0
-                   : S_ISDIR(file->mode) ? preserve_times & PRESERVE_DIR_TIMES
-                   : S_ISLNK(file->mode) ? preserve_times & PRESERVE_LINK_TIMES
+               int keep_time = !preserve_mtimes ? 0
+                   : S_ISDIR(file->mode) ? !omit_dir_times
+                   : S_ISLNK(file->mode) ? !omit_link_times
                    : 1;
 
                if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
@@ -528,12 +527,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
 #ifdef SUPPORT_CRTIMES
                if (crtimes_ndx) {
                        if (sxp->crtime == 0)
-                               sxp->crtime = get_create_time(fnamecmp);
+                               sxp->crtime = get_create_time(fnamecmp, &sxp->st);
                        if (!same_time(sxp->crtime, 0, F_CRTIME(file), 0))
                                iflags |= ITEM_REPORT_CRTIME;
                }
 #endif
-#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
+#ifndef CAN_CHMOD_SYMLINK
                if (S_ISLNK(file->mode)) {
                        ;
                } else
@@ -599,31 +598,78 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
        }
 }
 
+static enum filetype get_file_type(mode_t mode)
+{
+       if (S_ISREG(mode))
+               return FT_REG;
+       if (S_ISLNK(mode))
+               return FT_SYMLINK;
+       if (S_ISDIR(mode))
+               return FT_DIR;
+       if (IS_SPECIAL(mode))
+               return FT_SPECIAL;
+       if (IS_DEVICE(mode))
+               return FT_DEVICE;
+       return FT_UNSUPPORTED;
+}
 
 /* Perform our quick-check heuristic for determining if a file is unchanged. */
-int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+int quick_check_ok(enum filetype ftype, const char *fn, struct file_struct *file, STRUCT_STAT *st)
 {
-       if (st->st_size != F_LENGTH(file))
-               return 0;
+       switch (ftype) {
+         case FT_REG:
+               if (st->st_size != F_LENGTH(file))
+                       return 0;
 
-       /* if always checksum is set then we use the checksum instead
-          of the file time to determine whether to sync */
-       if (always_checksum > 0 && S_ISREG(st->st_mode)) {
-               char sum[MAX_DIGEST_LEN];
-               file_checksum(fn, st, sum);
-               return memcmp(sum, F_SUM(file), flist_csum_len) == 0;
-       }
+               /* If always_checksum is set then we use the checksum instead
+                * of the file mtime to determine whether to sync. */
+               if (always_checksum > 0) {
+                       char sum[MAX_DIGEST_LEN];
+                       file_checksum(fn, st, sum);
+                       return memcmp(sum, F_SUM(file), flist_csum_len) == 0;
+               }
 
-       if (size_only > 0)
-               return 1;
+               if (size_only > 0)
+                       return 1;
 
-       if (ignore_times)
-               return 0;
+               if (ignore_times)
+                       return 0;
 
-       return !mtime_differs(st, file);
+               if (mtime_differs(st, file))
+                       return 0;
+               break;
+         case FT_DIR:
+               break;
+         case FT_SYMLINK: {
+#ifdef SUPPORT_LINKS
+               char lnk[MAXPATHLEN];
+               int len = do_readlink(fn, lnk, MAXPATHLEN-1);
+               if (len <= 0)
+                       return 0;
+               lnk[len] = '\0';
+               if (strcmp(lnk, F_SYMLINK(file)) != 0)
+                       return 0;
+               break;
+#else
+               return -1;
+#endif
+         }
+         case FT_SPECIAL:
+               if (!BITS_EQUAL(file->mode, st->st_mode, _S_IFMT))
+                       return 0;
+               break;
+         case FT_DEVICE: {
+               uint32 *devp = F_RDEV_P(file);
+               if (st->st_rdev != MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)))
+                       return 0;
+               break;
+         }
+         case FT_UNSUPPORTED:
+               return -1;
+       }
+       return 1;
 }
 
-
 /*
  * set (initialize) the size entries in the per-file sum_struct
  * calculating dynamic block and checksum sizes.
@@ -829,9 +875,12 @@ static struct file_struct *find_fuzzy(struct file_struct *file, struct file_list
                        len = strlen(name);
                        suf = find_filename_suffix(name, len, &suf_len);
 
-                       dist = fuzzy_distance(name, len, fname, fname_len);
-                       /* Add some extra weight to how well the suffixes match. */
-                       dist += fuzzy_distance(suf, suf_len, fname_suf, fname_suf_len) * 10;
+                       dist = fuzzy_distance(name, len, fname, fname_len, lowest_dist);
+                       /* Add some extra weight to how well the suffixes match unless we've already disqualified
+                        * this file based on a heuristic. */
+                       if (dist < 0xFFFF0000U) {
+                               dist += fuzzy_distance(suf, suf_len, fname_suf, fname_suf_len, 0xFFFF0000U) * 10;
+                       }
                        if (DEBUG_GTE(FUZZY, 2)) {
                                rprintf(FINFO, "fuzzy distance for %s = %d.%05d\n",
                                        f_name(fp, NULL), (int)(dist>>16), (int)(dist&0xFFFF));
@@ -907,7 +956,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
                        best_match = j;
                        match_level = 1;
                }
-               if (!unchanged_file(cmpbuf, file, &sxp->st))
+               if (!quick_check_ok(FT_REG, cmpbuf, file, &sxp->st))
                        continue;
                if (match_level == 1) {
                        best_match = j;
@@ -1006,29 +1055,14 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
 {
        int best_match = -1;
        int match_level = 0;
-       enum nonregtype type;
-       uint32 *devp;
-#ifdef SUPPORT_LINKS
-       char lnk[MAXPATHLEN];
-       int len;
-#endif
+       enum filetype ftype = get_file_type(file->mode);
        int j = 0;
 
 #ifndef SUPPORT_LINKS
-       if (S_ISLNK(file->mode))
+       if (ftype == FT_SYMLINK)
                return -1;
 #endif
-       if (S_ISDIR(file->mode)) {
-               type = TYPE_DIR;
-       } else if (IS_SPECIAL(file->mode))
-               type = TYPE_SPECIAL;
-       else if (IS_DEVICE(file->mode))
-               type = TYPE_DEVICE;
-#ifdef SUPPORT_LINKS
-       else if (S_ISLNK(file->mode))
-               type = TYPE_SYMLINK;
-#endif
-       else {
+       if (ftype == FT_REG || ftype == FT_UNSUPPORTED) {
                rprintf(FERROR,
                        "internal: try_dests_non() called with invalid mode (%o)\n",
                        (int)file->mode);
@@ -1039,53 +1073,14 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
                pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
                if (link_stat(cmpbuf, &sxp->st, 0) < 0)
                        continue;
-               switch (type) {
-               case TYPE_DIR:
-                       if (!S_ISDIR(sxp->st.st_mode))
-                               continue;
-                       break;
-               case TYPE_SPECIAL:
-                       if (!IS_SPECIAL(sxp->st.st_mode))
-                               continue;
-                       break;
-               case TYPE_DEVICE:
-                       if (!IS_DEVICE(sxp->st.st_mode))
-                               continue;
-                       break;
-               case TYPE_SYMLINK:
-#ifdef SUPPORT_LINKS
-                       if (!S_ISLNK(sxp->st.st_mode))
-                               continue;
-                       break;
-#else
-                       return -1;
-#endif
-               }
+               if (ftype != get_file_type(sxp->st.st_mode))
+                       continue;
                if (match_level < 1) {
                        match_level = 1;
                        best_match = j;
                }
-               switch (type) {
-               case TYPE_DIR:
-               case TYPE_SPECIAL:
-                       break;
-               case TYPE_DEVICE:
-                       devp = F_RDEV_P(file);
-                       if (sxp->st.st_rdev != MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)))
-                               continue;
-                       break;
-               case TYPE_SYMLINK:
-#ifdef SUPPORT_LINKS
-                       if ((len = do_readlink(cmpbuf, lnk, MAXPATHLEN-1)) <= 0)
-                               continue;
-                       lnk[len] = '\0';
-                       if (strcmp(lnk, F_SYMLINK(file)) != 0)
-                               continue;
-                       break;
-#else
-                       return -1;
-#endif
-               }
+               if (!quick_check_ok(ftype, cmpbuf, file, &sxp->st))
+                       continue;
                if (match_level < 2) {
                        match_level = 2;
                        best_match = j;
@@ -1130,14 +1125,14 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
                        match_level = 2;
                if (itemizing && stdout_format_has_i
                 && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) {
-                       int chg = alt_dest_type == COMPARE_DEST && type != TYPE_DIR ? 0
+                       int chg = alt_dest_type == COMPARE_DEST && ftype != FT_DIR ? 0
                            : ITEM_LOCAL_CHANGE + (match_level == 3 ? ITEM_XNAME_FOLLOWS : 0);
                        char *lp = match_level == 3 ? "" : NULL;
                        itemize(cmpbuf, file, ndx, 0, sxp, chg + ITEM_MATCHED, 0, lp);
                }
                if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT) {
                        rprintf(FCLIENT, "%s%s is uptodate\n",
-                               fname, type == TYPE_DIR ? "/" : "");
+                               fname, ftype == FT_DIR ? "/" : "");
                }
                return -2;
        }
@@ -1231,7 +1226,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
        char fnamecmpbuf[MAXPATHLEN];
        uchar fnamecmp_type;
        int del_opts = delete_mode || force_delete ? DEL_RECURSE : 0;
-       int is_dir = !S_ISDIR(file->mode) ? 0
+       enum filetype stype, ftype = get_file_type(file->mode);
+       int is_dir = ftype != FT_DIR ? 0
                   : inc_recurse && ndx != cur_flist->ndx_start - 1 ? -1
                   : 1;
 
@@ -1278,7 +1274,6 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        return;
                }
        }
-       sx.crtime = 0;
 
        if (dry_run > 1 || (dry_missing_dir && is_below(file, dry_missing_dir))) {
                int i;
@@ -1380,10 +1375,27 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
         && !am_root && sx.st.st_uid == our_uid)
                del_opts |= DEL_NO_UID_WRITE;
 
+       if (statret == 0)
+               stype = get_file_type(sx.st.st_mode);
+       else
+               stype = FT_UNSUPPORTED;
+
        if (ignore_existing > 0 && statret == 0
-        && (!is_dir || !S_ISDIR(sx.st.st_mode))) {
-               if (INFO_GTE(SKIP, 1) && is_dir >= 0)
-                       rprintf(FINFO, "%s exists\n", fname);
+        && (!is_dir || stype != FT_DIR)) {
+               if (INFO_GTE(SKIP, 1) && is_dir >= 0) {
+                       const char *suf = "";
+                       if (INFO_GTE(SKIP, 2)) {
+                               if (ftype != stype)
+                                       suf = " (type change)";
+                               else if (!quick_check_ok(ftype, fname, file, &sx.st))
+                                       suf = always_checksum ? " (sum change)" : " (file change)";
+                               else if (!unchanged_attrs(fname, file, &sx))
+                                       suf = " (attr change)";
+                               else
+                                       suf = " (uptodate)";
+                       }
+                       rprintf(FINFO, "%s exists%s\n", fname, suf);
+               }
 #ifdef SUPPORT_HARD_LINKS
                if (F_IS_HLINKED(file))
                        handle_skipped_hlink(file, itemizing, code, f_out);
@@ -1404,7 +1416,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                } else
                        added_perms = 0;
                if (is_dir < 0) {
-                       if (!(preserve_times & PRESERVE_DIR_TIMES))
+                       if (!preserve_mtimes || omit_dir_times)
                                goto cleanup;
                        /* In inc_recurse mode we want to make sure any missing
                         * directories get created while we're still processing
@@ -1412,7 +1424,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                         * dir's mtime right away).  We will handle the dir in
                         * full later (right before we handle its contents). */
                        if (statret == 0
-                        && (S_ISDIR(sx.st.st_mode)
+                        && (stype == FT_DIR
                          || delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_DIR) != 0))
                                goto cleanup; /* Any errors get reported later. */
                        if (do_mkdir(fname, (file->mode|added_perms) & 0700) == 0)
@@ -1424,7 +1436,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                 * file of that name and it is *not* a directory, then
                 * we need to delete it.  If it doesn't exist, then
                 * (perhaps recursively) create it. */
-               if (statret == 0 && !S_ISDIR(sx.st.st_mode)) {
+               if (statret == 0 && stype != FT_DIR) {
                        if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_DIR) != 0)
                                goto skipping_dir_contents;
                        statret = -1;
@@ -1508,7 +1520,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                else if (delete_during && f_out != -1 && !phase
                    && !(file->flags & FLAG_MISSING_DIR)) {
                        if (file->flags & FLAG_CONTENT_DIR)
-                               delete_in_dir(fname, file, &real_sx.st.st_dev);
+                               delete_in_dir(fname, file, real_sx.st.st_dev);
                        else
                                change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
                }
@@ -1519,7 +1531,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
        /* If we're not preserving permissions, change the file-list's
         * mode based on the local permissions and some heuristics. */
        if (!preserve_perms) {
-               int exists = statret == 0 && !S_ISDIR(sx.st.st_mode);
+               int exists = statret == 0 && stype != FT_DIR;
                file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms, exists);
        }
 
@@ -1529,7 +1541,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
 #endif
 
-       if (preserve_links && S_ISLNK(file->mode)) {
+       if (preserve_links && ftype == FT_SYMLINK) {
 #ifdef SUPPORT_LINKS
                const char *sl = F_SYMLINK(file);
                if (safe_symlinks && unsafe_symlink(sl, fname)) {
@@ -1546,12 +1558,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        goto cleanup;
                }
                if (statret == 0) {
-                       char lnk[MAXPATHLEN];
-                       int len;
-
-                       if (S_ISLNK(sx.st.st_mode)
-                        && (len = do_readlink(fname, lnk, MAXPATHLEN-1)) > 0
-                        && strncmp(lnk, sl, len) == 0 && sl[len] == '\0') {
+                       if (stype == FT_SYMLINK && quick_check_ok(stype, fname, file, &sx.st)) {
                                /* The link is pointing to the right place. */
                                set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
                                if (itemizing)
@@ -1584,7 +1591,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                if (atomic_create(file, fname, sl, NULL, MAKEDEV(0, 0), &sx, statret == 0 ? DEL_FOR_SYMLINK : 0)) {
                        set_file_attrs(fname, file, NULL, NULL, 0);
                        if (itemizing) {
-                               if (statret == 0 && !S_ISLNK(sx.st.st_mode))
+                               if (statret == 0 && stype != FT_SYMLINK)
                                        statret = -1;
                                itemize(fnamecmp, file, ndx, statret, &sx,
                                        ITEM_LOCAL_CHANGE|ITEM_REPORT_CHANGE, 0, NULL);
@@ -1605,28 +1612,22 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
 
-       if ((am_root && preserve_devices && IS_DEVICE(file->mode))
-        || (preserve_specials && IS_SPECIAL(file->mode))) {
+       if ((am_root && preserve_devices && ftype == FT_DEVICE)
+        || (preserve_specials && ftype == FT_SPECIAL)) {
                dev_t rdev;
-               int del_for_flag = 0;
-               if (IS_DEVICE(file->mode)) {
+               int del_for_flag;
+               if (ftype == FT_DEVICE) {
                        uint32 *devp = F_RDEV_P(file);
                        rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
-               } else
+                       del_for_flag = DEL_FOR_DEVICE;
+               } else {
                        rdev = 0;
+                       del_for_flag = DEL_FOR_SPECIAL;
+               }
                if (statret == 0) {
-                       if (IS_DEVICE(file->mode)) {
-                               if (!IS_DEVICE(sx.st.st_mode))
-                                       statret = -1;
-                               del_for_flag = DEL_FOR_DEVICE;
-                       } else {
-                               if (!IS_SPECIAL(sx.st.st_mode))
-                                       statret = -1;
-                               del_for_flag = DEL_FOR_SPECIAL;
-                       }
-                       if (statret == 0
-                        && BITS_EQUAL(sx.st.st_mode, file->mode, _S_IFMT)
-                        && (IS_SPECIAL(sx.st.st_mode) || sx.st.st_rdev == rdev)) {
+                       if (ftype != stype)
+                               statret = -1;
+                       else if (quick_check_ok(ftype, fname, file, &sx.st)) {
                                /* The device or special file is identical. */
                                set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
                                if (itemizing)
@@ -1679,10 +1680,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
 
-       if (!S_ISREG(file->mode)) {
-               if (solo_file)
-                       fname = f_name(file, NULL);
-               rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
+       if (ftype != FT_REG) {
+               if (INFO_GTE(NONREG, 1)) {
+                       if (solo_file)
+                               fname = f_name(file, NULL);
+                       rprintf(FINFO, "skipping non-regular file \"%s\"\n", fname);
+               }
                goto cleanup;
        }
 
@@ -1703,7 +1706,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
 
-       if (update_only > 0 && statret == 0 && file->modtime - sx.st.st_mtime <= modify_window) {
+       if (update_only > 0 && statret == 0 && file->modtime - sx.st.st_mtime < modify_window) {
                if (INFO_GTE(SKIP, 1))
                        rprintf(FINFO, "%s is newer\n", fname);
 #ifdef SUPPORT_HARD_LINKS
@@ -1715,7 +1718,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 
        fnamecmp_type = FNAMECMP_FNAME;
 
-       if (statret == 0 && !(S_ISREG(sx.st.st_mode) || (write_devices && IS_DEVICE(sx.st.st_mode)))) {
+       if (statret == 0 && !(stype == FT_REG || (write_devices && stype == FT_DEVICE))) {
                if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0)
                        goto cleanup;
                statret = -1;
@@ -1749,7 +1752,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                partialptr = NULL;
 
        if (statret != 0 && fuzzy_basis) {
-               if (need_fuzzy_dirlist && S_ISREG(file->mode)) {
+               if (need_fuzzy_dirlist) {
                        const char *dn = file->dirname ? file->dirname : ".";
                        int i;
                        strlcpy(fnamecmpbuf, dn, sizeof fnamecmpbuf);
@@ -1793,11 +1796,17 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
 
+       if (write_devices && IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0) {
+               /* This early open into fd skips the regular open below. */
+               if ((fd = do_open(fnamecmp, O_RDONLY, 0)) >= 0)
+                       real_sx.st.st_size = sx.st.st_size = get_device_size(fd, fnamecmp);
+       }
+
        if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
                ;
        else if (fnamecmp_type >= FNAMECMP_FUZZY)
                ;
-       else if (unchanged_file(fnamecmp, file, &sx.st)) {
+       else if (quick_check_ok(FT_REG, fnamecmp, file, &sx.st)) {
                if (partialptr) {
                        do_unlink(partialptr);
                        handle_partial_dir(partialptr, PDIR_DELETE);
@@ -1813,7 +1822,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        goto cleanup;
          return_with_success:
                if (!dry_run)
-                       send_msg_int(MSG_SUCCESS, ndx);
+                       send_msg_success(fname, ndx);
                goto cleanup;
        }
 
@@ -1858,7 +1867,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
        }
 
        /* open the file */
-       if ((fd = do_open(fnamecmp, O_RDONLY, 0)) < 0) {
+       if (fd < 0 && (fd = do_open(fnamecmp, O_RDONLY, 0)) < 0) {
                rsyserr(FERROR, errno, "failed to open %s, continuing",
                        full_fname(fnamecmp));
          pretend_missing:
@@ -1875,11 +1884,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 
        if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) {
                if (!(backupptr = get_backup_name(fname))) {
-                       close(fd);
                        goto cleanup;
                }
                if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) {
-                       close(fd);
                        goto pretend_missing;
                }
                if (robust_unlink(backupptr) && errno != ENOENT) {
@@ -1887,14 +1894,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                                full_fname(backupptr));
                        unmake_file(back_file);
                        back_file = NULL;
-                       close(fd);
                        goto cleanup;
                }
                if ((f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
                        rsyserr(FERROR_XFER, errno, "open %s", full_fname(backupptr));
                        unmake_file(back_file);
                        back_file = NULL;
-                       close(fd);
                        goto cleanup;
                }
                fnamecmp_type = FNAMECMP_BACKUP;
@@ -1945,7 +1950,6 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                write_sum_head(f_out, NULL);
        else if (sx.st.st_size <= 0) {
                write_sum_head(f_out, NULL);
-               close(fd);
        } else {
                if (generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy) < 0) {
                        rprintf(FWARNING,
@@ -1953,10 +1957,11 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                                fnamecmp);
                        write_sum_head(f_out, NULL);
                }
-               close(fd);
        }
 
   cleanup:
+       if (fd >= 0)
+               close(fd);
        if (back_file) {
                int save_preserve_xattrs = preserve_xattrs;
                if (f_copy >= 0)
@@ -2242,7 +2247,7 @@ void generate_files(int f_out, const char *local_name)
        }
        solo_file = local_name;
        dir_tweaking = !(list_only || solo_file || dry_run);
-       need_retouch_dir_times = preserve_times & PRESERVE_DIR_TIMES;
+       need_retouch_dir_times = preserve_mtimes && !omit_dir_times;
        loopchk_limit = allowed_lull ? allowed_lull * 5 : 200;
        symlink_timeset_failed_flags = ITEM_REPORT_TIME
            | (protocol_version >= 30 || !am_server ? ITEM_REPORT_TIMEFAIL : 0);
@@ -2295,7 +2300,7 @@ void generate_files(int f_out, const char *local_name)
                                                dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
                                        } else
                                                dirdev = MAKEDEV(0, 0);
-                                       delete_in_dir(fbuf, fp, &dirdev);
+                                       delete_in_dir(fbuf, fp, dirdev);
                                } else
                                        change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
                        }
@@ -2342,7 +2347,7 @@ void generate_files(int f_out, const char *local_name)
        } while ((cur_flist = cur_flist->next) != NULL);
 
        if (delete_during)
-               delete_in_dir(NULL, NULL, &dev_zero);
+               delete_in_dir(NULL, NULL, dev_zero);
        phase++;
        if (DEBUG_GTE(GENR, 1))
                rprintf(FINFO, "generate_files phase=%d\n", phase);
index e272f43..2cc4e55 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Routines to provide a memory-efficient hashtable.
  *
- * Copyright (C) 2007-2020 Wayne Davison
+ * Copyright (C) 2007-2022 Wayne Davison
  *
  * 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
@@ -350,6 +350,9 @@ void *hashtable_find(struct hashtable *tbl, int64 key, void *data_when_new)
  -------------------------------------------------------------------------------
 */
 
+#define NON_ZERO_32(x) ((x) ? (x) : (uint32_t)1)
+#define NON_ZERO_64(x, y) ((x) || (y) ? (y) | (int64)(x) << 32 | (y) : (int64)1)
+
 uint32_t hashlittle(const void *key, size_t length)
 {
   uint32_t a,b,c;                                          /* internal state */
@@ -390,7 +393,7 @@ uint32_t hashlittle(const void *key, size_t length)
     case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */
     case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */
     case 1 : a+=k8[0]; break;
-    case 0 : return c;
+    case 0 : return NON_ZERO_32(c);
     }
   } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
     const uint16_t *k = (const uint16_t *)key;         /* read 16-bit chunks */
@@ -436,7 +439,7 @@ uint32_t hashlittle(const void *key, size_t length)
              break;
     case 1 : a+=k8[0];
              break;
-    case 0 : return c;                     /* zero length requires no mixing */
+    case 0 : return NON_ZERO_32(c);         /* zero length requires no mixing */
     }
 
   } else {                        /* need to read the key one byte at a time */
@@ -489,10 +492,171 @@ uint32_t hashlittle(const void *key, size_t length)
             /* FALLTHROUGH */
     case 1 : a+=k[0];
              break;
-    case 0 : return c;
+    case 0 : return NON_ZERO_32(c);
     }
   }
 
   final(a,b,c);
-  return c;
+  return NON_ZERO_32(c);
 }
+
+#if SIZEOF_INT64 >= 8
+/*
+ * hashlittle2: return 2 32-bit hash values joined into an int64.
+ *
+ * This is identical to hashlittle(), except it returns two 32-bit hash
+ * values instead of just one.  This is good enough for hash table
+ * lookup with 2^^64 buckets, or if you want a second hash if you're not
+ * happy with the first, or if you want a probably-unique 64-bit ID for
+ * the key.  *pc is better mixed than *pb, so use *pc first.  If you want
+ * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
+ */
+int64 hashlittle2(const void *key, size_t length)
+{
+  uint32_t a,b,c;                                          /* internal state */
+  union { const void *ptr; size_t i; } u;     /* needed for Mac Powerbook G4 */
+
+  /* Set up the internal state */
+  a = b = c = 0xdeadbeef + ((uint32_t)length);
+
+  u.ptr = key;
+  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
+    const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
+    const uint8_t  *k8;
+
+    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      b += k[1];
+      c += k[2];
+      mix(a,b,c);
+      length -= 12;
+      k += 3;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    k8 = (const uint8_t *)k;
+    switch(length)
+    {
+    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+    case 11: c+=((uint32_t)k8[10])<<16;  /* fall through */
+    case 10: c+=((uint32_t)k8[9])<<8;    /* fall through */
+    case 9 : c+=k8[8];                   /* fall through */
+    case 8 : b+=k[1]; a+=k[0]; break;
+    case 7 : b+=((uint32_t)k8[6])<<16;   /* fall through */
+    case 6 : b+=((uint32_t)k8[5])<<8;    /* fall through */
+    case 5 : b+=k8[4];                   /* fall through */
+    case 4 : a+=k[0]; break;
+    case 3 : a+=((uint32_t)k8[2])<<16;   /* fall through */
+    case 2 : a+=((uint32_t)k8[1])<<8;    /* fall through */
+    case 1 : a+=k8[0]; break;
+    case 0 : return NON_ZERO_64(b, c);
+    }
+  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
+    const uint16_t *k = (const uint16_t *)key;         /* read 16-bit chunks */
+    const uint8_t  *k8;
+
+    /*--------------- all but last block: aligned reads and different mixing */
+    while (length > 12)
+    {
+      a += k[0] + (((uint32_t)k[1])<<16);
+      b += k[2] + (((uint32_t)k[3])<<16);
+      c += k[4] + (((uint32_t)k[5])<<16);
+      mix(a,b,c);
+      length -= 12;
+      k += 6;
+    }
+
+    /*----------------------------- handle the last (probably partial) block */
+    k8 = (const uint8_t *)k;
+    switch(length)
+    {
+    case 12: c+=k[4]+(((uint32_t)k[5])<<16);
+             b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 11: c+=((uint32_t)k8[10])<<16;     /* fall through */
+    case 10: c+=k[4];
+             b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 9 : c+=k8[8];                      /* fall through */
+    case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 7 : b+=((uint32_t)k8[6])<<16;      /* fall through */
+    case 6 : b+=k[2];
+             a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 5 : b+=k8[4];                      /* fall through */
+    case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
+             break;
+    case 3 : a+=((uint32_t)k8[2])<<16;      /* fall through */
+    case 2 : a+=k[0];
+             break;
+    case 1 : a+=k8[0];
+             break;
+    case 0 : return NON_ZERO_64(b, c);  /* zero length strings require no mixing */
+    }
+
+  } else {                        /* need to read the key one byte at a time */
+    const uint8_t *k = (const uint8_t *)key;
+
+    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+    while (length > 12)
+    {
+      a += k[0];
+      a += ((uint32_t)k[1])<<8;
+      a += ((uint32_t)k[2])<<16;
+      a += ((uint32_t)k[3])<<24;
+      b += k[4];
+      b += ((uint32_t)k[5])<<8;
+      b += ((uint32_t)k[6])<<16;
+      b += ((uint32_t)k[7])<<24;
+      c += k[8];
+      c += ((uint32_t)k[9])<<8;
+      c += ((uint32_t)k[10])<<16;
+      c += ((uint32_t)k[11])<<24;
+      mix(a,b,c);
+      length -= 12;
+      k += 12;
+    }
+
+    /*-------------------------------- last block: affect all 32 bits of (c) */
+    switch(length)                   /* all the case statements fall through */
+    {
+    case 12: c+=((uint32_t)k[11])<<24;
+            /* FALLTHROUGH */
+    case 11: c+=((uint32_t)k[10])<<16;
+            /* FALLTHROUGH */
+    case 10: c+=((uint32_t)k[9])<<8;
+            /* FALLTHROUGH */
+    case 9 : c+=k[8];
+            /* FALLTHROUGH */
+    case 8 : b+=((uint32_t)k[7])<<24;
+            /* FALLTHROUGH */
+    case 7 : b+=((uint32_t)k[6])<<16;
+            /* FALLTHROUGH */
+    case 6 : b+=((uint32_t)k[5])<<8;
+            /* FALLTHROUGH */
+    case 5 : b+=k[4];
+            /* FALLTHROUGH */
+    case 4 : a+=((uint32_t)k[3])<<24;
+            /* FALLTHROUGH */
+    case 3 : a+=((uint32_t)k[2])<<16;
+            /* FALLTHROUGH */
+    case 2 : a+=((uint32_t)k[1])<<8;
+            /* FALLTHROUGH */
+    case 1 : a+=k[0];
+             break;
+    case 0 : return NON_ZERO_64(b, c);
+    }
+  }
+
+  final(a,b,c);
+  return NON_ZERO_64(b, c);
+}
+#else
+#define hashlittle2(key, len) hashlittle(key, len)
+#endif
diff --git a/hlink.c b/hlink.c
index adec89b..20291f2 100644 (file)
--- a/hlink.c
+++ b/hlink.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2004-2020 Wayne Davison
+ * Copyright (C) 2004-2022 Wayne Davison
  *
  * 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
@@ -406,7 +406,7 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
                                }
                                break;
                        }
-                       if (!unchanged_file(cmpbuf, file, &alt_sx.st))
+                       if (!quick_check_ok(FT_REG, cmpbuf, file, &alt_sx.st))
                                continue;
                        statret = 1;
                        if (unchanged_attrs(cmpbuf, file, &alt_sx))
@@ -446,7 +446,7 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
                return -1;
 
        if (remove_source_files == 1 && do_xfers)
-               send_msg_int(MSG_SUCCESS, ndx);
+               send_msg_success(fname, ndx);
 
        return 1;
 }
@@ -519,7 +519,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
                if (val < 0)
                        continue;
                if (remove_source_files == 1 && do_xfers)
-                       send_msg_int(MSG_SUCCESS, ndx);
+                       send_msg_success(fname, ndx);
        }
 
        if (inc_recurse) {
index 4037639..956fc22 100644 (file)
--- a/ifuncs.h
+++ b/ifuncs.h
@@ -1,6 +1,6 @@
 /* Inline functions for rsync.
  *
- * Copyright (C) 2007-2020 Wayne Davison
+ * Copyright (C) 2007-2022 Wayne Davison
  *
  * 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
@@ -75,6 +75,7 @@ d_name(struct dirent *di)
 static inline void
 init_stat_x(stat_x *sx_p)
 {
+       sx_p->crtime = 0;
 #ifdef SUPPORT_ACLS
        sx_p->acc_acl = sx_p->def_acl = NULL;
 #endif
index 956817d..8c409fb 100755 (executable)
@@ -115,7 +115,7 @@ else
 # might cause directories to be created, which would be especially bad 
 # if $src (and thus $dsttmp) contains '*'.
 
-       if [ -f $src -o -d $src ]
+       if [ -f $src ] || [ -d $src ]
        then
                true
        else
diff --git a/io.c b/io.c
index b50a066..a99ac0e 100644 (file)
--- a/io.c
+++ b/io.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2001 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -41,6 +41,7 @@ extern int am_server;
 extern int am_sender;
 extern int am_receiver;
 extern int am_generator;
+extern int local_server;
 extern int msgs2stderr;
 extern int inc_recurse;
 extern int io_error;
@@ -84,6 +85,8 @@ int sock_f_out = -1;
 int64 total_data_read = 0;
 int64 total_data_written = 0;
 
+char num_dev_ino_buf[4 + 8 + 8];
+
 static struct {
        xbuf in, out, msg;
        int in_fd;
@@ -264,15 +267,18 @@ static size_t safe_read(int fd, char *buf, size_t len)
                        rprintf(FINFO, "select exception on fd %d\n", fd); */
 
                if (FD_ISSET(fd, &r_fds)) {
-                       int n = read(fd, buf + got, len - got);
-                       if (DEBUG_GTE(IO, 2))
-                               rprintf(FINFO, "[%s] safe_read(%d)=%ld\n", who_am_i(), fd, (long)n);
+                       ssize_t n = read(fd, buf + got, len - got);
+                       if (DEBUG_GTE(IO, 2)) {
+                               rprintf(FINFO, "[%s] safe_read(%d)=%" SIZE_T_FMT_MOD "d\n",
+                                       who_am_i(), fd, (SIZE_T_FMT_CAST)n);
+                       }
                        if (n == 0)
                                break;
                        if (n < 0) {
                                if (errno == EINTR)
                                        continue;
-                               rsyserr(FERROR, errno, "safe_read failed to read %ld bytes", (long)len);
+                               rsyserr(FERROR, errno, "safe_read failed to read %" SIZE_T_FMT_MOD "d bytes",
+                                       (SIZE_T_FMT_CAST)len);
                                exit_cleanup(RERR_STREAMIO);
                        }
                        if ((got += (size_t)n) == len)
@@ -304,7 +310,7 @@ static const char *what_fd_is(int fd)
  * is not used on the socket except very early in the transfer. */
 static void safe_write(int fd, const char *buf, size_t len)
 {
-       int n;
+       ssize_t n;
 
        assert(fd != iobuf.out_fd);
 
@@ -315,8 +321,8 @@ static void safe_write(int fd, const char *buf, size_t len)
                if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) {
                  write_failed:
                        rsyserr(FERROR, errno,
-                               "safe_write failed to write %ld bytes to %s",
-                               (long)len, what_fd_is(fd));
+                               "safe_write failed to write %" SIZE_T_FMT_MOD "d bytes to %s",
+                               (SIZE_T_FMT_CAST)len, what_fd_is(fd));
                        exit_cleanup(RERR_STREAMIO);
                }
        } else {
@@ -362,7 +368,7 @@ static void safe_write(int fd, const char *buf, size_t len)
  * a chunk of data and put it into the output buffer. */
 static void forward_filesfrom_data(void)
 {
-       int len;
+       ssize_t len;
 
        len = read(ff_forward_fd, ff_xb.buf + ff_xb.len, ff_xb.size - ff_xb.len);
        if (len <= 0) {
@@ -373,12 +379,15 @@ static void forward_filesfrom_data(void)
                        free_xbuf(&ff_xb);
                        if (ff_reenable_multiplex >= 0)
                                io_start_multiplex_out(ff_reenable_multiplex);
+                       free_implied_include_partial_string();
                }
                return;
        }
 
-       if (DEBUG_GTE(IO, 2))
-               rprintf(FINFO, "[%s] files-from read=%ld\n", who_am_i(), (long)len);
+       if (DEBUG_GTE(IO, 2)) {
+               rprintf(FINFO, "[%s] files-from read=%" SIZE_T_FMT_MOD "d\n",
+                       who_am_i(), (SIZE_T_FMT_CAST)len);
+       }
 
 #ifdef ICONV_OPTION
        len += ff_xb.len;
@@ -414,6 +423,7 @@ static void forward_filesfrom_data(void)
                while (s != eob) {
                        if (*s++ == '\0') {
                                ff_xb.len = s - sob - 1;
+                               add_implied_include(sob, 0);
                                if (iconvbufs(ic_send, &ff_xb, &iobuf.out, flags) < 0)
                                        exit_cleanup(RERR_PROTOCOL); /* impossible? */
                                write_buf(iobuf.out_fd, s-1, 1); /* Send the '\0'. */
@@ -429,6 +439,7 @@ static void forward_filesfrom_data(void)
                        ff_lastchar = '\0';
                else {
                        /* Handle a partial string specially, saving any incomplete chars. */
+                       implied_include_partial_string(sob, s);
                        flags &= ~ICB_INCLUDE_INCOMPLETE;
                        if (iconvbufs(ic_send, &ff_xb, &iobuf.out, flags) < 0) {
                                if (errno == E2BIG)
@@ -445,13 +456,17 @@ static void forward_filesfrom_data(void)
                char *f = ff_xb.buf + ff_xb.pos;
                char *t = ff_xb.buf;
                char *eob = f + len;
+               char *cur = t;
                /* Eliminate any multi-'\0' runs. */
                while (f != eob) {
                        if (!(*t++ = *f++)) {
+                               add_implied_include(cur, 0);
+                               cur = t;
                                while (f != eob && *f == '\0')
                                        f++;
                        }
                }
+               implied_include_partial_string(cur, t);
                ff_lastchar = f[-1];
                if ((len = t - ff_xb.buf) != 0) {
                        /* This will not circle back to perform_io() because we only get
@@ -562,52 +577,59 @@ static char *perform_io(size_t needed, int flags)
        case PIO_NEED_INPUT:
                /* We never resize the circular input buffer. */
                if (iobuf.in.size < needed) {
-                       rprintf(FERROR, "need to read %ld bytes, iobuf.in.buf is only %ld bytes.\n",
-                               (long)needed, (long)iobuf.in.size);
+                       rprintf(FERROR, "need to read %" SIZE_T_FMT_MOD "d bytes,"
+                                       " iobuf.in.buf is only %" SIZE_T_FMT_MOD "d bytes.\n",
+                               (SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)iobuf.in.size);
                        exit_cleanup(RERR_PROTOCOL);
                }
 
                if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
-                       rprintf(FINFO, "[%s] perform_io(%ld, %sinput)\n",
-                               who_am_i(), (long)needed, flags & PIO_CONSUME_INPUT ? "consume&" : "");
+                       rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d, %sinput)\n",
+                               who_am_i(), (SIZE_T_FMT_CAST)needed, flags & PIO_CONSUME_INPUT ? "consume&" : "");
                }
                break;
 
        case PIO_NEED_OUTROOM:
                /* We never resize the circular output buffer. */
                if (iobuf.out.size - iobuf.out_empty_len < needed) {
-                       fprintf(stderr, "need to write %ld bytes, iobuf.out.buf is only %ld bytes.\n",
-                               (long)needed, (long)(iobuf.out.size - iobuf.out_empty_len));
+                       fprintf(stderr, "need to write %" SIZE_T_FMT_MOD "d bytes,"
+                                       " iobuf.out.buf is only %" SIZE_T_FMT_MOD "d bytes.\n",
+                               (SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)(iobuf.out.size - iobuf.out_empty_len));
                        exit_cleanup(RERR_PROTOCOL);
                }
 
                if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
-                       rprintf(FINFO, "[%s] perform_io(%ld, outroom) needs to flush %ld\n",
-                               who_am_i(), (long)needed,
+                       rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d,"
+                                      " outroom) needs to flush %" SIZE_T_FMT_MOD "d\n",
+                               who_am_i(), (SIZE_T_FMT_CAST)needed,
                                iobuf.out.len + needed > iobuf.out.size
-                               ? (long)(iobuf.out.len + needed - iobuf.out.size) : 0L);
+                               ? (SIZE_T_FMT_CAST)(iobuf.out.len + needed - iobuf.out.size) : (SIZE_T_FMT_CAST)0);
                }
                break;
 
        case PIO_NEED_MSGROOM:
                /* We never resize the circular message buffer. */
                if (iobuf.msg.size < needed) {
-                       fprintf(stderr, "need to write %ld bytes, iobuf.msg.buf is only %ld bytes.\n",
-                               (long)needed, (long)iobuf.msg.size);
+                       fprintf(stderr, "need to write %" SIZE_T_FMT_MOD "d bytes,"
+                                       " iobuf.msg.buf is only %" SIZE_T_FMT_MOD "d bytes.\n",
+                               (SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)iobuf.msg.size);
                        exit_cleanup(RERR_PROTOCOL);
                }
 
                if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
-                       rprintf(FINFO, "[%s] perform_io(%ld, msgroom) needs to flush %ld\n",
-                               who_am_i(), (long)needed,
+                       rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d,"
+                                      " msgroom) needs to flush %" SIZE_T_FMT_MOD "d\n",
+                               who_am_i(), (SIZE_T_FMT_CAST)needed,
                                iobuf.msg.len + needed > iobuf.msg.size
-                               ? (long)(iobuf.msg.len + needed - iobuf.msg.size) : 0L);
+                               ? (SIZE_T_FMT_CAST)(iobuf.msg.len + needed - iobuf.msg.size) : (SIZE_T_FMT_CAST)0);
                }
                break;
 
        case 0:
-               if (msgs2stderr == 1 && DEBUG_GTE(IO, 3))
-                       rprintf(FINFO, "[%s] perform_io(%ld, %d)\n", who_am_i(), (long)needed, flags);
+               if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
+                       rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d, %d)\n",
+                               who_am_i(), (SIZE_T_FMT_CAST)needed, flags);
+               }
                break;
 
        default:
@@ -665,8 +687,8 @@ static char *perform_io(size_t needed, int flags)
                                              ((MPLEX_BASE + (int)MSG_DATA)<<24) + iobuf.out.len - 4);
 
                                        if (msgs2stderr == 1 && DEBUG_GTE(IO, 1)) {
-                                               rprintf(FINFO, "[%s] send_msg(%d, %ld)\n",
-                                                       who_am_i(), (int)MSG_DATA, (long)iobuf.out.len - 4);
+                                               rprintf(FINFO, "[%s] send_msg(%d, %" SIZE_T_FMT_MOD "d)\n",
+                                                       who_am_i(), (int)MSG_DATA, (SIZE_T_FMT_CAST)iobuf.out.len - 4);
                                        }
 
                                        /* reserve room for the next MSG_DATA header */
@@ -757,7 +779,7 @@ static char *perform_io(size_t needed, int flags)
 
                if (iobuf.in_fd >= 0 && FD_ISSET(iobuf.in_fd, &r_fds)) {
                        size_t len, pos = iobuf.in.pos + iobuf.in.len;
-                       int n;
+                       ssize_t n;
                        if (pos >= iobuf.in.size) {
                                pos -= iobuf.in.size;
                                len = iobuf.in.size - iobuf.in.len;
@@ -784,15 +806,13 @@ static char *perform_io(size_t needed, int flags)
                                        exit_cleanup(RERR_SOCKETIO);
                                }
                        }
-                       if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
-                               rprintf(FINFO, "[%s] recv=%ld\n", who_am_i(), (long)n);
+                       if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
+                               rprintf(FINFO, "[%s] recv=%" SIZE_T_FMT_MOD "d\n",
+                                       who_am_i(), (SIZE_T_FMT_CAST)n);
+                       }
 
-                       if (io_timeout || stop_at_utime) {
+                       if (io_timeout) {
                                last_io_in = time(NULL);
-                               if (stop_at_utime && last_io_in >= stop_at_utime) {
-                                       rprintf(FERROR, "stopping at requested limit\n");
-                                       exit_cleanup(RERR_TIMEOUT);
-                               }
                                if (io_timeout && flags & PIO_NEED_INPUT)
                                        maybe_send_keepalive(last_io_in, 0);
                        }
@@ -801,9 +821,14 @@ static char *perform_io(size_t needed, int flags)
                        iobuf.in.len += n;
                }
 
+               if (stop_at_utime && time(NULL) >= stop_at_utime) {
+                       rprintf(FERROR, "stopping at requested limit\n");
+                       exit_cleanup(RERR_TIMEOUT);
+               }
+
                if (out && FD_ISSET(iobuf.out_fd, &w_fds)) {
                        size_t len = iobuf.raw_flushing_ends_before ? iobuf.raw_flushing_ends_before - out->pos : out->len;
-                       int n;
+                       ssize_t n;
 
                        if (bwlimit_writemax && len > bwlimit_writemax)
                                len = bwlimit_writemax;
@@ -824,8 +849,8 @@ static char *perform_io(size_t needed, int flags)
                                }
                        }
                        if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
-                               rprintf(FINFO, "[%s] %s sent=%ld\n",
-                                       who_am_i(), out == &iobuf.out ? "out" : "msg", (long)n);
+                               rprintf(FINFO, "[%s] %s sent=%" SIZE_T_FMT_MOD "d\n",
+                                       who_am_i(), out == &iobuf.out ? "out" : "msg", (SIZE_T_FMT_CAST)n);
                        }
 
                        if (io_timeout)
@@ -945,8 +970,10 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert)
        if (!OUT_MULTIPLEXED)
                return 0;
 
-       if (want_debug)
-               rprintf(FINFO, "[%s] send_msg(%d, %ld)\n", who_am_i(), (int)code, (long)len);
+       if (want_debug) {
+               rprintf(FINFO, "[%s] send_msg(%d, %" SIZE_T_FMT_MOD "d)\n",
+                       who_am_i(), (int)code, (SIZE_T_FMT_CAST)len);
+       }
 
        /* When checking for enough free space for this message, we need to
         * make sure that there is space for the 4-byte header, plus we'll
@@ -962,9 +989,9 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert)
 #endif
                needed = len + 4 + 3;
        if (iobuf.msg.len + needed > iobuf.msg.size) {
-               if (!am_receiver)
+               if (am_sender)
                        perform_io(needed, PIO_NEED_MSGROOM);
-               else { /* We allow the receiver to increase their iobuf.msg size to avoid a deadlock. */
+               else { /* We sometimes allow the iobuf.msg size to increase to avoid a deadlock. */
                        size_t old_size = iobuf.msg.size;
                        restore_iobuf_size(&iobuf.msg);
                        realloc_xbuf(&iobuf.msg, iobuf.msg.size * 2);
@@ -1021,8 +1048,10 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert)
 
        SIVAL(hdr, 0, ((MPLEX_BASE + (int)code)<<24) + len);
 
-       if (want_debug && convert > 0)
-               rprintf(FINFO, "[%s] converted msg len=%ld\n", who_am_i(), (long)len);
+       if (want_debug && convert > 0) {
+               rprintf(FINFO, "[%s] converted msg len=%" SIZE_T_FMT_MOD "d\n",
+                       who_am_i(), (SIZE_T_FMT_CAST)len);
+       }
 
        return 1;
 }
@@ -1038,6 +1067,24 @@ void send_msg_int(enum msgcode code, int num)
        send_msg(code, numbuf, 4, -1);
 }
 
+void send_msg_success(const char *fname, int num)
+{
+       if (local_server) {
+               STRUCT_STAT st;
+
+               if (DEBUG_GTE(IO, 1))
+                       rprintf(FINFO, "[%s] send_msg_success(%d)\n", who_am_i(), num);
+
+               if (stat(fname, &st) < 0)
+                       memset(&st, 0, sizeof (STRUCT_STAT));
+               SIVAL(num_dev_ino_buf, 0, num);
+               SIVAL64(num_dev_ino_buf, 4, st.st_dev);
+               SIVAL64(num_dev_ino_buf, 4+8, st.st_ino);
+               send_msg(MSG_SUCCESS, num_dev_ino_buf, sizeof num_dev_ino_buf, -1);
+       } else
+               send_msg_int(MSG_SUCCESS, num);
+}
+
 static void got_flist_entry_status(enum festatus status, int ndx)
 {
        struct file_list *flist = flist_for_ndx(ndx, "got_flist_entry_status");
@@ -1052,8 +1099,12 @@ static void got_flist_entry_status(enum festatus status, int ndx)
 
        switch (status) {
        case FES_SUCCESS:
-               if (remove_source_files)
-                       send_msg_int(MSG_SUCCESS, ndx);
+               if (remove_source_files) {
+                       if (local_server)
+                               send_msg(MSG_SUCCESS, num_dev_ino_buf, sizeof num_dev_ino_buf, -1);
+                       else
+                               send_msg_int(MSG_SUCCESS, ndx);
+               }
                /* FALL THROUGH */
        case FES_NO_SEND:
 #ifdef SUPPORT_HARD_LINKS
@@ -1436,8 +1487,10 @@ static void read_a_msg(void)
        msg_bytes = tag & 0xFFFFFF;
        tag = (tag >> 24) - MPLEX_BASE;
 
-       if (msgs2stderr == 1 && DEBUG_GTE(IO, 1))
-               rprintf(FINFO, "[%s] got msg=%d, len=%ld\n", who_am_i(), (int)tag, (long)msg_bytes);
+       if (msgs2stderr == 1 && DEBUG_GTE(IO, 1)) {
+               rprintf(FINFO, "[%s] got msg=%d, len=%" SIZE_T_FMT_MOD "d\n",
+                       who_am_i(), (int)tag, (SIZE_T_FMT_CAST)msg_bytes);
+       }
 
        switch (tag) {
        case MSG_DATA:
@@ -1546,14 +1599,15 @@ static void read_a_msg(void)
                }
                break;
        case MSG_SUCCESS:
-               if (msg_bytes != 4) {
+               if (msg_bytes != (local_server ? 4+8+8 : 4)) {
                  invalid_msg:
                        rprintf(FERROR, "invalid multi-message %d:%lu [%s%s]\n",
                                tag, (unsigned long)msg_bytes, who_am_i(),
                                inc_recurse ? "/inc" : "");
                        exit_cleanup(RERR_STREAMIO);
                }
-               val = raw_read_int();
+               raw_read_buf(num_dev_ino_buf, msg_bytes);
+               val = IVAL(num_dev_ino_buf, 0);
                iobuf.in_multiplexed = 1;
                if (am_generator)
                        got_flist_entry_status(FES_SUCCESS, val);
@@ -1613,8 +1667,10 @@ static void read_a_msg(void)
                else
                        goto invalid_msg;
                iobuf.in_multiplexed = 1;
-               if (DEBUG_GTE(EXIT, 3))
-                       rprintf(FINFO, "[%s] got MSG_ERROR_EXIT with %ld bytes\n", who_am_i(), (long)msg_bytes);
+               if (DEBUG_GTE(EXIT, 3)) {
+                       rprintf(FINFO, "[%s] got MSG_ERROR_EXIT with %" SIZE_T_FMT_MOD "d bytes\n",
+                                       who_am_i(), (SIZE_T_FMT_CAST)msg_bytes);
+               }
                if (msg_bytes == 0) {
                        if (!am_sender && !am_generator) {
                                if (DEBUG_GTE(EXIT, 3)) {
@@ -1728,6 +1784,13 @@ int32 read_int(int f)
        return num;
 }
 
+uint32 read_uint(int f)
+{
+       char b[4];
+       read_buf(f, b, 4);
+       return IVAL(b, 0);
+}
+
 int32 read_varint(int f)
 {
        union {
@@ -1820,6 +1883,7 @@ int64 read_longint(int f)
 #endif
 }
 
+/* Debugging note: this will be named read_buf_() when using an external zlib. */
 void read_buf(int f, char *buf, size_t len)
 {
        if (f != iobuf.in_fd) {
index db997bb..0a7111f 100644 (file)
--- a/itypes.h
+++ b/itypes.h
@@ -1,6 +1,6 @@
 /* Inline functions for rsync.
  *
- * Copyright (C) 2007-2020 Wayne Davison
+ * Copyright (C) 2007-2022 Wayne Davison
  *
  * 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
@@ -41,6 +41,12 @@ isSpace(const char *ptr)
 }
 
 static inline int
+isAlNum(const char *ptr)
+{
+       return isalnum(*(unsigned char *)ptr);
+}
+
+static inline int
 isLower(const char *ptr)
 {
        return islower(*(unsigned char *)ptr);
index ddbf2b5..37e8efb 100644 (file)
@@ -1 +1 @@
-#define LATEST_YEAR "2020"
+#define LATEST_YEAR "2022"
index 1410af5..6ef6a68 100644 (file)
@@ -1,11 +1,28 @@
 /* Keep this simple so both C and ASM can use it */
 
+/* These allow something like CFLAGS=-DDISABLE_SHA512_DIGEST */
+#ifdef DISABLE_SHA256_DIGEST
+#undef SHA256_DIGEST_LENGTH
+#endif
+#ifdef DISABLE_SHA512_DIGEST
+#undef SHA512_DIGEST_LENGTH
+#endif
+
 #define MD4_DIGEST_LEN 16
 #define MD5_DIGEST_LEN 16
+#if defined SHA512_DIGEST_LENGTH
+#define MAX_DIGEST_LEN SHA512_DIGEST_LENGTH
+#elif defined SHA256_DIGEST_LENGTH
+#define MAX_DIGEST_LEN SHA256_DIGEST_LENGTH
+#elif defined SHA_DIGEST_LENGTH
+#define MAX_DIGEST_LEN SHA_DIGEST_LENGTH
+#else
 #define MAX_DIGEST_LEN MD5_DIGEST_LEN
+#endif
 
 #define CSUM_CHUNK 64
 
+#define CSUM_gone -1
 #define CSUM_NONE 0
 #define CSUM_MD4_ARCHAIC 1
 #define CSUM_MD4_BUSTED 2
@@ -15,3 +32,6 @@
 #define CSUM_XXH64 6
 #define CSUM_XXH3_64 7
 #define CSUM_XXH3_128 8
+#define CSUM_SHA1 9
+#define CSUM_SHA256 10
+#define CSUM_SHA512 11
index 383f193..3737058 100644 (file)
@@ -27,7 +27,7 @@
 #include "config.h"
 #include "md-defines.h"
 
-#if !defined USE_OPENSSL && CSUM_CHUNK == 64
+#ifdef USE_MD5_ASM /* { */
 
 #ifdef __APPLE__
 #define md5_process_asm _md5_process_asm
@@ -698,4 +698,4 @@ md5_process_asm:
        pop     %rbp
        ret
 
-#endif /* !USE_OPENSSL ... */
+#endif /* } USE_MD5_ASM */
index 41f158b..f36c5ba 100644 (file)
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -2,7 +2,7 @@
  * RFC 1321 compliant MD5 implementation
  *
  * Copyright (C) 2001-2003 Christophe Devine
- * Copyright (C) 2007-2020 Wayne Davison
+ * Copyright (C) 2007-2022 Wayne Davison
  *
  * 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
@@ -20,7 +20,6 @@
 
 #include "rsync.h"
 
-#ifndef USE_OPENSSL
 void md5_begin(md_context *ctx)
 {
        ctx->A = 0x67452301;
@@ -148,7 +147,10 @@ static void md5_process(md_context *ctx, const uchar data[CSUM_CHUNK])
        ctx->D += D;
 }
 
-#if defined HAVE_ASM && CSUM_CHUNK == 64
+#ifdef USE_MD5_ASM
+#if CSUM_CHUNK != 64
+#error The MD5 ASM code does not support CSUM_CHUNK != 64
+#endif
 extern void md5_process_asm(md_context *ctx, const void *data, size_t num);
 #endif
 
@@ -176,20 +178,20 @@ void md5_update(md_context *ctx, const uchar *input, uint32 length)
                left = 0;
        }
 
-#if defined HAVE_ASM && CSUM_CHUNK == 64
+#ifdef USE_MD5_ASM /* { */
        if (length >= CSUM_CHUNK) {
                uint32 chunks = length / CSUM_CHUNK;
                md5_process_asm(ctx, input, chunks);
                length -= chunks * CSUM_CHUNK;
                input += chunks * CSUM_CHUNK;
        }
-#else
+#else /* } { */
        while (length >= CSUM_CHUNK) {
                md5_process(ctx, input);
                length -= CSUM_CHUNK;
                input  += CSUM_CHUNK;
        }
-#endif
+#endif /* } */
 
        if (length)
                memcpy(ctx->buffer + left, input, length);
@@ -221,9 +223,8 @@ void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN])
        SIVALu(digest, 8, ctx->C);
        SIVALu(digest, 12, ctx->D);
 }
-#endif
 
-#ifdef TEST_MD5
+#ifdef TEST_MD5 /* { */
 
 void get_md5(uchar *out, const uchar *input, int n)
 {
@@ -317,4 +318,4 @@ int main(int argc, char *argv[])
        return 0;
 }
 
-#endif
+#endif /* } */
index db17401..9d52ef5 100644 (file)
@@ -1,8 +1,8 @@
 /* The include file for both the MD4 and MD5 routines. */
 
 #ifdef USE_OPENSSL
-#include "openssl/md4.h"
-#include "openssl/md5.h"
+#include <openssl/sha.h>
+#include <openssl/evp.h>
 #endif
 #include "md-defines.h"
 
@@ -17,13 +17,6 @@ void mdfour_begin(md_context *md);
 void mdfour_update(md_context *md, const uchar *in, uint32 length);
 void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN]);
 
-#ifndef USE_OPENSSL
-#define MD5_CTX md_context
-#define MD5_Init md5_begin
-#define MD5_Update md5_update
-#define MD5_Final(digest, cptr) md5_result(cptr, digest)
-
 void md5_begin(md_context *ctx);
 void md5_update(md_context *ctx, const uchar *input, uint32 length);
 void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN]);
-#endif
index f6c6faf..a1a7245 100644 (file)
@@ -9,8 +9,7 @@ struct alloc_pool
        size_t                  size;           /* extent size          */
        size_t                  quantum;        /* allocation quantum   */
        struct pool_extent      *extents;       /* top extent is "live" */
-       void                    (*bomb)();      /* function to call if
-                                                * malloc fails         */
+       void                    (*bomb)();      /* called if malloc fails */
        int                     flags;
 
        /* statistical data */
@@ -49,7 +48,7 @@ pool_create(size_t size, size_t quantum, void (*bomb)(const char*, const char*,
 {
        struct alloc_pool *pool;
 
-       if ((MINALIGN & (MINALIGN - 1)) != 0) {
+       if ((MINALIGN & (MINALIGN - 1)) != (0)) {
                if (bomb)
                        (*bomb)("Compiler error: MINALIGN is not a power of 2", __FILE__, __LINE__);
                return NULL;
index 52fdd11..15c0529 100644 (file)
@@ -20,7 +20,7 @@
  * for string length.  This covers a nasty loophole.
  *
  * The other functions are there to prevent NULL pointers from
- * causing nast effects.
+ * causing nasty effects.
  *
  * More Recently:
  *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
index c23864f..a5abe40 100644 (file)
@@ -2,7 +2,7 @@
  * Unix SMB/CIFS implementation.
  * Based on the Samba ACL support code.
  * Copyright (C) Jeremy Allison 2000.
- * Copyright (C) 2007-2020 Wayne Davison
+ * Copyright (C) 2007-2022 Wayne Davison
  *
  * The permission functions have been changed to get/set all bits via
  * one call.  Some functions that rsync doesn't need were also removed.
@@ -175,7 +175,7 @@ int sys_acl_delete_def_file(const char *name)
        return acl_delete_def_file(name);
 }
 
-int sys_acl_free_acl(SMB_ACL_T the_acl) 
+int sys_acl_free_acl(SMB_ACL_T the_acl)
 {
        return acl_free(the_acl);
 }
@@ -185,7 +185,7 @@ int sys_acl_free_acl(SMB_ACL_T the_acl)
  * The interface to DEC/Compaq Tru64 UNIX ACLs
  * is based on Draft 13 of the POSIX spec which is
  * slightly different from the Draft 16 interface.
- * 
+ *
  * Also, some of the permset manipulation functions
  * such as acl_clear_perm() and acl_add_perm() appear
  * to be broken on Tru64 so we have to manipulate
@@ -310,7 +310,7 @@ int sys_acl_delete_def_file(const char *name)
        return acl_delete_def_file((char *)name);
 }
 
-int sys_acl_free_acl(SMB_ACL_T the_acl) 
+int sys_acl_free_acl(SMB_ACL_T the_acl)
 {
        return acl_free(the_acl);
 }
@@ -457,7 +457,7 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
                        break;
        }
        ndefault = count - naccess;
-       
+
        /*
         * if the caller wants the default ACL we have to copy
         * the entries down to the start of the acl[] buffer
@@ -517,7 +517,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
                if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
                        break;
        }
-       
+
        acl_d->count = naccess;
 
        return acl_d;
@@ -532,7 +532,7 @@ int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *b
 
        if (*tag_type_p == SMB_ACL_USER || *tag_type_p == SMB_ACL_GROUP)
                *u_g_id_p = entry->a_id;
-       
+
        return 0;
 }
 
@@ -633,7 +633,7 @@ static int acl_sort(SMB_ACL_T acl_d)
        }
        return 0;
 }
+
 int sys_acl_valid(SMB_ACL_T acl_d)
 {
        return acl_sort(acl_d);
@@ -755,11 +755,11 @@ int sys_acl_delete_def_file(const char *path)
        ret = acl(path, SETACL, acl_d->count, acl_d->acl);
 
        sys_acl_free_acl(acl_d);
-       
+
        return ret;
 }
 
-int sys_acl_free_acl(SMB_ACL_T acl_d) 
+int sys_acl_free_acl(SMB_ACL_T acl_d)
 {
        SAFE_FREE(acl_d);
        return 0;
@@ -895,10 +895,10 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
        int             ndefault;       /* # of default ACL entries     */
 
        if (hpux_acl_call_presence() == False) {
-               /* Looks like we don't have the acl() system call on HPUX. 
+               /* Looks like we don't have the acl() system call on HPUX.
                 * May be the system doesn't have the latest version of JFS.
                 */
-               return NULL; 
+               return NULL;
        }
 
        if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
@@ -949,7 +949,7 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
                        break;
        }
        ndefault = count - naccess;
-       
+
        /*
         * if the caller wants the default ACL we have to copy
         * the entries down to the start of the acl[] buffer
@@ -1109,9 +1109,9 @@ struct hpux_acl_types {
  * aclp           - Array of ACL structures.
  * acl_type_count - Pointer to acl_types structure. Should already be
  *                  allocated.
- * Output: 
+ * Output:
  *
- * acl_type_count - This structure is filled up with counts of various 
+ * acl_type_count - This structure is filled up with counts of various
  *                  acl types.
  */
 
@@ -1123,28 +1123,28 @@ static void hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_type
 
        for (i = 0; i < acl_count; i++) {
                switch (aclp[i].a_type) {
-               case USER: 
+               case USER:
                        acl_type_count->n_user++;
                        break;
-               case USER_OBJ: 
+               case USER_OBJ:
                        acl_type_count->n_user_obj++;
                        break;
-               case DEF_USER_OBJ: 
+               case DEF_USER_OBJ:
                        acl_type_count->n_def_user_obj++;
                        break;
-               case GROUP: 
+               case GROUP:
                        acl_type_count->n_group++;
                        break;
-               case GROUP_OBJ: 
+               case GROUP_OBJ:
                        acl_type_count->n_group_obj++;
                        break;
-               case DEF_GROUP_OBJ: 
+               case DEF_GROUP_OBJ:
                        acl_type_count->n_def_group_obj++;
                        break;
-               case OTHER_OBJ: 
+               case OTHER_OBJ:
                        acl_type_count->n_other_obj++;
                        break;
-               case DEF_OTHER_OBJ: 
+               case DEF_OTHER_OBJ:
                        acl_type_count->n_def_other_obj++;
                        break;
                case CLASS_OBJ:
@@ -1159,14 +1159,14 @@ static void hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_type
                case DEF_GROUP:
                        acl_type_count->n_def_group++;
                        break;
-               default: 
+               default:
                        acl_type_count->n_illegal_obj++;
                        break;
                }
        }
 }
 
-/* swap_acl_entries:  Swaps two ACL entries. 
+/* swap_acl_entries:  Swaps two ACL entries.
  *
  * Inputs: aclp0, aclp1 - ACL entries to be swapped.
  */
@@ -1189,25 +1189,25 @@ static void hpux_swap_acl_entries(struct acl *aclp0, struct acl *aclp1)
 }
 
 /* prohibited_duplicate_type
- * Identifies if given ACL type can have duplicate entries or 
+ * Identifies if given ACL type can have duplicate entries or
  * not.
  *
  * Inputs: acl_type - ACL Type.
  *
- * Outputs: 
+ * Outputs:
  *
- * Return.. 
+ * Return..
  *
  * True - If the ACL type matches any of the prohibited types.
  * False - If the ACL type doesn't match any of the prohibited types.
- */ 
+ */
 
 static BOOL hpux_prohibited_duplicate_type(int acl_type)
 {
        switch (acl_type) {
        case USER:
        case GROUP:
-       case DEF_USER: 
+       case DEF_USER:
        case DEF_GROUP:
                return True;
        default:
@@ -1217,7 +1217,7 @@ static BOOL hpux_prohibited_duplicate_type(int acl_type)
 
 /* get_needed_class_perm
  * Returns the permissions of a ACL structure only if the ACL
- * type matches one of the pre-determined types for computing 
+ * type matches one of the pre-determined types for computing
  * CLASS_OBJ permissions.
  *
  * Inputs: aclp - Pointer to ACL structure.
@@ -1226,17 +1226,17 @@ static BOOL hpux_prohibited_duplicate_type(int acl_type)
 static int hpux_get_needed_class_perm(struct acl *aclp)
 {
        switch (aclp->a_type) {
-       case USER: 
-       case GROUP_OBJ: 
-       case GROUP: 
-       case DEF_USER_OBJ: 
+       case USER:
+       case GROUP_OBJ:
+       case GROUP:
+       case DEF_USER_OBJ:
        case DEF_USER:
-       case DEF_GROUP_OBJ: 
+       case DEF_GROUP_OBJ:
        case DEF_GROUP:
        case DEF_CLASS_OBJ:
-       case DEF_OTHER_OBJ: 
+       case DEF_OTHER_OBJ:
                return aclp->a_perm;
-       default: 
+       default:
                return 0;
        }
 }
@@ -1267,15 +1267,15 @@ static int hpux_acl_sort(int acl_count, int calclass, struct acl *aclp)
 #if !defined(HAVE_HPUX_ACLSORT)
        /*
         * The aclsort() system call is available on the latest HPUX General
-        * Patch Bundles. So for HPUX, we developed our version of acl_sort 
-        * function. Because, we don't want to update to a new 
+        * Patch Bundles. So for HPUX, we developed our version of acl_sort
+        * function. Because, we don't want to update to a new
         * HPUX GR bundle just for aclsort() call.
         */
 
        struct hpux_acl_types acl_obj_count;
        int n_class_obj_perm = 0;
        int i, j;
+
        if (!acl_count) {
                DEBUG(10, ("Zero acl count passed. Returning Success\n"));
                return 0;
@@ -1290,8 +1290,8 @@ static int hpux_acl_sort(int acl_count, int calclass, struct acl *aclp)
 
        hpux_count_obj(acl_count, aclp, &acl_obj_count);
 
-       /* There should be only one entry each of type USER_OBJ, GROUP_OBJ, 
-        * CLASS_OBJ and OTHER_OBJ 
+       /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
+        * CLASS_OBJ and OTHER_OBJ
         */
 
        if (acl_obj_count.n_user_obj != 1
@@ -1313,15 +1313,15 @@ or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
                return -1;
        }
 
-       /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl 
-        * structures.  
+       /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
+        * structures.
         *
         * Sorting crieteria - First sort by ACL type. If there are multiple entries of
         * same ACL type, sort by ACL id.
         *
-        * I am using the trivial kind of sorting method here because, performance isn't 
+        * I am using the trivial kind of sorting method here because, performance isn't
         * really effected by the ACLs feature. More over there aren't going to be more
-        * than 17 entries on HPUX. 
+        * than 17 entries on HPUX.
         */
 
        for (i = 0; i < acl_count; i++) {
@@ -1390,7 +1390,7 @@ static int acl_sort(SMB_ACL_T acl_d)
        }
        return 0;
 }
+
 int sys_acl_valid(SMB_ACL_T acl_d)
 {
        return acl_sort(acl_d);
@@ -1405,11 +1405,11 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
        int             ret;
 
        if (hpux_acl_call_presence() == False) {
-               /* Looks like we don't have the acl() system call on HPUX. 
+               /* Looks like we don't have the acl() system call on HPUX.
                 * May be the system doesn't have the latest version of JFS.
                 */
                errno=ENOSYS;
-               return -1; 
+               return -1;
        }
 
        if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
@@ -1538,11 +1538,11 @@ int sys_acl_delete_def_file(const char *path)
        ret = acl(path, ACL_SET, acl_d->count, acl_d->acl);
 
        sys_acl_free_acl(acl_d);
-       
+
        return ret;
 }
 
-int sys_acl_free_acl(SMB_ACL_T acl_d) 
+int sys_acl_free_acl(SMB_ACL_T acl_d)
 {
        free(acl_d);
        return 0;
@@ -1723,7 +1723,7 @@ int sys_acl_delete_def_file(const char *name)
        return acl_delete_def_file(name);
 }
 
-int sys_acl_free_acl(SMB_ACL_T acl_d) 
+int sys_acl_free_acl(SMB_ACL_T acl_d)
 {
        if (acl_d->freeaclp) {
                acl_free(acl_d->aclp);
@@ -1739,7 +1739,6 @@ int sys_acl_free_acl(SMB_ACL_T acl_d)
 int sys_acl_get_entry(SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
 {
        struct acl_entry_link *link;
-       struct new_acl_entry *entry;
        int keep_going;
 
        if (entry_id == SMB_ACL_FIRST_ENTRY)
@@ -1765,10 +1764,15 @@ int sys_acl_get_entry(SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
        for (keep_going = 0; keep_going < theacl->count; keep_going++)
                link = link->nextp;
 
-       entry = *entry_p =  link->entryp;
+       *entry_p =  link->entryp;
 
-       DEBUG(10, ("*entry_p is %d\n", entry_p));
-       DEBUG(10, ("*entry_p->ace_access is %d\n", entry->ace_access));
+#if 0
+       {
+               struct new_acl_entry *entry = *entry_p;
+               DEBUG(10, ("*entry_p is %lx\n", (long)entry));
+               DEBUG(10, ("*entry_p->ace_access is %d\n", entry->ace_access));
+       }
+#endif
 
        /* Increment count */
        theacl->count++;
@@ -1830,12 +1834,12 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
        }
 
        /* Get the acl using statacl */
+
        DEBUG(10, ("Entering sys_acl_get_file\n"));
        DEBUG(10, ("path_p is %s\n", path_p));
 
        file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
+
        if (file_acl == NULL) {
                errno=ENOMEM;
                DEBUG(0, ("Error in AIX sys_acl_get_file: %d\n", errno));
@@ -1927,9 +1931,9 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
                         * to be specified but, it's better than leaving it 0 */
 
                        acl_entry_link->entryp->ace_type = acl_entry->ace_type;
+
                        acl_entry_link->entryp->ace_access = acl_entry->ace_access;
+
                        memcpy(acl_entry_link->entryp->ace_id, idp, sizeof (struct ace_id));
 
                        /* The access in the acl entries must be left shifted by *
@@ -1958,7 +1962,7 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
 
                        DEBUG(10, ("acl_entry = %d\n", acl_entry));
                        DEBUG(10, ("The ace_type is %d\n", acl_entry->ace_type));
+
                        acl_entry = acl_nxt(acl_entry);
                }
        } /* end of if enabled */
@@ -2010,12 +2014,12 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
                        new_acl_entry->ace_access = file_acl->o_access << 6;
                        idp->id_type = SMB_ACL_OTHER;
                        break;
+
                case 1:
                        new_acl_entry->ace_access = file_acl->u_access << 6;
                        idp->id_type = SMB_ACL_USER_OBJ;
                        break;
+
                default:
                        return NULL;
 
@@ -2044,7 +2048,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
        int rc = 0;
 
        /* Get the acl using fstatacl */
-   
+
        DEBUG(10, ("Entering sys_acl_get_fd\n"));
        DEBUG(10, ("fd is %d\n", fd));
        file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
@@ -2091,12 +2095,12 @@ SMB_ACL_T sys_acl_get_fd(int fd)
 
        DEBUG(10, ("acl_entry is %d\n", acl_entry));
        DEBUG(10, ("acl_last(file_acl) id %d\n", acl_last(file_acl)));
+
        /* Check if the extended acl bit is on.   *
         * If it isn't, do not show the           *
         * contents of the acl since AIX intends  *
         * the extended info to remain unused     */
+
        if (file_acl->acl_mode & S_IXACL){
                /* while we are not pointing to the very end */
                while (acl_entry < acl_last(file_acl)) {
@@ -2111,7 +2115,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
                        }
 
                        idp = acl_entry->ace_id;
+
                        /* Check if this is the first entry in the linked list. *
                         * The first entry needs to keep prevp pointing to NULL *
                         * and already has entryp allocated.                 */
@@ -2173,7 +2177,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
 
                        DEBUG(10, ("acl_entry = %d\n", acl_entry));
                        DEBUG(10, ("The ace_type is %d\n", acl_entry->ace_type));
+
                        acl_entry = acl_nxt(acl_entry);
                }
        } /* end of if enabled */
@@ -2206,43 +2210,43 @@ SMB_ACL_T sys_acl_get_fd(int fd)
                }
 
                acl_entry_link->nextp = NULL;
+
                new_acl_entry = acl_entry_link->entryp;
                idp = new_acl_entry->ace_id;
+
                new_acl_entry->ace_len = sizeof (struct acl_entry);
                new_acl_entry->ace_type = ACC_PERMIT;
                idp->id_len = sizeof (struct ace_id);
                DEBUG(10, ("idp->id_len = %d\n", idp->id_len));
                memset(idp->id_data, 0, sizeof (uid_t));
+
                switch (i) {
                case 2:
                        new_acl_entry->ace_access = file_acl->g_access << 6;
                        idp->id_type = SMB_ACL_GROUP_OBJ;
                        break;
+
                case 3:
                        new_acl_entry->ace_access = file_acl->o_access << 6;
                        idp->id_type = SMB_ACL_OTHER;
                        break;
+
                case 1:
                        new_acl_entry->ace_access = file_acl->u_access << 6;
                        idp->id_type = SMB_ACL_USER_OBJ;
                        break;
+
                default:
                        return NULL;
                }
+
                acl_entry_link_head->count++;
                DEBUG(10, ("new_acl_entry->ace_access = %d\n", new_acl_entry->ace_access));
        }
 
        acl_entry_link_head->count = 0;
        SAFE_FREE(file_acl);
+
        return acl_entry_link_head;
 }
 #endif
@@ -2270,7 +2274,7 @@ int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *b
 SMB_ACL_T sys_acl_init(int count)
 {
        struct acl_entry_link *theacl = NULL;
+
        if (count < 0) {
                errno = EINVAL;
                return NULL;
@@ -2297,7 +2301,7 @@ int sys_acl_create_entry(SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
 {
        struct acl_entry_link *theacl;
        struct acl_entry_link *acl_entryp;
-       struct acl_entry_link *temp_entry;
+       struct acl_entry_link *temp_entry = NULL;
        int counting;
 
        DEBUG(10, ("Entering the sys_acl_create_entry\n"));
@@ -2379,9 +2383,9 @@ int sys_acl_valid(SMB_ACL_T theacl)
        }
 
        DEBUG(10, ("user_obj=%d, group_obj=%d, other_obj=%d\n", user_obj, group_obj, other_obj));
+
        if (user_obj != 1 || group_obj != 1 || other_obj != 1)
-               return -1; 
+               return -1;
 
        return 0;
 }
@@ -2400,7 +2404,7 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
 
        DEBUG(10, ("Entering sys_acl_set_file\n"));
        DEBUG(10, ("File name is %s\n", name));
+
        /* AIX has no default ACL */
        if (acltype == SMB_ACL_TYPE_DEFAULT)
                return 0;
@@ -2445,7 +2449,7 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
                                errno = ENOMEM;
                                DEBUG(0, ("Error in sys_acl_set_file is %d\n", errno));
                                return -1;
-                       }  
+                       }
 
                        memcpy(file_acl_temp, file_acl, file_acl->acl_len);
                        SAFE_FREE(file_acl);
@@ -2456,15 +2460,15 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
                file_acl->acl_len += sizeof (struct acl_entry);
                acl_entry->ace_len = acl_entry_link->entryp->ace_len;
                acl_entry->ace_access = acl_entry_link->entryp->ace_access;
+
                /* In order to use this, we'll need to wait until we can get denies */
                /* if (!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
                        acl_entry->ace_type = ACC_SPECIFY; */
 
                acl_entry->ace_type = ACC_SPECIFY;
+
                ace_id = acl_entry->ace_id;
+
                ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
                DEBUG(10, ("The id type is %d\n", ace_id->id_type));
                ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
@@ -2492,7 +2496,7 @@ int sys_acl_set_fd(int fd, SMB_ACL_T theacl)
        uint user_id;
        uint acl_length;
        uint rc;
+
        DEBUG(10, ("Entering sys_acl_set_fd\n"));
        acl_length = BUFSIZ;
        file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
@@ -2504,7 +2508,7 @@ int sys_acl_set_fd(int fd, SMB_ACL_T theacl)
        }
 
        memset(file_acl, 0, BUFSIZ);
+
        file_acl->acl_len = ACL_SIZ;
        file_acl->acl_mode = S_IXACL;
 
@@ -2546,22 +2550,22 @@ int sys_acl_set_fd(int fd, SMB_ACL_T theacl)
                file_acl->acl_len += sizeof (struct acl_entry);
                acl_entry->ace_len = acl_entry_link->entryp->ace_len;
                acl_entry->ace_access = acl_entry_link->entryp->ace_access;
+
                /* In order to use this, we'll need to wait until we can get denies */
                /* if (!acl_entry->ace_access && acl_entry->ace_type == ACC_PERMIT)
                        acl_entry->ace_type = ACC_SPECIFY; */
+
                acl_entry->ace_type = ACC_SPECIFY;
+
                ace_id = acl_entry->ace_id;
+
                ace_id->id_type = acl_entry_link->entryp->ace_id->id_type;
                DEBUG(10, ("The id type is %d\n", ace_id->id_type));
                ace_id->id_len = acl_entry_link->entryp->ace_id->id_len;
                memcpy(&user_id, acl_entry_link->entryp->ace_id->id_data, sizeof (uid_t));
                memcpy(ace_id->id_data, &user_id, sizeof (uid_t));
        }
+
        rc = fchacl(fd, file_acl, file_acl->acl_len);
        DEBUG(10, ("errno is %d\n", errno));
        DEBUG(10, ("return code is %d\n", rc));
@@ -2590,7 +2594,7 @@ int sys_acl_free_acl(SMB_ACL_T posix_acl)
        SAFE_FREE(acl_entry_link->prevp);
        SAFE_FREE(acl_entry_link->entryp);
        SAFE_FREE(acl_entry_link);
+
        return 0;
 }
 
index 8865dae..c069597 100644 (file)
@@ -3,7 +3,7 @@
  * Version 2.2.x
  * Portable SMB ACL interface
  * Copyright (C) Jeremy Allison 2000
- * Copyright (C) 2007-2020 Wayne Davison
+ * Copyright (C) 2007-2022 Wayne Davison
  *
  * 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
@@ -232,7 +232,7 @@ struct new_acl_entry{
 
 #define SMB_ACL_ENTRY_T                struct new_acl_entry*
 #define SMB_ACL_T              struct acl_entry_link*
+
 #define SMB_ACL_TAG_T          unsigned short
 #define SMB_ACL_TYPE_T         int
 
index 583b93e..ca08d13 100644 (file)
@@ -2,7 +2,7 @@
  * Extended attribute support for rsync.
  *
  * Copyright (C) 2004 Red Hat, Inc.
- * Copyright (C) 2003-2019 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  * Written by Jay Fenlason.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -67,7 +67,7 @@ ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t si
                u_int32_t offset = len;
                size_t data_retrieved = len;
                while (data_retrieved < size) {
-                       len = getxattr(path, name, value + offset, size - data_retrieved, offset, XATTR_NOFOLLOW);
+                       len = getxattr(path, name, (char*)value + offset, size - data_retrieved, offset, XATTR_NOFOLLOW);
                        if (len <= 0)
                                break;
                        data_retrieved += len;
@@ -167,7 +167,7 @@ static ssize_t read_xattr(int attrfd, void *buf, size_t buflen)
        } else {
                size_t bufpos;
                for (bufpos = 0; bufpos < sb.st_size; ) {
-                       ssize_t cnt = read(attrfd, buf + bufpos, sb.st_size - bufpos);
+                       ssize_t cnt = read(attrfd, (char*)buf + bufpos, sb.st_size - bufpos);
                        if (cnt <= 0) {
                                if (cnt < 0 && errno == EINTR)
                                        continue;
@@ -218,7 +218,7 @@ int sys_lsetxattr(const char *path, const char *name, const void *value, size_t
                return -1;
 
        for (bufpos = 0; bufpos < size; ) {
-               ssize_t cnt = write(attrfd, value+bufpos, size);
+               ssize_t cnt = write(attrfd, (char*)value + bufpos, size);
                if (cnt <= 0) {
                        if (cnt < 0 && errno == EINTR)
                                continue;
@@ -274,7 +274,8 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size)
                 && (dp->d_name[10] == 'o' || dp->d_name[10] == 'w'))
                        continue;
 
-               if ((ret += len+1) > size) {
+               ret += len + 1;
+               if ((size_t)ret > size) {
                        if (size == 0)
                                continue;
                        ret = -1;
index 952a0b7..3906bc0 100644 (file)
@@ -437,7 +437,7 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
                break;
 
        case P_OCTAL:
-               sscanf(parmvalue, "%o", (int *)parm_ptr);
+               sscanf(parmvalue, "%o", (unsigned int *)parm_ptr);
                break;
 
        case P_PATH:
diff --git a/log.c b/log.c
index 062a930..e4ba1cc 100644 (file)
--- a/log.c
+++ b/log.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
  * Copyright (C) 2000-2001 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -34,10 +34,8 @@ extern int module_id;
 extern int allow_8bit_chars;
 extern int protocol_version;
 extern int always_checksum;
-extern int preserve_times;
+extern int preserve_mtimes;
 extern int msgs2stderr;
-extern int xfersum_type;
-extern int checksum_type;
 extern int stdout_format_has_i;
 extern int stdout_format_has_o_or_i;
 extern int logfile_format_has_i;
@@ -62,6 +60,8 @@ extern unsigned int module_dirlen;
 extern char sender_file_sum[MAX_DIGEST_LEN];
 extern const char undetermined_hostname[];
 
+extern struct name_num_item *xfer_sum_nni, *file_sum_nni;
+
 static int log_initialised;
 static int logfile_was_closed;
 static FILE *logfile_fp;
@@ -680,12 +680,12 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
                        n = NULL;
                        if (S_ISREG(file->mode)) {
                                if (always_checksum)
-                                       n = sum_as_hex(checksum_type, F_SUM(file), 1);
+                                       n = sum_as_hex(file_sum_nni->num, F_SUM(file), 1);
                                else if (iflags & ITEM_TRANSFER)
-                                       n = sum_as_hex(xfersum_type, sender_file_sum, 0);
+                                       n = sum_as_hex(xfer_sum_nni->num, sender_file_sum, 0);
                        }
                        if (!n) {
-                               int sum_len = csum_len_for_type(always_checksum ? checksum_type : xfersum_type,
+                               int sum_len = csum_len_for_type(always_checksum ? file_sum_nni->num : xfer_sum_nni->num,
                                                                always_checksum);
                                memset(buf2, ' ', sum_len*2);
                                buf2[sum_len*2] = '\0';
@@ -706,7 +706,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
                                c[1] = 'L';
                                c[3] = '.';
                                c[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
-                                    : !preserve_times || !receiver_symlink_times
+                                    : !preserve_mtimes || !receiver_symlink_times
                                    || (iflags & ITEM_REPORT_TIMEFAIL) ? 'T' : 't';
                        } else {
                                c[1] = S_ISDIR(file->mode) ? 'd'
@@ -714,7 +714,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
                                     : IS_DEVICE(file->mode) ? 'D' : 'f';
                                c[3] = !(iflags & ITEM_REPORT_SIZE) ? '.' : 's';
                                c[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
-                                    : !preserve_times ? 'T' : 't';
+                                    : !preserve_mtimes ? 'T' : 't';
                        }
                        c[2] = !(iflags & ITEM_REPORT_CHANGE) ? '.' : 'c';
                        c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
@@ -838,14 +838,24 @@ void maybe_log_item(struct file_struct *file, int iflags, int itemizing, const c
 
 void log_delete(const char *fname, int mode)
 {
-       static struct {
-               union file_extras ex[4]; /* just in case... */
-               struct file_struct file;
-       } x; /* Zero-initialized due to static declaration. */
+       static struct file_struct *file = NULL;
        int len = strlen(fname);
        const char *fmt;
 
-       x.file.mode = mode;
+       if (!file) {
+               int extra_len = (file_extra_cnt + 2) * EXTRA_LEN;
+               char *bp;
+#if EXTRA_ROUNDING > 0
+               if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
+                       extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;
+#endif
+
+               bp = new_array0(char, FILE_STRUCT_LEN + extra_len + 1);
+               bp += extra_len;
+               file = (struct file_struct *)bp;
+       }
+
+       file->mode = mode;
 
        if (am_server && protocol_version >= 29 && len < MAXPATHLEN) {
                if (S_ISDIR(mode))
@@ -855,14 +865,14 @@ void log_delete(const char *fname, int mode)
                ;
        else {
                fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n";
-               log_formatted(FCLIENT, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
+               log_formatted(FCLIENT, fmt, "del.", file, fname, ITEM_DELETED, NULL);
        }
 
        if (!logfile_name || dry_run || !logfile_format)
                return;
 
        fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n";
-       log_formatted(FLOG, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
+       log_formatted(FLOG, fmt, "del.", file, fname, ITEM_DELETED, NULL);
 }
 
 /*
index 704ca33..12fc719 100644 (file)
@@ -1,6 +1,5 @@
 dnl AC_HAVE_TYPE(TYPE,INCLUDES)
 AC_DEFUN([AC_HAVE_TYPE], [
-AC_REQUIRE([AC_HEADER_STDC])
 cv=`echo "$1" | sed 'y%./+- %__p__%'`
 AC_MSG_CHECKING(for $1)
 AC_CACHE_VAL([ac_cv_type_$cv],
diff --git a/main.c b/main.c
index 46b97b5..d2a7b9b 100644 (file)
--- a/main.c
+++ b/main.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -48,6 +48,7 @@ extern int called_from_signal_handler;
 extern int need_messages_from_generator;
 extern int kluge_around_eof;
 extern int got_xfer_error;
+extern int old_style_args;
 extern int msgs2stderr;
 extern int module_id;
 extern int read_only;
@@ -87,6 +88,7 @@ extern BOOL shutting_down;
 extern int backup_dir_len;
 extern int basis_dir_cnt;
 extern int default_af_hint;
+extern int stdout_format_has_i;
 extern struct stats stats;
 extern char *stdout_format;
 extern char *logfile_format;
@@ -102,7 +104,7 @@ extern char curr_dir[MAXPATHLEN];
 extern char backup_dir_buf[MAXPATHLEN];
 extern char *basis_dir[MAX_BASIS_DIRS+1];
 extern struct file_list *first_flist;
-extern filter_rule_list daemon_filter_list;
+extern filter_rule_list daemon_filter_list, implied_filter_list;
 
 uid_t our_uid;
 gid_t our_gid;
@@ -466,38 +468,33 @@ static void output_summary(void)
  **/
 static void show_malloc_stats(void)
 {
-#ifdef HAVE_MALLINFO
-       struct mallinfo mi;
-
-       mi = mallinfo();
+#ifdef MEM_ALLOC_INFO
+       struct MEM_ALLOC_INFO mi = MEM_ALLOC_INFO(); /* mallinfo or mallinfo2 */
 
        rprintf(FCLIENT, "\n");
        rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
                (int)getpid(), am_server ? "server " : "",
                am_daemon ? "daemon " : "", who_am_i());
-       rprintf(FINFO, "  arena:     %10ld   (bytes from sbrk)\n",
-               (long)mi.arena);
-       rprintf(FINFO, "  ordblks:   %10ld   (chunks not in use)\n",
-               (long)mi.ordblks);
-       rprintf(FINFO, "  smblks:    %10ld\n",
-               (long)mi.smblks);
-       rprintf(FINFO, "  hblks:     %10ld   (chunks from mmap)\n",
-               (long)mi.hblks);
-       rprintf(FINFO, "  hblkhd:    %10ld   (bytes from mmap)\n",
-               (long)mi.hblkhd);
-       rprintf(FINFO, "  allmem:    %10ld   (bytes from sbrk + mmap)\n",
-               (long)mi.arena + mi.hblkhd);
-       rprintf(FINFO, "  usmblks:   %10ld\n",
-               (long)mi.usmblks);
-       rprintf(FINFO, "  fsmblks:   %10ld\n",
-               (long)mi.fsmblks);
-       rprintf(FINFO, "  uordblks:  %10ld   (bytes used)\n",
-               (long)mi.uordblks);
-       rprintf(FINFO, "  fordblks:  %10ld   (bytes free)\n",
-               (long)mi.fordblks);
-       rprintf(FINFO, "  keepcost:  %10ld   (bytes in releasable chunk)\n",
-               (long)mi.keepcost);
-#endif /* HAVE_MALLINFO */
+
+#define PRINT_ALLOC_NUM(title, descr, num) \
+       rprintf(FINFO, "  %-11s%10" SIZE_T_FMT_MOD "d   (" descr ")\n", \
+               title ":", (SIZE_T_FMT_CAST)(num));
+
+       PRINT_ALLOC_NUM("arena", "bytes from sbrk", mi.arena);
+       PRINT_ALLOC_NUM("ordblks", "chunks not in use", mi.ordblks);
+       PRINT_ALLOC_NUM("smblks", "free fastbin blocks", mi.smblks);
+       PRINT_ALLOC_NUM("hblks", "chunks from mmap", mi.hblks);
+       PRINT_ALLOC_NUM("hblkhd", "bytes from mmap", mi.hblkhd);
+       PRINT_ALLOC_NUM("allmem", "bytes from sbrk + mmap", mi.arena + mi.hblkhd);
+       PRINT_ALLOC_NUM("usmblks", "always 0", mi.usmblks);
+       PRINT_ALLOC_NUM("fsmblks", "bytes in freed fastbin blocks", mi.fsmblks);
+       PRINT_ALLOC_NUM("uordblks", "bytes used", mi.uordblks);
+       PRINT_ALLOC_NUM("fordblks", "bytes free", mi.fordblks);
+       PRINT_ALLOC_NUM("keepcost", "bytes in releasable chunk", mi.keepcost);
+
+#undef PRINT_ALLOC_NUM
+
+#endif /* MEM_ALLOC_INFO */
 }
 
 
@@ -611,11 +608,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
                                rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
                                exit_cleanup(RERR_SYNTAX);
                        }
-                       if (**remote_argv == '-') {
-                               if (asprintf(args + argc++, "./%s", *remote_argv++) < 0)
-                                       out_of_memory("do_cmd");
-                       } else
-                               args[argc++] = *remote_argv++;
+                       args[argc++] = safe_arg(NULL, *remote_argv++);
                        remote_argc--;
                }
        }
@@ -667,6 +660,16 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
        return pid;
 }
 
+/* Older versions turn an empty string as a reference to the current directory.
+ * We now treat this as an error unless --old-args was used. */
+static char *dot_dir_or_error()
+{
+       if (old_style_args || am_server)
+               return ".";
+       rprintf(FERROR, "Empty destination arg specified (use \".\" or see --old-args).\n");
+       exit_cleanup(RERR_SYNTAX);
+}
+
 /* The receiving side operates in one of two modes:
  *
  * 1. it receives any number of files into a destination directory,
@@ -694,9 +697,8 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
        if (!dest_path || list_only)
                return NULL;
 
-       /* Treat an empty string as a copy into the current directory. */
        if (!*dest_path)
-               dest_path = ".";
+               dest_path = dot_dir_or_error();
 
        if (daemon_filter_list.head) {
                char *slash = strrchr(dest_path, '/');
@@ -721,18 +723,21 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
        trailing_slash = cp && !cp[1];
 
        if (mkpath_dest_arg && statret < 0 && (cp || file_total > 1)) {
+               int save_errno = errno;
                int ret = make_path(dest_path, file_total > 1 && !trailing_slash ? 0 : MKP_DROP_NAME);
                if (ret < 0)
                        goto mkdir_error;
-               if (INFO_GTE(NAME, 1)) {
+               if (ret && (INFO_GTE(NAME, 1) || stdout_format_has_i)) {
                        if (file_total == 1 || trailing_slash)
                                *cp = '\0';
                        rprintf(FINFO, "created %d director%s for %s\n", ret, ret == 1 ? "y" : "ies", dest_path);
                        if (file_total == 1 || trailing_slash)
                                *cp = '/';
                }
-               if (file_total > 1 || trailing_slash)
+               if (ret)
                        statret = do_stat(dest_path, &st);
+               else
+                       errno = save_errno;
        }
 
        if (statret == 0) {
@@ -788,7 +793,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
                 && strcmp(flist->files[flist->low]->basename, ".") == 0)
                        flist->files[0]->flags |= FLAG_DIR_CREATED;
 
-               if (INFO_GTE(NAME, 1))
+               if (INFO_GTE(NAME, 1) || stdout_format_has_i)
                        rprintf(FINFO, "created directory %s\n", dest_path);
 
                if (dry_run) {
@@ -1080,6 +1085,7 @@ static int do_recv(int f_in, int f_out, char *local_name)
        }
 
        am_generator = 1;
+       implied_filter_list.head = implied_filter_list.tail = NULL;
        flist_receiving_enabled = True;
 
        io_end_multiplex_in(MPLX_SWITCHING);
@@ -1435,6 +1441,8 @@ static int start_client(int argc, char *argv[])
 
                        if (argc > 1) {
                                p = argv[--argc];
+                               if (!*p)
+                                       p = dot_dir_or_error();
                                remote_argv = argv + argc;
                        } else {
                                static char *dotarg[1] = { "." };
@@ -1475,6 +1483,10 @@ static int start_client(int argc, char *argv[])
                rsync_port = 0;
        }
 
+       /* A local transfer doesn't unbackslash anything, so leave the args alone. */
+       if (local_server)
+               old_style_args = 2;
+
        if (!rsync_port && remote_argc && !**remote_argv) /* Turn an empty arg into a dot dir. */
                *remote_argv = ".";
 
@@ -1500,6 +1512,8 @@ static int start_client(int argc, char *argv[])
                char *dummy_host;
                int dummy_port = rsync_port;
                int i;
+               if (filesfrom_fd < 0)
+                       add_implied_include(remote_argv[0], daemon_connection);
                /* For remote source, any extra source args must have either
                 * the same hostname or an empty hostname. */
                for (i = 1; i < remote_argc; i++) {
@@ -1523,6 +1537,7 @@ static int start_client(int argc, char *argv[])
                        if (!rsync_port && !*arg) /* Turn an empty arg into a dot dir. */
                                arg = ".";
                        remote_argv[i] = arg;
+                       add_implied_include(arg, daemon_connection);
                }
        }
 
@@ -1564,6 +1579,8 @@ static int start_client(int argc, char *argv[])
 #ifdef HAVE_PUTENV
        if (daemon_connection)
                set_env_num("RSYNC_PORT", env_port);
+#else
+       (void)env_port;
 #endif
 
        pid = do_cmd(shell_cmd, shell_machine, shell_user, remote_argv, remote_argc, &f_in, &f_out);
@@ -1636,7 +1653,6 @@ void remember_children(UNUSED(int val))
 #endif
 }
 
-
 /**
  * This routine catches signals and tries to send them to gdb.
  *
@@ -1660,7 +1676,6 @@ const char *get_panic_action(void)
        return "xterm -display :0 -T Panic -n Panic -e gdb /proc/%d/exe %d";
 }
 
-
 /**
  * Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
  *
@@ -1684,6 +1699,22 @@ static void rsync_panic_handler(UNUSED(int whatsig))
 }
 #endif
 
+static void unset_env_var(const char *var)
+{
+#ifdef HAVE_UNSETENV
+       unsetenv(var);
+#else
+#ifdef HAVE_PUTENV
+       char *mem;
+       if (asprintf(&mem, "%s=", var) < 0)
+               out_of_memory("unset_env_var");
+       putenv(mem);
+#else
+       (void)var;
+#endif
+#endif
+}
+
 
 int main(int argc,char *argv[])
 {
@@ -1721,6 +1752,19 @@ int main(int argc,char *argv[])
        our_gid = MY_GID();
        am_root = our_uid == ROOT_UID;
 
+       unset_env_var("DISPLAY");
+
+#if defined USE_OPENSSL && defined SET_OPENSSL_CONF
+#define TO_STR2(x) #x
+#define TO_STR(x) TO_STR2(x)
+       /* ./configure --with-openssl-conf=/etc/ssl/openssl-rsync.cnf
+        * defines SET_OPENSSL_CONF as that unquoted pathname. */
+       if (!getenv("OPENSSL_CONF")) /* Don't override it if it's already set. */
+               set_env_str("OPENSSL_CONF", TO_STR(SET_OPENSSL_CONF));
+#undef TO_STR
+#undef TO_STR2
+#endif
+
        memset(&stats, 0, sizeof(stats));
 
        /* Even a non-daemon runs needs the default config values to be set, e.g.
@@ -1739,6 +1783,7 @@ int main(int argc,char *argv[])
 
 #if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
        setlocale(LC_CTYPE, "");
+       setlocale(LC_NUMERIC, "");
 #endif
 
        if (!parse_arguments(&argc, (const char ***) &argv)) {
diff --git a/match.c b/match.c
index 9d5c925..6243994 100644 (file)
--- a/match.c
+++ b/match.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -24,7 +24,9 @@
 
 extern int checksum_seed;
 extern int append_mode;
-extern int xfersum_type;
+
+extern struct name_num_item *xfer_sum_nni;
+extern int xfer_sum_len;
 
 int updating_basis_file;
 char sender_file_sum[MAX_DIGEST_LEN];
@@ -356,15 +358,13 @@ static void hash_search(int f,struct sum_struct *s,
  **/
 void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
 {
-       int sum_len;
-
        last_match = 0;
        false_alarms = 0;
        hash_hits = 0;
        matches = 0;
        data_transfer = 0;
 
-       sum_init(xfersum_type, checksum_seed);
+       sum_init(xfer_sum_nni, checksum_seed);
 
        if (append_mode > 0) {
                if (append_mode == 2) {
@@ -405,22 +405,22 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
                matched(f, s, buf, len, -1);
        }
 
-       sum_len = sum_end(sender_file_sum);
+       sum_end(sender_file_sum);
 
        /* If we had a read error, send a bad checksum.  We use all bits
         * off as long as the checksum doesn't happen to be that, in
         * which case we turn the last 0 bit into a 1. */
        if (buf && buf->status != 0) {
                int i;
-               for (i = 0; i < sum_len && sender_file_sum[i] == 0; i++) {}
-               memset(sender_file_sum, 0, sum_len);
-               if (i == sum_len)
+               for (i = 0; i < xfer_sum_len && sender_file_sum[i] == 0; i++) {}
+               memset(sender_file_sum, 0, xfer_sum_len);
+               if (i == xfer_sum_len)
                        sender_file_sum[i-1]++;
        }
 
        if (DEBUG_GTE(DELTASUM, 2))
                rprintf(FINFO,"sending file_sum\n");
-       write_buf(f, sender_file_sum, sum_len);
+       write_buf(f, sender_file_sum, xfer_sum_len);
 
        if (DEBUG_GTE(DELTASUM, 2)) {
                rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
index b7f0a9f..0dc1730 100755 (executable)
@@ -1,22 +1,17 @@
 #!/bin/sh
 
-if [ x"$2" = x ]; then
-    echo "Usage: $0 SRC_DIR NAME.NUM.md" 1>&2
+if [ $# != 1 ]; then
+    echo "Usage: $0 NAME.NUM.md" 1>&2
     exit 1
 fi
 
-srcdir="$1"
-inname="$2"
+inname="$1"
+srcdir=`dirname "$0"`
 flagfile="$srcdir/.md2man-works"
 
-if [ ! -d "$srcdir" ]; then
-    echo "The specified SRC_DIR is not a directory: $srcdir" 1>&2
-    exit 1
-fi
-
 if [ ! -f "$flagfile" ]; then
     # We test our smallest manpage just to see if the python setup works.
-    if "$srcdir/md2man" --test "$srcdir/rsync-ssl.1.md" >/dev/null 2>&1; then
+    if "$srcdir/md-convert" --test "$srcdir/rsync-ssl.1.md" >/dev/null 2>&1; then
        touch $flagfile
     else
        outname=`echo "$inname" | sed 's/\.md$//'`
@@ -37,4 +32,4 @@ if [ ! -f "$flagfile" ]; then
     fi
 fi
 
-"$srcdir/md2man" "$srcdir/$inname"
+"$srcdir/md-convert" "$srcdir/$inname"
diff --git a/md-convert b/md-convert
new file mode 100755 (executable)
index 0000000..a48689a
--- /dev/null
@@ -0,0 +1,634 @@
+#!/usr/bin/env python3
+
+# This script transforms markdown files into html and (optionally) nroff. The
+# output files are written into the current directory named for the input file
+# without the .md suffix and either the .html suffix or no suffix.
+#
+# If the input .md file has a section number at the end of the name (e.g.,
+# rsync.1.md) a nroff file is also output (PROJ.NUM.md -> PROJ.NUM).
+#
+# The markdown input format has one extra extension: if a numbered list starts
+# at 0, it is turned into a description list. The dl's dt tag is taken from the
+# contents of the first tag inside the li, which is usually a p, code, or
+# strong tag.
+#
+# The cmarkgfm or commonmark lib is used to transforms the input file into
+# html.  Then, the html.parser is used as a state machine that lets us tweak
+# the html and (optionally) output nroff data based on the html tags.
+#
+# If the string @USE_GFM_PARSER@ exists in the file, the string is removed and
+# a github-flavored-markup parser is used to parse the file.
+#
+# The man-page .md files also get the vars @VERSION@, @BINDIR@, and @LIBDIR@
+# substituted.  Some of these values depend on the Makefile $(prefix) (see the
+# generated Makefile).  If the maintainer wants to build files for /usr/local
+# while creating release-ready man-page files for /usr, use the environment to
+# set RSYNC_OVERRIDE_PREFIX=/usr.
+
+# Copyright (C) 2020 - 2021 Wayne Davison
+#
+# This program is freely redistributable.
+
+import os, sys, re, argparse, subprocess, time
+from html.parser import HTMLParser
+
+VALID_PAGES = 'README INSTALL COPYING rsync.1 rrsync.1 rsync-ssl.1 rsyncd.conf.5'.split()
+
+CONSUMES_TXT = set('h1 h2 h3 p li pre'.split())
+
+HTML_START = """\
+<html><head>
+<title>%TITLE%</title>
+<meta charset="UTF-8"/>
+<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap" rel="stylesheet">
+<style>
+body {
+  max-width: 50em;
+  margin: auto;
+}
+body, b, strong, u {
+  font-family: 'Roboto', sans-serif;
+}
+a.tgt { font-face: symbol; font-weight: 400; font-size: 70%; visibility: hidden; text-decoration: none; color: #ddd; padding: 0 4px; border: 0; }
+a.tgt:after { content: '🔗'; }
+a.tgt:hover { color: #444; background-color: #eaeaea; }
+h1:hover > a.tgt, h2:hover > a.tgt, h3:hover > a.tgt, dt:hover > a.tgt { visibility: visible; }
+code {
+  font-family: 'Roboto Mono', monospace;
+  font-weight: bold;
+  white-space: pre;
+}
+pre code {
+  display: block;
+  font-weight: normal;
+}
+blockquote pre code {
+  background: #f1f1f1;
+}
+dd p:first-of-type {
+  margin-block-start: 0em;
+}
+</style>
+</head><body>
+"""
+
+TABLE_STYLE = """\
+table {
+  border-color: grey;
+  border-spacing: 0;
+}
+tr {
+  border-top: 1px solid grey;
+}
+tr:nth-child(2n) {
+  background-color: #f6f8fa;
+}
+th, td {
+  border: 1px solid #dfe2e5;
+  text-align: center;
+  padding-left: 1em;
+  padding-right: 1em;
+}
+"""
+
+MAN_HTML_END = """\
+<div style="float: right"><p><i>%s</i></p></div>
+"""
+
+HTML_END = """\
+</body></html>
+"""
+
+MAN_START = r"""
+.TH "%s" "%s" "%s" "%s" "User Commands"
+.\" prefix=%s
+""".lstrip()
+
+MAN_END = """\
+"""
+
+NORM_FONT = ('\1', r"\fP")
+BOLD_FONT = ('\2', r"\fB")
+UNDR_FONT = ('\3', r"\fI")
+NBR_DASH = ('\4', r"\-")
+NBR_SPACE = ('\xa0', r"\ ")
+
+FILENAME_RE = re.compile(r'^(?P<fn>(?P<srcdir>.+/)?(?P<name>(?P<prog>[^/]+?)(\.(?P<sect>\d+))?)\.md)$')
+ASSIGNMENT_RE = re.compile(r'^(\w+)=(.+)')
+VER_RE = re.compile(r'^#define\s+RSYNC_VERSION\s+"(\d.+?)"', re.M)
+TZ_RE = re.compile(r'^#define\s+MAINTAINER_TZ_OFFSET\s+(-?\d+(\.\d+)?)', re.M)
+VAR_REF_RE = re.compile(r'\$\{(\w+)\}')
+VERSION_RE = re.compile(r' (\d[.\d]+)[, ]')
+BIN_CHARS_RE = re.compile(r'[\1-\7]+')
+SPACE_DOUBLE_DASH_RE = re.compile(r'\s--(\s)')
+NON_SPACE_SINGLE_DASH_RE = re.compile(r'(^|\W)-')
+WHITESPACE_RE = re.compile(r'\s')
+CODE_BLOCK_RE = re.compile(r'[%s]([^=%s]+)[=%s]' % (BOLD_FONT[0], NORM_FONT[0], NORM_FONT[0]))
+NBR_DASH_RE = re.compile(r'[%s]' % NBR_DASH[0])
+INVALID_TARGET_CHARS_RE = re.compile(r'[^-A-Za-z0-9._]')
+INVALID_START_CHAR_RE = re.compile(r'^([^A-Za-z0-9])')
+MANIFY_LINESTART_RE = re.compile(r"^(['.])", flags=re.M)
+
+md_parser = None
+env_subs = { }
+
+warning_count = 0
+
+def main():
+    for mdfn in args.mdfiles:
+        parse_md_file(mdfn)
+
+    if args.test:
+        print("The test was successful.")
+
+
+def parse_md_file(mdfn):
+    fi = FILENAME_RE.match(mdfn)
+    if not fi:
+        die('Failed to parse a md input file name:', mdfn)
+    fi = argparse.Namespace(**fi.groupdict())
+    fi.want_manpage = not not fi.sect
+    if fi.want_manpage:
+        fi.title = fi.prog + '(' + fi.sect + ') manpage'
+    else:
+        fi.title = fi.prog + ' for rsync'
+
+    if fi.want_manpage:
+        if not env_subs:
+            find_man_substitutions()
+        prog_ver = 'rsync ' + env_subs['VERSION']
+        if fi.prog != 'rsync':
+            prog_ver = fi.prog + ' from ' + prog_ver
+        fi.man_headings = (fi.prog, fi.sect, env_subs['date'], prog_ver, env_subs['prefix'])
+
+    with open(mdfn, 'r', encoding='utf-8') as fh:
+        txt = fh.read()
+
+    use_gfm_parser = '@USE_GFM_PARSER@' in txt
+    if use_gfm_parser:
+        txt = txt.replace('@USE_GFM_PARSER@', '')
+
+    if fi.want_manpage:
+        txt = (txt.replace('@VERSION@', env_subs['VERSION'])
+                  .replace('@BINDIR@', env_subs['bindir'])
+                  .replace('@LIBDIR@', env_subs['libdir']))
+
+    if use_gfm_parser:
+        if not gfm_parser:
+            die('Input file requires cmarkgfm parser:', mdfn)
+        fi.html_in = gfm_parser(txt)
+    else:
+        fi.html_in = md_parser(txt)
+    txt = None
+
+    TransformHtml(fi)
+
+    if args.test:
+        return
+
+    output_list = [ (fi.name + '.html', fi.html_out) ]
+    if fi.want_manpage:
+        output_list += [ (fi.name, fi.man_out) ]
+    for fn, txt in output_list:
+        if args.dest and args.dest != '.':
+            fn = os.path.join(args.dest, fn)
+        if os.path.lexists(fn):
+            os.unlink(fn)
+        print("Wrote:", fn)
+        with open(fn, 'w', encoding='utf-8') as fh:
+            fh.write(txt)
+
+
+def find_man_substitutions():
+    srcdir = os.path.dirname(sys.argv[0]) + '/'
+    mtime = 0
+
+    git_dir = srcdir + '.git'
+    if os.path.lexists(git_dir):
+        mtime = int(subprocess.check_output(['git', '--git-dir', git_dir, 'log', '-1', '--format=%at']))
+
+    # Allow "prefix" to be overridden via the environment:
+    env_subs['prefix'] = os.environ.get('RSYNC_OVERRIDE_PREFIX', None)
+
+    if args.test:
+        env_subs['VERSION'] = '1.0.0'
+        env_subs['bindir'] = '/usr/bin'
+        env_subs['libdir'] = '/usr/lib/rsync'
+        tz_offset = 0
+    else:
+        for fn in (srcdir + 'version.h', 'Makefile'):
+            try:
+                st = os.lstat(fn)
+            except OSError:
+                die('Failed to find', srcdir + fn)
+            if not mtime:
+                mtime = st.st_mtime
+
+        with open(srcdir + 'version.h', 'r', encoding='utf-8') as fh:
+            txt = fh.read()
+        m = VER_RE.search(txt)
+        env_subs['VERSION'] = m.group(1)
+        m = TZ_RE.search(txt) # the tzdata lib may not be installed, so we use a simple hour offset
+        tz_offset = float(m.group(1)) * 60 * 60
+
+        with open('Makefile', 'r', encoding='utf-8') as fh:
+            for line in fh:
+                m = ASSIGNMENT_RE.match(line)
+                if not m:
+                    continue
+                var, val = (m.group(1), m.group(2))
+                if var == 'prefix' and env_subs[var] is not None:
+                    continue
+                while VAR_REF_RE.search(val):
+                    val = VAR_REF_RE.sub(lambda m: env_subs[m.group(1)], val)
+                env_subs[var] = val
+                if var == 'srcdir':
+                    break
+
+    env_subs['date'] = time.strftime('%d %b %Y', time.gmtime(mtime + tz_offset)).lstrip('0')
+
+
+def html_via_commonmark(txt):
+    return commonmark.HtmlRenderer().render(commonmark.Parser().parse(txt))
+
+
+class TransformHtml(HTMLParser):
+    def __init__(self, fi):
+        HTMLParser.__init__(self, convert_charrefs=True)
+
+        self.fn = fi.fn
+
+        st = self.state = argparse.Namespace(
+                list_state = [ ],
+                p_macro = ".P\n",
+                at_first_tag_in_li = False,
+                at_first_tag_in_dd = False,
+                dt_from = None,
+                in_pre = False,
+                in_code = False,
+                html_out = [ HTML_START.replace('%TITLE%', fi.title) ],
+                man_out = [ ],
+                txt = '',
+                want_manpage = fi.want_manpage,
+                created_hashtags = set(),
+                derived_hashtags = set(),
+                referenced_hashtags = set(),
+                bad_hashtags = set(),
+                latest_targets = [ ],
+                opt_prefix = 'opt',
+                a_txt_start = None,
+                target_suf = '',
+                )
+
+        if st.want_manpage:
+            st.man_out.append(MAN_START % fi.man_headings)
+
+        if '</table>' in fi.html_in:
+            st.html_out[0] = st.html_out[0].replace('</style>', TABLE_STYLE + '</style>')
+
+        self.feed(fi.html_in)
+        fi.html_in = None
+
+        if st.want_manpage:
+            st.html_out.append(MAN_HTML_END % env_subs['date'])
+        st.html_out.append(HTML_END)
+        st.man_out.append(MAN_END)
+
+        fi.html_out = ''.join(st.html_out)
+        st.html_out = None
+
+        fi.man_out = ''.join(st.man_out)
+        st.man_out = None
+
+        for tgt, txt in st.derived_hashtags:
+            derived = txt2target(txt, tgt)
+            if derived not in st.created_hashtags:
+                txt = BIN_CHARS_RE.sub('', txt.replace(NBR_DASH[0], '-').replace(NBR_SPACE[0], ' '))
+                warn('Unknown derived hashtag link in', self.fn, 'based on:', (tgt, txt))
+
+        for bad in st.bad_hashtags:
+            if bad in st.created_hashtags:
+                warn('Missing "#" in hashtag link in', self.fn + ':', bad)
+            else:
+                warn('Unknown non-hashtag link in', self.fn + ':', bad)
+
+        for bad in st.referenced_hashtags - st.created_hashtags:
+            warn('Unknown hashtag link in', self.fn + ':', '#' + bad)
+
+    def handle_starttag(self, tag, attrs_list):
+        st = self.state
+        if args.debug:
+            self.output_debug('START', (tag, attrs_list))
+        if st.at_first_tag_in_li:
+            if st.list_state[-1] == 'dl':
+                st.dt_from = tag
+                if tag == 'p':
+                    tag = 'dt'
+                else:
+                    st.html_out.append('<dt>')
+            elif tag == 'p':
+                st.at_first_tag_in_dd = True # Kluge to suppress a .P at the start of an li.
+            st.at_first_tag_in_li = False
+        if tag == 'p':
+            if not st.at_first_tag_in_dd:
+                st.man_out.append(st.p_macro)
+        elif tag == 'li':
+            st.at_first_tag_in_li = True
+            lstate = st.list_state[-1]
+            if lstate == 'dl':
+                return
+            if lstate == 'o':
+                st.man_out.append(".IP o\n")
+            else:
+                st.man_out.append(".IP " + str(lstate) + ".\n")
+                st.list_state[-1] += 1
+        elif tag == 'blockquote':
+            st.man_out.append(".RS 4\n")
+        elif tag == 'pre':
+            st.in_pre = True
+            st.man_out.append(st.p_macro + ".nf\n")
+        elif tag == 'code' and not st.in_pre:
+            st.in_code = True
+            st.txt += BOLD_FONT[0]
+        elif tag == 'strong' or tag == 'b':
+            st.txt += BOLD_FONT[0]
+        elif tag == 'em' or  tag == 'i':
+            if st.want_manpage:
+                tag = 'u' # Change it into underline to be more like the manpage
+                st.txt += UNDR_FONT[0]
+        elif tag == 'ol':
+            start = 1
+            for var, val in attrs_list:
+                if var == 'start':
+                    start = int(val) # We only support integers.
+                    break
+            if st.list_state:
+                st.man_out.append(".RS\n")
+            if start == 0:
+                tag = 'dl'
+                attrs_list = [ ]
+                st.list_state.append('dl')
+            else:
+                st.list_state.append(start)
+            st.man_out.append(st.p_macro)
+            st.p_macro = ".IP\n"
+        elif tag == 'ul':
+            st.man_out.append(st.p_macro)
+            if st.list_state:
+                st.man_out.append(".RS\n")
+                st.p_macro = ".IP\n"
+            st.list_state.append('o')
+        elif tag == 'hr':
+            st.man_out.append(".l\n")
+            st.html_out.append("<hr />")
+            return
+        elif tag == 'a':
+            st.a_href = None
+            for var, val in attrs_list:
+                if var == 'href':
+                    if val.startswith(('https://', 'http://', 'mailto:', 'ftp:')):
+                        pass # nothing to check
+                    elif '#' in val:
+                        pg, tgt = val.split('#', 1)
+                        if pg and pg not in VALID_PAGES or '#' in tgt:
+                            st.bad_hashtags.add(val)
+                        elif tgt in ('', 'opt', 'dopt'):
+                            st.a_href = val
+                        elif pg == '':
+                            st.referenced_hashtags.add(tgt)
+                            if tgt in st.latest_targets:
+                                warn('Found link to the current section in', self.fn + ':', val)
+                    elif val not in VALID_PAGES:
+                        st.bad_hashtags.add(val)
+            st.a_txt_start = len(st.txt)
+        st.html_out.append('<' + tag + ''.join(' ' + var + '="' + htmlify(val) + '"' for var, val in attrs_list) + '>')
+        st.at_first_tag_in_dd = False
+
+
+    def handle_endtag(self, tag):
+        st = self.state
+        if args.debug:
+            self.output_debug('END', (tag,))
+        if tag in CONSUMES_TXT or st.dt_from == tag:
+            txt = st.txt.strip()
+            st.txt = ''
+        else:
+            txt = None
+        add_to_txt = None
+        if tag == 'h1':
+            tgt = txt
+            target_suf = ''
+            if tgt.startswith('NEWS for '):
+                m = VERSION_RE.search(tgt)
+                if m:
+                    tgt = m.group(1)
+                    st.target_suf = '-' + tgt
+            self.add_targets(tag, tgt)
+        elif tag == 'h2':
+            st.man_out.append(st.p_macro + '.SH "' + manify(txt) + '"\n')
+            self.add_targets(tag, txt, st.target_suf)
+            st.opt_prefix = 'dopt' if txt == 'DAEMON OPTIONS' else 'opt'
+        elif tag == 'h3':
+            st.man_out.append(st.p_macro + '.SS "' + manify(txt) + '"\n')
+            self.add_targets(tag, txt, st.target_suf)
+        elif tag == 'p':
+            if st.dt_from == 'p':
+                tag = 'dt'
+                st.man_out.append('.IP "' + manify(txt) + '"\n')
+                if txt.startswith(BOLD_FONT[0]):
+                    self.add_targets(tag, txt)
+                st.dt_from = None
+            elif txt != '':
+                st.man_out.append(manify(txt) + "\n")
+        elif tag == 'li':
+            if st.list_state[-1] == 'dl':
+                if st.at_first_tag_in_li:
+                    die("Invalid 0. -> td translation")
+                tag = 'dd'
+            if txt != '':
+                st.man_out.append(manify(txt) + "\n")
+            st.at_first_tag_in_li = False
+        elif tag == 'blockquote':
+            st.man_out.append(".RE\n")
+        elif tag == 'pre':
+            st.in_pre = False
+            st.man_out.append(manify(txt) + "\n.fi\n")
+        elif (tag == 'code' and not st.in_pre):
+            st.in_code = False
+            add_to_txt = NORM_FONT[0]
+        elif tag == 'strong' or tag == 'b':
+            add_to_txt = NORM_FONT[0]
+        elif tag == 'em' or  tag == 'i':
+            if st.want_manpage:
+                tag = 'u' # Change it into underline to be more like the manpage
+                add_to_txt = NORM_FONT[0]
+        elif tag == 'ol' or tag == 'ul':
+            if st.list_state.pop() == 'dl':
+                tag = 'dl'
+            if st.list_state:
+                st.man_out.append(".RE\n")
+            else:
+                st.p_macro = ".P\n"
+            st.at_first_tag_in_dd = False
+        elif tag == 'hr':
+            return
+        elif tag == 'a':
+            if st.a_href:
+                atxt = st.txt[st.a_txt_start:]
+                find = 'href="' + st.a_href + '"'
+                for j in range(len(st.html_out)-1, 0, -1):
+                    if find in st.html_out[j]:
+                        pg, tgt = st.a_href.split('#', 1)
+                        derived = txt2target(atxt, tgt)
+                        if pg == '':
+                            if derived in st.latest_targets:
+                                warn('Found link to the current section in', self.fn + ':', st.a_href)
+                            st.derived_hashtags.add((tgt, atxt))
+                        st.html_out[j] = st.html_out[j].replace(find, 'href="' + pg + '#' + derived + '"')
+                        break
+                else:
+                    die('INTERNAL ERROR: failed to find href in html data:', find)
+        st.html_out.append('</' + tag + '>')
+        if add_to_txt:
+            if txt is None:
+                st.txt += add_to_txt
+            else:
+                txt += add_to_txt
+        if st.dt_from == tag:
+            st.man_out.append('.IP "' + manify(txt) + '"\n')
+            st.html_out.append('</dt><dd>')
+            st.at_first_tag_in_dd = True
+            st.dt_from = None
+        elif tag == 'dt':
+            st.html_out.append('<dd>')
+            st.at_first_tag_in_dd = True
+
+
+    def handle_data(self, txt):
+        st = self.state
+        if '](' in txt:
+            warn('Malformed link in', self.fn + ':', txt)
+        if args.debug:
+            self.output_debug('DATA', (txt,))
+        if st.in_pre:
+            html = htmlify(txt)
+        else:
+            txt = SPACE_DOUBLE_DASH_RE.sub(NBR_SPACE[0] + r'--\1', txt).replace('--', NBR_DASH[0]*2)
+            txt = NON_SPACE_SINGLE_DASH_RE.sub(r'\1' + NBR_DASH[0], txt)
+            html = htmlify(txt)
+            if st.in_code:
+                txt = WHITESPACE_RE.sub(NBR_SPACE[0], txt)
+                html = html.replace(NBR_DASH[0], '-').replace(NBR_SPACE[0], ' ') # <code> is non-breaking in CSS
+        st.html_out.append(html.replace(NBR_SPACE[0], '&nbsp;').replace(NBR_DASH[0], '-&#8288;'))
+        st.txt += txt
+
+
+    def add_targets(self, tag, txt, suf=None):
+        st = self.state
+        tag = '<' + tag + '>'
+        targets = CODE_BLOCK_RE.findall(txt)
+        if not targets:
+            targets = [ txt ]
+        tag_pos = 0
+        for txt in targets:
+            txt = txt2target(txt, st.opt_prefix)
+            if not txt:
+                continue
+            if suf:
+                txt += suf
+            if txt in st.created_hashtags:
+                for j in range(2, 1000):
+                    chk = txt + '-' + str(j)
+                    if chk not in st.created_hashtags:
+                        print('Made link target unique:', chk)
+                        txt = chk
+                        break
+            if tag_pos == 0:
+                tag_pos -= 1
+                while st.html_out[tag_pos] != tag:
+                    tag_pos -= 1
+                st.html_out[tag_pos] = tag[:-1] + ' id="' + txt + '">'
+                st.html_out.append('<a href="#' + txt + '" class="tgt"></a>')
+                tag_pos -= 1 # take into account the append
+            else:
+                st.html_out[tag_pos] = '<span id="' + txt + '"></span>' + st.html_out[tag_pos]
+            st.created_hashtags.add(txt)
+        st.latest_targets = targets
+
+
+    def output_debug(self, event, extra):
+        import pprint
+        st = self.state
+        if args.debug < 2:
+            st = argparse.Namespace(**vars(st))
+            if len(st.html_out) > 2:
+                st.html_out = ['...'] + st.html_out[-2:]
+            if len(st.man_out) > 2:
+                st.man_out = ['...'] + st.man_out[-2:]
+        print(event, extra)
+        pprint.PrettyPrinter(indent=2).pprint(vars(st))
+
+
+def txt2target(txt, opt_prefix):
+    txt = txt.strip().rstrip(':')
+    m = CODE_BLOCK_RE.search(txt)
+    if m:
+        txt = m.group(1)
+    txt = NBR_DASH_RE.sub('-', txt)
+    txt = BIN_CHARS_RE.sub('', txt)
+    txt = INVALID_TARGET_CHARS_RE.sub('_', txt)
+    if opt_prefix and txt.startswith('-'):
+        txt = opt_prefix + txt
+    else:
+        txt = INVALID_START_CHAR_RE.sub(r't\1', txt)
+    return txt
+
+
+def manify(txt):
+    return MANIFY_LINESTART_RE.sub(r'\&\1', txt.replace('\\', '\\\\')
+            .replace(NBR_SPACE[0], NBR_SPACE[1])
+            .replace(NBR_DASH[0], NBR_DASH[1])
+            .replace(NORM_FONT[0], NORM_FONT[1])
+            .replace(BOLD_FONT[0], BOLD_FONT[1])
+            .replace(UNDR_FONT[0], UNDR_FONT[1]))
+
+
+def htmlify(txt):
+    return txt.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;')
+
+
+def warn(*msg):
+    print(*msg, file=sys.stderr)
+    global warning_count
+    warning_count += 1
+
+
+def die(*msg):
+    warn(*msg)
+    sys.exit(1)
+
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description="Convert markdown into html and (optionally) nroff. Each input filename must have a .md suffix, which is changed to .html for the output filename. If the input filename ends with .num.md (e.g. foo.1.md) then a nroff file is also output with the input filename's .md suffix removed (e.g. foo.1).", add_help=False)
+    parser.add_argument('--test', action='store_true', help="Just test the parsing without outputting any files.")
+    parser.add_argument('--dest', metavar='DIR', help="Create files in DIR instead of the current directory.")
+    parser.add_argument('--debug', '-D', action='count', default=0, help='Output copious info on the html parsing. Repeat for even more.')
+    parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
+    parser.add_argument("mdfiles", metavar='FILE.md', nargs='+', help="One or more .md files to convert.")
+    args = parser.parse_args()
+
+    try:
+        import cmarkgfm
+        md_parser = cmarkgfm.markdown_to_html
+        gfm_parser = cmarkgfm.github_flavored_markdown_to_html
+    except:
+        try:
+            import commonmark
+            md_parser = html_via_commonmark
+        except:
+            die("Failed to find cmarkgfm or commonmark for python3.")
+        gfm_parser = None
+
+    main()
+    if warning_count:
+        sys.exit(1)
diff --git a/md2man b/md2man
deleted file mode 100755 (executable)
index 7f783c56cc704ccd8b570acaf62052a81b695463..0000000000000000000000000000000000000000
--- a/md2man
+++ /dev/null
@@ -1,383 +0,0 @@
-#!/usr/bin/env python3
-
-# This script takes a manpage written in markdown and turns it into an html web
-# page and a nroff man page.  The input file must have the name of the program
-# and the section in this format: NAME.NUM.md.  The output files are written
-# into the current directory named NAME.NUM.html and NAME.NUM.  The input
-# format has one extra extension: if a numbered list starts at 0, it is turned
-# into a description list. The dl's dt tag is taken from the contents of the
-# first tag inside the li, which is usually a p, code, or strong tag.  The
-# cmarkgfm or commonmark lib is used to transforms the input file into html.
-# The html.parser is used as a state machine that both tweaks the html and
-# outputs the nroff data based on the html tags.
-#
-# Copyright (C) 2020 Wayne Davison
-#
-# This program is freely redistributable.
-
-import sys, os, re, argparse, subprocess, time
-from html.parser import HTMLParser
-
-CONSUMES_TXT = set('h1 h2 p li pre'.split())
-
-HTML_START = """\
-<html><head>
-<title>%s</title>
-<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap" rel="stylesheet">
-<style>
-body {
-  max-width: 50em;
-  margin: auto;
-}
-body, b, strong, u {
-  font-family: 'Roboto', sans-serif;
-}
-code {
-  font-family: 'Roboto Mono', monospace;
-  font-weight: bold;
-  white-space: pre;
-}
-pre code {
-  display: block;
-  font-weight: normal;
-}
-blockquote pre code {
-  background: #f1f1f1;
-}
-dd p:first-of-type {
-  margin-block-start: 0em;
-}
-</style>
-</head><body>
-"""
-
-HTML_END = """\
-<div style="float: right"><p><i>%s</i></p></div>
-</body></html>
-"""
-
-MAN_START = r"""
-.TH "%s" "%s" "%s" "%s" "User Commands"
-""".lstrip()
-
-MAN_END = """\
-"""
-
-NORM_FONT = ('\1', r"\fP")
-BOLD_FONT = ('\2', r"\fB")
-UNDR_FONT = ('\3', r"\fI")
-NBR_DASH = ('\4', r"\-")
-NBR_SPACE = ('\xa0', r"\ ")
-
-md_parser = None
-
-def main():
-    fi = re.match(r'^(?P<fn>(?P<srcdir>.+/)?(?P<name>(?P<prog>[^/]+)\.(?P<sect>\d+))\.md)$', args.mdfile)
-    if not fi:
-        die('Failed to parse NAME.NUM.md out of input file:', args.mdfile)
-    fi = argparse.Namespace(**fi.groupdict())
-
-    if not fi.srcdir:
-        fi.srcdir = './'
-
-    fi.title = fi.prog + '(' + fi.sect + ') man page'
-    fi.mtime = 0
-
-    git_dir = fi.srcdir + '.git'
-    if os.path.lexists(git_dir):
-        fi.mtime = int(subprocess.check_output(['git', '--git-dir', git_dir, 'log', '-1', '--format=%at']))
-
-    env_subs = { 'prefix': os.environ.get('RSYNC_OVERRIDE_PREFIX', None) }
-
-    if args.test:
-        env_subs['VERSION'] = '1.0.0'
-        env_subs['libdir'] = '/usr'
-    else:
-        for fn in (fi.srcdir + 'version.h', 'Makefile'):
-            try:
-                st = os.lstat(fn)
-            except:
-                die('Failed to find', fi.srcdir + fn)
-            if not fi.mtime:
-                fi.mtime = st.st_mtime
-
-        with open(fi.srcdir + 'version.h', 'r', encoding='utf-8') as fh:
-            txt = fh.read()
-        m = re.search(r'"(.+?)"', txt)
-        env_subs['VERSION'] = m.group(1)
-
-        with open('Makefile', 'r', encoding='utf-8') as fh:
-            for line in fh:
-                m = re.match(r'^(\w+)=(.+)', line)
-                if not m:
-                    continue
-                var, val = (m.group(1), m.group(2))
-                if var == 'prefix' and env_subs[var] is not None:
-                    continue
-                while re.search(r'\$\{', val):
-                    val = re.sub(r'\$\{(\w+)\}', lambda m: env_subs[m.group(1)], val)
-                env_subs[var] = val
-                if var == 'srcdir':
-                    break
-
-    with open(fi.fn, 'r', encoding='utf-8') as fh:
-        txt = fh.read()
-
-    txt = re.sub(r'@VERSION@', env_subs['VERSION'], txt)
-    txt = re.sub(r'@LIBDIR@', env_subs['libdir'], txt)
-
-    fi.html_in = md_parser(txt)
-    txt = None
-
-    fi.date = time.strftime('%d %b %Y', time.localtime(fi.mtime))
-    fi.man_headings = (fi.prog, fi.sect, fi.date, fi.prog + ' ' + env_subs['VERSION'])
-
-    HtmlToManPage(fi)
-
-    if args.test:
-        print("The test was successful.")
-        return
-
-    for fn, txt in ((fi.name + '.html', fi.html_out), (fi.name, fi.man_out)):
-        print("Wrote:", fn)
-        with open(fn, 'w', encoding='utf-8') as fh:
-            fh.write(txt)
-
-
-def html_via_commonmark(txt):
-    return commonmark.HtmlRenderer().render(commonmark.Parser().parse(txt))
-
-
-class HtmlToManPage(HTMLParser):
-    def __init__(self, fi):
-        HTMLParser.__init__(self, convert_charrefs=True)
-
-        st = self.state = argparse.Namespace(
-                list_state = [ ],
-                p_macro = ".P\n",
-                at_first_tag_in_li = False,
-                at_first_tag_in_dd = False,
-                dt_from = None,
-                in_pre = False,
-                in_code = False,
-                html_out = [ HTML_START % fi.title ],
-                man_out = [ MAN_START % fi.man_headings ],
-                txt = '',
-                )
-
-        self.feed(fi.html_in)
-        fi.html_in = None
-
-        st.html_out.append(HTML_END % fi.date)
-        st.man_out.append(MAN_END)
-
-        fi.html_out = ''.join(st.html_out)
-        st.html_out = None
-
-        fi.man_out = ''.join(st.man_out)
-        st.man_out = None
-
-
-    def handle_starttag(self, tag, attrs_list):
-        st = self.state
-        if args.debug:
-            self.output_debug('START', (tag, attrs_list))
-        if st.at_first_tag_in_li:
-            if st.list_state[-1] == 'dl':
-                st.dt_from = tag
-                if tag == 'p':
-                    tag = 'dt'
-                else:
-                    st.html_out.append('<dt>')
-            elif tag == 'p':
-                st.at_first_tag_in_dd = True # Kluge to suppress a .P at the start of an li.
-            st.at_first_tag_in_li = False
-        if tag == 'p':
-            if not st.at_first_tag_in_dd:
-                st.man_out.append(st.p_macro)
-        elif tag == 'li':
-            st.at_first_tag_in_li = True
-            lstate = st.list_state[-1]
-            if lstate == 'dl':
-                return
-            if lstate == 'o':
-                st.man_out.append(".IP o\n")
-            else:
-                st.man_out.append(".IP " + str(lstate) + ".\n")
-                st.list_state[-1] += 1
-        elif tag == 'blockquote':
-            st.man_out.append(".RS 4\n")
-        elif tag == 'pre':
-            st.in_pre = True
-            st.man_out.append(st.p_macro + ".nf\n")
-        elif tag == 'code' and not st.in_pre:
-            st.in_code = True
-            st.txt += BOLD_FONT[0]
-        elif tag == 'strong' or tag == 'b':
-            st.txt += BOLD_FONT[0]
-        elif tag == 'em' or  tag == 'i':
-            tag = 'u' # Change it into underline to be more like the man page
-            st.txt += UNDR_FONT[0]
-        elif tag == 'ol':
-            start = 1
-            for var, val in attrs_list:
-                if var == 'start':
-                    start = int(val) # We only support integers.
-                    break
-            if st.list_state:
-                st.man_out.append(".RS\n")
-            if start == 0:
-                tag = 'dl'
-                attrs_list = [ ]
-                st.list_state.append('dl')
-            else:
-                st.list_state.append(start)
-            st.man_out.append(st.p_macro)
-            st.p_macro = ".IP\n"
-        elif tag == 'ul':
-            st.man_out.append(st.p_macro)
-            if st.list_state:
-                st.man_out.append(".RS\n")
-                st.p_macro = ".IP\n"
-            st.list_state.append('o')
-        st.html_out.append('<' + tag + ''.join(' ' + var + '="' + htmlify(val) + '"' for var, val in attrs_list) + '>')
-        st.at_first_tag_in_dd = False
-
-
-    def handle_endtag(self, tag):
-        st = self.state
-        if args.debug:
-            self.output_debug('END', (tag,))
-        if tag in CONSUMES_TXT or st.dt_from == tag:
-            txt = st.txt.strip()
-            st.txt = ''
-        else:
-            txt = None
-        add_to_txt = None
-        if tag == 'h1':
-            st.man_out.append(st.p_macro + '.SH "' + manify(txt) + '"\n')
-        elif tag == 'h2':
-            st.man_out.append(st.p_macro + '.SS "' + manify(txt) + '"\n')
-        elif tag == 'p':
-            if st.dt_from == 'p':
-                tag = 'dt'
-                st.man_out.append('.IP "' + manify(txt) + '"\n')
-                st.dt_from = None
-            elif txt != '':
-                st.man_out.append(manify(txt) + "\n")
-        elif tag == 'li':
-            if st.list_state[-1] == 'dl':
-                if st.at_first_tag_in_li:
-                    die("Invalid 0. -> td translation")
-                tag = 'dd'
-            if txt != '':
-                st.man_out.append(manify(txt) + "\n")
-            st.at_first_tag_in_li = False
-        elif tag == 'blockquote':
-            st.man_out.append(".RE\n")
-        elif tag == 'pre':
-            st.in_pre = False
-            st.man_out.append(manify(txt) + "\n.fi\n")
-        elif (tag == 'code' and not st.in_pre):
-            st.in_code = False
-            add_to_txt = NORM_FONT[0]
-        elif tag == 'strong' or tag == 'b':
-            add_to_txt = NORM_FONT[0]
-        elif tag == 'em' or  tag == 'i':
-            tag = 'u' # Change it into underline to be more like the man page
-            add_to_txt = NORM_FONT[0]
-        elif tag == 'ol' or tag == 'ul':
-            if st.list_state.pop() == 'dl':
-                tag = 'dl'
-            if st.list_state:
-                st.man_out.append(".RE\n")
-            else:
-                st.p_macro = ".P\n"
-            st.at_first_tag_in_dd = False
-        st.html_out.append('</' + tag + '>')
-        if add_to_txt:
-            if txt is None:
-                st.txt += add_to_txt
-            else:
-                txt += add_to_txt
-        if st.dt_from == tag:
-            st.man_out.append('.IP "' + manify(txt) + '"\n')
-            st.html_out.append('</dt><dd>')
-            st.at_first_tag_in_dd = True
-            st.dt_from = None
-        elif tag == 'dt':
-            st.html_out.append('<dd>')
-            st.at_first_tag_in_dd = True
-
-
-    def handle_data(self, txt):
-        st = self.state
-        if args.debug:
-            self.output_debug('DATA', (txt,))
-        if st.in_pre:
-            html = htmlify(txt)
-        else:
-            txt = re.sub(r'\s--(\s)', NBR_SPACE[0] + r'--\1', txt).replace('--', NBR_DASH[0]*2)
-            txt = re.sub(r'(^|\W)-', r'\1' + NBR_DASH[0], txt)
-            html = htmlify(txt)
-            if st.in_code:
-                txt = re.sub(r'\s', NBR_SPACE[0], txt)
-                html = html.replace(NBR_DASH[0], '-').replace(NBR_SPACE[0], ' ') # <code> is non-breaking in CSS
-        st.html_out.append(html.replace(NBR_SPACE[0], '&nbsp;').replace(NBR_DASH[0], '-&#8288;'))
-        st.txt += txt
-
-
-    def output_debug(self, event, extra):
-        import pprint
-        st = self.state
-        if args.debug < 2:
-            st = argparse.Namespace(**vars(st))
-            if len(st.html_out) > 2:
-                st.html_out = ['...'] + st.html_out[-2:]
-            if len(st.man_out) > 2:
-                st.man_out = ['...'] + st.man_out[-2:]
-        print(event, extra)
-        pprint.PrettyPrinter(indent=2).pprint(vars(st))
-
-
-def manify(txt):
-    return re.sub(r"^(['.])", r'\&\1', txt.replace('\\', '\\\\')
-            .replace(NBR_SPACE[0], NBR_SPACE[1])
-            .replace(NBR_DASH[0], NBR_DASH[1])
-            .replace(NORM_FONT[0], NORM_FONT[1])
-            .replace(BOLD_FONT[0], BOLD_FONT[1])
-            .replace(UNDR_FONT[0], UNDR_FONT[1]), flags=re.M)
-
-
-def htmlify(txt):
-    return txt.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;')
-
-
-def warn(*msg):
-    print(*msg, file=sys.stderr)
-
-
-def die(*msg):
-    warn(*msg)
-    sys.exit(1)
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Transform a NAME.NUM.md markdown file into a NAME.NUM.html web page & a NAME.NUM man page.', add_help=False)
-    parser.add_argument('--test', action='store_true', help='Test if we can parse the input w/o updating any files.')
-    parser.add_argument('--debug', '-D', action='count', default=0, help='Output copious info on the html parsing. Repeat for even more.')
-    parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
-    parser.add_argument('mdfile', help="The NAME.NUM.md file to parse.")
-    args = parser.parse_args()
-
-    try:
-        import cmarkgfm
-        md_parser = cmarkgfm.markdown_to_html
-    except:
-        try:
-            import commonmark
-            md_parser = html_via_commonmark
-        except:
-            die("Failed to find cmarkgfm or commonmark for python3.")
-
-    main()
diff --git a/md2man b/md2man
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..5d1a8fcd984fac8d0745ab286dfcb039995d4d45
--- /dev/null
+++ b/md2man
@@ -0,0 +1 @@
+md-convert
\ No newline at end of file
index c0dd1b5..0102b08 100755 (executable)
--- a/mkgitver
+++ b/mkgitver
@@ -1,11 +1,22 @@
 #!/bin/sh
 
 srcdir=`dirname $0`
-gitver=`git describe --abbrev=8 2>/dev/null`
 
-if test x"$gitver" != x; then
-    gitver=\""$gitver"\"
-else
-    gitver=RSYNC_VERSION
+if [ ! -f git-version.h ]; then
+    touch git-version.h
+fi
+
+if test -d "$srcdir/.git" || test -f "$srcdir/.git"; then
+    gitver=`git describe --abbrev=8 2>/dev/null`
+    # NOTE: I'm avoiding "|" in sed since I'm not sure if sed -r is portable and "\|" fails on some OSes.
+    verchk=`echo "$gitver-" | sed -n '/^v3\.[0-9][0-9]*\.[0-9][0-9]*\(pre[0-9]*\)*-/p'`
+    if [ -n "$verchk" ]; then
+       echo "#define RSYNC_GITVER \"$gitver\"" >git-version.h.new
+       if ! diff git-version.h.new git-version.h >/dev/null; then
+           echo "Updating git-version.h"
+           mv git-version.h.new git-version.h
+       else
+           rm git-version.h.new
+       fi
+    fi
 fi
-echo "#define RSYNC_GITVER $gitver" >git-version.h
index a9f0dc9..d38bbe8 100644 (file)
--- a/options.c
+++ b/options.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
  * Copyright (C) 2000, 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2002-2020 Wayne Davison
+ * Copyright (C) 2002-2022 Wayne Davison
  *
  * 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
@@ -27,6 +27,8 @@
 extern int module_id;
 extern int local_server;
 extern int sanitize_paths;
+extern int trust_sender_args;
+extern int trust_sender_filter;
 extern unsigned int module_dirlen;
 extern filter_rule_list filter_list;
 extern filter_rule_list daemon_filter_list;
@@ -47,6 +49,7 @@ int append_mode = 0;
 int keep_dirlinks = 0;
 int copy_dirlinks = 0;
 int copy_links = 0;
+int copy_devices = 0;
 int write_devices = 0;
 int preserve_links = 0;
 int preserve_hard_links = 0;
@@ -58,14 +61,18 @@ int preserve_devices = 0;
 int preserve_specials = 0;
 int preserve_uid = 0;
 int preserve_gid = 0;
-int preserve_times = 0;
+int preserve_mtimes = 0;
 int preserve_atimes = 0;
 int preserve_crtimes = 0;
+int omit_dir_times = 0;
+int omit_link_times = 0;
+int trust_sender = 0;
 int update_only = 0;
 int open_noatime = 0;
 int cvs_exclude = 0;
 int dry_run = 0;
 int do_xfers = 1;
+int do_fsync = 0;
 int ignore_times = 0;
 int delete_mode = 0;
 int delete_during = 0;
@@ -88,6 +95,7 @@ int implied_dirs = 1;
 int missing_args = 0; /* 0 = FERROR_XFER, 1 = ignore, 2 = delete */
 int numeric_ids = 0;
 int msgs2stderr = 2; /* Default: send errors to stderr for local & remote-shell transfers */
+int saw_stderr_opt = 0;
 int allow_8bit_chars = 0;
 int force_delete = 0;
 int io_timeout = 0;
@@ -98,6 +106,7 @@ int filesfrom_fd = -1;
 char *filesfrom_host = NULL;
 int eol_nulls = 0;
 int protect_args = -1;
+int old_style_args = -1;
 int human_readable = 1;
 int recurse = 0;
 int mkpath_dest_arg = 0;
@@ -227,7 +236,7 @@ static const char *debug_verbosity[] = {
 #define MAX_VERBOSITY ((int)(sizeof debug_verbosity / sizeof debug_verbosity[0]) - 1)
 
 static const char *info_verbosity[1+MAX_VERBOSITY] = {
-       /*0*/ NULL,
+       /*0*/ "NONREG",
        /*1*/ "COPY,DEL,FLIST,MISC,NAME,STATS,SYMSAFE",
        /*2*/ "BACKUP,MISC2,MOUNT,NAME2,REMOVE,SKIP",
 };
@@ -265,9 +274,10 @@ static struct output_struct info_words[COUNT_INFO+1] = {
        INFO_WORD(MISC, W_SND|W_REC, "Mention miscellaneous information (levels 1-2)"),
        INFO_WORD(MOUNT, W_SND|W_REC, "Mention mounts that were found or skipped"),
        INFO_WORD(NAME, W_SND|W_REC, "Mention 1) updated file/dir names, 2) unchanged names"),
+       INFO_WORD(NONREG, W_REC, "Mention skipped non-regular files (default 1, 0 disables)"),
        INFO_WORD(PROGRESS, W_CLI, "Mention 1) per-file progress or 2) total transfer progress"),
        INFO_WORD(REMOVE, W_SND, "Mention files removed on the sending side"),
-       INFO_WORD(SKIP, W_REC, "Mention files that are skipped due to options used"),
+       INFO_WORD(SKIP, W_REC, "Mention files skipped due to transfer overrides (levels 1-2)"),
        INFO_WORD(STATS, W_CLI|W_SRV, "Mention statistics at end of run (levels 1-3)"),
        INFO_WORD(SYMSAFE, W_SND|W_REC, "Mention symlinks that are unsafe"),
        { NULL, "--info", 0, 0, 0, 0 }
@@ -286,7 +296,7 @@ static struct output_struct debug_words[COUNT_DEBUG+1] = {
        DEBUG_WORD(DELTASUM, W_SND|W_REC, "Debug delta-transfer checksumming (levels 1-4)"),
        DEBUG_WORD(DUP, W_REC, "Debug weeding of duplicate names"),
        DEBUG_WORD(EXIT, W_CLI|W_SRV, "Debug exit events (levels 1-3)"),
-       DEBUG_WORD(FILTER, W_SND|W_REC, "Debug filter actions (levels 1-2)"),
+       DEBUG_WORD(FILTER, W_SND|W_REC, "Debug filter actions (levels 1-3)"),
        DEBUG_WORD(FLIST, W_SND|W_REC, "Debug file-list operations (levels 1-4)"),
        DEBUG_WORD(FUZZY, W_REC, "Debug fuzzy scoring (levels 1-2)"),
        DEBUG_WORD(GENR, W_REC, "Debug generator functions"),
@@ -307,8 +317,6 @@ static int verbose = 0;
 static int do_stats = 0;
 static int do_progress = 0;
 static int daemon_opt;   /* sets am_daemon after option error-reporting */
-static int omit_dir_times = 0;
-static int omit_link_times = 0;
 static int F_option_cnt = 0;
 static int modify_window_set;
 static int itemize_changes = 0;
@@ -487,9 +495,9 @@ static void output_item_help(struct output_struct *words)
 
        rprintf(FINFO, fmt, "HELP", "Output this help message");
        rprintf(FINFO, "\n");
-       rprintf(FINFO, "Options added for each increase in verbose level:\n");
+       rprintf(FINFO, "Options added at each level of verbosity:\n");
 
-       for (j = 1; j <= MAX_VERBOSITY; j++) {
+       for (j = 0; j <= MAX_VERBOSITY; j++) {
                parse_output_words(words, levels, verbosity[j], HELP_PRIORITY);
                opt = make_output_option(words, levels, W_CLI|W_SRV|W_SND|W_REC);
                if (opt) {
@@ -508,7 +516,7 @@ static void set_output_verbosity(int level, uchar priority)
        if (level > MAX_VERBOSITY)
                level = MAX_VERBOSITY;
 
-       for (j = 1; j <= level; j++) {
+       for (j = 0; j <= level; j++) {
                parse_output_words(info_words, info_levels, info_verbosity[j], priority);
                parse_output_words(debug_words, debug_levels, debug_verbosity[j], priority);
        }
@@ -527,7 +535,7 @@ void limit_output_verbosity(int level)
        memset(debug_limits, 0, sizeof debug_limits);
 
        /* Compute the level limits in the above arrays. */
-       for (j = 1; j <= level; j++) {
+       for (j = 0; j <= level; j++) {
                parse_output_words(info_words, info_limits, info_verbosity[j], LIMIT_PRIORITY);
                parse_output_words(debug_words, debug_limits, debug_verbosity[j], LIMIT_PRIORITY);
        }
@@ -574,7 +582,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
       OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
       OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG, OPT_BLOCK_SIZE,
       OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR,
-      OPT_OLD_COMPRESS, OPT_NEW_COMPRESS, OPT_NO_COMPRESS,
+      OPT_OLD_COMPRESS, OPT_NEW_COMPRESS, OPT_NO_COMPRESS, OPT_OLD_ARGS,
       OPT_STOP_AFTER, OPT_STOP_AT,
       OPT_REFUSED_BASE = 9000};
 
@@ -621,9 +629,9 @@ static struct poptOption long_options[] = {
   {"xattrs",          'X', POPT_ARG_NONE,   0, 'X', 0, 0 },
   {"no-xattrs",        0,  POPT_ARG_VAL,    &preserve_xattrs, 0, 0, 0 },
   {"no-X",             0,  POPT_ARG_VAL,    &preserve_xattrs, 0, 0, 0 },
-  {"times",           't', POPT_ARG_VAL,    &preserve_times, 1, 0, 0 },
-  {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
-  {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
+  {"times",           't', POPT_ARG_VAL,    &preserve_mtimes, 1, 0, 0 },
+  {"no-times",         0,  POPT_ARG_VAL,    &preserve_mtimes, 0, 0, 0 },
+  {"no-t",             0,  POPT_ARG_VAL,    &preserve_mtimes, 0, 0, 0 },
   {"atimes",          'U', POPT_ARG_NONE,   0, 'U', 0, 0 },
   {"no-atimes",        0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
   {"no-U",             0,  POPT_ARG_VAL,    &preserve_atimes, 0, 0, 0 },
@@ -652,6 +660,7 @@ static struct poptOption long_options[] = {
   {"no-D",             0,  POPT_ARG_NONE,   0, OPT_NO_D, 0, 0 },
   {"devices",          0,  POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
   {"no-devices",       0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
+  {"copy-devices",     0,  POPT_ARG_NONE,   &copy_devices, 0, 0, 0 },
   {"write-devices",    0,  POPT_ARG_VAL,    &write_devices, 1, 0, 0 },
   {"no-write-devices", 0,  POPT_ARG_VAL,    &write_devices, 0, 0, 0 },
   {"specials",         0,  POPT_ARG_VAL,    &preserve_specials, 1, 0, 0 },
@@ -777,9 +786,14 @@ static struct poptOption long_options[] = {
   {"files-from",       0,  POPT_ARG_STRING, &files_from, 0, 0, 0 },
   {"from0",           '0', POPT_ARG_VAL,    &eol_nulls, 1, 0, 0},
   {"no-from0",         0,  POPT_ARG_VAL,    &eol_nulls, 0, 0, 0},
-  {"protect-args",    's', POPT_ARG_VAL,    &protect_args, 1, 0, 0},
+  {"old-args",         0,  POPT_ARG_NONE,   0, OPT_OLD_ARGS, 0, 0},
+  {"no-old-args",      0,  POPT_ARG_VAL,    &old_style_args, 0, 0, 0},
+  {"secluded-args",   's', POPT_ARG_VAL,    &protect_args, 1, 0, 0},
+  {"no-secluded-args", 0,  POPT_ARG_VAL,    &protect_args, 0, 0, 0},
+  {"protect-args",     0,  POPT_ARG_VAL,    &protect_args, 1, 0, 0},
   {"no-protect-args",  0,  POPT_ARG_VAL,    &protect_args, 0, 0, 0},
   {"no-s",             0,  POPT_ARG_VAL,    &protect_args, 0, 0, 0},
+  {"trust-sender",     0,  POPT_ARG_VAL,    &trust_sender, 1, 0, 0},
   {"numeric-ids",      0,  POPT_ARG_VAL,    &numeric_ids, 1, 0, 0 },
   {"no-numeric-ids",   0,  POPT_ARG_VAL,    &numeric_ids, 0, 0, 0 },
   {"usermap",          0,  POPT_ARG_STRING, 0, OPT_USERMAP, 0, 0 },
@@ -789,6 +803,7 @@ static struct poptOption long_options[] = {
   {"no-timeout",       0,  POPT_ARG_VAL,    &io_timeout, 0, 0, 0 },
   {"contimeout",       0,  POPT_ARG_INT,    &connect_timeout, 0, 0, 0 },
   {"no-contimeout",    0,  POPT_ARG_VAL,    &connect_timeout, 0, 0, 0 },
+  {"fsync",            0,  POPT_ARG_NONE,   &do_fsync, 0, 0, 0 },
   {"stop-after",       0,  POPT_ARG_STRING, 0, OPT_STOP_AFTER, 0, 0 },
   {"time-limit",       0,  POPT_ARG_STRING, 0, OPT_STOP_AFTER, 0, 0 }, /* earlier stop-after name */
   {"stop-at",          0,  POPT_ARG_STRING, 0, OPT_STOP_AT, 0, 0 },
@@ -937,11 +952,12 @@ static void set_refuse_options(void)
                if (!am_daemon
                 || op->shortName == 'e' /* Required for compatibility flags */
                 || op->shortName == '0' /* --from0 just modifies --files-from, so refuse that instead (or not) */
-                || op->shortName == 's' /* --protect-args is always OK */
+                || op->shortName == 's' /* --secluded-args is always OK */
                 || op->shortName == 'n' /* --dry-run is always OK */
                 || strcmp("iconv", longName) == 0
                 || strcmp("no-iconv", longName) == 0
                 || strcmp("checksum-seed", longName) == 0
+                || strcmp("copy-devices", longName) == 0 /* disable wild-match (it gets refused below) */
                 || strcmp("write-devices", longName) == 0 /* disable wild-match (it gets refused below) */
                 || strcmp("log-format", longName) == 0 /* aka out-format (NOT log-file-format) */
                 || strcmp("sender", longName) == 0
@@ -953,6 +969,7 @@ static void set_refuse_options(void)
        assert(list_end != NULL);
 
        if (am_daemon) { /* Refused by default, but can be accepted via a negated exact match. */
+               parse_one_refuse_match(0, "copy-devices", list_end);
                parse_one_refuse_match(0, "write-devices", list_end);
        }
 
@@ -1516,7 +1533,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        preserve_links = 1;
 #endif
                        preserve_perms = 1;
-                       preserve_times = 1;
+                       preserve_mtimes = 1;
                        preserve_gid = 1;
                        preserve_uid = 1;
                        preserve_devices = 1;
@@ -1601,6 +1618,13 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        compress_choice = NULL;
                        break;
 
+               case OPT_OLD_ARGS:
+                       if (old_style_args <= 0)
+                               old_style_args = 1;
+                       else
+                               old_style_args++;
+                       break;
+
                case 'M':
                        arg = poptGetOptArg(pc);
                        if (*arg != '-') {
@@ -1745,6 +1769,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        }
                        usermap = (char *)poptGetOptArg(pc);
                        usermap_via_chown = False;
+                       preserve_uid = 1;
                        break;
 
                case OPT_GROUPMAP:
@@ -1760,6 +1785,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                        }
                        groupmap = (char *)poptGetOptArg(pc);
                        groupmap_via_chown = False;
+                       preserve_gid = 1;
                        break;
 
                case OPT_CHOWN: {
@@ -1783,6 +1809,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                                if (asprintf(&usermap, "*:%.*s", len, chown) < 0)
                                        out_of_memory("parse_arguments");
                                usermap_via_chown = True;
+                               preserve_uid = 1;
                        }
                        if (arg && *arg) {
                                if (groupmap) {
@@ -1798,6 +1825,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                                if (asprintf(&groupmap, "*:%s", arg) < 0)
                                        out_of_memory("parse_arguments");
                                groupmap_via_chown = True;
+                               preserve_gid = 1;
                        }
                        break;
                }
@@ -1875,6 +1903,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                                        "--stderr mode \"%s\" is not one of errors, all, or client\n", arg);
                                return 0;
                        }
+                       saw_stderr_opt = 1;
                        break;
                }
 
@@ -1893,8 +1922,11 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                }
        }
 
+       if (msgs2stderr != 2)
+               saw_stderr_opt = 1;
+
        if (version_opt_cnt) {
-               print_rsync_version(FINFO);
+               print_rsync_version(version_opt_cnt > 1 && !am_server ? FNONE : FINFO);
                exit_cleanup(0);
        }
 
@@ -1910,13 +1942,28 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                max_alloc = size;
        }
 
+       if (old_style_args < 0) {
+               if (!am_server && protect_args <= 0 && (arg = getenv("RSYNC_OLD_ARGS")) != NULL && *arg) {
+                       protect_args = 0;
+                       old_style_args = atoi(arg);
+               } else
+                       old_style_args = 0;
+       } else if (old_style_args) {
+               if (protect_args > 0) {
+                       snprintf(err_buf, sizeof err_buf,
+                                "--secluded-args conflicts with --old-args.\n");
+                       return 0;
+               }
+               protect_args = 0;
+       }
+
        if (protect_args < 0) {
                if (am_server)
                        protect_args = 0;
                else if ((arg = getenv("RSYNC_PROTECT_ARGS")) != NULL && *arg)
                        protect_args = atoi(arg) ? 1 : 0;
                else {
-#ifdef RSYNC_USE_PROTECTED_ARGS
+#ifdef RSYNC_USE_SECLUDED_ARGS
                        protect_args = 1;
 #else
                        protect_args = 0;
@@ -2255,20 +2302,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                parse_filter_str(&filter_list, backup_dir_buf, rule_template(0), 0);
        }
 
-       if (preserve_times) {
-               preserve_times = PRESERVE_FILE_TIMES;
-               if (!omit_dir_times)
-                       preserve_times |= PRESERVE_DIR_TIMES;
-#ifdef CAN_SET_SYMLINK_TIMES
-               if (!omit_link_times)
-                       preserve_times |= PRESERVE_LINK_TIMES;
-#endif
-       }
-
-       if (make_backups && !backup_dir) {
-               omit_dir_times = 0; /* Implied, so avoid -O to sender. */
-               preserve_times &= ~PRESERVE_DIR_TIMES;
-       }
+       if (make_backups && !backup_dir)
+               omit_dir_times = -1; /* Implied, so avoid -O to sender. */
 
        if (stdout_format) {
                if (am_server && log_format_has(stdout_format, 'I'))
@@ -2436,6 +2471,11 @@ int parse_arguments(int *argc_p, const char ***argv_p)
                }
        }
 
+       if (trust_sender || am_server || read_batch)
+               trust_sender_args = trust_sender_filter = 1;
+       else if (old_style_args || filesfrom_host != NULL)
+               trust_sender_args = 1;
+
        am_starting_up = 0;
 
        return 1;
@@ -2447,6 +2487,73 @@ int parse_arguments(int *argc_p, const char ***argv_p)
 }
 
 
+static char SPLIT_ARG_WHEN_OLD[1];
+
+/**
+ * Do backslash quoting of any weird chars in "arg", append the resulting
+ * string to the end of the "opt" (which gets a "=" appended if it is not
+ * an empty or NULL string), and return the (perhaps malloced) result.
+ * If opt is NULL, arg is considered a filename arg that allows wildcards.
+ * If it is "" or any other value, it is considered an option.
+ **/
+char *safe_arg(const char *opt, const char *arg)
+{
+#define SHELL_CHARS "!#$&;|<>(){}\"' \t\\"
+#define WILD_CHARS  "*?[]" /* We don't allow remote brace expansion */
+       BOOL is_filename_arg = !opt;
+       char *escapes = is_filename_arg ? SHELL_CHARS : WILD_CHARS SHELL_CHARS;
+       BOOL escape_leading_dash = is_filename_arg && *arg == '-';
+       BOOL escape_leading_tilde = 0;
+       int len1 = opt && *opt ? strlen(opt) + 1 : 0;
+       int len2 = strlen(arg);
+       int extras = escape_leading_dash ? 2 : 0;
+       char *ret;
+       if (!protect_args && old_style_args < 2 && (!old_style_args || (!is_filename_arg && opt != SPLIT_ARG_WHEN_OLD))) {
+               const char *f;
+               if (!trust_sender_args && *arg == '~'
+                && ((relative_paths && !strstr(arg, "/./"))
+                 || !strchr(arg, '/'))) {
+                       extras++;
+                       escape_leading_tilde = 1;
+               }
+               for (f = arg; *f; f++) {
+                       if (strchr(escapes, *f))
+                               extras++;
+               }
+       }
+       if (!len1 && !extras)
+               return (char*)arg;
+       ret = new_array(char, len1 + len2 + extras + 1);
+       if (len1) {
+               memcpy(ret, opt, len1-1);
+               ret[len1-1] = '=';
+       }
+       if (escape_leading_dash) {
+               ret[len1++] = '.';
+               ret[len1++] = '/';
+               extras -= 2;
+       }
+       if (!extras)
+               memcpy(ret + len1, arg, len2);
+       else {
+               const char *f = arg;
+               char *t = ret + len1;
+               if (escape_leading_tilde)
+                       *t++ = '\\';
+               while (*f) {
+                        if (*f == '\\') {
+                               if (!is_filename_arg || !strchr(WILD_CHARS, f[1]))
+                                       *t++ = '\\';
+                       } else if (strchr(escapes, *f))
+                               *t++ = '\\';
+                       *t++ = *f++;
+               }
+       }
+       ret[len1+len2+extras] = '\0';
+       return ret;
+}
+
+
 /**
  * Construct a filtered list of options to pass through from the
  * client to the server.
@@ -2496,7 +2603,7 @@ void server_options(char **args, int *argc_p)
                        argstr[x++] = 'K';
                if (prune_empty_dirs)
                        argstr[x++] = 'm';
-               if (omit_dir_times)
+               if (omit_dir_times > 0)
                        argstr[x++] = 'O';
                if (omit_link_times)
                        argstr[x++] = 'J';
@@ -2529,7 +2636,7 @@ void server_options(char **args, int *argc_p)
                argstr[x++] = 'g';
        if (preserve_devices) /* ignore preserve_specials here */
                argstr[x++] = 'D';
-       if (preserve_times)
+       if (preserve_mtimes)
                argstr[x++] = 't';
        if (preserve_atimes) {
                argstr[x++] = 'U';
@@ -2577,47 +2684,8 @@ void server_options(char **args, int *argc_p)
 
        set_allow_inc_recurse();
 
-       /* We don't really know the actual protocol_version at this point,
-        * but checking the pre-negotiated value allows the user to use a
-        * --protocol=29 override to avoid the use of this -eFLAGS opt. */
-       if (protocol_version >= 30) {
-               /* Use "eFlags" alias so that cull_options doesn't think that these are no-arg option letters. */
-#define eFlags argstr
-               /* We make use of the -e option to let the server know about
-                * any pre-release protocol version && some behavior flags. */
-               eFlags[x++] = 'e';
-#if SUBPROTOCOL_VERSION != 0
-               if (protocol_version == PROTOCOL_VERSION) {
-                       x += snprintf(argstr+x, sizeof argstr - x,
-                                     "%d.%d",
-                                     PROTOCOL_VERSION, SUBPROTOCOL_VERSION);
-               } else
-#endif
-                       eFlags[x++] = '.';
-               if (allow_inc_recurse)
-                       eFlags[x++] = 'i';
-#ifdef CAN_SET_SYMLINK_TIMES
-               eFlags[x++] = 'L'; /* symlink time-setting support */
-#endif
-#ifdef ICONV_OPTION
-               eFlags[x++] = 's'; /* symlink iconv translation support */
-#endif
-               eFlags[x++] = 'f'; /* flist I/O-error safety support */
-               eFlags[x++] = 'x'; /* xattr hardlink optimization not desired */
-               eFlags[x++] = 'C'; /* support checksum seed order fix */
-               eFlags[x++] = 'I'; /* support inplace_partial behavior */
-               eFlags[x++] = 'v'; /* use varint for flist & compat flags; negotiate checksum */
-               eFlags[x++] = 'u'; /* include name of uid 0 & gid 0 in the id map */
-               /* NOTE: Avoid using 'V' -- it was the high bit of a write_byte() that became write_varint(). */
-#undef eFlags
-       }
-
-       if (x >= (int)sizeof argstr) { /* Not possible... */
-               rprintf(FERROR, "argstr overflow in server_options().\n");
-               exit_cleanup(RERR_MALLOC);
-       }
-
-       argstr[x] = '\0';
+       /* This '\0'-terminates argstr and makes sure it didn't overflow. */
+       x += maybe_add_e_option(argstr + x, (int)sizeof argstr - x);
 
        if (x > 1)
                args[ac++] = argstr;
@@ -2629,9 +2697,7 @@ void server_options(char **args, int *argc_p)
                        set++;
                else
                        set = iconv_opt;
-               if (asprintf(&arg, "--iconv=%s", set) < 0)
-                       goto oom;
-               args[ac++] = arg;
+               args[ac++] = safe_arg("--iconv", set);
        }
 #endif
 
@@ -2697,33 +2763,24 @@ void server_options(char **args, int *argc_p)
        }
 
        if (backup_dir) {
+               /* This split idiom allows for ~/path expansion via the shell. */
                args[ac++] = "--backup-dir";
-               args[ac++] = backup_dir;
+               args[ac++] = safe_arg("", backup_dir);
        }
 
        /* Only send --suffix if it specifies a non-default value. */
-       if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
-               /* We use the following syntax to avoid weirdness with '~'. */
-               if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
-                       goto oom;
-               args[ac++] = arg;
-       }
+       if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0)
+               args[ac++] = safe_arg("--suffix", backup_suffix);
 
-       if (checksum_choice) {
-               if (asprintf(&arg, "--checksum-choice=%s", checksum_choice) < 0)
-                       goto oom;
-               args[ac++] = arg;
-       }
+       if (checksum_choice)
+               args[ac++] = safe_arg("--checksum-choice", checksum_choice);
 
        if (do_compression == CPRES_ZLIBX)
                args[ac++] = "--new-compress";
        else if (compress_choice && do_compression == CPRES_ZLIB)
                args[ac++] = "--old-compress";
-       else if (compress_choice) {
-               if (asprintf(&arg, "--compress-choice=%s", compress_choice) < 0)
-                       goto oom;
-               args[ac++] = arg;
-       }
+       else if (compress_choice)
+               args[ac++] = safe_arg("--compress-choice", compress_choice);
 
        if (am_sender) {
                if (max_delete > 0) {
@@ -2732,14 +2789,10 @@ void server_options(char **args, int *argc_p)
                        args[ac++] = arg;
                } else if (max_delete == 0)
                        args[ac++] = "--max-delete=-1";
-               if (min_size >= 0) {
-                       args[ac++] = "--min-size";
-                       args[ac++] = min_size_arg;
-               }
-               if (max_size >= 0) {
-                       args[ac++] = "--max-size";
-                       args[ac++] = max_size_arg;
-               }
+               if (min_size >= 0)
+                       args[ac++] = safe_arg("--min-size", min_size_arg);
+               if (max_size >= 0)
+                       args[ac++] = safe_arg("--max-size", max_size_arg);
                if (delete_before)
                        args[ac++] = "--delete-before";
                else if (delete_during == 2)
@@ -2763,17 +2816,12 @@ void server_options(char **args, int *argc_p)
                if (do_stats)
                        args[ac++] = "--stats";
        } else {
-               if (skip_compress) {
-                       if (asprintf(&arg, "--skip-compress=%s", skip_compress) < 0)
-                               goto oom;
-                       args[ac++] = arg;
-               }
+               if (skip_compress)
+                       args[ac++] = safe_arg("--skip-compress", skip_compress);
        }
 
-       if (max_alloc_arg && max_alloc != DEFAULT_MAX_ALLOC) {
-               args[ac++] = "--max-alloc";
-               args[ac++] = max_alloc_arg;
-       }
+       if (max_alloc_arg && max_alloc != DEFAULT_MAX_ALLOC)
+               args[ac++] = safe_arg("--max-alloc", max_alloc_arg);
 
        /* --delete-missing-args needs the cooperation of both sides, but
         * the sender can handle --ignore-missing-args by itself. */
@@ -2798,7 +2846,7 @@ void server_options(char **args, int *argc_p)
        if (partial_dir && am_sender) {
                if (partial_dir != tmp_partialdir) {
                        args[ac++] = "--partial-dir";
-                       args[ac++] = partial_dir;
+                       args[ac++] = safe_arg("", partial_dir);
                }
                if (delay_updates)
                        args[ac++] = "--delay-updates";
@@ -2821,17 +2869,11 @@ void server_options(char **args, int *argc_p)
                args[ac++] = "--use-qsort";
 
        if (am_sender) {
-               if (usermap) {
-                       if (asprintf(&arg, "--usermap=%s", usermap) < 0)
-                               goto oom;
-                       args[ac++] = arg;
-               }
+               if (usermap)
+                       args[ac++] = safe_arg("--usermap", usermap);
 
-               if (groupmap) {
-                       if (asprintf(&arg, "--groupmap=%s", groupmap) < 0)
-                               goto oom;
-                       args[ac++] = arg;
-               }
+               if (groupmap)
+                       args[ac++] = safe_arg("--groupmap", groupmap);
 
                if (ignore_existing)
                        args[ac++] = "--ignore-existing";
@@ -2842,9 +2884,12 @@ void server_options(char **args, int *argc_p)
 
                if (tmpdir) {
                        args[ac++] = "--temp-dir";
-                       args[ac++] = tmpdir;
+                       args[ac++] = safe_arg("", tmpdir);
                }
 
+               if (do_fsync)
+                       args[ac++] = "--fsync";
+
                if (basis_dir[0]) {
                        /* the server only needs this option if it is not the sender,
                         *   and it may be an older version that doesn't know this
@@ -2852,7 +2897,7 @@ void server_options(char **args, int *argc_p)
                         */
                        for (i = 0; i < basis_dir_cnt; i++) {
                                args[ac++] = alt_dest_opt(0);
-                               args[ac++] = basis_dir[i];
+                               args[ac++] = safe_arg("", basis_dir[i]);
                        }
                }
        }
@@ -2867,13 +2912,17 @@ void server_options(char **args, int *argc_p)
                if (append_mode > 1)
                        args[ac++] = "--append";
                args[ac++] = "--append";
-       } else if (inplace)
+       } else if (inplace) {
                args[ac++] = "--inplace";
+               /* Work around a bug in older rsync versions (on the remote side) for --inplace --sparse */
+               if (sparse_files && !whole_file && am_sender)
+                       args[ac++] = "--no-W";
+       }
 
        if (files_from && (!am_sender || filesfrom_host)) {
                if (filesfrom_host) {
                        args[ac++] = "--files-from";
-                       args[ac++] = files_from;
+                       args[ac++] = safe_arg("", files_from);
                        if (eol_nulls)
                                args[ac++] = "--from0";
                } else {
@@ -2895,6 +2944,9 @@ void server_options(char **args, int *argc_p)
        else if (remove_source_files)
                args[ac++] = "--remove-sent-files";
 
+       if (copy_devices && !am_sender)
+               args[ac++] = "--copy-devices";
+
        if (preallocate_files && am_sender)
                args[ac++] = "--preallocate";
 
@@ -2916,7 +2968,7 @@ void server_options(char **args, int *argc_p)
                        exit_cleanup(RERR_SYNTAX);
                }
                for (j = 1; j <= remote_option_cnt; j++)
-                       args[ac++] = (char*)remote_options[j];
+                       args[ac++] = safe_arg(SPLIT_ARG_WHEN_OLD, remote_options[j]);
        }
 
        *argc_p = ac;
@@ -2926,6 +2978,52 @@ void server_options(char **args, int *argc_p)
        out_of_memory("server_options");
 }
 
+int maybe_add_e_option(char *buf, int buf_len)
+{
+       int x = 0;
+
+       /* We don't really know the actual protocol_version at this point,
+        * but checking the pre-negotiated value allows the user to use a
+        * --protocol=29 override to avoid the use of this -eFLAGS opt. */
+       if (protocol_version >= 30 && buf_len > 0) {
+               /* We make use of the -e option to let the server know about
+                * any pre-release protocol version && some behavior flags. */
+               buf[x++] = 'e';
+
+#if SUBPROTOCOL_VERSION != 0
+               if (protocol_version == PROTOCOL_VERSION)
+                       x += snprintf(buf + x, buf_len - x, "%d.%d", PROTOCOL_VERSION, SUBPROTOCOL_VERSION);
+               else
+#endif
+                       buf[x++] = '.';
+               if (allow_inc_recurse)
+                       buf[x++] = 'i';
+#ifdef CAN_SET_SYMLINK_TIMES
+               buf[x++] = 'L'; /* symlink time-setting support */
+#endif
+#ifdef ICONV_OPTION
+               buf[x++] = 's'; /* symlink iconv translation support */
+#endif
+               buf[x++] = 'f'; /* flist I/O-error safety support */
+               buf[x++] = 'x'; /* xattr hardlink optimization not desired */
+               buf[x++] = 'C'; /* support checksum seed order fix */
+               buf[x++] = 'I'; /* support inplace_partial behavior */
+               buf[x++] = 'v'; /* use varint for flist & compat flags; negotiate checksum */
+               buf[x++] = 'u'; /* include name of uid 0 & gid 0 in the id map */
+
+               /* NOTE: Avoid using 'V' -- it was represented with the high bit of a write_byte() that became a write_varint(). */
+       }
+
+       if (x >= buf_len) { /* Not possible... */
+               rprintf(FERROR, "overflow in add_e_flags().\n");
+               exit_cleanup(RERR_MALLOC);
+       }
+
+       buf[x] = '\0';
+
+       return x;
+}
+
 /* If str points to a valid hostspec, return allocated memory containing the
  * [USER@]HOST part of the string, and set the path_start_ptr to the part of
  * the string after the host part.  Otherwise, return NULL.  If port_ptr is
index 29d2d68..7f2e258 100644 (file)
@@ -1,6 +1,6 @@
 TARGETS := all install install-ssl-daemon install-all install-strip conf gen gensend reconfigure restatus \
        proto man clean cleantests distclean test check check29 check30 installcheck splint \
-       doxygen doxygen-upload finddead
+       doxygen doxygen-upload finddead rrsync
 
 .PHONY: $(TARGETS) auto-prep
 
diff --git a/packaging/cull-options b/packaging/cull-options
new file mode 100755 (executable)
index 0000000..e71818c
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/env python3
+# This script outputs either perl or python code that parses all possible options
+# that the code in options.c might send to the server.  The resulting code is then
+# included in the rrsync script.
+
+import re, argparse
+
+short_no_arg = { }
+short_with_num = { '@': 1 }
+long_opts = { # These include some extra long-args that BackupPC uses:
+        'block-size': 1,
+        'daemon': -1,
+        'debug': 1,
+        'fake-super': 0,
+        'fuzzy': 0,
+        'group': 0,
+        'hard-links': 0,
+        'ignore-times': 0,
+        'info': 1,
+        'links': 0,
+        'log-file': 3,
+        'munge-links': 0,
+        'no-munge-links': -1,
+        'one-file-system': 0,
+        'owner': 0,
+        'perms': 0,
+        'recursive': 0,
+        'stderr': 1,
+        'times': 0,
+        'copy-devices': -1,
+        'write-devices': -1,
+        }
+
+def main():
+    last_long_opt = None
+
+    with open('../options.c') as fh:
+        for line in fh:
+            m = re.search(r"argstr\[x\+\+\] = '([^.ie])'", line)
+            if m:
+                short_no_arg[m.group(1)] = 1
+                last_long_opt = None
+                continue
+
+            m = re.search(r'asprintf\([^,]+, "-([a-zA-Z0-9])\%l?[ud]"', line)
+            if m:
+                short_with_num[m.group(1)] = 1
+                last_long_opt = None
+                continue
+
+            m = re.search(r'args\[ac\+\+\] = "--([^"=]+)"', line)
+            if m:
+                last_long_opt = m.group(1)
+                if last_long_opt not in long_opts:
+                    long_opts[last_long_opt] = 0
+                else:
+                    last_long_opt = None
+                continue
+
+            if last_long_opt:
+                m = re.search(r'args\[ac\+\+\] = safe_arg\("", ([^[("\s]+)\);', line)
+                if m:
+                    long_opts[last_long_opt] = 2
+                    last_long_opt = None
+                    continue
+                if 'args[ac++] = ' in line:
+                    last_long_opt = None
+
+            m = re.search(r'return "--([^"]+-dest)";', line)
+            if m:
+                long_opts[m.group(1)] = 2
+                last_long_opt = None
+                continue
+
+            m = re.search(r'asprintf\([^,]+, "--([^"=]+)=', line)
+            if not m:
+                m = re.search(r'args\[ac\+\+\] = "--([^"=]+)=', line)
+                if not m:
+                    m = re.search(r'args\[ac\+\+\] = safe_arg\("--([^"=]+)"', line)
+                    if not m:
+                        m = re.search(r'fmt = .*: "--([^"=]+)=', line)
+            if m:
+                long_opts[m.group(1)] = 1
+                last_long_opt = None
+
+    long_opts['files-from'] = 3
+
+    txt = """\
+### START of options data produced by the cull-options script. ###
+
+# To disable a short-named option, add its letter to this string:
+"""
+
+    txt += str_assign('short_disabled', 's') + "\n"
+    txt += '# These are also disabled when the restricted dir is not "/":\n'
+    txt += str_assign('short_disabled_subdir', 'KLk') + "\n"
+    txt += '# These are all possible short options that we will accept (when not disabled above):\n'
+    txt += str_assign('short_no_arg', ''.join(sorted(short_no_arg)), 'DO NOT REMOVE ANY')
+    txt += str_assign('short_with_num', ''.join(sorted(short_with_num)), 'DO NOT REMOVE ANY')
+   
+    txt += """
+# To disable a long-named option, change its value to a -1.  The values mean:
+# 0 = the option has no arg; 1 = the arg doesn't need any checking; 2 = only
+# check the arg when receiving; and 3 = always check the arg.
+"""
+
+    print(txt, end='')
+
+    if args.python:
+        print("long_opts = {")
+        sep = ':'
+    else:
+        print("our %long_opt = (")
+        sep = ' =>'
+
+    for opt in sorted(long_opts):
+        if opt.startswith(('min-', 'max-')):
+            val = 1
+        else:
+            val = long_opts[opt]
+        print(' ', repr(opt) + sep, str(val) + ',')
+
+    if args.python:
+        print("}")
+    else:
+        print(");")
+    print("\n### END of options data produced by the cull-options script. ###")
+
+
+def str_assign(name, val, comment=None):
+    comment = ' # ' + comment if comment else ''
+    if args.python:
+        return name + ' = ' + repr(val) + comment + "\n"
+    return 'our $' + name + ' = ' + repr(val) + ';' + comment + "\n"
+
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description="Output culled rsync options for rrsync.", add_help=False)
+    out_group = parser.add_mutually_exclusive_group()
+    out_group.add_argument('--perl', action='store_true', help="Output perl code.")
+    out_group.add_argument('--python', action='store_true', help="Output python code (the default).")
+    parser.add_argument('--help', '-h', action='help', help="Output this help message and exit.")
+    args = parser.parse_args()
+    if not args.perl:
+        args.python = True
+    main()
+
+# vim: sw=4 et
diff --git a/packaging/cull_options b/packaging/cull_options
deleted file mode 100755 (executable)
index 7588002..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env perl
-# This script outputs some perl code that parses all possible options
-# that the code in options.c might send to the server.  This perl code
-# is included in the rrsync script.
-use strict;
-
-our %short_no_arg;
-our %short_with_num = ( '@' => 1 );
-our %long_opt = ( # These include some extra long-args that BackupPC uses:
-    'block-size' => 1,
-    'daemon' => -1,
-    'debug' => 1,
-    'fake-super' => 0,
-    'fuzzy' => 0,
-    'group' => 0,
-    'hard-links' => 0,
-    'ignore-times' => 0,
-    'info' => 1,
-    'links' => 0,
-    'log-file' => 3,
-    'one-file-system' => 0,
-    'owner' => 0,
-    'perms' => 0,
-    'recursive' => 0,
-    'times' => 0,
-    'write-devices' => -1,
-);
-our $last_long_opt;
-
-open(IN, '../options.c') or die "Unable to open ../options.c: $!\n";
-
-while (<IN>) {
-    if (/\Qargstr[x++]\E = '([^.ie])'/) {
-       $short_no_arg{$1} = 1;
-       undef $last_long_opt;
-    } elsif (/\Qasprintf(\E[^,]+, "-([a-zA-Z0-9])\%l?[ud]"/) {
-       $short_with_num{$1} = 1;
-       undef $last_long_opt;
-    } elsif (/\Qargs[ac++]\E = "--([^"=]+)"/) {
-       $last_long_opt = $1;
-       $long_opt{$1} = 0 unless exists $long_opt{$1};
-    } elsif (defined($last_long_opt)
-       && /\Qargs[ac++]\E = ([^["\s]+);/) {
-       $long_opt{$last_long_opt} = 2;
-       undef $last_long_opt;
-    } elsif (/return "--([^"]+-dest)";/) {
-       $long_opt{$1} = 2;
-       undef $last_long_opt;
-    } elsif (/\Qasprintf(\E[^,]+, "--([^"=]+)=/ || /\Qargs[ac++]\E = "--([^"=]+)=/ || /fmt = .*: "--([^"=]+)=/) {
-       $long_opt{$1} = 1;
-       undef $last_long_opt;
-    }
-}
-close IN;
-
-my $short_no_arg = join('', sort keys %short_no_arg);
-my $short_with_num = join('', sort keys %short_with_num);
-
-print <<EOT;
-
-# These options are the only options that rsync might send to the server,
-# and only in the option format that the stock rsync produces.
-
-# To disable a short-named option, add its letter to this string:
-our \$short_disabled = 's';
-
-our \$short_no_arg = '$short_no_arg'; # DO NOT REMOVE ANY
-our \$short_with_num = '$short_with_num'; # DO NOT REMOVE ANY
-
-# To disable a long-named option, change its value to a -1.  The values mean:
-# 0 = the option has no arg; 1 = the arg doesn't need any checking; 2 = only
-# check the arg when receiving; and 3 = always check the arg.
-our \%long_opt = (
-EOT
-
-foreach my $opt (sort keys %long_opt) {
-    my $val = $long_opt{$opt};
-    $val = 1 if $opt =~ /^(max-|min-)/;
-    $val = 3 if $opt eq 'files-from';
-    $val = q"$only eq 'r' ? -1 : " . $val if $opt =~ /^(remove-|log-file)/;
-    $val = q"$only eq 'w' ? -1 : " . $val if $opt eq 'sender';
-    print "  '$opt' => $val,\n";
-}
-
-print ");\n\n";
index 04163c7..f2d7aa4 100644 (file)
@@ -1,6 +1,6 @@
 Summary: A fast, versatile, remote (and local) file-copying tool
 Name: rsync
-Version: 3.2.3
+Version: 3.2.7
 %define fullversion %{version}
 Release: 1
 %define srcdir src
@@ -79,8 +79,8 @@ rm -rf $RPM_BUILD_ROOT
 %dir /etc/rsync-ssl/certs
 
 %changelog
-* Thu Aug 06 2020 Wayne Davison <wayne@opencoder.net>
-Released 3.2.3.
+* Thu Oct 20 2022 Wayne Davison <wayne@opencoder.net>
+Released 3.2.7.
 
 * Fri Mar 21 2008 Wayne Davison <wayne@opencoder.net>
 Added installation of /etc/xinetd.d/rsync file and some commented-out
diff --git a/packaging/md2html b/packaging/md2html
deleted file mode 100755 (executable)
index 21e42c6..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2020 Wayne Davison
-#
-# This program is freely redistributable.
-
-import os, re, argparse
-
-HTML_START = """\
-<html><head>
-<title>%s</title>
-<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap" rel="stylesheet">
-<style>
-body {
-  max-width: 50em;
-  margin: auto;
-}
-body, b, strong, u {
-  font-family: 'Roboto', sans-serif;
-}
-code {
-  font-family: 'Roboto Mono', monospace;
-  font-weight: bold;
-}
-pre code {
-  display: block;
-  font-weight: normal;
-}
-blockquote pre code {
-  background: #f1f1f1;
-}
-dd p:first-of-type {
-  margin-block-start: 0em;
-}
-table {
-  border-color: grey;
-  border-spacing: 0;
-}
-tr {
-  border-top: 1px solid grey;
-}
-tr:nth-child(2n) {
-  background-color: #f6f8fa;
-}
-th, td {
-  border: 1px solid #dfe2e5;
-  text-align: center;
-  padding-left: 1em;
-  padding-right: 1em;
-}
-</style>
-</head><body>
-"""
-
-HTML_END = """\
-</body></html>
-"""
-
-md_parser = None
-
-def main():
-    for mdfn in args.mdfiles:
-        if not mdfn.endswith('.md'):
-            print('Ignoring non-md input file:', mdfn)
-            continue
-        title = re.sub(r'.*/', '', mdfn).replace('.md', '')
-        htfn = mdfn.replace('.md', '.html')
-
-        print("Parsing", mdfn, '->', htfn)
-
-        with open(mdfn, 'r', encoding='utf-8') as fh:
-            txt = fh.read()
-
-        txt = re.sub(r'\s--\s', '\xa0-- ', txt)
-
-        html = md_parser(txt)
-
-        html = re.sub(r'(?<!<pre>)(<code>)([\s\S]*?)(</code>)', lambda m: m[1] + re.sub(r'\s', '\xa0', m[2]) + m[3], html)
-        html = html.replace('--', '&#8209;&#8209;').replace("\xa0-", '&nbsp;&#8209;').replace("\xa0", '&nbsp;')
-        html = re.sub(r'(\W)-', r'\1&#8209;', html)
-
-        if os.path.lexists(htfn):
-            os.unlink(htfn)
-
-        with open(htfn, 'w', encoding='utf-8') as fh:
-            fh.write(HTML_START % title)
-            fh.write(html)
-            fh.write(HTML_END)
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description='Output html for md pages.', add_help=False)
-    parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
-    parser.add_argument("mdfiles", nargs='+', help="The .md files to turn into .html files.")
-    args = parser.parse_args()
-
-    try:
-        import cmarkgfm
-        # Our NEWS.md file has a gfm table in it.
-        md_parser = cmarkgfm.github_flavored_markdown_to_html
-    except:
-        die("Failed to find cmarkgfm for python3.")
-
-    main()
diff --git a/packaging/openssl-rsync.cnf b/packaging/openssl-rsync.cnf
new file mode 100644 (file)
index 0000000..7432285
--- /dev/null
@@ -0,0 +1,18 @@
+# This config file can be used with rsync to enable legacy digests
+# (such as MD4) by using the OPENSSL_CONF environment variable.
+# See rsync's configure --with-openssl-conf=/path/name option.
+
+openssl_conf = openssl_init
+
+[openssl_init]
+providers = provider_sect
+
+[provider_sect]
+default = default_sect
+legacy = legacy_sect
+
+[default_sect]
+activate = 1
+
+[legacy_sect]
+activate = 1
index b3fb527..fd56a9d 100755 (executable)
@@ -33,7 +33,7 @@ def main():
 
     master_commit = latest_git_hash(args.base_branch)
 
-    if cmd_txt_chk(['packaging/prep-auto-dir']) == '':
+    if cmd_txt_chk(['packaging/prep-auto-dir']).out == '':
         die('You must setup an auto-build-save dir to use this script.')
 
     if args.gen:
index b201bf7..c4c5741 100644 (file)
@@ -1,4 +1,4 @@
-import os, sys, re, subprocess
+import os, sys, re, subprocess, argparse
 
 # This python3 library provides a few helpful routines that are
 # used by the latest packaging scripts.
@@ -23,27 +23,32 @@ def set_default_encoding(enc):
 
 
 # Set shell=True if the cmd is a string; sets a default encoding unless raw=True was specified.
-def _tweak_opts(cmd, opts, **maybe_set):
-    # This sets any maybe_set value that isn't already set AND creates a copy of opts for us.
-    opts = {**maybe_set, **opts}
+def _tweak_opts(cmd, opts, **maybe_set_args):
+    def _maybe_set(o, **msa): # Only set a value if the user didn't already set it.
+        for var, val in msa.items():
+            if var not in o:
+                o[var] = val
 
-    if type(cmd) == str:
-        opts = {'shell': True, **opts}
+    opts = opts.copy()
+    _maybe_set(opts, **maybe_set_args)
+
+    if isinstance(cmd, str):
+        _maybe_set(opts, shell=True)
 
     want_raw = opts.pop('raw', False)
     if default_encoding and not want_raw:
-        opts = {'encoding': default_encoding, **opts}
+        _maybe_set(opts, encoding=default_encoding)
 
     capture = opts.pop('capture', None)
     if capture:
         if capture == 'stdout':
-            opts = {'stdout': subprocess.PIPE, **opts}
+            _maybe_set(opts, stdout=subprocess.PIPE)
         elif capture == 'stderr':
-            opts = {'stderr': subprocess.PIPE, **opts}
+            _maybe_set(opts, stderr=subprocess.PIPE)
         elif capture == 'output':
-            opts = {'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE, **opts}
+            _maybe_set(opts, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         elif capture == 'combined':
-            opts = {'stdout': subprocess.PIPE, 'stderr': subprocess.STDOUT, **opts}
+            _maybe_set(opts, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
 
     discard = opts.pop('discard', None)
     if discard:
@@ -66,30 +71,26 @@ def cmd_chk(cmd, **opts):
     return subprocess.run(cmd, **_tweak_opts(cmd, opts, check=True))
 
 
-# Capture stdout in a string and return the (output, return_code) tuple.
-# Use capture='combined' opt to get both stdout and stderr together.
-def cmd_txt_status(cmd, **opts):
+# Capture stdout in a string and return an object with out, err, and rc (return code).
+# It defaults to capture='stdout' (so err is empty) but can be overridden using
+# capture='combined' or capture='output' (the latter populates the err value).
+def cmd_txt(cmd, **opts):
     input = opts.pop('input', None)
     if input is not None:
         opts['stdin'] = subprocess.PIPE
     proc = subprocess.Popen(cmd, **_tweak_opts(cmd, opts, capture='stdout'))
-    out = proc.communicate(input=input)[0]
-    return (out, proc.returncode)
-
-
-# Like cmd_txt_status() but just return the output.
-def cmd_txt(cmd, **opts):
-    return cmd_txt_status(cmd, **opts)[0]
+    out, err = proc.communicate(input=input)
+    return argparse.Namespace(out=out, err=err, rc=proc.returncode)
 
 
-# Capture stdout in a string and return the output if the command has a 0 return code.
-# Otherwise it throws an exception that indicates the return code and the output.
+# Just like calling cmd_txt() except that it raises an error if the command has a non-0 return code.
+# The raised error includes the cmd, the return code, and the captured output.
 def cmd_txt_chk(cmd, **opts):
-    out, rc = cmd_txt_status(cmd, **opts)
-    if rc != 0:
-        cmd_err = f'Command "{cmd}" returned non-zero exit status "{rc}" and output:\n{out}'
+    ct = cmd_txt(cmd, **opts)
+    if ct.rc != 0:
+        cmd_err = f'Command "{cmd}" returned non-0 exit status "{ct.rc}" and output:\n{ct.out}{ct.err}'
         raise Exception(cmd_err)
-    return out
+    return ct
 
 
 # Starts a piped-output command of stdout (by default) and leaves it up to you to read
@@ -102,7 +103,7 @@ def cmd_pipe(cmd, **opts):
 # arg fatal_unless_clean can be used to make that non-fatal.  Returns a
 # tuple of the current branch, the is_clean flag, and the status text.
 def check_git_status(fatal_unless_clean=True, subdir='.'):
-    status_txt = cmd_txt_chk(f"cd '{subdir}' && git status")
+    status_txt = cmd_txt_chk(f"cd '{subdir}' && git status").out
     is_clean = re.search(r'\nnothing to commit.+working (directory|tree) clean', status_txt) != None
 
     if not is_clean and fatal_unless_clean:
@@ -149,7 +150,7 @@ def check_git_state(master_branch, fatal_unless_clean=True, check_extra_dir=None
 
 # Return the git hash of the most recent commit.
 def latest_git_hash(branch):
-    out = cmd_txt_chk(['git', 'log', '-1', '--no-color', branch])
+    out = cmd_txt_chk(['git', 'log', '-1', '--no-color', branch]).out
     m = re.search(r'^commit (\S+)', out, flags=re.M)
     if not m:
         die(f"Unable to determine commit hash for master branch: {branch}")
@@ -175,20 +176,20 @@ def mandate_gensend_hook():
         print('Creating hook file:', hook)
         cmd_chk(['./rsync', '-a', 'packaging/pre-push', hook])
     else:
-        out, rc = cmd_txt_status(['fgrep', 'make gensend', hook], discard='output')
-        if rc:
+        ct = cmd_txt(['grep', 'make gensend', hook], discard='output')
+        if ct.rc:
             die('Please add a "make gensend" into your', hook, 'script.')
 
 
-# Snag the GENFILES values out of the Makefile.in file and return them as a list.
+# Snag the GENFILES values out of the Makefile file and return them as a list.
 def get_gen_files(want_dir_plus_list=False):
     cont_re = re.compile(r'\\\n')
 
     gen_files = [ ]
 
-    auto_dir = os.path.join('auto-build-save', cmd_txt('git rev-parse --abbrev-ref HEAD').strip().replace('/', '%'))
+    auto_dir = os.path.join('auto-build-save', cmd_txt('git rev-parse --abbrev-ref HEAD').out.strip().replace('/', '%'))
 
-    with open('Makefile.in', 'r', encoding='utf-8') as fh:
+    with open(auto_dir + '/Makefile', 'r', encoding='utf-8') as fh:
         for line in fh:
             if not gen_files:
                 chk = re.sub(r'^GENFILES=', '', line)
index 04b0d20..8a71369 100755 (executable)
@@ -1,3 +1,16 @@
-#!/bin/sh
+#!/bin/bash -e
+
 cat >/dev/null # Just discard stdin data
-make gensend
+
+if [[ -f /proc/$PPID/cmdline ]]; then
+    while read -d $'\0' arg ; do
+       if [[ "$arg" == '--tags' ]] ; then
+           exit 0
+       fi
+    done </proc/$PPID/cmdline
+fi
+
+branch=`git rev-parse --abbrev-ref HEAD`
+if [[ "$branch" = master && "$*" == *github* ]]; then
+    make gensend
+fi
index 1e5a296..b67f390 100755 (executable)
@@ -13,7 +13,7 @@
 # run "make distclean" before creating the auto-build-save dir.
 
 auto_top='auto-build-save'
-if test -d $auto_top -a -d .git; then
+if test -d $auto_top && test -d .git; then
     desired_branch=`git rev-parse --abbrev-ref HEAD | tr / %`
     if test "$desired_branch" = HEAD; then
        echo "ERROR: switch to the right build dir manually when in detached HEAD mode." 1>&2
index a8d63ec..511e90f 100755 (executable)
@@ -18,6 +18,9 @@ dest = os.environ['HOME'] + '/samba-rsync-ftp'
 ORIGINAL_PATH = os.environ['PATH']
 
 def main():
+    if not os.path.isfile('packaging/release-rsync'):
+        die('You must run this script from the top of your rsync checkout.')
+
     now = datetime.now()
     cl_today = now.strftime('* %a %b %d %Y')
     year = now.strftime('%Y')
@@ -30,7 +33,7 @@ def main():
 
     signal.signal(signal.SIGINT, signal_handler)
 
-    if cmd_txt_chk(['packaging/prep-auto-dir']) == '':
+    if cmd_txt_chk(['packaging/prep-auto-dir']).out == '':
         die('You must setup an auto-build-save dir to use this script.');
 
     auto_dir, gen_files = get_gen_files(True)
@@ -44,6 +47,17 @@ def main():
 {dash_line}
 """)
 
+    with open('build/rsync.1') as fh:
+        for line in fh:
+            if line.startswith(r'.\" prefix='):
+                doc_prefix = line.split('=')[1].strip()
+                if doc_prefix != '/usr':
+                    warn(f"*** The documentation was built with prefix {doc_prefix} instead of /usr ***")
+                    die("*** Read the md2man script for a way to override this. ***")
+                break
+            if line.startswith('.P'):
+                die("Failed to find the prefix comment at the start of the rsync.1 manpage.")
+
     if not os.path.isdir(dest):
         die(dest, "dest does not exist")
     if not os.path.isdir('.git'):
@@ -84,13 +98,15 @@ def main():
     if os.path.lexists(rsync_ver):
         die(f'"{rsync_ver}" must not exist in the current directory.')
 
-    out = cmd_txt_chk(['git', 'tag', '-l', v_ver])
+    out = cmd_txt_chk(['git', 'tag', '-l', v_ver]).out
     if out != '':
         print(f"Tag {v_ver} already exists.")
         ans = input("\nDelete tag or quit? [Q/del] ")
         if not re.match(r'^del', ans, flags=re.I):
             die("Aborted")
         cmd_chk(['git', 'tag', '-d', v_ver])
+        if os.path.isdir('patches/.git'):
+            cmd_chk(f"cd patches && git tag -d '{v_ver}'")
 
     version = re.sub(r'[-.]*pre[-.]*', 'pre', version)
     if 'pre' in version and not curversion.endswith('dev'):
@@ -179,7 +195,9 @@ About to:
         with open(fn, 'r', encoding='utf-8') as fh:
             old_txt = txt = fh.read()
         if fn == 'version.h':
-            txt = f'#define RSYNC_VERSION "{version}"\n'
+            x_re = re.compile(r'^(#define RSYNC_VERSION).*', re.M)
+            msg = f"Unable to update RSYNC_VERSION in {fn}"
+            txt = replace_or_die(x_re, r'\1 "%s"' % version, txt, msg)
         elif '.spec' in fn:
             for var, val in specvars.items():
                 x_re = re.compile(r'^%s .*' % re.escape(var), re.M)
@@ -192,10 +210,10 @@ About to:
             txt = replace_or_die(x_re, repl, txt, f"Unable to find SUBPROTOCOL_VERSION define in {fn}")
         elif fn == 'NEWS.md':
             efv = re.escape(finalversion)
-            x_re = re.compile(r'^<.+>\s+# NEWS for rsync %s \(UNRELEASED\)\s+## Changes in this version:\n' % efv
+            x_re = re.compile(r'^# NEWS for rsync %s \(UNRELEASED\)\s+## Changes in this version:\n' % efv
                     + r'(\n### PROTOCOL NUMBER:\s+- The protocol number was changed to \d+\.\n)?')
             rel_day = 'UNRELEASED' if pre else today
-            repl = (f'<a name="{finalversion}"></a>\n\n# NEWS for rsync {finalversion} ({rel_day})\n\n'
+            repl = (f'# NEWS for rsync {finalversion} ({rel_day})\n\n'
                 + '## Changes in this version:\n')
             if proto_changed:
                 repl += f'\n### PROTOCOL NUMBER:\n\n - The protocol number was changed to {protocol_version}.\n'
@@ -216,7 +234,7 @@ About to:
     cmd_chk(['packaging/year-tweak'])
 
     print(dash_line)
-    cmd_run("git diff --color | less -p '^diff .*'")
+    cmd_run("git diff".split())
 
     srctar_name = f"{rsync_ver}.tar.gz"
     pattar_name = f"rsync-patches-{version}.tar.gz"
@@ -231,20 +249,20 @@ About to:
 
 About to:
     - git commit all changes
-    - generate the manpages
+    - run a full build, ensuring that the manpages & configure.sh are up-to-date
     - merge the {args.master_branch} branch into the patch/{args.master_branch}/* branches
     - update the files in the "patches" dir and OPTIONALLY (if you type 'y') to
       run patch-update with the --make option (which opens a shell on error)
 """)
     ans = input("<Press Enter OR 'y' to continue> ")
 
-    s = cmd_run(['git', 'commit', '-a', '-m', f'Preparing for release of {version}'])
+    s = cmd_run(['git', 'commit', '-a', '-m', f'Preparing for release of {version} [buildall]'])
     if s.returncode:
         die('Aborting')
 
-    cmd_chk('make gen')
+    cmd_chk('touch configure.ac && packaging/smart-make && make gen')
 
-    print(f'Creating any missing patch branches.')
+    print('Creating any missing patch branches.')
     s = cmd_run(f'packaging/branch-from-patch --branch={args.master_branch} --add-missing')
     if s.returncode:
         die('Aborting')
@@ -282,13 +300,13 @@ About to:
     # TODO: is there a better way to ensure that our passphrase is in the agent?
     cmd_run("touch TeMp; gpg --sign TeMp; rm TeMp*")
 
-    out = cmd_txt(f"git tag -s -m 'Version {version}.' {v_ver}", capture='combined')
+    out = cmd_txt(f"git tag -s -m 'Version {version}.' {v_ver}", capture='combined').out
     print(out, end='')
     if 'bad passphrase' in out or 'failed' in out:
         die('Aborting')
 
     if os.path.isdir('patches/.git'):
-        out = cmd_txt(f"cd patches && git tag -s -m 'Version {version}.' {v_ver}", capture='combined')
+        out = cmd_txt(f"cd patches && git tag -s -m 'Version {version}.' {v_ver}", capture='combined').out
         print(out, end='')
         if 'bad passphrase' in out or 'failed' in out:
             die('Aborting')
@@ -327,7 +345,7 @@ About to:
     md_files = 'README.md NEWS.md INSTALL.md'.split()
     html_files = [ fn for fn in gen_pathnames if fn.endswith('.html') ]
     cmd_chk(['rsync', '-a', *md_files, *html_files, dest])
-    cmd_chk(["packaging/md2html"] + [ dest +'/'+ fn for fn in md_files ])
+    cmd_chk(["./md-convert", "--dest", dest, *md_files])
 
     cmd_chk(f"git log --name-status | gzip -9 >{dest}/ChangeLog.gz")
 
index 6f634d6..3826432 100755 (executable)
@@ -4,8 +4,6 @@ set -e
 
 export LANG=C
 
-make=`which gmake 2>/dev/null` || make=`which make 2>/dev/null`
-
 branch=`packaging/prep-auto-dir`
 if test x"$branch" = x; then
     srcdir=.
@@ -40,8 +38,8 @@ fi
 
 ./config.status
 
-$make all
+make all
 
 if test x"$1" = x"check"; then
-    $make check
+    make check
 fi
index 8a0b582..8a867ca 100644 (file)
@@ -7,6 +7,7 @@ Documentation=man:rsync(1) man:rsyncd.conf(5)
 [Service]
 ExecStart=/usr/bin/rsync --daemon --no-detach
 RestartSec=1
+Restart=on-failure
 
 # Citing README.md:
 #
index fe7491d..f17c69a 100755 (executable)
@@ -4,7 +4,7 @@
 # for vars that are defined but not used, and for inconsistent array
 # sizes.  Run it from inside the main rsync directory.
 
-import re, argparse, glob
+import os, sys, re, argparse, glob
 
 VARS_RE = re.compile(r'^(?!(?:extern|enum)\s)([a-zA-Z]\S*\s+.*);', re.M)
 EXTERNS_RE = re.compile(r'^extern\s+(.*);', re.M)
@@ -15,8 +15,15 @@ def main():
     add_syscall_c = set('t_stub.c t_unsafe.c tls.c trimslash.c'.split())
     add_util_c = set('t_stub.c t_unsafe.c'.split())
 
+    if not os.path.exists('syscall.c'):
+        if os.path.exists('var-checker'):
+            os.chdir('..')
+        else:
+            print("Couldn't find the source dir.")
+            sys.exit(1)
+
     syscall_c = slurp_file('syscall.c', True)
-    util_c = slurp_file('util.c', True)
+    util_c = slurp_file('util1.c', True)
 
     for fn in sorted(glob.glob('*.c')):
         txt = slurp_file(fn)
index f5b7b46..a4e78e6 100755 (executable)
@@ -6,7 +6,7 @@
 #
 #   build     build the config files [the default w/no arg]
 #   fetch     fetch the latest dev autoconfig files
-#   fetchgen  fetch all the latest dev generated files (including man pages)
+#   fetchgen  fetch all the latest dev generated files (including manpages)
 #   fetchSRC  fetch the latest dev source files [NON-GENERATED FILES]
 #
 # The script stops after the first successful action.
@@ -32,7 +32,7 @@ if test "$dir" != '.'; then
        fi
     done
     for fn in configure.sh config.h.in aclocal.m4; do
-       test ! -f $fn -a -f "$dir/$fn" && cp -p "$dir/$fn" $fn
+       test ! -f $fn && test -f "$dir/$fn" && cp -p "$dir/$fn" $fn
     done
 fi
 
index 8da5286..87207fb 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -115,13 +115,13 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now, int is_l
                units = "kB/s";
        }
 
-       if (remain < 0)
+       if (remain < 0 || remain > 9999.0 * 3600.0)
                strlcpy(rembuf, "  ??:??:??", sizeof rembuf);
        else {
-               snprintf(rembuf, sizeof rembuf, "%4d:%02d:%02d",
-                        (int) (remain / 3600.0),
-                        (int) (remain / 60.0) % 60,
-                        (int) remain % 60);
+               snprintf(rembuf, sizeof rembuf, "%4u:%02u:%02u",
+                        (unsigned int) (remain / 3600.0),
+                        (unsigned int) (remain / 60.0) % 60,
+                        (unsigned int) remain % 60);
        }
 
        output_needs_newline = 0;
index 9df603f..c9d7e01 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996-2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -41,6 +41,7 @@ extern int preserve_hard_links;
 extern int preserve_perms;
 extern int write_devices;
 extern int preserve_xattrs;
+extern int do_fsync;
 extern int basis_dir_cnt;
 extern int make_backups;
 extern int cleanup_got_literal;
@@ -55,7 +56,6 @@ extern int inplace;
 extern int inplace_partial;
 extern int allowed_lull;
 extern int delay_updates;
-extern int xfersum_type;
 extern BOOL want_progress_now;
 extern mode_t orig_umask;
 extern struct stats stats;
@@ -67,6 +67,9 @@ extern struct file_list *cur_flist, *first_flist, *dir_flist;
 extern filter_rule_list daemon_filter_list;
 extern OFF_T preallocated_len;
 
+extern struct name_num_item *xfer_sum_nni;
+extern int xfer_sum_len;
+
 static struct bitbag *delayed_bits = NULL;
 static int phase = 0, redoing = 0;
 static flist_ndx_list batch_redo_list;
@@ -239,7 +242,6 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
        static char file_sum1[MAX_DIGEST_LEN];
        struct map_struct *mapbuf;
        struct sum_struct sum;
-       int sum_len;
        int32 len;
        OFF_T total_size = F_LENGTH(file);
        OFF_T offset = 0;
@@ -279,7 +281,7 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
        } else
                mapbuf = NULL;
 
-       sum_init(xfersum_type, checksum_seed);
+       sum_init(xfer_sum_nni, checksum_seed);
 
        if (append_mode > 0) {
                OFF_T j;
@@ -392,15 +394,20 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
        if (INFO_GTE(PROGRESS, 1))
                end_progress(total_size);
 
-       sum_len = sum_end(file_sum1);
+       sum_end(file_sum1);
+
+       if (do_fsync && fd != -1 && fsync(fd) != 0) {
+               rsyserr(FERROR, errno, "fsync failed on %s", full_fname(fname));
+               exit_cleanup(RERR_FILEIO);
+       }
 
        if (mapbuf)
                unmap_file(mapbuf);
 
-       read_buf(f_in, sender_file_sum, sum_len);
+       read_buf(f_in, sender_file_sum, xfer_sum_len);
        if (DEBUG_GTE(DELTASUM, 2))
                rprintf(FINFO,"got file_sum\n");
-       if (fd != -1 && memcmp(file_sum1, sender_file_sum, sum_len) != 0)
+       if (fd != -1 && memcmp(file_sum1, sender_file_sum, xfer_sum_len) != 0)
                return 0;
        return 1;
 }
@@ -433,9 +440,8 @@ static void handle_delayed_updates(char *local_name)
                                        "rename failed for %s (from %s)",
                                        full_fname(fname), partialptr);
                        } else {
-                               if (remove_source_files
-                                || (preserve_hard_links && F_IS_HLINKED(file)))
-                                       send_msg_int(MSG_SUCCESS, ndx);
+                               if (remove_source_files || (preserve_hard_links && F_IS_HLINKED(file)))
+                                       send_msg_success(fname, ndx);
                                handle_partial_dir(partialptr, PDIR_DELETE);
                        }
                }
@@ -539,6 +545,9 @@ int recv_files(int f_in, int f_out, char *local_name)
        if (delay_updates)
                delayed_bits = bitbag_create(cur_flist->used + 1);
 
+       if (whole_file < 0)
+               whole_file = 0;
+
        progress_init();
 
        while (1) {
@@ -584,10 +593,13 @@ int recv_files(int f_in, int f_out, char *local_name)
                if (DEBUG_GTE(RECV, 1))
                        rprintf(FINFO, "recv_files(%s)\n", fname);
 
-               if (daemon_filter_list.head && (*fname != '.' || fname[1] != '\0')
-                && check_filter(&daemon_filter_list, FLOG, fname, 0) < 0) {
-                       rprintf(FERROR, "attempt to hack rsync failed.\n");
-                       exit_cleanup(RERR_PROTOCOL);
+               if (daemon_filter_list.head && (*fname != '.' || fname[1] != '\0')) {
+                       int filt_flags = S_ISDIR(file->mode) ? NAME_IS_DIR : NAME_IS_FILE;
+                       if (check_filter(&daemon_filter_list, FLOG, fname, filt_flags) < 0) {
+                               rprintf(FERROR, "ERROR: rejecting file transfer request for daemon excluded file: %s\n",
+                                       fname);
+                               exit_cleanup(RERR_PROTOCOL);
+                       }
                }
 
 #ifdef SUPPORT_XATTRS
@@ -686,7 +698,7 @@ int recv_files(int f_in, int f_out, char *local_name)
                        if (!am_server)
                                discard_receive_data(f_in, file);
                        if (inc_recurse)
-                               send_msg_int(MSG_SUCCESS, ndx);
+                               send_msg_success(fname, ndx);
                        continue;
                }
 
@@ -799,14 +811,16 @@ int recv_files(int f_in, int f_out, char *local_name)
                        continue;
                }
 
-               if (fd1 != -1 && !(S_ISREG(st.st_mode) || (write_devices && IS_DEVICE(st.st_mode)))) {
+               if (write_devices && IS_DEVICE(st.st_mode)) {
+                       if (fd1 != -1 && st.st_size == 0)
+                               st.st_size = get_device_size(fd1, fname);
+                       /* Mark the file entry as a device so that we don't try to truncate it later on. */
+                       file->mode = S_IFBLK | (file->mode & ACCESSPERMS);
+               } else if (fd1 != -1 && !(S_ISREG(st.st_mode))) {
                        close(fd1);
                        fd1 = -1;
                }
 
-               if (fd1 != -1 && IS_DEVICE(st.st_mode) && st.st_size == 0)
-                       st.st_size = get_device_size(fd1, fname);
-
                /* If we're not preserving permissions, change the file-list's
                 * mode based on the local permissions and some heuristics. */
                if (!preserve_perms) {
@@ -826,6 +840,12 @@ int recv_files(int f_in, int f_out, char *local_name)
                if (inplace || one_inplace)  {
                        fnametmp = one_inplace ? partialptr : fname;
                        fd2 = do_open(fnametmp, O_WRONLY|O_CREAT, 0600);
+#ifdef linux
+                       if (fd2 == -1 && errno == EACCES) {
+                               /* Maybe the error was due to protected_regular setting? */
+                               fd2 = do_open(fname, O_WRONLY, 0600);
+                       }
+#endif
                        if (fd2 == -1) {
                                rsyserr(FERROR_XFER, errno, "open %s failed",
                                        full_fname(fnametmp));
@@ -878,7 +898,7 @@ int recv_files(int f_in, int f_out, char *local_name)
                                        do_unlink(partialptr);
                                handle_partial_dir(partialptr, PDIR_DELETE);
                        }
-               } else if (keep_partial && partialptr && !one_inplace) {
+               } else if (keep_partial && partialptr && (!one_inplace || delay_updates)) {
                        if (!handle_partial_dir(partialptr, PDIR_CREATE)) {
                                rprintf(FERROR,
                                        "Unable to create partial-dir for %s -- discarding %s.\n",
@@ -906,13 +926,12 @@ int recv_files(int f_in, int f_out, char *local_name)
                case 2:
                        break;
                case 1:
-                       if (remove_source_files || inc_recurse
-                        || (preserve_hard_links && F_IS_HLINKED(file)))
-                               send_msg_int(MSG_SUCCESS, ndx);
+                       if (remove_source_files || inc_recurse || (preserve_hard_links && F_IS_HLINKED(file)))
+                               send_msg_success(fname, ndx);
                        break;
                case 0: {
                        enum logcode msgtype = redoing ? FERROR_XFER : FWARNING;
-                       if (msgtype == FERROR_XFER || INFO_GTE(NAME, 1)) {
+                       if (msgtype == FERROR_XFER || INFO_GTE(NAME, 1) || stdout_format_has_i) {
                                char *errstr, *redostr, *keptstr;
                                if (!(keep_partial && partialptr) && !inplace)
                                        keptstr = "discarded";
diff --git a/rrsync.1 b/rrsync.1
new file mode 100644 (file)
index 0000000..74f9d34
--- /dev/null
+++ b/rrsync.1
@@ -0,0 +1,166 @@
+.TH "rrsync" "1" "20 Oct 2022" "rrsync from rsync 3.2.7" "User Commands"
+.\" prefix=/usr
+.P
+.SH "NAME"
+.P
+rrsync \- a script to setup restricted rsync users via ssh logins
+.P
+.SH "SYNOPSIS"
+.P
+.nf
+rrsync [-ro|-rw] [-munge] [-no-del] [-no-lock] DIR
+.fi
+.P
+The single non-option argument specifies the restricted \fIDIR\fP to use. It can be
+relative to the user's home directory or an absolute path.
+.P
+The online version of this manpage (that includes cross-linking of topics)
+is available at https://download.samba.org/pub/rsync/rrsync.1.
+.P
+.SH "DESCRIPTION"
+.P
+A user's ssh login can be restricted to only allow the running of an rsync
+transfer in one of two easy ways:
+.P
+.IP o
+forcing the running of the rrsync script
+.IP o
+forcing the running of an rsync daemon-over-ssh command.
+.P
+Both of these setups use a feature of ssh that allows a command to be forced to
+run instead of an interactive shell.  However, if the user's home shell is bash,
+please see BASH SECURITY ISSUE for a potential issue.
+.P
+To use the rrsync script, edit the user's \fB~/.ssh/authorized_keys\fP file and add
+a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:
+.RS 4
+.P
+.nf
+command="rrsync DIR"
+command="rrsync -ro DIR"
+command="rrsync -munge -no-del DIR"
+.fi
+.RE
+.P
+Then, ensure that the rrsync script has your desired option restrictions. You
+may want to copy the script to a local bin dir with a unique name if you want
+to have multiple configurations. One or more rrsync options can be specified
+prior to the \fIDIR\fP if you want to further restrict the transfer.
+.P
+To use an rsync daemon setup, edit the user's \fB~/.ssh/authorized_keys\fP file and
+add a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:
+.RS 4
+.P
+.nf
+command="rsync --server --daemon ."
+command="rsync --server --daemon --config=/PATH/TO/rsyncd.conf ."
+.fi
+.RE
+.P
+Then, ensure that the rsyncd.conf file is created with one or more module names
+with the appropriate path and option restrictions.  If rsync's
+\fB\-\-config\fP option is omitted, it defaults to \fB~/rsyncd.conf\fP.
+See the \fBrsyncd.conf\fP(5) manpage for details of how to
+configure an rsync daemon.
+.P
+When using rrsync, there can be just one restricted dir per authorized key.  A
+daemon setup, on the other hand, allows multiple module names inside the config
+file, each one with its own path setting.
+.P
+The remainder of this manpage is dedicated to using the rrsync script.
+.P
+.SH "OPTIONS"
+.P
+.IP "\fB\-ro\fP"
+Allow only reading from the DIR. Implies \fB\-no-del\fP and
+\fB\-no-lock\fP.
+.IP "\fB\-wo\fP"
+Allow only writing to the DIR.
+.IP "\fB\-munge\fP"
+Enable rsync's \fB\-\-munge-links\fP on the server side.
+.IP "\fB\-no-del\fP"
+Disable rsync's \fB\-\-delete*\fP and \fB\-\-remove*\fP options.
+.IP "\fB\-no-lock\fP"
+Avoid the single-run (per-user) lock check.  Useful with \fB\-munge\fP.
+.IP "\fB\-help\fP, \fB\-h\fP"
+Output this help message and exit.
+.P
+.SH "SECURITY RESTRICTIONS"
+.P
+The rrsync script validates the path arguments it is sent to try to restrict
+them to staying within the specified DIR.
+.P
+The rrsync script rejects rsync's \fB\-\-copy-links\fP option (by
+default) so that a copy cannot dereference a symlink within the DIR to get to a
+file outside the DIR.
+.P
+The rrsync script rejects rsync's \fB\-\-protect-args\fP (\fB\-s\fP) option
+because it would allow options to be sent to the server-side that the script
+cannot check.  If you want to support \fB\-\-protect-args\fP, use a daemon-over-ssh
+setup.
+.P
+The rrsync script accepts just a subset of rsync's options that the real rsync
+uses when running the server command.  A few extra convenience options are also
+included to help it to interact with BackupPC and accept some convenient user
+overrides.
+.P
+The script (or a copy of it) can be manually edited if you want it to customize
+the option handling.
+.P
+.SH "BASH SECURITY ISSUE"
+.P
+If your users have bash set as their home shell, bash may try to be overly
+helpful and ensure that the user's login bashrc files are run prior to
+executing the forced command.  This can be a problem if the user can somehow
+update their home bashrc files, perhaps via the restricted copy, a shared home
+directory, or something similar.
+.P
+One simple way to avoid the issue is to switch the user to a simpler shell,
+such as dash.  When choosing the new home shell, make sure that you're not
+choosing bash in disguise, as it is unclear if it avoids the security issue.
+.P
+Another potential fix is to ensure that the user's home directory is not a
+shared mount and that they have no means of copying files outside of their
+restricted directories.  This may require you to force the enabling of symlink
+munging on the server side.
+.P
+A future version of openssh may have a change to the handling of forced
+commands that allows it to avoid using the user's home shell.
+.P
+.SH "EXAMPLES"
+.P
+The \fB~/.ssh/authorized_keys\fP file might have lines in it like this:
+.RS 4
+.P
+.nf
+command="rrsync client/logs" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAzG...
+command="rrsync -ro results" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAmk...
+.fi
+.RE
+.P
+.SH "FILES"
+.P
+~/.ssh/authorized_keys
+.P
+.SH "SEE ALSO"
+.P
+\fBrsync\fP(1), \fBrsyncd.conf\fP(5)
+.P
+.SH "VERSION"
+.P
+This manpage is current for version 3.2.7 of rsync.
+.P
+.SH "CREDITS"
+.P
+rsync is distributed under the GNU General Public License.  See the file
+COPYING for details.
+.P
+An rsync web site is available at https://rsync.samba.org/ and its github
+project is https://github.com/WayneD/rsync.
+.P
+.SH "AUTHOR"
+.P
+The original rrsync perl script was written by Joe Smith.  Many people have
+later contributed to it.  The python version was created by Wayne Davison.
diff --git a/rrsync.1.html b/rrsync.1.html
new file mode 100644 (file)
index 0000000..d0f88ee
--- /dev/null
@@ -0,0 +1,164 @@
+<html><head>
+<title>rrsync(1) manpage</title>
+<meta charset="UTF-8"/>
+<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap" rel="stylesheet">
+<style>
+body {
+  max-width: 50em;
+  margin: auto;
+}
+body, b, strong, u {
+  font-family: 'Roboto', sans-serif;
+}
+a.tgt { font-face: symbol; font-weight: 400; font-size: 70%; visibility: hidden; text-decoration: none; color: #ddd; padding: 0 4px; border: 0; }
+a.tgt:after { content: '🔗'; }
+a.tgt:hover { color: #444; background-color: #eaeaea; }
+h1:hover > a.tgt, h2:hover > a.tgt, h3:hover > a.tgt, dt:hover > a.tgt { visibility: visible; }
+code {
+  font-family: 'Roboto Mono', monospace;
+  font-weight: bold;
+  white-space: pre;
+}
+pre code {
+  display: block;
+  font-weight: normal;
+}
+blockquote pre code {
+  background: #f1f1f1;
+}
+dd p:first-of-type {
+  margin-block-start: 0em;
+}
+</style>
+</head><body>
+<h2 id="NAME">NAME<a href="#NAME" class="tgt"></a></h2>
+<p>rrsync -&#8288; a script to setup restricted rsync users via ssh logins</p>
+<h2 id="SYNOPSIS">SYNOPSIS<a href="#SYNOPSIS" class="tgt"></a></h2>
+<pre><code>rrsync [-ro|-rw] [-munge] [-no-del] [-no-lock] DIR
+</code></pre>
+<p>The single non-option argument specifies the restricted <u>DIR</u> to use. It can be
+relative to the user's home directory or an absolute path.</p>
+<p>The online version of this manpage (that includes cross-linking of topics)
+is available at <a href="https://download.samba.org/pub/rsync/rrsync.1">https://download.samba.org/pub/rsync/rrsync.1</a>.</p>
+<h2 id="DESCRIPTION">DESCRIPTION<a href="#DESCRIPTION" class="tgt"></a></h2>
+<p>A user's ssh login can be restricted to only allow the running of an rsync
+transfer in one of two easy ways:</p>
+<ul>
+<li>forcing the running of the rrsync script</li>
+<li>forcing the running of an rsync daemon-over-ssh command.</li>
+</ul>
+<p>Both of these setups use a feature of ssh that allows a command to be forced to
+run instead of an interactive shell.  However, if the user's home shell is bash,
+please see <a href="#BASH_SECURITY_ISSUE">BASH SECURITY ISSUE</a> for a potential issue.</p>
+<p>To use the rrsync script, edit the user's <code>~/.ssh/authorized_keys</code> file and add
+a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:</p>
+<blockquote>
+<pre><code>command=&quot;rrsync DIR&quot;
+command=&quot;rrsync -ro DIR&quot;
+command=&quot;rrsync -munge -no-del DIR&quot;
+</code></pre>
+</blockquote>
+<p>Then, ensure that the rrsync script has your desired option restrictions. You
+may want to copy the script to a local bin dir with a unique name if you want
+to have multiple configurations. One or more rrsync options can be specified
+prior to the <u>DIR</u> if you want to further restrict the transfer.</p>
+<p>To use an rsync daemon setup, edit the user's <code>~/.ssh/authorized_keys</code> file and
+add a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:</p>
+<blockquote>
+<pre><code>command=&quot;rsync --server --daemon .&quot;
+command=&quot;rsync --server --daemon --config=/PATH/TO/rsyncd.conf .&quot;
+</code></pre>
+</blockquote>
+<p>Then, ensure that the rsyncd.conf file is created with one or more module names
+with the appropriate path and option restrictions.  If rsync's
+<a href="rsync.1#dopt--config"><code>--config</code></a> option is omitted, it defaults to <code>~/rsyncd.conf</code>.
+See the <a href="rsyncd.conf.5"><strong>rsyncd.conf</strong>(5)</a> manpage for details of how to
+configure an rsync daemon.</p>
+<p>When using rrsync, there can be just one restricted dir per authorized key.  A
+daemon setup, on the other hand, allows multiple module names inside the config
+file, each one with its own path setting.</p>
+<p>The remainder of this manpage is dedicated to using the rrsync script.</p>
+<h2 id="OPTIONS">OPTIONS<a href="#OPTIONS" class="tgt"></a></h2>
+<dl>
+
+<dt id="opt-ro"><code>-ro</code><a href="#opt-ro" class="tgt"></a></dt><dd>
+<p>Allow only reading from the DIR. Implies <a href="#opt-no-del"><code>-no-del</code></a> and
+<a href="#opt-no-lock"><code>-no-lock</code></a>.</p>
+</dd>
+
+<dt id="opt-wo"><code>-wo</code><a href="#opt-wo" class="tgt"></a></dt><dd>
+<p>Allow only writing to the DIR.</p>
+</dd>
+
+<dt id="opt-munge"><code>-munge</code><a href="#opt-munge" class="tgt"></a></dt><dd>
+<p>Enable rsync's <a href="rsync.1#opt--munge-links"><code>--munge-links</code></a> on the server side.</p>
+</dd>
+
+<dt id="opt-no-del"><code>-no-del</code><a href="#opt-no-del" class="tgt"></a></dt><dd>
+<p>Disable rsync's <code>--delete*</code> and <code>--remove*</code> options.</p>
+</dd>
+
+<dt id="opt-no-lock"><code>-no-lock</code><a href="#opt-no-lock" class="tgt"></a></dt><dd>
+<p>Avoid the single-run (per-user) lock check.  Useful with <a href="#opt-munge"><code>-munge</code></a>.</p>
+</dd>
+
+<span id="opt-h"></span><dt id="opt-help"><code>-help</code>, <code>-h</code><a href="#opt-help" class="tgt"></a></dt><dd>
+<p>Output this help message and exit.</p>
+</dd>
+</dl>
+<h2 id="SECURITY_RESTRICTIONS">SECURITY RESTRICTIONS<a href="#SECURITY_RESTRICTIONS" class="tgt"></a></h2>
+<p>The rrsync script validates the path arguments it is sent to try to restrict
+them to staying within the specified DIR.</p>
+<p>The rrsync script rejects rsync's <a href="rsync.1#opt--copy-links"><code>--copy-links</code></a> option (by
+default) so that a copy cannot dereference a symlink within the DIR to get to a
+file outside the DIR.</p>
+<p>The rrsync script rejects rsync's <a href="rsync.1#opt--protect-args"><code>--protect-args</code></a> (<code>-s</code>) option
+because it would allow options to be sent to the server-side that the script
+cannot check.  If you want to support <code>--protect-args</code>, use a daemon-over-ssh
+setup.</p>
+<p>The rrsync script accepts just a subset of rsync's options that the real rsync
+uses when running the server command.  A few extra convenience options are also
+included to help it to interact with BackupPC and accept some convenient user
+overrides.</p>
+<p>The script (or a copy of it) can be manually edited if you want it to customize
+the option handling.</p>
+<h2 id="BASH_SECURITY_ISSUE">BASH SECURITY ISSUE<a href="#BASH_SECURITY_ISSUE" class="tgt"></a></h2>
+<p>If your users have bash set as their home shell, bash may try to be overly
+helpful and ensure that the user's login bashrc files are run prior to
+executing the forced command.  This can be a problem if the user can somehow
+update their home bashrc files, perhaps via the restricted copy, a shared home
+directory, or something similar.</p>
+<p>One simple way to avoid the issue is to switch the user to a simpler shell,
+such as dash.  When choosing the new home shell, make sure that you're not
+choosing bash in disguise, as it is unclear if it avoids the security issue.</p>
+<p>Another potential fix is to ensure that the user's home directory is not a
+shared mount and that they have no means of copying files outside of their
+restricted directories.  This may require you to force the enabling of symlink
+munging on the server side.</p>
+<p>A future version of openssh may have a change to the handling of forced
+commands that allows it to avoid using the user's home shell.</p>
+<h2 id="EXAMPLES">EXAMPLES<a href="#EXAMPLES" class="tgt"></a></h2>
+<p>The <code>~/.ssh/authorized_keys</code> file might have lines in it like this:</p>
+<blockquote>
+<pre><code>command=&quot;rrsync client/logs&quot; ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAzG...
+command=&quot;rrsync -ro results&quot; ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAmk...
+</code></pre>
+</blockquote>
+<h2 id="FILES">FILES<a href="#FILES" class="tgt"></a></h2>
+<p>~/.ssh/authorized_keys</p>
+<h2 id="SEE_ALSO">SEE ALSO<a href="#SEE_ALSO" class="tgt"></a></h2>
+<p><a href="rsync.1"><strong>rsync</strong>(1)</a>, <a href="rsyncd.conf.5"><strong>rsyncd.conf</strong>(5)</a></p>
+<h2 id="VERSION">VERSION<a href="#VERSION" class="tgt"></a></h2>
+<p>This manpage is current for version 3.2.7 of rsync.</p>
+<h2 id="CREDITS">CREDITS<a href="#CREDITS" class="tgt"></a></h2>
+<p>rsync is distributed under the GNU General Public License.  See the file
+<a href="COPYING">COPYING</a> for details.</p>
+<p>An rsync web site is available at <a href="https://rsync.samba.org/">https://rsync.samba.org/</a> and its github
+project is <a href="https://github.com/WayneD/rsync">https://github.com/WayneD/rsync</a>.</p>
+<h2 id="AUTHOR">AUTHOR<a href="#AUTHOR" class="tgt"></a></h2>
+<p>The original rrsync perl script was written by Joe Smith.  Many people have
+later contributed to it.  The python version was created by Wayne Davison.</p>
+<div style="float: right"><p><i>20 Oct 2022</i></p></div>
+</body></html>
index 8101975..56ee7df 100755 (executable)
--- a/rsync-ssl
+++ b/rsync-ssl
@@ -73,8 +73,16 @@ function rsync_ssl_helper {
        certopt=""
        gnutls_cert_opt=""
     else
-       certopt="cert$optsep$RSYNC_SSL_CERT"
-       gnutls_cert_opt="--x509keyfile=$RSYNC_SSL_CERT"
+       certopt="-cert$optsep$RSYNC_SSL_CERT"
+       gnutls_cert_opt="--x509certfile=$RSYNC_SSL_CERT"
+    fi
+
+    if [[ -z "$RSYNC_SSL_KEY" ]]; then
+       keyopt=""
+       gnutls_key_opt=""
+    else
+       keyopt="-key$optsep$RSYNC_SSL_KEY"
+       gnutls_key_opt="--x509keyfile=$RSYNC_SSL_KEY"
     fi
 
     if [[ -z ${RSYNC_SSL_CA_CERT+x} ]]; then
@@ -129,9 +137,9 @@ function rsync_ssl_helper {
     fi
 
     if [[ $RSYNC_SSL_TYPE == openssl ]]; then
-       exec $RSYNC_SSL_OPENSSL s_client $caopt $certopt -quiet -verify_quiet -servername $hostname -connect $hostname:$port
+       exec $RSYNC_SSL_OPENSSL s_client $caopt $certopt $keyopt -quiet -verify_quiet -servername $hostname -verify_hostname $hostname -connect $hostname:$port
     elif [[ $RSYNC_SSL_TYPE == gnutls ]]; then
-       exec $RSYNC_SSL_GNUTLS --logfile=/dev/null $gnutls_cert_opt $gnutls_opts $hostname:$port
+       exec $RSYNC_SSL_GNUTLS --logfile=/dev/null $gnutls_cert_opt $gnutls_key_opt $gnutls_opts $hostname:$port
     else
        # devzero@web.de came up with this no-tmpfile calling syntax:
        exec $RSYNC_SSL_STUNNEL -fd 10 11<&0 <<EOF 10<&0 0<&11 11<&-
index aa92862..c7f5ad1 100644 (file)
@@ -1,4 +1,5 @@
-.TH "rsync-ssl" "1" "06 Aug 2020" "rsync-ssl 3.2.3" "User Commands"
+.TH "rsync-ssl" "1" "20 Oct 2022" "rsync-ssl from rsync 3.2.7" "User Commands"
+.\" prefix=/usr
 .P
 .SH "NAME"
 .P
@@ -10,6 +11,9 @@ rsync-ssl \- a helper script for connecting to an ssl rsync daemon
 rsync-ssl [--type=SSL_TYPE] RSYNC_ARGS
 .fi
 .P
+The online version of this manpage (that includes cross-linking of topics)
+is available at https://download.samba.org/pub/rsync/rsync-ssl.1.
+.P
 .SH "DESCRIPTION"
 .P
 The rsync-ssl script helps you to run an rsync copy to/from an rsync daemon
@@ -39,33 +43,34 @@ All the other options are passed through to the rsync command, so consult the
 The ssl helper scripts are affected by the following environment variables:
 .P
 .IP "\fBRSYNC_SSL_TYPE\fP"
-Specifies the program type that should be used to open the
-ssl connection.  It must be one of \fBopenssl\fP or \fBstunnel\fP.  The
-\fB\-\-type=SSL_TYPE\fP option overrides this, when specified.
+Specifies the program type that should be used to open the ssl connection.
+It must be one of \fBopenssl\fP or \fBstunnel\fP.  The \fB\-\-type=SSL_TYPE\fP option
+overrides this, when specified.
 .IP "\fBRSYNC_SSL_PORT\fP"
-If specified, the value is the port number that is used as
-the default when the user does not specify a port in their rsync command.
-When not specified, the default port number is 874.  (Note that older rsync
-versions (prior to 3.2.0) did not communicate an overriding port number
-value to the helper script.)
+If specified, the value is the port number that is used as the default when
+the user does not specify a port in their rsync command.  When not
+specified, the default port number is 874.  (Note that older rsync versions
+(prior to 3.2.0) did not communicate an overriding port number value to the
+helper script.)
 .IP "\fBRSYNC_SSL_CERT\fP"
-If specified, the value is a filename that contains a
+If specified, the value is a filename that contains a certificate to use
+for the connection.
+.IP "\fBRSYNC_SSL_KEY\fP"
+If specified, the value is a filename that contains a key for the provided
 certificate to use for the connection.
 .IP "\fBRSYNC_SSL_CA_CERT\fP"
-If specified, the value is a filename that contains a
-certificate authority certificate that is used to validate the connection.
+If specified, the value is a filename that contains a certificate authority
+certificate that is used to validate the connection.
 .IP "\fBRSYNC_SSL_OPENSSL\fP"
-Specifies the openssl executable to run when the
-connection type is set to openssl.  If unspecified, the $PATH is searched
-for "openssl".
+Specifies the openssl executable to run when the connection type is set to
+openssl.  If unspecified, the $PATH is searched for "openssl".
 .IP "\fBRSYNC_SSL_GNUTLS\fP"
-Specifies the gnutls-cli executable to run when the
-connection type is set to gnutls.  If unspecified, the $PATH is searched
-for "gnutls-cli".
+Specifies the gnutls-cli executable to run when the connection type is set
+to gnutls.  If unspecified, the $PATH is searched for "gnutls-cli".
 .IP "\fBRSYNC_SSL_STUNNEL\fP"
-Specifies the stunnel executable to run when the
-connection type is set to stunnel.  If unspecified, the $PATH is searched
-first for "stunnel4" and then for "stunnel".
+Specifies the stunnel executable to run when the connection type is set to
+stunnel.  If unspecified, the $PATH is searched first for "stunnel4" and
+then for "stunnel".
 .P
 .SH "EXAMPLES"
 .RS 4
@@ -93,6 +98,11 @@ rsync-ssl -aiv rsync://example.com:9874/mod/ dest
 .fi
 .RE
 .P
+.SH "THE SERVER SIDE"
+.P
+For help setting up an SSL/TLS supporting rsync, see the instructions in
+rsyncd.conf.
+.P
 .SH "SEE ALSO"
 .P
 \fBrsync\fP(1), \fBrsyncd.conf\fP(5)
@@ -116,11 +126,11 @@ Please report bugs! See the web site at https://rsync.samba.org/.
 .P
 .SH "VERSION"
 .P
-This man page is current for version 3.2.3 of rsync.
+This manpage is current for version 3.2.7 of rsync.
 .P
 .SH "CREDITS"
 .P
-rsync is distributed under the GNU General Public License.  See the file
+Rsync is distributed under the GNU General Public License.  See the file
 COPYING for details.
 .P
 A web site is available at https://rsync.samba.org/.  The site includes an
index e852bd0..682a7e9 100644 (file)
@@ -1,5 +1,6 @@
 <html><head>
-<title>rsync-ssl(1) man page</title>
+<title>rsync-ssl(1) manpage</title>
+<meta charset="UTF-8"/>
 <link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap" rel="stylesheet">
 <style>
 body {
@@ -9,6 +10,10 @@ body {
 body, b, strong, u {
   font-family: 'Roboto', sans-serif;
 }
+a.tgt { font-face: symbol; font-weight: 400; font-size: 70%; visibility: hidden; text-decoration: none; color: #ddd; padding: 0 4px; border: 0; }
+a.tgt:after { content: '🔗'; }
+a.tgt:hover { color: #444; background-color: #eaeaea; }
+h1:hover > a.tgt, h2:hover > a.tgt, h3:hover > a.tgt, dt:hover > a.tgt { visibility: visible; }
 code {
   font-family: 'Roboto Mono', monospace;
   font-weight: bold;
@@ -26,12 +31,14 @@ dd p:first-of-type {
 }
 </style>
 </head><body>
-<h1>NAME</h1>
+<h2 id="NAME">NAME<a href="#NAME" class="tgt"></a></h2>
 <p>rsync-ssl -&#8288; a helper script for connecting to an ssl rsync daemon</p>
-<h1>SYNOPSIS</h1>
+<h2 id="SYNOPSIS">SYNOPSIS<a href="#SYNOPSIS" class="tgt"></a></h2>
 <pre><code>rsync-ssl [--type=SSL_TYPE] RSYNC_ARGS
 </code></pre>
-<h1>DESCRIPTION</h1>
+<p>The online version of this manpage (that includes cross-linking of topics)
+is available at <a href="https://download.samba.org/pub/rsync/rsync-ssl.1">https://download.samba.org/pub/rsync/rsync-ssl.1</a>.</p>
+<h2 id="DESCRIPTION">DESCRIPTION<a href="#DESCRIPTION" class="tgt"></a></h2>
 <p>The rsync-ssl script helps you to run an rsync copy to/from an rsync daemon
 that requires ssl connections.</p>
 <p>The script requires that you specify an rsync-daemon arg in the style of either
@@ -40,7 +47,7 @@ connecting is 874 (one higher than the normal 873) unless overridden in the
 environment.  You can specify an overriding port via <code>--port</code> or by including
 it in the normal spot in the URL format, though both of those require your
 rsync version to be at least 3.2.0.</p>
-<h1>OPTIONS</h1>
+<h2 id="OPTIONS">OPTIONS<a href="#OPTIONS" class="tgt"></a></h2>
 <p>If the <strong>first</strong> arg is a <code>--type=SSL_TYPE</code> option, the script will only use
 that particular program to open an ssl connection instead of trying to find an
 openssl or stunnel executable via a simple heuristic (assuming that the
@@ -49,32 +56,56 @@ option must specify one of <code>openssl</code> or <code>stunnel</code>.  The eq
 required for this particular option.</p>
 <p>All the other options are passed through to the rsync command, so consult the
 <strong>rsync</strong>(1) manpage for more information on how it works.</p>
-<h1>ENVIRONMENT VARIABLES</h1>
+<h2 id="ENVIRONMENT_VARIABLES">ENVIRONMENT VARIABLES<a href="#ENVIRONMENT_VARIABLES" class="tgt"></a></h2>
 <p>The ssl helper scripts are affected by the following environment variables:</p>
 <dl>
-<dt><code>RSYNC_SSL_TYPE</code></dt><dd> Specifies the program type that should be used to open the
-ssl connection.  It must be one of <code>openssl</code> or <code>stunnel</code>.  The
-<code>--type=SSL_TYPE</code> option overrides this, when specified.</dd>
-<dt><code>RSYNC_SSL_PORT</code></dt><dd> If specified, the value is the port number that is used as
-the default when the user does not specify a port in their rsync command.
-When not specified, the default port number is 874.  (Note that older rsync
-versions (prior to 3.2.0) did not communicate an overriding port number
-value to the helper script.)</dd>
-<dt><code>RSYNC_SSL_CERT</code></dt><dd> If specified, the value is a filename that contains a
-certificate to use for the connection.</dd>
-<dt><code>RSYNC_SSL_CA_CERT</code></dt><dd> If specified, the value is a filename that contains a
-certificate authority certificate that is used to validate the connection.</dd>
-<dt><code>RSYNC_SSL_OPENSSL</code></dt><dd> Specifies the openssl executable to run when the
-connection type is set to openssl.  If unspecified, the $PATH is searched
-for &quot;openssl&quot;.</dd>
-<dt><code>RSYNC_SSL_GNUTLS</code></dt><dd> Specifies the gnutls-cli executable to run when the
-connection type is set to gnutls.  If unspecified, the $PATH is searched
-for &quot;gnutls-cli&quot;.</dd>
-<dt><code>RSYNC_SSL_STUNNEL</code></dt><dd> Specifies the stunnel executable to run when the
-connection type is set to stunnel.  If unspecified, the $PATH is searched
-first for &quot;stunnel4&quot; and then for &quot;stunnel&quot;.</dd>
+
+<dt id="RSYNC_SSL_TYPE"><code>RSYNC_SSL_TYPE</code><a href="#RSYNC_SSL_TYPE" class="tgt"></a></dt><dd>
+<p>Specifies the program type that should be used to open the ssl connection.
+It must be one of <code>openssl</code> or <code>stunnel</code>.  The <code>--type=SSL_TYPE</code> option
+overrides this, when specified.</p>
+</dd>
+
+<dt id="RSYNC_SSL_PORT"><code>RSYNC_SSL_PORT</code><a href="#RSYNC_SSL_PORT" class="tgt"></a></dt><dd>
+<p>If specified, the value is the port number that is used as the default when
+the user does not specify a port in their rsync command.  When not
+specified, the default port number is 874.  (Note that older rsync versions
+(prior to 3.2.0) did not communicate an overriding port number value to the
+helper script.)</p>
+</dd>
+
+<dt id="RSYNC_SSL_CERT"><code>RSYNC_SSL_CERT</code><a href="#RSYNC_SSL_CERT" class="tgt"></a></dt><dd>
+<p>If specified, the value is a filename that contains a certificate to use
+for the connection.</p>
+</dd>
+
+<dt id="RSYNC_SSL_KEY"><code>RSYNC_SSL_KEY</code><a href="#RSYNC_SSL_KEY" class="tgt"></a></dt><dd>
+<p>If specified, the value is a filename that contains a key for the provided
+certificate to use for the connection.</p>
+</dd>
+
+<dt id="RSYNC_SSL_CA_CERT"><code>RSYNC_SSL_CA_CERT</code><a href="#RSYNC_SSL_CA_CERT" class="tgt"></a></dt><dd>
+<p>If specified, the value is a filename that contains a certificate authority
+certificate that is used to validate the connection.</p>
+</dd>
+
+<dt id="RSYNC_SSL_OPENSSL"><code>RSYNC_SSL_OPENSSL</code><a href="#RSYNC_SSL_OPENSSL" class="tgt"></a></dt><dd>
+<p>Specifies the openssl executable to run when the connection type is set to
+openssl.  If unspecified, the $PATH is searched for &quot;openssl&quot;.</p>
+</dd>
+
+<dt id="RSYNC_SSL_GNUTLS"><code>RSYNC_SSL_GNUTLS</code><a href="#RSYNC_SSL_GNUTLS" class="tgt"></a></dt><dd>
+<p>Specifies the gnutls-cli executable to run when the connection type is set
+to gnutls.  If unspecified, the $PATH is searched for &quot;gnutls-cli&quot;.</p>
+</dd>
+
+<dt id="RSYNC_SSL_STUNNEL"><code>RSYNC_SSL_STUNNEL</code><a href="#RSYNC_SSL_STUNNEL" class="tgt"></a></dt><dd>
+<p>Specifies the stunnel executable to run when the connection type is set to
+stunnel.  If unspecified, the $PATH is searched first for &quot;stunnel4&quot; and
+then for &quot;stunnel&quot;.</p>
+</dd>
 </dl>
-<h1>EXAMPLES</h1>
+<h2 id="EXAMPLES">EXAMPLES<a href="#EXAMPLES" class="tgt"></a></h2>
 <blockquote>
 <pre><code>rsync-ssl -aiv example.com::mod/ dest
 </code></pre>
@@ -91,9 +122,12 @@ first for &quot;stunnel4&quot; and then for &quot;stunnel&quot;.</dd>
 <pre><code>rsync-ssl -aiv rsync://example.com:9874/mod/ dest
 </code></pre>
 </blockquote>
-<h1>SEE ALSO</h1>
-<p><strong>rsync</strong>(1), <strong>rsyncd.conf</strong>(5)</p>
-<h1>CAVEATS</h1>
+<h2 id="THE_SERVER_SIDE">THE SERVER SIDE<a href="#THE_SERVER_SIDE" class="tgt"></a></h2>
+<p>For help setting up an SSL/TLS supporting rsync, see the <a href="rsyncd.conf.5#SSL_TLS_Daemon_Setup">instructions in
+rsyncd.conf</a>.</p>
+<h2 id="SEE_ALSO">SEE ALSO<a href="#SEE_ALSO" class="tgt"></a></h2>
+<p><a href="rsync.1"><strong>rsync</strong>(1)</a>, <a href="rsyncd.conf.5"><strong>rsyncd.conf</strong>(5)</a></p>
+<h2 id="CAVEATS">CAVEATS<a href="#CAVEATS" class="tgt"></a></h2>
 <p>Note that using an stunnel connection requires at least version 4 of stunnel,
 which should be the case on modern systems.  Also, it does not verify a
 connection against the CA certificate collection, so it only encrypts the
@@ -103,18 +137,18 @@ certificate environment options.</p>
 release the gnutls-cli command was dropping output, making it unusable.  If
 that bug has been fixed in your version, feel free to put gnutls into an
 exported RSYNC_SSL_TYPE environment variable to make its use the default.</p>
-<h1>BUGS</h1>
+<h2 id="BUGS">BUGS<a href="#BUGS" class="tgt"></a></h2>
 <p>Please report bugs! See the web site at <a href="https://rsync.samba.org/">https://rsync.samba.org/</a>.</p>
-<h1>VERSION</h1>
-<p>This man page is current for version 3.2.3 of rsync.</p>
-<h1>CREDITS</h1>
-<p>rsync is distributed under the GNU General Public License.  See the file
-COPYING for details.</p>
+<h2 id="VERSION">VERSION<a href="#VERSION" class="tgt"></a></h2>
+<p>This manpage is current for version 3.2.7 of rsync.</p>
+<h2 id="CREDITS">CREDITS<a href="#CREDITS" class="tgt"></a></h2>
+<p>Rsync is distributed under the GNU General Public License.  See the file
+<a href="COPYING">COPYING</a> for details.</p>
 <p>A web site is available at <a href="https://rsync.samba.org/">https://rsync.samba.org/</a>.  The site includes an
 FAQ-O-Matic which may cover questions unanswered by this manual page.</p>
-<h1>AUTHOR</h1>
+<h2 id="AUTHOR">AUTHOR<a href="#AUTHOR" class="tgt"></a></h2>
 <p>This manpage was written by Wayne Davison.</p>
 <p>Mailing lists for support and development are available at
 <a href="https://lists.samba.org/">https://lists.samba.org/</a>.</p>
-<div style="float: right"><p><i>06 Aug 2020</i></p></div>
+<div style="float: right"><p><i>20 Oct 2022</i></p></div>
 </body></html>
index 3a01486..a6f1e3d 100644 (file)
@@ -1,14 +1,17 @@
-# NAME
+## NAME
 
 rsync-ssl - a helper script for connecting to an ssl rsync daemon
 
-# SYNOPSIS
+## SYNOPSIS
 
 ```
 rsync-ssl [--type=SSL_TYPE] RSYNC_ARGS
 ```
 
-# DESCRIPTION
+The online version of this manpage (that includes cross-linking of topics)
+is available at <https://download.samba.org/pub/rsync/rsync-ssl.1>.
+
+## DESCRIPTION
 
 The rsync-ssl script helps you to run an rsync copy to/from an rsync daemon
 that requires ssl connections.
@@ -20,7 +23,7 @@ environment.  You can specify an overriding port via `--port` or by including
 it in the normal spot in the URL format, though both of those require your
 rsync version to be at least 3.2.0.
 
-# OPTIONS
+## OPTIONS
 
 If the **first** arg is a `--type=SSL_TYPE` option, the script will only use
 that particular program to open an ssl connection instead of trying to find an
@@ -32,33 +35,56 @@ required for this particular option.
 All the other options are passed through to the rsync command, so consult the
 **rsync**(1) manpage for more information on how it works.
 
-# ENVIRONMENT VARIABLES
+## ENVIRONMENT VARIABLES
 
 The ssl helper scripts are affected by the following environment variables:
 
-0.  `RSYNC_SSL_TYPE` Specifies the program type that should be used to open the
-    ssl connection.  It must be one of `openssl` or `stunnel`.  The
-    `--type=SSL_TYPE` option overrides this, when specified.
-0.  `RSYNC_SSL_PORT` If specified, the value is the port number that is used as
-    the default when the user does not specify a port in their rsync command.
-    When not specified, the default port number is 874.  (Note that older rsync
-    versions (prior to 3.2.0) did not communicate an overriding port number
-    value to the helper script.)
-0.  `RSYNC_SSL_CERT` If specified, the value is a filename that contains a
+0.  `RSYNC_SSL_TYPE`
+
+    Specifies the program type that should be used to open the ssl connection.
+    It must be one of `openssl` or `stunnel`.  The `--type=SSL_TYPE` option
+    overrides this, when specified.
+
+0.  `RSYNC_SSL_PORT`
+
+    If specified, the value is the port number that is used as the default when
+    the user does not specify a port in their rsync command.  When not
+    specified, the default port number is 874.  (Note that older rsync versions
+    (prior to 3.2.0) did not communicate an overriding port number value to the
+    helper script.)
+
+0.  `RSYNC_SSL_CERT`
+
+    If specified, the value is a filename that contains a certificate to use
+    for the connection.
+
+0.  `RSYNC_SSL_KEY`
+
+    If specified, the value is a filename that contains a key for the provided
     certificate to use for the connection.
-0.  `RSYNC_SSL_CA_CERT` If specified, the value is a filename that contains a
-    certificate authority certificate that is used to validate the connection.
-0.  `RSYNC_SSL_OPENSSL` Specifies the openssl executable to run when the
-    connection type is set to openssl.  If unspecified, the $PATH is searched
-    for "openssl".
-0.  `RSYNC_SSL_GNUTLS` Specifies the gnutls-cli executable to run when the
-    connection type is set to gnutls.  If unspecified, the $PATH is searched
-    for "gnutls-cli".
-0.  `RSYNC_SSL_STUNNEL` Specifies the stunnel executable to run when the
-    connection type is set to stunnel.  If unspecified, the $PATH is searched
-    first for "stunnel4" and then for "stunnel".
-
-# EXAMPLES
+
+0.  `RSYNC_SSL_CA_CERT`
+
+    If specified, the value is a filename that contains a certificate authority
+    certificate that is used to validate the connection.
+
+0.  `RSYNC_SSL_OPENSSL`
+
+    Specifies the openssl executable to run when the connection type is set to
+    openssl.  If unspecified, the $PATH is searched for "openssl".
+
+0.  `RSYNC_SSL_GNUTLS`
+
+    Specifies the gnutls-cli executable to run when the connection type is set
+    to gnutls.  If unspecified, the $PATH is searched for "gnutls-cli".
+
+0.  `RSYNC_SSL_STUNNEL`
+
+    Specifies the stunnel executable to run when the connection type is set to
+    stunnel.  If unspecified, the $PATH is searched first for "stunnel4" and
+    then for "stunnel".
+
+## EXAMPLES
 
 >     rsync-ssl -aiv example.com::mod/ dest
 
@@ -68,11 +94,16 @@ The ssl helper scripts are affected by the following environment variables:
 
 >     rsync-ssl -aiv rsync://example.com:9874/mod/ dest
 
-# SEE ALSO
+## THE SERVER SIDE
+
+For help setting up an SSL/TLS supporting rsync, see the [instructions in
+rsyncd.conf](rsyncd.conf.5#SSL_TLS_Daemon_Setup).
+
+## SEE ALSO
 
-**rsync**(1), **rsyncd.conf**(5)
+[**rsync**(1)](rsync.1), [**rsyncd.conf**(5)](rsyncd.conf.5)
 
-# CAVEATS
+## CAVEATS
 
 Note that using an stunnel connection requires at least version 4 of stunnel,
 which should be the case on modern systems.  Also, it does not verify a
@@ -85,23 +116,23 @@ release the gnutls-cli command was dropping output, making it unusable.  If
 that bug has been fixed in your version, feel free to put gnutls into an
 exported RSYNC_SSL_TYPE environment variable to make its use the default.
 
-# BUGS
+## BUGS
 
 Please report bugs! See the web site at <https://rsync.samba.org/>.
 
-# VERSION
+## VERSION
 
-This man page is current for version @VERSION@ of rsync.
+This manpage is current for version @VERSION@ of rsync.
 
-# CREDITS
+## CREDITS
 
-rsync is distributed under the GNU General Public License.  See the file
-COPYING for details.
+Rsync is distributed under the GNU General Public License.  See the file
+[COPYING](COPYING) for details.
 
 A web site is available at <https://rsync.samba.org/>.  The site includes an
 FAQ-O-Matic which may cover questions unanswered by this manual page.
 
-# AUTHOR
+## AUTHOR
 
 This manpage was written by Wayne Davison.
 
diff --git a/rsync.1 b/rsync.1
index a7a3c41..66a2da3 100644 (file)
--- a/rsync.1
+++ b/rsync.1
@@ -1,4 +1,5 @@
-.TH "rsync" "1" "06 Aug 2020" "rsync 3.2.3" "User Commands"
+.TH "rsync" "1" "20 Oct 2022" "rsync 3.2.7" "User Commands"
+.\" prefix=/usr
 .P
 .SH "NAME"
 .P
@@ -28,6 +29,9 @@ Access via rsync daemon:
 Usages with just one SRC arg and no DEST arg will list the source files instead
 of copying.
 .P
+The online version of this manpage (that includes cross-linking of topics)
+is available at https://download.samba.org/pub/rsync/rsync.1.
+.P
 .SH "DESCRIPTION"
 .P
 Rsync is a fast and extraordinarily versatile file copying tool.  It can copy
@@ -74,9 +78,9 @@ rsync daemon directly via TCP.  The remote-shell transport is used whenever the
 source or destination path contains a single colon (:) separator after a host
 specification.  Contacting an rsync daemon directly happens when the source or
 destination path contains a double colon (::) separator after a host
-specification, OR when an rsync:// URL is specified (see also the "USING
-RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION" section for an exception
-to this latter rule).
+specification, OR when an rsync:// URL is specified (see also the USING
+RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION section for an
+exception to this latter rule).
 .P
 As a special case, if a single source arg is specified without a destination,
 the files are listed in an output format similar to "\fBls\ \-l\fP".
@@ -99,7 +103,7 @@ communications, but it may have been configured to use a different remote shell
 by default, such as rsh or remsh.
 .P
 You can also specify any remote shell you like, either by using the \fB\-e\fP
-command line option, or by setting the RSYNC_RSH environment variable.
+command line option, or by setting the \fBRSYNC_RSH\fP environment variable.
 .P
 Note that rsync must be installed on both the source and destination machines.
 .P
@@ -182,73 +186,203 @@ rsync somehost.mydomain.com::
 .fi
 .RE
 .P
-See the following section for more details.
+.SH "COPYING TO A DIFFERENT NAME"
 .P
-.SH "ADVANCED USAGE"
+When you want to copy a directory to a different name, use a trailing slash on
+the source directory to put the contents of the directory into any destination
+directory you like:
+.RS 4
 .P
-The syntax for requesting multiple files from a remote host is done by
-specifying additional remote-host args in the same style as the first, or with
-the hostname omitted.  For instance, all these work:
+.nf
+rsync -ai foo/ bar/
+.fi
+.RE
+.P
+Rsync also has the ability to customize a destination file's name when copying
+a single item.  The rules for this are:
+.P
+.IP o
+The transfer list must consist of a single item (either a file or an empty
+directory)
+.IP o
+The final element of the destination path must not exist as a directory
+.IP o
+The destination path must not have been specified with a trailing slash
+.P
+Under those circumstances, rsync will set the name of the destination's single
+item to the last element of the destination path.  Keep in mind that it is best
+to only use this idiom when copying a file and use the above trailing-slash
+idiom when copying a directory.
+.P
+The following example copies the \fBfoo.c\fP file as \fBbar.c\fP in the \fBsave\fP dir
+(assuming that \fBbar.c\fP isn't a directory):
+.RS 4
+.P
+.nf
+rsync -ai src/foo.c save/bar.c
+.fi
+.RE
+.P
+The single-item copy rule might accidentally bite you if you unknowingly copy a
+single item and specify a destination dir that doesn't exist (without using a
+trailing slash).  For example, if \fBsrc/*.c\fP matches one file and \fBsave/dir\fP
+doesn't exist, this will confuse you by naming the destination file \fBsave/dir\fP:
+.RS 4
+.P
+.nf
+rsync -ai src/*.c save/dir
+.fi
+.RE
+.P
+To prevent such an accident, either make sure the destination dir exists or
+specify the destination path with a trailing slash:
+.RS 4
+.P
+.nf
+rsync -ai src/*.c save/dir/
+.fi
+.RE
+.P
+.SH "SORTED TRANSFER ORDER"
+.P
+Rsync always sorts the specified filenames into its internal transfer list.
+This handles the merging together of the contents of identically named
+directories, makes it easy to remove duplicate filenames. It can, however,
+confuse someone when the files are transferred in a different order than what
+was given on the command-line.
+.P
+If you need a particular file to be transferred prior to another, either
+separate the files into different rsync calls, or consider using
+\fB\-\-delay-updates\fP (which doesn't affect the sorted transfer order, but
+does make the final file-updating phase happen much more rapidly).
+.P
+.SH "MULTI-HOST SECURITY"
+.P
+Rsync takes steps to ensure that the file requests that are shared in a
+transfer are protected against various security issues.  Most of the potential
+problems arise on the receiving side where rsync takes steps to ensure that the
+list of files being transferred remains within the bounds of what was
+requested.
+.P
+Toward this end, rsync 3.1.2 and later have aborted when a file list contains
+an absolute or relative path that tries to escape out of the top of the
+transfer.  Also, beginning with version 3.2.5, rsync does two more safety
+checks of the file list to (1) ensure that no extra source arguments were added
+into the transfer other than those that the client requested and (2) ensure
+that the file list obeys the exclude rules that were sent to the sender.
+.P
+For those that don't yet have a 3.2.5 client rsync (or those that want to be
+extra careful), it is safest to do a copy into a dedicated destination
+directory for the remote files when you don't trust the remote host.  For
+example, instead of doing an rsync copy into your home directory:
+.RS 4
+.P
+.nf
+rsync -aiv host1:dir1 ~
+.fi
+.RE
+.P
+Dedicate a "host1-files" dir to the remote content:
 .RS 4
 .P
 .nf
-rsync -av host:file1 :file2 host:file{3,4} /dest/
-rsync -av host::modname/file{1,2} host::modname/file3 /dest/
-rsync -av host::modname/file1 ::modname/file{3,4}
+rsync -aiv host1:dir1 ~/host1-files
 .fi
 .RE
 .P
-Older versions of rsync required using quoted spaces in the SRC, like these
-examples:
+See the \fB\-\-trust-sender\fP option for additional details.
+.P
+CAUTION: it is not particularly safe to use rsync to copy files from a
+case-preserving filesystem to a case-ignoring filesystem.  If you must perform
+such a copy, you should either disable symlinks via \fB\-\-no-links\fP or enable the
+munging of symlinks via \fB\-\-munge-links\fP (and make sure you use the
+right local or remote option).  This will prevent rsync from doing potentially
+dangerous things if a symlink name overlaps with a file or directory. It does
+not, however, ensure that you get a full copy of all the files (since that may
+not be possible when the names overlap). A potentially better solution is to
+list all the source files and create a safe list of filenames that you pass to
+the \fB\-\-files-from\fP option.  Any files that conflict in name would need
+to be copied to different destination directories using more than one copy.
+.P
+While a copy of a case-ignoring filesystem to a case-ignoring filesystem can
+work out fairly well, if no \fB\-\-delete-during\fP or \fB\-\-delete-before\fP option is
+active, rsync can potentially update an existing file on the receiveing side
+without noticing that the upper-/lower-case of the filename should be changed
+to match the sender.
+.P
+.SH "ADVANCED USAGE"
+.P
+The syntax for requesting multiple files from a remote host is done by
+specifying additional remote-host args in the same style as the first, or with
+the hostname omitted.  For instance, all these work:
 .RS 4
 .P
 .nf
-rsync -av host:'dir1/file1 dir2/file2' /dest
-rsync host::'modname/dir1/file1 modname/dir2/file2' /dest
+rsync -aiv host:file1 :file2 host:file{3,4} /dest/
+rsync -aiv host::modname/file{1,2} host::modname/extra /dest/
+rsync -aiv host::modname/first ::extra-file{1,2} /dest/
 .fi
 .RE
 .P
-This word-splitting still works (by default) in the latest rsync, but is not as
-easy to use as the first method.
+Note that a daemon connection only supports accessing one module per copy
+command, so if the start of a follow-up path doesn't begin with the
+modname of the first path, it is assumed to be a path in the module (such as
+the extra-file1 & extra-file2 that are grabbed above).
+.P
+Really old versions of rsync (2.6.9 and before) only allowed specifying one
+remote-source arg, so some people have instead relied on the remote-shell
+performing space splitting to break up an arg into multiple paths. Such
+unintuitive behavior is no longer supported by default (though you can request
+it, as described below).
 .P
-If you need to transfer a filename that contains whitespace, you can either
-specify the \fB\-\-protect-args\fP (\fB\-s\fP) option, or you'll need to escape the
-whitespace in a way that the remote shell will understand.  For instance:
+Starting in 3.2.4, filenames are passed to a remote shell in such a way as to
+preserve the characters you give it. Thus, if you ask for a file with spaces
+in the name, that's what the remote rsync looks for:
 .RS 4
 .P
 .nf
-rsync -av host:'file\\ name\\ with\\ spaces' /dest
+rsync -aiv host:'a simple file.pdf' /dest/
 .fi
 .RE
 .P
+If you use scripts that have been written to manually apply extra quoting to
+the remote rsync args (or to require remote arg splitting), you can ask rsync
+to let your script handle the extra escaping.  This is done by either adding
+the \fB\-\-old-args\fP option to the rsync runs in the script (which requires
+a new rsync) or exporting RSYNC_OLD_ARGS=1 and RSYNC_PROTECT_ARGS=0
+(which works with old or new rsync versions).
+.P
 .SH "CONNECTING TO AN RSYNC DAEMON"
 .P
 It is also possible to use rsync without a remote shell as the transport.  In
 this case you will directly connect to a remote rsync daemon, typically using
 TCP port 873. (This obviously requires the daemon to be running on the remote
-system, so refer to the STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS section
-below for information on that.)
+system, so refer to the STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS
+section below for information on that.)
 .P
 Using rsync in this way is the same as using it with a remote shell except
 that:
 .P
 .IP o
-you either use a double colon :: instead of a single colon to separate the
-hostname from the path, or you use an rsync:// URL.
+Use either double-colon syntax or rsync:// URL syntax instead of the
+single-colon (remote shell) syntax.
+.IP o
+The first element of the "path" is actually a module name.
 .IP o
-the first word of the "path" is actually a module name.
+Additional remote source args can use an abbreviated syntax that omits the
+hostname and/or the module name, as discussed in ADVANCED USAGE.
 .IP o
-the remote daemon may print a message of the day when you connect.
+The remote daemon may print a "message of the day" when you connect.
 .IP o
-if you specify no path name on the remote daemon then the list of accessible
-paths on the daemon will be shown.
+If you specify only the host (with no module or path) then a list of
+accessible modules on the daemon is output.
 .IP o
-if you specify no local destination then a listing of the specified files on
-the remote daemon is provided.
+If you specify a remote source path but no destination, a listing of the
+matching files on the remote daemon is output.
 .IP o
-you must not specify the \fB\-\-rsh\fP (\fB\-e\fP) option (since that overrides the
-daemon connection to use ssh\ \-\- see USING RSYNC-DAEMON FEATURES VIA A
-REMOTE-SHELL CONNECTION below).
+The \fB\-\-rsh\fP (\fB\-e\fP) option must be omitted to avoid changing the
+connection style from using a socket connection to USING RSYNC-DAEMON
+FEATURES VIA A REMOTE-SHELL CONNECTION.
 .P
 An example that copies all the files in a remote module named "src":
 .RS 4
@@ -260,22 +394,23 @@ rsync -av host::src /dest
 .P
 Some modules on the remote daemon may require authentication.  If so, you will
 receive a password prompt when you connect.  You can avoid the password prompt
-by setting the environment variable RSYNC_PASSWORD to the password you want to
-use or using the \fB\-\-password-file\fP option.  This may be useful when scripting
-rsync.
+by setting the environment variable \fBRSYNC_PASSWORD\fP to the password you
+want to use or using the \fB\-\-password-file\fP option.  This may be useful
+when scripting rsync.
 .P
 WARNING: On some systems environment variables are visible to all users.  On
 those systems using \fB\-\-password-file\fP is recommended.
 .P
 You may establish the connection via a web proxy by setting the environment
-variable RSYNC_PROXY to a hostname:port pair pointing to your web proxy.  Note
-that your web proxy's configuration must support proxy connections to port 873.
+variable \fBRSYNC_PROXY\fP to a hostname:port pair pointing to your web proxy.
+Note that your web proxy's configuration must support proxy connections to port
+873.
 .P
 You may also establish a daemon connection using a program as a proxy by
-setting the environment variable RSYNC_CONNECT_PROG to the commands you wish to
-run in place of making a direct socket connection.  The string may contain the
-escape "%H" to represent the hostname specified in the rsync command (so use
-"%%" if you need a single "%" in your string).  For example:
+setting the environment variable \fBRSYNC_CONNECT_PROG\fP to the commands you
+wish to run in place of making a direct socket connection.  The string may
+contain the escape "%H" to represent the hostname specified in the rsync
+command (so use "%%" if you need a single "%" in your string).  For example:
 .RS 4
 .P
 .nf
@@ -288,9 +423,9 @@ rsync -av rsync://targethost2/module/src/ /dest/
 The command specified above uses ssh to run nc (netcat) on a proxyhost, which
 forwards all data to port 873 (the rsync daemon) on the targethost (%H).
 .P
-Note also that if the RSYNC_SHELL environment variable is set, that program
-will be used to run the RSYNC_CONNECT_PROG command instead of using the default
-shell of the \fBsystem()\fP call.
+Note also that if the \fBRSYNC_SHELL\fP environment variable is set, that
+program will be used to run the \fBRSYNC_CONNECT_PROG\fP command instead of using
+the default shell of the \fBsystem()\fP call.
 .P
 .SH "USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION"
 .P
@@ -333,78 +468,48 @@ rsync -av -e "ssh -l ssh-user" rsync-user@host::module /dest
 The "ssh-user" will be used at the ssh level; the "rsync-user" will be used to
 log-in to the "module".
 .P
+In this setup, the daemon is started by the ssh command that is accessing the
+system (which can be forced via the \fB~/.ssh/authorized_keys\fP file, if desired).
+However, when accessing a daemon directly, it needs to be started beforehand.
+.P
 .SH "STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS"
 .P
 In order to connect to an rsync daemon, the remote system needs to have a
 daemon already running (or it needs to have configured something like inetd to
 spawn an rsync daemon for incoming connections on a particular port).  For full
 information on how to start a daemon that will handling incoming socket
-connections, see the \fBrsyncd.conf\fP(5) man page\ \-\- that is the config file for
-the daemon, and it contains the full details for how to run the daemon
-(including stand-alone and inetd configurations).
+connections, see the \fBrsyncd.conf\fP(5) manpage\ \-\- that is
+the config file for the daemon, and it contains the full details for how to run
+the daemon (including stand-alone and inetd configurations).
 .P
 If you're using one of the remote-shell transports for the transfer, there is
 no need to manually start an rsync daemon.
 .P
-.SH "SORTED TRANSFER ORDER"
-.P
-Rsync always sorts the specified filenames into its internal transfer list.
-This handles the merging together of the contents of identically named
-directories, makes it easy to remove duplicate filenames, and may confuse
-someone when the files are transferred in a different order than what was given
-on the command-line.
-.P
-If you need a particular file to be transferred prior to another, either
-separate the files into different rsync calls, or consider using
-\fB\-\-delay-updates\fP (which doesn't affect the sorted transfer order, but does
-make the final file-updating phase happen much more rapidly).
-.P
 .SH "EXAMPLES"
 .P
-Here are some examples of how I use rsync.
+Here are some examples of how rsync can be used.
 .P
-To backup my wife's home directory, which consists of large MS Word files and
-mail folders, I use a cron job that runs
+To backup a home directory, which consists of large MS Word files and mail
+folders, a per-user cron job can be used that runs this each day:
 .RS 4
 .P
 .nf
-rsync -Cavz . arvidsjaur:backup
+rsync -aiz . bkhost:backup/joe/
 .fi
 .RE
 .P
-each night over a PPP connection to a duplicate directory on my machine
-"arvidsjaur".
-.P
-To synchronize my samba source trees I use the following Makefile targets:
+To move some files from a remote host to the local host, you could run:
 .RS 4
 .P
 .nf
-get:
-    rsync -avuzb --exclude '*~' samba:samba/ .
-put:
-    rsync -Cavuzb . samba:samba/
-sync: get put
+rsync -aiv --remove-source-files rhost:/tmp/{file1,file2}.c ~/src/
 .fi
 .RE
 .P
-This allows me to sync with a CVS directory at the other end of the connection.
-I then do CVS operations on the remote machine, which saves a lot of time as
-the remote CVS protocol isn't very efficient.
-.P
-I mirror a directory between my "old" and "new" ftp sites with the command:
-.RS 4
-.P
-.nf
-rsync -az -e ssh --delete ~ftp/pub/samba nimbus:"~ftp/pub/tridge"
-.fi
-.RE
-.P
-This is launched from cron every few hours.
-.P
 .SH "OPTION SUMMARY"
 .P
-Here is a short summary of the options available in rsync.  Please refer to the
-detailed description below for a complete description.
+Here is a short summary of the options available in rsync.  Each option also
+has its own detailed description later in this manpage.
 .P
 .nf
 --verbose, -v            increase verbosity
@@ -414,7 +519,7 @@ detailed description below for a complete description.
 --quiet, -q              suppress non-error messages
 --no-motd                suppress daemon-mode MOTD
 --checksum, -c           skip based on checksum, not mod-time & size
---archive, -a            archive mode; equals -rlptgoD (no -H,-A,-X)
+--archive, -a            archive mode is -rlptgoD (no -A,-X,-U,-N,-H)
 --no-OPTION              turn off an implied OPTION (e.g. --no-D)
 --recursive, -r          recurse into directories
 --relative, -R           use relative path names
@@ -427,7 +532,8 @@ detailed description below for a complete description.
 --append                 append data onto shorter files
 --append-verify          --append w/old data in file checksum
 --dirs, -d               transfer directories without recursing
---mkpath                 create the destination's path component
+--old-dirs, --old-d      works like --dirs when talking to old rsync
+--mkpath                 create destination's missing path components
 --links, -l              copy symlinks as symlinks
 --copy-links, -L         transform symlink into referent file/dir
 --copy-unsafe-links      only "unsafe" symlinks are transformed
@@ -444,6 +550,8 @@ detailed description below for a complete description.
 --owner, -o              preserve owner (super-user only)
 --group, -g              preserve group
 --devices                preserve device files (super-user only)
+--copy-devices           copy device contents as a regular file
+--write-devices          write to devices as files (implies --inplace)
 --specials               preserve special files
 -D                       same as --devices --specials
 --times, -t              preserve modification times
@@ -456,7 +564,6 @@ detailed description below for a complete description.
 --fake-super             store/recover privileged attrs using xattrs
 --sparse, -S             turn sequences of nulls into sparse blocks
 --preallocate            allocate dest files before writing them
---write-devices          write to devices as files (implies --inplace)
 --dry-run, -n            perform a trial run with no changes made
 --whole-file, -W         copy files whole (w/o delta-xfer algorithm)
 --checksum-choice=STR    choose the checksum algorithm (aka --cc)
@@ -514,7 +621,9 @@ detailed description below for a complete description.
 --include-from=FILE      read include patterns from FILE
 --files-from=FILE        read list of source-file names from FILE
 --from0, -0              all *-from/filter files are delimited by 0s
---protect-args, -s       no space-splitting; wildcard chars only
+--old-args               disable the modern arg-protection idiom
+--secluded-args, -s      use the protocol to safely send the args
+--trust-sender           trust the remote sender's file list
 --copy-as=USER[:GROUP]   specify user & optional group for the copy
 --address=ADDRESS        bind address for outgoing socket to daemon
 --port=PORT              specify double-colon alternate port number
@@ -537,6 +646,7 @@ detailed description below for a complete description.
 --bwlimit=RATE           limit socket I/O bandwidth
 --stop-after=MINS        Stop rsync after MINS minutes have elapsed
 --stop-at=y-m-dTh:m      Stop rsync at the specified point in time
+--fsync                  fsync every written file
 --write-batch=FILE       write a batched update to FILE
 --only-write-batch=FILE  like --write-batch but w/o updating dest
 --read-batch=FILE        read a batched update from FILE
@@ -574,25 +684,33 @@ accepted:
 Rsync accepts both long (double-dash + word) and short (single-dash + letter)
 options.  The full list of the available options are described below.  If an
 option can be specified in more than one way, the choices are comma-separated.
-Some options only have a long variant, not a short.  If the option takes a
-parameter, the parameter is only listed after the long variant, even though it
-must also be specified for the short.  When specifying a parameter, you can
-either use the form \fB\-\-option=param\fP or replace the '=' with whitespace.  The
-parameter may need to be quoted in some manner for it to survive the shell's
-command-line parsing.  Keep in mind that a leading tilde (\fB~\fP) in a filename is
-substituted by your shell, so \fB\-\-option=~/foo\fP will not change the tilde into
-your home directory (remove the '=' for that).
-.P
-.IP "\fB\-\-help\fP, \fB\-h\fP \fB(*)\fP"
+Some options only have a long variant, not a short.
+.P
+If the option takes a parameter, the parameter is only listed after the long
+variant, even though it must also be specified for the short.  When specifying
+a parameter, you can either use the form \fB\-\-option=param\fP, \fB\-\-option\ param\fP,
+\fB\-o=param\fP, \fB\-o\ param\fP, or \fB\-oparam\fP (the latter choices assume that your
+option has a short variant).
+.P
+The parameter may need to be quoted in some manner for it to survive the
+shell's command-line parsing.  Also keep in mind that a leading tilde (\fB~\fP) in
+a pathname is substituted by your shell, so make sure that you separate the
+option name from the pathname using a space if you want the local shell to
+expand it.
+.P
+.IP "\fB\-\-help\fP"
 Print a short help page describing the options available in rsync and exit.
-(*) The \fB\-h\fP short option will only invoke \fB\-\-help\fP when used without other
-options since it normally means \fB\-\-human-readable\fP.
+You can also use \fB\-h\fP for \fB\-\-help\fP when it is used without any other
+options (since it normally means \fB\-\-human-readable\fP).
 .IP "\fB\-\-version\fP, \fB\-V\fP"
-Print the rsync version plus other info and exit.
-.IP
-The output includes the default list of checksum algorithms, the default
-list of compression algorithms, a list of compiled-in capabilities, a link
-to the rsync web site, and some license/copyright info.
+Print the rsync version plus other info and exit.  When repeated, the
+information is output is a JSON format that is still fairly readable
+(client side only).
+.IP
+The output includes a list of compiled-in capabilities, a list of
+optimizations, the default list of checksum algorithms, the default list of
+compression algorithms, the default list of daemon auth digests, a link to
+the rsync web site, and a few other items.
 .IP "\fB\-\-verbose\fP, \fB\-v\fP"
 This option increases the amount of information you are given during the
 transfer.  By default, rsync works silently.  A single \fB\-v\fP will give you
@@ -601,12 +719,24 @@ the end.  Two \fB\-v\fP options will give you information on what files are
 being skipped and slightly more information at the end.  More than two \fB\-v\fP
 options should only be used if you are debugging rsync.
 .IP
+The end-of-run summary tells you the number of bytes sent to the remote
+rsync (which is the receiving side on a local copy), the number of bytes
+received from the remote host, and the average bytes per second of the
+transferred data computed over the entire length of the rsync run. The
+second line shows the total size (in bytes), which is the sum of all the
+file sizes that rsync considered transferring.  It also shows a "speedup"
+value, which is a ratio of the total file size divided by the sum of the
+sent and received bytes (which is really just a feel-good bigger-is-better
+number).  Note that these byte values can be made more (or less)
+human-readable by using the \fB\-\-human-readable\fP (or
+\fB\-\-no-human-readable\fP) options.
+.IP
 In a modern rsync, the \fB\-v\fP option is equivalent to the setting of groups
-of \fB\-\-info\fP and \fB\-\-debug\fP options.  You can choose to use these newer
-options in addition to, or in place of using \fB\-\-verbose\fP, as any
-fine-grained settings override the implied settings of \fB\-v\fP.  Both \fB\-\-info\fP
-and \fB\-\-debug\fP have a way to ask for help that tells you exactly what flags
-are set for each increase in verbosity.
+of \fB\-\-info\fP and \fB\-\-debug\fP options.  You can choose to use
+these newer options in addition to, or in place of using \fB\-\-verbose\fP, as
+any fine-grained settings override the implied settings of \fB\-v\fP.  Both
+\fB\-\-info\fP and \fB\-\-debug\fP have a way to ask for help that
+tells you exactly what flags are set for each increase in verbosity.
 .IP
 However, do keep in mind that a daemon's "\fBmax\ verbosity\fP" setting will limit
 how high of a level the various individual flags can be set on the daemon
@@ -629,9 +759,9 @@ rsync -avv --info=stats2,misc1,flist0 src/ dest/
 .fi
 .RE
 .IP
-Note that \fB\-\-info=name\fP's output is affected by the \fB\-\-out-format\fP and
-\fB\-\-itemize-changes\fP (\fB\-i\fP) options.  See those options for more information
-on what is output and when.
+Note that \fB\-\-info=name\fP's output is affected by the \fB\-\-out-format\fP
+and \fB\-\-itemize-changes\fP (\fB\-i\fP) options.  See those options for more
+information on what is output and when.
 .IP
 This option was added to 3.1.0, so an older rsync on the server side might
 reject your attempts at fine-grained control (if one or more flags needed
@@ -653,8 +783,8 @@ rsync -avA --del --debug=del2,acl src/ dest/
 .fi
 .RE
 .IP
-Note that some debug messages will only be output when \fB\-\-stderr=all\fP is
-specified, especially those pertaining to I/O and buffer debugging.
+Note that some debug messages will only be output when the \fB\-\-stderr=all\fP
+option is specified, especially those pertaining to I/O and buffer debugging.
 .IP
 Beginning in 3.2.0, this option is no longer auto-forwarded to the server
 side in order to allow you to specify different debug values for each side
@@ -688,8 +818,8 @@ become line-buffered (instead of raw) and eliminates the ability to
 divide up the info and error messages by file handle.  For those doing
 debugging or using several levels of verbosity, this option can help to
 avoid clogging up the transfer stream (which should prevent any chance of
-a deadlock bug hanging things up).  It also enables the outputting of some
-I/O related debug messages.
+a deadlock bug hanging things up).  It also allows \fB\-\-debug\fP to
+enable some extra I/O related messages.
 .IP o
 \fBclient\fP \- causes all rsync messages to be sent to the client side
 via the protocol stream.  One client process outputs all messages, with
@@ -720,6 +850,10 @@ from the daemon.
 Normally rsync will skip any files that are already the same size and have
 the same modification timestamp.  This option turns off this "quick check"
 behavior, causing all files to be updated.
+.IP
+This option can be confusing compared to \fB\-\-ignore-existing\fP and
+\fB\-\-ignore-non-existing\fP in that that they cause rsync to transfer
+fewer files, while this option causes rsync to transfer more files.
 .IP "\fB\-\-size-only\fP"
 This modifies rsync's "quick check" algorithm for finding files that need
 to be transferred, changing it from the default of transferring files with
@@ -773,56 +907,89 @@ after-the-transfer verification has nothing to do with this option's
 before-the-transfer "Does this file need to be updated?" check.
 .IP
 The checksum used is auto-negotiated between the client and the server, but
-can be overridden using either the \fB\-\-checksum-choice\fP (\fB\-\-cc\fP) option or an
-environment variable that is discussed in that option's section.
+can be overridden using either the \fB\-\-checksum-choice\fP (\fB\-\-cc\fP)
+option or an environment variable that is discussed in that option's
+section.
 .IP "\fB\-\-archive\fP, \fB\-a\fP"
 This is equivalent to \fB\-rlptgoD\fP.  It is a quick way of saying you want
-recursion and want to preserve almost everything (with \fB\-H\fP being a notable
-omission).  The only exception to the above equivalence is when
-\fB\-\-files-from\fP is specified, in which case \fB\-r\fP is not implied.
+recursion and want to preserve almost everything.  Be aware that it does
+\fBnot\fP include preserving ACLs (\fB\-A\fP), xattrs (\fB\-X\fP), atimes (\fB\-U\fP),
+crtimes (\fB\-N\fP), nor the finding and preserving of hardlinks (\fB\-H\fP).
 .IP
-Note that \fB\-a\fP \fBdoes not preserve hardlinks\fP, because finding
-multiply-linked files is expensive.  You must separately specify \fB\-H\fP.
+The only exception to the above equivalence is when \fB\-\-files-from\fP
+is specified, in which case \fB\-r\fP is not implied.
 .IP "\fB\-\-no-OPTION\fP"
 You may turn off one or more implied options by prefixing the option name
-with "no-".  Not all options may be prefixed with a "no-": only options that
-are implied by other options (e.g. \fB\-\-no-D\fP, \fB\-\-no-perms\fP) or have
-different defaults in various circumstances (e.g. \fB\-\-no-whole-file\fP,
-\fB\-\-no-blocking-io\fP, \fB\-\-no-dirs\fP).  You may specify either the short or the
-long option name after the "no-" prefix (e.g. \fB\-\-no-R\fP is the same as
-\fB\-\-no-relative\fP).
-.IP
-For example: if you want to use \fB\-a\fP (\fB\-\-archive\fP) but don't want \fB\-o\fP
-(\fB\-\-owner\fP), instead of converting \fB\-a\fP into \fB\-rlptgD\fP, you could specify
-\fB\-a\ \-\-no-o\fP (or \fB\-a\ \-\-no-owner\fP).
-.IP
-The order of the options is important: if you specify \fB\-\-no-r\ \-a\fP, the
-\fB\-r\fP option would end up being turned on, the opposite of \fB\-a\ \-\-no-r\fP.
-Note also that the side-effects of the \fB\-\-files-from\fP option are NOT
+with "no-".  Not all positive options have a negated opposite, but a lot
+do, including those that can be used to disable an implied option (e.g.
+\fB\-\-no-D\fP, \fB\-\-no-perms\fP) or have different defaults in various circumstances
+(e.g. \fB\-\-no-whole-file\fP, \fB\-\-no-blocking-io\fP, \fB\-\-no-dirs\fP).  Every
+valid negated option accepts both the short and the long option name after
+the "no-" prefix (e.g. \fB\-\-no-R\fP is the same as \fB\-\-no-relative\fP).
+.IP
+As an example, if you want to use \fB\-\-archive\fP (\fB\-a\fP) but don't want
+\fB\-\-owner\fP (\fB\-o\fP), instead of converting \fB\-a\fP into \fB\-rlptgD\fP, you
+can specify \fB\-a\ \-\-no-o\fP (aka \fB\-\-archive\ \-\-no-owner\fP).
+.IP
+The order of the options is important: if you specify \fB\-\-no-r\ \-a\fP, the \fB\-r\fP
+option would end up being turned on, the opposite of \fB\-a\ \-\-no-r\fP.  Note
+also that the side-effects of the \fB\-\-files-from\fP option are NOT
 positional, as it affects the default state of several options and slightly
-changes the meaning of \fB\-a\fP (see the \fB\-\-files-from\fP option for more
-details).
+changes the meaning of \fB\-a\fP (see the \fB\-\-files-from\fP option
+for more details).
 .IP "\fB\-\-recursive\fP, \fB\-r\fP"
-This tells rsync to copy directories recursively.  See also \fB\-\-dirs\fP (\fB\-d\fP).
+This tells rsync to copy directories recursively.  See also
+\fB\-\-dirs\fP (\fB\-d\fP) for an option that allows the scanning of a single
+directory.
+.IP
+See the \fB\-\-inc-recursive\fP option for a discussion of the
+incremental recursion for creating the list of files to transfer.
+.IP "\fB\-\-inc-recursive\fP, \fB\-\-i-r\fP"
+This option explicitly enables on incremental recursion when scanning for
+files, which is enabled by default when using the \fB\-\-recursive\fP
+option and both sides of the transfer are running rsync 3.0.0 or newer.
 .IP
-Beginning with rsync 3.0.0, the recursive algorithm used is now an
-incremental scan that uses much less memory than before and begins the
-transfer after the scanning of the first few directories have been
-completed.  This incremental scan only affects our recursion algorithm, and
-does not change a non-recursive transfer.  It is also only possible when
-both ends of the transfer are at least version 3.0.0.
+Incremental recursion uses much less memory than non-incremental, while
+also beginning the transfer more quickly (since it doesn't need to scan the
+entire transfer hierarchy before it starts transferring files).  If no
+recursion is enabled in the source files, this option has no effect.
 .IP
 Some options require rsync to know the full file list, so these options
-disable the incremental recursion mode.  These include: \fB\-\-delete-before\fP,
-\fB\-\-delete-after\fP, \fB\-\-prune-empty-dirs\fP, and \fB\-\-delay-updates\fP.  Because of
-this, the default delete mode when you specify \fB\-\-delete\fP is now
-\fB\-\-delete-during\fP when both ends of the connection are at least 3.0.0 (use
-\fB\-\-del\fP or \fB\-\-delete-during\fP to request this improved deletion mode
-explicitly).  See also the \fB\-\-delete-delay\fP option that is a better choice
-than using \fB\-\-delete-after\fP.
-.IP
-Incremental recursion can be disabled using the \fB\-\-no-inc-recursive\fP option
-or its shorter \fB\-\-no-i-r\fP alias.
+disable the incremental recursion mode.  These include:
+.IP
+.RS
+.IP o
+\fB\-\-delete-before\fP (the old default of \fB\-\-delete\fP)
+.IP o
+\fB\-\-delete-after\fP
+.IP o
+\fB\-\-prune-empty-dirs\fP
+.IP o
+\fB\-\-delay-updates\fP
+.RE
+.IP
+In order to make \fB\-\-delete\fP compatible with incremental recursion,
+rsync 3.0.0 made \fB\-\-delete-during\fP the default delete mode (which
+was first added in 2.6.4).
+.IP
+One side-effect of incremental recursion is that any missing
+sub-directories inside a recursively-scanned directory are (by default)
+created prior to recursing into the sub-dirs.  This earlier creation point
+(compared to a non-incremental recursion) allows rsync to then set the
+modify time of the finished directory right away (without having to delay
+that until a bunch of recursive copying has finished).  However, these
+early directories don't yet have their completed mode, mtime, or ownership
+set\ \-\- they have more restrictive rights until the subdirectory's copying
+actually begins.  This early-creation idiom can be avoided by using the
+\fB\-\-omit-dir-times\fP option.
+.IP
+Incremental recursion can be disabled using the
+\fB\-\-no-inc-recursive\fP (\fB\-\-no-i-r\fP) option.
+.IP "\fB\-\-no-inc-recursive\fP, \fB\-\-no-i-r\fP"
+Disables the new incremental recursion algorithm of the
+\fB\-\-recursive\fP option.  This makes rsync scan the full file list
+before it begins to transfer files.  See \fB\-\-inc-recursive\fP for more
+info.
 .IP "\fB\-\-relative\fP, \fB\-R\fP"
 Use relative paths.  This means that the full path names specified on the
 command line are sent to the server rather than just the last parts of the
@@ -918,25 +1085,33 @@ wish the implied directories to be transferred as normal directories.
 .IP "\fB\-\-backup\fP, \fB\-b\fP"
 With this option, preexisting destination files are renamed as each file is
 transferred or deleted.  You can control where the backup file goes and
-what (if any) suffix gets appended using the \fB\-\-backup-dir\fP and \fB\-\-suffix\fP
-options.
-.IP
-Note that if you don't specify \fB\-\-backup-dir\fP, (1) the \fB\-\-omit-dir-times\fP
-option will be forced on, and (2) if \fB\-\-delete\fP is also in effect (without
-\fB\-\-delete-excluded\fP), rsync will add a "protect" filter-rule for the backup
-suffix to the end of all your existing excludes (e.g. \fB\-f\ "P\ *~"\fP).  This
-will prevent previously backed-up files from being deleted.  Note that if
-you are supplying your own filter rules, you may need to manually insert
-your own exclude/protect rule somewhere higher up in the list so that it
-has a high enough priority to be effective (e.g., if your rules specify a
-trailing inclusion/exclusion of \fB*\fP, the auto-added rule would never be
-reached).
+what (if any) suffix gets appended using the \fB\-\-backup-dir\fP and
+\fB\-\-suffix\fP options.
+.IP
+If you don't specify \fB\-\-backup-dir\fP:
+.RS
+.IP
+.IP 1.
+the \fB\-\-omit-dir-times\fP option will be forced on
+.IP 2.
+the use of \fB\-\-delete\fP (without \fB\-\-delete-excluded\fP),
+causes rsync to add a "protect" filter-rule for the
+backup suffix to the end of all your existing filters that looks like
+this: \fB\-f\ "P\ *~"\fP.  This rule prevents previously backed-up files from
+being deleted.
+.RE
+.IP
+Note that if you are supplying your own filter rules, you may need to
+manually insert your own exclude/protect rule somewhere higher up in the
+list so that it has a high enough priority to be effective (e.g. if your
+rules specify a trailing inclusion/exclusion of \fB*\fP, the auto-added rule
+would never be reached).
 .IP "\fB\-\-backup-dir=DIR\fP"
 This implies the \fB\-\-backup\fP option, and tells rsync to store all
 backups in the specified directory on the receiving side.  This can be used
 for incremental backups.  You can additionally specify a backup suffix
-using the \fB\-\-suffix\fP option (otherwise the files backed up in the specified
-directory will keep their original filenames).
+using the \fB\-\-suffix\fP option (otherwise the files backed up in the
+specified directory will keep their original filenames).
 .IP
 Note that if you specify a relative path, the backup directory will be
 relative to the destination directory, so you probably want to specify
@@ -945,8 +1120,8 @@ daemon is the receiver, the backup dir cannot go outside the module's path
 hierarchy, so take extra care not to delete it or copy into it.
 .IP "\fB\-\-suffix=SUFFIX\fP"
 This option allows you to override the default backup suffix used with the
-\fB\-\-backup\fP (\fB\-b\fP) option.  The default suffix is a \fB~\fP if no \fB\-\-backup-dir\fP
-was specified, otherwise it is an empty string.
+\fB\-\-backup\fP (\fB\-b\fP) option.  The default suffix is a \fB~\fP if no
+\fB\-\-backup-dir\fP was specified, otherwise it is an empty string.
 .IP "\fB\-\-update\fP, \fB\-u\fP"
 This forces rsync to skip any files which exist on the destination and have
 a modified time that is newer than the source file. (If an existing
@@ -960,9 +1135,15 @@ matter what date is on the objects.  In other words, if the source has a
 directory where the destination has a file, the transfer would occur
 regardless of the timestamps.
 .IP
-This option is a transfer rule, not an exclude, so it doesn't affect the
-data that goes into the file-lists, and thus it doesn't affect deletions.
-It just limits the files that the receiver requests to be transferred.
+This option is a TRANSFER RULE, so don't expect any
+exclude side effects.
+.IP
+A caution for those that choose to combine \fB\-\-inplace\fP with
+\fB\-\-update\fP: an interrupted transfer will leave behind a partial file on the
+receiving side that has a very recent modified time, so re-running the
+transfer will probably \fBnot\fP continue the interrupted file.  As such, it
+is usually best to avoid combining this with \fB\-\-inplace\fP unless you
+have implemented manual steps to handle any interrupted in-progress files.
 .IP "\fB\-\-inplace\fP"
 This option changes how rsync transfers a file when its data needs to be
 updated: instead of the default method of creating a new copy of the file
@@ -1006,10 +1187,10 @@ or appended data, and also on systems that are disk bound, not network
 bound.  It can also help keep a copy-on-write filesystem snapshot from
 diverging the entire contents of a file that only has minor changes.
 .IP
-The option implies \fB\-\-partial\fP (since an interrupted transfer does not
-delete the file), but conflicts with \fB\-\-partial-dir\fP and \fB\-\-delay-updates\fP.
-Prior to rsync 2.6.4 \fB\-\-inplace\fP was also incompatible with
-\fB\-\-compare-dest\fP and \fB\-\-link-dest\fP.
+The option implies \fB\-\-partial\fP (since an interrupted transfer does
+not delete the file), but conflicts with \fB\-\-partial-dir\fP and
+\fB\-\-delay-updates\fP.  Prior to rsync 2.6.4 \fB\-\-inplace\fP was also
+incompatible with \fB\-\-compare-dest\fP and \fB\-\-link-dest\fP.
 .IP "\fB\-\-append\fP"
 This special copy mode only works to efficiently update files that are
 known to be growing larger where any existing content on the receiving side
@@ -1022,15 +1203,17 @@ Rsync updates these growing file in-place without verifying any of the
 existing content in the file (it only verifies the content that it is
 appending).  Rsync skips any files that exist on the receiving side that
 are not shorter than the associated file on the sending side (which means
-that new files are trasnferred).
+that new files are transferred).  It also skips any files whose size on the
+sending side gets shorter during the send negotiations (rsync warns about a
+"diminished" file when this happens).
 .IP
 This does not interfere with the updating of a file's non-content
 attributes (e.g.  permissions, ownership, etc.) when the file does not need
 to be transferred, nor does it affect the updating of any directories or
 non-regular files.
 .IP "\fB\-\-append-verify\fP"
-This special copy mode works like \fB\-\-append\fP except that all the data in
-the file is included in the checksum verification (making it much less
+This special copy mode works like \fB\-\-append\fP except that all the
+data in the file is included in the checksum verification (making it less
 efficient but also potentially safer).  This option \fBcan be dangerous\fP if
 you aren't 100% sure that all the files in the transfer are shared, growing
 files.  See the \fB\-\-append\fP option for more details.
@@ -1041,64 +1224,84 @@ transfer is using a protocol prior to 30), specifying either append option
 will initiate an \fB\-\-append-verify\fP transfer.
 .IP "\fB\-\-dirs\fP, \fB\-d\fP"
 Tell the sending side to include any directories that are encountered.
-Unlike \fB\-\-recursive\fP, a directory's contents are not copied unless the
-directory name specified is "." or ends with a trailing slash (e.g. ".",
-"dir/.", "dir/", etc.).  Without this option or the \fB\-\-recursive\fP option,
-rsync will skip all directories it encounters (and output a message to that
-effect for each one).  If you specify both \fB\-\-dirs\fP and \fB\-\-recursive\fP,
-\fB\-\-recursive\fP takes precedence.
+Unlike \fB\-\-recursive\fP, a directory's contents are not copied unless
+the directory name specified is "." or ends with a trailing slash (e.g.
+".", "dir/.", "dir/", etc.).  Without this option or the
+\fB\-\-recursive\fP option, rsync will skip all directories it encounters
+(and output a message to that effect for each one).  If you specify both
+\fB\-\-dirs\fP and \fB\-\-recursive\fP, \fB\-\-recursive\fP takes precedence.
 .IP
 The \fB\-\-dirs\fP option is implied by the \fB\-\-files-from\fP option or the
-\fB\-\-list-only\fP option (including an implied \fB\-\-list-only\fP usage) if
-\fB\-\-recursive\fP wasn't specified (so that directories are seen in the
-listing).  Specify \fB\-\-no-dirs\fP (or \fB\-\-no-d\fP) if you want to turn this off.
+\fB\-\-list-only\fP option (including an implied \fB\-\-list-only\fP
+usage) if \fB\-\-recursive\fP wasn't specified (so that directories are
+seen in the listing).  Specify \fB\-\-no-dirs\fP (or \fB\-\-no-d\fP) if you want to
+turn this off.
 .IP
-There is also a backward-compatibility helper option, \fB\-\-old-dirs\fP (or
-\fB\-\-old-d\fP) that tells rsync to use a hack of \fB\-r\ \-\-exclude='/*/*'\fP to get
+There is also a backward-compatibility helper option, \fB\-\-old-dirs\fP
+(\fB\-\-old-d\fP) that tells rsync to use a hack of \fB\-r\ \-\-exclude='/*/*'\fP to get
 an older rsync to list a single directory without recursing.
 .IP "\fB\-\-mkpath\fP"
-Create a missing path component of the destination arg.  This allows rsync
-to create multiple levels of missing destination dirs and to create a path
-in which to put a single renamed file.  Keep in mind that you'll need to
-supply a trailing slash if you want the entire destination path to be
-treated as a directory when copying a single arg (making rsync behave the
-same way that it would if the path component of the destination had already
-existed).
-.IP
-For example, the following creates a copy of file foo as bar in the sub/dir
-directory, creating dirs "sub" and "sub/dir" if either do not yet exist:
+Create all missing path components of the destination path.
+.IP
+By default, rsync allows only the final component of the destination path
+to not exist, which is an attempt to help you to validate your destination
+path.  With this option, rsync creates all the missing destination-path
+components, just as if \fBmkdir\ \-p\ $DEST_PATH\fP had been run on the receiving
+side.
+.IP
+When specifying a destination path, including a trailing slash ensures that
+the whole path is treated as directory names to be created, even when the
+file list has a single item. See the COPYING TO A DIFFERENT NAME
+section for full details on how rsync decides if a final destination-path
+component should be created as a directory or not.
+.IP
+If you would like the newly-created destination dirs to match the dirs on
+the sending side, you should be using \fB\-\-relative\fP (\fB\-R\fP) instead
+of \fB\-\-mkpath\fP.  For instance, the following two commands result in the same
+destination tree, but only the second command ensures that the
+"some/extra/path" components match the dirs on the sending side:
 .RS 4
 .IP
 .nf
-rsync -ai --mkpath foo sub/dir/bar
+rsync -ai --mkpath host:some/extra/path/*.c some/extra/path/
+rsync -aiR host:some/extra/path/*.c ./
 .fi
 .RE
+.IP "\fB\-\-links\fP, \fB\-l\fP"
+Add symlinks to the transferred files instead of noisily ignoring them with
+a "non-regular file" warning for each symlink encountered.  You can
+alternately silence the warning by specifying \fB\-\-info=nonreg0\fP.
 .IP
-If you instead ran the following, it would have created file foo in the
-sub/dir/bar directory:
-.RS 4
+The default handling of symlinks is to recreate each symlink's unchanged
+value on the receiving side.
 .IP
-.nf
-rsync -ai --mkpath foo sub/dir/bar/
-.fi
-.RE
-.IP "\fB\-\-links\fP, \fB\-l\fP"
-When symlinks are encountered, recreate the symlink on the destination.
+See the SYMBOLIC LINKS section for multi-option info.
 .IP "\fB\-\-copy-links\fP, \fB\-L\fP"
-When symlinks are encountered, the item that they point to (the referent)
-is copied, rather than the symlink.  In older versions of rsync, this
-option also had the side-effect of telling the receiving side to follow
-symlinks, such as symlinks to directories.  In a modern rsync such as this
-one, you'll need to specify \fB\-\-keep-dirlinks\fP (\fB\-K\fP) to get this extra
-behavior.  The only exception is when sending files to an rsync that is too
-old to understand \fB\-K\fP\ \-\- in that case, the \fB\-L\fP option will still have the
-side-effect of \fB\-K\fP on that older receiving rsync.
+The sender transforms each symlink encountered in the transfer into the
+referent item, following the symlink chain to the file or directory that it
+references.  If a symlink chain is broken, an error is output and the file
+is dropped from the transfer.
+.IP
+This option supersedes any other options that affect symlinks in the
+transfer, since there are no symlinks left in the transfer.
+.IP
+This option does not change the handling of existing symlinks on the
+receiving side, unlike versions of rsync prior to 2.6.3 which had the
+side-effect of telling the receiving side to also follow symlinks.  A
+modern rsync won't forward this option to a remote receiver (since only the
+sender needs to know about it), so this caveat should only affect someone
+using an rsync client older than 2.6.7 (which is when \fB\-L\fP stopped being
+forwarded to the receiver).
+.IP
+See the \fB\-\-keep-dirlinks\fP (\fB\-K\fP) if you need a symlink to a
+directory to be treated as a real directory on the receiving side.
+.IP
+See the SYMBOLIC LINKS section for multi-option info.
 .IP "\fB\-\-copy-unsafe-links\fP"
 This tells rsync to copy the referent of symbolic links that point outside
 the copied tree.  Absolute symlinks are also treated like ordinary files,
-and so are any symlinks in the source path itself when \fB\-\-relative\fP is
-used.  This option has no additional effect if \fB\-\-copy-links\fP was also
-specified.
+and so are any symlinks in the source path itself when \fB\-\-relative\fP
+is used.
 .IP
 Note that the cut-off point is the top of the transfer, which is the part
 of the path that rsync isn't mentioning in the verbose output.  If you copy
@@ -1108,40 +1311,78 @@ for created relative symlinks to refer to other names inside the /src and
 /dest directories.  If you instead copy "/src/subdir/" (with a trailing
 slash) to "/dest/subdir" that would not allow symlinks to any files outside
 of "subdir".
+.IP
+Note that safe symlinks are only copied if \fB\-\-links\fP was also
+specified or implied. The \fB\-\-copy-unsafe-links\fP option has no extra effect
+when combined with \fB\-\-copy-links\fP.
+.IP
+See the SYMBOLIC LINKS section for multi-option info.
 .IP "\fB\-\-safe-links\fP"
-This tells rsync to ignore any symbolic links which point outside the
-copied tree.  All absolute symlinks are also ignored. Using this option in
-conjunction with \fB\-\-relative\fP may give unexpected results.
+This tells the receiving rsync to ignore any symbolic links in the transfer
+which point outside the copied tree.  All absolute symlinks are also
+ignored.
+.IP
+Since this ignoring is happening on the receiving side, it will still be
+effective even when the sending side has munged symlinks (when it is using
+\fB\-\-munge-links\fP). It also affects deletions, since the file being
+present in the transfer prevents any matching file on the receiver from
+being deleted when the symlink is deemed to be unsafe and is skipped.
+.IP
+This option must be combined with \fB\-\-links\fP (or
+\fB\-\-archive\fP) to have any symlinks in the transfer to conditionally
+ignore. Its effect is superseded by \fB\-\-copy-unsafe-links\fP.
+.IP
+Using this option in conjunction with \fB\-\-relative\fP may give
+unexpected results.
+.IP
+See the SYMBOLIC LINKS section for multi-option info.
 .IP "\fB\-\-munge-links\fP"
-This option tells rsync to (1) modify all symlinks on the receiving side in
-a way that makes them unusable but recoverable (see below), or (2) to
-unmunge symlinks on the sending side that had been stored in a munged
-state.  This is useful if you don't quite trust the source of the data to
-not try to slip in a symlink to a unexpected place.
-.IP
-The way rsync disables the use of symlinks is to prefix each one with the
-string "/rsyncd-munged/".  This prevents the links from being used as long
-as that directory does not exist.  When this option is enabled, rsync will
-refuse to run if that path is a directory or a symlink to a directory.
-.IP
-The option only affects the client side of the transfer, so if you need it
-to affect the server, specify it via \fB\-\-remote-option\fP. (Note that in a
-local transfer, the client side is the sender.)
-.IP
-This option has no affect on a daemon, since the daemon configures whether
-it wants munged symlinks via its "\fBmunge\ symlinks\fP" parameter.  See also the
-"munge-symlinks" perl script in the support directory of the source code.
+This option affects just one side of the transfer and tells rsync to munge
+symlink values when it is receiving files or unmunge symlink values when it
+is sending files.  The munged values make the symlinks unusable on disk but
+allows the original contents of the symlinks to be recovered.
+.IP
+The server-side rsync often enables this option without the client's
+knowledge, such as in an rsync daemon's configuration file or by an option
+given to the rrsync (restricted rsync) script.  When specified on the
+client side, specify the option normally if it is the client side that
+has/needs the munged symlinks, or use \fB\-M\-\-munge-links\fP to give the option
+to the server when it has/needs the munged symlinks.  Note that on a local
+transfer, the client is the sender, so specifying the option directly
+unmunges symlinks while specifying it as a remote option munges symlinks.
+.IP
+This option has no effect when sent to a daemon via \fB\-\-remote-option\fP
+because the daemon configures whether it wants munged symlinks via its
+"\fBmunge\ symlinks\fP" parameter.
+.IP
+The symlink value is munged/unmunged once it is in the transfer, so any
+option that transforms symlinks into non-symlinks occurs prior to the
+munging/unmunging \fBexcept\fP for \fB\-\-safe-links\fP, which is a choice
+that the receiver makes, so it bases its decision on the munged/unmunged
+value.  This does mean that if a receiver has munging enabled, that using
+\fB\-\-safe-links\fP will cause all symlinks to be ignored (since they
+are all absolute).
+.IP
+The method that rsync uses to munge the symlinks is to prefix each one's
+value with the string "/rsyncd-munged/".  This prevents the links from
+being used as long as the directory does not exist.  When this option is
+enabled, rsync will refuse to run if that path is a directory or a symlink
+to a directory (though it only checks at startup).  See also the
+"munge-symlinks" python script in the support directory of the source code
+for a way to munge/unmunge one or more symlinks in-place.
 .IP "\fB\-\-copy-dirlinks\fP, \fB\-k\fP"
 This option causes the sending side to treat a symlink to a directory as
 though it were a real directory.  This is useful if you don't want symlinks
-to non-directories to be affected, as they would be using \fB\-\-copy-links\fP.
+to non-directories to be affected, as they would be using
+\fB\-\-copy-links\fP.
 .IP
 Without this option, if the sending side has replaced a directory with a
 symlink to a directory, the receiving side will delete anything that is in
 the way of the new symlink, including a directory hierarchy (as long as
 \fB\-\-force\fP or \fB\-\-delete\fP is in effect).
 .IP
-See also \fB\-\-keep-dirlinks\fP for an analogous option for the receiving side.
+See also \fB\-\-keep-dirlinks\fP for an analogous option for the
+receiving side.
 .IP
 \fB\-\-copy-dirlinks\fP applies to all symlinks to directories in the source.  If
 you want to follow only a few specified symlinks, a trick you can use is to
@@ -1158,6 +1399,8 @@ This works because rsync calls \fBlstat\fP(2) on the source arg as given, and
 the trailing slash makes \fBlstat\fP(2) follow the symlink, giving rise to a
 directory in the file-list which overrides the symlink found during the
 scan of "src/./".
+.IP
+See the SYMBOLIC LINKS section for multi-option info.
 .IP "\fB\-\-keep-dirlinks\fP, \fB\-K\fP"
 This option causes the receiving side to treat a symlink to a directory as
 though it were a real directory, but only if it matches a real directory
@@ -1172,14 +1415,18 @@ directory, and receives the file into the new directory.  With
 "bar".
 .IP
 One note of caution: if you use \fB\-\-keep-dirlinks\fP, you must trust all the
-symlinks in the copy! If it is possible for an untrusted user to create
-their own symlink to any directory, the user could then (on a subsequent
+symlinks in the copy or enable the \fB\-\-munge-links\fP option on the
+receiving side!  If it is possible for an untrusted user to create their
+own symlink to any real directory, the user could then (on a subsequent
 copy) replace the symlink with a real directory and affect the content of
 whatever directory the symlink references.  For backup copies, you are
 better off using something like a bind mount instead of a symlink to modify
 your receiving hierarchy.
 .IP
-See also \fB\-\-copy-dirlinks\fP for an analogous option for the sending side.
+See also \fB\-\-copy-dirlinks\fP for an analogous option for the sending
+side.
+.IP
+See the SYMBOLIC LINKS section for multi-option info.
 .IP "\fB\-\-hard-links\fP, \fB\-H\fP"
 This tells rsync to look for hard-linked files in the source and link
 together the corresponding files on the destination.  Without this option,
@@ -1198,10 +1445,10 @@ them explicitly.  However, if one or more of the paths have content
 differences, the normal file-update process will break those extra links
 (unless you are using the \fB\-\-inplace\fP option).
 .IP o
-If you specify a \fB\-\-link-dest\fP directory that contains hard links, the
-linking of the destination files against the \fB\-\-link-dest\fP files can
-cause some paths in the destination to become linked together due to the
-\fB\-\-link-dest\fP associations.
+If you specify a \fB\-\-link-dest\fP directory that contains hard
+links, the linking of the destination files against the
+\fB\-\-link-dest\fP files can cause some paths in the destination to
+become linked together due to the \fB\-\-link-dest\fP associations.
 .RE
 .IP
 Note that rsync can only detect hard links between files that are inside
@@ -1212,27 +1459,28 @@ very careful that you know how your files are being updated so that you are
 certain that no unintended changes happen due to lingering hard links (and
 see the \fB\-\-inplace\fP option for more caveats).
 .IP
-If incremental recursion is active (see \fB\-\-recursive\fP), rsync may transfer
-a missing hard-linked file before it finds that another link for that
-contents exists elsewhere in the hierarchy.  This does not affect the
-accuracy of the transfer (i.e. which files are hard-linked together), just
-its efficiency (i.e. copying the data for a new, early copy of a
+If incremental recursion is active (see \fB\-\-inc-recursive\fP), rsync
+may transfer a missing hard-linked file before it finds that another link
+for that contents exists elsewhere in the hierarchy.  This does not affect
+the accuracy of the transfer (i.e. which files are hard-linked together),
+just its efficiency (i.e. copying the data for a new, early copy of a
 hard-linked file that could have been found later in the transfer in
 another member of the hard-linked set of files).  One way to avoid this
 inefficiency is to disable incremental recursion using the
 \fB\-\-no-inc-recursive\fP option.
 .IP "\fB\-\-perms\fP, \fB\-p\fP"
 This option causes the receiving rsync to set the destination permissions
-to be the same as the source permissions. (See also the \fB\-\-chmod\fP option
-for a way to modify what rsync considers to be the source permissions.)
+to be the same as the source permissions. (See also the \fB\-\-chmod\fP
+option for a way to modify what rsync considers to be the source
+permissions.)
 .IP
 When this option is \fIoff\fP, permissions are set as follows:
 .IP
 .RS
 .IP o
 Existing files (including updated files) retain their existing
-permissions, though the \fB\-\-executability\fP option might change just the
-execute permission for the file.
+permissions, though the \fB\-\-executability\fP option might change
+just the execute permission for the file.
 .IP o
 New files get their "normal" permission bits set to the source file's
 permissions masked with the receiving directory's default permissions
@@ -1249,11 +1497,12 @@ and \fBtar\fP(1).
 In summary: to give destination files (both old and new) the source
 permissions, use \fB\-\-perms\fP.  To give new files the destination-default
 permissions (while leaving existing files unchanged), make sure that the
-\fB\-\-perms\fP option is off and use \fB\-\-chmod=ugo=rwX\fP (which ensures that all
-non-masked bits get enabled).  If you'd care to make this latter behavior
-easier to type, you could define a popt alias for it, such as putting this
-line in the file \fB~/.popt\fP (the following defines the \fB\-Z\fP option, and
-includes \fB\-\-no-g\fP to use the default group of the destination dir):
+\fB\-\-perms\fP option is off and use \fB\-\-chmod=ugo=rwX\fP (which ensures
+that all non-masked bits get enabled).  If you'd care to make this latter
+behavior easier to type, you could define a popt alias for it, such as
+putting this line in the file \fB~/.popt\fP (the following defines the \fB\-Z\fP
+option, and includes \fB\-\-no-g\fP to use the default group of the destination
+dir):
 .RS 4
 .IP
 .nf
@@ -1283,8 +1532,8 @@ non-ACL-enabled) rsyncs use the umask even if default ACLs are present.
 these behaviors.)
 .IP "\fB\-\-executability\fP, \fB\-E\fP"
 This option causes rsync to preserve the executability (or
-non-executability) of regular files when \fB\-\-perms\fP is not enabled.  A
-regular file is considered to be executable if at least one 'x' is turned
+non-executability) of regular files when \fB\-\-perms\fP is not enabled.
+regular file is considered to be executable if at least one 'x' is turned
 on in its permissions.  When an existing destination file's executability
 differs from that of the corresponding source file, rsync modifies the
 destination file's permissions as follows:
@@ -1303,8 +1552,8 @@ This option causes rsync to update the destination ACLs to be the same as
 the source ACLs.  The option also implies \fB\-\-perms\fP.
 .IP
 The source and destination systems must have compatible ACL entries for
-this option to work properly.  See the \fB\-\-fake-super\fP option for a way to
-backup and restore ACLs that are not compatible.
+this option to work properly.  See the \fB\-\-fake-super\fP option for a
+way to backup and restore ACLs that are not compatible.
 .IP "\fB\-\-xattrs\fP, \fB\-X\fP"
 This option causes rsync to update the destination extended attributes to
 be the same as the source ones.
@@ -1380,14 +1629,14 @@ Using octal mode numbers is also allowed:
 It is also legal to specify multiple \fB\-\-chmod\fP options, as each additional
 option is just appended to the list of changes to make.
 .IP
-See the \fB\-\-perms\fP and \fB\-\-executability\fP options for how the resulting
-permission value can be applied to the files in the transfer.
+See the \fB\-\-perms\fP and \fB\-\-executability\fP options for how the
+resulting permission value can be applied to the files in the transfer.
 .IP "\fB\-\-owner\fP, \fB\-o\fP"
 This option causes rsync to set the owner of the destination file to be the
 same as the source file, but only if the receiving rsync is being run as
-the super-user (see also the \fB\-\-super\fP and \fB\-\-fake-super\fP options).  Without
-this option, the owner of new and/or transferred files are set to the
-invoking user on the receiving side.
+the super-user (see also the \fB\-\-super\fP and \fB\-\-fake-super\fP
+options).  Without this option, the owner of new and/or transferred files
+are set to the invoking user on the receiving side.
 .IP
 The preservation of ownership will associate matching names by default, but
 may fall back to using the ID number in some circumstances (see also the
@@ -1405,14 +1654,31 @@ default, but may fall back to using the ID number in some circumstances
 (see also the \fB\-\-numeric-ids\fP option for a full discussion).
 .IP "\fB\-\-devices\fP"
 This option causes rsync to transfer character and block device files to
-the remote system to recreate these devices.  This option has no effect if
-the receiving rsync is not run as the super-user (see also the \fB\-\-super\fP
-and \fB\-\-fake-super\fP options).
+the remote system to recreate these devices.  If the receiving rsync is not
+being run as the super-user, rsync silently skips creating the device files
+(see also the \fB\-\-super\fP and \fB\-\-fake-super\fP options).
+.IP
+By default, rsync generates a "non-regular file" warning for each device
+file encountered when this option is not set.  You can silence the warning
+by specifying \fB\-\-info=nonreg0\fP.
 .IP "\fB\-\-specials\fP"
-This option causes rsync to transfer special files such as named sockets
-and fifos.
+This option causes rsync to transfer special files, such as named sockets
+and fifos.  If the receiving rsync is not being run as the super-user,
+rsync silently skips creating the special files (see also the
+\fB\-\-super\fP and \fB\-\-fake-super\fP options).
+.IP
+By default, rsync generates a "non-regular file" warning for each special
+file encountered when this option is not set.  You can silence the warning
+by specifying \fB\-\-info=nonreg0\fP.
 .IP "\fB\-D\fP"
-The \fB\-D\fP option is equivalent to \fB\-\-devices\ \-\-specials\fP.
+The \fB\-D\fP option is equivalent to "\fB\-\-devices\fP
+\fB\-\-specials\fP".
+.IP "\fB\-\-copy-devices\fP"
+This tells rsync to treat a device on the sending side as a regular file,
+allowing it to be copied to a normal destination file (or another device
+if \fB\-\-write-devices\fP was also specified).
+.IP
+This option is refused by default by an rsync daemon.
 .IP "\fB\-\-write-devices\fP"
 This tells rsync to treat a device on the receiving side as a regular file,
 allowing the writing of file data into a device.
@@ -1420,18 +1686,27 @@ allowing the writing of file data into a device.
 This option implies the \fB\-\-inplace\fP option.
 .IP
 Be careful using this, as you should know what devices are present on the
-receiving side of the transfer, especially if running rsync as root.
+receiving side of the transfer, especially when running rsync as root.
 .IP
-This option is refused by an rsync daemon.
+This option is refused by default by an rsync daemon.
 .IP "\fB\-\-times\fP, \fB\-t\fP"
 This tells rsync to transfer modification times along with the files and
 update them on the remote system.  Note that if this option is not used,
 the optimization that excludes files that have not been modified cannot be
-effective; in other words, a missing \fB\-t\fP or \fB\-a\fP will cause the next
-transfer to behave as if it used \fB\-I\fP, causing all files to be updated
-(though rsync's delta-transfer algorithm will make the update fairly
-efficient if the files haven't actually changed, you're much better off
-using \fB\-t\fP).
+effective; in other words, a missing \fB\-t\fP (or \fB\-a\fP) will cause the
+next transfer to behave as if it used \fB\-\-ignore-times\fP (\fB\-I\fP),
+causing all files to be updated (though rsync's delta-transfer algorithm
+will make the update fairly efficient if the files haven't actually
+changed, you're much better off using \fB\-t\fP).
+.IP
+A modern rsync that is using transfer protocol 30 or 31 conveys a modify
+time using up to 8-bytes. If rsync is forced to speak an older protocol
+(perhaps due to the remote rsync being older than 3.0.0) a modify time is
+conveyed using 4-bytes. Prior to 3.2.7, these shorter values could convey
+a date range of 13-Dec-1901 to 19-Jan-2038.  Beginning with 3.2.7, these
+4-byte values now convey a date range of 1-Jan-1970 to 7-Feb-2106.  If you
+have files dated older than 1970, make sure your rsync executables are
+upgraded so that the full range of dates can be conveyed.
 .IP "\fB\-\-atimes\fP, \fB\-U\fP"
 This tells rsync to set the access (use) times of the destination files to
 the same value as the source files.
@@ -1442,8 +1717,8 @@ transferred files without needing to run rsync an extra time after a file
 is transferred.
 .IP
 Note that some older rsync versions (prior to 3.2.0) may have been built
-with a pre-release \fB\-\-atimes\fP patch that does not imply \fB\-\-open-noatime\fP
-when this option is repeated.
+with a pre-release \fB\-\-atimes\fP patch that does not imply
+\fB\-\-open-noatime\fP when this option is repeated.
 .IP "\fB\-\-open-noatime\fP"
 This tells rsync to open files with the O_NOATIME flag (on systems that
 support it) to avoid changing the access time of the files that are being
@@ -1455,33 +1730,27 @@ O_NOATIME flag being set.
 This tells rsync to set the create times (newness) of the destination
 files to the same value as the source files.
 .IP "\fB\-\-omit-dir-times\fP, \fB\-O\fP"
-This tells rsync to omit directories when it is preserving modification
-times (see \fB\-\-times\fP).  If NFS is sharing the directories on the receiving
+This tells rsync to omit directories when it is preserving modification,
+access, and create times.  If NFS is sharing the directories on the receiving
 side, it is a good idea to use \fB\-O\fP.  This option is inferred if you use
 \fB\-\-backup\fP without \fB\-\-backup-dir\fP.
 .IP
-This option also has the side-effect of avoiding early creation of
-directories in incremental recursion copies.  The default \fB\-\-inc-recursive\fP
-copying normally does an early-create pass of all the sub-directories in a
-parent directory in order for it to be able to then set the modify time of
-the parent directory right away (without having to delay that until a bunch
-of recursive copying has finished).  This early-create idiom is not
-necessary if directory modify times are not being preserved, so it is
-skipped.  Since early-create directories don't have accurate mode, mtime,
-or ownership, the use of this option can help when someone wants to avoid
-these partially-finished directories.
+This option also has the side-effect of avoiding early creation of missing
+sub-directories when incremental recursion is enabled, as discussed in the
+\fB\-\-inc-recursive\fP section.
 .IP "\fB\-\-omit-link-times\fP, \fB\-J\fP"
-This tells rsync to omit symlinks when it is preserving modification times
-(see \fB\-\-times\fP).
+This tells rsync to omit symlinks when it is preserving modification,
+access, and create times.
 .IP "\fB\-\-super\fP"
 This tells the receiving side to attempt super-user activities even if the
 receiving rsync wasn't run by the super-user.  These activities include:
-preserving users via the \fB\-\-owner\fP option, preserving all groups (not just
-the current user's groups) via the \fB\-\-groups\fP option, and copying devices
-via the \fB\-\-devices\fP option.  This is useful for systems that allow such
-activities without being the super-user, and also for ensuring that you
-will get errors if the receiving side isn't being run as the super-user.
-To turn off super-user activities, the super-user can use \fB\-\-no-super\fP.
+preserving users via the \fB\-\-owner\fP option, preserving all groups
+(not just the current user's groups) via the \fB\-\-group\fP option, and
+copying devices via the \fB\-\-devices\fP option.  This is useful for
+systems that allow such activities without being the super-user, and also
+for ensuring that you will get errors if the receiving side isn't being run
+as the super-user.  To turn off super-user activities, the super-user can
+use \fB\-\-no-super\fP.
 .IP "\fB\-\-fake-super\fP"
 When this option is enabled, rsync simulates super-user activities by
 saving/restoring the privileged attributes via special extended attributes
@@ -1492,8 +1761,8 @@ that we won't allow to be set on the real file (e.g. the real file gets
 u-s,g-s,o-t for safety) or that would limit the owner's access (since the
 real super-user can always access/change a file, the files we create can
 always be accessed/changed by the creating user).  This option also handles
-ACLs (if \fB\-\-acls\fP was specified) and non-user extended attributes (if
-\fB\-\-xattrs\fP was specified).
+ACLs (if \fB\-\-acls\fP was specified) and non-user extended attributes
+(if \fB\-\-xattrs\fP was specified).
 .IP
 This is a good way to backup data without using a super-user, and to store
 ACLs from incompatible systems.
@@ -1515,14 +1784,15 @@ option just for the source files, combine \fB\-\-fake-super\fP with \fB\-M\-\-su
 .IP
 This option is overridden by both \fB\-\-super\fP and \fB\-\-no-super\fP.
 .IP
-See also the "\fBfake\ super\fP" setting in the daemon's rsyncd.conf file.
+See also the \fBfake\ super\fP setting in the
+daemon's rsyncd.conf file.
 .IP "\fB\-\-sparse\fP, \fB\-S\fP"
 Try to handle sparse files efficiently so they take up less space on the
-destination.  If combined with \fB\-\-inplace\fP the file created might not end
-up with sparse blocks with some combinations of kernel version and/or
-filesystem type.  If \fB\-\-whole-file\fP is in effect (e.g. for a local copy)
-then it will always work because rsync truncates the file prior to writing
-out the updated version.
+destination.  If combined with \fB\-\-inplace\fP the file created might
+not end up with sparse blocks with some combinations of kernel version
+and/or filesystem type.  If \fB\-\-whole-file\fP is in effect (e.g. for a
+local copy) then it will always work because rsync truncates the file prior
+to writing out the updated version.
 .IP
 Note that versions of rsync older than 3.1.3 will reject the combination of
 \fB\-\-sparse\fP and \fB\-\-inplace\fP.
@@ -1538,24 +1808,24 @@ filesystem, but with this option rsync will probably copy more slowly.  If
 the destination is not an extent-supporting filesystem (such as ext4, xfs,
 NTFS, etc.), this option may have no positive effect at all.
 .IP
-If combined with \fB\-\-sparse\fP, the file will only have sparse blocks (as
-opposed to allocated sequences of null bytes) if the kernel version and
+If combined with \fB\-\-sparse\fP, the file will only have sparse blocks
+(as opposed to allocated sequences of null bytes) if the kernel version and
 filesystem type support creating holes in the allocated data.
 .IP "\fB\-\-dry-run\fP, \fB\-n\fP"
 This makes rsync perform a trial run that doesn't make any changes (and
 produces mostly the same output as a real run).  It is most commonly used
-in combination with the \fB\-\-verbose\fP, \fB\-v\fP and/or \fB\-\-itemize-changes\fP, \fB\-i\fP
-options to see what an rsync command is going to do before one actually
-runs it.
-.IP
-The output of \fB\-\-itemize-changes\fP is supposed to be exactly the same on a
-dry run and a subsequent real run (barring intentional trickery and system
-call failures); if it isn't, that's a bug.  Other output should be mostly
-unchanged, but may differ in some areas.  Notably, a dry run does not send
-the actual data for file transfers, so \fB\-\-progress\fP has no effect, the
-"bytes sent", "bytes received", "literal data", and "matched data"
-statistics are too small, and the "speedup" value is equivalent to a run
-where no file transfers were needed.
+in combination with the \fB\-\-verbose\fP (\fB\-v\fP) and/or
+\fB\-\-itemize-changes\fP (\fB\-i\fP) options to see what an rsync command is
+going to do before one actually runs it.
+.IP
+The output of \fB\-\-itemize-changes\fP is supposed to be exactly the
+same on a dry run and a subsequent real run (barring intentional trickery
+and system call failures); if it isn't, that's a bug.  Other output should
+be mostly unchanged, but may differ in some areas.  Notably, a dry run does
+not send the actual data for file transfers, so \fB\-\-progress\fP has no
+effect, the "bytes sent", "bytes received", "literal data", and "matched
+data" statistics are too small, and the "speedup" value is equivalent to a
+run where no file transfers were needed.
 .IP "\fB\-\-whole-file\fP, \fB\-W\fP"
 This option disables rsync's delta-transfer algorithm, which causes all
 transferred files to be sent whole.  The transfer may be faster if this
@@ -1564,6 +1834,13 @@ machines is higher than the bandwidth to disk (especially when the "disk"
 is actually a networked filesystem).  This is the default when both the
 source and destination are specified as local paths, but only if no
 batch-writing option is in effect.
+.IP "\fB\-\-no-whole-file\fP, \fB\-\-no-W\fP"
+Disable whole-file updating when it is enabled by default for a local
+transfer.  This usually slows rsync down, but it can be useful if you are
+trying to minimize the writes to the destination file (if combined with
+\fB\-\-inplace\fP) or for testing the checksum-based update algorithm.
+.IP
+See also the \fB\-\-whole-file\fP option.
 .IP "\fB\-\-checksum-choice=STR\fP, \fB\-\-cc=STR\fP"
 This option overrides the checksum algorithms.  If one algorithm name is
 specified, it is used for both the transfer checksums and (assuming
@@ -1587,6 +1864,8 @@ The checksum options that you may be able to use are:
 .IP o
 \fBmd4\fP
 .IP o
+\fBsha1\fP
+.IP o
 \fBnone\fP
 .RE
 .IP
@@ -1609,14 +1888,14 @@ a value is chosen based on the protocol version (which chooses between MD5
 and various flavors of MD4 based on protocol age).
 .IP
 The default order can be customized by setting the environment variable
-RSYNC_CHECKSUM_LIST to a space-separated list of acceptable checksum names.
-If the string contains a "\fB&\fP" character, it is separated into the "client
-string & server string", otherwise the same string
-applies to both.  If the string (or string portion) contains no
-non-whitespace characters, the default checksum list is used.  This method
-does not allow you to specify the transfer checksum separately from the
-pre-transfer checksum, and it discards "auto" and all unknown checksum
-names.  A list with only invalid names results in a failed negotiation.
+\fBRSYNC_CHECKSUM_LIST\fP to a space-separated list of acceptable checksum
+names.  If the string contains a "\fB&\fP" character, it is separated into the
+"client string & server string", otherwise the same string applies to both.
+If the string (or string portion) contains no non-whitespace characters,
+the default checksum list is used.  This method does not allow you to
+specify the transfer checksum separately from the pre-transfer checksum,
+and it discards "auto" and all unknown checksum names.  A list with only
+invalid names results in a failed negotiation.
 .IP
 The use of the \fB\-\-checksum-choice\fP option overrides this environment list.
 .IP "\fB\-\-one-file-system\fP, \fB\-x\fP"
@@ -1633,34 +1912,40 @@ encounters (using the attributes of the mounted directory because those of
 the underlying mount-point directory are inaccessible).
 .IP
 If rsync has been told to collapse symlinks (via \fB\-\-copy-links\fP or
-\fB\-\-copy-unsafe-links\fP), a symlink to a directory on another device is
-treated like a mount-point.  Symlinks to non-directories are unaffected by
-this option.
-.IP "\fB\-\-existing\fP, \fB\-\-ignore-non-existing\fP"
+\fB\-\-copy-unsafe-links\fP), a symlink to a directory on another device
+is treated like a mount-point.  Symlinks to non-directories are unaffected
+by this option.
+.IP "\fB\-\-ignore-non-existing\fP, \fB\-\-existing\fP"
 This tells rsync to skip creating files (including directories) that do not
 exist yet on the destination.  If this option is combined with the
-\fB\-\-ignore-existing\fP option, no files will be updated (which can be useful
-if all you want to do is delete extraneous files).
+\fB\-\-ignore-existing\fP option, no files will be updated (which can be
+useful if all you want to do is delete extraneous files).
 .IP
-This option is a transfer rule, not an exclude, so it doesn't affect the
-data that goes into the file-lists, and thus it doesn't affect deletions.
-It just limits the files that the receiver requests to be transferred.
+This option is a TRANSFER RULE, so don't expect any
+exclude side effects.
 .IP "\fB\-\-ignore-existing\fP"
 This tells rsync to skip updating files that already exist on the
 destination (this does \fInot\fP ignore existing directories, or nothing would
-get done).  See also \fB\-\-existing\fP.
-.IP
-This option is a transfer rule, not an exclude, so it doesn't affect the
-data that goes into the file-lists, and thus it doesn't affect deletions.
-It just limits the files that the receiver requests to be transferred.
-.IP
-This option can be useful for those doing backups using the \fB\-\-link-dest\fP
-option when they need to continue a backup run that got interrupted.  Since
-a \fB\-\-link-dest\fP run is copied into a new directory hierarchy (when it is
-used properly), using \fB\-\-ignore-existing\fP will ensure that the
-already-handled files don't get tweaked (which avoids a change in
-permissions on the hard-linked files).  This does mean that this option is
-only looking at the existing files in the destination hierarchy itself.
+get done).  See also \fB\-\-ignore-non-existing\fP.
+.IP
+This option is a TRANSFER RULE, so don't expect any
+exclude side effects.
+.IP
+This option can be useful for those doing backups using the
+\fB\-\-link-dest\fP option when they need to continue a backup run that
+got interrupted.  Since a \fB\-\-link-dest\fP run is copied into a new
+directory hierarchy (when it is used properly), using [\fB\-\-ignore-existing\fP
+will ensure that the already-handled files don't get tweaked (which avoids
+a change in permissions on the hard-linked files).  This does mean that
+this option is only looking at the existing files in the destination
+hierarchy itself.
+.IP
+When \fB\-\-info=skip2\fP is used rsync will output "FILENAME exists
+(INFO)" messages where the INFO indicates one of "type change", "sum
+change" (requires \fB\-c\fP), "file change" (based on the quick check),
+"attr change", or "uptodate".  Using \fB\-\-info=skip1\fP (which is also
+implied by 2 \fB\-v\fP options) outputs the exists message without the
+INFO suffix.
 .IP "\fB\-\-remove-source-files\fP"
 This tells rsync to remove from the sending side the files (meaning
 non-directories) that are a part of the transfer and have been successfully
@@ -1674,11 +1959,15 @@ so that rsync can't possibly transfer a file that is not yet fully written.
 If you can't first write the files into a different directory, you should
 use a naming idiom that lets rsync avoid transferring files that are not
 yet finished (e.g. name the file "foo.new" when it is written, rename it to
-"foo" when it is done, and then use the option \fB\-\-exclude='*.new'\fP for the
-rsync transfer).
+"foo" when it is done, and then use the option \fB\-\-exclude='*.new'\fP
+for the rsync transfer).
 .IP
 Starting with 3.1.0, rsync will skip the sender-side removal (and output an
 error) if the file's size or modify time has not stayed unchanged.
+.IP
+Starting with 3.2.6, a local rsync copy will ensure that the sender does
+not remove a file the receiver just verified, such as when the user
+accidentally makes the source and destination directory the same path.
 .IP "\fB\-\-delete\fP"
 This tells rsync to delete extraneous files from the receiving side (ones
 that aren't on the sending side), but only for the directories that are
@@ -1687,18 +1976,18 @@ being synchronized.  You must have asked rsync to send the whole directory
 contents (e.g. "\fBdir/*\fP") since the wildcard is expanded by the shell and
 rsync thus gets a request to transfer individual files, not the files'
 parent directory.  Files that are excluded from the transfer are also
-excluded from being deleted unless you use the \fB\-\-delete-excluded\fP option
-or mark the rules as only matching on the sending side (see the
+excluded from being deleted unless you use the \fB\-\-delete-excluded\fP
+option or mark the rules as only matching on the sending side (see the
 include/exclude modifiers in the FILTER RULES section).
 .IP
-Prior to rsync 2.6.7, this option would have no effect unless \fB\-\-recursive\fP
-was enabled.  Beginning with 2.6.7, deletions will also occur when \fB\-\-dirs\fP
-(\fB\-d\fP) is enabled, but only for directories whose contents are being
-copied.
+Prior to rsync 2.6.7, this option would have no effect unless
+\fB\-\-recursive\fP was enabled.  Beginning with 2.6.7, deletions will
+also occur when \fB\-\-dirs\fP (\fB\-d\fP) is enabled, but only for
+directories whose contents are being copied.
 .IP
 This option can be dangerous if used incorrectly! It is a very good idea to
-first try a run using the \fB\-\-dry-run\fP option (\fB\-n\fP) to see what files are
-going to be deleted.
+first try a run using the \fB\-\-dry-run\fP (\fB\-n\fP) option to see what
+files are going to be deleted.
 .IP
 If the sending side detects any I/O errors, then the deletion of any files
 at the destination will be automatically disabled.  This is to prevent
@@ -1707,15 +1996,15 @@ causing a massive deletion of files on the destination.  You can override
 this with the \fB\-\-ignore-errors\fP option.
 .IP
 The \fB\-\-delete\fP option may be combined with one of the \-\-delete-WHEN options
-without conflict, as well as \fB\-\-delete-excluded\fP.  However, if none of the
-\fB\-\-delete-WHEN\fP options are specified, rsync will choose the
-\fB\-\-delete-during\fP algorithm when talking to rsync 3.0.0 or newer, and the
-\fB\-\-delete-before\fP algorithm when talking to an older rsync.  See also
-\fB\-\-delete-delay\fP and \fB\-\-delete-after\fP.
+without conflict, as well as \fB\-\-delete-excluded\fP.  However, if none
+of the \fB\-\-delete-WHEN\fP options are specified, rsync will choose the
+\fB\-\-delete-during\fP algorithm when talking to rsync 3.0.0 or newer,
+or the \fB\-\-delete-before\fP algorithm when talking to an older rsync.
+See also \fB\-\-delete-delay\fP and \fB\-\-delete-after\fP.
 .IP "\fB\-\-delete-before\fP"
 Request that the file-deletions on the receiving side be done before the
-transfer starts.  See \fB\-\-delete\fP (which is implied) for more details on
-file-deletion.
+transfer starts.  See \fB\-\-delete\fP (which is implied) for more
+details on file-deletion.
 .IP
 Deleting before the transfer is helpful if the filesystem is tight for
 space and removing extraneous files would help to make the transfer
@@ -1728,23 +2017,24 @@ files in the transfer into memory at once (see \fB\-\-recursive\fP).
 Request that the file-deletions on the receiving side be done incrementally
 as the transfer happens.  The per-directory delete scan is done right
 before each directory is checked for updates, so it behaves like a more
-efficient \fB\-\-delete-before\fP, including doing the deletions prior to any
-per-directory filter files being updated.  This option was first added in
-rsync version 2.6.4.  See \fB\-\-delete\fP (which is implied) for more details on
-file-deletion.
+efficient \fB\-\-delete-before\fP, including doing the deletions prior to
+any per-directory filter files being updated.  This option was first added
+in rsync version 2.6.4.  See \fB\-\-delete\fP (which is implied) for more
+details on file-deletion.
 .IP "\fB\-\-delete-delay\fP"
 Request that the file-deletions on the receiving side be computed during
-the transfer (like \fB\-\-delete-during\fP), and then removed after the transfer
-completes.  This is useful when combined with \fB\-\-delay-updates\fP and/or
-\fB\-\-fuzzy\fP, and is more efficient than using \fB\-\-delete-after\fP (but can
-behave differently, since \fB\-\-delete-after\fP computes the deletions in a
-separate pass after all updates are done).  If the number of removed files
-overflows an internal buffer, a temporary file will be created on the
-receiving side to hold the names (it is removed while open, so you
-shouldn't see it during the transfer).  If the creation of the temporary
-file fails, rsync will try to fall back to using \fB\-\-delete-after\fP (which it
-cannot do if \fB\-\-recursive\fP is doing an incremental scan).  See \fB\-\-delete\fP
-(which is implied) for more details on file-deletion.
+the transfer (like \fB\-\-delete-during\fP), and then removed after the
+transfer completes.  This is useful when combined with
+\fB\-\-delay-updates\fP and/or \fB\-\-fuzzy\fP, and is more efficient
+than using \fB\-\-delete-after\fP (but can behave differently, since
+\fB\-\-delete-after\fP computes the deletions in a separate pass after
+all updates are done).  If the number of removed files overflows an
+internal buffer, a temporary file will be created on the receiving side to
+hold the names (it is removed while open, so you shouldn't see it during
+the transfer).  If the creation of the temporary file fails, rsync will try
+to fall back to using \fB\-\-delete-after\fP (which it cannot do if
+\fB\-\-recursive\fP is doing an incremental scan).  See
+\fB\-\-delete\fP (which is implied) for more details on file-deletion.
 .IP "\fB\-\-delete-after\fP"
 Request that the file-deletions on the receiving side be done after the
 transfer has completed.  This is useful if you are sending new
@@ -1752,35 +2042,51 @@ per-directory merge files as a part of the transfer and you want their
 exclusions to take effect for the delete phase of the current transfer.  It
 also forces rsync to use the old, non-incremental recursion algorithm that
 requires rsync to scan all the files in the transfer into memory at once
-(see \fB\-\-recursive\fP). See \fB\-\-delete\fP (which is implied) for more details on
-file-deletion.
+(see \fB\-\-recursive\fP). See \fB\-\-delete\fP (which is implied) for
+more details on file-deletion.
+.IP
+See also the \fB\-\-delete-delay\fP option that might be a faster choice
+for those that just want the deletions to occur at the end of the transfer.
 .IP "\fB\-\-delete-excluded\fP"
-In addition to deleting the files on the receiving side that are not on the
-sending side, this tells rsync to also delete any files on the receiving
-side that are excluded (see \fB\-\-exclude\fP).  See the FILTER RULES section for
-a way to make individual exclusions behave this way on the receiver, and
-for a way to protect files from \fB\-\-delete-excluded\fP.  See \fB\-\-delete\fP (which
-is implied) for more details on file-deletion.
+This option turns any unqualified exclude/include rules into server-side
+rules that do not affect the receiver's deletions.
+.IP
+By default, an exclude or include has both a server-side effect (to "hide"
+and "show" files when building the server's file list) and a receiver-side
+effect (to "protect" and "risk" files when deletions are occurring).  Any
+rule that has no modifier to specify what sides it is executed on will be
+instead treated as if it were a server-side rule only, avoiding any
+"protect" effects of the rules.
+.IP
+A rule can still apply to both sides even with this option specified if the
+rule is given both the sender & receiver modifier letters (e.g., \fB\-f'\-sr\ foo'\fP).  Receiver-side protect/risk rules can also be explicitly specified
+to limit the deletions.  This saves you from having to edit a bunch of
+\fB\-f'\-\ foo'\fP rules into \fB\-f'\-s\ foo'\fP (aka \fB\-f'H\ foo'\fP) rules (not to mention
+the corresponding includes).
+.IP
+See the FILTER RULES section for more information.  See
+\fB\-\-delete\fP (which is implied) for more details on deletion.
 .IP "\fB\-\-ignore-missing-args\fP"
 When rsync is first processing the explicitly requested source files (e.g.
-command-line arguments or \fB\-\-files-from\fP entries), it is normally an error
-if the file cannot be found.  This option suppresses that error, and does
-not try to transfer the file.  This does not affect subsequent
+command-line arguments or \fB\-\-files-from\fP entries), it is normally
+an error if the file cannot be found.  This option suppresses that error,
+and does not try to transfer the file.  This does not affect subsequent
 vanished-file errors if a file was initially found to be present and later
 is no longer there.
 .IP "\fB\-\-delete-missing-args\fP"
-This option takes the behavior of (the implied) \fB\-\-ignore-missing-args\fP
-option a step farther: each missing arg will become a deletion request of
-the corresponding destination file on the receiving side (should it exist).
-If the destination file is a non-empty directory, it will only be
-successfully deleted if \fB\-\-force\fP or \fB\-\-delete\fP are in effect.  Other than
-that, this option is independent of any other type of delete processing.
+This option takes the behavior of the (implied)
+\fB\-\-ignore-missing-args\fP option a step farther: each missing arg
+will become a deletion request of the corresponding destination file on the
+receiving side (should it exist).  If the destination file is a non-empty
+directory, it will only be successfully deleted if \fB\-\-force\fP or
+\fB\-\-delete\fP are in effect.  Other than that, this option is
+independent of any other type of delete processing.
 .IP
 The missing source files are represented by special file-list entries which
 display as a "\fB*missing\fP" entry in the \fB\-\-list-only\fP output.
 .IP "\fB\-\-ignore-errors\fP"
-Tells \fB\-\-delete\fP to go ahead and delete files even when there are I/O
-errors.
+Tells \fB\-\-delete\fP to go ahead and delete files even when there are
+I/O errors.
 .IP "\fB\-\-force\fP"
 This option tells rsync to delete a non-empty directory when it is to be
 replaced by a non-directory.  This is only relevant if deletions are not
@@ -1808,9 +2114,8 @@ specified SIZE.  A numeric value can be suffixed with a string to indicate
 the numeric units or left unqualified to specify bytes.  Feel free to use a
 fractional value along with the units, such as \fB\-\-max-size=1.5m\fP.
 .IP
-This option is a transfer rule, not an exclude, so it doesn't affect the
-data that goes into the file-lists, and thus it doesn't affect deletions.
-It just limits the files that the receiver requests to be transferred.
+This option is a TRANSFER RULE, so don't expect any
+exclude side effects.
 .IP
 The first letter of a units string can be \fBB\fP (bytes), \fBK\fP (kilo), \fBM\fP
 (mega), \fBG\fP (giga), \fBT\fP (tera), or \fBP\fP (peta).  If the string is a single
@@ -1830,7 +2135,7 @@ Note that rsync versions prior to 3.1.0 did not allow \fB\-\-max-size=0\fP.
 .IP "\fB\-\-min-size=SIZE\fP"
 This tells rsync to avoid transferring any file that is smaller than the
 specified SIZE, which can help in not transferring small, junk files.  See
-the \fB\-\-max-size\fP option for a description of SIZE and other information.
+the \fB\-\-max-size\fP option for a description of SIZE and other info.
 .IP
 Note that rsync versions prior to 3.1.0 did not allow \fB\-\-min-size=0\fP.
 .IP "\fB\-\-max-alloc=SIZE\fP"
@@ -1845,16 +2150,17 @@ consume more memory.
 Keep in mind that this is not a limit on the total size of allocated
 memory.  It is a sanity-check value for each individual allocation.
 .IP
-See the \fB\-\-max-size\fP option for a description of how SIZE can be specified.
-The default suffix if none is given is bytes.
+See the \fB\-\-max-size\fP option for a description of how SIZE can be
+specified.  The default suffix if none is given is bytes.
 .IP
 Beginning in 3.2.3, a value of 0 specifies no limit.
 .IP
-You can set a default value using the environment variable RSYNC_MAX_ALLOC
-using the same SIZE values as supported by this option.  If the remote
-rsync doesn't understand the \fB\-\-max-alloc\fP option, you can override an
-environmental value by specifying \fB\-\-max-alloc=1g\fP, which will make rsync
-avoid sending the option to the remote side (because "1G" is the default).
+You can set a default value using the environment variable
+\fBRSYNC_MAX_ALLOC\fP using the same SIZE values as supported by this
+option.  If the remote rsync doesn't understand the \fB\-\-max-alloc\fP option,
+you can override an environmental value by specifying \fB\-\-max-alloc=1g\fP,
+which will make rsync avoid sending the option to the remote side (because
+"1G" is the default).
 .IP "\fB\-\-block-size=SIZE\fP, \fB\-B\fP"
 This forces the block size used in rsync's delta-transfer algorithm to a
 fixed value.  It is normally selected based on the size of each file being
@@ -1872,17 +2178,17 @@ If this option is used with \fB[user@]host::module/path\fP, then the remote
 shell \fICOMMAND\fP will be used to run an rsync daemon on the remote host, and
 all data will be transmitted through that remote shell connection, rather
 than through a direct socket connection to a running rsync daemon on the
-remote host.  See the section "USING RSYNC-DAEMON FEATURES VIA A
-REMOTE-SHELL CONNECTION" above.
-.IP
-Beginning with rsync 3.2.0, the RSYNC_PORT environment variable will be set
-when a daemon connection is being made via a remote-shell connection.  It
-is set to 0 if the default daemon port is being assumed, or it is set to
-the value of the rsync port that was specified via either the \fB\-\-port\fP
-option or a non-empty port value in an rsync:// URL.  This allows the
-script to discern if a non-default port is being requested, allowing for
-things such as an SSL or stunnel helper script to connect to a default or
-alternate port.
+remote host.  See the USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL
+CONNECTION section above.
+.IP
+Beginning with rsync 3.2.0, the \fBRSYNC_PORT\fP environment variable will
+be set when a daemon connection is being made via a remote-shell
+connection.  It is set to 0 if the default daemon port is being assumed, or
+it is set to the value of the rsync port that was specified via either the
+\fB\-\-port\fP option or a non-empty port value in an \fBrsync://\fP URL.
+This allows the script to discern if a non-default port is being requested,
+allowing for things such as an SSL or stunnel helper script to connect to a
+default or alternate port.
 .IP
 Command-line arguments are permitted in COMMAND provided that COMMAND is
 presented to rsync as a single argument.  You must use spaces (not tabs or
@@ -1903,10 +2209,11 @@ quotes rsync is parsing).  Some examples:
 (Note that ssh users can alternately customize site-specific connect
 options in their .ssh/config file.)
 .IP
-You can also choose the remote shell program using the RSYNC_RSH
+You can also choose the remote shell program using the \fBRSYNC_RSH\fP
 environment variable, which accepts the same range of values as \fB\-e\fP.
 .IP
-See also the \fB\-\-blocking-io\fP option which is affected by this option.
+See also the \fB\-\-blocking-io\fP option which is affected by this
+option.
 .IP "\fB\-\-rsync-path=PROGRAM\fP"
 Use this to specify what program is to be run on the remote machine to
 start-up rsync.  Often used when rsync is not in the default remote-shell's
@@ -1926,8 +2233,8 @@ rsync -avR --rsync-path="cd /a/b && rsync" host:c/d /e/
 .IP "\fB\-\-remote-option=OPTION\fP, \fB\-M\fP"
 This option is used for more advanced situations where you want certain
 effects to be limited to one side of the transfer only.  For instance, if
-you want to pass \fB\-\-log-file=FILE\fP and \fB\-\-fake-super\fP to the remote system,
-specify it like this:
+you want to pass \fB\-\-log-file=FILE\fP and \fB\-\-fake-super\fP to
+the remote system, specify it like this:
 .RS 4
 .IP
 .nf
@@ -1949,11 +2256,10 @@ Be cautious using this, as it is possible to toggle an option that will
 cause rsync to have a different idea about what data to expect next over
 the socket, and that will make it fail in a cryptic fashion.
 .IP
-Note that it is best to use a separate \fB\-\-remote-option\fP for each option
-you want to pass.  This makes your usage compatible with the
-\fB\-\-protect-args\fP option.  If that option is off, any spaces in your remote
-options will be split by the remote shell unless you take steps to protect
-them.
+Note that you should use a separate \fB\-M\fP option for each remote option you
+want to pass.  On older rsync versions, the presence of any spaces in the
+remote-option arg could cause it to be split into separate remote args, but
+this requires the use of \fB\-\-old-args\fP in a modern rsync.
 .IP
 When performing a local transfer, the "local" side is the sender and the
 "remote" side is the receiver.
@@ -1969,7 +2275,8 @@ often don't want to transfer between systems.  It uses a similar algorithm
 to CVS to determine if a file should be ignored.
 .IP
 The exclude list is initialized to exclude the following items (these
-initial items are marked as perishable\ \-\- see the FILTER RULES section):
+initial items are marked as perishable\ \-\- see the FILTER RULES
+section):
 .RS 4
 .IP
 \fBRCS\fP
@@ -2019,17 +2326,17 @@ file and matches one of the patterns listed therein.  Unlike rsync's
 filter/exclude files, these patterns are split on whitespace.  See the
 \fBcvs\fP(1) manual for more information.
 .IP
-If you're combining \fB\-C\fP with your own \fB\-\-filter\fP rules, you should note
-that these CVS excludes are appended at the end of your own rules,
+If you're combining \fB\-C\fP with your own \fB\-\-filter\fP rules, you should
+note that these CVS excludes are appended at the end of your own rules,
 regardless of where the \fB\-C\fP was placed on the command-line.  This makes
 them a lower priority than any rules you specified explicitly.  If you want
 to control where these CVS excludes get inserted into your filter rules,
 you should omit the \fB\-C\fP as a command-line option and use a combination of
-\fB\-\-filter=:C\fP and \fB\-\-filter=\-C\fP (either on your command-line or by putting
-the ":C" and "\-C" rules into a filter file with your other rules).  The
-first option turns on the per-directory scanning for the .cvsignore file.
-The second option does a one-time import of the CVS excludes mentioned
-above.
+\fB\-\-filter=:C\fP and \fB\-\-filter=\-C\fP (either on your
+command-line or by putting the ":C" and "\-C" rules into a filter file with
+your other rules).  The first option turns on the per-directory scanning
+for the .cvsignore file.  The second option does a one-time import of the
+CVS excludes mentioned above.
 .IP "\fB\-\-filter=RULE\fP, \fB\-f\fP"
 This option allows you to add rules to selectively exclude certain files
 from the list of files to be transferred.  This is most useful in
@@ -2043,8 +2350,8 @@ replace the space that separates a rule from its arg.
 .IP
 See the FILTER RULES section for detailed information on this option.
 .IP "\fB\-F\fP"
-The \fB\-F\fP option is a shorthand for adding two \fB\-\-filter\fP rules to your
-command.  The first time it is used is a shorthand for this rule:
+The \fB\-F\fP option is a shorthand for adding two \fB\-\-filter\fP rules to
+your command.  The first time it is used is a shorthand for this rule:
 .RS 4
 .IP
 .nf
@@ -2065,30 +2372,48 @@ rule:
 .IP
 This filters out the .rsync-filter files themselves from the transfer.
 .IP
-See the FILTER RULES section for detailed information on how these options
-work.
+See the FILTER RULES section for detailed information on how these
+options work.
 .IP "\fB\-\-exclude=PATTERN\fP"
-This option is a simplified form of the \fB\-\-filter\fP option that defaults to
-an exclude rule and does not allow the full rule-parsing syntax of normal
-filter rules.
+This option is a simplified form of the \fB\-\-filter\fP option that
+specifies an exclude rule and does not allow the full rule-parsing syntax
+of normal filter rules.  This is equivalent to specifying \fB\-f'\-\ PATTERN'\fP.
 .IP
 See the FILTER RULES section for detailed information on this option.
 .IP "\fB\-\-exclude-from=FILE\fP"
-This option is related to the \fB\-\-exclude\fP option, but it specifies a FILE
-that contains exclude patterns (one per line).  Blank lines in the file and
-lines starting with '\fB;\fP' or '\fB#\fP' are ignored.  If \fIFILE\fP is '\fB\-\fP', the
-list will be read from standard input.
+This option is related to the \fB\-\-exclude\fP option, but it specifies
+a FILE that contains exclude patterns (one per line).  Blank lines in the
+file are ignored, as are whole-line comments that start with '\fB;\fP' or '\fB#\fP'
+(filename rules that contain those characters are unaffected).
+.IP
+If a line begins with "\fB\-\ \fP" (dash, space) or "\fB+\ \fP" (plus, space), then
+the type of rule is being explicitly specified as an exclude or an include
+(respectively).  Any rules without such a prefix are taken to be an exclude.
+.IP
+If a line consists of just "\fB!\fP", then the current filter rules are cleared
+before adding any further rules.
+.IP
+If \fIFILE\fP is '\fB\-\fP', the list will be read from standard input.
 .IP "\fB\-\-include=PATTERN\fP"
-This option is a simplified form of the \fB\-\-filter\fP option that defaults to
-an include rule and does not allow the full rule-parsing syntax of normal
-filter rules.
+This option is a simplified form of the \fB\-\-filter\fP option that
+specifies an include rule and does not allow the full rule-parsing syntax
+of normal filter rules.  This is equivalent to specifying \fB\-f'+\ PATTERN'\fP.
 .IP
 See the FILTER RULES section for detailed information on this option.
 .IP "\fB\-\-include-from=FILE\fP"
-This option is related to the \fB\-\-include\fP option, but it specifies a FILE
-that contains include patterns (one per line).  Blank lines in the file and
-lines starting with '\fB;\fP' or '\fB#\fP' are ignored.  If \fIFILE\fP is '\fB\-\fP', the
-list will be read from standard input.
+This option is related to the \fB\-\-include\fP option, but it specifies
+a FILE that contains include patterns (one per line).  Blank lines in the
+file are ignored, as are whole-line comments that start with '\fB;\fP' or '\fB#\fP'
+(filename rules that contain those characters are unaffected).
+.IP
+If a line begins with "\fB\-\ \fP" (dash, space) or "\fB+\ \fP" (plus, space), then
+the type of rule is being explicitly specified as an exclude or an include
+(respectively).  Any rules without such a prefix are taken to be an include.
+.IP
+If a line consists of just "\fB!\fP", then the current filter rules are cleared
+before adding any further rules.
+.IP
+If \fIFILE\fP is '\fB\-\fP', the list will be read from standard input.
 .IP "\fB\-\-files-from=FILE\fP"
 Using this option allows you to specify the exact list of files to transfer
 (as read from the specified FILE or '\fB\-\fP' for standard input).  It also
@@ -2097,16 +2422,16 @@ specified files and directories easier:
 .IP
 .RS
 .IP o
-The \fB\-\-relative\fP (\fB\-R\fP) option is implied, which preserves the path
-information that is specified for each item in the file (use
+The \fB\-\-relative\fP (\fB\-R\fP) option is implied, which preserves the
+path information that is specified for each item in the file (use
 \fB\-\-no-relative\fP or \fB\-\-no-R\fP if you want to turn that off).
 .IP o
-The \fB\-\-dirs\fP (\fB\-d\fP) option is implied, which will create directories
-specified in the list on the destination rather than noisily skipping
-them (use \fB\-\-no-dirs\fP or \fB\-\-no-d\fP if you want to turn that off).
+The \fB\-\-dirs\fP (\fB\-d\fP) option is implied, which will create
+directories specified in the list on the destination rather than noisily
+skipping them (use \fB\-\-no-dirs\fP or \fB\-\-no-d\fP if you want to turn that off).
 .IP o
-The \fB\-\-archive\fP (\fB\-a\fP) option's behavior does not imply \fB\-\-recursive\fP
-(\fB\-r\fP), so specify it explicitly, if you want it.
+The \fB\-\-archive\fP (\fB\-a\fP) option's behavior does not imply
+\fB\-\-recursive\fP (\fB\-r\fP), so specify it explicitly, if you want it.
 .IP o
 These side-effects change the default state of rsync, so the position of
 the \fB\-\-files-from\fP option on the command-line has no bearing on how other
@@ -2128,13 +2453,13 @@ If /tmp/foo contains the string "bin" (or even "/bin"), the /usr/bin
 directory will be created as /backup/bin on the remote host.  If it
 contains "bin/" (note the trailing slash), the immediate contents of the
 directory would also be sent (without needing to be explicitly mentioned in
-the file\ \-\- this began in version 2.6.4).  In both cases, if the \fB\-r\fP
-option was enabled, that dir's entire hierarchy would also be transferred
-(keep in mind that \fB\-r\fP needs to be specified explicitly with
-\fB\-\-files-from\fP, since it is not implied by \fB\-a\fP).  Also note that the
-effect of the (enabled by default) \fB\-\-relative\fP option is to duplicate only
-the path info that is read from the file\ \-\- it does not force the
-duplication of the source-spec path (/usr in this case).
+the file\ \-\- this began in version 2.6.4).  In both cases, if the
+\fB\-r\fP option was enabled, that dir's entire hierarchy would also be
+transferred (keep in mind that \fB\-r\fP needs to be specified
+explicitly with \fB\-\-files-from\fP, since it is not implied by \fB\-a\fP.
+Also note that the effect of the (enabled by default) \fB\-r\fP option
+is to duplicate only the path info that is read from the file\ \-\- it does
+not force the duplication of the source-spec path (/usr in this case).
 .IP
 In addition, the \fB\-\-files-from\fP file can be read from the remote host
 instead of the local host if you specify a "host:" in front of the file
@@ -2151,9 +2476,9 @@ rsync -a --files-from=:/path/file-list src:/ /tmp/copy
 This would copy all the files specified in the /path/file-list file that
 was located on the remote "src" host.
 .IP
-If the \fB\-\-iconv\fP and \fB\-\-protect-args\fP options are specified and the
-\fB\-\-files-from\fP filenames are being sent from one host to another, the
-filenames will be translated from the sending host's charset to the
+If the \fB\-\-iconv\fP and \fB\-\-secluded-args\fP options are specified
+and the \fB\-\-files-from\fP filenames are being sent from one host to another,
+the filenames will be translated from the sending host's charset to the
 receiving host's charset.
 .IP
 NOTE: sorting the list of files in the \fB\-\-files-from\fP input helps rsync to
@@ -2165,38 +2490,121 @@ elements.
 .IP "\fB\-\-from0\fP, \fB\-0\fP"
 This tells rsync that the rules/filenames it reads from a file are
 terminated by a null ('\\0') character, not a NL, CR, or CR+LF.  This
-affects \fB\-\-exclude-from\fP, \fB\-\-include-from\fP, \fB\-\-files-from\fP, and any merged
-files specified in a \fB\-\-filter\fP rule.  It does not affect \fB\-\-cvs-exclude\fP
-(since all names read from a .cvsignore file are split on whitespace).
-.IP "\fB\-\-protect-args\fP, \fB\-s\fP"
-This option sends all filenames and most options to the remote rsync
-without allowing the remote shell to interpret them.  This means that
-spaces are not split in names, and any non-wildcard special characters are
-not translated (such as \fB~\fP, \fB$\fP, \fB;\fP, \fB&\fP, etc.).  Wildcards are expanded
-on the remote host by rsync (instead of the shell doing it).
-.IP
-If you use this option with \fB\-\-iconv\fP, the args related to the remote side
-will also be translated from the local to the remote character-set.  The
-translation happens before wild-cards are expanded.  See also the
+affects \fB\-\-exclude-from\fP, \fB\-\-include-from\fP,
+\fB\-\-files-from\fP, and any merged files specified in a
+\fB\-\-filter\fP rule.  It does not affect \fB\-\-cvs-exclude\fP (since
+all names read from a .cvsignore file are split on whitespace).
+.IP "\fB\-\-old-args\fP"
+This option tells rsync to stop trying to protect the arg values on the
+remote side from unintended word-splitting or other misinterpretation.
+It also allows the client to treat an empty arg as a "." instead of
+generating an error.
+.IP
+The default in a modern rsync is for "shell-active" characters (including
+spaces) to be backslash-escaped in the args that are sent to the remote
+shell.  The wildcard characters \fB*\fP, \fB?\fP, \fB[\fP, & \fB]\fP are not escaped in
+filename args (allowing them to expand into multiple filenames) while being
+protected in option args, such as \fB\-\-usermap\fP.
+.IP
+If you have a script that wants to use old-style arg splitting in its
+filenames, specify this option once.  If the remote shell has a problem
+with any backslash escapes at all, specify this option twice.
+.IP
+You may also control this setting via the \fBRSYNC_OLD_ARGS\fP environment
+variable.  If it has the value "1", rsync will default to a single-option
+setting.  If it has the value "2" (or more), rsync will default to a
+repeated-option setting.  If it is "0", you'll get the default escaping
+behavior.  The environment is always overridden by manually specified
+positive or negative options (the negative is \fB\-\-no-old-args\fP).
+.IP
+Note that this option also disables the extra safety check added in 3.2.5
+that ensures that a remote sender isn't including extra top-level items in
+the file-list that you didn't request.  This side-effect is necessary
+because we can't know for sure what names to expect when the remote shell
+is interpreting the args.
+.IP
+This option conflicts with the \fB\-\-secluded-args\fP option.
+.IP "\fB\-\-secluded-args\fP, \fB\-s\fP"
+This option sends all filenames and most options to the remote rsync via
+the protocol (not the remote shell command line) which avoids letting the
+remote shell modify them.  Wildcards are expanded on the remote host by
+rsync instead of a shell.
+.IP
+This is similar to the default backslash-escaping of args that was added
+in 3.2.4 (see \fB\-\-old-args\fP) in that it prevents things like space
+splitting and unwanted special-character side-effects. However, it has the
+drawbacks of being incompatible with older rsync versions (prior to 3.0.0)
+and of being refused by restricted shells that want to be able to inspect
+all the option values for safety.
+.IP
+This option is useful for those times that you need the argument's
+character set to be converted for the remote host, if the remote shell is
+incompatible with the default backslash-escpaing method, or there is some
+other reason that you want the majority of the options and arguments to
+bypass the command-line of the remote shell.
+.IP
+If you combine this option with \fB\-\-iconv\fP, the args related to the
+remote side will be translated from the local to the remote character-set.
+The translation happens before wild-cards are expanded.  See also the
 \fB\-\-files-from\fP option.
 .IP
-You may also control this option via the RSYNC_PROTECT_ARGS environment
-variable.  If this variable has a non-zero value, this option will be
+You may also control this setting via the \fBRSYNC_PROTECT_ARGS\fP
+environment variable.  If it has a non-zero value, this setting will be
 enabled by default, otherwise it will be disabled by default.  Either state
 is overridden by a manually specified positive or negative version of this
-option (note that \fB\-\-no-s\fP and \fB\-\-no-protect-args\fP are the negative
-versions).  Since this option was first introduced in 3.0.0, you'll need to
-make sure it's disabled if you ever need to interact with a remote rsync
-that is older than that.
-.IP
-Rsync can also be configured (at build time) to have this option enabled by
-default (with is overridden by both the environment and the command-line).
-Run \fBrsync\ \-\-version\fP to check if this is the case, as it will display
-"default protect-args" or "optional protect-args" depending on how it was
-compiled.
-.IP
-This option will eventually become a new default setting at some
-as-yet-undetermined point in the future.
+option (note that \fB\-\-no-s\fP and \fB\-\-no-secluded-args\fP are the negative
+versions).  This environment variable is also superseded by a non-zero
+\fBRSYNC_OLD_ARGS\fP export.
+.IP
+This option conflicts with the \fB\-\-old-args\fP option.
+.IP
+This option used to be called \fB\-\-protect-args\fP (before 3.2.6) and that
+older name can still be used (though specifying it as \fB\-s\fP is always the
+easiest and most compatible choice).
+.IP "\fB\-\-trust-sender\fP"
+This option disables two extra validation checks that a local client
+performs on the file list generated by a remote sender.  This option should
+only be used if you trust the sender to not put something malicious in the
+file list (something that could possibly be done via a modified rsync, a
+modified shell, or some other similar manipulation).
+.IP
+Normally, the rsync client (as of version 3.2.5) runs two extra validation
+checks when pulling files from a remote rsync:
+.IP
+.RS
+.IP o
+It verifies that additional arg items didn't get added at the top of the
+transfer.
+.IP o
+It verifies that none of the items in the file list are names that should
+have been excluded (if filter rules were specified).
+.RE
+.IP
+Note that various options can turn off one or both of these checks if the
+option interferes with the validation.  For instance:
+.IP
+.RS
+.IP o
+Using a per-directory filter file reads filter rules that only the server
+knows about, so the filter checking is disabled.
+.IP o
+Using the \fB\-\-old-args\fP option allows the sender to manipulate the
+requested args, so the arg checking is disabled.
+.IP o
+Reading the files-from list from the server side means that the client
+doesn't know the arg list, so the arg checking is disabled.
+.IP o
+Using \fB\-\-read-batch\fP disables both checks since the batch file's
+contents will have been verified when it was created.
+.RE
+.IP
+This option may help an under-powered client server if the extra pattern
+matching is slowing things down on a huge transfer.  It can also be used to
+work around a currently-unknown bug in the verification logic for a transfer
+from a trusted sender.
+.IP
+When using this option it is a good idea to specify a dedicated destination
+directory, as discussed in the MULTI-HOST SECURITY section.
 .IP "\fB\-\-copy-as=USER[:GROUP]\fP"
 This option instructs rsync to use the USER and (if specified after a
 colon) the GROUP for the copy operations.  This only works if the user that
@@ -2212,14 +2620,14 @@ to be used, so this allows rsync to drop root for the copying part of the
 operation after the remote-shell or daemon connection is established.
 .IP
 The option only affects one side of the transfer unless the transfer is
-local, in which case it affects both sides.  Use the \fB\-\-remote-option\fP to
-affect the remote side, such as \fB\-M\-\-copy-as=joe\fP.  For a local transfer,
-the lsh (or lsh.sh) support file provides a local-shell helper script that
-can be used to allow a "localhost:" or "lh:" host-spec to be specified
-without needing to setup any remote shells, allowing you to specify remote
-options that affect the side of the transfer that is using the host-spec
-(and using hostname "lh" avoids the overriding of the remote directory to
-the user's home dir).
+local, in which case it affects both sides.  Use the
+\fB\-\-remote-option\fP to affect the remote side, such as
+\fB\-M\-\-copy-as=joe\fP.  For a local transfer, the lsh (or lsh.sh) support file
+provides a local-shell helper script that can be used to allow a
+"localhost:" or "lh:" host-spec to be specified without needing to setup
+any remote shells, allowing you to specify remote options that affect the
+side of the transfer that is using the host-spec (and using hostname "lh"
+avoids the overriding of the remote directory to the user's home dir).
 .IP
 For example, the following rsync writes the local files as user "joe":
 .RS 4
@@ -2265,17 +2673,17 @@ someone had it open), and thus there might not be enough room to fit the
 new version on the disk at the same time.
 .IP
 If you are using this option for reasons other than a shortage of disk
-space, you may wish to combine it with the \fB\-\-delay-updates\fP option, which
-will ensure that all copied files get put into subdirectories in the
-destination hierarchy, awaiting the end of the transfer.  If you don't have
-enough room to duplicate all the arriving files on the destination
-partition, another way to tell rsync that you aren't overly concerned about
-disk space is to use the \fB\-\-partial-dir\fP option with a relative path;
-because this tells rsync that it is OK to stash off a copy of a single file
-in a subdir in the destination hierarchy, rsync will use the partial-dir as
-a staging area to bring over the copied file, and then rename it into place
-from there. (Specifying a \fB\-\-partial-dir\fP with an absolute path does not
-have this side-effect.)
+space, you may wish to combine it with the \fB\-\-delay-updates\fP
+option, which will ensure that all copied files get put into subdirectories
+in the destination hierarchy, awaiting the end of the transfer.  If you
+don't have enough room to duplicate all the arriving files on the
+destination partition, another way to tell rsync that you aren't overly
+concerned about disk space is to use the \fB\-\-partial-dir\fP option
+with a relative path; because this tells rsync that it is OK to stash off a
+copy of a single file in a subdir in the destination hierarchy, rsync will
+use the partial-dir as a staging area to bring over the copied file, and
+then rename it into place from there. (Specifying a \fB\-\-partial-dir\fP
+with an absolute path does not have this side-effect.)
 .IP "\fB\-\-fuzzy\fP, \fB\-y\fP"
 This option tells rsync that it should look for a basis file for any
 destination file that is missing.  The current algorithm looks in the same
@@ -2284,12 +2692,12 @@ size and modified-time, or a similarly-named file.  If found, rsync uses
 the fuzzy basis file to try to speed up the transfer.
 .IP
 If the option is repeated, the fuzzy scan will also be done in any matching
-alternate destination directories that are specified via \fB\-\-compare-dest\fP,
-\fB\-\-copy-dest\fP, or \fB\-\-link-dest\fP.
+alternate destination directories that are specified via
+\fB\-\-compare-dest\fP, \fB\-\-copy-dest\fP, or \fB\-\-link-dest\fP.
 .IP
-Note that the use of the \fB\-\-delete\fP option might get rid of any potential
-fuzzy-match files, so either use \fB\-\-delete-after\fP or specify some filename
-exclusions if you need to prevent this.
+Note that the use of the \fB\-\-delete\fP option might get rid of any
+potential fuzzy-match files, so either use \fB\-\-delete-after\fP or
+specify some filename exclusions if you need to prevent this.
 .IP "\fB\-\-compare-dest=DIR\fP"
 This option instructs rsync to use \fIDIR\fP on the destination machine as an
 additional hierarchy to compare destination files against doing transfers
@@ -2329,10 +2737,10 @@ try to speed up the transfer.
 If \fIDIR\fP is a relative path, it is relative to the destination directory.
 See also \fB\-\-compare-dest\fP and \fB\-\-link-dest\fP.
 .IP "\fB\-\-link-dest=DIR\fP"
-This option behaves like \fB\-\-copy-dest\fP, but unchanged files are hard linked
-from \fIDIR\fP to the destination directory.  The files must be identical in
-all preserved attributes (e.g. permissions, possibly ownership) in order
-for the files to be linked together.  An example:
+This option behaves like \fB\-\-copy-dest\fP, but unchanged files are
+hard linked from \fIDIR\fP to the destination directory.  The files must be
+identical in all preserved attributes (e.g. permissions, possibly
+ownership) in order for the files to be linked together.  An example:
 .RS 4
 .IP
 .nf
@@ -2340,7 +2748,7 @@ rsync -av --link-dest=$PWD/prior_dir host:src_dir/ new_dir/
 .fi
 .RE
 .IP
-If file's aren't linking, double-check their attributes.  Also check if
+If files aren't linking, double-check their attributes.  Also check if
 some attributes are getting forced outside of rsync's control, such a mount
 option that squishes root to a single user, or mounts a removable drive
 with generic ownership (such as OS X's "Ignore ownership on this volume"
@@ -2369,16 +2777,18 @@ If \fIDIR\fP is a relative path, it is relative to the destination directory.
 See also \fB\-\-compare-dest\fP and \fB\-\-copy-dest\fP.
 .IP
 Note that rsync versions prior to 2.6.1 had a bug that could prevent
-\fB\-\-link-dest\fP from working properly for a non-super-user when \fB\-o\fP was
-specified (or implied by \fB\-a\fP).  You can work-around this bug by avoiding
-the \fB\-o\fP option when sending to an old rsync.
+\fB\-\-link-dest\fP from working properly for a non-super-user when
+\fB\-\-owner\fP (\fB\-o\fP) was specified (or implied).  You can work-around
+this bug by avoiding the \fB\-o\fP option (or using \fB\-\-no-o\fP) when sending to an
+old rsync.
 .IP "\fB\-\-compress\fP, \fB\-z\fP"
 With this option, rsync compresses the file data as it is sent to the
 destination machine, which reduces the amount of data being transmitted\ \-\-
 something that is useful over a slow connection.
 .IP
 Rsync supports multiple compression methods and will choose one for you
-unless you force the choice using the \fB\-\-compress-choice\fP (\fB\-\-zc\fP) option.
+unless you force the choice using the \fB\-\-compress-choice\fP (\fB\-\-zc\fP)
+option.
 .IP
 Run \fBrsync\ \-\-version\fP to see the default compress list compiled into your
 version.
@@ -2390,10 +2800,10 @@ an error.  If the remote rsync is too old to support checksum negotiation,
 its list is assumed to be "zlib".
 .IP
 The default order can be customized by setting the environment variable
-RSYNC_COMPRESS_LIST to a space-separated list of acceptable compression
-names.  If the string contains a "\fB&\fP" character, it is separated into the
-"client string & server string", otherwise the same string applies to both.
-If the string (or string portion) contains no
+\fBRSYNC_COMPRESS_LIST\fP to a space-separated list of acceptable
+compression names.  If the string contains a "\fB&\fP" character, it is
+separated into the "client string & server string", otherwise the same
+string applies to both.  If the string (or string portion) contains no
 non-whitespace characters, the default compress list is used.  Any unknown
 compression names are discarded from the list, but a list with only invalid
 names results in a failed negotiation.
@@ -2403,14 +2813,11 @@ option and require the use of \fB\-zz\fP because their compression library was
 not compatible with the default zlib compression method.  You can usually
 ignore this weirdness unless the rsync server complains and tells you to
 specify \fB\-zz\fP.
-.IP
-See also the \fB\-\-skip-compress\fP option for the default list of file suffixes
-that will be transferred with no (or minimal) compression.
 .IP "\fB\-\-compress-choice=STR\fP, \fB\-\-zc=STR\fP"
 This option can be used to override the automatic negotiation of the
-compression algorithm that occurs when \fB\-\-compress\fP is used.  The option
-implies \fB\-\-compress\fP unless "none" was specified, which instead implies
-\fB\-\-no-compress\fP.
+compression algorithm that occurs when \fB\-\-compress\fP is used.  The
+option implies \fB\-\-compress\fP unless "none" was specified, which
+instead implies \fB\-\-no-compress\fP.
 .IP
 The compression options that you may be able to use are:
 .IP
@@ -2440,16 +2847,17 @@ Note that the "zlibx" compression algorithm is just the "zlib" algorithm
 with matched data excluded from the compression stream (to try to make it
 more compatible with an external zlib implementation).
 .IP "\fB\-\-compress-level=NUM\fP, \fB\-\-zl=NUM\fP"
-Explicitly set the compression level to use (see \fB\-\-compress\fP, \fB\-z\fP)
-instead of letting it default.  The \fB\-\-compress\fP option is implied as long
-as the level chosen is not a "don't compress" level for the compression
-algorithm that is in effect (e.g. zlib compression treats level 0 as
-"off").
+Explicitly set the compression level to use (see \fB\-\-compress\fP,
+\fB\-z\fP) instead of letting it default.  The \fB\-\-compress\fP option is
+implied as long as the level chosen is not a "don't compress" level for the
+compression algorithm that is in effect (e.g. zlib compression treats level
+0 as "off").
 .IP
 The level values vary depending on the checksum in effect.  Because rsync
 will negotiate a checksum choice by default (when the remote rsync is new
-enough), it can be good to combine this option with a \fB\-\-compress-choice\fP
-(\fB\-\-zc\fP) option unless you're sure of the choice in effect.  For example:
+enough), it can be good to combine this option with a
+\fB\-\-compress-choice\fP (\fB\-\-zc\fP) option unless you're sure of the
+choice in effect.  For example:
 .RS 4
 .IP
 .nf
@@ -2458,8 +2866,8 @@ rsync -aiv --zc=zstd --zl=22 host:src/ dest/
 .RE
 .IP
 For zlib & zlibx compression the valid values are from 1 to 9 with 6 being
-the default.  Specifying 0 turns compression off, and specifying \-1 chooses
-the default of 6.
+the default.  Specifying \fB\-\-zl=0\fP turns compression off, and specifying
+\fB\-\-zl=\-1\fP chooses the default level of 6.
 .IP
 For zstd compression the valid values are from \-131072 to 22 with 3 being
 the default. Specifying 0 chooses the default of 3.
@@ -2472,18 +2880,19 @@ limited to a valid value.  This allows you to specify something like
 compression level no matter what algorithm was chosen.
 .IP
 If you want to know the compression level that is in effect, specify
-\fB\-\-debug=nstr\fP to see the "negotiated string" results.  This will report
-something like "\fBClient\ compress:\ zstd\ (level\ 3)\fP" (along with the checksum
-choice in effect).
+\fB\-\-debug=nstr\fP to see the "negotiated string" results.  This will
+report something like "\fBClient\ compress:\ zstd\ (level\ 3)\fP" (along with the
+checksum choice in effect).
 .IP "\fB\-\-skip-compress=LIST\fP"
+\fBNOTE:\fP no compression method currently supports per-file compression
+changes, so this option has no effect.
+.IP
 Override the list of file suffixes that will be compressed as little as
 possible.  Rsync sets the compression level on a per-file basis based on
-the file's suffix.  If the compression algorithm has an "off" level (such
-as zlib/zlibx) then no compression occurs for those files.  Other
-algorithms that support changing the streaming level on-the-fly will have
-the level minimized to reduces the CPU usage as much as possible for a
-matching file.  At this time, only zlib & zlibx compression support this
-changing of levels on a per-file basis.
+the file's suffix.  If the compression algorithm has an "off" level, then
+no compression occurs for those files.  Other algorithms that support
+changing the streaming level on-the-fly will have the level minimized to
+reduces the CPU usage as much as possible for a matching file.
 .IP
 The \fBLIST\fP should be one or more file suffixes (without the dot) separated
 by slashes (\fB/\fP).  You may specify an empty string to indicate that no files
@@ -2621,10 +3030,10 @@ specified.
 .IP
 If a user or group has no name on the source system or it has no match on
 the destination system, then the numeric ID from the source system is used
-instead.  See also the comments on the "\fBuse\ chroot\fP" setting in the
-rsyncd.conf manpage for information on how the chroot setting affects
-rsync's ability to look up the names of the users and groups and what you
-can do about it.
+instead.  See also the \fBuse\ chroot\fP setting
+in the rsyncd.conf manpage for some comments on how the chroot setting
+affects rsync's ability to look up the names of the users and groups and
+what you can do about it.
 .IP "\fB\-\-usermap=STRING\fP, \fB\-\-groupmap=STRING\fP"
 These options allow you to specify users and groups that should be mapped
 to other values by the receiving side.  The \fBSTRING\fP is one or more
@@ -2668,24 +3077,32 @@ names, so all the IDs are treated as having an empty name.  This means that
 you will need to specify numeric \fBFROM\fP values if you want to map these
 nameless IDs to different values.
 .IP
-For the \fB\-\-usermap\fP option to have any effect, the \fB\-o\fP (\fB\-\-owner\fP) option
-must be used (or implied), and the receiver will need to be running as a
-super-user (see also the \fB\-\-fake-super\fP option).  For the \fB\-\-groupmap\fP
-option to have any effect, the \fB\-g\fP (\fB\-\-groups\fP) option must be used (or
-implied), and the receiver will need to have permissions to set that group.
+For the \fB\-\-usermap\fP option to work, the receiver will need to be running as
+a super-user (see also the \fB\-\-super\fP and \fB\-\-fake-super\fP
+options).  For the \fB\-\-groupmap\fP option to work, the receiver will need to
+have permissions to set that group.
+.IP
+Starting with rsync 3.2.4, the \fB\-\-usermap\fP option implies the
+\fB\-\-owner\fP (\fB\-o\fP) option while the \fB\-\-groupmap\fP option implies the
+\fB\-\-group\fP (\fB\-g\fP) option (since rsync needs to have those options
+enabled for the mapping options to work).
 .IP
-If your shell complains about the wildcards, use \fB\-\-protect-args\fP (\fB\-s\fP).
+An older rsync client may need to use \fB\-s\fP to avoid a complaint
+about wildcard characters, but a modern rsync handles this automatically.
 .IP "\fB\-\-chown=USER:GROUP\fP"
 This option forces all files to be owned by USER with group GROUP.  This is
-a simpler interface than using \fB\-\-usermap\fP and \fB\-\-groupmap\fP directly, but
-it is implemented using those options internally, so you cannot mix them.
-If either the USER or GROUP is empty, no mapping for the omitted user/group
-will occur.  If GROUP is empty, the trailing colon may be omitted, but if
-USER is empty, a leading colon must be supplied.
+a simpler interface than using \fB\-\-usermap\fP & \fB\-\-groupmap\fP
+directly, but it is implemented using those options internally so they
+cannot be mixed.  If either the USER or GROUP is empty, no mapping for the
+omitted user/group will occur.  If GROUP is empty, the trailing colon may
+be omitted, but if USER is empty, a leading colon must be supplied.
 .IP
 If you specify "\fB\-\-chown=foo:bar\fP", this is exactly the same as specifying
-"\fB\-\-usermap=*:foo\ \-\-groupmap=*:bar\fP", only easier.  If your shell complains
-about the wildcards, use \fB\-\-protect-args\fP (\fB\-s\fP).
+"\fB\-\-usermap=*:foo\ \-\-groupmap=*:bar\fP", only easier (and with the same
+implied \fB\-\-owner\fP and/or \fB\-\-group\fP options).
+.IP
+An older rsync client may need to use \fB\-s\fP to avoid a complaint
+about wildcard characters, but a modern rsync handles this automatically.
 .IP "\fB\-\-timeout=SECONDS\fP"
 This option allows you to set a maximum I/O timeout in seconds.  If no data
 is transferred for the specified time then rsync will exit.  The default is
@@ -2697,23 +3114,25 @@ rsync exits with an error.
 .IP "\fB\-\-address=ADDRESS\fP"
 By default rsync will bind to the wildcard address when connecting to an
 rsync daemon.  The \fB\-\-address\fP option allows you to specify a specific IP
-address (or hostname) to bind to.  See also this option in the \fB\-\-daemon\fP
-mode section.
+address (or hostname) to bind to.
+.IP
+See also the daemon version of the \fB\-\-address\fP option.
 .IP "\fB\-\-port=PORT\fP"
 This specifies an alternate TCP port number to use rather than the default
 of 873.  This is only needed if you are using the double-colon (::) syntax
 to connect with an rsync daemon (since the URL syntax has a way to specify
-the port as a part of the URL).  See also this option in the \fB\-\-daemon\fP
-mode section.
+the port as a part of the URL).
+.IP
+See also the daemon version of the \fB\-\-port\fP option.
 .IP "\fB\-\-sockopts=OPTIONS\fP"
 This option can provide endless fun for people who like to tune their
 systems to the utmost degree.  You can set all sorts of socket options
-which may make transfers faster (or slower!).  Read the man page for the
+which may make transfers faster (or slower!).  Read the manpage for the
 \fBsetsockopt()\fP system call for details on some of the options you may be
 able to set.  By default no special socket options are set.  This only
 affects direct socket connections to a remote rsync daemon.
 .IP
-This option also exists in the \fB\-\-daemon\fP mode section.
+See also the daemon version of the \fB\-\-sockopts\fP option.
 .IP "\fB\-\-blocking-io\fP"
 This tells rsync to use blocking I/O when launching a remote shell
 transport.  If the remote shell is either rsh or remsh, rsync defaults to
@@ -2729,10 +3148,10 @@ when rsync's output is going to a file or pipe.
 .IP "\fB\-\-itemize-changes\fP, \fB\-i\fP"
 Requests a simple itemized list of the changes that are being made to each
 file, including attribute changes.  This is exactly the same as specifying
-\fB\-\-out-format='%i\ %n%L'\fP.  If you repeat the option, unchanged files will
-also be output, but only if the receiving rsync is at least version 2.6.7
-(you can use \fB\-vv\fP with older versions of rsync, but that also turns on the
-output of other verbose messages).
+\fB\-\-out-format='%i\ %n%L'\fP.  If you repeat the option, unchanged
+files will also be output, but only if the receiving rsync is at least
+version 2.6.7 (you can use \fB\-vv\fP with older versions of rsync, but that
+also turns on the output of other verbose messages).
 .IP
 The "%i" escape has a cryptic output that is 11 letters long.  The general
 format is like the string \fBYXcstpoguax\fP, where \fBY\fP is replaced by the type
@@ -2786,21 +3205,22 @@ The attribute that is associated with each letter is as follows:
 .RS
 .IP o
 A \fBc\fP means either that a regular file has a different checksum (requires
-\fB\-\-checksum\fP) or that a symlink, device, or special file has a changed
-value.  Note that if you are sending files to an rsync prior to 3.0.1,
-this change flag will be present only for checksum-differing regular
-files.
+\fB\-\-checksum\fP) or that a symlink, device, or special file has a
+changed value.  Note that if you are sending files to an rsync prior to
+3.0.1, this change flag will be present only for checksum-differing
+regular files.
 .IP o
 A \fBs\fP means the size of a regular file is different and will be updated
 by the file transfer.
 .IP o
 A \fBt\fP means the modification time is different and is being updated to
-the sender's value (requires \fB\-\-times\fP).  An alternate value of \fBT\fP means
-that the modification time will be set to the transfer time, which
-happens when a file/symlink/device is updated without \fB\-\-times\fP and when
-a symlink is changed and the receiver can't set its time. (Note: when
-using an rsync 3.0.0 client, you might see the \fBs\fP flag combined with \fBt\fP
-instead of the proper \fBT\fP flag for this time-setting failure.)
+the sender's value (requires \fB\-\-times\fP).  An alternate value of
+\fBT\fP means that the modification time will be set to the transfer time,
+which happens when a file/symlink/device is updated without
+\fB\-\-times\fP and when a symlink is changed and the receiver can't
+set its time. (Note: when using an rsync 3.0.0 client, you might see the
+\fBs\fP flag combined with \fBt\fP instead of the proper \fBT\fP flag for this
+time-setting failure.)
 .IP o
 A \fBp\fP means the permissions are different and are being updated to the
 sender's value (requires \fB\-\-perms\fP).
@@ -2811,11 +3231,19 @@ value (requires \fB\-\-owner\fP and super-user privileges).
 A \fBg\fP means the group is different and is being updated to the sender's
 value (requires \fB\-\-group\fP and the authority to set the group).
 .IP o
-A \fBu\fP|\fBn\fP|\fBb\fP indicates the following information: \fBu\fP  means the access
-(use) time is different and is being updated to the sender's value
-(requires \fB\-\-atimes\fP); \fBn\fP means the create time (newness) is different
-and is being updated to the sender's value (requires \fB\-\-crtimes\fP); \fBb\fP
-means that both the access and create times are being updated.
+.IP
+.RS
+.IP o
+A \fBu\fP|\fBn\fP|\fBb\fP indicates the following information:
+
+\fBu\fP  means the access (use) time is different and is being updated to
+the sender's value (requires \fB\-\-atimes\fP)
+.IP o
+\fBn\fP means the create time (newness) is different and is being updated
+to the sender's value (requires \fB\-\-crtimes\fP)
+.IP o
+\fBb\fP means that both the access and create times are being updated
+.RE
 .IP o
 The \fBa\fP means that the ACL information is being changed.
 .IP o
@@ -2830,35 +3258,35 @@ outputting them as a verbose message).
 This allows you to specify exactly what the rsync client outputs to the
 user on a per-update basis.  The format is a text string containing
 embedded single-character escape sequences prefixed with a percent (%)
-character.  A default format of "%n%L" is assumed if either \fB\-\-info=name\fP
-or \fB\-v\fP is specified (this tells you just the name of the file and, if the
-item is a link, where it points).  For a full list of the possible escape
-characters, see the "\fBlog\ format\fP" setting in the rsyncd.conf manpage.
-.IP
-Specifying the \fB\-\-out-format\fP option implies the \fB\-\-info=name\fP option,
-which will mention each file, dir, etc. that gets updated in a significant
-way (a transferred file, a recreated symlink/device, or a touched
-directory).  In addition, if the itemize-changes escape (%i) is included in
-the string (e.g. if the \fB\-\-itemize-changes\fP option was used), the logging
-of names increases to mention any item that is changed in any way (as long
-as the receiving side is at least 2.6.4).  See the \fB\-\-itemize-changes\fP
-option for a description of the output of "%i".
+character.  A default format of "%n%L" is assumed if either
+\fB\-\-info=name\fP or \fB\-v\fP is specified (this tells you just the
+name of the file and, if the item is a link, where it points).  For a full
+list of the possible escape characters, see the \fBlog\ format\fP setting in the rsyncd.conf manpage.
+.IP
+Specifying the \fB\-\-out-format\fP option implies the \fB\-\-info=name\fP
+option, which will mention each file, dir, etc. that gets updated in a
+significant way (a transferred file, a recreated symlink/device, or a
+touched directory).  In addition, if the itemize-changes escape (%i) is
+included in the string (e.g. if the \fB\-\-itemize-changes\fP option was
+used), the logging of names increases to mention any item that is changed
+in any way (as long as the receiving side is at least 2.6.4).  See the
+\fB\-\-itemize-changes\fP option for a description of the output of "%i".
 .IP
 Rsync will output the out-format string prior to a file's transfer unless
 one of the transfer-statistic escapes is requested, in which case the
 logging is done at the end of the file's transfer.  When this late logging
-is in effect and \fB\-\-progress\fP is also specified, rsync will also output the
-name of the file being transferred prior to its progress information
-(followed, of course, by the out-format output).
+is in effect and \fB\-\-progress\fP is also specified, rsync will also
+output the name of the file being transferred prior to its progress
+information (followed, of course, by the out-format output).
 .IP "\fB\-\-log-file=FILE\fP"
 This option causes rsync to log what it is doing to a file.  This is
 similar to the logging that a daemon does, but can be requested for the
 client side and/or the server side of a non-daemon transfer.  If specified
 as a client option, transfer logging will be enabled with a default format
-of "%i %n%L".  See the \fB\-\-log-file-format\fP option if you wish to override
-this.
+of "%i %n%L".  See the \fB\-\-log-file-format\fP option if you wish to
+override this.
 .IP
-Here's a example command that requests the remote side to log what is
+Here's an example command that requests the remote side to log what is
 happening:
 .RS 4
 .IP
@@ -2869,21 +3297,27 @@ rsync -av --remote-option=--log-file=/tmp/rlog src/ dest/
 .IP
 This is very useful if you need to debug why a connection is closing
 unexpectedly.
+.IP
+See also the daemon version of the \fB\-\-log-file\fP option.
 .IP "\fB\-\-log-file-format=FORMAT\fP"
 This allows you to specify exactly what per-update logging is put into the
-file specified by the \fB\-\-log-file\fP option (which must also be specified for
-this option to have any effect).  If you specify an empty string, updated
-files will not be mentioned in the log file.  For a list of the possible
-escape characters, see the "\fBlog\ format\fP" setting in the rsyncd.conf manpage.
+file specified by the \fB\-\-log-file\fP option (which must also be
+specified for this option to have any effect).  If you specify an empty
+string, updated files will not be mentioned in the log file.  For a list of
+the possible escape characters, see the \fBlog\ format\fP
+setting in the rsyncd.conf manpage.
+.IP
+The default FORMAT used if \fB\-\-log-file\fP is specified and this
+option is not is '%i %n%L'.
 .IP
-The default FORMAT used if \fB\-\-log-file\fP is specified and this option is not
-is '%i %n%L'.
+See also the daemon version of the \fB\-\-log-file-format\fP
+option.
 .IP "\fB\-\-stats\fP"
 This tells rsync to print a verbose set of statistics on the file transfer,
 allowing you to tell how effective rsync's delta-transfer algorithm is for
-your data.  This option is equivalent to \fB\-\-info=stats2\fP if combined with 0
-or 1 \fB\-v\fP options, or \fB\-\-info=stats3\fP if combined with 2 or more \fB\-v\fP
-options.
+your data.  This option is equivalent to \fB\-\-info=stats2\fP if
+combined with 0 or 1 \fB\-v\fP options, or \fB\-\-info=stats3\fP if
+combined with 2 or more \fB\-v\fP options.
 .IP
 The current statistics are as follows:
 .IP
@@ -2901,7 +3335,7 @@ sense) were created (as opposed to updated).  The total count will be
 followed by a list of counts by filetype (if the total is non-zero).
 .IP o
 \fBNumber\ of\ deleted\ files\fP is the count of how many "files" (generic
-sense) were created (as opposed to updated).  The total count will be
+sense) were deleted.  The total count will be
 followed by a list of counts by filetype (if the total is non-zero).
 Note that this line is only output if deletions are in effect, and only
 if protocol 31 is being used (the default for rsync 3.1.x).
@@ -2955,12 +3389,19 @@ The escape idiom that started in 2.6.7 is to output a literal backslash
 newline would output as "\fB\\#012\fP".  A literal backslash that is in a
 filename is not escaped unless it is followed by a hash and 3 digits (0-9).
 .IP "\fB\-\-human-readable\fP, \fB\-h\fP"
-Output numbers in a more human-readable format.  There are 3 possible
-levels: (1) output numbers with a separator between each set of 3 digits
-(either a comma or a period, depending on if the decimal point is
-represented by a period or a comma); (2) output numbers in units of 1000
-(with a character suffix for larger units\ \-\- see below); (3) output
-numbers in units of 1024.
+Output numbers in a more human-readable format.  There are 3 possible levels:
+.RS
+.IP
+.IP 1.
+output numbers with a separator between each set of 3 digits (either a
+comma or a period, depending on if the decimal point is represented by a
+period or a comma).
+.IP 2.
+output numbers in units of 1000 (with a character suffix for larger
+units\ \-\- see below).
+.IP 3.
+output numbers in units of 1024.
+.RE
 .IP
 The default is human-readable level 1.  Each \fB\-h\fP option increases the
 level by one.  You can take the level down to 0 (to output numbers as pure
@@ -2984,56 +3425,72 @@ keep partially transferred files.  Using the \fB\-\-partial\fP option tells rsyn
 to keep the partial file which should make a subsequent transfer of the
 rest of the file much faster.
 .IP "\fB\-\-partial-dir=DIR\fP"
-A better way to keep partial files than the \fB\-\-partial\fP option is to
-specify a \fIDIR\fP that will be used to hold the partial data (instead of
-writing it out to the destination file).  On the next transfer, rsync will
-use a file found in this dir as data to speed up the resumption of the
+This option modifies the behavior of the \fB\-\-partial\fP option while
+also implying that it be enabled.  This enhanced partial-file method puts
+any partially transferred files into the specified \fIDIR\fP instead of writing
+the partial file out to the destination file.  On the next transfer, rsync
+will use a file found in this dir as data to speed up the resumption of the
 transfer and then delete it after it has served its purpose.
 .IP
-Note that if \fB\-\-whole-file\fP is specified (or implied), any partial-dir file
-that is found for a file that is being updated will simply be removed
-(since rsync is sending files without using rsync's delta-transfer
-algorithm).
+Note that if \fB\-\-whole-file\fP is specified (or implied), any
+partial-dir files that are found for a file that is being updated will
+simply be removed (since rsync is sending files without using rsync's
+delta-transfer algorithm).
 .IP
-Rsync will create the \fIDIR\fP if it is missing (just the last dir\ \-\- not the
-whole path).  This makes it easy to use a relative path (such as
+Rsync will create the \fIDIR\fP if it is missing, but just the last dir\ \-\- not
+the whole path.  This makes it easy to use a relative path (such as
 "\fB\-\-partial-dir=.rsync-partial\fP") to have rsync create the
-partial-directory in the destination file's directory when needed, and then
-remove it again when the partial file is deleted.  Note that the directory
-is only removed if it is a relative pathname, as it is expected that an
-absolute path is to a directory that is reserved for partial-dir work.
+partial-directory in the destination file's directory when it is needed,
+and then remove it again when the partial file is deleted.  Note that this
+directory removal is only done for a relative pathname, as it is expected
+that an absolute path is to a directory that is reserved for partial-dir
+work.
 .IP
 If the partial-dir value is not an absolute path, rsync will add an exclude
 rule at the end of all your existing excludes.  This will prevent the
 sending of any partial-dir files that may exist on the sending side, and
 will also prevent the untimely deletion of partial-dir items on the
 receiving side.  An example: the above \fB\-\-partial-dir\fP option would add the
-equivalent of "\fB\-f\ '\-p\ .rsync-partial/'\fP" at the end of any other filter
-rules.
+equivalent of this "perishable" exclude at the end of any other filter
+rules: \fB\-f\ '\-p\ .rsync-partial/'\fP
 .IP
 If you are supplying your own exclude rules, you may need to add your own
-exclude/hide/protect rule for the partial-dir because (1) the auto-added
-rule may be ineffective at the end of your other rules, or (2) you may wish
-to override rsync's exclude choice.  For instance, if you want to make
-rsync clean-up any left-over partial-dirs that may be lying around, you
-should specify \fB\-\-delete-after\fP and add a "risk" filter rule, e.g.
-\fB\-f\ 'R\ .rsync-partial/'\fP. (Avoid using \fB\-\-delete-before\fP or
-\fB\-\-delete-during\fP unless you don't need rsync to use any of the left-over
-partial-dir data during the current run.)
+exclude/hide/protect rule for the partial-dir because:
+.RS
+.IP
+.IP 1.
+the auto-added rule may be ineffective at the end of your other rules, or
+.IP 2.
+you may wish to override rsync's exclude choice.
+.RE
+.IP
+For instance, if you want to make rsync clean-up any left-over partial-dirs
+that may be lying around, you should specify \fB\-\-delete-after\fP and
+add a "risk" filter rule, e.g.  \fB\-f\ 'R\ .rsync-partial/'\fP. Avoid using
+\fB\-\-delete-before\fP or \fB\-\-delete-during\fP unless you don't
+need rsync to use any of the left-over partial-dir data during the current
+run.
 .IP
 IMPORTANT: the \fB\-\-partial-dir\fP should not be writable by other users or it
-is a security risk.  E.g. AVOID "/tmp".
-.IP
-You can also set the partial-dir value the RSYNC_PARTIAL_DIR environment
-variable.  Setting this in the environment does not force \fB\-\-partial\fP to be
-enabled, but rather it affects where partial files go when \fB\-\-partial\fP is
-specified.  For instance, instead of using \fB\-\-partial-dir=.rsync-tmp\fP along
-with \fB\-\-progress\fP, you could set RSYNC_PARTIAL_DIR=.rsync-tmp in your
-environment and then just use the \fB\-P\fP option to turn on the use of the
-\&.rsync-tmp dir for partial transfers.  The only times that the \fB\-\-partial\fP
-option does not look for this environment value are (1) when \fB\-\-inplace\fP
-was specified (since \fB\-\-inplace\fP conflicts with \fB\-\-partial-dir\fP), and (2)
+is a security risk!  E.g. AVOID "/tmp"!
+.IP
+You can also set the partial-dir value the \fBRSYNC_PARTIAL_DIR\fP
+environment variable.  Setting this in the environment does not force
+\fB\-\-partial\fP to be enabled, but rather it affects where partial
+files go when \fB\-\-partial\fP is specified.  For instance, instead of
+using \fB\-\-partial-dir=.rsync-tmp\fP along with \fB\-\-progress\fP, you could
+set \fBRSYNC_PARTIAL_DIR=.rsync-tmp\fP in your environment and then use
+the \fB\-P\fP option to turn on the use of the .rsync-tmp dir for
+partial transfers.  The only times that the \fB\-\-partial\fP option does
+not look for this environment value are:
+.RS
+.IP
+.IP 1.
+when \fB\-\-inplace\fP was specified (since \fB\-\-inplace\fP
+conflicts with \fB\-\-partial-dir\fP), and
+.IP 2.
 when \fB\-\-delay-updates\fP was specified (see below).
+.RE
 .IP
 When a modern rsync resumes the transfer of a file in the partial-dir, that
 partial file is now updated in-place instead of creating yet another
@@ -3042,37 +3499,44 @@ tmp).  This requires both ends of the transfer to be at least version
 3.2.0.
 .IP
 For the purposes of the daemon-config's "\fBrefuse\ options\fP" setting,
-\fB\-\-partial-dir\fP does \fInot\fP imply \fB\-\-partial\fP.  This is so that a refusal of
-the \fB\-\-partial\fP option can be used to disallow the overwriting of
-destination files with a partial transfer, while still allowing the safer
-idiom provided by \fB\-\-partial-dir\fP.
+\fB\-\-partial-dir\fP does \fInot\fP imply \fB\-\-partial\fP.  This is so that a
+refusal of the \fB\-\-partial\fP option can be used to disallow the
+overwriting of destination files with a partial transfer, while still
+allowing the safer idiom provided by \fB\-\-partial-dir\fP.
 .IP "\fB\-\-delay-updates\fP"
 This option puts the temporary file from each updated file into a holding
 directory until the end of the transfer, at which time all the files are
 renamed into place in rapid succession.  This attempts to make the updating
 of the files a little more atomic.  By default the files are placed into a
 directory named \fB.~tmp~\fP in each file's destination directory, but if
-you've specified the \fB\-\-partial-dir\fP option, that directory will be used
-instead.  See the comments in the \fB\-\-partial-dir\fP section for a discussion
-of how this \fB.~tmp~\fP dir will be excluded from the transfer, and what you
-can do if you want rsync to cleanup old \fB.~tmp~\fP dirs that might be lying
-around.  Conflicts with \fB\-\-inplace\fP and \fB\-\-append\fP.
+you've specified the \fB\-\-partial-dir\fP option, that directory will be
+used instead.  See the comments in the \fB\-\-partial-dir\fP section for
+a discussion of how this \fB.~tmp~\fP dir will be excluded from the transfer,
+and what you can do if you want rsync to cleanup old \fB.~tmp~\fP dirs that
+might be lying around.  Conflicts with \fB\-\-inplace\fP and
+\fB\-\-append\fP.
 .IP
-This option implies \fB\-\-no-inc-recursive\fP since it needs the full file list
-in memory in order to be able to iterate over it at the end.
+This option implies \fB\-\-no-inc-recursive\fP since it needs the full
+file list in memory in order to be able to iterate over it at the end.
 .IP
 This option uses more memory on the receiving side (one bit per file
 transferred) and also requires enough free disk space on the receiving side
 to hold an additional copy of all the updated files.  Note also that you
-should not use an absolute path to \fB\-\-partial-dir\fP unless (1) there is no
-chance of any of the files in the transfer having the same name (since all
-the updated files will be put into a single directory if the path is
-absolute) and (2) there are no mount points in the hierarchy (since the
-delayed updates will fail if they can't be renamed into place).
-.IP
-See also the "atomic-rsync" perl script in the "support" subdir for an
-update algorithm that is even more atomic (it uses \fB\-\-link-dest\fP and a
-parallel hierarchy of files).
+should not use an absolute path to \fB\-\-partial-dir\fP unless:
+.RS
+.IP
+.IP 1.
+there is no chance of any of the files in the transfer having the same
+name (since all the updated files will be put into a single directory if
+the path is absolute), and
+.IP 2.
+there are no mount points in the hierarchy (since the delayed updates
+will fail if they can't be renamed into place).
+.RE
+.IP
+See also the "atomic-rsync" python script in the "support" subdir for an
+update algorithm that is even more atomic (it uses \fB\-\-link-dest\fP
+and a parallel hierarchy of files).
 .IP "\fB\-\-prune-empty-dirs\fP, \fB\-m\fP"
 This option tells the receiving rsync to get rid of empty directories from
 the file-list, including nested directories that have no non-directory
@@ -3080,10 +3544,8 @@ children.  This is useful for avoiding the creation of a bunch of useless
 directories when the sending rsync is recursively scanning a hierarchy of
 files using include/exclude/filter rules.
 .IP
-Note that the use of transfer rules, such as the \fB\-\-min-size\fP option, does
-not affect what goes into the file list, and thus does not leave
-directories empty, even if none of the files in a directory match the
-transfer rule.
+This option can still leave empty directories on the receiving side if you
+make use of TRANSFER_RULES.
 .IP
 Because the file-list is actually being pruned, this option also affects
 what directories get deleted when a delete is active.  However, keep in
@@ -3119,9 +3581,9 @@ fine in place of the hide-filter (if that is more natural to you).
 .IP "\fB\-\-progress\fP"
 This option tells rsync to print information showing the progress of the
 transfer.  This gives a bored user something to watch.  With a modern rsync
-this is the same as specifying \fB\-\-info=flist2,name,progress\fP, but any
-user-supplied settings for those info flags takes precedence (e.g.
-"\fB\-\-info=flist0\ \-\-progress\fP").
+this is the same as specifying \fB\-\-info=flist2,name,progress\fP, but
+any user-supplied settings for those info flags takes precedence (e.g.
+\fB\-\-info=flist0\ \-\-progress\fP).
 .IP
 While rsync is transferring a regular file, it updates a progress line that
 looks like this:
@@ -3170,16 +3632,17 @@ total count of files in the file list is still going to increase (and each
 time it does, the count of files left to check will increase by the number
 of the files added to the list).
 .IP "\fB\-P\fP"
-The \fB\-P\fP option is equivalent to \fB\-\-partial\ \-\-progress\fP.  Its purpose is
-to make it much easier to specify these two options for a long transfer
-that may be interrupted.
-.IP
-There is also a \fB\-\-info=progress2\fP option that outputs statistics based on
-the whole transfer, rather than individual files.  Use this flag without
-outputting a filename (e.g. avoid \fB\-v\fP or specify \fB\-\-info=name0\fP) if you
-want to see how the transfer is doing without scrolling the screen with a
-lot of names. (You don't need to specify the \fB\-\-progress\fP option in order
-to use \fB\-\-info=progress2\fP.)
+The \fB\-P\fP option is equivalent to "\fB\-\-partial\fP
+\fB\-\-progress\fP".  Its purpose is to make it much easier to specify
+these two options for a long transfer that may be interrupted.
+.IP
+There is also a \fB\-\-info=progress2\fP option that outputs statistics
+based on the whole transfer, rather than individual files.  Use this flag
+without outputting a filename (e.g. avoid \fB\-v\fP or specify
+\fB\-\-info=name0\fP) if you want to see how the transfer is doing
+without scrolling the screen with a lot of names. (You don't need to
+specify the \fB\-\-progress\fP option in order to use
+\fB\-\-info=progress2\fP.)
 .IP
 Finally, you can get an instant progress report by sending rsync a signal
 of either SIGINFO or SIGVTALRM.  On BSD systems, a SIGINFO is generated by
@@ -3188,8 +3651,8 @@ the client-side process receives one of those signals, it sets a flag to
 output a single progress report which is output when the current file
 transfer finishes (so it may take a little time if a big file is being
 handled when the signal arrives).  A filename is output (if needed)
-followed by the \fB\-\-info=progress2\fP format of progress info.  If you don't
-know which of the 3 rsync processes is the client process, it's OK to
+followed by the \fB\-\-info=progress2\fP format of progress info.  If you
+don't know which of the 3 rsync processes is the client process, it's OK to
 signal all of them (since the non-client processes ignore the signal).
 .IP
 CAUTION: sending SIGVTALRM to an older rsync (pre-3.2.0) will kill it.
@@ -3216,12 +3679,20 @@ The daemon must be at least version 3.2.1.
 .IP "\fB\-\-list-only\fP"
 This option will cause the source files to be listed instead of
 transferred.  This option is inferred if there is a single source arg and
-no destination specified, so its main uses are: (1) to turn a copy command
-that includes a destination arg into a file-listing command, or (2) to be
-able to specify more than one source arg (note: be sure to include the
-destination).  Caution: keep in mind that a source arg with a wild-card is
-expanded by the shell into multiple args, so it is never safe to try to
-list such an arg without using this option. For example:
+no destination specified, so its main uses are:
+.RS
+.IP
+.IP 1.
+to turn a copy command that includes a destination arg into a
+file-listing command, or
+.IP 2.
+to be able to specify more than one source arg.  Note: be sure to
+include the destination.
+.RE
+.IP
+CAUTION: keep in mind that a source arg with a wild-card is expanded by the
+shell into multiple args, so it is never safe to try to specify a single
+wild-card arg to try to infer this option. A safe example is:
 .RS 4
 .IP
 .nf
@@ -3229,29 +3700,37 @@ rsync -av --list-only foo* dest/
 .fi
 .RE
 .IP
-Starting with rsync 3.1.0, the sizes output by \fB\-\-list-only\fP are affected
-by the \fB\-\-human-readable\fP option.  By default they will contain digit
-separators, but higher levels of readability will output the sizes with
-unit suffixes.  Note also that the column width for the size output has
-increased from 11 to 14 characters for all human-readable levels.  Use
-\fB\-\-no-h\fP if you want just digits in the sizes, and the old column width of
-11 characters.
+This option always uses an output format that looks similar to this:
+.RS 4
+.IP
+.nf
+drwxrwxr-x          4,096 2022/09/30 12:53:11 support
+-rw-rw-r--             80 2005/01/11 10:37:37 support/Makefile
+.fi
+.RE
+.IP
+The only option that affects this output style is (as of 3.1.0) the
+\fB\-\-human-readable\fP (\fB\-h\fP) option.  The default is to output sizes
+as byte counts with digit separators (in a 14-character-width column).
+Specifying at least one \fB\-h\fP option makes the sizes output with unit
+suffixes.  If you want old-style bytecount sizes without digit separators
+(and an 11-character-width column) use \fB\-\-no-h\fP.
 .IP
 Compatibility note: when requesting a remote listing of files from an rsync
 that is version 2.6.3 or older, you may encounter an error if you ask for a
-non-recursive listing.  This is because a file listing implies the \fB\-\-dirs\fP
-option w/o \fB\-\-recursive\fP, and older rsyncs don't have that option.  To
-avoid this problem, either specify the \fB\-\-no-dirs\fP option (if you don't
-need to expand a directory's content), or turn on recursion and exclude the
-content of subdirectories: \fB\-r\ \-\-exclude='/*/*'\fP.
+non-recursive listing.  This is because a file listing implies the
+\fB\-\-dirs\fP option w/o \fB\-\-recursive\fP, and older rsyncs don't
+have that option.  To avoid this problem, either specify the \fB\-\-no-dirs\fP
+option (if you don't need to expand a directory's content), or turn on
+recursion and exclude the content of subdirectories: \fB\-r\ \-\-exclude='/*/*'\fP.
 .IP "\fB\-\-bwlimit=RATE\fP"
 This option allows you to specify the maximum transfer rate for the data
 sent over the socket, specified in units per second.  The RATE value can be
 suffixed with a string to indicate a size multiplier, and may be a
-fractional value (e.g. "\fB\-\-bwlimit=1.5m\fP").  If no suffix is specified, the
+fractional value (e.g. \fB\-\-bwlimit=1.5m\fP).  If no suffix is specified, the
 value will be assumed to be in units of 1024 bytes (as if "K" or "KiB" had
-been appended).  See the \fB\-\-max-size\fP option for a description of all the
-available suffixes.  A value of 0 specifies no limit.
+been appended).  See the \fB\-\-max-size\fP option for a description of
+all the available suffixes.  A value of 0 specifies no limit.
 .IP
 For backward-compatibility reasons, the rate limit will be rounded to the
 nearest KiB unit, so no rate smaller than 1024 bytes per second is
@@ -3263,23 +3742,25 @@ transfer rate at the requested limit.  Some burstiness may be seen where
 rsync writes out a block of data and then sleeps to bring the average rate
 into compliance.
 .IP
-Due to the internal buffering of data, the \fB\-\-progress\fP option may not be
-an accurate reflection on how fast the data is being sent.  This is because
-some files can show up as being rapidly sent when the data is quickly
-buffered, while other can show up as very slow when the flushing of the
-output buffer occurs.  This may be fixed in a future version.
-.IP "`\-\-stop-after=MINS"
+Due to the internal buffering of data, the \fB\-\-progress\fP option may
+not be an accurate reflection on how fast the data is being sent.  This is
+because some files can show up as being rapidly sent when the data is
+quickly buffered, while other can show up as very slow when the flushing of
+the output buffer occurs.  This may be fixed in a future version.
+.IP
+See also the daemon version of the \fB\-\-bwlimit\fP option.
+.IP "\fB\-\-stop-after=MINS\fP, (\fB\-\-time-limit=MINS\fP)"
 This option tells rsync to stop copying when the specified number of
 minutes has elapsed.
 .IP
-Rsync also accepts an earlier version of this option: \fB\-\-time-limit=MINS\fP.
-.IP
 For maximal flexibility, rsync does not communicate this option to the
 remote rsync since it is usually enough that one side of the connection
 quits as specified.  This allows the option's use even when only one side
 of the connection supports it.  You can tell the remote side about the time
 limit using \fB\-\-remote-option\fP (\fB\-M\fP), should the need arise.
-.IP "`\-\-stop-at=y-m-dTh:m"
+.IP
+The \fB\-\-time-limit\fP version of this option is deprecated.
+.IP "\fB\-\-stop-at=y-m-dTh:m\fP"
 This option tells rsync to stop copying when the specified point in time
 has been reached. The date & time can be fully specified in a numeric
 format of year-month-dayThour:minute (e.g. 2000-12-31T23:59) in the local
@@ -3301,13 +3782,17 @@ For maximal flexibility, rsync does not communicate this option to the
 remote rsync since it is usually enough that one side of the connection
 quits as specified.  This allows the option's use even when only one side
 of the connection supports it.  You can tell the remote side about the time
-limit using \fB\-\-remote-option\fP (\fB\-M\fP), should the need arise.  Do keep in
-mind that the remote host may have a different default timezone than your
-local host.
+limit using \fB\-\-remote-option\fP (\fB\-M\fP), should the need arise.  Do
+keep in mind that the remote host may have a different default timezone
+than your local host.
+.IP "\fB\-\-fsync\fP"
+Cause the receiving side to fsync each finished file.  This may slow down
+the transfer, but can help to provide peace of mind when updating critical
+files.
 .IP "\fB\-\-write-batch=FILE\fP"
 Record a file that can later be applied to another identical destination
-with \fB\-\-read-batch\fP.  See the "BATCH MODE" section for details, and also
-the \fB\-\-only-write-batch\fP option.
+with \fB\-\-read-batch\fP.  See the "BATCH MODE" section for details, and
+also the \fB\-\-only-write-batch\fP option.
 .IP
 This option overrides the negotiated checksum & compress lists and always
 negotiates a choice based on old-school md5/md4/zlib choices.  If you want
@@ -3332,16 +3817,16 @@ into the batch file without having to flow over the wire to the receiver
 (when pulling, the sender is remote, and thus can't write the batch).
 .IP "\fB\-\-read-batch=FILE\fP"
 Apply all of the changes stored in FILE, a file previously generated by
-\fB\-\-write-batch\fP.  If \fIFILE\fP is \fB\-\fP, the batch data will be read from
-standard input. See the "BATCH MODE" section for details.
+\fB\-\-write-batch\fP.  If \fIFILE\fP is \fB\-\fP, the batch data will be read
+from standard input. See the "BATCH MODE" section for details.
 .IP "\fB\-\-protocol=NUM\fP"
 Force an older protocol version to be used.  This is useful for creating a
 batch file that is compatible with an older version of rsync.  For
-instance, if rsync 2.6.4 is being used with the \fB\-\-write-batch\fP option, but
-rsync 2.6.3 is what will be used to run the \fB\-\-read-batch\fP option, you
-should use "\-\-protocol=28" when creating the batch file to force the older
-protocol version to be used in the batch file (assuming you can't upgrade
-the rsync on the reading system).
+instance, if rsync 2.6.4 is being used with the \fB\-\-write-batch\fP
+option, but rsync 2.6.3 is what will be used to run the
+\fB\-\-read-batch\fP option, you should use "\-\-protocol=28" when creating
+the batch file to force the older protocol version to be used in the batch
+file (assuming you can't upgrade the rsync on the reading system).
 .IP "\fB\-\-iconv=CONVERT_SPEC\fP"
 Rsync can convert filenames between character sets using this option.
 Using a CONVERT_SPEC of "." tells rsync to look up the default
@@ -3351,15 +3836,15 @@ comma in the order \fB\-\-iconv=LOCAL,REMOTE\fP, e.g. \fB\-\-iconv=utf8,iso88591
 This order ensures that the option will stay the same whether you're
 pushing or pulling files.  Finally, you can specify either \fB\-\-no-iconv\fP or
 a CONVERT_SPEC of "\-" to turn off any conversion.  The default setting of
-this option is site-specific, and can also be affected via the RSYNC_ICONV
-environment variable.
+this option is site-specific, and can also be affected via the
+\fBRSYNC_ICONV\fP environment variable.
 .IP
 For a list of what charset names your local iconv library supports, you can
 run "\fBiconv\ \-\-list\fP".
 .IP
-If you specify the \fB\-\-protect-args\fP option (\fB\-s\fP), rsync will translate the
-filenames you specify on the command-line that are being sent to the remote
-host.  See also the \fB\-\-files-from\fP option.
+If you specify the \fB\-\-secluded-args\fP (\fB\-s\fP) option, rsync will
+translate the filenames you specify on the command-line that are being sent
+to the remote host.  See also the \fB\-\-files-from\fP option.
 .IP
 Note that rsync does not do any conversion of names in filter files
 (including include/exclude files).  It is up to you to ensure that you're
@@ -3378,12 +3863,12 @@ affects sockets that rsync has direct control over, such as the outgoing
 socket when directly contacting an rsync daemon, as well as the forwarding
 of the \fB\-4\fP or \fB\-6\fP option to ssh when rsync can deduce that ssh is being
 used as the remote shell.  For other remote shells you'll need to specify
-the "\fB\-\-rsh\ SHELL\ \-4\fP" option directly (or whatever ipv4/ipv6 hint options
+the "\fB\-\-rsh\ SHELL\ \-4\fP" option directly (or whatever IPv4/IPv6 hint options
 it uses).
 .IP
-These options also exist in the \fB\-\-daemon\fP mode section.
+See also the daemon version of these options.
 .IP
-If rsync was complied without support for IPv6, the \fB\-\-ipv6\fP option will
+If rsync was compiled without support for IPv6, the \fB\-\-ipv6\fP option will
 have no effect.  The \fBrsync\ \-\-version\fP output will contain "\fBno\ IPv6\fP" if
 is the case.
 .IP "\fB\-\-checksum-seed=NUM\fP"
@@ -3408,25 +3893,31 @@ running may be accessed using an rsync client using the \fBhost::module\fP or
 If standard input is a socket then rsync will assume that it is being run
 via inetd, otherwise it will detach from the current terminal and become a
 background daemon.  The daemon will read the config file (rsyncd.conf) on
-each connect made by a client and respond to requests accordingly.  See the
-\fBrsyncd.conf\fP(5) man page for more details.
+each connect made by a client and respond to requests accordingly.
+.IP
+See the \fBrsyncd.conf\fP(5) manpage for more details.
 .IP "\fB\-\-address=ADDRESS\fP"
 By default rsync will bind to the wildcard address when run as a daemon
 with the \fB\-\-daemon\fP option.  The \fB\-\-address\fP option allows you to specify a
 specific IP address (or hostname) to bind to.  This makes virtual hosting
-possible in conjunction with the \fB\-\-config\fP option.  See also the "address"
-global option in the rsyncd.conf manpage.
+possible in conjunction with the \fB\-\-config\fP option.
+.IP
+See also the address global option in the
+rsyncd.conf manpage and the client version of the \fB\-\-address\fP
+option.
 .IP "\fB\-\-bwlimit=RATE\fP"
 This option allows you to specify the maximum transfer rate for the data
 the daemon sends over the socket.  The client can still specify a smaller
-\fB\-\-bwlimit\fP value, but no larger value will be allowed.  See the client
-version of this option (above) for some extra details.
+\fB\-\-bwlimit\fP value, but no larger value will be allowed.
+.IP
+See the client version of the \fB\-\-bwlimit\fP option for some
+extra details.
 .IP "\fB\-\-config=FILE\fP"
 This specifies an alternate config file than the default.  This is only
-relevant when \fB\-\-daemon\fP is specified.  The default is /etc/rsyncd.conf
-unless the daemon is running over a remote shell program and the remote
-user is not the super-user; in that case the default is rsyncd.conf in the
-current directory (typically $HOME).
+relevant when \fB\-\-daemon\fP is specified.  The default is
+/etc/rsyncd.conf unless the daemon is running over a remote shell program
+and the remote user is not the super-user; in that case the default is
+rsyncd.conf in the current directory (typically $HOME).
 .IP "\fB\-\-dparam=OVERRIDE\fP, \fB\-M\fP"
 This option can be used to set a daemon-config parameter when starting up
 rsync in daemon mode.  It is equivalent to adding the parameter at the end
@@ -3448,24 +3939,35 @@ program such as \fBdaemontools\fP or AIX's \fBSystem\ Resource\ Controller\fP.
 option has no effect if rsync is run from inetd or sshd.
 .IP "\fB\-\-port=PORT\fP"
 This specifies an alternate TCP port number for the daemon to listen on
-rather than the default of 873.  See also the "port" global option in the
-rsyncd.conf manpage.
+rather than the default of 873.
+.IP
+See also the client version of the \fB\-\-port\fP option and the
+port global setting in the rsyncd.conf manpage.
 .IP "\fB\-\-log-file=FILE\fP"
 This option tells the rsync daemon to use the given log-file name instead
 of using the "\fBlog\ file\fP" setting in the config file.
+.IP
+See also the client version of the \fB\-\-log-file\fP option.
 .IP "\fB\-\-log-file-format=FORMAT\fP"
 This option tells the rsync daemon to use the given FORMAT string instead
 of using the "\fBlog\ format\fP" setting in the config file.  It also enables
 "\fBtransfer\ logging\fP" unless the string is empty, in which case transfer
 logging is turned off.
+.IP
+See also the client version of the \fB\-\-log-file-format\fP
+option.
 .IP "\fB\-\-sockopts\fP"
-This overrides the \fBsocket\ options\fP setting in the rsyncd.conf file and has
-the same syntax.
+This overrides the \fBsocket\ options\fP
+setting in the rsyncd.conf file and has the same syntax.
+.IP
+See also the client version of the \fB\-\-sockopts\fP option.
 .IP "\fB\-\-verbose\fP, \fB\-v\fP"
 This option increases the amount of information the daemon logs during its
 startup phase.  After the client connects, the daemon's verbosity level
 will be controlled by the options that the client used and the
 "\fBmax\ verbosity\fP" setting in the module's config section.
+.IP
+See also the client version of the \fB\-\-verbose\fP option.
 .IP "\fB\-\-ipv4\fP, \fB\-4\fP or \fB\-\-ipv6\fP, \fB\-6\fP"
 Tells rsync to prefer IPv4/IPv6 when creating the incoming sockets that the
 rsync daemon will use to listen for connections.  One of these options may
@@ -3474,9 +3976,9 @@ kernel (if you see an "address already in use" error when nothing else is
 using the port, try specifying \fB\-\-ipv6\fP or \fB\-\-ipv4\fP when starting the
 daemon).
 .IP
-These options also exist in the regular rsync options section.
+See also the client version of these options.
 .IP
-If rsync was complied without support for IPv6, the \fB\-\-ipv6\fP option will
+If rsync was compiled without support for IPv6, the \fB\-\-ipv6\fP option will
 have no effect.  The \fBrsync\ \-\-version\fP output will contain "\fBno\ IPv6\fP" if
 is the case.
 .IP "\fB\-\-help\fP, \fB\-h\fP"
@@ -3485,19 +3987,173 @@ options available for starting an rsync daemon.
 .P
 .SH "FILTER RULES"
 .P
-The filter rules allow for flexible selection of which files to transfer
-(include) and which files to skip (exclude).  The rules either directly specify
-include/exclude patterns or they specify a way to acquire more include/exclude
-patterns (e.g. to read them from a file).
+The filter rules allow for custom control of several aspects of how files are
+handled:
+.P
+.IP o
+Control which files the sending side puts into the file list that describes
+the transfer hierarchy
+.IP o
+Control which files the receiving side protects from deletion when the file
+is not in the sender's file list
+.IP o
+Control which extended attribute names are skipped when copying xattrs
+.P
+The rules are either directly specified via option arguments or they can be
+read in from one or more files.  The filter-rule files can even be a part of
+the hierarchy of files being copied, affecting different parts of the tree in
+different ways.
+.P
+.SS "SIMPLE INCLUDE/EXCLUDE RULES"
+.P
+We will first cover the basics of how include & exclude rules affect what files
+are transferred, ignoring any deletion side-effects.  Filter rules mainly
+affect the contents of directories that rsync is "recursing" into, but they can
+also affect a top-level item in the transfer that was specified as a argument.
+.P
+The default for any unmatched file/dir is for it to be included in the
+transfer, which puts the file/dir into the sender's file list.  The use of an
+exclude rule causes one or more matching files/dirs to be left out of the
+sender's file list.  An include rule can be used to limit the effect of an
+exclude rule that is matching too many files.
+.P
+The order of the rules is important because the first rule that matches is the
+one that takes effect.  Thus, if an early rule excludes a file, no include rule
+that comes after it can have any effect. This means that you must place any
+include overrides somewhere prior to the exclude that it is intended to limit.
+.P
+When a directory is excluded, all its contents and sub-contents are also
+excluded.  The sender doesn't scan through any of it at all, which can save a
+lot of time when skipping large unneeded sub-trees.
+.P
+It is also important to understand that the include/exclude rules are applied
+to every file and directory that the sender is recursing into. Thus, if you
+want a particular deep file to be included, you have to make sure that none of
+the directories that must be traversed on the way down to that file are
+excluded or else the file will never be discovered to be included. As an
+example, if the directory "\fBa/path\fP" was given as a transfer argument and you
+want to ensure that the file "\fBa/path/down/deep/wanted.txt\fP" is a part of the
+transfer, then the sender must not exclude the directories "\fBa/path\fP",
+"\fBa/path/down\fP", or "\fBa/path/down/deep\fP" as it makes it way scanning through
+the file tree.
+.P
+When you are working on the rules, it can be helpful to ask rsync to tell you
+what is being excluded/included and why.  Specifying \fB\-\-debug=FILTER\fP or (when
+pulling files) \fB\-M\-\-debug=FILTER\fP turns on level 1 of the FILTER debug
+information that will output a message any time that a file or directory is
+included or excluded and which rule it matched.  Beginning in 3.2.4 it will
+also warn if a filter rule has trailing whitespace, since an exclude of "foo\ "
+(with a trailing space) will not exclude a file named "foo".
+.P
+Exclude and include rules can specify wildcard PATTERN MATCHING RULES
+(similar to shell wildcards) that allow you to match things like a file suffix
+or a portion of a filename.
+.P
+A rule can be limited to only affecting a directory by putting a trailing slash
+onto the filename.
+.P
+.SS "SIMPLE INCLUDE/EXCLUDE EXAMPLE"
+.P
+With the following file tree created on the sending side:
+.RS 4
 .P
-As the list of files/directories to transfer is built, rsync checks each name
-to be transferred against the list of include/exclude patterns in turn, and the
-first matching pattern is acted on: if it is an exclude pattern, then that file
-is skipped; if it is an include pattern then that filename is not skipped; if
-no matching pattern is found, then the filename is not skipped.
+.nf
+mkdir x/
+touch x/file.txt
+mkdir x/y/
+touch x/y/file.txt
+touch x/y/zzz.txt
+mkdir x/z/
+touch x/z/file.txt
+.fi
+.RE
 .P
-Rsync builds an ordered list of filter rules as specified on the command-line.
-Filter rules have the following syntax:
+Then the following rsync command will transfer the file "\fBx/y/file.txt\fP" and
+the directories needed to hold it, resulting in the path "\fB/tmp/x/y/file.txt\fP"
+existing on the remote host:
+.RS 4
+.P
+.nf
+rsync -ai -f'+ x/' -f'+ x/y/' -f'+ x/y/file.txt' -f'- *' x host:/tmp/
+.fi
+.RE
+.P
+Aside: this copy could also have been accomplished using the \fB\-R\fP
+option (though the 2 commands behave differently if deletions are enabled):
+.RS 4
+.P
+.nf
+rsync -aiR x/y/file.txt host:/tmp/
+.fi
+.RE
+.P
+The following command does not need an include of the "x" directory because it
+is not a part of the transfer (note the traililng slash).  Running this command
+would copy just "\fB/tmp/x/file.txt\fP" because the "y" and "z" dirs get excluded:
+.RS 4
+.P
+.nf
+rsync -ai -f'+ file.txt' -f'- *' x/ host:/tmp/x/
+.fi
+.RE
+.P
+This command would omit the zzz.txt file while copying "x" and everything else
+it contains:
+.RS 4
+.P
+.nf
+rsync -ai -f'- zzz.txt' x host:/tmp/
+.fi
+.RE
+.P
+.SS "FILTER RULES WHEN DELETING"
+.P
+By default the include & exclude filter rules affect both the sender
+(as it creates its file list)
+and the receiver (as it creates its file lists for calculating deletions).  If
+no delete option is in effect, the receiver skips creating the delete-related
+file lists.  This two-sided default can be manually overridden so that you are
+only specifying sender rules or receiver rules, as described in the FILTER
+RULES IN DEPTH section.
+.P
+When deleting, an exclude protects a file from being removed on the receiving
+side while an include overrides that protection (putting the file at risk of
+deletion). The default is for a file to be at risk\ \-\- its safety depends on it
+matching a corresponding file from the sender.
+.P
+An example of the two-sided exclude effect can be illustrated by the copying of
+a C development directory between 2 systems.  When doing a touch-up copy, you
+might want to skip copying the built executable and the \fB.o\fP files (sender
+hide) so that the receiving side can build their own and not lose any object
+files that are already correct (receiver protect).  For instance:
+.RS 4
+.P
+.nf
+rsync -ai --del -f'- *.o' -f'- cmd' src host:/dest/
+.fi
+.RE
+.P
+Note that using \fB\-f'\-p\ *.o'\fP is even better than \fB\-f'\-\ *.o'\fP if there is a
+chance that the directory structure may have changed.  The "p" modifier is
+discussed in FILTER RULE MODIFIERS.
+.P
+One final note, if your shell doesn't mind unexpanded wildcards, you could
+simplify the typing of the filter options by using an underscore in place of
+the space and leaving off the quotes.  For instance, \fB\-f\ \-_*.o\ \-f\ \-_cmd\fP (and
+similar) could be used instead of the filter options above.
+.P
+.SS "FILTER RULES IN DEPTH"
+.P
+Rsync supports old-style include/exclude rules and new-style filter rules.  The
+older rules are specified using \fB\-\-include\fP and \fB\-\-exclude\fP as
+well as the \fB\-\-include-from\fP and \fB\-\-exclude-from\fP. These are
+limited in behavior but they don't require a "\-" or "+" prefix.  An old-style
+exclude rule is turned into a "\fB\-\ name\fP" filter rule (with no modifiers) and an
+old-style include rule is turned into a "\fB+\ name\fP" filter rule (with no
+modifiers).
+.P
+Rsync builds an ordered list of filter rules as specified on the command-line
+and/or read-in from files.  New style filter rules have the following syntax:
 .RS 4
 .P
 .nf
@@ -3509,189 +4165,154 @@ RULE,MODIFIERS [PATTERN_OR_FILENAME]
 You have your choice of using either short or long RULE names, as described
 below.  If you use a short-named rule, the ',' separating the RULE from the
 MODIFIERS is optional.  The PATTERN or FILENAME that follows (when present)
-must come after either a single space or an underscore (_).  Here are the
-available rule prefixes:
+must come after either a single space or an underscore (_). Any additional
+spaces and/or underscores are considered to be a part of the pattern name.
+Here are the available rule prefixes:
 .P
 .IP "\fBexclude,\ '\-'\fP"
-specifies an exclude pattern.
+specifies an exclude pattern that (by default) is both a
+\fBhide\fP and a \fBprotect\fP.
 .IP "\fBinclude,\ '+'\fP"
-specifies an include pattern.
+specifies an include pattern that (by default) is both a
+\fBshow\fP and a \fBrisk\fP.
 .IP "\fBmerge,\ '.'\fP"
-specifies a merge-file to read for more rules.
+specifies a merge-file on the client side to read for more
+rules.
 .IP "\fBdir-merge,\ ':'\fP"
-specifies a per-directory merge-file.
+specifies a per-directory merge-file.  Using this kind of
+filter rule requires that you trust the sending side's filter checking, so
+it has the side-effect mentioned under the \fB\-\-trust-sender\fP option.
 .IP "\fBhide,\ 'H'\fP"
 specifies a pattern for hiding files from the transfer.
+Equivalent to a sender-only exclude, so \fB\-f'H\ foo'\fP could also be specified
+as \fB\-f'\-s\ foo'\fP.
 .IP "\fBshow,\ 'S'\fP"
-files that match the pattern are not hidden.
+files that match the pattern are not hidden. Equivalent to a
+sender-only include, so \fB\-f'S\ foo'\fP could also be specified as \fB\-f'+s\ foo'\fP.
 .IP "\fBprotect,\ 'P'\fP"
 specifies a pattern for protecting files from deletion.
+Equivalent to a receiver-only exclude, so \fB\-f'P\ foo'\fP could also be
+specified as \fB\-f'\-r\ foo'\fP.
 .IP "\fBrisk,\ 'R'\fP"
-files that match the pattern are not protected.
+files that match the pattern are not protected. Equivalent to a
+receiver-only include, so \fB\-f'R\ foo'\fP could also be specified as \fB\-f'+r\ foo'\fP.
 .IP "\fBclear,\ '!'\fP"
 clears the current include/exclude list (takes no arg)
 .P
-When rules are being read from a file, empty lines are ignored, as are comment
-lines that start with a "#".
-.P
-Note that the \fB\-\-include\fP & \fB\-\-exclude\fP command-line options do not allow the
-full range of rule parsing as described above\ \-\- they only allow the
-specification of include / exclude patterns plus a "\fB!\fP" token to clear the
-list (and the normal comment parsing when rules are read from a file).  If a
-pattern does not begin with "\fB\-\ \fP" (dash, space) or "\fB+\ \fP" (plus, space), then
-the rule will be interpreted as if "\fB+\ \fP" (for an include option) or "\fB\-\ \fP"
-(for an exclude option) were prefixed to the string.  A \fB\-\-filter\fP option, on
-the other hand, must always contain either a short or long rule name at the
-start of the rule.
-.P
-Note also that the \fB\-\-filter\fP, \fB\-\-include\fP, and \fB\-\-exclude\fP options take one
-rule/pattern each.  To add multiple ones, you can repeat the options on the
-command-line, use the merge-file syntax of the \fB\-\-filter\fP option, or the
-\fB\-\-include-from\fP / \fB\-\-exclude-from\fP options.
-.P
-.SH "INCLUDE/EXCLUDE PATTERN RULES"
-.P
-You can include and exclude files by specifying patterns using the "+", "\-",
-etc. filter rules (as introduced in the FILTER RULES section above).  The
-include/exclude rules each specify a pattern that is matched against the names
-of the files that are going to be transferred.  These patterns can take several
-forms:
-.P
-.IP o
-if the pattern starts with a \fB/\fP then it is anchored to a particular spot in
-the hierarchy of files, otherwise it is matched against the end of the
-pathname.  This is similar to a leading \fB^\fP in regular expressions.  Thus
-\fB/foo\fP would match a name of "foo" at either the "root of the transfer" (for
-a global rule) or in the merge-file's directory (for a per-directory rule).
-An unqualified \fBfoo\fP would match a name of "foo" anywhere in the tree because
-the algorithm is applied recursively from the top down; it behaves as if each
-path component gets a turn at being the end of the filename.  Even the
-unanchored "sub/foo" would match at any point in the hierarchy where a "foo"
-was found within a directory named "sub".  See the section on ANCHORING
-INCLUDE/EXCLUDE PATTERNS for a full discussion of how to specify a pattern
-that matches at the root of the transfer.
-.IP o
-if the pattern ends with a \fB/\fP then it will only match a directory, not a
-regular file, symlink, or device.
-.IP o
-rsync chooses between doing a simple string match and wildcard matching by
-checking if the pattern contains one of these three wildcard characters:
-\&'\fB*\fP', '\fB?\fP', and '\fB[\fP' .
-.IP o
-a '\fB*\fP' matches any path component, but it stops at slashes.
-.IP o
-use '\fB**\fP' to match anything, including slashes.
-.IP o
-a '\fB?\fP' matches any character except a slash (\fB/\fP).
-.IP o
-a '\fB[\fP' introduces a character class, such as \fB[a-z]\fP or \fB[[:alpha:]]\fP.
-.IP o
-in a wildcard pattern, a backslash can be used to escape a wildcard
-character, but it is matched literally when no wildcards are present.  This
-means that there is an extra level of backslash removal when a pattern
-contains wildcard characters compared to a pattern that has none.  e.g. if
-you add a wildcard to "\fBfoo\\bar\fP" (which matches the backslash) you would
-need to use "\fBfoo\\\\bar*\fP" to avoid the "\fB\\b\fP" becoming just "b".
-.IP o
-if the pattern contains a \fB/\fP (not counting a trailing /) or a "\fB**\fP", then it
-is matched against the full pathname, including any leading directories.  If
-the pattern doesn't contain a \fB/\fP or a "\fB**\fP", then it is matched only against
-the final component of the filename. (Remember that the algorithm is applied
-recursively so "full filename" can actually be any portion of a path from the
-starting directory on down.)
-.IP o
-a trailing "\fBdir_name/***\fP" will match both the directory (as if "dir_name/"
-had been specified) and everything in the directory (as if "\fBdir_name/**\fP"
-had been specified).  This behavior was added in version 2.6.7.
-.P
-Note that, when using the \fB\-\-recursive\fP (\fB\-r\fP) option (which is implied by
-\fB\-a\fP), every subdir component of every path is visited left to right, with each
-directory having a chance for exclusion before its content.  In this way
-include/exclude patterns are applied recursively to the pathname of each node
-in the filesystem's tree (those inside the transfer).  The exclude patterns
-short-circuit the directory traversal stage as rsync finds the files to send.
-.P
-For instance, to include "\fB/foo/bar/baz\fP", the directories "\fB/foo\fP" and "\fB/foo/bar\fP"
-must not be excluded.  Excluding one of those parent directories prevents the
-examination of its content, cutting off rsync's recursion into those paths and
-rendering the include for "\fB/foo/bar/baz\fP" ineffectual (since rsync can't match
-something it never sees in the cut-off section of the directory hierarchy).
-.P
-The concept path exclusion is particularly important when using a trailing '\fB*\fP'
-rule.  For instance, this won't work:
-.RS 4
+When rules are being read from a file (using merge or dir-merge), empty lines
+are ignored, as are whole-line comments that start with a '\fB#\fP' (filename rules
+that contain a hash character are unaffected).
 .P
-.nf
-+ /some/path/this-file-will-not-be-found
-+ /file-is-included
-- *
-.fi
-.RE
+Note also that the \fB\-\-filter\fP, \fB\-\-include\fP, and
+\fB\-\-exclude\fP options take one rule/pattern each.  To add multiple ones,
+you can repeat the options on the command-line, use the merge-file syntax of
+the \fB\-\-filter\fP option, or the \fB\-\-include-from\fP /
+\fB\-\-exclude-from\fP options.
 .P
-This fails because the parent directory "some" is excluded by the '\fB*\fP' rule, so
-rsync never visits any of the files in the "some" or "some/path" directories.
-One solution is to ask for all directories in the hierarchy to be included by
-using a single rule: "\fB+\ */\fP" (put it somewhere before the "\fB\-\ *\fP" rule), and
-perhaps use the \fB\-\-prune-empty-dirs\fP option.  Another solution is to add
-specific include rules for all the parent dirs that need to be visited.  For
-instance, this set of rules works fine:
-.RS 4
+.SS "PATTERN MATCHING RULES"
 .P
-.nf
-+ /some/
-+ /some/path/
-+ /some/path/this-file-is-found
-+ /file-also-included
-- *
-.fi
-.RE
+Most of the rules mentioned above take an argument that specifies what the rule
+should match.  If rsync is recursing through a directory hierarchy, keep in
+mind that each pattern is matched against the name of every directory in the
+descent path as rsync finds the filenames to send.
+.P
+The matching rules for the pattern argument take several forms:
+.P
+.IP o
+If a pattern contains a \fB/\fP (not counting a trailing slash) or a "\fB**\fP"
+(which can match a slash), then the pattern is matched against the full
+pathname, including any leading directories within the transfer.  If the
+pattern doesn't contain a (non-trailing) \fB/\fP or a "\fB**\fP", then it is matched
+only against the final component of the filename or pathname. For example,
+\fBfoo\fP means that the final path component must be "foo" while \fBfoo/bar\fP would
+match the last 2 elements of the path (as long as both elements are within
+the transfer).
+.IP o
+A pattern that ends with a \fB/\fP only matches a directory, not a regular file,
+symlink, or device.
+.IP o
+A pattern that starts with a \fB/\fP is anchored to the start of the transfer
+path instead of the end.  For example, \fB/foo/**\fP or \fB/foo/bar/**\fP match only
+leading elements in the path.  If the rule is read from a per-directory
+filter file, the transfer path being matched will begin at the level of the
+filter file instead of the top of the transfer.  See the section on
+ANCHORING INCLUDE/EXCLUDE PATTERNS for a full discussion of how to
+specify a pattern that matches at the root of the transfer.
+.P
+Rsync chooses between doing a simple string match and wildcard matching by
+checking if the pattern contains one of these three wildcard characters: '\fB*\fP',
+\&'\fB?\fP', and '\fB[\fP' :
+.P
+.IP o
+a '\fB?\fP' matches any single character except a slash (\fB/\fP).
+.IP o
+a '\fB*\fP' matches zero or more non-slash characters.
+.IP o
+a '\fB**\fP' matches zero or more characters, including slashes.
+.IP o
+a '\fB[\fP' introduces a character class, such as \fB[a-z]\fP or \fB[[:alpha:]]\fP, that
+must match one character.
+.IP o
+a trailing \fB***\fP in the pattern is a shorthand that allows you to match a
+directory and all its contents using a single rule.  For example, specifying
+"\fBdir_name/***\fP" will match both the "dir_name" directory (as if "\fBdir_name/\fP"
+had been specified) and everything in the directory (as if "\fBdir_name/**\fP"
+had been specified).
+.IP o
+a backslash can be used to escape a wildcard character, but it is only
+interpreted as an escape character if at least one wildcard character is
+present in the match pattern. For instance, the pattern "\fBfoo\\bar\fP" matches
+that single backslash literally, while the pattern "\fBfoo\\bar*\fP" would need to
+be changed to "\fBfoo\\\\bar*\fP" to avoid the "\fB\\b\fP" becoming just "b".
 .P
 Here are some examples of exclude/include matching:
 .P
 .IP o
-"\fB\-\ *.o\fP" would exclude all names matching \fB*.o\fP
+Option \fB\-f'\-\ *.o'\fP would exclude all filenames ending with \fB.o\fP
 .IP o
-"\fB\-\ /foo\fP" would exclude a file (or directory) named foo in the transfer-root
-directory
+Option \fB\-f'\-\ /foo'\fP would exclude a file (or directory) named foo in the
+transfer-root directory
 .IP o
-"\fB\-\ foo/\fP" would exclude any directory named foo
+Option \fB\-f'\-\ foo/'\fP would exclude any directory named foo
 .IP o
-"\fB\-\ /foo/*/bar\fP" would exclude any file named bar which is at two levels
-below a directory named foo in the transfer-root directory
+Option \fB\-f'\-\ foo/*/bar'\fP would exclude any file/dir named bar which is at two
+levels below a directory named foo (if foo is in the transfer)
 .IP o
-"\fB\-\ /foo/**/bar\fP" would exclude any file named bar two or more levels below a
-directory named foo in the transfer-root directory
+Option \fB\-f'\-\ /foo/**/bar'\fP would exclude any file/dir named bar that was two
+or more levels below a top-level directory named foo (note that /foo/bar is
+\fBnot\fP excluded by this)
 .IP o
-The combination of "\fB+\ */\fP", "\fB+\ *.c\fP", and "\fB\-\ *\fP" would include all
-directories and C source files but nothing else (see also the
-\fB\-\-prune-empty-dirs\fP option)
+Options \fB\-f'+\ */'\ \-f'+\ *.c'\ \-f'\-\ *'\fP would include all directories and .c
+source files but nothing else
 .IP o
-The combination of "\fB+\ foo/\fP", "\fB+\ foo/bar.c\fP", and "\fB\-\ *\fP" would include
-only the foo directory and foo/bar.c (the foo directory must be explicitly
-included or it would be excluded by the "\fB*\fP")
+Options \fB\-f'+\ foo/'\ \-f'+\ foo/bar.c'\ \-f'\-\ *'\fP would include only the foo
+directory and foo/bar.c (the foo directory must be explicitly included or it
+would be excluded by the "\fB\-\ *\fP")
 .P
-The following modifiers are accepted after a "\fB+\fP" or "\fB\-\fP":
+.SS "FILTER RULE MODIFIERS"
+.P
+The following modifiers are accepted after an include (+) or exclude (\-) rule:
 .P
 .IP o
 A \fB/\fP specifies that the include/exclude rule should be matched against the
-absolute pathname of the current item.  For example, "\fB\-/\ /etc/passwd\fP" would
-exclude the passwd file any time the transfer was sending files from the
-"/etc" directory, and "\-/ subdir/foo" would always exclude "foo" when it is
-in a dir named "subdir", even if "foo" is at the root of the current
+absolute pathname of the current item.  For example, \fB\-f'\-/\ /etc/passwd'\fP
+would exclude the passwd file any time the transfer was sending files from
+the "/etc" directory, and "\-/ subdir/foo" would always exclude "foo" when it
+is in a dir named "subdir", even if "foo" is at the root of the current
 transfer.
 .IP o
 A \fB!\fP specifies that the include/exclude should take effect if the pattern
-fails to match.  For instance, "\fB\-!\ */\fP" would exclude all non-directories.
+fails to match.  For instance, \fB\-f'\-!\ */'\fP would exclude all non-directories.
 .IP o
 A \fBC\fP is used to indicate that all the global CVS-exclude rules should be
 inserted as excludes in place of the "\-C".  No arg should follow.
 .IP o
 An \fBs\fP is used to indicate that the rule applies to the sending side.  When a
-rule affects the sending side, it prevents files from being transferred.  The
-default is for a rule to affect both sides unless \fB\-\-delete-excluded\fP was
-specified, in which case default rules become sender-side only.  See also the
-hide (H) and show (S) rules, which are an alternate way to specify
-sending-side includes/excludes.
+rule affects the sending side, it affects what files are put into the
+sender's file list.  The default is for a rule to affect both sides unless
+\fB\-\-delete-excluded\fP was specified, in which case default rules become
+sender-side only.  See also the hide (H) and show (S) rules, which are an
+alternate way to specify sending-side includes/excludes.
 .IP o
 An \fBr\fP is used to indicate that the rule applies to the receiving side.  When
 a rule affects the receiving side, it prevents files from being deleted.  See
@@ -3699,21 +4320,22 @@ the \fBs\fP modifier for more info.  See also the protect (P) and risk (R) rules
 which are an alternate way to specify receiver-side includes/excludes.
 .IP o
 A \fBp\fP indicates that a rule is perishable, meaning that it is ignored in
-directories that are being deleted.  For instance, the \fB\-C\fP option's default
-rules that exclude things like "CVS" and "\fB*.o\fP" are marked as perishable,
-and will not prevent a directory that was removed on the source from being
-deleted on the destination.
+directories that are being deleted.  For instance, the
+\fB\-\-cvs-exclude\fP (\fB\-C\fP) option's default rules that exclude things
+like "CVS" and "\fB*.o\fP" are marked as perishable, and will not prevent a
+directory that was removed on the source from being deleted on the
+destination.
 .IP o
 An \fBx\fP indicates that a rule affects xattr names in xattr copy/delete
 operations (and is thus ignored when matching file/dir names).  If no
 xattr-matching rules are specified, a default xattr filtering rule is used
 (see the \fB\-\-xattrs\fP option).
 .P
-.SH "MERGE-FILE FILTER RULES"
+.SS "MERGE-FILE FILTER RULES"
 .P
 You can merge whole files into your filter rules by specifying either a merge
-(.) or a dir-merge (:) filter rule (as introduced in the FILTER RULES section
-above).
+(.) or a dir-merge (:) filter rule (as introduced in the FILTER RULES
+section above).
 .P
 There are two kinds of merged files\ \-\- single-instance ('.') and per-directory
 (':').  A single-instance merge file is read one time, and its rules are
@@ -3842,11 +4464,11 @@ the ".rsync-filter" files in each directory that is a part of the transfer.
 If you want to include the contents of a ".cvsignore" in your patterns, you
 should use the rule ":C", which creates a dir-merge of the .cvsignore file, but
 parsed in a CVS-compatible manner.  You can use this to affect where the
-\fB\-\-cvs-exclude\fP (\fB\-C\fP) option's inclusion of the per-directory .cvsignore file
-gets placed into your rules by putting the ":C" wherever you like in your
-filter rules.  Without this, rsync would add the dir-merge rule for the
-\&.cvsignore file at the end of all your other rules (giving it a lower priority
-than your command-line rules).  For example:
+\fB\-\-cvs-exclude\fP (\fB\-C\fP) option's inclusion of the per-directory
+\&.cvsignore file gets placed into your rules by putting the ":C" wherever you
+like in your filter rules.  Without this, rsync would add the dir-merge rule
+for the .cvsignore file at the end of all your other rules (giving it a lower
+priority than your command-line rules).  For example:
 .RS 4
 .P
 .nf
@@ -3868,7 +4490,7 @@ $HOME/.cvsignore, and the value of $CVSIGNORE) you should omit the \fB\-C\fP
 command-line option and instead insert a "\-C" rule into your filter rules; e.g.
 "\fB\-\-filter=\-C\fP".
 .P
-.SH "LIST-CLEARING FILTER RULE"
+.SS "LIST-CLEARING FILTER RULE"
 .P
 You can clear the current include/exclude list by using the "!" filter rule (as
 introduced in the FILTER RULES section above).  The "current" list is either
@@ -3876,7 +4498,7 @@ the global list of rules (if the rule is encountered while parsing the filter
 options) or a set of per-directory rules (which are inherited in their own
 sub-list, so a subdirectory can use this to clear out the parent's rules).
 .P
-.SH "ANCHORING INCLUDE/EXCLUDE PATTERNS"
+.SS "ANCHORING INCLUDE/EXCLUDE PATTERNS"
 .P
 As mentioned earlier, global include/exclude patterns are anchored at the "root
 of the transfer" (as opposed to per-directory patterns, which are anchored at
@@ -3886,10 +4508,10 @@ the tree starts to be duplicated in the destination directory.  This root
 governs where patterns that start with a / match.
 .P
 Because the matching is relative to the transfer-root, changing the trailing
-slash on a source path or changing your use of the \fB\-\-relative\fP option affects
-the path you need to use in your matching (in addition to changing how much of
-the file tree is duplicated on the destination host).  The following examples
-demonstrate this.
+slash on a source path or changing your use of the \fB\-\-relative\fP option
+affects the path you need to use in your matching (in addition to changing how
+much of the file tree is duplicated on the destination host).  The following
+examples demonstrate this.
 .P
 Let's say that we want to match two source files, one with an absolute
 path of "/home/me/foo/bar", and one with a path of "/home/you/bar/baz".
@@ -3935,11 +4557,11 @@ Target file: /dest/you/bar/baz
 .fi
 .RE
 .P
-The easiest way to see what name you should filter is to just
-look at the output when using \fB\-\-verbose\fP and put a / in front of the name
-(use the \fB\-\-dry-run\fP option if you're not yet ready to copy any files).
+The easiest way to see what name you should filter is to just look at the
+output when using \fB\-\-verbose\fP and put a / in front of the name (use the
+\fB\-\-dry-run\fP option if you're not yet ready to copy any files).
 .P
-.SH "PER-DIRECTORY RULES AND DELETE"
+.SS "PER-DIRECTORY RULES AND DELETE"
 .P
 Without a delete option, per-directory rules are only relevant on the sending
 side, so you can feel free to exclude the merge files themselves without
@@ -3956,9 +4578,9 @@ rsync -av --filter=':e .excl' host:src/dir /dest
 However, if you want to do a delete on the receiving side AND you want some
 files to be excluded from being deleted, you'll need to be sure that the
 receiving side knows what files to exclude.  The easiest way is to include the
-per-directory merge files in the transfer and use \fB\-\-delete-after\fP, because
-this ensures that the receiving side gets all the same exclude rules as the
-sending side before it tries to delete anything:
+per-directory merge files in the transfer and use \fB\-\-delete-after\fP,
+because this ensures that the receiving side gets all the same exclude rules as
+the sending side before it tries to delete anything:
 .RS 4
 .P
 .nf
@@ -3999,6 +4621,38 @@ rsync -avFF --delete host:src/dir /dest
 .fi
 .RE
 .P
+.SH "TRANSFER RULES"
+.P
+In addition to the FILTER RULES that affect the recursive file scans that
+generate the file list on the sending and (when deleting) receiving sides,
+there are transfer rules. These rules affect which files the generator decides
+need to be transferred without the side effects of an exclude filter rule.
+Transfer rules affect only files and never directories.
+.P
+Because a transfer rule does not affect what goes into the sender's (and
+receiver's) file list, it cannot have any effect on which files get deleted on
+the receiving side.  For example, if the file "foo" is present in the sender's
+list but its size is such that it is omitted due to a transfer rule, the
+receiving side does not request the file.  However, its presence in the file
+list means that a delete pass will not remove a matching file named "foo" on
+the receiving side.  On the other hand, a server-side exclude (hide) of the
+file "foo" leaves the file out of the server's file list, and absent a
+receiver-side exclude (protect) the receiver will remove a matching file named
+"foo" if deletions are requested.
+.P
+Given that the files are still in the sender's file list, the
+\fB\-\-prune-empty-dirs\fP option will not judge a directory as being empty
+even if it contains only files that the transfer rules omitted.
+.P
+Similarly, a transfer rule does not have any extra effect on which files are
+deleted on the receiving side, so setting a maximum file size for the transfer
+does not prevent big files from being deleted.
+.P
+Examples of transfer rules include the default "quick check" algorithm (which
+compares size & modify time), the \fB\-\-update\fP option, the
+\fB\-\-max-size\fP option, the \fB\-\-ignore-non-existing\fP option, and a
+few others.
+.P
 .SH "BATCH MODE"
 .P
 Batch mode can be used to apply the same set of updates to many identical
@@ -4063,10 +4717,10 @@ options when running the read-batch command on the remote host.
 .IP o
 The second example reads the batch data via standard input so that the batch
 file doesn't need to be copied to the remote machine first.  This example
-avoids the foo.sh script because it needed to use a modified \fB\-\-read-batch\fP
-option, but you could edit the script file if you wished to make use of it
-(just be sure that no other option is trying to use standard input, such as
-the "\fB\-\-exclude-from=\-\fP" option).
+avoids the foo.sh script because it needed to use a modified
+\fB\-\-read-batch\fP option, but you could edit the script file if you
+wished to make use of it (just be sure that no other option is trying to use
+standard input, such as the \fB\-\-exclude-from=\-\fP option).
 .P
 Caveats:
 .P
@@ -4078,32 +4732,33 @@ already) or the file-update may be attempted and then, if the file fails to
 verify, the update discarded with an error.  This means that it should be safe
 to re-run a read-batch operation if the command got interrupted.  If you wish
 to force the batched-update to always be attempted regardless of the file's
-size and date, use the \fB\-I\fP option (when reading the batch).  If an error
-occurs, the destination tree will probably be in a partially updated state.  In
-that case, rsync can be used in its regular (non-batch) mode of operation to
-fix up the destination tree.
+size and date, use the \fB\-I\fP option (when reading the batch).  If an
+error occurs, the destination tree will probably be in a partially updated
+state.  In that case, rsync can be used in its regular (non-batch) mode of
+operation to fix up the destination tree.
 .P
 The rsync version used on all destinations must be at least as new as the one
 used to generate the batch file.  Rsync will die with an error if the protocol
 version in the batch file is too new for the batch-reading rsync to handle.
-See also the \fB\-\-protocol\fP option for a way to have the creating rsync generate
-a batch file that an older rsync can understand.  (Note that batch files
-changed format in version 2.6.3, so mixing versions older than that with newer
-versions will not work.)
+See also the \fB\-\-protocol\fP option for a way to have the creating rsync
+generate a batch file that an older rsync can understand.  (Note that batch
+files changed format in version 2.6.3, so mixing versions older than that with
+newer versions will not work.)
 .P
 When reading a batch file, rsync will force the value of certain options to
 match the data in the batch file if you didn't set them to the same as the
 batch-writing command.  Other options can (and should) be changed.  For
-instance \fB\-\-write-batch\fP changes to \fB\-\-read-batch\fP, \fB\-\-files-from\fP is dropped,
-and the \fB\-\-filter\fP / \fB\-\-include\fP / \fB\-\-exclude\fP options are not needed unless
-one of the \fB\-\-delete\fP options is specified.
+instance \fB\-\-write-batch\fP changes to \fB\-\-read-batch\fP,
+\fB\-\-files-from\fP is dropped, and the \fB\-\-filter\fP /
+\fB\-\-include\fP / \fB\-\-exclude\fP options are not needed unless one of
+the \fB\-\-delete\fP options is specified.
 .P
 The code that creates the BATCH.sh file transforms any filter/include/exclude
 options into a single list that is appended as a "here" document to the shell
 script file.  An advanced user can use this to modify the exclude list if a
-change in what gets deleted by \fB\-\-delete\fP is desired.  A normal user can ignore
-this detail and just use the shell script as an easy way to run the appropriate
-\fB\-\-read-batch\fP command for the batched data.
+change in what gets deleted by \fB\-\-delete\fP is desired.  A normal user
+can ignore this detail and just use the shell script as an easy way to run the
+appropriate \fB\-\-read-batch\fP command for the batched data.
 .P
 The original batch mode in rsync was based on "rsync+", but the latest
 version uses a new implementation.
@@ -4116,8 +4771,10 @@ link in the source directory.
 By default, symbolic links are not transferred at all.  A message "skipping
 non-regular" file is emitted for any symlinks that exist.
 .P
-If \fB\-\-links\fP is specified, then symlinks are recreated with the same target on
-the destination.  Note that \fB\-\-archive\fP implies \fB\-\-links\fP.
+If \fB\-\-links\fP is specified, then symlinks are added to the transfer
+(instead of being noisily ignored), and the default handling is to recreate
+them with the same target on the destination.  Note that \fB\-\-archive\fP
+implies \fB\-\-links\fP.
 .P
 If \fB\-\-copy-links\fP is specified, then symlinks are "collapsed" by
 copying their referent, rather than the symlink.
@@ -4125,36 +4782,48 @@ copying their referent, rather than the symlink.
 Rsync can also distinguish "safe" and "unsafe" symbolic links.  An example
 where this might be used is a web site mirror that wishes to ensure that the
 rsync module that is copied does not include symbolic links to \fB/etc/passwd\fP in
-the public section of the site.  Using \fB\-\-copy-unsafe-links\fP will cause any
-links to be copied as the file they point to on the destination.  Using
-\fB\-\-safe-links\fP will cause unsafe links to be omitted altogether. (Note that you
-must specify \fB\-\-links\fP for \fB\-\-safe-links\fP to have any effect.)
+the public section of the site.  Using \fB\-\-copy-unsafe-links\fP will cause
+any links to be copied as the file they point to on the destination.  Using
+\fB\-\-safe-links\fP will cause unsafe links to be omitted by the receiver.
+(Note that you must specify or imply \fB\-\-links\fP for
+\fB\-\-safe-links\fP to have any effect.)
 .P
-Symbolic links are considered unsafe if they are absolute symlinks
-(start with \fB/\fP), empty, or if they contain enough ".."
-components to ascend from the directory being copied.
+Symbolic links are considered unsafe if they are absolute symlinks (start with
+\fB/\fP), empty, or if they contain enough ".." components to ascend from the top
+of the transfer.
 .P
 Here's a summary of how the symlink options are interpreted.  The list is in
 order of precedence, so if your combination of options isn't mentioned, use the
 first line that is a complete subset of your options:
 .P
 .IP "\fB\-\-copy-links\fP"
-Turn all symlinks into normal files (leaving no symlinks for
-any other options to affect).
+Turn all symlinks into normal files and directories
+(leaving no symlinks in the transfer for any other options to affect).
+.IP "\fB\-\-copy-dirlinks\fP"
+Turn just symlinks to directories into real
+directories, leaving all other symlinks to be handled as described below.
 .IP "\fB\-\-links\ \-\-copy-unsafe-links\fP"
-Turn all unsafe symlinks into files and
-duplicate all safe symlinks.
+Turn all unsafe symlinks
+into files and create all safe symlinks.
 .IP "\fB\-\-copy-unsafe-links\fP"
-Turn all unsafe symlinks into files, noisily skip all
-safe symlinks.
+Turn all unsafe symlinks into files, noisily
+skip all safe symlinks.
 .IP "\fB\-\-links\ \-\-safe-links\fP"
-Duplicate safe symlinks and skip unsafe ones.
+The receiver skips creating
+unsafe symlinks found in the transfer and creates the safe ones.
 .IP "\fB\-\-links\fP"
-Duplicate all symlinks.
+Create all symlinks.
+.P
+For the effect of \fB\-\-munge-links\fP, see the discussion in that option's
+section.
+.P
+Note that the \fB\-\-keep-dirlinks\fP option does not effect symlinks in the
+transfer but instead affects how rsync treats a symlink to a directory that
+already exists on the receiving side.  See that option's section for a warning.
 .P
 .SH "DIAGNOSTICS"
 .P
-rsync occasionally produces error messages that may seem a little cryptic.  The
+Rsync occasionally produces error messages that may seem a little cryptic.  The
 one that seems to cause the most confusion is "protocol version mismatch\ \-\- is
 your shell clean?".
 .P
@@ -4181,48 +4850,54 @@ file is included or excluded.
 .P
 .SH "EXIT VALUES"
 .P
-.IP "\fB0\fP"
-Success
-.IP "\fB1\fP"
-Syntax or usage error
-.IP "\fB2\fP"
-Protocol incompatibility
-.IP "\fB3\fP"
-Errors selecting input/output files, dirs
-.IP "\fB4\fP"
-Requested action not supported: an attempt was made to manipulate
-64-bit files on a platform that cannot support them; or an option was
-specified that is supported by the client and not by the server.
-.IP "\fB5\fP"
-Error starting client-server protocol
-.IP "\fB6\fP"
-Daemon unable to append to log-file
-.IP "\fB10\fP"
-Error in socket I/O
-.IP "\fB11\fP"
-Error in file I/O
-.IP "\fB12\fP"
-Error in rsync protocol data stream
-.IP "\fB13\fP"
-Errors with program diagnostics
-.IP "\fB14\fP"
-Error in IPC code
-.IP "\fB20\fP"
-Received SIGUSR1 or SIGINT
-.IP "\fB21\fP"
-Some error returned by \fBwaitpid()\fP
-.IP "\fB22\fP"
-Error allocating core memory buffers
-.IP "\fB23\fP"
-Partial transfer due to error
-.IP "\fB24\fP"
-Partial transfer due to vanished source files
-.IP "\fB25\fP"
-The \-\-max-delete limit stopped deletions
-.IP "\fB30\fP"
-Timeout in data send/receive
-.IP "\fB35\fP"
-Timeout waiting for daemon connection
+.IP o
+\fB0\fP \- Success
+.IP o
+\fB1\fP \- Syntax or usage error
+.IP o
+\fB2\fP \- Protocol incompatibility
+.IP o
+\fB3\fP \- Errors selecting input/output files, dirs
+.IP o
+.P
+.RS
+.IP o
+\fB4\fP \- Requested action not supported. Either:
+
+an attempt was made to manipulate 64-bit files on a platform that cannot support them
+.IP o
+an option was specified that is supported by the client and not by the server
+.RE
+.IP o
+\fB5\fP \- Error starting client-server protocol
+.IP o
+\fB6\fP \- Daemon unable to append to log-file
+.IP o
+\fB10\fP \- Error in socket I/O
+.IP o
+\fB11\fP \- Error in file I/O
+.IP o
+\fB12\fP \- Error in rsync protocol data stream
+.IP o
+\fB13\fP \- Errors with program diagnostics
+.IP o
+\fB14\fP \- Error in IPC code
+.IP o
+\fB20\fP \- Received SIGUSR1 or SIGINT
+.IP o
+\fB21\fP \- Some error returned by \fBwaitpid()\fP
+.IP o
+\fB22\fP \- Error allocating core memory buffers
+.IP o
+\fB23\fP \- Partial transfer due to error
+.IP o
+\fB24\fP \- Partial transfer due to vanished source files
+.IP o
+\fB25\fP \- The \-\-max-delete limit stopped deletions
+.IP o
+\fB30\fP \- Timeout in data send/receive
+.IP o
+\fB35\fP \- Timeout waiting for daemon connection
 .P
 .SH "ENVIRONMENT VARIABLES"
 .P
@@ -4230,33 +4905,80 @@ Timeout waiting for daemon connection
 The CVSIGNORE environment variable supplements any ignore patterns in
 \&.cvsignore files.  See the \fB\-\-cvs-exclude\fP option for more details.
 .IP "\fBRSYNC_ICONV\fP"
-Specify a default \fB\-\-iconv\fP setting using this environment variable. (First
-supported in 3.0.0.)
+Specify a default \fB\-\-iconv\fP setting using this environment
+variable. First supported in 3.0.0.
+.IP "\fBRSYNC_OLD_ARGS\fP"
+Specify a "1" if you want the \fB\-\-old-args\fP option to be enabled by
+default, a "2" (or more) if you want it to be enabled in the
+repeated-option state, or a "0" to make sure that it is disabled by
+default. When this environment variable is set to a non-zero value, it
+supersedes the \fBRSYNC_PROTECT_ARGS\fP variable.
+.IP
+This variable is ignored if \fB\-\-old-args\fP, \fB\-\-no-old-args\fP, or
+\fB\-\-secluded-args\fP is specified on the command line.
+.IP
+First supported in 3.2.4.
 .IP "\fBRSYNC_PROTECT_ARGS\fP"
-Specify a non-zero numeric value if you want the \fB\-\-protect-args\fP option to
-be enabled by default, or a zero value to make sure that it is disabled by
-default. (First supported in 3.1.0.)
+Specify a non-zero numeric value if you want the \fB\-\-secluded-args\fP
+option to be enabled by default, or a zero value to make sure that it is
+disabled by default.
+.IP
+This variable is ignored if \fB\-\-secluded-args\fP, \fB\-\-no-secluded-args\fP,
+or \fB\-\-old-args\fP is specified on the command line.
+.IP
+First supported in 3.1.0.  Starting in 3.2.4, this variable is ignored if
+\fBRSYNC_OLD_ARGS\fP is set to a non-zero value.
 .IP "\fBRSYNC_RSH\fP"
-The RSYNC_RSH environment variable allows you to override the default shell
-used as the transport for rsync.  Command line options are permitted after
-the command name, just as in the \fB\-e\fP option.
+This environment variable allows you to override the default shell used as
+the transport for rsync.  Command line options are permitted after the
+command name, just as in the \fB\-\-rsh\fP (\fB\-e\fP) option.
 .IP "\fBRSYNC_PROXY\fP"
-The RSYNC_PROXY environment variable allows you to redirect your rsync
-client to use a web proxy when connecting to a rsync daemon.  You should
-set RSYNC_PROXY to a hostname:port pair.
+This environment variable allows you to redirect your rsync
+client to use a web proxy when connecting to an rsync daemon.  You should
+set \fBRSYNC_PROXY\fP to a hostname:port pair.
 .IP "\fBRSYNC_PASSWORD\fP"
-Setting RSYNC_PASSWORD to the required password allows you to run
-authenticated rsync connections to an rsync daemon without user
-intervention.  Note that this does not supply a password to a remote shell
-transport such as ssh; to learn how to do that, consult the remote shell's
-documentation.
+This environment variable allows you to set the password for an rsync
+\fBdaemon\fP connection, which avoids the password prompt.  Note that this
+does \fBnot\fP supply a password to a remote shell transport such as ssh
+(consult its documentation for how to do that).
 .IP "\fBUSER\fP or \fBLOGNAME\fP"
 The USER or LOGNAME environment variables are used to determine the default
 username sent to an rsync daemon.  If neither is set, the username defaults
-to "nobody".
+to "nobody".  If both are set, \fBUSER\fP takes precedence.
+.IP "\fBRSYNC_PARTIAL_DIR\fP"
+This environment variable specifies the directory to use for a
+\fB\-\-partial\fP transfer without implying that partial transfers be
+enabled.  See the \fB\-\-partial-dir\fP option for full details.
+.IP "\fBRSYNC_COMPRESS_LIST\fP"
+This environment variable allows you to customize the negotiation of the
+compression algorithm by specifying an alternate order or a reduced list of
+names.  Use the command \fBrsync\ \-\-version\fP to see the available compression
+names.  See the \fB\-\-compress\fP option for full details.
+.IP "\fBRSYNC_CHECKSUM_LIST\fP"
+This environment variable allows you to customize the negotiation of the
+checksum algorithm by specifying an alternate order or a reduced list of
+names.  Use the command \fBrsync\ \-\-version\fP to see the available checksum
+names.  See the \fB\-\-checksum-choice\fP option for full details.
+.IP "\fBRSYNC_MAX_ALLOC\fP"
+This environment variable sets an allocation maximum as if you had used the
+\fB\-\-max-alloc\fP option.
+.IP "\fBRSYNC_PORT\fP"
+This environment variable is not read by rsync, but is instead set in
+its sub-environment when rsync is running the remote shell in combination
+with a daemon connection.  This allows a script such as
+\fBrsync-ssl\fP to be able to know the port number that the user
+specified on the command line.
 .IP "\fBHOME\fP"
-The HOME environment variable is used to find the user's default .cvsignore
+This environment variable is used to find the user's default .cvsignore
 file.
+.IP "\fBRSYNC_CONNECT_PROG\fP"
+This environment variable is mainly used in debug setups to set the program
+to use when making a daemon connection.  See CONNECTING TO AN RSYNC
+DAEMON for full details.
+.IP "\fBRSYNC_SHELL\fP"
+This environment variable is mainly used in debug setups to set the program
+to use to run the program specified by \fBRSYNC_CONNECT_PROG\fP.  See
+CONNECTING TO AN RSYNC DAEMON for full details.
 .P
 .SH "FILES"
 .P
@@ -4264,26 +4986,25 @@ file.
 .P
 .SH "SEE ALSO"
 .P
-\fBrsync-ssl\fP(1), \fBrsyncd.conf\fP(5)
+\fBrsync-ssl\fP(1), \fBrsyncd.conf\fP(5), \fBrrsync\fP(1)
 .P
 .SH "BUGS"
 .P
-times are transferred as *nix time_t values
-.P
-When transferring to FAT filesystems rsync may re-sync
-unmodified files.
-See the comments on the \fB\-\-modify-window\fP option.
-.P
-file permissions, devices, etc. are transferred as native numerical
-values
-.P
-see also the comments on the \fB\-\-delete\fP option
+.IP o
+Times are transferred as *nix time_t values.
+.IP o
+When transferring to FAT filesystems rsync may re-sync unmodified files.  See
+the comments on the \fB\-\-modify-window\fP option.
+.IP o
+File permissions, devices, etc. are transferred as native numerical values.
+.IP o
+See also the comments on the \fB\-\-delete\fP option.
 .P
 Please report bugs! See the web site at https://rsync.samba.org/.
 .P
 .SH "VERSION"
 .P
-This man page is current for version 3.2.3 of rsync.
+This manpage is current for version 3.2.7 of rsync.
 .P
 .SH "INTERNAL OPTIONS"
 .P
@@ -4296,11 +5017,14 @@ that can be used with a restricted ssh login.
 .P
 .SH "CREDITS"
 .P
-rsync is distributed under the GNU General Public License.  See the file
+Rsync is distributed under the GNU General Public License.  See the file
 COPYING for details.
 .P
-A web site is available at https://rsync.samba.org/.  The site includes an
-FAQ-O-Matic which may cover questions unanswered by this manual page.
+An rsync web site is available at https://rsync.samba.org/.  The site
+includes an FAQ-O-Matic which may cover questions unanswered by this manual
+page.
+.P
+The rsync github project is https://github.com/WayneD/rsync.
 .P
 We would be delighted to hear from you if you like this program.  Please
 contact the mailing-list at rsync@lists.samba.org.
@@ -4319,7 +5043,7 @@ David Bell.  I've probably missed some people, my apologies if I have.
 .P
 .SH "AUTHOR"
 .P
-rsync was originally written by Andrew Tridgell and Paul Mackerras.  Many
+Rsync was originally written by Andrew Tridgell and Paul Mackerras.  Many
 people have later contributed to it. It is currently maintained by Wayne
 Davison.
 .P
index d6baaf0..453b2cd 100644 (file)
@@ -1,5 +1,6 @@
 <html><head>
-<title>rsync(1) man page</title>
+<title>rsync(1) manpage</title>
+<meta charset="UTF-8"/>
 <link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap" rel="stylesheet">
 <style>
 body {
@@ -9,6 +10,10 @@ body {
 body, b, strong, u {
   font-family: 'Roboto', sans-serif;
 }
+a.tgt { font-face: symbol; font-weight: 400; font-size: 70%; visibility: hidden; text-decoration: none; color: #ddd; padding: 0 4px; border: 0; }
+a.tgt:after { content: '🔗'; }
+a.tgt:hover { color: #444; background-color: #eaeaea; }
+h1:hover > a.tgt, h2:hover > a.tgt, h3:hover > a.tgt, dt:hover > a.tgt { visibility: visible; }
 code {
   font-family: 'Roboto Mono', monospace;
   font-weight: bold;
@@ -26,9 +31,9 @@ dd p:first-of-type {
 }
 </style>
 </head><body>
-<h1>NAME</h1>
+<h2 id="NAME">NAME<a href="#NAME" class="tgt"></a></h2>
 <p>rsync -&#8288; a fast, versatile, remote (and local) file-copying tool</p>
-<h1>SYNOPSIS</h1>
+<h2 id="SYNOPSIS">SYNOPSIS<a href="#SYNOPSIS" class="tgt"></a></h2>
 <pre><code>Local:
     rsync [OPTION...] SRC... [DEST]
 
@@ -48,7 +53,9 @@ Access via rsync daemon:
 </code></pre>
 <p>Usages with just one SRC arg and no DEST arg will list the source files instead
 of copying.</p>
-<h1>DESCRIPTION</h1>
+<p>The online version of this manpage (that includes cross-linking of topics)
+is available at <a href="https://download.samba.org/pub/rsync/rsync.1">https://download.samba.org/pub/rsync/rsync.1</a>.</p>
+<h2 id="DESCRIPTION">DESCRIPTION<a href="#DESCRIPTION" class="tgt"></a></h2>
 <p>Rsync is a fast and extraordinarily versatile file copying tool.  It can copy
 locally, to/from another host over any remote shell, or to/from a remote rsync
 daemon.  It offers a large number of options that control every aspect of its
@@ -73,7 +80,7 @@ the file's data does not need to be updated.</p>
 <li>pipelining of file transfers to minimize latency costs</li>
 <li>support for anonymous or authenticated rsync daemons (ideal for mirroring)</li>
 </ul>
-<h1>GENERAL</h1>
+<h2 id="GENERAL">GENERAL<a href="#GENERAL" class="tgt"></a></h2>
 <p>Rsync copies files either to or from a remote host, or locally on the current
 host (it does not support copying files between two remote hosts).</p>
 <p>There are two different ways for rsync to contact a remote system: using a
@@ -82,27 +89,27 @@ rsync daemon directly via TCP.  The remote-shell transport is used whenever the
 source or destination path contains a single colon (:) separator after a host
 specification.  Contacting an rsync daemon directly happens when the source or
 destination path contains a double colon (::) separator after a host
-specification, OR when an rsync:// URL is specified (see also the &quot;USING
-RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION&quot; section for an exception
-to this latter rule).</p>
+specification, OR when an rsync:// URL is specified (see also the <a href="#USING_RSYNC-DAEMON_FEATURES_VIA_A_REMOTE-SHELL_CONNECTION">USING
+RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION</a> section for an
+exception to this latter rule).</p>
 <p>As a special case, if a single source arg is specified without a destination,
 the files are listed in an output format similar to &quot;<code>ls -l</code>&quot;.</p>
 <p>As expected, if neither the source or destination path specify a remote host,
-the copy occurs locally (see also the <code>--list-only</code> option).</p>
+the copy occurs locally (see also the <a href="#opt--list-only"><code>--list-only</code></a> option).</p>
 <p>Rsync refers to the local side as the client and the remote side as the server.
 Don't confuse server with an rsync daemon.  A daemon is always a server, but a
 server can be either a daemon or a remote-shell spawned process.</p>
-<h1>SETUP</h1>
+<h2 id="SETUP">SETUP<a href="#SETUP" class="tgt"></a></h2>
 <p>See the file README.md for installation instructions.</p>
 <p>Once installed, you can use rsync to any machine that you can access via a
 remote shell (as well as some that you can access using the rsync daemon-mode
 protocol).  For remote transfers, a modern rsync uses ssh for its
 communications, but it may have been configured to use a different remote shell
 by default, such as rsh or remsh.</p>
-<p>You can also specify any remote shell you like, either by using the <code>-e</code>
-command line option, or by setting the RSYNC_RSH environment variable.</p>
+<p>You can also specify any remote shell you like, either by using the <a href="#opt-e"><code>-e</code></a>
+command line option, or by setting the <a href="#RSYNC_RSH"><code>RSYNC_RSH</code></a> environment variable.</p>
 <p>Note that rsync must be installed on both the source and destination machines.</p>
-<h1>USAGE</h1>
+<h2 id="USAGE">USAGE<a href="#USAGE" class="tgt"></a></h2>
 <p>You use rsync in the same way you use rcp.  You must specify a source and a
 destination, one of which may be remote.</p>
 <p>Perhaps the best way to explain the syntax is with some examples:</p>
@@ -160,53 +167,152 @@ rsync daemon by leaving off the module name:</p>
 <pre><code>rsync somehost.mydomain.com::
 </code></pre>
 </blockquote>
-<p>See the following section for more details.</p>
-<h1>ADVANCED USAGE</h1>
-<p>The syntax for requesting multiple files from a remote host is done by
-specifying additional remote-host args in the same style as the first, or with
-the hostname omitted.  For instance, all these work:</p>
+<h2 id="COPYING_TO_A_DIFFERENT_NAME">COPYING TO A DIFFERENT NAME<a href="#COPYING_TO_A_DIFFERENT_NAME" class="tgt"></a></h2>
+<p>When you want to copy a directory to a different name, use a trailing slash on
+the source directory to put the contents of the directory into any destination
+directory you like:</p>
+<blockquote>
+<pre><code>rsync -ai foo/ bar/
+</code></pre>
+</blockquote>
+<p>Rsync also has the ability to customize a destination file's name when copying
+a single item.  The rules for this are:</p>
+<ul>
+<li>The transfer list must consist of a single item (either a file or an empty
+directory)</li>
+<li>The final element of the destination path must not exist as a directory</li>
+<li>The destination path must not have been specified with a trailing slash</li>
+</ul>
+<p>Under those circumstances, rsync will set the name of the destination's single
+item to the last element of the destination path.  Keep in mind that it is best
+to only use this idiom when copying a file and use the above trailing-slash
+idiom when copying a directory.</p>
+<p>The following example copies the <code>foo.c</code> file as <code>bar.c</code> in the <code>save</code> dir
+(assuming that <code>bar.c</code> isn't a directory):</p>
+<blockquote>
+<pre><code>rsync -ai src/foo.c save/bar.c
+</code></pre>
+</blockquote>
+<p>The single-item copy rule might accidentally bite you if you unknowingly copy a
+single item and specify a destination dir that doesn't exist (without using a
+trailing slash).  For example, if <code>src/*.c</code> matches one file and <code>save/dir</code>
+doesn't exist, this will confuse you by naming the destination file <code>save/dir</code>:</p>
 <blockquote>
-<pre><code>rsync -av host:file1 :file2 host:file{3,4} /dest/
-rsync -av host::modname/file{1,2} host::modname/file3 /dest/
-rsync -av host::modname/file1 ::modname/file{3,4}
+<pre><code>rsync -ai src/*.c save/dir
 </code></pre>
 </blockquote>
-<p>Older versions of rsync required using quoted spaces in the SRC, like these
-examples:</p>
+<p>To prevent such an accident, either make sure the destination dir exists or
+specify the destination path with a trailing slash:</p>
+<blockquote>
+<pre><code>rsync -ai src/*.c save/dir/
+</code></pre>
+</blockquote>
+<h2 id="SORTED_TRANSFER_ORDER">SORTED TRANSFER ORDER<a href="#SORTED_TRANSFER_ORDER" class="tgt"></a></h2>
+<p>Rsync always sorts the specified filenames into its internal transfer list.
+This handles the merging together of the contents of identically named
+directories, makes it easy to remove duplicate filenames. It can, however,
+confuse someone when the files are transferred in a different order than what
+was given on the command-line.</p>
+<p>If you need a particular file to be transferred prior to another, either
+separate the files into different rsync calls, or consider using
+<a href="#opt--delay-updates"><code>--delay-updates</code></a> (which doesn't affect the sorted transfer order, but
+does make the final file-updating phase happen much more rapidly).</p>
+<h2 id="MULTI-HOST_SECURITY">MULTI-HOST SECURITY<a href="#MULTI-HOST_SECURITY" class="tgt"></a></h2>
+<p>Rsync takes steps to ensure that the file requests that are shared in a
+transfer are protected against various security issues.  Most of the potential
+problems arise on the receiving side where rsync takes steps to ensure that the
+list of files being transferred remains within the bounds of what was
+requested.</p>
+<p>Toward this end, rsync 3.1.2 and later have aborted when a file list contains
+an absolute or relative path that tries to escape out of the top of the
+transfer.  Also, beginning with version 3.2.5, rsync does two more safety
+checks of the file list to (1) ensure that no extra source arguments were added
+into the transfer other than those that the client requested and (2) ensure
+that the file list obeys the exclude rules that were sent to the sender.</p>
+<p>For those that don't yet have a 3.2.5 client rsync (or those that want to be
+extra careful), it is safest to do a copy into a dedicated destination
+directory for the remote files when you don't trust the remote host.  For
+example, instead of doing an rsync copy into your home directory:</p>
 <blockquote>
-<pre><code>rsync -av host:'dir1/file1 dir2/file2' /dest
-rsync host::'modname/dir1/file1 modname/dir2/file2' /dest
+<pre><code>rsync -aiv host1:dir1 ~
 </code></pre>
 </blockquote>
-<p>This word-splitting still works (by default) in the latest rsync, but is not as
-easy to use as the first method.</p>
-<p>If you need to transfer a filename that contains whitespace, you can either
-specify the <code>--protect-args</code> (<code>-s</code>) option, or you'll need to escape the
-whitespace in a way that the remote shell will understand.  For instance:</p>
+<p>Dedicate a &quot;host1-files&quot; dir to the remote content:</p>
 <blockquote>
-<pre><code>rsync -av host:'file\ name\ with\ spaces' /dest
+<pre><code>rsync -aiv host1:dir1 ~/host1-files
 </code></pre>
 </blockquote>
-<h1>CONNECTING TO AN RSYNC DAEMON</h1>
+<p>See the <a href="#opt--trust-sender"><code>--trust-sender</code></a> option for additional details.</p>
+<p>CAUTION: it is not particularly safe to use rsync to copy files from a
+case-preserving filesystem to a case-ignoring filesystem.  If you must perform
+such a copy, you should either disable symlinks via <code>--no-links</code> or enable the
+munging of symlinks via <a href="#opt--munge-links"><code>--munge-links</code></a> (and make sure you use the
+right local or remote option).  This will prevent rsync from doing potentially
+dangerous things if a symlink name overlaps with a file or directory. It does
+not, however, ensure that you get a full copy of all the files (since that may
+not be possible when the names overlap). A potentially better solution is to
+list all the source files and create a safe list of filenames that you pass to
+the <a href="#opt--files-from"><code>--files-from</code></a> option.  Any files that conflict in name would need
+to be copied to different destination directories using more than one copy.</p>
+<p>While a copy of a case-ignoring filesystem to a case-ignoring filesystem can
+work out fairly well, if no <code>--delete-during</code> or <code>--delete-before</code> option is
+active, rsync can potentially update an existing file on the receiveing side
+without noticing that the upper-/lower-case of the filename should be changed
+to match the sender.</p>
+<h2 id="ADVANCED_USAGE">ADVANCED USAGE<a href="#ADVANCED_USAGE" class="tgt"></a></h2>
+<p>The syntax for requesting multiple files from a remote host is done by
+specifying additional remote-host args in the same style as the first, or with
+the hostname omitted.  For instance, all these work:</p>
+<blockquote>
+<pre><code>rsync -aiv host:file1 :file2 host:file{3,4} /dest/
+rsync -aiv host::modname/file{1,2} host::modname/extra /dest/
+rsync -aiv host::modname/first ::extra-file{1,2} /dest/
+</code></pre>
+</blockquote>
+<p>Note that a daemon connection only supports accessing one module per copy
+command, so if the start of a follow-up path doesn't begin with the
+modname of the first path, it is assumed to be a path in the module (such as
+the extra-file1 &amp; extra-file2 that are grabbed above).</p>
+<p>Really old versions of rsync (2.6.9 and before) only allowed specifying one
+remote-source arg, so some people have instead relied on the remote-shell
+performing space splitting to break up an arg into multiple paths. Such
+unintuitive behavior is no longer supported by default (though you can request
+it, as described below).</p>
+<p>Starting in 3.2.4, filenames are passed to a remote shell in such a way as to
+preserve the characters you give it. Thus, if you ask for a file with spaces
+in the name, that's what the remote rsync looks for:</p>
+<blockquote>
+<pre><code>rsync -aiv host:'a simple file.pdf' /dest/
+</code></pre>
+</blockquote>
+<p>If you use scripts that have been written to manually apply extra quoting to
+the remote rsync args (or to require remote arg splitting), you can ask rsync
+to let your script handle the extra escaping.  This is done by either adding
+the <a href="#opt--old-args"><code>--old-args</code></a> option to the rsync runs in the script (which requires
+a new rsync) or exporting <a href="#RSYNC_OLD_ARGS">RSYNC_OLD_ARGS</a>=1 and <a href="#RSYNC_PROTECT_ARGS">RSYNC_PROTECT_ARGS</a>=0
+(which works with old or new rsync versions).</p>
+<h2 id="CONNECTING_TO_AN_RSYNC_DAEMON">CONNECTING TO AN RSYNC DAEMON<a href="#CONNECTING_TO_AN_RSYNC_DAEMON" class="tgt"></a></h2>
 <p>It is also possible to use rsync without a remote shell as the transport.  In
 this case you will directly connect to a remote rsync daemon, typically using
 TCP port 873. (This obviously requires the daemon to be running on the remote
-system, so refer to the STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS section
-below for information on that.)</p>
+system, so refer to the <a href="#STARTING_AN_RSYNC_DAEMON_TO_ACCEPT_CONNECTIONS">STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS</a>
+section below for information on that.)</p>
 <p>Using rsync in this way is the same as using it with a remote shell except
 that:</p>
 <ul>
-<li>you either use a double colon :: instead of a single colon to separate the
-hostname from the path, or you use an rsync:// URL.</li>
-<li>the first word of the &quot;path&quot; is actually a module name.</li>
-<li>the remote daemon may print a message of the day when you connect.</li>
-<li>if you specify no path name on the remote daemon then the list of accessible
-paths on the daemon will be shown.</li>
-<li>if you specify no local destination then a listing of the specified files on
-the remote daemon is provided.</li>
-<li>you must not specify the <code>--rsh</code> (<code>-e</code>) option (since that overrides the
-daemon connection to use ssh&nbsp;-&#8288;-&#8288; see USING RSYNC-DAEMON FEATURES VIA A
-REMOTE-SHELL CONNECTION below).</li>
+<li>Use either double-colon syntax or rsync:// URL syntax instead of the
+single-colon (remote shell) syntax.</li>
+<li>The first element of the &quot;path&quot; is actually a module name.</li>
+<li>Additional remote source args can use an abbreviated syntax that omits the
+hostname and/or the module name, as discussed in <a href="#ADVANCED_USAGE">ADVANCED USAGE</a>.</li>
+<li>The remote daemon may print a &quot;message of the day&quot; when you connect.</li>
+<li>If you specify only the host (with no module or path) then a list of
+accessible modules on the daemon is output.</li>
+<li>If you specify a remote source path but no destination, a listing of the
+matching files on the remote daemon is output.</li>
+<li>The <a href="#opt--rsh"><code>--rsh</code></a> (<code>-e</code>) option must be omitted to avoid changing the
+connection style from using a socket connection to <a href="#USING_RSYNC-DAEMON_FEATURES_VIA_A_REMOTE-SHELL_CONNECTION">USING RSYNC-DAEMON
+FEATURES VIA A REMOTE-SHELL CONNECTION</a>.</li>
 </ul>
 <p>An example that copies all the files in a remote module named &quot;src&quot;:</p>
 <blockquote>
@@ -215,19 +321,20 @@ REMOTE-SHELL CONNECTION below).</li>
 </blockquote>
 <p>Some modules on the remote daemon may require authentication.  If so, you will
 receive a password prompt when you connect.  You can avoid the password prompt
-by setting the environment variable RSYNC_PASSWORD to the password you want to
-use or using the <code>--password-file</code> option.  This may be useful when scripting
-rsync.</p>
+by setting the environment variable <a href="#RSYNC_PASSWORD"><code>RSYNC_PASSWORD</code></a> to the password you
+want to use or using the <a href="#opt--password-file"><code>--password-file</code></a> option.  This may be useful
+when scripting rsync.</p>
 <p>WARNING: On some systems environment variables are visible to all users.  On
-those systems using <code>--password-file</code> is recommended.</p>
+those systems using <a href="#opt--password-file"><code>--password-file</code></a> is recommended.</p>
 <p>You may establish the connection via a web proxy by setting the environment
-variable RSYNC_PROXY to a hostname:port pair pointing to your web proxy.  Note
-that your web proxy's configuration must support proxy connections to port 873.</p>
+variable <a href="#RSYNC_PROXY"><code>RSYNC_PROXY</code></a> to a hostname:port pair pointing to your web proxy.
+Note that your web proxy's configuration must support proxy connections to port
+873.</p>
 <p>You may also establish a daemon connection using a program as a proxy by
-setting the environment variable RSYNC_CONNECT_PROG to the commands you wish to
-run in place of making a direct socket connection.  The string may contain the
-escape &quot;%H&quot; to represent the hostname specified in the rsync command (so use
-&quot;%%&quot; if you need a single &quot;%&quot; in your string).  For example:</p>
+setting the environment variable <a href="#RSYNC_CONNECT_PROG"><code>RSYNC_CONNECT_PROG</code></a> to the commands you
+wish to run in place of making a direct socket connection.  The string may
+contain the escape &quot;%H&quot; to represent the hostname specified in the rsync
+command (so use &quot;%%&quot; if you need a single &quot;%&quot; in your string).  For example:</p>
 <blockquote>
 <pre><code>export RSYNC_CONNECT_PROG='ssh proxyhost nc %H 873'
 rsync -av targethost1::module/src/ /dest/
@@ -236,10 +343,10 @@ rsync -av rsync://targethost2/module/src/ /dest/
 </blockquote>
 <p>The command specified above uses ssh to run nc (netcat) on a proxyhost, which
 forwards all data to port 873 (the rsync daemon) on the targethost (%H).</p>
-<p>Note also that if the RSYNC_SHELL environment variable is set, that program
-will be used to run the RSYNC_CONNECT_PROG command instead of using the default
-shell of the <strong>system()</strong> call.</p>
-<h1>USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION</h1>
+<p>Note also that if the <a href="#RSYNC_SHELL"><code>RSYNC_SHELL</code></a> environment variable is set, that
+program will be used to run the <code>RSYNC_CONNECT_PROG</code> command instead of using
+the default shell of the <strong>system()</strong> call.</p>
+<h2 id="USING_RSYNC-DAEMON_FEATURES_VIA_A_REMOTE-SHELL_CONNECTION">USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION<a href="#USING_RSYNC-DAEMON_FEATURES_VIA_A_REMOTE-SHELL_CONNECTION" class="tgt"></a></h2>
 <p>It is sometimes useful to use various features of an rsync daemon (such as
 named modules) without actually allowing any new socket connections into a
 system (other than what is already required to allow remote-shell access).
@@ -254,7 +361,7 @@ on that remote host to only allow connections from &quot;localhost&quot;.)</p>
 <p>From the user's perspective, a daemon transfer via a remote-shell connection
 uses nearly the same command-line syntax as a normal rsync-daemon transfer,
 with the only exception being that you must explicitly set the remote shell
-program on the command-line with the <code>--rsh=COMMAND</code> option. (Setting the
+program on the command-line with the <a href="#opt--rsh"><code>--rsh=COMMAND</code></a> option. (Setting the
 RSYNC_RSH in the environment will not turn on this functionality.) For example:</p>
 <blockquote>
 <pre><code>rsync -av --rsh=ssh host::module /dest
@@ -264,64 +371,42 @@ RSYNC_RSH in the environment will not turn on this functionality.) For example:<
 user@ prefix in front of the host is specifying the rsync-user value (for a
 module that requires user-based authentication).  This means that you must give
 the '-&#8288;l user' option to ssh when specifying the remote-shell, as in this
-example that uses the short version of the <code>--rsh</code> option:</p>
+example that uses the short version of the <a href="#opt--rsh"><code>--rsh</code></a> option:</p>
 <blockquote>
 <pre><code>rsync -av -e &quot;ssh -l ssh-user&quot; rsync-user@host::module /dest
 </code></pre>
 </blockquote>
 <p>The &quot;ssh-user&quot; will be used at the ssh level; the &quot;rsync-user&quot; will be used to
 log-in to the &quot;module&quot;.</p>
-<h1>STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS</h1>
+<p>In this setup, the daemon is started by the ssh command that is accessing the
+system (which can be forced via the <code>~/.ssh/authorized_keys</code> file, if desired).
+However, when accessing a daemon directly, it needs to be started beforehand.</p>
+<h2 id="STARTING_AN_RSYNC_DAEMON_TO_ACCEPT_CONNECTIONS">STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS<a href="#STARTING_AN_RSYNC_DAEMON_TO_ACCEPT_CONNECTIONS" class="tgt"></a></h2>
 <p>In order to connect to an rsync daemon, the remote system needs to have a
 daemon already running (or it needs to have configured something like inetd to
 spawn an rsync daemon for incoming connections on a particular port).  For full
 information on how to start a daemon that will handling incoming socket
-connections, see the <strong>rsyncd.conf</strong>(5) man page&nbsp;-&#8288;-&#8288; that is the config file for
-the daemon, and it contains the full details for how to run the daemon
-(including stand-alone and inetd configurations).</p>
+connections, see the <a href="rsyncd.conf.5"><strong>rsyncd.conf</strong>(5)</a> manpage&nbsp;-&#8288;-&#8288; that is
+the config file for the daemon, and it contains the full details for how to run
+the daemon (including stand-alone and inetd configurations).</p>
 <p>If you're using one of the remote-shell transports for the transfer, there is
 no need to manually start an rsync daemon.</p>
-<h1>SORTED TRANSFER ORDER</h1>
-<p>Rsync always sorts the specified filenames into its internal transfer list.
-This handles the merging together of the contents of identically named
-directories, makes it easy to remove duplicate filenames, and may confuse
-someone when the files are transferred in a different order than what was given
-on the command-line.</p>
-<p>If you need a particular file to be transferred prior to another, either
-separate the files into different rsync calls, or consider using
-<code>--delay-updates</code> (which doesn't affect the sorted transfer order, but does
-make the final file-updating phase happen much more rapidly).</p>
-<h1>EXAMPLES</h1>
-<p>Here are some examples of how I use rsync.</p>
-<p>To backup my wife's home directory, which consists of large MS Word files and
-mail folders, I use a cron job that runs</p>
-<blockquote>
-<pre><code>rsync -Cavz . arvidsjaur:backup
-</code></pre>
-</blockquote>
-<p>each night over a PPP connection to a duplicate directory on my machine
-&quot;arvidsjaur&quot;.</p>
-<p>To synchronize my samba source trees I use the following Makefile targets:</p>
+<h2 id="EXAMPLES">EXAMPLES<a href="#EXAMPLES" class="tgt"></a></h2>
+<p>Here are some examples of how rsync can be used.</p>
+<p>To backup a home directory, which consists of large MS Word files and mail
+folders, a per-user cron job can be used that runs this each day:</p>
 <blockquote>
-<pre><code>get:
-    rsync -avuzb --exclude '*~' samba:samba/ .
-put:
-    rsync -Cavuzb . samba:samba/
-sync: get put
+<pre><code>rsync -aiz . bkhost:backup/joe/
 </code></pre>
 </blockquote>
-<p>This allows me to sync with a CVS directory at the other end of the connection.
-I then do CVS operations on the remote machine, which saves a lot of time as
-the remote CVS protocol isn't very efficient.</p>
-<p>I mirror a directory between my &quot;old&quot; and &quot;new&quot; ftp sites with the command:</p>
+<p>To move some files from a remote host to the local host, you could run:</p>
 <blockquote>
-<pre><code>rsync -az -e ssh --delete ~ftp/pub/samba nimbus:&quot;~ftp/pub/tridge&quot;
+<pre><code>rsync -aiv --remove-source-files rhost:/tmp/{file1,file2}.c ~/src/
 </code></pre>
 </blockquote>
-<p>This is launched from cron every few hours.</p>
-<h1>OPTION SUMMARY</h1>
-<p>Here is a short summary of the options available in rsync.  Please refer to the
-detailed description below for a complete description.</p>
+<h2 id="OPTION_SUMMARY">OPTION SUMMARY<a href="#OPTION_SUMMARY" class="tgt"></a></h2>
+<p>Here is a short summary of the options available in rsync.  Each option also
+has its own detailed description later in this manpage.</p>
 <pre><code>--verbose, -v            increase verbosity
 --info=FLAGS             fine-grained informational verbosity
 --debug=FLAGS            fine-grained debug verbosity
@@ -329,7 +414,7 @@ detailed description below for a complete description.</p>
 --quiet, -q              suppress non-error messages
 --no-motd                suppress daemon-mode MOTD
 --checksum, -c           skip based on checksum, not mod-time &amp; size
---archive, -a            archive mode; equals -rlptgoD (no -H,-A,-X)
+--archive, -a            archive mode is -rlptgoD (no -A,-X,-U,-N,-H)
 --no-OPTION              turn off an implied OPTION (e.g. --no-D)
 --recursive, -r          recurse into directories
 --relative, -R           use relative path names
@@ -342,7 +427,8 @@ detailed description below for a complete description.</p>
 --append                 append data onto shorter files
 --append-verify          --append w/old data in file checksum
 --dirs, -d               transfer directories without recursing
---mkpath                 create the destination's path component
+--old-dirs, --old-d      works like --dirs when talking to old rsync
+--mkpath                 create destination's missing path components
 --links, -l              copy symlinks as symlinks
 --copy-links, -L         transform symlink into referent file/dir
 --copy-unsafe-links      only &quot;unsafe&quot; symlinks are transformed
@@ -359,6 +445,8 @@ detailed description below for a complete description.</p>
 --owner, -o              preserve owner (super-user only)
 --group, -g              preserve group
 --devices                preserve device files (super-user only)
+--copy-devices           copy device contents as a regular file
+--write-devices          write to devices as files (implies --inplace)
 --specials               preserve special files
 -D                       same as --devices --specials
 --times, -t              preserve modification times
@@ -371,7 +459,6 @@ detailed description below for a complete description.</p>
 --fake-super             store/recover privileged attrs using xattrs
 --sparse, -S             turn sequences of nulls into sparse blocks
 --preallocate            allocate dest files before writing them
---write-devices          write to devices as files (implies --inplace)
 --dry-run, -n            perform a trial run with no changes made
 --whole-file, -W         copy files whole (w/o delta-xfer algorithm)
 --checksum-choice=STR    choose the checksum algorithm (aka --cc)
@@ -429,7 +516,9 @@ detailed description below for a complete description.</p>
 --include-from=FILE      read include patterns from FILE
 --files-from=FILE        read list of source-file names from FILE
 --from0, -0              all *-from/filter files are delimited by 0s
---protect-args, -s       no space-splitting; wildcard chars only
+--old-args               disable the modern arg-protection idiom
+--secluded-args, -s      use the protocol to safely send the args
+--trust-sender           trust the remote sender's file list
 --copy-as=USER[:GROUP]   specify user &amp; optional group for the copy
 --address=ADDRESS        bind address for outgoing socket to daemon
 --port=PORT              specify double-colon alternate port number
@@ -452,6 +541,7 @@ detailed description below for a complete description.</p>
 --bwlimit=RATE           limit socket I/O bandwidth
 --stop-after=MINS        Stop rsync after MINS minutes have elapsed
 --stop-at=y-m-dTh:m      Stop rsync at the specified point in time
+--fsync                  fsync every written file
 --write-batch=FILE       write a batched update to FILE
 --only-write-batch=FILE  like --write-batch but w/o updating dest
 --read-batch=FILE        read a batched update from FILE
@@ -480,46 +570,63 @@ accepted:</p>
 --ipv6, -6               prefer IPv6
 --help, -h               show this help (when used with --daemon)
 </code></pre>
-<h1>OPTIONS</h1>
+<h2 id="OPTIONS">OPTIONS<a href="#OPTIONS" class="tgt"></a></h2>
 <p>Rsync accepts both long (double-dash + word) and short (single-dash + letter)
 options.  The full list of the available options are described below.  If an
 option can be specified in more than one way, the choices are comma-separated.
-Some options only have a long variant, not a short.  If the option takes a
-parameter, the parameter is only listed after the long variant, even though it
-must also be specified for the short.  When specifying a parameter, you can
-either use the form <code>--option=param</code> or replace the '=' with whitespace.  The
-parameter may need to be quoted in some manner for it to survive the shell's
-command-line parsing.  Keep in mind that a leading tilde (<code>~</code>) in a filename is
-substituted by your shell, so <code>--option=~/foo</code> will not change the tilde into
-your home directory (remove the '=' for that).</p>
+Some options only have a long variant, not a short.</p>
+<p>If the option takes a parameter, the parameter is only listed after the long
+variant, even though it must also be specified for the short.  When specifying
+a parameter, you can either use the form <code>--option=param</code>, <code>--option param</code>,
+<code>-o=param</code>, <code>-o param</code>, or <code>-oparam</code> (the latter choices assume that your
+option has a short variant).</p>
+<p>The parameter may need to be quoted in some manner for it to survive the
+shell's command-line parsing.  Also keep in mind that a leading tilde (<code>~</code>) in
+a pathname is substituted by your shell, so make sure that you separate the
+option name from the pathname using a space if you want the local shell to
+expand it.</p>
 <dl>
 
-<dt><code>--help</code>, <code>-h</code> <code>(*)</code></dt><dd>
+<dt id="opt--help"><code>--help</code><a href="#opt--help" class="tgt"></a></dt><dd>
 <p>Print a short help page describing the options available in rsync and exit.
-(*) The <code>-h</code> short option will only invoke <code>--help</code> when used without other
-options since it normally means <code>--human-readable</code>.</p>
+You can also use <code>-h</code> for <code>--help</code> when it is used without any other
+options (since it normally means <a href="#opt--human-readable"><code>--human-readable</code></a>).</p>
 </dd>
 
-<dt><code>--version</code>, <code>-V</code></dt><dd>
-<p>Print the rsync version plus other info and exit.</p>
-<p>The output includes the default list of checksum algorithms, the default
-list of compression algorithms, a list of compiled-in capabilities, a link
-to the rsync web site, and some license/copyright info.</p>
+<span id="opt-V"></span><dt id="opt--version"><code>--version</code>, <code>-V</code><a href="#opt--version" class="tgt"></a></dt><dd>
+<p>Print the rsync version plus other info and exit.  When repeated, the
+information is output is a JSON format that is still fairly readable
+(client side only).</p>
+<p>The output includes a list of compiled-in capabilities, a list of
+optimizations, the default list of checksum algorithms, the default list of
+compression algorithms, the default list of daemon auth digests, a link to
+the rsync web site, and a few other items.</p>
 </dd>
 
-<dt><code>--verbose</code>, <code>-v</code></dt><dd>
+<span id="opt-v"></span><dt id="opt--verbose"><code>--verbose</code>, <code>-v</code><a href="#opt--verbose" class="tgt"></a></dt><dd>
 <p>This option increases the amount of information you are given during the
 transfer.  By default, rsync works silently.  A single <code>-v</code> will give you
 information about what files are being transferred and a brief summary at
 the end.  Two <code>-v</code> options will give you information on what files are
 being skipped and slightly more information at the end.  More than two <code>-v</code>
 options should only be used if you are debugging rsync.</p>
+<p>The end-of-run summary tells you the number of bytes sent to the remote
+rsync (which is the receiving side on a local copy), the number of bytes
+received from the remote host, and the average bytes per second of the
+transferred data computed over the entire length of the rsync run. The
+second line shows the total size (in bytes), which is the sum of all the
+file sizes that rsync considered transferring.  It also shows a &quot;speedup&quot;
+value, which is a ratio of the total file size divided by the sum of the
+sent and received bytes (which is really just a feel-good bigger-is-better
+number).  Note that these byte values can be made more (or less)
+human-readable by using the <a href="#opt--human-readable"><code>--human-readable</code></a> (or
+<code>--no-human-readable</code>) options.</p>
 <p>In a modern rsync, the <code>-v</code> option is equivalent to the setting of groups
-of <code>--info</code> and <code>--debug</code> options.  You can choose to use these newer
-options in addition to, or in place of using <code>--verbose</code>, as any
-fine-grained settings override the implied settings of <code>-v</code>.  Both <code>--info</code>
-and <code>--debug</code> have a way to ask for help that tells you exactly what flags
-are set for each increase in verbosity.</p>
+of <a href="#opt--info"><code>--info</code></a> and <a href="#opt--debug"><code>--debug</code></a> options.  You can choose to use
+these newer options in addition to, or in place of using <code>--verbose</code>, as
+any fine-grained settings override the implied settings of <code>-v</code>.  Both
+<a href="#opt--info"><code>--info</code></a> and <a href="#opt--debug"><code>--debug</code></a> have a way to ask for help that
+tells you exactly what flags are set for each increase in verbosity.</p>
 <p>However, do keep in mind that a daemon's &quot;<code>max verbosity</code>&quot; setting will limit
 how high of a level the various individual flags can be set on the daemon
 side.  For instance, if the max is 2, then any info and/or debug flag that
@@ -527,7 +634,7 @@ is set to a higher value than what would be set by <code>-vv</code> will be down
 to the <code>-vv</code> level in the daemon's logging.</p>
 </dd>
 
-<dt><code>--info=FLAGS</code></dt><dd>
+<dt id="opt--info"><code>--info=FLAGS</code><a href="#opt--info" class="tgt"></a></dt><dd>
 <p>This option lets you have fine-grained control over the information output
 you want to see.  An individual flag name may be followed by a level
 number, with 0 meaning to silence that output, 1 being the default output
@@ -540,16 +647,16 @@ increase in the verbose level.  Some examples:</p>
 rsync -avv --info=stats2,misc1,flist0 src/ dest/
 </code></pre>
 </blockquote>
-<p>Note that <code>--info=name</code>'s output is affected by the <code>--out-format</code> and
-<code>--itemize-changes</code> (<code>-i</code>) options.  See those options for more information
-on what is output and when.</p>
+<p>Note that <code>--info=name</code>'s output is affected by the <a href="#opt--out-format"><code>--out-format</code></a>
+and <a href="#opt--itemize-changes"><code>--itemize-changes</code></a> (<code>-i</code>) options.  See those options for more
+information on what is output and when.</p>
 <p>This option was added to 3.1.0, so an older rsync on the server side might
 reject your attempts at fine-grained control (if one or more flags needed
 to be send to the server and the server was too old to understand them).
 See also the &quot;<code>max verbosity</code>&quot; caveat above when dealing with a daemon.</p>
 </dd>
 
-<dt><code>--debug=FLAGS</code></dt><dd>
+<dt id="opt--debug"><code>--debug=FLAGS</code><a href="#opt--debug" class="tgt"></a></dt><dd>
 <p>This option lets you have fine-grained control over the debug output you
 want to see.  An individual flag name may be followed by a level number,
 with 0 meaning to silence that output, 1 being the default output level,
@@ -562,8 +669,8 @@ the verbose level.  Some examples:</p>
 rsync -avA --del --debug=del2,acl src/ dest/
 </code></pre>
 </blockquote>
-<p>Note that some debug messages will only be output when <code>--stderr=all</code> is
-specified, especially those pertaining to I/O and buffer debugging.</p>
+<p>Note that some debug messages will only be output when the <a href="#opt--stderr"><code>--stderr=all</code></a>
+option is specified, especially those pertaining to I/O and buffer debugging.</p>
 <p>Beginning in 3.2.0, this option is no longer auto-forwarded to the server
 side in order to allow you to specify different debug values for each side
 of the transfer, as well as to specify a new debug option that is only
@@ -576,7 +683,7 @@ typing.  This works in zsh and bash:</p>
 </blockquote>
 </dd>
 
-<dt><code>--stderr=errors|all|client</code></dt><dd>
+<dt id="opt--stderr"><code>--stderr=errors|all|client</code><a href="#opt--stderr" class="tgt"></a></dt><dd>
 <p>This option controls which processes output to stderr and if info messages
 are also changed to stderr.  The mode strings can be abbreviated, so feel
 free to use a single letter value.  The 3 possible choices are:</p>
@@ -596,8 +703,8 @@ become line-buffered (instead of raw) and eliminates the ability to
 divide up the info and error messages by file handle.  For those doing
 debugging or using several levels of verbosity, this option can help to
 avoid clogging up the transfer stream (which should prevent any chance of
-a deadlock bug hanging things up).  It also enables the outputting of some
-I/O related debug messages.</p>
+a deadlock bug hanging things up).  It also allows <a href="#opt--debug"><code>--debug</code></a> to
+enable some extra I/O related messages.</p>
 </li>
 <li>
 <p><code>client</code> -&#8288; causes all rsync messages to be sent to the client side
@@ -616,13 +723,13 @@ represent the <code>all</code> and <code>client</code> settings, respectively.
 will continue to accept these older option names to maintain compatibility.</p>
 </dd>
 
-<dt><code>--quiet</code>, <code>-q</code></dt><dd>
+<span id="opt-q"></span><dt id="opt--quiet"><code>--quiet</code>, <code>-q</code><a href="#opt--quiet" class="tgt"></a></dt><dd>
 <p>This option decreases the amount of information you are given during the
 transfer, notably suppressing information messages from the remote server.
 This option is useful when invoking rsync from cron.</p>
 </dd>
 
-<dt><code>--no-motd</code></dt><dd>
+<dt id="opt--no-motd"><code>--no-motd</code><a href="#opt--no-motd" class="tgt"></a></dt><dd>
 <p>This option affects the information that is output by the client at the
 start of a daemon transfer.  This suppresses the message-of-the-day (MOTD)
 text, but it also affects the list of modules that the daemon sends in
@@ -631,13 +738,16 @@ protocol), so omit this option if you want to request the list of modules
 from the daemon.</p>
 </dd>
 
-<dt><code>--ignore-times</code>, <code>-I</code></dt><dd>
+<span id="opt-I"></span><dt id="opt--ignore-times"><code>--ignore-times</code>, <code>-I</code><a href="#opt--ignore-times" class="tgt"></a></dt><dd>
 <p>Normally rsync will skip any files that are already the same size and have
 the same modification timestamp.  This option turns off this &quot;quick check&quot;
 behavior, causing all files to be updated.</p>
+<p>This option can be confusing compared to <a href="#opt--ignore-existing"><code>--ignore-existing</code></a> and
+<a href="#opt--ignore-non-existing"><code>--ignore-non-existing</code></a> in that that they cause rsync to transfer
+fewer files, while this option causes rsync to transfer more files.</p>
 </dd>
 
-<dt><code>--size-only</code></dt><dd>
+<dt id="opt--size-only"><code>--size-only</code><a href="#opt--size-only" class="tgt"></a></dt><dd>
 <p>This modifies rsync's &quot;quick check&quot; algorithm for finding files that need
 to be transferred, changing it from the default of transferring files with
 either a changed size or a changed last-modified time to just looking for
@@ -646,7 +756,7 @@ after using another mirroring system which may not preserve timestamps
 exactly.</p>
 </dd>
 
-<dt><code>--modify-window=NUM</code>, <code>-@</code></dt><dd>
+<span id="opt-_"></span><dt id="opt--modify-window"><code>--modify-window=NUM</code>, <code>-@</code><a href="#opt--modify-window" class="tgt"></a></dt><dd>
 <p>When comparing two timestamps, rsync treats the timestamps as being equal
 if they differ by no more than the modify-window value.  The default is 0,
 which matches just integer seconds.  If you specify a negative value (and
@@ -666,7 +776,7 @@ rsync alias -t -t@-1
 between ext3 and ext4, or if the receiving rsync is older than 3.1.3.</p>
 </dd>
 
-<dt><code>--checksum</code>, <code>-c</code></dt><dd>
+<span id="opt-c"></span><dt id="opt--checksum"><code>--checksum</code>, <code>-c</code><a href="#opt--checksum" class="tgt"></a></dt><dd>
 <p>This changes the way rsync checks if the files have been changed and are in
 need of a transfer.  Without this option, rsync uses a &quot;quick check&quot; that
 (by default) checks if each file's size and time of last modification match
@@ -687,59 +797,88 @@ is generated as the file is transferred, but that automatic
 after-the-transfer verification has nothing to do with this option's
 before-the-transfer &quot;Does this file need to be updated?&quot; check.</p>
 <p>The checksum used is auto-negotiated between the client and the server, but
-can be overridden using either the <code>--checksum-choice</code> (<code>--cc</code>) option or an
-environment variable that is discussed in that option's section.</p>
+can be overridden using either the <a href="#opt--checksum-choice"><code>--checksum-choice</code></a> (<code>--cc</code>)
+option or an environment variable that is discussed in that option's
+section.</p>
 </dd>
 
-<dt><code>--archive</code>, <code>-a</code></dt><dd>
+<span id="opt-a"></span><dt id="opt--archive"><code>--archive</code>, <code>-a</code><a href="#opt--archive" class="tgt"></a></dt><dd>
 <p>This is equivalent to <code>-rlptgoD</code>.  It is a quick way of saying you want
-recursion and want to preserve almost everything (with <code>-H</code> being a notable
-omission).  The only exception to the above equivalence is when
-<code>--files-from</code> is specified, in which case <code>-r</code> is not implied.</p>
-<p>Note that <code>-a</code> <strong>does not preserve hardlinks</strong>, because finding
-multiply-linked files is expensive.  You must separately specify <code>-H</code>.</p>
+recursion and want to preserve almost everything.  Be aware that it does
+<strong>not</strong> include preserving ACLs (<code>-A</code>), xattrs (<code>-X</code>), atimes (<code>-U</code>),
+crtimes (<code>-N</code>), nor the finding and preserving of hardlinks (<code>-H</code>).</p>
+<p>The only exception to the above equivalence is when <a href="#opt--files-from"><code>--files-from</code></a>
+is specified, in which case <a href="#opt-r"><code>-r</code></a> is not implied.</p>
 </dd>
 
-<dt><code>--no-OPTION</code></dt><dd>
+<dt id="opt--no-OPTION"><code>--no-OPTION</code><a href="#opt--no-OPTION" class="tgt"></a></dt><dd>
 <p>You may turn off one or more implied options by prefixing the option name
-with &quot;no-&quot;.  Not all options may be prefixed with a &quot;no-&quot;: only options that
-are implied by other options (e.g. <code>--no-D</code>, <code>--no-perms</code>) or have
-different defaults in various circumstances (e.g. <code>--no-whole-file</code>,
-<code>--no-blocking-io</code>, <code>--no-dirs</code>).  You may specify either the short or the
-long option name after the &quot;no-&quot; prefix (e.g. <code>--no-R</code> is the same as
-<code>--no-relative</code>).</p>
-<p>For example: if you want to use <code>-a</code> (<code>--archive</code>) but don't want <code>-o</code>
-(<code>--owner</code>), instead of converting <code>-a</code> into <code>-rlptgD</code>, you could specify
-<code>-a --no-o</code> (or <code>-a --no-owner</code>).</p>
-<p>The order of the options is important: if you specify <code>--no-r -a</code>, the
-<code>-r</code> option would end up being turned on, the opposite of <code>-a --no-r</code>.
-Note also that the side-effects of the <code>--files-from</code> option are NOT
+with &quot;no-&quot;.  Not all positive options have a negated opposite, but a lot
+do, including those that can be used to disable an implied option (e.g.
+<code>--no-D</code>, <code>--no-perms</code>) or have different defaults in various circumstances
+(e.g. <a href="#opt--no-whole-file"><code>--no-whole-file</code></a>, <code>--no-blocking-io</code>, <code>--no-dirs</code>).  Every
+valid negated option accepts both the short and the long option name after
+the &quot;no-&quot; prefix (e.g. <code>--no-R</code> is the same as <code>--no-relative</code>).</p>
+<p>As an example, if you want to use <a href="#opt--archive"><code>--archive</code></a> (<code>-a</code>) but don't want
+<a href="#opt--owner"><code>--owner</code></a> (<code>-o</code>), instead of converting <code>-a</code> into <code>-rlptgD</code>, you
+can specify <code>-a --no-o</code> (aka <code>--archive --no-owner</code>).</p>
+<p>The order of the options is important: if you specify <code>--no-r -a</code>, the <code>-r</code>
+option would end up being turned on, the opposite of <code>-a --no-r</code>.  Note
+also that the side-effects of the <a href="#opt--files-from"><code>--files-from</code></a> option are NOT
 positional, as it affects the default state of several options and slightly
-changes the meaning of <code>-a</code> (see the <code>--files-from</code> option for more
-details).</p>
-</dd>
-
-<dt><code>--recursive</code>, <code>-r</code></dt><dd>
-<p>This tells rsync to copy directories recursively.  See also <code>--dirs</code> (<code>-d</code>).</p>
-<p>Beginning with rsync 3.0.0, the recursive algorithm used is now an
-incremental scan that uses much less memory than before and begins the
-transfer after the scanning of the first few directories have been
-completed.  This incremental scan only affects our recursion algorithm, and
-does not change a non-recursive transfer.  It is also only possible when
-both ends of the transfer are at least version 3.0.0.</p>
+changes the meaning of <a href="#opt-a"><code>-a</code></a> (see the <a href="#opt--files-from"><code>--files-from</code></a> option
+for more details).</p>
+</dd>
+
+<span id="opt-r"></span><dt id="opt--recursive"><code>--recursive</code>, <code>-r</code><a href="#opt--recursive" class="tgt"></a></dt><dd>
+<p>This tells rsync to copy directories recursively.  See also
+<a href="#opt--dirs"><code>--dirs</code></a> (<code>-d</code>) for an option that allows the scanning of a single
+directory.</p>
+<p>See the <a href="#opt--inc-recursive"><code>--inc-recursive</code></a> option for a discussion of the
+incremental recursion for creating the list of files to transfer.</p>
+</dd>
+
+<span id="opt--i-r"></span><dt id="opt--inc-recursive"><code>--inc-recursive</code>, <code>--i-r</code><a href="#opt--inc-recursive" class="tgt"></a></dt><dd>
+<p>This option explicitly enables on incremental recursion when scanning for
+files, which is enabled by default when using the <a href="#opt--recursive"><code>--recursive</code></a>
+option and both sides of the transfer are running rsync 3.0.0 or newer.</p>
+<p>Incremental recursion uses much less memory than non-incremental, while
+also beginning the transfer more quickly (since it doesn't need to scan the
+entire transfer hierarchy before it starts transferring files).  If no
+recursion is enabled in the source files, this option has no effect.</p>
 <p>Some options require rsync to know the full file list, so these options
-disable the incremental recursion mode.  These include: <code>--delete-before</code>,
-<code>--delete-after</code>, <code>--prune-empty-dirs</code>, and <code>--delay-updates</code>.  Because of
-this, the default delete mode when you specify <code>--delete</code> is now
-<code>--delete-during</code> when both ends of the connection are at least 3.0.0 (use
-<code>--del</code> or <code>--delete-during</code> to request this improved deletion mode
-explicitly).  See also the <code>--delete-delay</code> option that is a better choice
-than using <code>--delete-after</code>.</p>
-<p>Incremental recursion can be disabled using the <code>--no-inc-recursive</code> option
-or its shorter <code>--no-i-r</code> alias.</p>
-</dd>
-
-<dt><code>--relative</code>, <code>-R</code></dt><dd>
+disable the incremental recursion mode.  These include:</p>
+<ul>
+<li><a href="#opt--delete-before"><code>--delete-before</code></a> (the old default of <a href="#opt--delete"><code>--delete</code></a>)</li>
+<li><a href="#opt--delete-after"><code>--delete-after</code></a></li>
+<li><a href="#opt--prune-empty-dirs"><code>--prune-empty-dirs</code></a></li>
+<li><a href="#opt--delay-updates"><code>--delay-updates</code></a></li>
+</ul>
+<p>In order to make <a href="#opt--delete"><code>--delete</code></a> compatible with incremental recursion,
+rsync 3.0.0 made <a href="#opt--delete-during"><code>--delete-during</code></a> the default delete mode (which
+was first added in 2.6.4).</p>
+<p>One side-effect of incremental recursion is that any missing
+sub-directories inside a recursively-scanned directory are (by default)
+created prior to recursing into the sub-dirs.  This earlier creation point
+(compared to a non-incremental recursion) allows rsync to then set the
+modify time of the finished directory right away (without having to delay
+that until a bunch of recursive copying has finished).  However, these
+early directories don't yet have their completed mode, mtime, or ownership
+set&nbsp;-&#8288;-&#8288; they have more restrictive rights until the subdirectory's copying
+actually begins.  This early-creation idiom can be avoided by using the
+<a href="#opt--omit-dir-times"><code>--omit-dir-times</code></a> option.</p>
+<p>Incremental recursion can be disabled using the
+<a href="#opt--no-inc-recursive"><code>--no-inc-recursive</code></a> (<code>--no-i-r</code>) option.</p>
+</dd>
+
+<span id="opt--no-i-r"></span><dt id="opt--no-inc-recursive"><code>--no-inc-recursive</code>, <code>--no-i-r</code><a href="#opt--no-inc-recursive" class="tgt"></a></dt><dd>
+<p>Disables the new incremental recursion algorithm of the
+<a href="#opt--recursive"><code>--recursive</code></a> option.  This makes rsync scan the full file list
+before it begins to transfer files.  See <a href="#opt--inc-recursive"><code>--inc-recursive</code></a> for more
+info.</p>
+</dd>
+
+<span id="opt-R"></span><dt id="opt--relative"><code>--relative</code>, <code>-R</code><a href="#opt--relative" class="tgt"></a></dt><dd>
 <p>Use relative paths.  This means that the full path names specified on the
 command line are sent to the server rather than just the last parts of the
 filenames.  This is particularly useful when you want to send several
@@ -766,7 +905,7 @@ when copying the full path of a file that you didn't realize had a symlink
 in its path.  If you want to duplicate a server-side symlink, include both
 the symlink via its path, and referent directory via its real path.  If
 you're dealing with an older rsync on the sending side, you may need to use
-the <code>--no-implied-dirs</code> option.</p>
+the <a href="#opt--no-implied-dirs"><code>--no-implied-dirs</code></a> option.</p>
 <p>It is also possible to limit the amount of path information that is sent as
 implied directories for each path you specify.  With a modern rsync on the
 sending side (beginning with 2.6.7), you can insert a dot and a slash into
@@ -794,8 +933,8 @@ non-daemon transfer):</p>
 </blockquote>
 </dd>
 
-<dt><code>--no-implied-dirs</code></dt><dd>
-<p>This option affects the default behavior of the <code>--relative</code> option.  When
+<dt id="opt--no-implied-dirs"><code>--no-implied-dirs</code><a href="#opt--no-implied-dirs" class="tgt"></a></dt><dd>
+<p>This option affects the default behavior of the <a href="#opt--relative"><code>--relative</code></a> option.  When
 it is specified, the attributes of the implied directories from the source
 names are not included in the transfer.  This means that the corresponding
 path elements on the destination system are left unchanged if they exist,
@@ -804,42 +943,46 @@ This even allows these implied path elements to have big differences, such
 as being a symlink to a directory on the receiving side.</p>
 <p>For instance, if a command-line arg or a files-from entry told rsync to
 transfer the file &quot;path/foo/file&quot;, the directories &quot;path&quot; and &quot;path/foo&quot;
-are implied when <code>--relative</code> is used.  If &quot;path/foo&quot; is a symlink to &quot;bar&quot;
+are implied when <a href="#opt--relative"><code>--relative</code></a> is used.  If &quot;path/foo&quot; is a symlink to &quot;bar&quot;
 on the destination system, the receiving rsync would ordinarily delete
 &quot;path/foo&quot;, recreate it as a directory, and receive the file into the new
 directory.  With <code>--no-implied-dirs</code>, the receiving rsync updates
 &quot;path/foo/file&quot; using the existing path elements, which means that the file
 ends up being created in &quot;path/bar&quot;.  Another way to accomplish this link
-preservation is to use the <code>--keep-dirlinks</code> option (which will also affect
+preservation is to use the <a href="#opt--keep-dirlinks"><code>--keep-dirlinks</code></a> option (which will also affect
 symlinks to directories in the rest of the transfer).</p>
 <p>When pulling files from an rsync older than 3.0.0, you may need to use this
 option if the sending side has a symlink in the path you request and you
 wish the implied directories to be transferred as normal directories.</p>
 </dd>
 
-<dt><code>--backup</code>, <code>-b</code></dt><dd>
+<span id="opt-b"></span><dt id="opt--backup"><code>--backup</code>, <code>-b</code><a href="#opt--backup" class="tgt"></a></dt><dd>
 <p>With this option, preexisting destination files are renamed as each file is
 transferred or deleted.  You can control where the backup file goes and
-what (if any) suffix gets appended using the <code>--backup-dir</code> and <code>--suffix</code>
-options.</p>
-<p>Note that if you don't specify <code>--backup-dir</code>, (1) the <code>--omit-dir-times</code>
-option will be forced on, and (2) if <code>--delete</code> is also in effect (without
-<code>--delete-excluded</code>), rsync will add a &quot;protect&quot; filter-rule for the backup
-suffix to the end of all your existing excludes (e.g. <code>-f &quot;P *~&quot;</code>).  This
-will prevent previously backed-up files from being deleted.  Note that if
-you are supplying your own filter rules, you may need to manually insert
-your own exclude/protect rule somewhere higher up in the list so that it
-has a high enough priority to be effective (e.g., if your rules specify a
-trailing inclusion/exclusion of <code>*</code>, the auto-added rule would never be
-reached).</p>
-</dd>
-
-<dt><code>--backup-dir=DIR</code></dt><dd>
-<p>This implies the <code>--backup</code> option, and tells rsync to store all
+what (if any) suffix gets appended using the <a href="#opt--backup-dir"><code>--backup-dir</code></a> and
+<a href="#opt--suffix"><code>--suffix</code></a> options.</p>
+<p>If you don't specify <a href="#opt--backup-dir"><code>--backup-dir</code></a>:</p>
+<ol>
+<li>the <a href="#opt--omit-dir-times"><code>--omit-dir-times</code></a> option will be forced on</li>
+<li>the use of <a href="#opt--delete"><code>--delete</code></a> (without <a href="#opt--delete-excluded"><code>--delete-excluded</code></a>),
+causes rsync to add a &quot;protect&quot; <a href="#FILTER_RULES">filter-rule</a> for the
+backup suffix to the end of all your existing filters that looks like
+this: <code>-f &quot;P *~&quot;</code>.  This rule prevents previously backed-up files from
+being deleted.</li>
+</ol>
+<p>Note that if you are supplying your own filter rules, you may need to
+manually insert your own exclude/protect rule somewhere higher up in the
+list so that it has a high enough priority to be effective (e.g. if your
+rules specify a trailing inclusion/exclusion of <code>*</code>, the auto-added rule
+would never be reached).</p>
+</dd>
+
+<dt id="opt--backup-dir"><code>--backup-dir=DIR</code><a href="#opt--backup-dir" class="tgt"></a></dt><dd>
+<p>This implies the <a href="#opt--backup"><code>--backup</code></a> option, and tells rsync to store all
 backups in the specified directory on the receiving side.  This can be used
 for incremental backups.  You can additionally specify a backup suffix
-using the <code>--suffix</code> option (otherwise the files backed up in the specified
-directory will keep their original filenames).</p>
+using the <a href="#opt--suffix"><code>--suffix</code></a> option (otherwise the files backed up in the
+specified directory will keep their original filenames).</p>
 <p>Note that if you specify a relative path, the backup directory will be
 relative to the destination directory, so you probably want to specify
 either an absolute path or a path that starts with &quot;../&quot;.  If an rsync
@@ -847,13 +990,13 @@ daemon is the receiver, the backup dir cannot go outside the module's path
 hierarchy, so take extra care not to delete it or copy into it.</p>
 </dd>
 
-<dt><code>--suffix=SUFFIX</code></dt><dd>
+<dt id="opt--suffix"><code>--suffix=SUFFIX</code><a href="#opt--suffix" class="tgt"></a></dt><dd>
 <p>This option allows you to override the default backup suffix used with the
-<code>--backup</code> (<code>-b</code>) option.  The default suffix is a <code>~</code> if no <code>--backup-dir</code>
-was specified, otherwise it is an empty string.</p>
+<a href="#opt--backup"><code>--backup</code></a> (<code>-b</code>) option.  The default suffix is a <code>~</code> if no
+<a href="#opt--backup-dir"><code>--backup-dir</code></a> was specified, otherwise it is an empty string.</p>
 </dd>
 
-<dt><code>--update</code>, <code>-u</code></dt><dd>
+<span id="opt-u"></span><dt id="opt--update"><code>--update</code>, <code>-u</code><a href="#opt--update" class="tgt"></a></dt><dd>
 <p>This forces rsync to skip any files which exist on the destination and have
 a modified time that is newer than the source file. (If an existing
 destination file has a modification time equal to the source file's, it
@@ -864,12 +1007,17 @@ receiver is always considered to be important enough for an update, no
 matter what date is on the objects.  In other words, if the source has a
 directory where the destination has a file, the transfer would occur
 regardless of the timestamps.</p>
-<p>This option is a transfer rule, not an exclude, so it doesn't affect the
-data that goes into the file-lists, and thus it doesn't affect deletions.
-It just limits the files that the receiver requests to be transferred.</p>
+<p>This option is a <a href="#TRANSFER_RULES">TRANSFER RULE</a>, so don't expect any
+exclude side effects.</p>
+<p>A caution for those that choose to combine <a href="#opt--inplace"><code>--inplace</code></a> with
+<code>--update</code>: an interrupted transfer will leave behind a partial file on the
+receiving side that has a very recent modified time, so re-running the
+transfer will probably <strong>not</strong> continue the interrupted file.  As such, it
+is usually best to avoid combining this with<a href="#opt--inplace"> <code>--inplace</code></a> unless you
+have implemented manual steps to handle any interrupted in-progress files.</p>
 </dd>
 
-<dt><code>--inplace</code></dt><dd>
+<dt id="opt--inplace"><code>--inplace</code><a href="#opt--inplace" class="tgt"></a></dt><dd>
 <p>This option changes how rsync transfers a file when its data needs to be
 updated: instead of the default method of creating a new copy of the file
 and moving it into place when it is complete, rsync instead writes the
@@ -892,7 +1040,7 @@ can update any file, a normal user needs to be granted write permission
 for the open of the file for writing to be successful.</li>
 <li>The efficiency of rsync's delta-transfer algorithm may be reduced if some
 data in the destination file is overwritten before it can be copied to a
-position later in the file.  This does not apply if you use <code>--backup</code>,
+position later in the file.  This does not apply if you use <a href="#opt--backup"><code>--backup</code></a>,
 since rsync is smart enough to use the backup file as the basis file for
 the transfer.</li>
 </ul>
@@ -902,13 +1050,13 @@ accessed by others, so be careful when choosing to use this for a copy.</p>
 or appended data, and also on systems that are disk bound, not network
 bound.  It can also help keep a copy-on-write filesystem snapshot from
 diverging the entire contents of a file that only has minor changes.</p>
-<p>The option implies <code>--partial</code> (since an interrupted transfer does not
-delete the file), but conflicts with <code>--partial-dir</code> and <code>--delay-updates</code>.
-Prior to rsync 2.6.4 <code>--inplace</code> was also incompatible with
-<code>--compare-dest</code> and <code>--link-dest</code>.</p>
+<p>The option implies <a href="#opt--partial"><code>--partial</code></a> (since an interrupted transfer does
+not delete the file), but conflicts with <a href="#opt--partial-dir"><code>--partial-dir</code></a> and
+<a href="#opt--delay-updates"><code>--delay-updates</code></a>.  Prior to rsync 2.6.4 <code>--inplace</code> was also
+incompatible with <a href="#opt--compare-dest"><code>--compare-dest</code></a> and <a href="#opt--link-dest"><code>--link-dest</code></a>.</p>
 </dd>
 
-<dt><code>--append</code></dt><dd>
+<dt id="opt--append"><code>--append</code><a href="#opt--append" class="tgt"></a></dt><dd>
 <p>This special copy mode only works to efficiently update files that are
 known to be growing larger where any existing content on the receiving side
 is also known to be the same as the content on the sender.  The use of
@@ -919,85 +1067,102 @@ rules to ensure that you weed out any files that do not fit this criteria.</p>
 existing content in the file (it only verifies the content that it is
 appending).  Rsync skips any files that exist on the receiving side that
 are not shorter than the associated file on the sending side (which means
-that new files are trasnferred).</p>
+that new files are transferred).  It also skips any files whose size on the
+sending side gets shorter during the send negotiations (rsync warns about a
+&quot;diminished&quot; file when this happens).</p>
 <p>This does not interfere with the updating of a file's non-content
 attributes (e.g.  permissions, ownership, etc.) when the file does not need
 to be transferred, nor does it affect the updating of any directories or
 non-regular files.</p>
 </dd>
 
-<dt><code>--append-verify</code></dt><dd>
-<p>This special copy mode works like <code>--append</code> except that all the data in
-the file is included in the checksum verification (making it much less
+<dt id="opt--append-verify"><code>--append-verify</code><a href="#opt--append-verify" class="tgt"></a></dt><dd>
+<p>This special copy mode works like <a href="#opt--append"><code>--append</code></a> except that all the
+data in the file is included in the checksum verification (making it less
 efficient but also potentially safer).  This option <strong>can be dangerous</strong> if
 you aren't 100% sure that all the files in the transfer are shared, growing
-files.  See the <code>--append</code> option for more details.</p>
-<p>Note: prior to rsync 3.0.0, the <code>--append</code> option worked like
+files.  See the <a href="#opt--append"><code>--append</code></a> option for more details.</p>
+<p>Note: prior to rsync 3.0.0, the <a href="#opt--append"><code>--append</code></a> option worked like
 <code>--append-verify</code>, so if you are interacting with an older rsync (or the
 transfer is using a protocol prior to 30), specifying either append option
 will initiate an <code>--append-verify</code> transfer.</p>
 </dd>
 
-<dt><code>--dirs</code>, <code>-d</code></dt><dd>
+<span id="opt-d"></span><dt id="opt--dirs"><code>--dirs</code>, <code>-d</code><a href="#opt--dirs" class="tgt"></a></dt><dd>
 <p>Tell the sending side to include any directories that are encountered.
-Unlike <code>--recursive</code>, a directory's contents are not copied unless the
-directory name specified is &quot;.&quot; or ends with a trailing slash (e.g. &quot;.&quot;,
-&quot;dir/.&quot;, &quot;dir/&quot;, etc.).  Without this option or the <code>--recursive</code> option,
-rsync will skip all directories it encounters (and output a message to that
-effect for each one).  If you specify both <code>--dirs</code> and <code>--recursive</code>,
-<code>--recursive</code> takes precedence.</p>
-<p>The <code>--dirs</code> option is implied by the <code>--files-from</code> option or the
-<code>--list-only</code> option (including an implied <code>--list-only</code> usage) if
-<code>--recursive</code> wasn't specified (so that directories are seen in the
-listing).  Specify <code>--no-dirs</code> (or <code>--no-d</code>) if you want to turn this off.</p>
-<p>There is also a backward-compatibility helper option, <code>--old-dirs</code> (or
-<code>--old-d</code>) that tells rsync to use a hack of <code>-r --exclude='/*/*'</code> to get
+Unlike <a href="#opt--recursive"><code>--recursive</code></a>, a directory's contents are not copied unless
+the directory name specified is &quot;.&quot; or ends with a trailing slash (e.g.
+&quot;.&quot;, &quot;dir/.&quot;, &quot;dir/&quot;, etc.).  Without this option or the
+<a href="#opt--recursive"><code>--recursive</code></a> option, rsync will skip all directories it encounters
+(and output a message to that effect for each one).  If you specify both
+<code>--dirs</code> and <a href="#opt--recursive"><code>--recursive</code></a>, <code>--recursive</code> takes precedence.</p>
+<p>The <code>--dirs</code> option is implied by the <a href="#opt--files-from"><code>--files-from</code></a> option or the
+<a href="#opt--list-only"><code>--list-only</code></a> option (including an implied <a href="#opt--list-only"><code>--list-only</code></a>
+usage) if <a href="#opt--recursive"><code>--recursive</code></a> wasn't specified (so that directories are
+seen in the listing).  Specify <code>--no-dirs</code> (or <code>--no-d</code>) if you want to
+turn this off.</p>
+<p>There is also a backward-compatibility helper option, <code>--old-dirs</code>
+(<code>--old-d</code>) that tells rsync to use a hack of <code>-r --exclude='/*/*'</code> to get
 an older rsync to list a single directory without recursing.</p>
 </dd>
 
-<dt><code>--mkpath</code></dt><dd>
-<p>Create a missing path component of the destination arg.  This allows rsync
-to create multiple levels of missing destination dirs and to create a path
-in which to put a single renamed file.  Keep in mind that you'll need to
-supply a trailing slash if you want the entire destination path to be
-treated as a directory when copying a single arg (making rsync behave the
-same way that it would if the path component of the destination had already
-existed).</p>
-<p>For example, the following creates a copy of file foo as bar in the sub/dir
-directory, creating dirs &quot;sub&quot; and &quot;sub/dir&quot; if either do not yet exist:</p>
-<blockquote>
-<pre><code>rsync -ai --mkpath foo sub/dir/bar
-</code></pre>
-</blockquote>
-<p>If you instead ran the following, it would have created file foo in the
-sub/dir/bar directory:</p>
+<dt id="opt--mkpath"><code>--mkpath</code><a href="#opt--mkpath" class="tgt"></a></dt><dd>
+<p>Create all missing path components of the destination path.</p>
+<p>By default, rsync allows only the final component of the destination path
+to not exist, which is an attempt to help you to validate your destination
+path.  With this option, rsync creates all the missing destination-path
+components, just as if <code>mkdir -p $DEST_PATH</code> had been run on the receiving
+side.</p>
+<p>When specifying a destination path, including a trailing slash ensures that
+the whole path is treated as directory names to be created, even when the
+file list has a single item. See the <a href="#COPYING_TO_A_DIFFERENT_NAME">COPYING TO A DIFFERENT NAME</a>
+section for full details on how rsync decides if a final destination-path
+component should be created as a directory or not.</p>
+<p>If you would like the newly-created destination dirs to match the dirs on
+the sending side, you should be using <a href="#opt--relative"><code>--relative</code></a> (<code>-R</code>) instead
+of <code>--mkpath</code>.  For instance, the following two commands result in the same
+destination tree, but only the second command ensures that the
+&quot;some/extra/path&quot; components match the dirs on the sending side:</p>
 <blockquote>
-<pre><code>rsync -ai --mkpath foo sub/dir/bar/
+<pre><code>rsync -ai --mkpath host:some/extra/path/*.c some/extra/path/
+rsync -aiR host:some/extra/path/*.c ./
 </code></pre>
 </blockquote>
 </dd>
 
-<dt><code>--links</code>, <code>-l</code></dt><dd>
-<p>When symlinks are encountered, recreate the symlink on the destination.</p>
-</dd>
-
-<dt><code>--copy-links</code>, <code>-L</code></dt><dd>
-<p>When symlinks are encountered, the item that they point to (the referent)
-is copied, rather than the symlink.  In older versions of rsync, this
-option also had the side-effect of telling the receiving side to follow
-symlinks, such as symlinks to directories.  In a modern rsync such as this
-one, you'll need to specify <code>--keep-dirlinks</code> (<code>-K</code>) to get this extra
-behavior.  The only exception is when sending files to an rsync that is too
-old to understand <code>-K</code>&nbsp;-&#8288;-&#8288; in that case, the <code>-L</code> option will still have the
-side-effect of <code>-K</code> on that older receiving rsync.</p>
-</dd>
-
-<dt><code>--copy-unsafe-links</code></dt><dd>
+<span id="opt-l"></span><dt id="opt--links"><code>--links</code>, <code>-l</code><a href="#opt--links" class="tgt"></a></dt><dd>
+<p>Add symlinks to the transferred files instead of noisily ignoring them with
+a &quot;non-regular file&quot; warning for each symlink encountered.  You can
+alternately silence the warning by specifying <a href="#opt--info"><code>--info=nonreg0</code></a>.</p>
+<p>The default handling of symlinks is to recreate each symlink's unchanged
+value on the receiving side.</p>
+<p>See the <a href="#SYMBOLIC_LINKS">SYMBOLIC LINKS</a> section for multi-option info.</p>
+</dd>
+
+<span id="opt-L"></span><dt id="opt--copy-links"><code>--copy-links</code>, <code>-L</code><a href="#opt--copy-links" class="tgt"></a></dt><dd>
+<p>The sender transforms each symlink encountered in the transfer into the
+referent item, following the symlink chain to the file or directory that it
+references.  If a symlink chain is broken, an error is output and the file
+is dropped from the transfer.</p>
+<p>This option supersedes any other options that affect symlinks in the
+transfer, since there are no symlinks left in the transfer.</p>
+<p>This option does not change the handling of existing symlinks on the
+receiving side, unlike versions of rsync prior to 2.6.3 which had the
+side-effect of telling the receiving side to also follow symlinks.  A
+modern rsync won't forward this option to a remote receiver (since only the
+sender needs to know about it), so this caveat should only affect someone
+using an rsync client older than 2.6.7 (which is when <code>-L</code> stopped being
+forwarded to the receiver).</p>
+<p>See the <a href="#opt--keep-dirlinks"><code>--keep-dirlinks</code></a> (<code>-K</code>) if you need a symlink to a
+directory to be treated as a real directory on the receiving side.</p>
+<p>See the <a href="#SYMBOLIC_LINKS">SYMBOLIC LINKS</a> section for multi-option info.</p>
+</dd>
+
+<dt id="opt--copy-unsafe-links"><code>--copy-unsafe-links</code><a href="#opt--copy-unsafe-links" class="tgt"></a></dt><dd>
 <p>This tells rsync to copy the referent of symbolic links that point outside
 the copied tree.  Absolute symlinks are also treated like ordinary files,
-and so are any symlinks in the source path itself when <code>--relative</code> is
-used.  This option has no additional effect if <code>--copy-links</code> was also
-specified.</p>
+and so are any symlinks in the source path itself when <a href="#opt--relative"><code>--relative</code></a>
+is used.</p>
 <p>Note that the cut-off point is the top of the transfer, which is the part
 of the path that rsync isn't mentioning in the verbose output.  If you copy
 &quot;/src/subdir&quot; to &quot;/dest/&quot; then the &quot;subdir&quot; directory is a name inside the
@@ -1006,45 +1171,76 @@ for created relative symlinks to refer to other names inside the /src and
 /dest directories.  If you instead copy &quot;/src/subdir/&quot; (with a trailing
 slash) to &quot;/dest/subdir&quot; that would not allow symlinks to any files outside
 of &quot;subdir&quot;.</p>
-</dd>
-
-<dt><code>--safe-links</code></dt><dd>
-<p>This tells rsync to ignore any symbolic links which point outside the
-copied tree.  All absolute symlinks are also ignored. Using this option in
-conjunction with <code>--relative</code> may give unexpected results.</p>
-</dd>
-
-<dt><code>--munge-links</code></dt><dd>
-<p>This option tells rsync to (1) modify all symlinks on the receiving side in
-a way that makes them unusable but recoverable (see below), or (2) to
-unmunge symlinks on the sending side that had been stored in a munged
-state.  This is useful if you don't quite trust the source of the data to
-not try to slip in a symlink to a unexpected place.</p>
-<p>The way rsync disables the use of symlinks is to prefix each one with the
-string &quot;/rsyncd-munged/&quot;.  This prevents the links from being used as long
-as that directory does not exist.  When this option is enabled, rsync will
-refuse to run if that path is a directory or a symlink to a directory.</p>
-<p>The option only affects the client side of the transfer, so if you need it
-to affect the server, specify it via <code>--remote-option</code>. (Note that in a
-local transfer, the client side is the sender.)</p>
-<p>This option has no affect on a daemon, since the daemon configures whether
-it wants munged symlinks via its &quot;<code>munge symlinks</code>&quot; parameter.  See also the
-&quot;munge-symlinks&quot; perl script in the support directory of the source code.</p>
-</dd>
-
-<dt><code>--copy-dirlinks</code>, <code>-k</code></dt><dd>
+<p>Note that safe symlinks are only copied if <a href="#opt--links"><code>--links</code></a> was also
+specified or implied. The <code>--copy-unsafe-links</code> option has no extra effect
+when combined with <a href="#opt--copy-links"><code>--copy-links</code></a>.</p>
+<p>See the <a href="#SYMBOLIC_LINKS">SYMBOLIC LINKS</a> section for multi-option info.</p>
+</dd>
+
+<dt id="opt--safe-links"><code>--safe-links</code><a href="#opt--safe-links" class="tgt"></a></dt><dd>
+<p>This tells the receiving rsync to ignore any symbolic links in the transfer
+which point outside the copied tree.  All absolute symlinks are also
+ignored.</p>
+<p>Since this ignoring is happening on the receiving side, it will still be
+effective even when the sending side has munged symlinks (when it is using
+<a href="#opt--munge-links"><code>--munge-links</code></a>). It also affects deletions, since the file being
+present in the transfer prevents any matching file on the receiver from
+being deleted when the symlink is deemed to be unsafe and is skipped.</p>
+<p>This option must be combined with <a href="#opt--links"><code>--links</code></a> (or
+<a href="#opt--archive"><code>--archive</code></a>) to have any symlinks in the transfer to conditionally
+ignore. Its effect is superseded by <a href="#opt--copy-unsafe-links"><code>--copy-unsafe-links</code></a>.</p>
+<p>Using this option in conjunction with <a href="#opt--relative"><code>--relative</code></a> may give
+unexpected results.</p>
+<p>See the <a href="#SYMBOLIC_LINKS">SYMBOLIC LINKS</a> section for multi-option info.</p>
+</dd>
+
+<dt id="opt--munge-links"><code>--munge-links</code><a href="#opt--munge-links" class="tgt"></a></dt><dd>
+<p>This option affects just one side of the transfer and tells rsync to munge
+symlink values when it is receiving files or unmunge symlink values when it
+is sending files.  The munged values make the symlinks unusable on disk but
+allows the original contents of the symlinks to be recovered.</p>
+<p>The server-side rsync often enables this option without the client's
+knowledge, such as in an rsync daemon's configuration file or by an option
+given to the rrsync (restricted rsync) script.  When specified on the
+client side, specify the option normally if it is the client side that
+has/needs the munged symlinks, or use <code>-M--munge-links</code> to give the option
+to the server when it has/needs the munged symlinks.  Note that on a local
+transfer, the client is the sender, so specifying the option directly
+unmunges symlinks while specifying it as a remote option munges symlinks.</p>
+<p>This option has no effect when sent to a daemon via <a href="#opt--remote-option"><code>--remote-option</code></a>
+because the daemon configures whether it wants munged symlinks via its
+&quot;<code>munge symlinks</code>&quot; parameter.</p>
+<p>The symlink value is munged/unmunged once it is in the transfer, so any
+option that transforms symlinks into non-symlinks occurs prior to the
+munging/unmunging <strong>except</strong> for <a href="#opt--safe-links"><code>--safe-links</code></a>, which is a choice
+that the receiver makes, so it bases its decision on the munged/unmunged
+value.  This does mean that if a receiver has munging enabled, that using
+<a href="#opt--safe-links"><code>--safe-links</code></a> will cause all symlinks to be ignored (since they
+are all absolute).</p>
+<p>The method that rsync uses to munge the symlinks is to prefix each one's
+value with the string &quot;/rsyncd-munged/&quot;.  This prevents the links from
+being used as long as the directory does not exist.  When this option is
+enabled, rsync will refuse to run if that path is a directory or a symlink
+to a directory (though it only checks at startup).  See also the
+&quot;munge-symlinks&quot; python script in the support directory of the source code
+for a way to munge/unmunge one or more symlinks in-place.</p>
+</dd>
+
+<span id="opt-k"></span><dt id="opt--copy-dirlinks"><code>--copy-dirlinks</code>, <code>-k</code><a href="#opt--copy-dirlinks" class="tgt"></a></dt><dd>
 <p>This option causes the sending side to treat a symlink to a directory as
 though it were a real directory.  This is useful if you don't want symlinks
-to non-directories to be affected, as they would be using <code>--copy-links</code>.</p>
+to non-directories to be affected, as they would be using
+<a href="#opt--copy-links"><code>--copy-links</code></a>.</p>
 <p>Without this option, if the sending side has replaced a directory with a
 symlink to a directory, the receiving side will delete anything that is in
 the way of the new symlink, including a directory hierarchy (as long as
-<code>--force</code> or <code>--delete</code> is in effect).</p>
-<p>See also <code>--keep-dirlinks</code> for an analogous option for the receiving side.</p>
+<a href="#opt--force"><code>--force</code></a> or <a href="#opt--delete"><code>--delete</code></a> is in effect).</p>
+<p>See also <a href="#opt--keep-dirlinks"><code>--keep-dirlinks</code></a> for an analogous option for the
+receiving side.</p>
 <p><code>--copy-dirlinks</code> applies to all symlinks to directories in the source.  If
 you want to follow only a few specified symlinks, a trick you can use is to
 pass them as additional source args with a trailing slash, using
-<code>--relative</code> to make the paths match up right.  For example:</p>
+<a href="#opt--relative"><code>--relative</code></a> to make the paths match up right.  For example:</p>
 <blockquote>
 <pre><code>rsync -r --relative src/./ src/./follow-me/ dest/
 </code></pre>
@@ -1053,9 +1249,10 @@ pass them as additional source args with a trailing slash, using
 the trailing slash makes <strong>lstat</strong>(2) follow the symlink, giving rise to a
 directory in the file-list which overrides the symlink found during the
 scan of &quot;src/./&quot;.</p>
+<p>See the <a href="#SYMBOLIC_LINKS">SYMBOLIC LINKS</a> section for multi-option info.</p>
 </dd>
 
-<dt><code>--keep-dirlinks</code>, <code>-K</code></dt><dd>
+<span id="opt-K"></span><dt id="opt--keep-dirlinks"><code>--keep-dirlinks</code>, <code>-K</code><a href="#opt--keep-dirlinks" class="tgt"></a></dt><dd>
 <p>This option causes the receiving side to treat a symlink to a directory as
 though it were a real directory, but only if it matches a real directory
 from the sender.  Without this option, the receiver's symlink would be
@@ -1067,16 +1264,19 @@ directory, and receives the file into the new directory.  With
 <code>--keep-dirlinks</code>, the receiver keeps the symlink and &quot;file&quot; ends up in
 &quot;bar&quot;.</p>
 <p>One note of caution: if you use <code>--keep-dirlinks</code>, you must trust all the
-symlinks in the copy! If it is possible for an untrusted user to create
-their own symlink to any directory, the user could then (on a subsequent
+symlinks in the copy or enable the <a href="#opt--munge-links"><code>--munge-links</code></a> option on the
+receiving side!  If it is possible for an untrusted user to create their
+own symlink to any real directory, the user could then (on a subsequent
 copy) replace the symlink with a real directory and affect the content of
 whatever directory the symlink references.  For backup copies, you are
 better off using something like a bind mount instead of a symlink to modify
 your receiving hierarchy.</p>
-<p>See also <code>--copy-dirlinks</code> for an analogous option for the sending side.</p>
+<p>See also <a href="#opt--copy-dirlinks"><code>--copy-dirlinks</code></a> for an analogous option for the sending
+side.</p>
+<p>See the <a href="#SYMBOLIC_LINKS">SYMBOLIC LINKS</a> section for multi-option info.</p>
 </dd>
 
-<dt><code>--hard-links</code>, <code>-H</code></dt><dd>
+<span id="opt-H"></span><dt id="opt--hard-links"><code>--hard-links</code>, <code>-H</code><a href="#opt--hard-links" class="tgt"></a></dt><dd>
 <p>This tells rsync to look for hard-linked files in the source and link
 together the corresponding files on the destination.  Without this option,
 hard-linked files in the source are treated as though they were separate
@@ -1089,39 +1289,40 @@ destination may end up with extra hard links include the following:</p>
 is present in the source file list), the copying algorithm will not break
 them explicitly.  However, if one or more of the paths have content
 differences, the normal file-update process will break those extra links
-(unless you are using the <code>--inplace</code> option).</li>
-<li>If you specify a <code>--link-dest</code> directory that contains hard links, the
-linking of the destination files against the <code>--link-dest</code> files can
-cause some paths in the destination to become linked together due to the
-<code>--link-dest</code> associations.</li>
+(unless you are using the <a href="#opt--inplace"><code>--inplace</code></a> option).</li>
+<li>If you specify a <a href="#opt--link-dest"><code>--link-dest</code></a> directory that contains hard
+links, the linking of the destination files against the
+<a href="#opt--link-dest"><code>--link-dest</code></a> files can cause some paths in the destination to
+become linked together due to the <a href="#opt--link-dest"><code>--link-dest</code></a> associations.</li>
 </ul>
 <p>Note that rsync can only detect hard links between files that are inside
 the transfer set.  If rsync updates a file that has extra hard-link
 connections to files outside the transfer, that linkage will be broken.  If
-you are tempted to use the <code>--inplace</code> option to avoid this breakage, be
+you are tempted to use the <a href="#opt--inplace"><code>--inplace</code></a> option to avoid this breakage, be
 very careful that you know how your files are being updated so that you are
 certain that no unintended changes happen due to lingering hard links (and
-see the <code>--inplace</code> option for more caveats).</p>
-<p>If incremental recursion is active (see <code>--recursive</code>), rsync may transfer
-a missing hard-linked file before it finds that another link for that
-contents exists elsewhere in the hierarchy.  This does not affect the
-accuracy of the transfer (i.e. which files are hard-linked together), just
-its efficiency (i.e. copying the data for a new, early copy of a
+see the <a href="#opt--inplace"><code>--inplace</code></a> option for more caveats).</p>
+<p>If incremental recursion is active (see <a href="#opt--inc-recursive"><code>--inc-recursive</code></a>), rsync
+may transfer a missing hard-linked file before it finds that another link
+for that contents exists elsewhere in the hierarchy.  This does not affect
+the accuracy of the transfer (i.e. which files are hard-linked together),
+just its efficiency (i.e. copying the data for a new, early copy of a
 hard-linked file that could have been found later in the transfer in
 another member of the hard-linked set of files).  One way to avoid this
 inefficiency is to disable incremental recursion using the
-<code>--no-inc-recursive</code> option.</p>
+<a href="#opt--no-inc-recursive"><code>--no-inc-recursive</code></a> option.</p>
 </dd>
 
-<dt><code>--perms</code>, <code>-p</code></dt><dd>
+<span id="opt-p"></span><dt id="opt--perms"><code>--perms</code>, <code>-p</code><a href="#opt--perms" class="tgt"></a></dt><dd>
 <p>This option causes the receiving rsync to set the destination permissions
-to be the same as the source permissions. (See also the <code>--chmod</code> option
-for a way to modify what rsync considers to be the source permissions.)</p>
+to be the same as the source permissions. (See also the <a href="#opt--chmod"><code>--chmod</code></a>
+option for a way to modify what rsync considers to be the source
+permissions.)</p>
 <p>When this option is <u>off</u>, permissions are set as follows:</p>
 <ul>
 <li>Existing files (including updated files) retain their existing
-permissions, though the <code>--executability</code> option might change just the
-execute permission for the file.</li>
+permissions, though the <a href="#opt--executability"><code>--executability</code></a> option might change
+just the execute permission for the file.</li>
 <li>New files get their &quot;normal&quot; permission bits set to the source file's
 permissions masked with the receiving directory's default permissions
 (either the receiving process's umask, or the permissions specified via
@@ -1129,17 +1330,18 @@ the destination directory's default ACL), and their special permission
 bits disabled except in the case where a new directory inherits a setgid
 bit from its parent directory.</li>
 </ul>
-<p>Thus, when <code>--perms</code> and <code>--executability</code> are both disabled, rsync's
+<p>Thus, when <code>--perms</code> and <a href="#opt--executability"><code>--executability</code></a> are both disabled, rsync's
 behavior is the same as that of other file-copy utilities, such as <strong>cp</strong>(1)
 and <strong>tar</strong>(1).</p>
 <p>In summary: to give destination files (both old and new) the source
 permissions, use <code>--perms</code>.  To give new files the destination-default
 permissions (while leaving existing files unchanged), make sure that the
-<code>--perms</code> option is off and use <code>--chmod=ugo=rwX</code> (which ensures that all
-non-masked bits get enabled).  If you'd care to make this latter behavior
-easier to type, you could define a popt alias for it, such as putting this
-line in the file <code>~/.popt</code> (the following defines the <code>-Z</code> option, and
-includes <code>--no-g</code> to use the default group of the destination dir):</p>
+<code>--perms</code> option is off and use <a href="#opt--chmod"><code>--chmod=ugo=rwX</code></a> (which ensures
+that all non-masked bits get enabled).  If you'd care to make this latter
+behavior easier to type, you could define a popt alias for it, such as
+putting this line in the file <code>~/.popt</code> (the following defines the <code>-Z</code>
+option, and includes <code>--no-g</code> to use the default group of the destination
+dir):</p>
 <blockquote>
 <pre><code> rsync alias -Z --no-p --no-g --chmod=ugo=rwX
 </code></pre>
@@ -1162,10 +1364,10 @@ non-ACL-enabled) rsyncs use the umask even if default ACLs are present.
 these behaviors.)</p>
 </dd>
 
-<dt><code>--executability</code>, <code>-E</code></dt><dd>
+<span id="opt-E"></span><dt id="opt--executability"><code>--executability</code>, <code>-E</code><a href="#opt--executability" class="tgt"></a></dt><dd>
 <p>This option causes rsync to preserve the executability (or
-non-executability) of regular files when <code>--perms</code> is not enabled.  A
-regular file is considered to be executable if at least one 'x' is turned
+non-executability) of regular files when <a href="#opt--perms"><code>--perms</code></a> is not enabled.
+regular file is considered to be executable if at least one 'x' is turned
 on in its permissions.  When an existing destination file's executability
 differs from that of the corresponding source file, rsync modifies the
 destination file's permissions as follows:</p>
@@ -1174,24 +1376,24 @@ destination file's permissions as follows:</p>
 <li>To make a file executable, rsync turns on each 'x' permission that has a
 corresponding 'r' permission enabled.</li>
 </ul>
-<p>If <code>--perms</code> is enabled, this option is ignored.</p>
+<p>If <a href="#opt--perms"><code>--perms</code></a> is enabled, this option is ignored.</p>
 </dd>
 
-<dt><code>--acls</code>, <code>-A</code></dt><dd>
+<span id="opt-A"></span><dt id="opt--acls"><code>--acls</code>, <code>-A</code><a href="#opt--acls" class="tgt"></a></dt><dd>
 <p>This option causes rsync to update the destination ACLs to be the same as
-the source ACLs.  The option also implies <code>--perms</code>.</p>
+the source ACLs.  The option also implies <a href="#opt--perms"><code>--perms</code></a>.</p>
 <p>The source and destination systems must have compatible ACL entries for
-this option to work properly.  See the <code>--fake-super</code> option for a way to
-backup and restore ACLs that are not compatible.</p>
+this option to work properly.  See the <a href="#opt--fake-super"><code>--fake-super</code></a> option for a
+way to backup and restore ACLs that are not compatible.</p>
 </dd>
 
-<dt><code>--xattrs</code>, <code>-X</code></dt><dd>
+<span id="opt-X"></span><dt id="opt--xattrs"><code>--xattrs</code>, <code>-X</code><a href="#opt--xattrs" class="tgt"></a></dt><dd>
 <p>This option causes rsync to update the destination extended attributes to
 be the same as the source ones.</p>
 <p>For systems that support extended-attribute namespaces, a copy being done
 by a super-user copies all namespaces except system.*.  A normal user only
 copies the user.* namespace.  To be able to backup and restore non-user
-namespaces as a normal user, see the <code>--fake-super</code> option.</p>
+namespaces as a normal user, see the <a href="#opt--fake-super"><code>--fake-super</code></a> option.</p>
 <p>The above name filtering can be overridden by using one or more filter
 options with the <strong>x</strong> modifier.  When you specify an xattr-affecting
 filter rule, rsync requires that you do your own system/user filtering, as
@@ -1215,16 +1417,16 @@ receiver-only rule that excludes all names:</p>
 </code></pre>
 </blockquote>
 <p>Note that the <code>-X</code> option does not copy rsync's special xattr values (e.g.
-those used by <code>--fake-super</code>) unless you repeat the option (e.g. <code>-XX</code>).
-This &quot;copy all xattrs&quot; mode cannot be used with <code>--fake-super</code>.</p>
+those used by <a href="#opt--fake-super"><code>--fake-super</code></a>) unless you repeat the option (e.g. <code>-XX</code>).
+This &quot;copy all xattrs&quot; mode cannot be used with <a href="#opt--fake-super"><code>--fake-super</code></a>.</p>
 </dd>
 
-<dt><code>--chmod=CHMOD</code></dt><dd>
+<dt id="opt--chmod"><code>--chmod=CHMOD</code><a href="#opt--chmod" class="tgt"></a></dt><dd>
 <p>This option tells rsync to apply one or more comma-separated &quot;chmod&quot; modes
 to the permission of the files in the transfer.  The resulting value is
 treated as though it were the permissions that the sending side supplied
 for the file, which means that this option can seem to have no effect on
-existing files if <code>--perms</code> is not enabled.</p>
+existing files if <a href="#opt--perms"><code>--perms</code></a> is not enabled.</p>
 <p>In addition to the normal parsing rules specified in the <strong>chmod</strong>(1)
 manpage, you can specify an item that should only apply to a directory by
 prefixing it with a 'D', or specify an item that should only apply to a
@@ -1243,22 +1445,22 @@ consistent executability across all bits:</p>
 </blockquote>
 <p>It is also legal to specify multiple <code>--chmod</code> options, as each additional
 option is just appended to the list of changes to make.</p>
-<p>See the <code>--perms</code> and <code>--executability</code> options for how the resulting
-permission value can be applied to the files in the transfer.</p>
+<p>See the <a href="#opt--perms"><code>--perms</code></a> and <a href="#opt--executability"><code>--executability</code></a> options for how the
+resulting permission value can be applied to the files in the transfer.</p>
 </dd>
 
-<dt><code>--owner</code>, <code>-o</code></dt><dd>
+<span id="opt-o"></span><dt id="opt--owner"><code>--owner</code>, <code>-o</code><a href="#opt--owner" class="tgt"></a></dt><dd>
 <p>This option causes rsync to set the owner of the destination file to be the
 same as the source file, but only if the receiving rsync is being run as
-the super-user (see also the <code>--super</code> and <code>--fake-super</code> options).  Without
-this option, the owner of new and/or transferred files are set to the
-invoking user on the receiving side.</p>
+the super-user (see also the <a href="#opt--super"><code>--super</code></a> and <a href="#opt--fake-super"><code>--fake-super</code></a>
+options).  Without this option, the owner of new and/or transferred files
+are set to the invoking user on the receiving side.</p>
 <p>The preservation of ownership will associate matching names by default, but
 may fall back to using the ID number in some circumstances (see also the
-<code>--numeric-ids</code> option for a full discussion).</p>
+<a href="#opt--numeric-ids"><code>--numeric-ids</code></a> option for a full discussion).</p>
 </dd>
 
-<dt><code>--group</code>, <code>-g</code></dt><dd>
+<span id="opt-g"></span><dt id="opt--group"><code>--group</code>, <code>-g</code><a href="#opt--group" class="tgt"></a></dt><dd>
 <p>This option causes rsync to set the group of the destination file to be the
 same as the source file.  If the receiving program is not running as the
 super-user (or if <code>--no-super</code> was specified), only groups that the
@@ -1267,58 +1469,82 @@ Without this option, the group is set to the default group of the invoking
 user on the receiving side.</p>
 <p>The preservation of group information will associate matching names by
 default, but may fall back to using the ID number in some circumstances
-(see also the <code>--numeric-ids</code> option for a full discussion).</p>
+(see also the <a href="#opt--numeric-ids"><code>--numeric-ids</code></a> option for a full discussion).</p>
 </dd>
 
-<dt><code>--devices</code></dt><dd>
+<dt id="opt--devices"><code>--devices</code><a href="#opt--devices" class="tgt"></a></dt><dd>
 <p>This option causes rsync to transfer character and block device files to
-the remote system to recreate these devices.  This option has no effect if
-the receiving rsync is not run as the super-user (see also the <code>--super</code>
-and <code>--fake-super</code> options).</p>
+the remote system to recreate these devices.  If the receiving rsync is not
+being run as the super-user, rsync silently skips creating the device files
+(see also the <a href="#opt--super"><code>--super</code></a> and <a href="#opt--fake-super"><code>--fake-super</code></a> options).</p>
+<p>By default, rsync generates a &quot;non-regular file&quot; warning for each device
+file encountered when this option is not set.  You can silence the warning
+by specifying <a href="#opt--info"><code>--info=nonreg0</code></a>.</p>
 </dd>
 
-<dt><code>--specials</code></dt><dd>
-<p>This option causes rsync to transfer special files such as named sockets
-and fifos.</p>
+<dt id="opt--specials"><code>--specials</code><a href="#opt--specials" class="tgt"></a></dt><dd>
+<p>This option causes rsync to transfer special files, such as named sockets
+and fifos.  If the receiving rsync is not being run as the super-user,
+rsync silently skips creating the special files (see also the
+<a href="#opt--super"><code>--super</code></a> and <a href="#opt--fake-super"><code>--fake-super</code></a> options).</p>
+<p>By default, rsync generates a &quot;non-regular file&quot; warning for each special
+file encountered when this option is not set.  You can silence the warning
+by specifying <a href="#opt--info"><code>--info=nonreg0</code></a>.</p>
 </dd>
 
-<dt><code>-D</code></dt><dd>
-<p>The <code>-D</code> option is equivalent to <code>--devices --specials</code>.</p>
+<dt id="opt-D"><code>-D</code><a href="#opt-D" class="tgt"></a></dt><dd>
+<p>The <code>-D</code> option is equivalent to &quot;<a href="#opt--devices"><code>--devices</code></a>
+<a href="#opt--specials"><code>--specials</code></a>&quot;.</p>
 </dd>
 
-<dt><code>--write-devices</code></dt><dd>
+<dt id="opt--copy-devices"><code>--copy-devices</code><a href="#opt--copy-devices" class="tgt"></a></dt><dd>
+<p>This tells rsync to treat a device on the sending side as a regular file,
+allowing it to be copied to a normal destination file (or another device
+if <code>--write-devices</code> was also specified).</p>
+<p>This option is refused by default by an rsync daemon.</p>
+</dd>
+
+<dt id="opt--write-devices"><code>--write-devices</code><a href="#opt--write-devices" class="tgt"></a></dt><dd>
 <p>This tells rsync to treat a device on the receiving side as a regular file,
 allowing the writing of file data into a device.</p>
-<p>This option implies the <code>--inplace</code> option.</p>
+<p>This option implies the <a href="#opt--inplace"><code>--inplace</code></a> option.</p>
 <p>Be careful using this, as you should know what devices are present on the
-receiving side of the transfer, especially if running rsync as root.</p>
-<p>This option is refused by an rsync daemon.</p>
+receiving side of the transfer, especially when running rsync as root.</p>
+<p>This option is refused by default by an rsync daemon.</p>
 </dd>
 
-<dt><code>--times</code>, <code>-t</code></dt><dd>
+<span id="opt-t"></span><dt id="opt--times"><code>--times</code>, <code>-t</code><a href="#opt--times" class="tgt"></a></dt><dd>
 <p>This tells rsync to transfer modification times along with the files and
 update them on the remote system.  Note that if this option is not used,
 the optimization that excludes files that have not been modified cannot be
-effective; in other words, a missing <code>-t</code> or <code>-a</code> will cause the next
-transfer to behave as if it used <code>-I</code>, causing all files to be updated
-(though rsync's delta-transfer algorithm will make the update fairly
-efficient if the files haven't actually changed, you're much better off
-using <code>-t</code>).</p>
-</dd>
-
-<dt><code>--atimes</code>, <code>-U</code></dt><dd>
+effective; in other words, a missing <code>-t</code> (or <a href="#opt-a"><code>-a</code></a>) will cause the
+next transfer to behave as if it used <a href="#opt--ignore-times"><code>--ignore-times</code></a> (<code>-I</code>),
+causing all files to be updated (though rsync's delta-transfer algorithm
+will make the update fairly efficient if the files haven't actually
+changed, you're much better off using <code>-t</code>).</p>
+<p>A modern rsync that is using transfer protocol 30 or 31 conveys a modify
+time using up to 8-bytes. If rsync is forced to speak an older protocol
+(perhaps due to the remote rsync being older than 3.0.0) a modify time is
+conveyed using 4-bytes. Prior to 3.2.7, these shorter values could convey
+a date range of 13-Dec-1901 to 19-Jan-2038.  Beginning with 3.2.7, these
+4-byte values now convey a date range of 1-Jan-1970 to 7-Feb-2106.  If you
+have files dated older than 1970, make sure your rsync executables are
+upgraded so that the full range of dates can be conveyed.</p>
+</dd>
+
+<span id="opt-U"></span><dt id="opt--atimes"><code>--atimes</code>, <code>-U</code><a href="#opt--atimes" class="tgt"></a></dt><dd>
 <p>This tells rsync to set the access (use) times of the destination files to
 the same value as the source files.</p>
-<p>If repeated, it also sets the <code>--open-noatime</code> option, which can help you
+<p>If repeated, it also sets the <a href="#opt--open-noatime"><code>--open-noatime</code></a> option, which can help you
 to make the sending and receiving systems have the same access times on the
 transferred files without needing to run rsync an extra time after a file
 is transferred.</p>
 <p>Note that some older rsync versions (prior to 3.2.0) may have been built
-with a pre-release <code>--atimes</code> patch that does not imply <code>--open-noatime</code>
-when this option is repeated.</p>
+with a pre-release <code>--atimes</code> patch that does not imply
+<a href="#opt--open-noatime"><code>--open-noatime</code></a> when this option is repeated.</p>
 </dd>
 
-<dt><code>--open-noatime</code></dt><dd>
+<dt id="opt--open-noatime"><code>--open-noatime</code><a href="#opt--open-noatime" class="tgt"></a></dt><dd>
 <p>This tells rsync to open files with the O_NOATIME flag (on systems that
 support it) to avoid changing the access time of the files that are being
 transferred.  If your OS does not support the O_NOATIME flag then rsync
@@ -1327,45 +1553,39 @@ mounted to avoid updating the atime on read access even without the
 O_NOATIME flag being set.</p>
 </dd>
 
-<dt><code>--crtimes</code>, <code>-N,</code></dt><dd>
+<span id="opt-N_"></span><dt id="opt--crtimes"><code>--crtimes</code>, <code>-N,</code><a href="#opt--crtimes" class="tgt"></a></dt><dd>
 <p>This tells rsync to set the create times (newness) of the destination
 files to the same value as the source files.</p>
 </dd>
 
-<dt><code>--omit-dir-times</code>, <code>-O</code></dt><dd>
-<p>This tells rsync to omit directories when it is preserving modification
-times (see <code>--times</code>).  If NFS is sharing the directories on the receiving
+<span id="opt-O"></span><dt id="opt--omit-dir-times"><code>--omit-dir-times</code>, <code>-O</code><a href="#opt--omit-dir-times" class="tgt"></a></dt><dd>
+<p>This tells rsync to omit directories when it is preserving modification,
+access, and create times.  If NFS is sharing the directories on the receiving
 side, it is a good idea to use <code>-O</code>.  This option is inferred if you use
-<code>--backup</code> without <code>--backup-dir</code>.</p>
-<p>This option also has the side-effect of avoiding early creation of
-directories in incremental recursion copies.  The default <code>--inc-recursive</code>
-copying normally does an early-create pass of all the sub-directories in a
-parent directory in order for it to be able to then set the modify time of
-the parent directory right away (without having to delay that until a bunch
-of recursive copying has finished).  This early-create idiom is not
-necessary if directory modify times are not being preserved, so it is
-skipped.  Since early-create directories don't have accurate mode, mtime,
-or ownership, the use of this option can help when someone wants to avoid
-these partially-finished directories.</p>
+<a href="#opt--backup"><code>--backup</code></a> without <a href="#opt--backup-dir"><code>--backup-dir</code></a>.</p>
+<p>This option also has the side-effect of avoiding early creation of missing
+sub-directories when incremental recursion is enabled, as discussed in the
+<a href="#opt--inc-recursive"><code>--inc-recursive</code></a> section.</p>
 </dd>
 
-<dt><code>--omit-link-times</code>, <code>-J</code></dt><dd>
-<p>This tells rsync to omit symlinks when it is preserving modification times
-(see <code>--times</code>).</p>
+<span id="opt-J"></span><dt id="opt--omit-link-times"><code>--omit-link-times</code>, <code>-J</code><a href="#opt--omit-link-times" class="tgt"></a></dt><dd>
+<p>This tells rsync to omit symlinks when it is preserving modification,
+access, and create times.</p>
 </dd>
 
-<dt><code>--super</code></dt><dd>
+<dt id="opt--super"><code>--super</code><a href="#opt--super" class="tgt"></a></dt><dd>
 <p>This tells the receiving side to attempt super-user activities even if the
 receiving rsync wasn't run by the super-user.  These activities include:
-preserving users via the <code>--owner</code> option, preserving all groups (not just
-the current user's groups) via the <code>--groups</code> option, and copying devices
-via the <code>--devices</code> option.  This is useful for systems that allow such
-activities without being the super-user, and also for ensuring that you
-will get errors if the receiving side isn't being run as the super-user.
-To turn off super-user activities, the super-user can use <code>--no-super</code>.</p>
+preserving users via the <a href="#opt--owner"><code>--owner</code></a> option, preserving all groups
+(not just the current user's groups) via the <a href="#opt--group"><code>--group</code></a> option, and
+copying devices via the <a href="#opt--devices"><code>--devices</code></a> option.  This is useful for
+systems that allow such activities without being the super-user, and also
+for ensuring that you will get errors if the receiving side isn't being run
+as the super-user.  To turn off super-user activities, the super-user can
+use <code>--no-super</code>.</p>
 </dd>
 
-<dt><code>--fake-super</code></dt><dd>
+<dt id="opt--fake-super"><code>--fake-super</code><a href="#opt--fake-super" class="tgt"></a></dt><dd>
 <p>When this option is enabled, rsync simulates super-user activities by
 saving/restoring the privileged attributes via special extended attributes
 that are attached to each file (as needed).  This includes the file's owner
@@ -1375,13 +1595,13 @@ that we won't allow to be set on the real file (e.g. the real file gets
 u-s,g-s,o-t for safety) or that would limit the owner's access (since the
 real super-user can always access/change a file, the files we create can
 always be accessed/changed by the creating user).  This option also handles
-ACLs (if <code>--acls</code> was specified) and non-user extended attributes (if
-<code>--xattrs</code> was specified).</p>
+ACLs (if <a href="#opt--acls"><code>--acls</code></a> was specified) and non-user extended attributes
+(if <a href="#opt--xattrs"><code>--xattrs</code></a> was specified).</p>
 <p>This is a good way to backup data without using a super-user, and to store
 ACLs from incompatible systems.</p>
 <p>The <code>--fake-super</code> option only affects the side where the option is used.
 To affect the remote side of a remote-shell connection, use the
-<code>--remote-option</code> (<code>-M</code>) option:</p>
+<a href="#opt--remote-option"><code>--remote-option</code></a> (<code>-M</code>) option:</p>
 <blockquote>
 <pre><code>rsync -av -M--fake-super /src/ host:/dest/
 </code></pre>
@@ -1390,22 +1610,23 @@ To affect the remote side of a remote-shell connection, use the
 If you wish a local copy to enable this option just for the destination
 files, specify <code>-M--fake-super</code>.  If you wish a local copy to enable this
 option just for the source files, combine <code>--fake-super</code> with <code>-M--super</code>.</p>
-<p>This option is overridden by both <code>--super</code> and <code>--no-super</code>.</p>
-<p>See also the &quot;<code>fake super</code>&quot; setting in the daemon's rsyncd.conf file.</p>
+<p>This option is overridden by both <a href="#opt--super"><code>--super</code></a> and <code>--no-super</code>.</p>
+<p>See also the <a href="rsyncd.conf.5#fake_super"><code>fake super</code></a> setting in the
+daemon's rsyncd.conf file.</p>
 </dd>
 
-<dt><code>--sparse</code>, <code>-S</code></dt><dd>
+<span id="opt-S"></span><dt id="opt--sparse"><code>--sparse</code>, <code>-S</code><a href="#opt--sparse" class="tgt"></a></dt><dd>
 <p>Try to handle sparse files efficiently so they take up less space on the
-destination.  If combined with <code>--inplace</code> the file created might not end
-up with sparse blocks with some combinations of kernel version and/or
-filesystem type.  If <code>--whole-file</code> is in effect (e.g. for a local copy)
-then it will always work because rsync truncates the file prior to writing
-out the updated version.</p>
+destination.  If combined with <a href="#opt--inplace"><code>--inplace</code></a> the file created might
+not end up with sparse blocks with some combinations of kernel version
+and/or filesystem type.  If <a href="#opt--whole-file"><code>--whole-file</code></a> is in effect (e.g. for a
+local copy) then it will always work because rsync truncates the file prior
+to writing out the updated version.</p>
 <p>Note that versions of rsync older than 3.1.3 will reject the combination of
-<code>--sparse</code> and <code>--inplace</code>.</p>
+<code>--sparse</code> and <a href="#opt--inplace"><code>--inplace</code></a>.</p>
 </dd>
 
-<dt><code>--preallocate</code></dt><dd>
+<dt id="opt--preallocate"><code>--preallocate</code><a href="#opt--preallocate" class="tgt"></a></dt><dd>
 <p>This tells the receiver to allocate each destination file to its eventual
 size before writing data to the file.  Rsync will only use the real
 filesystem-level preallocation support provided by Linux's <strong>fallocate</strong>(2)
@@ -1415,28 +1636,28 @@ implementation that writes a null byte into each block.</p>
 filesystem, but with this option rsync will probably copy more slowly.  If
 the destination is not an extent-supporting filesystem (such as ext4, xfs,
 NTFS, etc.), this option may have no positive effect at all.</p>
-<p>If combined with <code>--sparse</code>, the file will only have sparse blocks (as
-opposed to allocated sequences of null bytes) if the kernel version and
+<p>If combined with <a href="#opt--sparse"><code>--sparse</code></a>, the file will only have sparse blocks
+(as opposed to allocated sequences of null bytes) if the kernel version and
 filesystem type support creating holes in the allocated data.</p>
 </dd>
 
-<dt><code>--dry-run</code>, <code>-n</code></dt><dd>
+<span id="opt-n"></span><dt id="opt--dry-run"><code>--dry-run</code>, <code>-n</code><a href="#opt--dry-run" class="tgt"></a></dt><dd>
 <p>This makes rsync perform a trial run that doesn't make any changes (and
 produces mostly the same output as a real run).  It is most commonly used
-in combination with the <code>--verbose</code>, <code>-v</code> and/or <code>--itemize-changes</code>, <code>-i</code>
-options to see what an rsync command is going to do before one actually
-runs it.</p>
-<p>The output of <code>--itemize-changes</code> is supposed to be exactly the same on a
-dry run and a subsequent real run (barring intentional trickery and system
-call failures); if it isn't, that's a bug.  Other output should be mostly
-unchanged, but may differ in some areas.  Notably, a dry run does not send
-the actual data for file transfers, so <code>--progress</code> has no effect, the
-&quot;bytes sent&quot;, &quot;bytes received&quot;, &quot;literal data&quot;, and &quot;matched data&quot;
-statistics are too small, and the &quot;speedup&quot; value is equivalent to a run
-where no file transfers were needed.</p>
-</dd>
-
-<dt><code>--whole-file</code>, <code>-W</code></dt><dd>
+in combination with the <a href="#opt--verbose"><code>--verbose</code></a> (<code>-v</code>) and/or
+<a href="#opt--itemize-changes"><code>--itemize-changes</code></a> (<code>-i</code>) options to see what an rsync command is
+going to do before one actually runs it.</p>
+<p>The output of <a href="#opt--itemize-changes"><code>--itemize-changes</code></a> is supposed to be exactly the
+same on a dry run and a subsequent real run (barring intentional trickery
+and system call failures); if it isn't, that's a bug.  Other output should
+be mostly unchanged, but may differ in some areas.  Notably, a dry run does
+not send the actual data for file transfers, so <a href="#opt--progress"><code>--progress</code></a> has no
+effect, the &quot;bytes sent&quot;, &quot;bytes received&quot;, &quot;literal data&quot;, and &quot;matched
+data&quot; statistics are too small, and the &quot;speedup&quot; value is equivalent to a
+run where no file transfers were needed.</p>
+</dd>
+
+<span id="opt-W"></span><dt id="opt--whole-file"><code>--whole-file</code>, <code>-W</code><a href="#opt--whole-file" class="tgt"></a></dt><dd>
 <p>This option disables rsync's delta-transfer algorithm, which causes all
 transferred files to be sent whole.  The transfer may be faster if this
 option is used when the bandwidth between the source and destination
@@ -1446,10 +1667,18 @@ source and destination are specified as local paths, but only if no
 batch-writing option is in effect.</p>
 </dd>
 
-<dt><code>--checksum-choice=STR</code>, <code>--cc=STR</code></dt><dd>
+<span id="opt--no-W"></span><dt id="opt--no-whole-file"><code>--no-whole-file</code>, <code>--no-W</code><a href="#opt--no-whole-file" class="tgt"></a></dt><dd>
+<p>Disable whole-file updating when it is enabled by default for a local
+transfer.  This usually slows rsync down, but it can be useful if you are
+trying to minimize the writes to the destination file (if combined with
+<a href="#opt--inplace"><code>--inplace</code></a>) or for testing the checksum-based update algorithm.</p>
+<p>See also the <a href="#opt--whole-file"><code>--whole-file</code></a> option.</p>
+</dd>
+
+<span id="opt--cc"></span><dt id="opt--checksum-choice"><code>--checksum-choice=STR</code>, <code>--cc=STR</code><a href="#opt--checksum-choice" class="tgt"></a></dt><dd>
 <p>This option overrides the checksum algorithms.  If one algorithm name is
 specified, it is used for both the transfer checksums and (assuming
-<code>--checksum</code> is specified) the pre-transfer checksums.  If two
+<a href="#opt--checksum"><code>--checksum</code></a> is specified) the pre-transfer checksums.  If two
 comma-separated names are supplied, the first name affects the transfer
 checksums, and the second name affects the pre-transfer checksums (<code>-c</code>).</p>
 <p>The checksum options that you may be able to use are:</p>
@@ -1460,14 +1689,15 @@ checksums, and the second name affects the pre-transfer checksums (<code>-c</cod
 <li><code>xxh64</code> (aka <code>xxhash</code>)</li>
 <li><code>md5</code></li>
 <li><code>md4</code></li>
+<li><code>sha1</code></li>
 <li><code>none</code></li>
 </ul>
 <p>Run <code>rsync --version</code> to see the default checksum list compiled into your
 version (which may differ from the list above).</p>
-<p>If &quot;none&quot; is specified for the first (or only) name, the <code>--whole-file</code>
+<p>If &quot;none&quot; is specified for the first (or only) name, the <a href="#opt--whole-file"><code>--whole-file</code></a>
 option is forced on and no checksum verification is performed on the
 transferred data.  If &quot;none&quot; is specified for the second (or only) name,
-the <code>--checksum</code> option cannot be used.</p>
+the <a href="#opt--checksum"><code>--checksum</code></a> option cannot be used.</p>
 <p>The &quot;auto&quot; option is the default, where rsync bases its algorithm choice on
 a negotiation between the client and the server as follows:</p>
 <p>When both sides of the transfer are at least 3.2.0, rsync chooses the first
@@ -1477,18 +1707,18 @@ an error.  If the remote rsync is too old to support checksum negotiation,
 a value is chosen based on the protocol version (which chooses between MD5
 and various flavors of MD4 based on protocol age).</p>
 <p>The default order can be customized by setting the environment variable
-RSYNC_CHECKSUM_LIST to a space-separated list of acceptable checksum names.
-If the string contains a &quot;<code>&amp;</code>&quot; character, it is separated into the &quot;client
-string &amp; server string&quot;, otherwise the same string
-applies to both.  If the string (or string portion) contains no
-non-whitespace characters, the default checksum list is used.  This method
-does not allow you to specify the transfer checksum separately from the
-pre-transfer checksum, and it discards &quot;auto&quot; and all unknown checksum
-names.  A list with only invalid names results in a failed negotiation.</p>
+<a href="#RSYNC_CHECKSUM_LIST"><code>RSYNC_CHECKSUM_LIST</code></a> to a space-separated list of acceptable checksum
+names.  If the string contains a &quot;<code>&amp;</code>&quot; character, it is separated into the
+&quot;client string &amp; server string&quot;, otherwise the same string applies to both.
+If the string (or string portion) contains no non-whitespace characters,
+the default checksum list is used.  This method does not allow you to
+specify the transfer checksum separately from the pre-transfer checksum,
+and it discards &quot;auto&quot; and all unknown checksum names.  A list with only
+invalid names results in a failed negotiation.</p>
 <p>The use of the <code>--checksum-choice</code> option overrides this environment list.</p>
 </dd>
 
-<dt><code>--one-file-system</code>, <code>-x</code></dt><dd>
+<span id="opt-x"></span><dt id="opt--one-file-system"><code>--one-file-system</code>, <code>-x</code><a href="#opt--one-file-system" class="tgt"></a></dt><dd>
 <p>This tells rsync to avoid crossing a filesystem boundary when recursing.
 This does not limit the user's ability to specify items to copy from
 multiple filesystems, just rsync's recursion through the hierarchy of each
@@ -1499,39 +1729,44 @@ receiving side during deletion.  Also keep in mind that rsync treats a
 the copy.  Otherwise, it includes an empty directory at each mount-point it
 encounters (using the attributes of the mounted directory because those of
 the underlying mount-point directory are inaccessible).</p>
-<p>If rsync has been told to collapse symlinks (via <code>--copy-links</code> or
-<code>--copy-unsafe-links</code>), a symlink to a directory on another device is
-treated like a mount-point.  Symlinks to non-directories are unaffected by
-this option.</p>
+<p>If rsync has been told to collapse symlinks (via <a href="#opt--copy-links"><code>--copy-links</code></a> or
+<a href="#opt--copy-unsafe-links"><code>--copy-unsafe-links</code></a>), a symlink to a directory on another device
+is treated like a mount-point.  Symlinks to non-directories are unaffected
+by this option.</p>
 </dd>
 
-<dt><code>--existing</code>, <code>--ignore-non-existing</code></dt><dd>
+<span id="opt--existing"></span><dt id="opt--ignore-non-existing"><code>--ignore-non-existing</code>, <code>--existing</code><a href="#opt--ignore-non-existing" class="tgt"></a></dt><dd>
 <p>This tells rsync to skip creating files (including directories) that do not
 exist yet on the destination.  If this option is combined with the
-<code>--ignore-existing</code> option, no files will be updated (which can be useful
-if all you want to do is delete extraneous files).</p>
-<p>This option is a transfer rule, not an exclude, so it doesn't affect the
-data that goes into the file-lists, and thus it doesn't affect deletions.
-It just limits the files that the receiver requests to be transferred.</p>
+<a href="#opt--ignore-existing"><code>--ignore-existing</code></a> option, no files will be updated (which can be
+useful if all you want to do is delete extraneous files).</p>
+<p>This option is a <a href="#TRANSFER_RULES">TRANSFER RULE</a>, so don't expect any
+exclude side effects.</p>
 </dd>
 
-<dt><code>--ignore-existing</code></dt><dd>
+<dt id="opt--ignore-existing"><code>--ignore-existing</code><a href="#opt--ignore-existing" class="tgt"></a></dt><dd>
 <p>This tells rsync to skip updating files that already exist on the
 destination (this does <u>not</u> ignore existing directories, or nothing would
-get done).  See also <code>--existing</code>.</p>
-<p>This option is a transfer rule, not an exclude, so it doesn't affect the
-data that goes into the file-lists, and thus it doesn't affect deletions.
-It just limits the files that the receiver requests to be transferred.</p>
-<p>This option can be useful for those doing backups using the <code>--link-dest</code>
-option when they need to continue a backup run that got interrupted.  Since
-a <code>--link-dest</code> run is copied into a new directory hierarchy (when it is
-used properly), using <code>--ignore-existing</code> will ensure that the
-already-handled files don't get tweaked (which avoids a change in
-permissions on the hard-linked files).  This does mean that this option is
-only looking at the existing files in the destination hierarchy itself.</p>
-</dd>
-
-<dt><code>--remove-source-files</code></dt><dd>
+get done).  See also <a href="#opt--ignore-non-existing"><code>--ignore-non-existing</code></a>.</p>
+<p>This option is a <a href="#TRANSFER_RULES">TRANSFER RULE</a>, so don't expect any
+exclude side effects.</p>
+<p>This option can be useful for those doing backups using the
+<a href="#opt--link-dest"><code>--link-dest</code></a> option when they need to continue a backup run that
+got interrupted.  Since a <a href="#opt--link-dest"><code>--link-dest</code></a> run is copied into a new
+directory hierarchy (when it is used properly), using [<code>--ignore-existing</code>
+will ensure that the already-handled files don't get tweaked (which avoids
+a change in permissions on the hard-linked files).  This does mean that
+this option is only looking at the existing files in the destination
+hierarchy itself.</p>
+<p>When <a href="#opt--info"><code>--info=skip2</code></a> is used rsync will output &quot;FILENAME exists
+(INFO)&quot; messages where the INFO indicates one of &quot;type change&quot;, &quot;sum
+change&quot; (requires <a href="#opt-c"><code>-c</code></a>), &quot;file change&quot; (based on the quick check),
+&quot;attr change&quot;, or &quot;uptodate&quot;.  Using <a href="#opt--info"><code>--info=skip1</code></a> (which is also
+implied by 2 <a href="#opt-v"><code>-v</code></a> options) outputs the exists message without the
+INFO suffix.</p>
+</dd>
+
+<dt id="opt--remove-source-files"><code>--remove-source-files</code><a href="#opt--remove-source-files" class="tgt"></a></dt><dd>
 <p>This tells rsync to remove from the sending side the files (meaning
 non-directories) that are a part of the transfer and have been successfully
 duplicated on the receiving side.</p>
@@ -1543,13 +1778,16 @@ so that rsync can't possibly transfer a file that is not yet fully written.
 If you can't first write the files into a different directory, you should
 use a naming idiom that lets rsync avoid transferring files that are not
 yet finished (e.g. name the file &quot;foo.new&quot; when it is written, rename it to
-&quot;foo&quot; when it is done, and then use the option <code>--exclude='*.new'</code> for the
-rsync transfer).</p>
+&quot;foo&quot; when it is done, and then use the option <a href="#opt--exclude"><code>--exclude='*.new'</code></a>
+for the rsync transfer).</p>
 <p>Starting with 3.1.0, rsync will skip the sender-side removal (and output an
 error) if the file's size or modify time has not stayed unchanged.</p>
+<p>Starting with 3.2.6, a local rsync copy will ensure that the sender does
+not remove a file the receiver just verified, such as when the user
+accidentally makes the source and destination directory the same path.</p>
 </dd>
 
-<dt><code>--delete</code></dt><dd>
+<dt id="opt--delete"><code>--delete</code><a href="#opt--delete" class="tgt"></a></dt><dd>
 <p>This tells rsync to delete extraneous files from the receiving side (ones
 that aren't on the sending side), but only for the directories that are
 being synchronized.  You must have asked rsync to send the whole directory
@@ -1557,122 +1795,135 @@ being synchronized.  You must have asked rsync to send the whole directory
 contents (e.g. &quot;<code>dir/*</code>&quot;) since the wildcard is expanded by the shell and
 rsync thus gets a request to transfer individual files, not the files'
 parent directory.  Files that are excluded from the transfer are also
-excluded from being deleted unless you use the <code>--delete-excluded</code> option
-or mark the rules as only matching on the sending side (see the
-include/exclude modifiers in the FILTER RULES section).</p>
-<p>Prior to rsync 2.6.7, this option would have no effect unless <code>--recursive</code>
-was enabled.  Beginning with 2.6.7, deletions will also occur when <code>--dirs</code>
-(<code>-d</code>) is enabled, but only for directories whose contents are being
-copied.</p>
+excluded from being deleted unless you use the <a href="#opt--delete-excluded"><code>--delete-excluded</code></a>
+option or mark the rules as only matching on the sending side (see the
+include/exclude modifiers in the <a href="#FILTER_RULES">FILTER RULES</a> section).</p>
+<p>Prior to rsync 2.6.7, this option would have no effect unless
+<a href="#opt--recursive"><code>--recursive</code></a> was enabled.  Beginning with 2.6.7, deletions will
+also occur when <a href="#opt--dirs"><code>--dirs</code></a> (<code>-d</code>) is enabled, but only for
+directories whose contents are being copied.</p>
 <p>This option can be dangerous if used incorrectly! It is a very good idea to
-first try a run using the <code>--dry-run</code> option (<code>-n</code>) to see what files are
-going to be deleted.</p>
+first try a run using the <a href="#opt--dry-run"><code>--dry-run</code></a> (<code>-n</code>) option to see what
+files are going to be deleted.</p>
 <p>If the sending side detects any I/O errors, then the deletion of any files
 at the destination will be automatically disabled.  This is to prevent
 temporary filesystem failures (such as NFS errors) on the sending side from
 causing a massive deletion of files on the destination.  You can override
-this with the <code>--ignore-errors</code> option.</p>
+this with the <a href="#opt--ignore-errors"><code>--ignore-errors</code></a> option.</p>
 <p>The <code>--delete</code> option may be combined with one of the -&#8288;-&#8288;delete-WHEN options
-without conflict, as well as <code>--delete-excluded</code>.  However, if none of the
-<code>--delete-WHEN</code> options are specified, rsync will choose the
-<code>--delete-during</code> algorithm when talking to rsync 3.0.0 or newer, and the
-<code>--delete-before</code> algorithm when talking to an older rsync.  See also
-<code>--delete-delay</code> and <code>--delete-after</code>.</p>
+without conflict, as well as <a href="#opt--delete-excluded"><code>--delete-excluded</code></a>.  However, if none
+of the <code>--delete-WHEN</code> options are specified, rsync will choose the
+<a href="#opt--delete-during"><code>--delete-during</code></a> algorithm when talking to rsync 3.0.0 or newer,
+or the <a href="#opt--delete-before"><code>--delete-before</code></a> algorithm when talking to an older rsync.
+See also <a href="#opt--delete-delay"><code>--delete-delay</code></a> and <a href="#opt--delete-after"><code>--delete-after</code></a>.</p>
 </dd>
 
-<dt><code>--delete-before</code></dt><dd>
+<dt id="opt--delete-before"><code>--delete-before</code><a href="#opt--delete-before" class="tgt"></a></dt><dd>
 <p>Request that the file-deletions on the receiving side be done before the
-transfer starts.  See <code>--delete</code> (which is implied) for more details on
-file-deletion.</p>
+transfer starts.  See <a href="#opt--delete"><code>--delete</code></a> (which is implied) for more
+details on file-deletion.</p>
 <p>Deleting before the transfer is helpful if the filesystem is tight for
 space and removing extraneous files would help to make the transfer
 possible.  However, it does introduce a delay before the start of the
 transfer, and this delay might cause the transfer to timeout (if
-<code>--timeout</code> was specified).  It also forces rsync to use the old,
+<a href="#opt--timeout"><code>--timeout</code></a> was specified).  It also forces rsync to use the old,
 non-incremental recursion algorithm that requires rsync to scan all the
-files in the transfer into memory at once (see <code>--recursive</code>).</p>
+files in the transfer into memory at once (see <a href="#opt--recursive"><code>--recursive</code></a>).</p>
 </dd>
 
-<dt><code>--delete-during</code>, <code>--del</code></dt><dd>
+<span id="opt--del"></span><dt id="opt--delete-during"><code>--delete-during</code>, <code>--del</code><a href="#opt--delete-during" class="tgt"></a></dt><dd>
 <p>Request that the file-deletions on the receiving side be done incrementally
 as the transfer happens.  The per-directory delete scan is done right
 before each directory is checked for updates, so it behaves like a more
-efficient <code>--delete-before</code>, including doing the deletions prior to any
-per-directory filter files being updated.  This option was first added in
-rsync version 2.6.4.  See <code>--delete</code> (which is implied) for more details on
-file-deletion.</p>
+efficient <a href="#opt--delete-before"><code>--delete-before</code></a>, including doing the deletions prior to
+any per-directory filter files being updated.  This option was first added
+in rsync version 2.6.4.  See <a href="#opt--delete"><code>--delete</code></a> (which is implied) for more
+details on file-deletion.</p>
 </dd>
 
-<dt><code>--delete-delay</code></dt><dd>
+<dt id="opt--delete-delay"><code>--delete-delay</code><a href="#opt--delete-delay" class="tgt"></a></dt><dd>
 <p>Request that the file-deletions on the receiving side be computed during
-the transfer (like <code>--delete-during</code>), and then removed after the transfer
-completes.  This is useful when combined with <code>--delay-updates</code> and/or
-<code>--fuzzy</code>, and is more efficient than using <code>--delete-after</code> (but can
-behave differently, since <code>--delete-after</code> computes the deletions in a
-separate pass after all updates are done).  If the number of removed files
-overflows an internal buffer, a temporary file will be created on the
-receiving side to hold the names (it is removed while open, so you
-shouldn't see it during the transfer).  If the creation of the temporary
-file fails, rsync will try to fall back to using <code>--delete-after</code> (which it
-cannot do if <code>--recursive</code> is doing an incremental scan).  See <code>--delete</code>
-(which is implied) for more details on file-deletion.</p>
-</dd>
-
-<dt><code>--delete-after</code></dt><dd>
+the transfer (like <a href="#opt--delete-during"><code>--delete-during</code></a>), and then removed after the
+transfer completes.  This is useful when combined with
+<a href="#opt--delay-updates"><code>--delay-updates</code></a> and/or <a href="#opt--fuzzy"><code>--fuzzy</code></a>, and is more efficient
+than using <a href="#opt--delete-after"><code>--delete-after</code></a> (but can behave differently, since
+<a href="#opt--delete-after"><code>--delete-after</code></a> computes the deletions in a separate pass after
+all updates are done).  If the number of removed files overflows an
+internal buffer, a temporary file will be created on the receiving side to
+hold the names (it is removed while open, so you shouldn't see it during
+the transfer).  If the creation of the temporary file fails, rsync will try
+to fall back to using <a href="#opt--delete-after"><code>--delete-after</code></a> (which it cannot do if
+<a href="#opt--recursive"><code>--recursive</code></a> is doing an incremental scan).  See
+<a href="#opt--delete"><code>--delete</code></a> (which is implied) for more details on file-deletion.</p>
+</dd>
+
+<dt id="opt--delete-after"><code>--delete-after</code><a href="#opt--delete-after" class="tgt"></a></dt><dd>
 <p>Request that the file-deletions on the receiving side be done after the
 transfer has completed.  This is useful if you are sending new
 per-directory merge files as a part of the transfer and you want their
 exclusions to take effect for the delete phase of the current transfer.  It
 also forces rsync to use the old, non-incremental recursion algorithm that
 requires rsync to scan all the files in the transfer into memory at once
-(see <code>--recursive</code>). See <code>--delete</code> (which is implied) for more details on
-file-deletion.</p>
-</dd>
-
-<dt><code>--delete-excluded</code></dt><dd>
-<p>In addition to deleting the files on the receiving side that are not on the
-sending side, this tells rsync to also delete any files on the receiving
-side that are excluded (see <code>--exclude</code>).  See the FILTER RULES section for
-a way to make individual exclusions behave this way on the receiver, and
-for a way to protect files from <code>--delete-excluded</code>.  See <code>--delete</code> (which
-is implied) for more details on file-deletion.</p>
-</dd>
-
-<dt><code>--ignore-missing-args</code></dt><dd>
+(see <a href="#opt--recursive"><code>--recursive</code></a>). See <a href="#opt--delete"><code>--delete</code></a> (which is implied) for
+more details on file-deletion.</p>
+<p>See also the <a href="#opt--delete-delay"><code>--delete-delay</code></a> option that might be a faster choice
+for those that just want the deletions to occur at the end of the transfer.</p>
+</dd>
+
+<dt id="opt--delete-excluded"><code>--delete-excluded</code><a href="#opt--delete-excluded" class="tgt"></a></dt><dd>
+<p>This option turns any unqualified exclude/include rules into server-side
+rules that do not affect the receiver's deletions.</p>
+<p>By default, an exclude or include has both a server-side effect (to &quot;hide&quot;
+and &quot;show&quot; files when building the server's file list) and a receiver-side
+effect (to &quot;protect&quot; and &quot;risk&quot; files when deletions are occurring).  Any
+rule that has no modifier to specify what sides it is executed on will be
+instead treated as if it were a server-side rule only, avoiding any
+&quot;protect&quot; effects of the rules.</p>
+<p>A rule can still apply to both sides even with this option specified if the
+rule is given both the sender &amp; receiver modifier letters (e.g., <code>-f'-sr foo'</code>).  Receiver-side protect/risk rules can also be explicitly specified
+to limit the deletions.  This saves you from having to edit a bunch of
+<code>-f'- foo'</code> rules into <code>-f'-s foo'</code> (aka <code>-f'H foo'</code>) rules (not to mention
+the corresponding includes).</p>
+<p>See the <a href="#FILTER_RULES">FILTER RULES</a> section for more information.  See
+<a href="#opt--delete"><code>--delete</code></a> (which is implied) for more details on deletion.</p>
+</dd>
+
+<dt id="opt--ignore-missing-args"><code>--ignore-missing-args</code><a href="#opt--ignore-missing-args" class="tgt"></a></dt><dd>
 <p>When rsync is first processing the explicitly requested source files (e.g.
-command-line arguments or <code>--files-from</code> entries), it is normally an error
-if the file cannot be found.  This option suppresses that error, and does
-not try to transfer the file.  This does not affect subsequent
+command-line arguments or <a href="#opt--files-from"><code>--files-from</code></a> entries), it is normally
+an error if the file cannot be found.  This option suppresses that error,
+and does not try to transfer the file.  This does not affect subsequent
 vanished-file errors if a file was initially found to be present and later
 is no longer there.</p>
 </dd>
 
-<dt><code>--delete-missing-args</code></dt><dd>
-<p>This option takes the behavior of (the implied) <code>--ignore-missing-args</code>
-option a step farther: each missing arg will become a deletion request of
-the corresponding destination file on the receiving side (should it exist).
-If the destination file is a non-empty directory, it will only be
-successfully deleted if <code>--force</code> or <code>--delete</code> are in effect.  Other than
-that, this option is independent of any other type of delete processing.</p>
+<dt id="opt--delete-missing-args"><code>--delete-missing-args</code><a href="#opt--delete-missing-args" class="tgt"></a></dt><dd>
+<p>This option takes the behavior of the (implied)
+<a href="#opt--ignore-missing-args"><code>--ignore-missing-args</code></a> option a step farther: each missing arg
+will become a deletion request of the corresponding destination file on the
+receiving side (should it exist).  If the destination file is a non-empty
+directory, it will only be successfully deleted if <a href="#opt--force"><code>--force</code></a> or
+<a href="#opt--delete"><code>--delete</code></a> are in effect.  Other than that, this option is
+independent of any other type of delete processing.</p>
 <p>The missing source files are represented by special file-list entries which
-display as a &quot;<code>*missing</code>&quot; entry in the <code>--list-only</code> output.</p>
+display as a &quot;<code>*missing</code>&quot; entry in the <a href="#opt--list-only"><code>--list-only</code></a> output.</p>
 </dd>
 
-<dt><code>--ignore-errors</code></dt><dd>
-<p>Tells <code>--delete</code> to go ahead and delete files even when there are I/O
-errors.</p>
+<dt id="opt--ignore-errors"><code>--ignore-errors</code><a href="#opt--ignore-errors" class="tgt"></a></dt><dd>
+<p>Tells <a href="#opt--delete"><code>--delete</code></a> to go ahead and delete files even when there are
+I/O errors.</p>
 </dd>
 
-<dt><code>--force</code></dt><dd>
+<dt id="opt--force"><code>--force</code><a href="#opt--force" class="tgt"></a></dt><dd>
 <p>This option tells rsync to delete a non-empty directory when it is to be
 replaced by a non-directory.  This is only relevant if deletions are not
-active (see <code>--delete</code> for details).</p>
+active (see <a href="#opt--delete"><code>--delete</code></a> for details).</p>
 <p>Note for older rsync versions: <code>--force</code> used to still be required when
-using <code>--delete-after</code>, and it used to be non-functional unless the
-<code>--recursive</code> option was also enabled.</p>
+using <a href="#opt--delete-after"><code>--delete-after</code></a>, and it used to be non-functional unless the
+<a href="#opt--recursive"><code>--recursive</code></a> option was also enabled.</p>
 </dd>
 
-<dt><code>--max-delete=NUM</code></dt><dd>
+<dt id="opt--max-delete"><code>--max-delete=NUM</code><a href="#opt--max-delete" class="tgt"></a></dt><dd>
 <p>This tells rsync not to delete more than NUM files or directories.  If that
 limit is exceeded, all further deletions are skipped through the end of the
 transfer.  At the end, rsync outputs a warning (including a count of the
@@ -1686,14 +1937,13 @@ backward-compatible way to specify that no deletions be allowed (though
 really old versions didn't warn when the limit was exceeded).</p>
 </dd>
 
-<dt><code>--max-size=SIZE</code></dt><dd>
+<dt id="opt--max-size"><code>--max-size=SIZE</code><a href="#opt--max-size" class="tgt"></a></dt><dd>
 <p>This tells rsync to avoid transferring any file that is larger than the
 specified SIZE.  A numeric value can be suffixed with a string to indicate
 the numeric units or left unqualified to specify bytes.  Feel free to use a
 fractional value along with the units, such as <code>--max-size=1.5m</code>.</p>
-<p>This option is a transfer rule, not an exclude, so it doesn't affect the
-data that goes into the file-lists, and thus it doesn't affect deletions.
-It just limits the files that the receiver requests to be transferred.</p>
+<p>This option is a <a href="#TRANSFER_RULES">TRANSFER RULE</a>, so don't expect any
+exclude side effects.</p>
 <p>The first letter of a units string can be <code>B</code> (bytes), <code>K</code> (kilo), <code>M</code>
 (mega), <code>G</code> (giga), <code>T</code> (tera), or <code>P</code> (peta).  If the string is a single
 char or has &quot;ib&quot; added to it (e.g. &quot;G&quot; or &quot;GiB&quot;) then the units are
@@ -1708,14 +1958,14 @@ byte in the indicated direction.  The largest possible value is usually
 <p>Note that rsync versions prior to 3.1.0 did not allow <code>--max-size=0</code>.</p>
 </dd>
 
-<dt><code>--min-size=SIZE</code></dt><dd>
+<dt id="opt--min-size"><code>--min-size=SIZE</code><a href="#opt--min-size" class="tgt"></a></dt><dd>
 <p>This tells rsync to avoid transferring any file that is smaller than the
 specified SIZE, which can help in not transferring small, junk files.  See
-the <code>--max-size</code> option for a description of SIZE and other information.</p>
+the <a href="#opt--max-size"><code>--max-size</code></a> option for a description of SIZE and other info.</p>
 <p>Note that rsync versions prior to 3.1.0 did not allow <code>--min-size=0</code>.</p>
 </dd>
 
-<dt><code>--max-alloc=SIZE</code></dt><dd>
+<dt id="opt--max-alloc"><code>--max-alloc=SIZE</code><a href="#opt--max-alloc" class="tgt"></a></dt><dd>
 <p>By default rsync limits an individual malloc/realloc to about 1GB in size.
 For most people this limit works just fine and prevents a protocol error
 causing rsync to request massive amounts of memory.  However, if you have
@@ -1725,25 +1975,26 @@ increase the per-allocation limit to something larger and rsync will
 consume more memory.</p>
 <p>Keep in mind that this is not a limit on the total size of allocated
 memory.  It is a sanity-check value for each individual allocation.</p>
-<p>See the <code>--max-size</code> option for a description of how SIZE can be specified.
-The default suffix if none is given is bytes.</p>
+<p>See the <a href="#opt--max-size"><code>--max-size</code></a> option for a description of how SIZE can be
+specified.  The default suffix if none is given is bytes.</p>
 <p>Beginning in 3.2.3, a value of 0 specifies no limit.</p>
-<p>You can set a default value using the environment variable RSYNC_MAX_ALLOC
-using the same SIZE values as supported by this option.  If the remote
-rsync doesn't understand the <code>--max-alloc</code> option, you can override an
-environmental value by specifying <code>--max-alloc=1g</code>, which will make rsync
-avoid sending the option to the remote side (because &quot;1G&quot; is the default).</p>
+<p>You can set a default value using the environment variable
+<a href="#RSYNC_MAX_ALLOC"><code>RSYNC_MAX_ALLOC</code></a> using the same SIZE values as supported by this
+option.  If the remote rsync doesn't understand the <code>--max-alloc</code> option,
+you can override an environmental value by specifying <code>--max-alloc=1g</code>,
+which will make rsync avoid sending the option to the remote side (because
+&quot;1G&quot; is the default).</p>
 </dd>
 
-<dt><code>--block-size=SIZE</code>, <code>-B</code></dt><dd>
+<span id="opt-B"></span><dt id="opt--block-size"><code>--block-size=SIZE</code>, <code>-B</code><a href="#opt--block-size" class="tgt"></a></dt><dd>
 <p>This forces the block size used in rsync's delta-transfer algorithm to a
 fixed value.  It is normally selected based on the size of each file being
 updated.  See the technical report for details.</p>
 <p>Beginning in 3.2.3 the SIZE can be specified with a suffix as detailed in
-the <code>--max-size</code> option.  Older versions only accepted a byte count.</p>
+the <a href="#opt--max-size"><code>--max-size</code></a> option.  Older versions only accepted a byte count.</p>
 </dd>
 
-<dt><code>--rsh=COMMAND</code>, <code>-e</code></dt><dd>
+<span id="opt-e"></span><dt id="opt--rsh"><code>--rsh=COMMAND</code>, <code>-e</code><a href="#opt--rsh" class="tgt"></a></dt><dd>
 <p>This option allows you to choose an alternative remote shell program to use
 for communication between the local and remote copies of rsync.  Typically,
 rsync is configured to use ssh by default, but you may prefer to use rsh on
@@ -1752,16 +2003,16 @@ a local network.</p>
 shell <u>COMMAND</u> will be used to run an rsync daemon on the remote host, and
 all data will be transmitted through that remote shell connection, rather
 than through a direct socket connection to a running rsync daemon on the
-remote host.  See the section &quot;USING RSYNC-DAEMON FEATURES VIA A
-REMOTE-SHELL CONNECTION&quot; above.</p>
-<p>Beginning with rsync 3.2.0, the RSYNC_PORT environment variable will be set
-when a daemon connection is being made via a remote-shell connection.  It
-is set to 0 if the default daemon port is being assumed, or it is set to
-the value of the rsync port that was specified via either the <code>--port</code>
-option or a non-empty port value in an rsync:// URL.  This allows the
-script to discern if a non-default port is being requested, allowing for
-things such as an SSL or stunnel helper script to connect to a default or
-alternate port.</p>
+remote host.  See the <a href="#USING_RSYNC-DAEMON_FEATURES_VIA_A_REMOTE-SHELL_CONNECTION">USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL
+CONNECTION</a> section above.</p>
+<p>Beginning with rsync 3.2.0, the <a href="#RSYNC_PORT"><code>RSYNC_PORT</code></a> environment variable will
+be set when a daemon connection is being made via a remote-shell
+connection.  It is set to 0 if the default daemon port is being assumed, or
+it is set to the value of the rsync port that was specified via either the
+<a href="#opt--port"><code>--port</code></a> option or a non-empty port value in an <code>rsync://</code> URL.
+This allows the script to discern if a non-default port is being requested,
+allowing for things such as an SSL or stunnel helper script to connect to a
+default or alternate port.</p>
 <p>Command-line arguments are permitted in COMMAND provided that COMMAND is
 presented to rsync as a single argument.  You must use spaces (not tabs or
 other whitespace) to separate the command and args from each other, and you
@@ -1777,12 +2028,13 @@ quotes rsync is parsing).  Some examples:</p>
 </blockquote>
 <p>(Note that ssh users can alternately customize site-specific connect
 options in their .ssh/config file.)</p>
-<p>You can also choose the remote shell program using the RSYNC_RSH
+<p>You can also choose the remote shell program using the <a href="#RSYNC_RSH"><code>RSYNC_RSH</code></a>
 environment variable, which accepts the same range of values as <code>-e</code>.</p>
-<p>See also the <code>--blocking-io</code> option which is affected by this option.</p>
+<p>See also the <a href="#opt--blocking-io"><code>--blocking-io</code></a> option which is affected by this
+option.</p>
 </dd>
 
-<dt><code>--rsync-path=PROGRAM</code></dt><dd>
+<dt id="opt--rsync-path"><code>--rsync-path=PROGRAM</code><a href="#opt--rsync-path" class="tgt"></a></dt><dd>
 <p>Use this to specify what program is to be run on the remote machine to
 start-up rsync.  Often used when rsync is not in the default remote-shell's
 path (e.g. <code>--rsync-path=/usr/local/bin/rsync</code>).  Note that PROGRAM is run
@@ -1790,18 +2042,18 @@ with the help of a shell, so it can be any program, script, or command
 sequence you'd care to run, so long as it does not corrupt the standard-in
 &amp; standard-out that rsync is using to communicate.</p>
 <p>One tricky example is to set a different default directory on the remote
-machine for use with the <code>--relative</code> option.  For instance:</p>
+machine for use with the <a href="#opt--relative"><code>--relative</code></a> option.  For instance:</p>
 <blockquote>
 <pre><code>rsync -avR --rsync-path=&quot;cd /a/b &amp;&amp; rsync&quot; host:c/d /e/
 </code></pre>
 </blockquote>
 </dd>
 
-<dt><code>--remote-option=OPTION</code>, <code>-M</code></dt><dd>
+<span id="opt-M"></span><dt id="opt--remote-option"><code>--remote-option=OPTION</code>, <code>-M</code><a href="#opt--remote-option" class="tgt"></a></dt><dd>
 <p>This option is used for more advanced situations where you want certain
 effects to be limited to one side of the transfer only.  For instance, if
-you want to pass <code>--log-file=FILE</code> and <code>--fake-super</code> to the remote system,
-specify it like this:</p>
+you want to pass <a href="#opt--log-file"><code>--log-file=FILE</code></a> and <a href="#opt--fake-super"><code>--fake-super</code></a> to
+the remote system, specify it like this:</p>
 <blockquote>
 <pre><code>rsync -av -M --log-file=foo -M--fake-super src/ dest/
 </code></pre>
@@ -1816,11 +2068,10 @@ this:</p>
 <p>Be cautious using this, as it is possible to toggle an option that will
 cause rsync to have a different idea about what data to expect next over
 the socket, and that will make it fail in a cryptic fashion.</p>
-<p>Note that it is best to use a separate <code>--remote-option</code> for each option
-you want to pass.  This makes your usage compatible with the
-<code>--protect-args</code> option.  If that option is off, any spaces in your remote
-options will be split by the remote shell unless you take steps to protect
-them.</p>
+<p>Note that you should use a separate <code>-M</code> option for each remote option you
+want to pass.  On older rsync versions, the presence of any spaces in the
+remote-option arg could cause it to be split into separate remote args, but
+this requires the use of <a href="#opt--old-args"><code>--old-args</code></a> in a modern rsync.</p>
 <p>When performing a local transfer, the &quot;local&quot; side is the sender and the
 &quot;remote&quot; side is the receiver.</p>
 <p>Note some versions of the popt option-parsing library have a bug in them
@@ -1830,12 +2081,13 @@ your version of popt, you can use the version of popt that is included with
 rsync.</p>
 </dd>
 
-<dt><code>--cvs-exclude</code>, <code>-C</code></dt><dd>
+<span id="opt-C"></span><dt id="opt--cvs-exclude"><code>--cvs-exclude</code>, <code>-C</code><a href="#opt--cvs-exclude" class="tgt"></a></dt><dd>
 <p>This is a useful shorthand for excluding a broad range of files that you
 often don't want to transfer between systems.  It uses a similar algorithm
 to CVS to determine if a file should be ignored.</p>
 <p>The exclude list is initialized to exclude the following items (these
-initial items are marked as perishable&nbsp;-&#8288;-&#8288; see the FILTER RULES section):</p>
+initial items are marked as perishable&nbsp;-&#8288;-&#8288; see the <a href="#FILTER_RULES">FILTER RULES</a>
+section):</p>
 <blockquote>
 <p><code>RCS</code>
 <code>SCCS</code>
@@ -1881,20 +2133,20 @@ delimited by whitespace).</p>
 file and matches one of the patterns listed therein.  Unlike rsync's
 filter/exclude files, these patterns are split on whitespace.  See the
 <strong>cvs</strong>(1) manual for more information.</p>
-<p>If you're combining <code>-C</code> with your own <code>--filter</code> rules, you should note
-that these CVS excludes are appended at the end of your own rules,
+<p>If you're combining <code>-C</code> with your own <a href="#opt--filter"><code>--filter</code></a> rules, you should
+note that these CVS excludes are appended at the end of your own rules,
 regardless of where the <code>-C</code> was placed on the command-line.  This makes
 them a lower priority than any rules you specified explicitly.  If you want
 to control where these CVS excludes get inserted into your filter rules,
 you should omit the <code>-C</code> as a command-line option and use a combination of
-<code>--filter=:C</code> and <code>--filter=-C</code> (either on your command-line or by putting
-the &quot;:C&quot; and &quot;-&#8288;C&quot; rules into a filter file with your other rules).  The
-first option turns on the per-directory scanning for the .cvsignore file.
-The second option does a one-time import of the CVS excludes mentioned
-above.</p>
+<a href="#opt--filter"><code>--filter=:C</code></a> and <a href="#opt--filter"><code>--filter=-C</code></a> (either on your
+command-line or by putting the &quot;:C&quot; and &quot;-&#8288;C&quot; rules into a filter file with
+your other rules).  The first option turns on the per-directory scanning
+for the .cvsignore file.  The second option does a one-time import of the
+CVS excludes mentioned above.</p>
 </dd>
 
-<dt><code>--filter=RULE</code>, <code>-f</code></dt><dd>
+<span id="opt-f"></span><dt id="opt--filter"><code>--filter=RULE</code>, <code>-f</code><a href="#opt--filter" class="tgt"></a></dt><dd>
 <p>This option allows you to add rules to selectively exclude certain files
 from the list of files to be transferred.  This is most useful in
 combination with a recursive transfer.</p>
@@ -1903,12 +2155,12 @@ build up the list of files to exclude.  If the filter contains whitespace,
 be sure to quote it so that the shell gives the rule to rsync as a single
 argument.  The text below also mentions that you can use an underscore to
 replace the space that separates a rule from its arg.</p>
-<p>See the FILTER RULES section for detailed information on this option.</p>
+<p>See the <a href="#FILTER_RULES">FILTER RULES</a> section for detailed information on this option.</p>
 </dd>
 
-<dt><code>-F</code></dt><dd>
-<p>The <code>-F</code> option is a shorthand for adding two <code>--filter</code> rules to your
-command.  The first time it is used is a shorthand for this rule:</p>
+<dt id="opt-F"><code>-F</code><a href="#opt-F" class="tgt"></a></dt><dd>
+<p>The <code>-F</code> option is a shorthand for adding two <a href="#opt--filter"><code>--filter</code></a> rules to
+your command.  The first time it is used is a shorthand for this rule:</p>
 <blockquote>
 <pre><code>--filter='dir-merge /.rsync-filter'
 </code></pre>
@@ -1922,55 +2174,67 @@ rule:</p>
 </code></pre>
 </blockquote>
 <p>This filters out the .rsync-filter files themselves from the transfer.</p>
-<p>See the FILTER RULES section for detailed information on how these options
-work.</p>
-</dd>
-
-<dt><code>--exclude=PATTERN</code></dt><dd>
-<p>This option is a simplified form of the <code>--filter</code> option that defaults to
-an exclude rule and does not allow the full rule-parsing syntax of normal
-filter rules.</p>
-<p>See the FILTER RULES section for detailed information on this option.</p>
-</dd>
-
-<dt><code>--exclude-from=FILE</code></dt><dd>
-<p>This option is related to the <code>--exclude</code> option, but it specifies a FILE
-that contains exclude patterns (one per line).  Blank lines in the file and
-lines starting with '<code>;</code>' or '<code>#</code>' are ignored.  If <u>FILE</u> is '<code>-</code>', the
-list will be read from standard input.</p>
-</dd>
-
-<dt><code>--include=PATTERN</code></dt><dd>
-<p>This option is a simplified form of the <code>--filter</code> option that defaults to
-an include rule and does not allow the full rule-parsing syntax of normal
-filter rules.</p>
-<p>See the FILTER RULES section for detailed information on this option.</p>
-</dd>
-
-<dt><code>--include-from=FILE</code></dt><dd>
-<p>This option is related to the <code>--include</code> option, but it specifies a FILE
-that contains include patterns (one per line).  Blank lines in the file and
-lines starting with '<code>;</code>' or '<code>#</code>' are ignored.  If <u>FILE</u> is '<code>-</code>', the
-list will be read from standard input.</p>
-</dd>
-
-<dt><code>--files-from=FILE</code></dt><dd>
+<p>See the <a href="#FILTER_RULES">FILTER RULES</a> section for detailed information on how these
+options work.</p>
+</dd>
+
+<dt id="opt--exclude"><code>--exclude=PATTERN</code><a href="#opt--exclude" class="tgt"></a></dt><dd>
+<p>This option is a simplified form of the <a href="#opt--filter"><code>--filter</code></a> option that
+specifies an exclude rule and does not allow the full rule-parsing syntax
+of normal filter rules.  This is equivalent to specifying <code>-f'- PATTERN'</code>.</p>
+<p>See the <a href="#FILTER_RULES">FILTER RULES</a> section for detailed information on this option.</p>
+</dd>
+
+<dt id="opt--exclude-from"><code>--exclude-from=FILE</code><a href="#opt--exclude-from" class="tgt"></a></dt><dd>
+<p>This option is related to the <a href="#opt--exclude"><code>--exclude</code></a> option, but it specifies
+a FILE that contains exclude patterns (one per line).  Blank lines in the
+file are ignored, as are whole-line comments that start with '<code>;</code>' or '<code>#</code>'
+(filename rules that contain those characters are unaffected).</p>
+<p>If a line begins with &quot;<code>- </code>&quot; (dash, space) or &quot;<code>+ </code>&quot; (plus, space), then
+the type of rule is being explicitly specified as an exclude or an include
+(respectively).  Any rules without such a prefix are taken to be an exclude.</p>
+<p>If a line consists of just &quot;<code>!</code>&quot;, then the current filter rules are cleared
+before adding any further rules.</p>
+<p>If <u>FILE</u> is '<code>-</code>', the list will be read from standard input.</p>
+</dd>
+
+<dt id="opt--include"><code>--include=PATTERN</code><a href="#opt--include" class="tgt"></a></dt><dd>
+<p>This option is a simplified form of the <a href="#opt--filter"><code>--filter</code></a> option that
+specifies an include rule and does not allow the full rule-parsing syntax
+of normal filter rules.  This is equivalent to specifying <code>-f'+ PATTERN'</code>.</p>
+<p>See the <a href="#FILTER_RULES">FILTER RULES</a> section for detailed information on this option.</p>
+</dd>
+
+<dt id="opt--include-from"><code>--include-from=FILE</code><a href="#opt--include-from" class="tgt"></a></dt><dd>
+<p>This option is related to the <a href="#opt--include"><code>--include</code></a> option, but it specifies
+a FILE that contains include patterns (one per line).  Blank lines in the
+file are ignored, as are whole-line comments that start with '<code>;</code>' or '<code>#</code>'
+(filename rules that contain those characters are unaffected).</p>
+<p>If a line begins with &quot;<code>- </code>&quot; (dash, space) or &quot;<code>+ </code>&quot; (plus, space), then
+the type of rule is being explicitly specified as an exclude or an include
+(respectively).  Any rules without such a prefix are taken to be an include.</p>
+<p>If a line consists of just &quot;<code>!</code>&quot;, then the current filter rules are cleared
+before adding any further rules.</p>
+<p>If <u>FILE</u> is '<code>-</code>', the list will be read from standard input.</p>
+</dd>
+
+<dt id="opt--files-from"><code>--files-from=FILE</code><a href="#opt--files-from" class="tgt"></a></dt><dd>
 <p>Using this option allows you to specify the exact list of files to transfer
 (as read from the specified FILE or '<code>-</code>' for standard input).  It also
 tweaks the default behavior of rsync to make transferring just the
 specified files and directories easier:</p>
 <ul>
-<li>The <code>--relative</code> (<code>-R</code>) option is implied, which preserves the path
-information that is specified for each item in the file (use
+<li>The <a href="#opt--relative"><code>--relative</code></a> (<code>-R</code>) option is implied, which preserves the
+path information that is specified for each item in the file (use
 <code>--no-relative</code> or <code>--no-R</code> if you want to turn that off).</li>
-<li>The <code>--dirs</code> (<code>-d</code>) option is implied, which will create directories
-specified in the list on the destination rather than noisily skipping
-them (use <code>--no-dirs</code> or <code>--no-d</code> if you want to turn that off).</li>
-<li>The <code>--archive</code> (<code>-a</code>) option's behavior does not imply <code>--recursive</code>
-(<code>-r</code>), so specify it explicitly, if you want it.</li>
+<li>The <a href="#opt--dirs"><code>--dirs</code></a> (<code>-d</code>) option is implied, which will create
+directories specified in the list on the destination rather than noisily
+skipping them (use <code>--no-dirs</code> or <code>--no-d</code> if you want to turn that off).</li>
+<li>The <a href="#opt--archive"><code>--archive</code></a> (<code>-a</code>) option's behavior does not imply
+<a href="#opt--recursive"><code>--recursive</code></a> (<code>-r</code>), so specify it explicitly, if you want it.</li>
 <li>These side-effects change the default state of rsync, so the position of
 the <code>--files-from</code> option on the command-line has no bearing on how other
-options are parsed (e.g. <code>-a</code> works the same before or after
+options are parsed (e.g. <a href="#opt-a"><code>-a</code></a> works the same before or after
 <code>--files-from</code>, as does <code>--no-R</code> and all other options).</li>
 </ul>
 <p>The filenames that are read from the FILE are all relative to the source
@@ -1984,13 +2248,13 @@ to go higher than the source dir.  For example, take this command:</p>
 directory will be created as /backup/bin on the remote host.  If it
 contains &quot;bin/&quot; (note the trailing slash), the immediate contents of the
 directory would also be sent (without needing to be explicitly mentioned in
-the file&nbsp;-&#8288;-&#8288; this began in version 2.6.4).  In both cases, if the <code>-r</code>
-option was enabled, that dir's entire hierarchy would also be transferred
-(keep in mind that <code>-r</code> needs to be specified explicitly with
-<code>--files-from</code>, since it is not implied by <code>-a</code>).  Also note that the
-effect of the (enabled by default) <code>--relative</code> option is to duplicate only
-the path info that is read from the file&nbsp;-&#8288;-&#8288; it does not force the
-duplication of the source-spec path (/usr in this case).</p>
+the file&nbsp;-&#8288;-&#8288; this began in version 2.6.4).  In both cases, if the
+<a href="#opt-r"><code>-r</code></a> option was enabled, that dir's entire hierarchy would also be
+transferred (keep in mind that <a href="#opt-r"><code>-r</code></a> needs to be specified
+explicitly with <code>--files-from</code>, since it is not implied by <a href="#opt-a"><code>-a</code></a>.
+Also note that the effect of the (enabled by default) <a href="#opt-r"><code>-r</code></a> option
+is to duplicate only the path info that is read from the file&nbsp;-&#8288;-&#8288; it does
+not force the duplication of the source-spec path (/usr in this case).</p>
 <p>In addition, the <code>--files-from</code> file can be read from the remote host
 instead of the local host if you specify a &quot;host:&quot; in front of the file
 (the host must match one end of the transfer).  As a short-cut, you can
@@ -2002,9 +2266,9 @@ For example:</p>
 </blockquote>
 <p>This would copy all the files specified in the /path/file-list file that
 was located on the remote &quot;src&quot; host.</p>
-<p>If the <code>--iconv</code> and <code>--protect-args</code> options are specified and the
-<code>--files-from</code> filenames are being sent from one host to another, the
-filenames will be translated from the sending host's charset to the
+<p>If the <a href="#opt--iconv"><code>--iconv</code></a> and <a href="#opt--secluded-args"><code>--secluded-args</code></a> options are specified
+and the <code>--files-from</code> filenames are being sent from one host to another,
+the filenames will be translated from the sending host's charset to the
 receiving host's charset.</p>
 <p>NOTE: sorting the list of files in the <code>--files-from</code> input helps rsync to
 be more efficient, as it will avoid re-visiting the path elements that are
@@ -2014,42 +2278,110 @@ rsync will eventually unduplicate them after they get turned into file-list
 elements.</p>
 </dd>
 
-<dt><code>--from0</code>, <code>-0</code></dt><dd>
+<span id="opt-0"></span><dt id="opt--from0"><code>--from0</code>, <code>-0</code><a href="#opt--from0" class="tgt"></a></dt><dd>
 <p>This tells rsync that the rules/filenames it reads from a file are
 terminated by a null ('\0') character, not a NL, CR, or CR+LF.  This
-affects <code>--exclude-from</code>, <code>--include-from</code>, <code>--files-from</code>, and any merged
-files specified in a <code>--filter</code> rule.  It does not affect <code>--cvs-exclude</code>
-(since all names read from a .cvsignore file are split on whitespace).</p>
-</dd>
-
-<dt><code>--protect-args</code>, <code>-s</code></dt><dd>
-<p>This option sends all filenames and most options to the remote rsync
-without allowing the remote shell to interpret them.  This means that
-spaces are not split in names, and any non-wildcard special characters are
-not translated (such as <code>~</code>, <code>$</code>, <code>;</code>, <code>&amp;</code>, etc.).  Wildcards are expanded
-on the remote host by rsync (instead of the shell doing it).</p>
-<p>If you use this option with <code>--iconv</code>, the args related to the remote side
-will also be translated from the local to the remote character-set.  The
-translation happens before wild-cards are expanded.  See also the
-<code>--files-from</code> option.</p>
-<p>You may also control this option via the RSYNC_PROTECT_ARGS environment
-variable.  If this variable has a non-zero value, this option will be
+affects <a href="#opt--exclude-from"><code>--exclude-from</code></a>, <a href="#opt--include-from"><code>--include-from</code></a>,
+<a href="#opt--files-from"><code>--files-from</code></a>, and any merged files specified in a
+<a href="#opt--filter"><code>--filter</code></a> rule.  It does not affect <a href="#opt--cvs-exclude"><code>--cvs-exclude</code></a> (since
+all names read from a .cvsignore file are split on whitespace).</p>
+</dd>
+
+<dt id="opt--old-args"><code>--old-args</code><a href="#opt--old-args" class="tgt"></a></dt><dd>
+<p>This option tells rsync to stop trying to protect the arg values on the
+remote side from unintended word-splitting or other misinterpretation.
+It also allows the client to treat an empty arg as a &quot;.&quot; instead of
+generating an error.</p>
+<p>The default in a modern rsync is for &quot;shell-active&quot; characters (including
+spaces) to be backslash-escaped in the args that are sent to the remote
+shell.  The wildcard characters <code>*</code>, <code>?</code>, <code>[</code>, &amp; <code>]</code> are not escaped in
+filename args (allowing them to expand into multiple filenames) while being
+protected in option args, such as <a href="#opt--usermap"><code>--usermap</code></a>.</p>
+<p>If you have a script that wants to use old-style arg splitting in its
+filenames, specify this option once.  If the remote shell has a problem
+with any backslash escapes at all, specify this option twice.</p>
+<p>You may also control this setting via the <a href="#RSYNC_OLD_ARGS"><code>RSYNC_OLD_ARGS</code></a> environment
+variable.  If it has the value &quot;1&quot;, rsync will default to a single-option
+setting.  If it has the value &quot;2&quot; (or more), rsync will default to a
+repeated-option setting.  If it is &quot;0&quot;, you'll get the default escaping
+behavior.  The environment is always overridden by manually specified
+positive or negative options (the negative is <code>--no-old-args</code>).</p>
+<p>Note that this option also disables the extra safety check added in 3.2.5
+that ensures that a remote sender isn't including extra top-level items in
+the file-list that you didn't request.  This side-effect is necessary
+because we can't know for sure what names to expect when the remote shell
+is interpreting the args.</p>
+<p>This option conflicts with the <a href="#opt--secluded-args"><code>--secluded-args</code></a> option.</p>
+</dd>
+
+<span id="opt-s"></span><dt id="opt--secluded-args"><code>--secluded-args</code>, <code>-s</code><a href="#opt--secluded-args" class="tgt"></a></dt><dd>
+<p>This option sends all filenames and most options to the remote rsync via
+the protocol (not the remote shell command line) which avoids letting the
+remote shell modify them.  Wildcards are expanded on the remote host by
+rsync instead of a shell.</p>
+<p>This is similar to the default backslash-escaping of args that was added
+in 3.2.4 (see <a href="#opt--old-args"><code>--old-args</code></a>) in that it prevents things like space
+splitting and unwanted special-character side-effects. However, it has the
+drawbacks of being incompatible with older rsync versions (prior to 3.0.0)
+and of being refused by restricted shells that want to be able to inspect
+all the option values for safety.</p>
+<p>This option is useful for those times that you need the argument's
+character set to be converted for the remote host, if the remote shell is
+incompatible with the default backslash-escpaing method, or there is some
+other reason that you want the majority of the options and arguments to
+bypass the command-line of the remote shell.</p>
+<p>If you combine this option with <a href="#opt--iconv"><code>--iconv</code></a>, the args related to the
+remote side will be translated from the local to the remote character-set.
+The translation happens before wild-cards are expanded.  See also the
+<a href="#opt--files-from"><code>--files-from</code></a> option.</p>
+<p>You may also control this setting via the <a href="#RSYNC_PROTECT_ARGS"><code>RSYNC_PROTECT_ARGS</code></a>
+environment variable.  If it has a non-zero value, this setting will be
 enabled by default, otherwise it will be disabled by default.  Either state
 is overridden by a manually specified positive or negative version of this
-option (note that <code>--no-s</code> and <code>--no-protect-args</code> are the negative
-versions).  Since this option was first introduced in 3.0.0, you'll need to
-make sure it's disabled if you ever need to interact with a remote rsync
-that is older than that.</p>
-<p>Rsync can also be configured (at build time) to have this option enabled by
-default (with is overridden by both the environment and the command-line).
-Run <code>rsync --version</code> to check if this is the case, as it will display
-&quot;default protect-args&quot; or &quot;optional protect-args&quot; depending on how it was
-compiled.</p>
-<p>This option will eventually become a new default setting at some
-as-yet-undetermined point in the future.</p>
-</dd>
-
-<dt><code>--copy-as=USER[:GROUP]</code></dt><dd>
+option (note that <code>--no-s</code> and <code>--no-secluded-args</code> are the negative
+versions).  This environment variable is also superseded by a non-zero
+<a href="#RSYNC_OLD_ARGS"><code>RSYNC_OLD_ARGS</code></a> export.</p>
+<p>This option conflicts with the <a href="#opt--old-args"><code>--old-args</code></a> option.</p>
+<p>This option used to be called <code>--protect-args</code> (before 3.2.6) and that
+older name can still be used (though specifying it as <code>-s</code> is always the
+easiest and most compatible choice).</p>
+</dd>
+
+<dt id="opt--trust-sender"><code>--trust-sender</code><a href="#opt--trust-sender" class="tgt"></a></dt><dd>
+<p>This option disables two extra validation checks that a local client
+performs on the file list generated by a remote sender.  This option should
+only be used if you trust the sender to not put something malicious in the
+file list (something that could possibly be done via a modified rsync, a
+modified shell, or some other similar manipulation).</p>
+<p>Normally, the rsync client (as of version 3.2.5) runs two extra validation
+checks when pulling files from a remote rsync:</p>
+<ul>
+<li>It verifies that additional arg items didn't get added at the top of the
+transfer.</li>
+<li>It verifies that none of the items in the file list are names that should
+have been excluded (if filter rules were specified).</li>
+</ul>
+<p>Note that various options can turn off one or both of these checks if the
+option interferes with the validation.  For instance:</p>
+<ul>
+<li>Using a per-directory filter file reads filter rules that only the server
+knows about, so the filter checking is disabled.</li>
+<li>Using the <a href="#opt--old-args"><code>--old-args</code></a> option allows the sender to manipulate the
+requested args, so the arg checking is disabled.</li>
+<li>Reading the files-from list from the server side means that the client
+doesn't know the arg list, so the arg checking is disabled.</li>
+<li>Using <a href="#opt--read-batch"><code>--read-batch</code></a> disables both checks since the batch file's
+contents will have been verified when it was created.</li>
+</ul>
+<p>This option may help an under-powered client server if the extra pattern
+matching is slowing things down on a huge transfer.  It can also be used to
+work around a currently-unknown bug in the verification logic for a transfer
+from a trusted sender.</p>
+<p>When using this option it is a good idea to specify a dedicated destination
+directory, as discussed in the <a href="#MULTI-HOST_SECURITY">MULTI-HOST SECURITY</a> section.</p>
+</dd>
+
+<dt id="opt--copy-as"><code>--copy-as=USER[:GROUP]</code><a href="#opt--copy-as" class="tgt"></a></dt><dd>
 <p>This option instructs rsync to use the USER and (if specified after a
 colon) the GROUP for the copy operations.  This only works if the user that
 is running rsync has the ability to change users.  If the group is not
@@ -2062,14 +2394,14 @@ specified user, sometimes you need the root-level host-access credentials
 to be used, so this allows rsync to drop root for the copying part of the
 operation after the remote-shell or daemon connection is established.</p>
 <p>The option only affects one side of the transfer unless the transfer is
-local, in which case it affects both sides.  Use the <code>--remote-option</code> to
-affect the remote side, such as <code>-M--copy-as=joe</code>.  For a local transfer,
-the lsh (or lsh.sh) support file provides a local-shell helper script that
-can be used to allow a &quot;localhost:&quot; or &quot;lh:&quot; host-spec to be specified
-without needing to setup any remote shells, allowing you to specify remote
-options that affect the side of the transfer that is using the host-spec
-(and using hostname &quot;lh&quot; avoids the overriding of the remote directory to
-the user's home dir).</p>
+local, in which case it affects both sides.  Use the
+<a href="#opt--remote-option"><code>--remote-option</code></a> to affect the remote side, such as
+<code>-M--copy-as=joe</code>.  For a local transfer, the lsh (or lsh.sh) support file
+provides a local-shell helper script that can be used to allow a
+&quot;localhost:&quot; or &quot;lh:&quot; host-spec to be specified without needing to setup
+any remote shells, allowing you to specify remote options that affect the
+side of the transfer that is using the host-spec (and using hostname &quot;lh&quot;
+avoids the overriding of the remote directory to the user's home dir).</p>
 <p>For example, the following rsync writes the local files as user &quot;joe&quot;:</p>
 <blockquote>
 <pre><code>sudo rsync -aiv --copy-as=joe host1:backups/joe/ /home/joe/
@@ -2087,7 +2419,7 @@ has no permissions to change.</p>
 </blockquote>
 </dd>
 
-<dt><code>--temp-dir=DIR</code>, <code>-T</code></dt><dd>
+<span id="opt-T"></span><dt id="opt--temp-dir"><code>--temp-dir=DIR</code>, <code>-T</code><a href="#opt--temp-dir" class="tgt"></a></dt><dd>
 <p>This option instructs rsync to use DIR as a scratch directory when creating
 temporary copies of the files transferred on the receiving side.  The
 default behavior is to create each temporary file in the same directory as
@@ -2108,34 +2440,34 @@ it would be possible for the old file to continue taking up disk space (if
 someone had it open), and thus there might not be enough room to fit the
 new version on the disk at the same time.</p>
 <p>If you are using this option for reasons other than a shortage of disk
-space, you may wish to combine it with the <code>--delay-updates</code> option, which
-will ensure that all copied files get put into subdirectories in the
-destination hierarchy, awaiting the end of the transfer.  If you don't have
-enough room to duplicate all the arriving files on the destination
-partition, another way to tell rsync that you aren't overly concerned about
-disk space is to use the <code>--partial-dir</code> option with a relative path;
-because this tells rsync that it is OK to stash off a copy of a single file
-in a subdir in the destination hierarchy, rsync will use the partial-dir as
-a staging area to bring over the copied file, and then rename it into place
-from there. (Specifying a <code>--partial-dir</code> with an absolute path does not
-have this side-effect.)</p>
-</dd>
-
-<dt><code>--fuzzy</code>, <code>-y</code></dt><dd>
+space, you may wish to combine it with the <a href="#opt--delay-updates"><code>--delay-updates</code></a>
+option, which will ensure that all copied files get put into subdirectories
+in the destination hierarchy, awaiting the end of the transfer.  If you
+don't have enough room to duplicate all the arriving files on the
+destination partition, another way to tell rsync that you aren't overly
+concerned about disk space is to use the <a href="#opt--partial-dir"><code>--partial-dir</code></a> option
+with a relative path; because this tells rsync that it is OK to stash off a
+copy of a single file in a subdir in the destination hierarchy, rsync will
+use the partial-dir as a staging area to bring over the copied file, and
+then rename it into place from there. (Specifying a <a href="#opt--partial-dir"><code>--partial-dir</code></a>
+with an absolute path does not have this side-effect.)</p>
+</dd>
+
+<span id="opt-y"></span><dt id="opt--fuzzy"><code>--fuzzy</code>, <code>-y</code><a href="#opt--fuzzy" class="tgt"></a></dt><dd>
 <p>This option tells rsync that it should look for a basis file for any
 destination file that is missing.  The current algorithm looks in the same
 directory as the destination file for either a file that has an identical
 size and modified-time, or a similarly-named file.  If found, rsync uses
 the fuzzy basis file to try to speed up the transfer.</p>
 <p>If the option is repeated, the fuzzy scan will also be done in any matching
-alternate destination directories that are specified via <code>--compare-dest</code>,
-<code>--copy-dest</code>, or <code>--link-dest</code>.</p>
-<p>Note that the use of the <code>--delete</code> option might get rid of any potential
-fuzzy-match files, so either use <code>--delete-after</code> or specify some filename
-exclusions if you need to prevent this.</p>
+alternate destination directories that are specified via
+<a href="#opt--compare-dest"><code>--compare-dest</code></a>, <a href="#opt--copy-dest"><code>--copy-dest</code></a>, or <a href="#opt--link-dest"><code>--link-dest</code></a>.</p>
+<p>Note that the use of the <a href="#opt--delete"><code>--delete</code></a> option might get rid of any
+potential fuzzy-match files, so either use <a href="#opt--delete-after"><code>--delete-after</code></a> or
+specify some filename exclusions if you need to prevent this.</p>
 </dd>
 
-<dt><code>--compare-dest=DIR</code></dt><dd>
+<dt id="opt--compare-dest"><code>--compare-dest=DIR</code><a href="#opt--compare-dest" class="tgt"></a></dt><dd>
 <p>This option instructs rsync to use <u>DIR</u> on the destination machine as an
 additional hierarchy to compare destination files against doing transfers
 (if the files are missing in the destination directory).  If a file is
@@ -2151,15 +2483,15 @@ local copy is made and the attributes updated.  If a match is not found, a
 basis file from one of the <u>DIRs</u> will be selected to try to speed up the
 transfer.</p>
 <p>If <u>DIR</u> is a relative path, it is relative to the destination directory.
-See also <code>--copy-dest</code> and <code>--link-dest</code>.</p>
+See also <a href="#opt--copy-dest"><code>--copy-dest</code></a> and <a href="#opt--link-dest"><code>--link-dest</code></a>.</p>
 <p>NOTE: beginning with version 3.1.0, rsync will remove a file from a
 non-empty destination hierarchy if an exact match is found in one of the
 compare-dest hierarchies (making the end result more closely match a fresh
 copy).</p>
 </dd>
 
-<dt><code>--copy-dest=DIR</code></dt><dd>
-<p>This option behaves like <code>--compare-dest</code>, but rsync will also copy
+<dt id="opt--copy-dest"><code>--copy-dest=DIR</code><a href="#opt--copy-dest" class="tgt"></a></dt><dd>
+<p>This option behaves like <a href="#opt--compare-dest"><code>--compare-dest</code></a>, but rsync will also copy
 unchanged files found in <u>DIR</u> to the destination directory using a local
 copy.  This is useful for doing transfers to a new destination while
 leaving existing files intact, and then doing a flash-cutover when all
@@ -2169,19 +2501,19 @@ to search the list in the order specified for an unchanged file.  If a
 match is not found, a basis file from one of the <u>DIRs</u> will be selected to
 try to speed up the transfer.</p>
 <p>If <u>DIR</u> is a relative path, it is relative to the destination directory.
-See also <code>--compare-dest</code> and <code>--link-dest</code>.</p>
+See also <a href="#opt--compare-dest"><code>--compare-dest</code></a> and <a href="#opt--link-dest"><code>--link-dest</code></a>.</p>
 </dd>
 
-<dt><code>--link-dest=DIR</code></dt><dd>
-<p>This option behaves like <code>--copy-dest</code>, but unchanged files are hard linked
-from <u>DIR</u> to the destination directory.  The files must be identical in
-all preserved attributes (e.g. permissions, possibly ownership) in order
-for the files to be linked together.  An example:</p>
+<dt id="opt--link-dest"><code>--link-dest=DIR</code><a href="#opt--link-dest" class="tgt"></a></dt><dd>
+<p>This option behaves like <a href="#opt--copy-dest"><code>--copy-dest</code></a>, but unchanged files are
+hard linked from <u>DIR</u> to the destination directory.  The files must be
+identical in all preserved attributes (e.g. permissions, possibly
+ownership) in order for the files to be linked together.  An example:</p>
 <blockquote>
 <pre><code>rsync -av --link-dest=$PWD/prior_dir host:src_dir/ new_dir/
 </code></pre>
 </blockquote>
-<p>If file's aren't linking, double-check their attributes.  Also check if
+<p>If files aren't linking, double-check their attributes.  Also check if
 some attributes are getting forced outside of rsync's control, such a mount
 option that squishes root to a single user, or mounts a removable drive
 with generic ownership (such as OS X's &quot;Ignore ownership on this volume&quot;
@@ -2198,24 +2530,26 @@ alternate destination files via hard-links.  Also, itemizing of changes can
 get a bit muddled.  Note that prior to version 3.1.0, an
 alternate-directory exact match would never be found (nor linked into the
 destination) when a destination file already exists.</p>
-<p>Note that if you combine this option with <code>--ignore-times</code>, rsync will not
+<p>Note that if you combine this option with <a href="#opt--ignore-times"><code>--ignore-times</code></a>, rsync will not
 link any files together because it only links identical files together as a
 substitute for transferring the file, never as an additional check after
 the file is updated.</p>
 <p>If <u>DIR</u> is a relative path, it is relative to the destination directory.
-See also <code>--compare-dest</code> and <code>--copy-dest</code>.</p>
+See also <a href="#opt--compare-dest"><code>--compare-dest</code></a> and <a href="#opt--copy-dest"><code>--copy-dest</code></a>.</p>
 <p>Note that rsync versions prior to 2.6.1 had a bug that could prevent
-<code>--link-dest</code> from working properly for a non-super-user when <code>-o</code> was
-specified (or implied by <code>-a</code>).  You can work-around this bug by avoiding
-the <code>-o</code> option when sending to an old rsync.</p>
+<code>--link-dest</code> from working properly for a non-super-user when
+<a href="#opt--owner"><code>--owner</code></a> (<code>-o</code>) was specified (or implied).  You can work-around
+this bug by avoiding the <code>-o</code> option (or using <code>--no-o</code>) when sending to an
+old rsync.</p>
 </dd>
 
-<dt><code>--compress</code>, <code>-z</code></dt><dd>
+<span id="opt-z"></span><dt id="opt--compress"><code>--compress</code>, <code>-z</code><a href="#opt--compress" class="tgt"></a></dt><dd>
 <p>With this option, rsync compresses the file data as it is sent to the
 destination machine, which reduces the amount of data being transmitted&nbsp;-&#8288;-&#8288;
 something that is useful over a slow connection.</p>
 <p>Rsync supports multiple compression methods and will choose one for you
-unless you force the choice using the <code>--compress-choice</code> (<code>--zc</code>) option.</p>
+unless you force the choice using the <a href="#opt--compress-choice"><code>--compress-choice</code></a> (<code>--zc</code>)
+option.</p>
 <p>Run <code>rsync --version</code> to see the default compress list compiled into your
 version.</p>
 <p>When both sides of the transfer are at least 3.2.0, rsync chooses the first
@@ -2224,10 +2558,10 @@ of choices.  If no common compress choice is found, rsync exits with
 an error.  If the remote rsync is too old to support checksum negotiation,
 its list is assumed to be &quot;zlib&quot;.</p>
 <p>The default order can be customized by setting the environment variable
-RSYNC_COMPRESS_LIST to a space-separated list of acceptable compression
-names.  If the string contains a &quot;<code>&amp;</code>&quot; character, it is separated into the
-&quot;client string &amp; server string&quot;, otherwise the same string applies to both.
-If the string (or string portion) contains no
+<a href="#RSYNC_COMPRESS_LIST"><code>RSYNC_COMPRESS_LIST</code></a> to a space-separated list of acceptable
+compression names.  If the string contains a &quot;<code>&amp;</code>&quot; character, it is
+separated into the &quot;client string &amp; server string&quot;, otherwise the same
+string applies to both.  If the string (or string portion) contains no
 non-whitespace characters, the default compress list is used.  Any unknown
 compression names are discarded from the list, but a list with only invalid
 names results in a failed negotiation.</p>
@@ -2236,15 +2570,13 @@ option and require the use of <code>-zz</code> because their compression library
 not compatible with the default zlib compression method.  You can usually
 ignore this weirdness unless the rsync server complains and tells you to
 specify <code>-zz</code>.</p>
-<p>See also the <code>--skip-compress</code> option for the default list of file suffixes
-that will be transferred with no (or minimal) compression.</p>
 </dd>
 
-<dt><code>--compress-choice=STR</code>, <code>--zc=STR</code></dt><dd>
+<span id="opt--zc"></span><dt id="opt--compress-choice"><code>--compress-choice=STR</code>, <code>--zc=STR</code><a href="#opt--compress-choice" class="tgt"></a></dt><dd>
 <p>This option can be used to override the automatic negotiation of the
-compression algorithm that occurs when <code>--compress</code> is used.  The option
-implies <code>--compress</code> unless &quot;none&quot; was specified, which instead implies
-<code>--no-compress</code>.</p>
+compression algorithm that occurs when <a href="#opt--compress"><code>--compress</code></a> is used.  The
+option implies <a href="#opt--compress"><code>--compress</code></a> unless &quot;none&quot; was specified, which
+instead implies <code>--no-compress</code>.</p>
 <p>The compression options that you may be able to use are:</p>
 <ul>
 <li><code>zstd</code></li>
@@ -2265,23 +2597,24 @@ with matched data excluded from the compression stream (to try to make it
 more compatible with an external zlib implementation).</p>
 </dd>
 
-<dt><code>--compress-level=NUM</code>, <code>--zl=NUM</code></dt><dd>
-<p>Explicitly set the compression level to use (see <code>--compress</code>, <code>-z</code>)
-instead of letting it default.  The <code>--compress</code> option is implied as long
-as the level chosen is not a &quot;don't compress&quot; level for the compression
-algorithm that is in effect (e.g. zlib compression treats level 0 as
-&quot;off&quot;).</p>
+<span id="opt--zl"></span><dt id="opt--compress-level"><code>--compress-level=NUM</code>, <code>--zl=NUM</code><a href="#opt--compress-level" class="tgt"></a></dt><dd>
+<p>Explicitly set the compression level to use (see <a href="#opt--compress"><code>--compress</code></a>,
+<code>-z</code>) instead of letting it default.  The <a href="#opt--compress"><code>--compress</code></a> option is
+implied as long as the level chosen is not a &quot;don't compress&quot; level for the
+compression algorithm that is in effect (e.g. zlib compression treats level
+0 as &quot;off&quot;).</p>
 <p>The level values vary depending on the checksum in effect.  Because rsync
 will negotiate a checksum choice by default (when the remote rsync is new
-enough), it can be good to combine this option with a <code>--compress-choice</code>
-(<code>--zc</code>) option unless you're sure of the choice in effect.  For example:</p>
+enough), it can be good to combine this option with a
+<a href="#opt--compress-choice"><code>--compress-choice</code></a> (<code>--zc</code>) option unless you're sure of the
+choice in effect.  For example:</p>
 <blockquote>
 <pre><code>rsync -aiv --zc=zstd --zl=22 host:src/ dest/
 </code></pre>
 </blockquote>
 <p>For zlib &amp; zlibx compression the valid values are from 1 to 9 with 6 being
-the default.  Specifying 0 turns compression off, and specifying -&#8288;1 chooses
-the default of 6.</p>
+the default.  Specifying <code>--zl=0</code> turns compression off, and specifying
+<code>--zl=-1</code> chooses the default level of 6.</p>
 <p>For zstd compression the valid values are from -&#8288;131072 to 22 with 3 being
 the default. Specifying 0 chooses the default of 3.</p>
 <p>For lz4 compression there are no levels, so the value is always 0.</p>
@@ -2290,20 +2623,20 @@ limited to a valid value.  This allows you to specify something like
 <code>--zl=999999999</code> and be assured that you'll end up with the maximum
 compression level no matter what algorithm was chosen.</p>
 <p>If you want to know the compression level that is in effect, specify
-<code>--debug=nstr</code> to see the &quot;negotiated string&quot; results.  This will report
-something like &quot;<code>Client compress: zstd (level 3)</code>&quot; (along with the checksum
-choice in effect).</p>
+<a href="#opt--debug"><code>--debug=nstr</code></a> to see the &quot;negotiated string&quot; results.  This will
+report something like &quot;<code>Client compress: zstd (level 3)</code>&quot; (along with the
+checksum choice in effect).</p>
 </dd>
 
-<dt><code>--skip-compress=LIST</code></dt><dd>
+<dt id="opt--skip-compress"><code>--skip-compress=LIST</code><a href="#opt--skip-compress" class="tgt"></a></dt><dd>
+<p><strong>NOTE:</strong> no compression method currently supports per-file compression
+changes, so this option has no effect.</p>
 <p>Override the list of file suffixes that will be compressed as little as
 possible.  Rsync sets the compression level on a per-file basis based on
-the file's suffix.  If the compression algorithm has an &quot;off&quot; level (such
-as zlib/zlibx) then no compression occurs for those files.  Other
-algorithms that support changing the streaming level on-the-fly will have
-the level minimized to reduces the CPU usage as much as possible for a
-matching file.  At this time, only zlib &amp; zlibx compression support this
-changing of levels on a per-file basis.</p>
+the file's suffix.  If the compression algorithm has an &quot;off&quot; level, then
+no compression occurs for those files.  Other algorithms that support
+changing the streaming level on-the-fly will have the level minimized to
+reduces the CPU usage as much as possible for a matching file.</p>
 <p>The <strong>LIST</strong> should be one or more file suffixes (without the dot) separated
 by slashes (<code>/</code>).  You may specify an empty string to indicate that no files
 should be skipped.</p>
@@ -2423,7 +2756,7 @@ list of non-compressing files (and its list may be configured to a
 different default).</p>
 </dd>
 
-<dt><code>--numeric-ids</code></dt><dd>
+<dt id="opt--numeric-ids"><code>--numeric-ids</code><a href="#opt--numeric-ids" class="tgt"></a></dt><dd>
 <p>With this option rsync will transfer numeric group and user IDs rather than
 using user and group names and mapping them at both ends.</p>
 <p>By default rsync will use the username and groupname to determine what
@@ -2432,13 +2765,13 @@ never mapped via user/group names even if the <code>--numeric-ids</code> option
 specified.</p>
 <p>If a user or group has no name on the source system or it has no match on
 the destination system, then the numeric ID from the source system is used
-instead.  See also the comments on the &quot;<code>use chroot</code>&quot; setting in the
-rsyncd.conf manpage for information on how the chroot setting affects
-rsync's ability to look up the names of the users and groups and what you
-can do about it.</p>
+instead.  See also the <a href="rsyncd.conf.5#use_chroot"><code>use chroot</code></a> setting
+in the rsyncd.conf manpage for some comments on how the chroot setting
+affects rsync's ability to look up the names of the users and groups and
+what you can do about it.</p>
 </dd>
 
-<dt><code>--usermap=STRING</code>, <code>--groupmap=STRING</code></dt><dd>
+<span id="opt--groupmap"></span><dt id="opt--usermap"><code>--usermap=STRING</code>, <code>--groupmap=STRING</code><a href="#opt--usermap" class="tgt"></a></dt><dd>
 <p>These options allow you to specify users and groups that should be mapped
 to other values by the receiving side.  The <strong>STRING</strong> is one or more
 <strong>FROM</strong>:<strong>TO</strong> pairs of values separated by commas.  Any matching <strong>FROM</strong>
@@ -2468,75 +2801,81 @@ via a &quot;<code>*</code>&quot; or using an empty name.  For instance:</p>
 <pre><code>--usermap=:nobody --groupmap=*:nobody
 </code></pre>
 </blockquote>
-<p>When the <code>--numeric-ids</code> option is used, the sender does not send any
+<p>When the <a href="#opt--numeric-ids"><code>--numeric-ids</code></a> option is used, the sender does not send any
 names, so all the IDs are treated as having an empty name.  This means that
 you will need to specify numeric <strong>FROM</strong> values if you want to map these
 nameless IDs to different values.</p>
-<p>For the <code>--usermap</code> option to have any effect, the <code>-o</code> (<code>--owner</code>) option
-must be used (or implied), and the receiver will need to be running as a
-super-user (see also the <code>--fake-super</code> option).  For the <code>--groupmap</code>
-option to have any effect, the <code>-g</code> (<code>--groups</code>) option must be used (or
-implied), and the receiver will need to have permissions to set that group.</p>
-<p>If your shell complains about the wildcards, use <code>--protect-args</code> (<code>-s</code>).</p>
-</dd>
-
-<dt><code>--chown=USER:GROUP</code></dt><dd>
+<p>For the <code>--usermap</code> option to work, the receiver will need to be running as
+a super-user (see also the <a href="#opt--super"><code>--super</code></a> and <a href="#opt--fake-super"><code>--fake-super</code></a>
+options).  For the <code>--groupmap</code> option to work, the receiver will need to
+have permissions to set that group.</p>
+<p>Starting with rsync 3.2.4, the <code>--usermap</code> option implies the
+<a href="#opt--owner"><code>--owner</code></a> (<code>-o</code>) option while the <code>--groupmap</code> option implies the
+<a href="#opt--group"><code>--group</code></a> (<code>-g</code>) option (since rsync needs to have those options
+enabled for the mapping options to work).</p>
+<p>An older rsync client may need to use <a href="#opt-s"><code>-s</code></a> to avoid a complaint
+about wildcard characters, but a modern rsync handles this automatically.</p>
+</dd>
+
+<dt id="opt--chown"><code>--chown=USER:GROUP</code><a href="#opt--chown" class="tgt"></a></dt><dd>
 <p>This option forces all files to be owned by USER with group GROUP.  This is
-a simpler interface than using <code>--usermap</code> and <code>--groupmap</code> directly, but
-it is implemented using those options internally, so you cannot mix them.
-If either the USER or GROUP is empty, no mapping for the omitted user/group
-will occur.  If GROUP is empty, the trailing colon may be omitted, but if
-USER is empty, a leading colon must be supplied.</p>
+a simpler interface than using <a href="#opt--usermap"><code>--usermap</code></a> &amp; <a href="#opt--groupmap"><code>--groupmap</code></a>
+directly, but it is implemented using those options internally so they
+cannot be mixed.  If either the USER or GROUP is empty, no mapping for the
+omitted user/group will occur.  If GROUP is empty, the trailing colon may
+be omitted, but if USER is empty, a leading colon must be supplied.</p>
 <p>If you specify &quot;<code>--chown=foo:bar</code>&quot;, this is exactly the same as specifying
-&quot;<code>--usermap=*:foo --groupmap=*:bar</code>&quot;, only easier.  If your shell complains
-about the wildcards, use <code>--protect-args</code> (<code>-s</code>).</p>
+&quot;<code>--usermap=*:foo --groupmap=*:bar</code>&quot;, only easier (and with the same
+implied <a href="#opt--owner"><code>--owner</code></a> and/or <a href="#opt--group"><code>--group</code></a> options).</p>
+<p>An older rsync client may need to use <a href="#opt-s"><code>-s</code></a> to avoid a complaint
+about wildcard characters, but a modern rsync handles this automatically.</p>
 </dd>
 
-<dt><code>--timeout=SECONDS</code></dt><dd>
+<dt id="opt--timeout"><code>--timeout=SECONDS</code><a href="#opt--timeout" class="tgt"></a></dt><dd>
 <p>This option allows you to set a maximum I/O timeout in seconds.  If no data
 is transferred for the specified time then rsync will exit.  The default is
 0, which means no timeout.</p>
 </dd>
 
-<dt><code>--contimeout=SECONDS</code></dt><dd>
+<dt id="opt--contimeout"><code>--contimeout=SECONDS</code><a href="#opt--contimeout" class="tgt"></a></dt><dd>
 <p>This option allows you to set the amount of time that rsync will wait for
 its connection to an rsync daemon to succeed.  If the timeout is reached,
 rsync exits with an error.</p>
 </dd>
 
-<dt><code>--address=ADDRESS</code></dt><dd>
+<dt id="opt--address"><code>--address=ADDRESS</code><a href="#opt--address" class="tgt"></a></dt><dd>
 <p>By default rsync will bind to the wildcard address when connecting to an
 rsync daemon.  The <code>--address</code> option allows you to specify a specific IP
-address (or hostname) to bind to.  See also this option in the <code>--daemon</code>
-mode section.</p>
+address (or hostname) to bind to.</p>
+<p>See also <a href="#dopt--address">the daemon version of the <code>--address</code> option</a>.</p>
 </dd>
 
-<dt><code>--port=PORT</code></dt><dd>
+<dt id="opt--port"><code>--port=PORT</code><a href="#opt--port" class="tgt"></a></dt><dd>
 <p>This specifies an alternate TCP port number to use rather than the default
 of 873.  This is only needed if you are using the double-colon (::) syntax
 to connect with an rsync daemon (since the URL syntax has a way to specify
-the port as a part of the URL).  See also this option in the <code>--daemon</code>
-mode section.</p>
+the port as a part of the URL).</p>
+<p>See also <a href="#dopt--port">the daemon version of the <code>--port</code> option</a>.</p>
 </dd>
 
-<dt><code>--sockopts=OPTIONS</code></dt><dd>
+<dt id="opt--sockopts"><code>--sockopts=OPTIONS</code><a href="#opt--sockopts" class="tgt"></a></dt><dd>
 <p>This option can provide endless fun for people who like to tune their
 systems to the utmost degree.  You can set all sorts of socket options
-which may make transfers faster (or slower!).  Read the man page for the
+which may make transfers faster (or slower!).  Read the manpage for the
 <code>setsockopt()</code> system call for details on some of the options you may be
 able to set.  By default no special socket options are set.  This only
 affects direct socket connections to a remote rsync daemon.</p>
-<p>This option also exists in the <code>--daemon</code> mode section.</p>
+<p>See also <a href="#dopt--sockopts">the daemon version of the <code>--sockopts</code> option</a>.</p>
 </dd>
 
-<dt><code>--blocking-io</code></dt><dd>
+<dt id="opt--blocking-io"><code>--blocking-io</code><a href="#opt--blocking-io" class="tgt"></a></dt><dd>
 <p>This tells rsync to use blocking I/O when launching a remote shell
 transport.  If the remote shell is either rsh or remsh, rsync defaults to
 using blocking I/O, otherwise it defaults to using non-blocking I/O. (Note
 that ssh prefers non-blocking I/O.)</p>
 </dd>
 
-<dt><code>--outbuf=MODE</code></dt><dd>
+<dt id="opt--outbuf"><code>--outbuf=MODE</code><a href="#opt--outbuf" class="tgt"></a></dt><dd>
 <p>This sets the output buffering mode.  The mode can be None (aka
 Unbuffered), Line, or Block (aka Full).  You may specify as little as a
 single letter for the mode, and use upper or lower case.</p>
@@ -2544,13 +2883,13 @@ single letter for the mode, and use upper or lower case.</p>
 when rsync's output is going to a file or pipe.</p>
 </dd>
 
-<dt><code>--itemize-changes</code>, <code>-i</code></dt><dd>
+<span id="opt-i"></span><dt id="opt--itemize-changes"><code>--itemize-changes</code>, <code>-i</code><a href="#opt--itemize-changes" class="tgt"></a></dt><dd>
 <p>Requests a simple itemized list of the changes that are being made to each
 file, including attribute changes.  This is exactly the same as specifying
-<code>--out-format='%i %n%L'</code>.  If you repeat the option, unchanged files will
-also be output, but only if the receiving rsync is at least version 2.6.7
-(you can use <code>-vv</code> with older versions of rsync, but that also turns on the
-output of other verbose messages).</p>
+<a href="#opt--out-format"><code>--out-format='%i %n%L'</code></a>.  If you repeat the option, unchanged
+files will also be output, but only if the receiving rsync is at least
+version 2.6.7 (you can use <code>-vv</code> with older versions of rsync, but that
+also turns on the output of other verbose messages).</p>
 <p>The &quot;%i&quot; escape has a cryptic output that is 11 letters long.  The general
 format is like the string <code>YXcstpoguax</code>, where <strong>Y</strong> is replaced by the type
 of update being done, <strong>X</strong> is replaced by the file-type, and the other
@@ -2563,7 +2902,7 @@ letters represent attributes that may be output if they are being modified.</p>
 <li>A <code>c</code> means that a local change/creation is occurring for the item (such
 as the creation of a directory or the changing of a symlink, etc.).</li>
 <li>A <code>h</code> means that the item is a hard link to another item (requires
-<code>--hard-links</code>).</li>
+<a href="#opt--hard-links"><code>--hard-links</code></a>).</li>
 <li>A <code>.</code> means that the item is not being updated (though it might have
 attributes that are being modified).</li>
 <li>A <code>*</code> means that the rest of the itemized-output area contains a message
@@ -2584,30 +2923,35 @@ have changed, as follows:</p>
 <p>The attribute that is associated with each letter is as follows:</p>
 <ul>
 <li>A <code>c</code> means either that a regular file has a different checksum (requires
-<code>--checksum</code>) or that a symlink, device, or special file has a changed
-value.  Note that if you are sending files to an rsync prior to 3.0.1,
-this change flag will be present only for checksum-differing regular
-files.</li>
+<a href="#opt--checksum"><code>--checksum</code></a>) or that a symlink, device, or special file has a
+changed value.  Note that if you are sending files to an rsync prior to
+3.0.1, this change flag will be present only for checksum-differing
+regular files.</li>
 <li>A <code>s</code> means the size of a regular file is different and will be updated
 by the file transfer.</li>
 <li>A <code>t</code> means the modification time is different and is being updated to
-the sender's value (requires <code>--times</code>).  An alternate value of <code>T</code> means
-that the modification time will be set to the transfer time, which
-happens when a file/symlink/device is updated without <code>--times</code> and when
-a symlink is changed and the receiver can't set its time. (Note: when
-using an rsync 3.0.0 client, you might see the <code>s</code> flag combined with <code>t</code>
-instead of the proper <code>T</code> flag for this time-setting failure.)</li>
+the sender's value (requires <a href="#opt--times"><code>--times</code></a>).  An alternate value of
+<code>T</code> means that the modification time will be set to the transfer time,
+which happens when a file/symlink/device is updated without
+<a href="#opt--times"><code>--times</code></a> and when a symlink is changed and the receiver can't
+set its time. (Note: when using an rsync 3.0.0 client, you might see the
+<code>s</code> flag combined with <code>t</code> instead of the proper <code>T</code> flag for this
+time-setting failure.)</li>
 <li>A <code>p</code> means the permissions are different and are being updated to the
-sender's value (requires <code>--perms</code>).</li>
+sender's value (requires <a href="#opt--perms"><code>--perms</code></a>).</li>
 <li>An <code>o</code> means the owner is different and is being updated to the sender's
-value (requires <code>--owner</code> and super-user privileges).</li>
+value (requires <a href="#opt--owner"><code>--owner</code></a> and super-user privileges).</li>
 <li>A <code>g</code> means the group is different and is being updated to the sender's
-value (requires <code>--group</code> and the authority to set the group).</li>
-<li>A <code>u</code>|<code>n</code>|<code>b</code> indicates the following information: <code>u</code>  means the access
-(use) time is different and is being updated to the sender's value
-(requires <code>--atimes</code>); <code>n</code> means the create time (newness) is different
-and is being updated to the sender's value (requires <code>--crtimes</code>); <code>b</code>
-means that both the access and create times are being updated.</li>
+value (requires <a href="#opt--group"><code>--group</code></a> and the authority to set the group).</li>
+<li>A <code>u</code>|<code>n</code>|<code>b</code> indicates the following information:
+<ul>
+<li><code>u</code>  means the access (use) time is different and is being updated to
+the sender's value (requires <a href="#opt--atimes"><code>--atimes</code></a>)</li>
+<li><code>n</code> means the create time (newness) is different and is being updated
+to the sender's value (requires <a href="#opt--crtimes"><code>--crtimes</code></a>)</li>
+<li><code>b</code> means that both the access and create times are being updated</li>
+</ul>
+</li>
 <li>The <code>a</code> means that the ACL information is being changed.</li>
 <li>The <code>x</code> means that the extended attribute information is being changed.</li>
 </ul>
@@ -2617,38 +2961,38 @@ are talking to a recent enough rsync that it logs deletions instead of
 outputting them as a verbose message).</p>
 </dd>
 
-<dt><code>--out-format=FORMAT</code></dt><dd>
+<dt id="opt--out-format"><code>--out-format=FORMAT</code><a href="#opt--out-format" class="tgt"></a></dt><dd>
 <p>This allows you to specify exactly what the rsync client outputs to the
 user on a per-update basis.  The format is a text string containing
 embedded single-character escape sequences prefixed with a percent (%)
-character.  A default format of &quot;%n%L&quot; is assumed if either <code>--info=name</code>
-or <code>-v</code> is specified (this tells you just the name of the file and, if the
-item is a link, where it points).  For a full list of the possible escape
-characters, see the &quot;<code>log format</code>&quot; setting in the rsyncd.conf manpage.</p>
-<p>Specifying the <code>--out-format</code> option implies the <code>--info=name</code> option,
-which will mention each file, dir, etc. that gets updated in a significant
-way (a transferred file, a recreated symlink/device, or a touched
-directory).  In addition, if the itemize-changes escape (%i) is included in
-the string (e.g. if the <code>--itemize-changes</code> option was used), the logging
-of names increases to mention any item that is changed in any way (as long
-as the receiving side is at least 2.6.4).  See the <code>--itemize-changes</code>
-option for a description of the output of &quot;%i&quot;.</p>
+character.  A default format of &quot;%n%L&quot; is assumed if either
+<a href="#opt--info"><code>--info=name</code></a> or <a href="#opt-v"><code>-v</code></a> is specified (this tells you just the
+name of the file and, if the item is a link, where it points).  For a full
+list of the possible escape characters, see the <a href="rsyncd.conf.5#log_format"><code>log format</code></a> setting in the rsyncd.conf manpage.</p>
+<p>Specifying the <code>--out-format</code> option implies the <a href="#opt--info"><code>--info=name</code></a>
+option, which will mention each file, dir, etc. that gets updated in a
+significant way (a transferred file, a recreated symlink/device, or a
+touched directory).  In addition, if the itemize-changes escape (%i) is
+included in the string (e.g. if the <a href="#opt--itemize-changes"><code>--itemize-changes</code></a> option was
+used), the logging of names increases to mention any item that is changed
+in any way (as long as the receiving side is at least 2.6.4).  See the
+<a href="#opt--itemize-changes"><code>--itemize-changes</code></a> option for a description of the output of &quot;%i&quot;.</p>
 <p>Rsync will output the out-format string prior to a file's transfer unless
 one of the transfer-statistic escapes is requested, in which case the
 logging is done at the end of the file's transfer.  When this late logging
-is in effect and <code>--progress</code> is also specified, rsync will also output the
-name of the file being transferred prior to its progress information
-(followed, of course, by the out-format output).</p>
+is in effect and <a href="#opt--progress"><code>--progress</code></a> is also specified, rsync will also
+output the name of the file being transferred prior to its progress
+information (followed, of course, by the out-format output).</p>
 </dd>
 
-<dt><code>--log-file=FILE</code></dt><dd>
+<dt id="opt--log-file"><code>--log-file=FILE</code><a href="#opt--log-file" class="tgt"></a></dt><dd>
 <p>This option causes rsync to log what it is doing to a file.  This is
 similar to the logging that a daemon does, but can be requested for the
 client side and/or the server side of a non-daemon transfer.  If specified
 as a client option, transfer logging will be enabled with a default format
-of &quot;%i %n%L&quot;.  See the <code>--log-file-format</code> option if you wish to override
-this.</p>
-<p>Here's a example command that requests the remote side to log what is
+of &quot;%i %n%L&quot;.  See the <a href="#opt--log-file-format"><code>--log-file-format</code></a> option if you wish to
+override this.</p>
+<p>Here's an example command that requests the remote side to log what is
 happening:</p>
 <blockquote>
 <pre><code>rsync -av --remote-option=--log-file=/tmp/rlog src/ dest/
@@ -2656,24 +3000,28 @@ happening:</p>
 </blockquote>
 <p>This is very useful if you need to debug why a connection is closing
 unexpectedly.</p>
+<p>See also <a href="#dopt--log-file">the daemon version of the <code>--log-file</code> option</a>.</p>
 </dd>
 
-<dt><code>--log-file-format=FORMAT</code></dt><dd>
+<dt id="opt--log-file-format"><code>--log-file-format=FORMAT</code><a href="#opt--log-file-format" class="tgt"></a></dt><dd>
 <p>This allows you to specify exactly what per-update logging is put into the
-file specified by the <code>--log-file</code> option (which must also be specified for
-this option to have any effect).  If you specify an empty string, updated
-files will not be mentioned in the log file.  For a list of the possible
-escape characters, see the &quot;<code>log format</code>&quot; setting in the rsyncd.conf manpage.</p>
-<p>The default FORMAT used if <code>--log-file</code> is specified and this option is not
-is '%i %n%L'.</p>
-</dd>
-
-<dt><code>--stats</code></dt><dd>
+file specified by the <a href="#opt--log-file"><code>--log-file</code></a> option (which must also be
+specified for this option to have any effect).  If you specify an empty
+string, updated files will not be mentioned in the log file.  For a list of
+the possible escape characters, see the <a href="rsyncd.conf.5#log_format"><code>log format</code></a>
+setting in the rsyncd.conf manpage.</p>
+<p>The default FORMAT used if <a href="#opt--log-file"><code>--log-file</code></a> is specified and this
+option is not is '%i %n%L'.</p>
+<p>See also <a href="#dopt--log-file-format">the daemon version of the <code>--log-file-format</code>
+option</a>.</p>
+</dd>
+
+<dt id="opt--stats"><code>--stats</code><a href="#opt--stats" class="tgt"></a></dt><dd>
 <p>This tells rsync to print a verbose set of statistics on the file transfer,
 allowing you to tell how effective rsync's delta-transfer algorithm is for
-your data.  This option is equivalent to <code>--info=stats2</code> if combined with 0
-or 1 <code>-v</code> options, or <code>--info=stats3</code> if combined with 2 or more <code>-v</code>
-options.</p>
+your data.  This option is equivalent to <a href="#opt--info"><code>--info=stats2</code></a> if
+combined with 0 or 1 <a href="#opt-v"><code>-v</code></a> options, or <a href="#opt--info"><code>--info=stats3</code></a> if
+combined with 2 or more <a href="#opt-v"><code>-v</code></a> options.</p>
 <p>The current statistics are as follows:</p>
 <ul>
 <li><code>Number of files</code> is the count of all &quot;files&quot; (in the generic sense),
@@ -2686,7 +3034,7 @@ any of value is 0, it is completely omitted from the list.</li>
 sense) were created (as opposed to updated).  The total count will be
 followed by a list of counts by filetype (if the total is non-zero).</li>
 <li><code>Number of deleted files</code> is the count of how many &quot;files&quot; (generic
-sense) were created (as opposed to updated).  The total count will be
+sense) were deleted.  The total count will be
 followed by a list of counts by filetype (if the total is non-zero).
 Note that this line is only output if deletions are in effect, and only
 if protocol 31 is being used (the default for rsync 3.1.x).</li>
@@ -2721,7 +3069,7 @@ sent to us, which makes the stats more consistent.</li>
 </ul>
 </dd>
 
-<dt><code>--8-bit-output</code>, <code>-8</code></dt><dd>
+<span id="opt-8"></span><dt id="opt--8-bit-output"><code>--8-bit-output</code>, <code>-8</code><a href="#opt--8-bit-output" class="tgt"></a></dt><dd>
 <p>This tells rsync to leave all high-bit characters unescaped in the output
 instead of trying to test them to see if they're valid in the current
 locale and escaping the invalid ones.  All control characters (but never
@@ -2732,13 +3080,16 @@ newline would output as &quot;<code>\#012</code>&quot;.  A literal backslash tha
 filename is not escaped unless it is followed by a hash and 3 digits (0-9).</p>
 </dd>
 
-<dt><code>--human-readable</code>, <code>-h</code></dt><dd>
-<p>Output numbers in a more human-readable format.  There are 3 possible
-levels: (1) output numbers with a separator between each set of 3 digits
-(either a comma or a period, depending on if the decimal point is
-represented by a period or a comma); (2) output numbers in units of 1000
-(with a character suffix for larger units&nbsp;-&#8288;-&#8288; see below); (3) output
-numbers in units of 1024.</p>
+<span id="opt-h"></span><dt id="opt--human-readable"><code>--human-readable</code>, <code>-h</code><a href="#opt--human-readable" class="tgt"></a></dt><dd>
+<p>Output numbers in a more human-readable format.  There are 3 possible levels:</p>
+<ol>
+<li>output numbers with a separator between each set of 3 digits (either a
+comma or a period, depending on if the decimal point is represented by a
+period or a comma).</li>
+<li>output numbers in units of 1000 (with a character suffix for larger
+units&nbsp;-&#8288;-&#8288; see below).</li>
+<li>output numbers in units of 1024.</li>
+</ol>
 <p>The default is human-readable level 1.  Each <code>-h</code> option increases the
 level by one.  You can take the level down to 0 (to output numbers as pure
 digits) by specifying the <code>--no-human-readable</code> (<code>--no-h</code>) option.</p>
@@ -2750,11 +3101,11 @@ decimal point).</p>
 support human-readable level 1, and they default to level 0.  Thus,
 specifying one or two <code>-h</code> options will behave in a comparable manner in
 old and new versions as long as you didn't specify a <code>--no-h</code> option prior
-to one or more <code>-h</code> options.  See the <code>--list-only</code> option for one
+to one or more <code>-h</code> options.  See the <a href="#opt--list-only"><code>--list-only</code></a> option for one
 difference.</p>
 </dd>
 
-<dt><code>--partial</code></dt><dd>
+<dt id="opt--partial"><code>--partial</code><a href="#opt--partial" class="tgt"></a></dt><dd>
 <p>By default, rsync will delete any partially transferred file if the
 transfer is interrupted.  In some circumstances it is more desirable to
 keep partially transferred files.  Using the <code>--partial</code> option tells rsync
@@ -2762,99 +3113,110 @@ to keep the partial file which should make a subsequent transfer of the
 rest of the file much faster.</p>
 </dd>
 
-<dt><code>--partial-dir=DIR</code></dt><dd>
-<p>A better way to keep partial files than the <code>--partial</code> option is to
-specify a <u>DIR</u> that will be used to hold the partial data (instead of
-writing it out to the destination file).  On the next transfer, rsync will
-use a file found in this dir as data to speed up the resumption of the
+<dt id="opt--partial-dir"><code>--partial-dir=DIR</code><a href="#opt--partial-dir" class="tgt"></a></dt><dd>
+<p>This option modifies the behavior of the <a href="#opt--partial"><code>--partial</code></a> option while
+also implying that it be enabled.  This enhanced partial-file method puts
+any partially transferred files into the specified <u>DIR</u> instead of writing
+the partial file out to the destination file.  On the next transfer, rsync
+will use a file found in this dir as data to speed up the resumption of the
 transfer and then delete it after it has served its purpose.</p>
-<p>Note that if <code>--whole-file</code> is specified (or implied), any partial-dir file
-that is found for a file that is being updated will simply be removed
-(since rsync is sending files without using rsync's delta-transfer
-algorithm).</p>
-<p>Rsync will create the <u>DIR</u> if it is missing (just the last dir&nbsp;-&#8288;-&#8288; not the
-whole path).  This makes it easy to use a relative path (such as
+<p>Note that if <a href="#opt--whole-file"><code>--whole-file</code></a> is specified (or implied), any
+partial-dir files that are found for a file that is being updated will
+simply be removed (since rsync is sending files without using rsync's
+delta-transfer algorithm).</p>
+<p>Rsync will create the <u>DIR</u> if it is missing, but just the last dir&nbsp;-&#8288;-&#8288; not
+the whole path.  This makes it easy to use a relative path (such as
 &quot;<code>--partial-dir=.rsync-partial</code>&quot;) to have rsync create the
-partial-directory in the destination file's directory when needed, and then
-remove it again when the partial file is deleted.  Note that the directory
-is only removed if it is a relative pathname, as it is expected that an
-absolute path is to a directory that is reserved for partial-dir work.</p>
+partial-directory in the destination file's directory when it is needed,
+and then remove it again when the partial file is deleted.  Note that this
+directory removal is only done for a relative pathname, as it is expected
+that an absolute path is to a directory that is reserved for partial-dir
+work.</p>
 <p>If the partial-dir value is not an absolute path, rsync will add an exclude
 rule at the end of all your existing excludes.  This will prevent the
 sending of any partial-dir files that may exist on the sending side, and
 will also prevent the untimely deletion of partial-dir items on the
 receiving side.  An example: the above <code>--partial-dir</code> option would add the
-equivalent of &quot;<code>-f '-p .rsync-partial/'</code>&quot; at the end of any other filter
-rules.</p>
+equivalent of this &quot;perishable&quot; exclude at the end of any other filter
+rules: <code>-f '-p .rsync-partial/'</code></p>
 <p>If you are supplying your own exclude rules, you may need to add your own
-exclude/hide/protect rule for the partial-dir because (1) the auto-added
-rule may be ineffective at the end of your other rules, or (2) you may wish
-to override rsync's exclude choice.  For instance, if you want to make
-rsync clean-up any left-over partial-dirs that may be lying around, you
-should specify <code>--delete-after</code> and add a &quot;risk&quot; filter rule, e.g.
-<code>-f 'R .rsync-partial/'</code>. (Avoid using <code>--delete-before</code> or
-<code>--delete-during</code> unless you don't need rsync to use any of the left-over
-partial-dir data during the current run.)</p>
+exclude/hide/protect rule for the partial-dir because:</p>
+<ol>
+<li>the auto-added rule may be ineffective at the end of your other rules, or</li>
+<li>you may wish to override rsync's exclude choice.</li>
+</ol>
+<p>For instance, if you want to make rsync clean-up any left-over partial-dirs
+that may be lying around, you should specify <a href="#opt--delete-after"><code>--delete-after</code></a> and
+add a &quot;risk&quot; filter rule, e.g.  <code>-f 'R .rsync-partial/'</code>. Avoid using
+<a href="#opt--delete-before"><code>--delete-before</code></a> or <a href="#opt--delete-during"><code>--delete-during</code></a> unless you don't
+need rsync to use any of the left-over partial-dir data during the current
+run.</p>
 <p>IMPORTANT: the <code>--partial-dir</code> should not be writable by other users or it
-is a security risk.  E.g. AVOID &quot;/tmp&quot;.</p>
-<p>You can also set the partial-dir value the RSYNC_PARTIAL_DIR environment
-variable.  Setting this in the environment does not force <code>--partial</code> to be
-enabled, but rather it affects where partial files go when <code>--partial</code> is
-specified.  For instance, instead of using <code>--partial-dir=.rsync-tmp</code> along
-with <code>--progress</code>, you could set RSYNC_PARTIAL_DIR=.rsync-tmp in your
-environment and then just use the <code>-P</code> option to turn on the use of the
-.rsync-tmp dir for partial transfers.  The only times that the <code>--partial</code>
-option does not look for this environment value are (1) when <code>--inplace</code>
-was specified (since <code>--inplace</code> conflicts with <code>--partial-dir</code>), and (2)
-when <code>--delay-updates</code> was specified (see below).</p>
+is a security risk!  E.g. AVOID &quot;/tmp&quot;!</p>
+<p>You can also set the partial-dir value the <a href="#RSYNC_PARTIAL_DIR"><code>RSYNC_PARTIAL_DIR</code></a>
+environment variable.  Setting this in the environment does not force
+<a href="#opt--partial"><code>--partial</code></a> to be enabled, but rather it affects where partial
+files go when <a href="#opt--partial"><code>--partial</code></a> is specified.  For instance, instead of
+using <code>--partial-dir=.rsync-tmp</code> along with <a href="#opt--progress"><code>--progress</code></a>, you could
+set <a href="#RSYNC_PARTIAL_DIR"><code>RSYNC_PARTIAL_DIR=.rsync-tmp</code></a> in your environment and then use
+the <a href="#opt-P"><code>-P</code></a> option to turn on the use of the .rsync-tmp dir for
+partial transfers.  The only times that the <a href="#opt--partial"><code>--partial</code></a> option does
+not look for this environment value are:</p>
+<ol>
+<li>when <a href="#opt--inplace"><code>--inplace</code></a> was specified (since <a href="#opt--inplace"><code>--inplace</code></a>
+conflicts with <code>--partial-dir</code>), and</li>
+<li>when <a href="#opt--delay-updates"><code>--delay-updates</code></a> was specified (see below).</li>
+</ol>
 <p>When a modern rsync resumes the transfer of a file in the partial-dir, that
 partial file is now updated in-place instead of creating yet another
 tmp-file copy (so it maxes out at dest + tmp instead of dest + partial +
 tmp).  This requires both ends of the transfer to be at least version
 3.2.0.</p>
 <p>For the purposes of the daemon-config's &quot;<code>refuse options</code>&quot; setting,
-<code>--partial-dir</code> does <u>not</u> imply <code>--partial</code>.  This is so that a refusal of
-the <code>--partial</code> option can be used to disallow the overwriting of
-destination files with a partial transfer, while still allowing the safer
-idiom provided by <code>--partial-dir</code>.</p>
+<code>--partial-dir</code> does <u>not</u> imply <a href="#opt--partial"><code>--partial</code></a>.  This is so that a
+refusal of the <a href="#opt--partial"><code>--partial</code></a> option can be used to disallow the
+overwriting of destination files with a partial transfer, while still
+allowing the safer idiom provided by <code>--partial-dir</code>.</p>
 </dd>
 
-<dt><code>--delay-updates</code></dt><dd>
+<dt id="opt--delay-updates"><code>--delay-updates</code><a href="#opt--delay-updates" class="tgt"></a></dt><dd>
 <p>This option puts the temporary file from each updated file into a holding
 directory until the end of the transfer, at which time all the files are
 renamed into place in rapid succession.  This attempts to make the updating
 of the files a little more atomic.  By default the files are placed into a
 directory named <code>.~tmp~</code> in each file's destination directory, but if
-you've specified the <code>--partial-dir</code> option, that directory will be used
-instead.  See the comments in the <code>--partial-dir</code> section for a discussion
-of how this <code>.~tmp~</code> dir will be excluded from the transfer, and what you
-can do if you want rsync to cleanup old <code>.~tmp~</code> dirs that might be lying
-around.  Conflicts with <code>--inplace</code> and <code>--append</code>.</p>
-<p>This option implies <code>--no-inc-recursive</code> since it needs the full file list
-in memory in order to be able to iterate over it at the end.</p>
+you've specified the <a href="#opt--partial-dir"><code>--partial-dir</code></a> option, that directory will be
+used instead.  See the comments in the <a href="#opt--partial-dir"><code>--partial-dir</code></a> section for
+a discussion of how this <code>.~tmp~</code> dir will be excluded from the transfer,
+and what you can do if you want rsync to cleanup old <code>.~tmp~</code> dirs that
+might be lying around.  Conflicts with <a href="#opt--inplace"><code>--inplace</code></a> and
+<a href="#opt--append"><code>--append</code></a>.</p>
+<p>This option implies <a href="#opt--no-inc-recursive"><code>--no-inc-recursive</code></a> since it needs the full
+file list in memory in order to be able to iterate over it at the end.</p>
 <p>This option uses more memory on the receiving side (one bit per file
 transferred) and also requires enough free disk space on the receiving side
 to hold an additional copy of all the updated files.  Note also that you
-should not use an absolute path to <code>--partial-dir</code> unless (1) there is no
-chance of any of the files in the transfer having the same name (since all
-the updated files will be put into a single directory if the path is
-absolute) and (2) there are no mount points in the hierarchy (since the
-delayed updates will fail if they can't be renamed into place).</p>
-<p>See also the &quot;atomic-rsync&quot; perl script in the &quot;support&quot; subdir for an
-update algorithm that is even more atomic (it uses <code>--link-dest</code> and a
-parallel hierarchy of files).</p>
-</dd>
-
-<dt><code>--prune-empty-dirs</code>, <code>-m</code></dt><dd>
+should not use an absolute path to <a href="#opt--partial-dir"><code>--partial-dir</code></a> unless:</p>
+<ol>
+<li>there is no chance of any of the files in the transfer having the same
+name (since all the updated files will be put into a single directory if
+the path is absolute), and</li>
+<li>there are no mount points in the hierarchy (since the delayed updates
+will fail if they can't be renamed into place).</li>
+</ol>
+<p>See also the &quot;atomic-rsync&quot; python script in the &quot;support&quot; subdir for an
+update algorithm that is even more atomic (it uses <a href="#opt--link-dest"><code>--link-dest</code></a>
+and a parallel hierarchy of files).</p>
+</dd>
+
+<span id="opt-m"></span><dt id="opt--prune-empty-dirs"><code>--prune-empty-dirs</code>, <code>-m</code><a href="#opt--prune-empty-dirs" class="tgt"></a></dt><dd>
 <p>This option tells the receiving rsync to get rid of empty directories from
 the file-list, including nested directories that have no non-directory
 children.  This is useful for avoiding the creation of a bunch of useless
 directories when the sending rsync is recursively scanning a hierarchy of
 files using include/exclude/filter rules.</p>
-<p>Note that the use of transfer rules, such as the <code>--min-size</code> option, does
-not affect what goes into the file list, and thus does not leave
-directories empty, even if none of the files in a directory match the
-transfer rule.</p>
+<p>This option can still leave empty directories on the receiving side if you
+make use of <a href="#TRANSFER_RULES">TRANSFER_RULES</a>.</p>
 <p>Because the file-list is actually being pruned, this option also affects
 what directories get deleted when a delete is active.  However, keep in
 mind that excluded files and directories can prevent existing items from
@@ -2881,12 +3243,12 @@ time-honored options of <code>--include='*/' --exclude='*'</code> would work
 fine in place of the hide-filter (if that is more natural to you).</p>
 </dd>
 
-<dt><code>--progress</code></dt><dd>
+<dt id="opt--progress"><code>--progress</code><a href="#opt--progress" class="tgt"></a></dt><dd>
 <p>This option tells rsync to print information showing the progress of the
 transfer.  This gives a bored user something to watch.  With a modern rsync
-this is the same as specifying <code>--info=flist2,name,progress</code>, but any
-user-supplied settings for those info flags takes precedence (e.g.
-&quot;<code>--info=flist0 --progress</code>&quot;).</p>
+this is the same as specifying <a href="#opt--info"><code>--info=flist2,name,progress</code></a>, but
+any user-supplied settings for those info flags takes precedence (e.g.
+<a href="#opt--info"><code>--info=flist0 --progress</code></a>).</p>
 <p>While rsync is transferring a regular file, it updates a progress line that
 looks like this:</p>
 <blockquote>
@@ -2926,16 +3288,17 @@ time it does, the count of files left to check will increase by the number
 of the files added to the list).</p>
 </dd>
 
-<dt><code>-P</code></dt><dd>
-<p>The <code>-P</code> option is equivalent to <code>--partial --progress</code>.  Its purpose is
-to make it much easier to specify these two options for a long transfer
-that may be interrupted.</p>
-<p>There is also a <code>--info=progress2</code> option that outputs statistics based on
-the whole transfer, rather than individual files.  Use this flag without
-outputting a filename (e.g. avoid <code>-v</code> or specify <code>--info=name0</code>) if you
-want to see how the transfer is doing without scrolling the screen with a
-lot of names. (You don't need to specify the <code>--progress</code> option in order
-to use <code>--info=progress2</code>.)</p>
+<dt id="opt-P"><code>-P</code><a href="#opt-P" class="tgt"></a></dt><dd>
+<p>The <code>-P</code> option is equivalent to &quot;<a href="#opt--partial"><code>--partial</code></a>
+<a href="#opt--progress"><code>--progress</code></a>&quot;.  Its purpose is to make it much easier to specify
+these two options for a long transfer that may be interrupted.</p>
+<p>There is also a <a href="#opt--info"><code>--info=progress2</code></a> option that outputs statistics
+based on the whole transfer, rather than individual files.  Use this flag
+without outputting a filename (e.g. avoid <code>-v</code> or specify
+<a href="#opt--info"><code>--info=name0</code></a>) if you want to see how the transfer is doing
+without scrolling the screen with a lot of names. (You don't need to
+specify the <a href="#opt--progress"><code>--progress</code></a> option in order to use
+<a href="#opt--info"><code>--info=progress2</code></a>.)</p>
 <p>Finally, you can get an instant progress report by sending rsync a signal
 of either SIGINFO or SIGVTALRM.  On BSD systems, a SIGINFO is generated by
 typing a Ctrl+T (Linux doesn't currently support a SIGINFO signal).  When
@@ -2943,13 +3306,13 @@ the client-side process receives one of those signals, it sets a flag to
 output a single progress report which is output when the current file
 transfer finishes (so it may take a little time if a big file is being
 handled when the signal arrives).  A filename is output (if needed)
-followed by the <code>--info=progress2</code> format of progress info.  If you don't
-know which of the 3 rsync processes is the client process, it's OK to
+followed by the <a href="#opt--info"><code>--info=progress2</code></a> format of progress info.  If you
+don't know which of the 3 rsync processes is the client process, it's OK to
 signal all of them (since the non-client processes ignore the signal).</p>
 <p>CAUTION: sending SIGVTALRM to an older rsync (pre-3.2.0) will kill it.</p>
 </dd>
 
-<dt><code>--password-file=FILE</code></dt><dd>
+<dt id="opt--password-file"><code>--password-file=FILE</code><a href="#opt--password-file" class="tgt"></a></dt><dd>
 <p>This option allows you to provide a password for accessing an rsync daemon
 via a file or via standard input if <strong>FILE</strong> is <code>-</code>.  The file should
 contain just the password on the first line (all other lines are ignored).
@@ -2963,7 +3326,7 @@ authentication (i.e. if you have also specified a password in the daemon's
 config file).</p>
 </dd>
 
-<dt><code>--early-input=FILE</code></dt><dd>
+<dt id="opt--early-input"><code>--early-input=FILE</code><a href="#opt--early-input" class="tgt"></a></dt><dd>
 <p>This option allows rsync to send up to 5K of data to the &quot;early exec&quot;
 script on its stdin.  One possible use of this data is to give the script a
 secret that can be used to mount an encrypted filesystem (which you should
@@ -2971,43 +3334,52 @@ unmount in the the &quot;post-xfer exec&quot; script).</p>
 <p>The daemon must be at least version 3.2.1.</p>
 </dd>
 
-<dt><code>--list-only</code></dt><dd>
+<dt id="opt--list-only"><code>--list-only</code><a href="#opt--list-only" class="tgt"></a></dt><dd>
 <p>This option will cause the source files to be listed instead of
 transferred.  This option is inferred if there is a single source arg and
-no destination specified, so its main uses are: (1) to turn a copy command
-that includes a destination arg into a file-listing command, or (2) to be
-able to specify more than one source arg (note: be sure to include the
-destination).  Caution: keep in mind that a source arg with a wild-card is
-expanded by the shell into multiple args, so it is never safe to try to
-list such an arg without using this option. For example:</p>
+no destination specified, so its main uses are:</p>
+<ol>
+<li>to turn a copy command that includes a destination arg into a
+file-listing command, or</li>
+<li>to be able to specify more than one source arg.  Note: be sure to
+include the destination.</li>
+</ol>
+<p>CAUTION: keep in mind that a source arg with a wild-card is expanded by the
+shell into multiple args, so it is never safe to try to specify a single
+wild-card arg to try to infer this option. A safe example is:</p>
 <blockquote>
 <pre><code>rsync -av --list-only foo* dest/
 </code></pre>
 </blockquote>
-<p>Starting with rsync 3.1.0, the sizes output by <code>--list-only</code> are affected
-by the <code>--human-readable</code> option.  By default they will contain digit
-separators, but higher levels of readability will output the sizes with
-unit suffixes.  Note also that the column width for the size output has
-increased from 11 to 14 characters for all human-readable levels.  Use
-<code>--no-h</code> if you want just digits in the sizes, and the old column width of
-11 characters.</p>
+<p>This option always uses an output format that looks similar to this:</p>
+<blockquote>
+<pre><code>drwxrwxr-x          4,096 2022/09/30 12:53:11 support
+-rw-rw-r--             80 2005/01/11 10:37:37 support/Makefile
+</code></pre>
+</blockquote>
+<p>The only option that affects this output style is (as of 3.1.0) the
+<a href="#opt--human-readable"><code>--human-readable</code></a> (<code>-h</code>) option.  The default is to output sizes
+as byte counts with digit separators (in a 14-character-width column).
+Specifying at least one <code>-h</code> option makes the sizes output with unit
+suffixes.  If you want old-style bytecount sizes without digit separators
+(and an 11-character-width column) use <code>--no-h</code>.</p>
 <p>Compatibility note: when requesting a remote listing of files from an rsync
 that is version 2.6.3 or older, you may encounter an error if you ask for a
-non-recursive listing.  This is because a file listing implies the <code>--dirs</code>
-option w/o <code>--recursive</code>, and older rsyncs don't have that option.  To
-avoid this problem, either specify the <code>--no-dirs</code> option (if you don't
-need to expand a directory's content), or turn on recursion and exclude the
-content of subdirectories: <code>-r --exclude='/*/*'</code>.</p>
+non-recursive listing.  This is because a file listing implies the
+<a href="#opt--dirs"><code>--dirs</code></a> option w/o <a href="#opt--recursive"><code>--recursive</code></a>, and older rsyncs don't
+have that option.  To avoid this problem, either specify the <code>--no-dirs</code>
+option (if you don't need to expand a directory's content), or turn on
+recursion and exclude the content of subdirectories: <code>-r --exclude='/*/*'</code>.</p>
 </dd>
 
-<dt><code>--bwlimit=RATE</code></dt><dd>
+<dt id="opt--bwlimit"><code>--bwlimit=RATE</code><a href="#opt--bwlimit" class="tgt"></a></dt><dd>
 <p>This option allows you to specify the maximum transfer rate for the data
 sent over the socket, specified in units per second.  The RATE value can be
 suffixed with a string to indicate a size multiplier, and may be a
-fractional value (e.g. &quot;<code>--bwlimit=1.5m</code>&quot;).  If no suffix is specified, the
+fractional value (e.g. <code>--bwlimit=1.5m</code>).  If no suffix is specified, the
 value will be assumed to be in units of 1024 bytes (as if &quot;K&quot; or &quot;KiB&quot; had
-been appended).  See the <code>--max-size</code> option for a description of all the
-available suffixes.  A value of 0 specifies no limit.</p>
+been appended).  See the <a href="#opt--max-size"><code>--max-size</code></a> option for a description of
+all the available suffixes.  A value of 0 specifies no limit.</p>
 <p>For backward-compatibility reasons, the rate limit will be rounded to the
 nearest KiB unit, so no rate smaller than 1024 bytes per second is
 possible.</p>
@@ -3016,25 +3388,26 @@ the size of the blocks that rsync writes, and tries to keep the average
 transfer rate at the requested limit.  Some burstiness may be seen where
 rsync writes out a block of data and then sleeps to bring the average rate
 into compliance.</p>
-<p>Due to the internal buffering of data, the <code>--progress</code> option may not be
-an accurate reflection on how fast the data is being sent.  This is because
-some files can show up as being rapidly sent when the data is quickly
-buffered, while other can show up as very slow when the flushing of the
-output buffer occurs.  This may be fixed in a future version.</p>
+<p>Due to the internal buffering of data, the <a href="#opt--progress"><code>--progress</code></a> option may
+not be an accurate reflection on how fast the data is being sent.  This is
+because some files can show up as being rapidly sent when the data is
+quickly buffered, while other can show up as very slow when the flushing of
+the output buffer occurs.  This may be fixed in a future version.</p>
+<p>See also <a href="#dopt--bwlimit">the daemon version of the <code>--bwlimit</code> option</a>.</p>
 </dd>
 
-<dt>`-&#8288;-&#8288;stop-after=MINS</dt><dd>
+<span id="opt--time-limit"></span><dt id="opt--stop-after"><code>--stop-after=MINS</code>, (<code>--time-limit=MINS</code>)<a href="#opt--stop-after" class="tgt"></a></dt><dd>
 <p>This option tells rsync to stop copying when the specified number of
 minutes has elapsed.</p>
-<p>Rsync also accepts an earlier version of this option: <code>--time-limit=MINS</code>.</p>
 <p>For maximal flexibility, rsync does not communicate this option to the
 remote rsync since it is usually enough that one side of the connection
 quits as specified.  This allows the option's use even when only one side
 of the connection supports it.  You can tell the remote side about the time
-limit using <code>--remote-option</code> (<code>-M</code>), should the need arise.</p>
+limit using <a href="#opt--remote-option"><code>--remote-option</code></a> (<code>-M</code>), should the need arise.</p>
+<p>The <code>--time-limit</code> version of this option is deprecated.</p>
 </dd>
 
-<dt>`-&#8288;-&#8288;stop-at=y-m-dTh:m</dt><dd>
+<dt id="opt--stop-at"><code>--stop-at=y-m-dTh:m</code><a href="#opt--stop-at" class="tgt"></a></dt><dd>
 <p>This option tells rsync to stop copying when the specified point in time
 has been reached. The date &amp; time can be fully specified in a numeric
 format of year-month-dayThour:minute (e.g. 2000-12-31T23:59) in the local
@@ -3053,26 +3426,32 @@ month at midnight, &quot;31&quot; specifies the next month where we can stop on
 remote rsync since it is usually enough that one side of the connection
 quits as specified.  This allows the option's use even when only one side
 of the connection supports it.  You can tell the remote side about the time
-limit using <code>--remote-option</code> (<code>-M</code>), should the need arise.  Do keep in
-mind that the remote host may have a different default timezone than your
-local host.</p>
+limit using <a href="#opt--remote-option"><code>--remote-option</code></a> (<code>-M</code>), should the need arise.  Do
+keep in mind that the remote host may have a different default timezone
+than your local host.</p>
 </dd>
 
-<dt><code>--write-batch=FILE</code></dt><dd>
+<dt id="opt--fsync"><code>--fsync</code><a href="#opt--fsync" class="tgt"></a></dt><dd>
+<p>Cause the receiving side to fsync each finished file.  This may slow down
+the transfer, but can help to provide peace of mind when updating critical
+files.</p>
+</dd>
+
+<dt id="opt--write-batch"><code>--write-batch=FILE</code><a href="#opt--write-batch" class="tgt"></a></dt><dd>
 <p>Record a file that can later be applied to another identical destination
-with <code>--read-batch</code>.  See the &quot;BATCH MODE&quot; section for details, and also
-the <code>--only-write-batch</code> option.</p>
+with <a href="#opt--read-batch"><code>--read-batch</code></a>.  See the &quot;BATCH MODE&quot; section for details, and
+also the <a href="#opt--only-write-batch"><code>--only-write-batch</code></a> option.</p>
 <p>This option overrides the negotiated checksum &amp; compress lists and always
 negotiates a choice based on old-school md5/md4/zlib choices.  If you want
-a more modern choice, use the <code>--checksum-choice</code> (<code>--cc</code>) and/or
-<code>--compress-choice</code> (<code>--zc</code>) options.</p>
+a more modern choice, use the <a href="#opt--checksum-choice"><code>--checksum-choice</code></a> (<code>--cc</code>) and/or
+<a href="#opt--compress-choice"><code>--compress-choice</code></a> (<code>--zc</code>) options.</p>
 </dd>
 
-<dt><code>--only-write-batch=FILE</code></dt><dd>
-<p>Works like <code>--write-batch</code>, except that no updates are made on the
+<dt id="opt--only-write-batch"><code>--only-write-batch=FILE</code><a href="#opt--only-write-batch" class="tgt"></a></dt><dd>
+<p>Works like <a href="#opt--write-batch"><code>--write-batch</code></a>, except that no updates are made on the
 destination system when creating the batch.  This lets you transport the
 changes to the destination system via some other means and then apply the
-changes via <code>--read-batch</code>.</p>
+changes via <a href="#opt--read-batch"><code>--read-batch</code></a>.</p>
 <p>Note that you can feel free to write the batch directly to some portable
 media: if this media fills to capacity before the end of the transfer, you
 can just apply that partial transfer to the destination and repeat the
@@ -3085,23 +3464,23 @@ into the batch file without having to flow over the wire to the receiver
 (when pulling, the sender is remote, and thus can't write the batch).</p>
 </dd>
 
-<dt><code>--read-batch=FILE</code></dt><dd>
+<dt id="opt--read-batch"><code>--read-batch=FILE</code><a href="#opt--read-batch" class="tgt"></a></dt><dd>
 <p>Apply all of the changes stored in FILE, a file previously generated by
-<code>--write-batch</code>.  If <u>FILE</u> is <code>-</code>, the batch data will be read from
-standard input. See the &quot;BATCH MODE&quot; section for details.</p>
+<a href="#opt--write-batch"><code>--write-batch</code></a>.  If <u>FILE</u> is <code>-</code>, the batch data will be read
+from standard input. See the &quot;BATCH MODE&quot; section for details.</p>
 </dd>
 
-<dt><code>--protocol=NUM</code></dt><dd>
+<dt id="opt--protocol"><code>--protocol=NUM</code><a href="#opt--protocol" class="tgt"></a></dt><dd>
 <p>Force an older protocol version to be used.  This is useful for creating a
 batch file that is compatible with an older version of rsync.  For
-instance, if rsync 2.6.4 is being used with the <code>--write-batch</code> option, but
-rsync 2.6.3 is what will be used to run the <code>--read-batch</code> option, you
-should use &quot;-&#8288;-&#8288;protocol=28&quot; when creating the batch file to force the older
-protocol version to be used in the batch file (assuming you can't upgrade
-the rsync on the reading system).</p>
+instance, if rsync 2.6.4 is being used with the <a href="#opt--write-batch"><code>--write-batch</code></a>
+option, but rsync 2.6.3 is what will be used to run the
+<a href="#opt--read-batch"><code>--read-batch</code></a> option, you should use &quot;-&#8288;-&#8288;protocol=28&quot; when creating
+the batch file to force the older protocol version to be used in the batch
+file (assuming you can't upgrade the rsync on the reading system).</p>
 </dd>
 
-<dt><code>--iconv=CONVERT_SPEC</code></dt><dd>
+<dt id="opt--iconv"><code>--iconv=CONVERT_SPEC</code><a href="#opt--iconv" class="tgt"></a></dt><dd>
 <p>Rsync can convert filenames between character sets using this option.
 Using a CONVERT_SPEC of &quot;.&quot; tells rsync to look up the default
 character-set via the locale setting.  Alternately, you can fully specify
@@ -3110,13 +3489,13 @@ comma in the order <code>--iconv=LOCAL,REMOTE</code>, e.g. <code>--iconv=utf8,is
 This order ensures that the option will stay the same whether you're
 pushing or pulling files.  Finally, you can specify either <code>--no-iconv</code> or
 a CONVERT_SPEC of &quot;-&#8288;&quot; to turn off any conversion.  The default setting of
-this option is site-specific, and can also be affected via the RSYNC_ICONV
-environment variable.</p>
+this option is site-specific, and can also be affected via the
+<a href="#RSYNC_ICONV"><code>RSYNC_ICONV</code></a> environment variable.</p>
 <p>For a list of what charset names your local iconv library supports, you can
 run &quot;<code>iconv --list</code>&quot;.</p>
-<p>If you specify the <code>--protect-args</code> option (<code>-s</code>), rsync will translate the
-filenames you specify on the command-line that are being sent to the remote
-host.  See also the <code>--files-from</code> option.</p>
+<p>If you specify the <a href="#opt--secluded-args"><code>--secluded-args</code></a> (<code>-s</code>) option, rsync will
+translate the filenames you specify on the command-line that are being sent
+to the remote host.  See also the <a href="#opt--files-from"><code>--files-from</code></a> option.</p>
 <p>Note that rsync does not do any conversion of names in filter files
 (including include/exclude files).  It is up to you to ensure that you're
 specifying matching rules that can match on both sides of the transfer.
@@ -3129,21 +3508,21 @@ free to specify just the local charset for a daemon transfer (e.g.
 <code>--iconv=utf8</code>).</p>
 </dd>
 
-<dt><code>--ipv4</code>, <code>-4</code> or <code>--ipv6</code>, <code>-6</code></dt><dd>
+<span id="opt-6"></span><span id="opt--ipv6"></span><span id="opt-4"></span><dt id="opt--ipv4"><code>--ipv4</code>, <code>-4</code> or <code>--ipv6</code>, <code>-6</code><a href="#opt--ipv4" class="tgt"></a></dt><dd>
 <p>Tells rsync to prefer IPv4/IPv6 when creating sockets or running ssh.  This
 affects sockets that rsync has direct control over, such as the outgoing
 socket when directly contacting an rsync daemon, as well as the forwarding
 of the <code>-4</code> or <code>-6</code> option to ssh when rsync can deduce that ssh is being
 used as the remote shell.  For other remote shells you'll need to specify
-the &quot;<code>--rsh SHELL -4</code>&quot; option directly (or whatever ipv4/ipv6 hint options
+the &quot;<code>--rsh SHELL -4</code>&quot; option directly (or whatever IPv4/IPv6 hint options
 it uses).</p>
-<p>These options also exist in the <code>--daemon</code> mode section.</p>
-<p>If rsync was complied without support for IPv6, the <code>--ipv6</code> option will
+<p>See also <a href="#dopt--ipv4">the daemon version of these options</a>.</p>
+<p>If rsync was compiled without support for IPv6, the <code>--ipv6</code> option will
 have no effect.  The <code>rsync --version</code> output will contain &quot;<code>no IPv6</code>&quot; if
 is the case.</p>
 </dd>
 
-<dt><code>--checksum-seed=NUM</code></dt><dd>
+<dt id="opt--checksum-seed"><code>--checksum-seed=NUM</code><a href="#opt--checksum-seed" class="tgt"></a></dt><dd>
 <p>Set the checksum seed to the integer NUM.  This 4 byte checksum seed is
 included in each block and MD4 file checksum calculation (the more modern
 MD5 file checksums don't use a seed).  By default the checksum seed is
@@ -3154,45 +3533,48 @@ user wants a more random checksum seed.  Setting NUM to 0 causes rsync to
 use the default of <strong>time</strong>() for checksum seed.</p>
 </dd>
 </dl>
-<h1>DAEMON OPTIONS</h1>
+<h2 id="DAEMON_OPTIONS">DAEMON OPTIONS<a href="#DAEMON_OPTIONS" class="tgt"></a></h2>
 <p>The options allowed when starting an rsync daemon are as follows:</p>
 <dl>
 
-<dt><code>--daemon</code></dt><dd>
+<dt id="dopt--daemon"><code>--daemon</code><a href="#dopt--daemon" class="tgt"></a></dt><dd>
 <p>This tells rsync that it is to run as a daemon.  The daemon you start
 running may be accessed using an rsync client using the <code>host::module</code> or
 <code>rsync://host/module/</code> syntax.</p>
 <p>If standard input is a socket then rsync will assume that it is being run
 via inetd, otherwise it will detach from the current terminal and become a
 background daemon.  The daemon will read the config file (rsyncd.conf) on
-each connect made by a client and respond to requests accordingly.  See the
-<strong>rsyncd.conf</strong>(5) man page for more details.</p>
+each connect made by a client and respond to requests accordingly.</p>
+<p>See the <a href="rsyncd.conf.5"><strong>rsyncd.conf</strong>(5)</a> manpage for more details.</p>
 </dd>
 
-<dt><code>--address=ADDRESS</code></dt><dd>
+<dt id="dopt--address"><code>--address=ADDRESS</code><a href="#dopt--address" class="tgt"></a></dt><dd>
 <p>By default rsync will bind to the wildcard address when run as a daemon
 with the <code>--daemon</code> option.  The <code>--address</code> option allows you to specify a
 specific IP address (or hostname) to bind to.  This makes virtual hosting
-possible in conjunction with the <code>--config</code> option.  See also the &quot;address&quot;
-global option in the rsyncd.conf manpage.</p>
+possible in conjunction with the <code>--config</code> option.</p>
+<p>See also the <a href="rsyncd.conf.5#address">address</a> global option in the
+rsyncd.conf manpage and the <a href="#opt--address">client version of the <code>--address</code>
+option</a>.</p>
 </dd>
 
-<dt><code>--bwlimit=RATE</code></dt><dd>
+<dt id="dopt--bwlimit"><code>--bwlimit=RATE</code><a href="#dopt--bwlimit" class="tgt"></a></dt><dd>
 <p>This option allows you to specify the maximum transfer rate for the data
 the daemon sends over the socket.  The client can still specify a smaller
-<code>--bwlimit</code> value, but no larger value will be allowed.  See the client
-version of this option (above) for some extra details.</p>
+<code>--bwlimit</code> value, but no larger value will be allowed.</p>
+<p>See the <a href="#opt--bwlimit">client version of the <code>--bwlimit</code> option</a> for some
+extra details.</p>
 </dd>
 
-<dt><code>--config=FILE</code></dt><dd>
+<dt id="dopt--config"><code>--config=FILE</code><a href="#dopt--config" class="tgt"></a></dt><dd>
 <p>This specifies an alternate config file than the default.  This is only
-relevant when <code>--daemon</code> is specified.  The default is /etc/rsyncd.conf
-unless the daemon is running over a remote shell program and the remote
-user is not the super-user; in that case the default is rsyncd.conf in the
-current directory (typically $HOME).</p>
+relevant when <a href="#dopt--daemon"><code>--daemon</code></a> is specified.  The default is
+/etc/rsyncd.conf unless the daemon is running over a remote shell program
+and the remote user is not the super-user; in that case the default is
+rsyncd.conf in the current directory (typically $HOME).</p>
 </dd>
 
-<dt><code>--dparam=OVERRIDE</code>, <code>-M</code></dt><dd>
+<span id="dopt-M"></span><dt id="dopt--dparam"><code>--dparam=OVERRIDE</code>, <code>-M</code><a href="#dopt--dparam" class="tgt"></a></dt><dd>
 <p>This option can be used to set a daemon-config parameter when starting up
 rsync in daemon mode.  It is equivalent to adding the parameter at the end
 of the global settings prior to the first module's definition.  The
@@ -3204,7 +3586,7 @@ instance:</p>
 </blockquote>
 </dd>
 
-<dt><code>--no-detach</code></dt><dd>
+<dt id="dopt--no-detach"><code>--no-detach</code><a href="#dopt--no-detach" class="tgt"></a></dt><dd>
 <p>When running as a daemon, this option instructs rsync to not detach itself
 and become a background process.  This option is required when running as a
 service on Cygwin, and may also be useful when rsync is supervised by a
@@ -3213,66 +3595,189 @@ program such as <code>daemontools</code> or AIX's <code>System Resource Controll
 option has no effect if rsync is run from inetd or sshd.</p>
 </dd>
 
-<dt><code>--port=PORT</code></dt><dd>
+<dt id="dopt--port"><code>--port=PORT</code><a href="#dopt--port" class="tgt"></a></dt><dd>
 <p>This specifies an alternate TCP port number for the daemon to listen on
-rather than the default of 873.  See also the &quot;port&quot; global option in the
-rsyncd.conf manpage.</p>
+rather than the default of 873.</p>
+<p>See also <a href="#opt--port">the client version of the <code>--port</code> option</a> and the
+<a href="rsyncd.conf.5#port">port</a> global setting in the rsyncd.conf manpage.</p>
 </dd>
 
-<dt><code>--log-file=FILE</code></dt><dd>
+<dt id="dopt--log-file"><code>--log-file=FILE</code><a href="#dopt--log-file" class="tgt"></a></dt><dd>
 <p>This option tells the rsync daemon to use the given log-file name instead
 of using the &quot;<code>log file</code>&quot; setting in the config file.</p>
+<p>See also <a href="#opt--log-file">the client version of the <code>--log-file</code> option</a>.</p>
 </dd>
 
-<dt><code>--log-file-format=FORMAT</code></dt><dd>
+<dt id="dopt--log-file-format"><code>--log-file-format=FORMAT</code><a href="#dopt--log-file-format" class="tgt"></a></dt><dd>
 <p>This option tells the rsync daemon to use the given FORMAT string instead
 of using the &quot;<code>log format</code>&quot; setting in the config file.  It also enables
 &quot;<code>transfer logging</code>&quot; unless the string is empty, in which case transfer
 logging is turned off.</p>
+<p>See also <a href="#opt--log-file-format">the client version of the <code>--log-file-format</code>
+option</a>.</p>
 </dd>
 
-<dt><code>--sockopts</code></dt><dd>
-<p>This overrides the <code>socket options</code> setting in the rsyncd.conf file and has
-the same syntax.</p>
+<dt id="dopt--sockopts"><code>--sockopts</code><a href="#dopt--sockopts" class="tgt"></a></dt><dd>
+<p>This overrides the <a href="rsyncd.conf.5#socket_options"><code>socket options</code></a>
+setting in the rsyncd.conf file and has the same syntax.</p>
+<p>See also <a href="#opt--sockopts">the client version of the <code>--sockopts</code> option</a>.</p>
 </dd>
 
-<dt><code>--verbose</code>, <code>-v</code></dt><dd>
+<span id="dopt-v"></span><dt id="dopt--verbose"><code>--verbose</code>, <code>-v</code><a href="#dopt--verbose" class="tgt"></a></dt><dd>
 <p>This option increases the amount of information the daemon logs during its
 startup phase.  After the client connects, the daemon's verbosity level
 will be controlled by the options that the client used and the
 &quot;<code>max verbosity</code>&quot; setting in the module's config section.</p>
+<p>See also <a href="#opt--verbose">the client version of the <code>--verbose</code> option</a>.</p>
 </dd>
 
-<dt><code>--ipv4</code>, <code>-4</code> or <code>--ipv6</code>, <code>-6</code></dt><dd>
+<span id="dopt-6"></span><span id="dopt--ipv6"></span><span id="dopt-4"></span><dt id="dopt--ipv4"><code>--ipv4</code>, <code>-4</code> or <code>--ipv6</code>, <code>-6</code><a href="#dopt--ipv4" class="tgt"></a></dt><dd>
 <p>Tells rsync to prefer IPv4/IPv6 when creating the incoming sockets that the
 rsync daemon will use to listen for connections.  One of these options may
 be required in older versions of Linux to work around an IPv6 bug in the
 kernel (if you see an &quot;address already in use&quot; error when nothing else is
 using the port, try specifying <code>--ipv6</code> or <code>--ipv4</code> when starting the
 daemon).</p>
-<p>These options also exist in the regular rsync options section.</p>
-<p>If rsync was complied without support for IPv6, the <code>--ipv6</code> option will
+<p>See also <a href="#opt--ipv4">the client version of these options</a>.</p>
+<p>If rsync was compiled without support for IPv6, the <code>--ipv6</code> option will
 have no effect.  The <code>rsync --version</code> output will contain &quot;<code>no IPv6</code>&quot; if
 is the case.</p>
 </dd>
 
-<dt><code>--help</code>, <code>-h</code></dt><dd>
+<span id="dopt-h"></span><dt id="dopt--help"><code>--help</code>, <code>-h</code><a href="#dopt--help" class="tgt"></a></dt><dd>
 <p>When specified after <code>--daemon</code>, print a short help page describing the
 options available for starting an rsync daemon.</p>
 </dd>
 </dl>
-<h1>FILTER RULES</h1>
-<p>The filter rules allow for flexible selection of which files to transfer
-(include) and which files to skip (exclude).  The rules either directly specify
-include/exclude patterns or they specify a way to acquire more include/exclude
-patterns (e.g. to read them from a file).</p>
-<p>As the list of files/directories to transfer is built, rsync checks each name
-to be transferred against the list of include/exclude patterns in turn, and the
-first matching pattern is acted on: if it is an exclude pattern, then that file
-is skipped; if it is an include pattern then that filename is not skipped; if
-no matching pattern is found, then the filename is not skipped.</p>
-<p>Rsync builds an ordered list of filter rules as specified on the command-line.
-Filter rules have the following syntax:</p>
+<h2 id="FILTER_RULES">FILTER RULES<a href="#FILTER_RULES" class="tgt"></a></h2>
+<p>The filter rules allow for custom control of several aspects of how files are
+handled:</p>
+<ul>
+<li>Control which files the sending side puts into the file list that describes
+the transfer hierarchy</li>
+<li>Control which files the receiving side protects from deletion when the file
+is not in the sender's file list</li>
+<li>Control which extended attribute names are skipped when copying xattrs</li>
+</ul>
+<p>The rules are either directly specified via option arguments or they can be
+read in from one or more files.  The filter-rule files can even be a part of
+the hierarchy of files being copied, affecting different parts of the tree in
+different ways.</p>
+<h3 id="SIMPLE_INCLUDE_EXCLUDE_RULES">SIMPLE INCLUDE/EXCLUDE RULES<a href="#SIMPLE_INCLUDE_EXCLUDE_RULES" class="tgt"></a></h3>
+<p>We will first cover the basics of how include &amp; exclude rules affect what files
+are transferred, ignoring any deletion side-effects.  Filter rules mainly
+affect the contents of directories that rsync is &quot;recursing&quot; into, but they can
+also affect a top-level item in the transfer that was specified as a argument.</p>
+<p>The default for any unmatched file/dir is for it to be included in the
+transfer, which puts the file/dir into the sender's file list.  The use of an
+exclude rule causes one or more matching files/dirs to be left out of the
+sender's file list.  An include rule can be used to limit the effect of an
+exclude rule that is matching too many files.</p>
+<p>The order of the rules is important because the first rule that matches is the
+one that takes effect.  Thus, if an early rule excludes a file, no include rule
+that comes after it can have any effect. This means that you must place any
+include overrides somewhere prior to the exclude that it is intended to limit.</p>
+<p>When a directory is excluded, all its contents and sub-contents are also
+excluded.  The sender doesn't scan through any of it at all, which can save a
+lot of time when skipping large unneeded sub-trees.</p>
+<p>It is also important to understand that the include/exclude rules are applied
+to every file and directory that the sender is recursing into. Thus, if you
+want a particular deep file to be included, you have to make sure that none of
+the directories that must be traversed on the way down to that file are
+excluded or else the file will never be discovered to be included. As an
+example, if the directory &quot;<code>a/path</code>&quot; was given as a transfer argument and you
+want to ensure that the file &quot;<code>a/path/down/deep/wanted.txt</code>&quot; is a part of the
+transfer, then the sender must not exclude the directories &quot;<code>a/path</code>&quot;,
+&quot;<code>a/path/down</code>&quot;, or &quot;<code>a/path/down/deep</code>&quot; as it makes it way scanning through
+the file tree.</p>
+<p>When you are working on the rules, it can be helpful to ask rsync to tell you
+what is being excluded/included and why.  Specifying <code>--debug=FILTER</code> or (when
+pulling files) <code>-M--debug=FILTER</code> turns on level 1 of the FILTER debug
+information that will output a message any time that a file or directory is
+included or excluded and which rule it matched.  Beginning in 3.2.4 it will
+also warn if a filter rule has trailing whitespace, since an exclude of &quot;foo&nbsp;&quot;
+(with a trailing space) will not exclude a file named &quot;foo&quot;.</p>
+<p>Exclude and include rules can specify wildcard <a href="#PATTERN_MATCHING_RULES">PATTERN MATCHING RULES</a>
+(similar to shell wildcards) that allow you to match things like a file suffix
+or a portion of a filename.</p>
+<p>A rule can be limited to only affecting a directory by putting a trailing slash
+onto the filename.</p>
+<h3 id="SIMPLE_INCLUDE_EXCLUDE_EXAMPLE">SIMPLE INCLUDE/EXCLUDE EXAMPLE<a href="#SIMPLE_INCLUDE_EXCLUDE_EXAMPLE" class="tgt"></a></h3>
+<p>With the following file tree created on the sending side:</p>
+<blockquote>
+<pre><code>mkdir x/
+touch x/file.txt
+mkdir x/y/
+touch x/y/file.txt
+touch x/y/zzz.txt
+mkdir x/z/
+touch x/z/file.txt
+</code></pre>
+</blockquote>
+<p>Then the following rsync command will transfer the file &quot;<code>x/y/file.txt</code>&quot; and
+the directories needed to hold it, resulting in the path &quot;<code>/tmp/x/y/file.txt</code>&quot;
+existing on the remote host:</p>
+<blockquote>
+<pre><code>rsync -ai -f'+ x/' -f'+ x/y/' -f'+ x/y/file.txt' -f'- *' x host:/tmp/
+</code></pre>
+</blockquote>
+<p>Aside: this copy could also have been accomplished using the <a href="#opt-R"><code>-R</code></a>
+option (though the 2 commands behave differently if deletions are enabled):</p>
+<blockquote>
+<pre><code>rsync -aiR x/y/file.txt host:/tmp/
+</code></pre>
+</blockquote>
+<p>The following command does not need an include of the &quot;x&quot; directory because it
+is not a part of the transfer (note the traililng slash).  Running this command
+would copy just &quot;<code>/tmp/x/file.txt</code>&quot; because the &quot;y&quot; and &quot;z&quot; dirs get excluded:</p>
+<blockquote>
+<pre><code>rsync -ai -f'+ file.txt' -f'- *' x/ host:/tmp/x/
+</code></pre>
+</blockquote>
+<p>This command would omit the zzz.txt file while copying &quot;x&quot; and everything else
+it contains:</p>
+<blockquote>
+<pre><code>rsync -ai -f'- zzz.txt' x host:/tmp/
+</code></pre>
+</blockquote>
+<h3 id="FILTER_RULES_WHEN_DELETING">FILTER RULES WHEN DELETING<a href="#FILTER_RULES_WHEN_DELETING" class="tgt"></a></h3>
+<p>By default the include &amp; exclude filter rules affect both the sender
+(as it creates its file list)
+and the receiver (as it creates its file lists for calculating deletions).  If
+no delete option is in effect, the receiver skips creating the delete-related
+file lists.  This two-sided default can be manually overridden so that you are
+only specifying sender rules or receiver rules, as described in the <a href="#FILTER_RULES_IN_DEPTH">FILTER
+RULES IN DEPTH</a> section.</p>
+<p>When deleting, an exclude protects a file from being removed on the receiving
+side while an include overrides that protection (putting the file at risk of
+deletion). The default is for a file to be at risk&nbsp;-&#8288;-&#8288; its safety depends on it
+matching a corresponding file from the sender.</p>
+<p>An example of the two-sided exclude effect can be illustrated by the copying of
+a C development directory between 2 systems.  When doing a touch-up copy, you
+might want to skip copying the built executable and the <code>.o</code> files (sender
+hide) so that the receiving side can build their own and not lose any object
+files that are already correct (receiver protect).  For instance:</p>
+<blockquote>
+<pre><code>rsync -ai --del -f'- *.o' -f'- cmd' src host:/dest/
+</code></pre>
+</blockquote>
+<p>Note that using <code>-f'-p *.o'</code> is even better than <code>-f'- *.o'</code> if there is a
+chance that the directory structure may have changed.  The &quot;p&quot; modifier is
+discussed in <a href="#FILTER_RULE_MODIFIERS">FILTER RULE MODIFIERS</a>.</p>
+<p>One final note, if your shell doesn't mind unexpanded wildcards, you could
+simplify the typing of the filter options by using an underscore in place of
+the space and leaving off the quotes.  For instance, <code>-f -_*.o -f -_cmd</code> (and
+similar) could be used instead of the filter options above.</p>
+<h3 id="FILTER_RULES_IN_DEPTH">FILTER RULES IN DEPTH<a href="#FILTER_RULES_IN_DEPTH" class="tgt"></a></h3>
+<p>Rsync supports old-style include/exclude rules and new-style filter rules.  The
+older rules are specified using <a href="#opt--include"><code>--include</code></a> and <a href="#opt--exclude"><code>--exclude</code></a> as
+well as the <a href="#opt--include-from"><code>--include-from</code></a> and <a href="#opt--exclude-from"><code>--exclude-from</code></a>. These are
+limited in behavior but they don't require a &quot;-&#8288;&quot; or &quot;+&quot; prefix.  An old-style
+exclude rule is turned into a &quot;<code>- name</code>&quot; filter rule (with no modifiers) and an
+old-style include rule is turned into a &quot;<code>+ name</code>&quot; filter rule (with no
+modifiers).</p>
+<p>Rsync builds an ordered list of filter rules as specified on the command-line
+and/or read-in from files.  New style filter rules have the following syntax:</p>
 <blockquote>
 <pre><code>RULE [PATTERN_OR_FILENAME]
 RULE,MODIFIERS [PATTERN_OR_FILENAME]
@@ -3281,165 +3786,139 @@ RULE,MODIFIERS [PATTERN_OR_FILENAME]
 <p>You have your choice of using either short or long RULE names, as described
 below.  If you use a short-named rule, the ',' separating the RULE from the
 MODIFIERS is optional.  The PATTERN or FILENAME that follows (when present)
-must come after either a single space or an underscore (_).  Here are the
-available rule prefixes:</p>
+must come after either a single space or an underscore (_). Any additional
+spaces and/or underscores are considered to be a part of the pattern name.
+Here are the available rule prefixes:</p>
 <dl>
-<dt><code>exclude, '-'</code></dt><dd> specifies an exclude pattern.</dd>
-<dt><code>include, '+'</code></dt><dd> specifies an include pattern.</dd>
-<dt><code>merge, '.'</code></dt><dd> specifies a merge-file to read for more rules.</dd>
-<dt><code>dir-merge, ':'</code></dt><dd> specifies a per-directory merge-file.</dd>
-<dt><code>hide, 'H'</code></dt><dd> specifies a pattern for hiding files from the transfer.</dd>
-<dt><code>show, 'S'</code></dt><dd> files that match the pattern are not hidden.</dd>
-<dt><code>protect, 'P'</code></dt><dd> specifies a pattern for protecting files from deletion.</dd>
-<dt><code>risk, 'R'</code></dt><dd> files that match the pattern are not protected.</dd>
+<dt><code>exclude, '-'</code></dt><dd> specifies an exclude pattern that (by default) is both a
+<code>hide</code> and a <code>protect</code>.</dd>
+<dt><code>include, '+'</code></dt><dd> specifies an include pattern that (by default) is both a
+<code>show</code> and a <code>risk</code>.</dd>
+<dt><code>merge, '.'</code></dt><dd> specifies a merge-file on the client side to read for more
+rules.</dd>
+<dt><code>dir-merge, ':'</code></dt><dd> specifies a per-directory merge-file.  Using this kind of
+filter rule requires that you trust the sending side's filter checking, so
+it has the side-effect mentioned under the <a href="#opt--trust-sender"><code>--trust-sender</code></a> option.</dd>
+<dt><code>hide, 'H'</code></dt><dd> specifies a pattern for hiding files from the transfer.
+Equivalent to a sender-only exclude, so <code>-f'H foo'</code> could also be specified
+as <code>-f'-s foo'</code>.</dd>
+<dt><code>show, 'S'</code></dt><dd> files that match the pattern are not hidden. Equivalent to a
+sender-only include, so <code>-f'S foo'</code> could also be specified as <code>-f'+s foo'</code>.</dd>
+<dt><code>protect, 'P'</code></dt><dd> specifies a pattern for protecting files from deletion.
+Equivalent to a receiver-only exclude, so <code>-f'P foo'</code> could also be
+specified as <code>-f'-r foo'</code>.</dd>
+<dt><code>risk, 'R'</code></dt><dd> files that match the pattern are not protected. Equivalent to a
+receiver-only include, so <code>-f'R foo'</code> could also be specified as <code>-f'+r foo'</code>.</dd>
 <dt><code>clear, '!'</code></dt><dd> clears the current include/exclude list (takes no arg)</dd>
 </dl>
-<p>When rules are being read from a file, empty lines are ignored, as are comment
-lines that start with a &quot;#&quot;.</p>
-<p>Note that the <code>--include</code> &amp; <code>--exclude</code> command-line options do not allow the
-full range of rule parsing as described above&nbsp;-&#8288;-&#8288; they only allow the
-specification of include / exclude patterns plus a &quot;<code>!</code>&quot; token to clear the
-list (and the normal comment parsing when rules are read from a file).  If a
-pattern does not begin with &quot;<code>- </code>&quot; (dash, space) or &quot;<code>+ </code>&quot; (plus, space), then
-the rule will be interpreted as if &quot;<code>+ </code>&quot; (for an include option) or &quot;<code>- </code>&quot;
-(for an exclude option) were prefixed to the string.  A <code>--filter</code> option, on
-the other hand, must always contain either a short or long rule name at the
-start of the rule.</p>
-<p>Note also that the <code>--filter</code>, <code>--include</code>, and <code>--exclude</code> options take one
-rule/pattern each.  To add multiple ones, you can repeat the options on the
-command-line, use the merge-file syntax of the <code>--filter</code> option, or the
-<code>--include-from</code> / <code>--exclude-from</code> options.</p>
-<h1>INCLUDE/EXCLUDE PATTERN RULES</h1>
-<p>You can include and exclude files by specifying patterns using the &quot;+&quot;, &quot;-&#8288;&quot;,
-etc. filter rules (as introduced in the FILTER RULES section above).  The
-include/exclude rules each specify a pattern that is matched against the names
-of the files that are going to be transferred.  These patterns can take several
-forms:</p>
+<p>When rules are being read from a file (using merge or dir-merge), empty lines
+are ignored, as are whole-line comments that start with a '<code>#</code>' (filename rules
+that contain a hash character are unaffected).</p>
+<p>Note also that the <a href="#opt--filter"><code>--filter</code></a>, <a href="#opt--include"><code>--include</code></a>, and
+<a href="#opt--exclude"><code>--exclude</code></a> options take one rule/pattern each.  To add multiple ones,
+you can repeat the options on the command-line, use the merge-file syntax of
+the <a href="#opt--filter"><code>--filter</code></a> option, or the <a href="#opt--include-from"><code>--include-from</code></a> /
+<a href="#opt--exclude-from"><code>--exclude-from</code></a> options.</p>
+<h3 id="PATTERN_MATCHING_RULES">PATTERN MATCHING RULES<a href="#PATTERN_MATCHING_RULES" class="tgt"></a></h3>
+<p>Most of the rules mentioned above take an argument that specifies what the rule
+should match.  If rsync is recursing through a directory hierarchy, keep in
+mind that each pattern is matched against the name of every directory in the
+descent path as rsync finds the filenames to send.</p>
+<p>The matching rules for the pattern argument take several forms:</p>
 <ul>
-<li>if the pattern starts with a <code>/</code> then it is anchored to a particular spot in
-the hierarchy of files, otherwise it is matched against the end of the
-pathname.  This is similar to a leading <code>^</code> in regular expressions.  Thus
-<code>/foo</code> would match a name of &quot;foo&quot; at either the &quot;root of the transfer&quot; (for
-a global rule) or in the merge-file's directory (for a per-directory rule).
-An unqualified <code>foo</code> would match a name of &quot;foo&quot; anywhere in the tree because
-the algorithm is applied recursively from the top down; it behaves as if each
-path component gets a turn at being the end of the filename.  Even the
-unanchored &quot;sub/foo&quot; would match at any point in the hierarchy where a &quot;foo&quot;
-was found within a directory named &quot;sub&quot;.  See the section on ANCHORING
-INCLUDE/EXCLUDE PATTERNS for a full discussion of how to specify a pattern
-that matches at the root of the transfer.</li>
-<li>if the pattern ends with a <code>/</code> then it will only match a directory, not a
-regular file, symlink, or device.</li>
-<li>rsync chooses between doing a simple string match and wildcard matching by
-checking if the pattern contains one of these three wildcard characters:
-'<code>*</code>', '<code>?</code>', and '<code>[</code>' .</li>
-<li>a '<code>*</code>' matches any path component, but it stops at slashes.</li>
-<li>use '<code>**</code>' to match anything, including slashes.</li>
-<li>a '<code>?</code>' matches any character except a slash (<code>/</code>).</li>
-<li>a '<code>[</code>' introduces a character class, such as <code>[a-z]</code> or <code>[[:alpha:]]</code>.</li>
-<li>in a wildcard pattern, a backslash can be used to escape a wildcard
-character, but it is matched literally when no wildcards are present.  This
-means that there is an extra level of backslash removal when a pattern
-contains wildcard characters compared to a pattern that has none.  e.g. if
-you add a wildcard to &quot;<code>foo\bar</code>&quot; (which matches the backslash) you would
-need to use &quot;<code>foo\\bar*</code>&quot; to avoid the &quot;<code>\b</code>&quot; becoming just &quot;b&quot;.</li>
-<li>if the pattern contains a <code>/</code> (not counting a trailing /) or a &quot;<code>**</code>&quot;, then it
-is matched against the full pathname, including any leading directories.  If
-the pattern doesn't contain a <code>/</code> or a &quot;<code>**</code>&quot;, then it is matched only against
-the final component of the filename. (Remember that the algorithm is applied
-recursively so &quot;full filename&quot; can actually be any portion of a path from the
-starting directory on down.)</li>
-<li>a trailing &quot;<code>dir_name/***</code>&quot; will match both the directory (as if &quot;dir_name/&quot;
+<li>If a pattern contains a <code>/</code> (not counting a trailing slash) or a &quot;<code>**</code>&quot;
+(which can match a slash), then the pattern is matched against the full
+pathname, including any leading directories within the transfer.  If the
+pattern doesn't contain a (non-trailing) <code>/</code> or a &quot;<code>**</code>&quot;, then it is matched
+only against the final component of the filename or pathname. For example,
+<code>foo</code> means that the final path component must be &quot;foo&quot; while <code>foo/bar</code> would
+match the last 2 elements of the path (as long as both elements are within
+the transfer).</li>
+<li>A pattern that ends with a <code>/</code> only matches a directory, not a regular file,
+symlink, or device.</li>
+<li>A pattern that starts with a <code>/</code> is anchored to the start of the transfer
+path instead of the end.  For example, <code>/foo/**</code> or <code>/foo/bar/**</code> match only
+leading elements in the path.  If the rule is read from a per-directory
+filter file, the transfer path being matched will begin at the level of the
+filter file instead of the top of the transfer.  See the section on
+<a href="#ANCHORING_INCLUDE_EXCLUDE_PATTERNS">ANCHORING INCLUDE/EXCLUDE PATTERNS</a> for a full discussion of how to
+specify a pattern that matches at the root of the transfer.</li>
+</ul>
+<p>Rsync chooses between doing a simple string match and wildcard matching by
+checking if the pattern contains one of these three wildcard characters: '<code>*</code>',
+'<code>?</code>', and '<code>[</code>' :</p>
+<ul>
+<li>a '<code>?</code>' matches any single character except a slash (<code>/</code>).</li>
+<li>a '<code>*</code>' matches zero or more non-slash characters.</li>
+<li>a '<code>**</code>' matches zero or more characters, including slashes.</li>
+<li>a '<code>[</code>' introduces a character class, such as <code>[a-z]</code> or <code>[[:alpha:]]</code>, that
+must match one character.</li>
+<li>a trailing <code>***</code> in the pattern is a shorthand that allows you to match a
+directory and all its contents using a single rule.  For example, specifying
+&quot;<code>dir_name/***</code>&quot; will match both the &quot;dir_name&quot; directory (as if &quot;<code>dir_name/</code>&quot;
 had been specified) and everything in the directory (as if &quot;<code>dir_name/**</code>&quot;
-had been specified).  This behavior was added in version 2.6.7.</li>
+had been specified).</li>
+<li>a backslash can be used to escape a wildcard character, but it is only
+interpreted as an escape character if at least one wildcard character is
+present in the match pattern. For instance, the pattern &quot;<code>foo\bar</code>&quot; matches
+that single backslash literally, while the pattern &quot;<code>foo\bar*</code>&quot; would need to
+be changed to &quot;<code>foo\\bar*</code>&quot; to avoid the &quot;<code>\b</code>&quot; becoming just &quot;b&quot;.</li>
 </ul>
-<p>Note that, when using the <code>--recursive</code> (<code>-r</code>) option (which is implied by
-<code>-a</code>), every subdir component of every path is visited left to right, with each
-directory having a chance for exclusion before its content.  In this way
-include/exclude patterns are applied recursively to the pathname of each node
-in the filesystem's tree (those inside the transfer).  The exclude patterns
-short-circuit the directory traversal stage as rsync finds the files to send.</p>
-<p>For instance, to include &quot;<code>/foo/bar/baz</code>&quot;, the directories &quot;<code>/foo</code>&quot; and &quot;<code>/foo/bar</code>&quot;
-must not be excluded.  Excluding one of those parent directories prevents the
-examination of its content, cutting off rsync's recursion into those paths and
-rendering the include for &quot;<code>/foo/bar/baz</code>&quot; ineffectual (since rsync can't match
-something it never sees in the cut-off section of the directory hierarchy).</p>
-<p>The concept path exclusion is particularly important when using a trailing '<code>*</code>'
-rule.  For instance, this won't work:</p>
-<blockquote>
-<pre><code>+ /some/path/this-file-will-not-be-found
-+ /file-is-included
-- *
-</code></pre>
-</blockquote>
-<p>This fails because the parent directory &quot;some&quot; is excluded by the '<code>*</code>' rule, so
-rsync never visits any of the files in the &quot;some&quot; or &quot;some/path&quot; directories.
-One solution is to ask for all directories in the hierarchy to be included by
-using a single rule: &quot;<code>+ */</code>&quot; (put it somewhere before the &quot;<code>- *</code>&quot; rule), and
-perhaps use the <code>--prune-empty-dirs</code> option.  Another solution is to add
-specific include rules for all the parent dirs that need to be visited.  For
-instance, this set of rules works fine:</p>
-<blockquote>
-<pre><code>+ /some/
-+ /some/path/
-+ /some/path/this-file-is-found
-+ /file-also-included
-- *
-</code></pre>
-</blockquote>
 <p>Here are some examples of exclude/include matching:</p>
 <ul>
-<li>&quot;<code>- *.o</code>&quot; would exclude all names matching <code>*.o</code></li>
-<li>&quot;<code>- /foo</code>&quot; would exclude a file (or directory) named foo in the transfer-root
-directory</li>
-<li>&quot;<code>- foo/</code>&quot; would exclude any directory named foo</li>
-<li>&quot;<code>- /foo/*/bar</code>&quot; would exclude any file named bar which is at two levels
-below a directory named foo in the transfer-root directory</li>
-<li>&quot;<code>- /foo/**/bar</code>&quot; would exclude any file named bar two or more levels below a
-directory named foo in the transfer-root directory</li>
-<li>The combination of &quot;<code>+ */</code>&quot;, &quot;<code>+ *.c</code>&quot;, and &quot;<code>- *</code>&quot; would include all
-directories and C source files but nothing else (see also the
-<code>--prune-empty-dirs</code> option)</li>
-<li>The combination of &quot;<code>+ foo/</code>&quot;, &quot;<code>+ foo/bar.c</code>&quot;, and &quot;<code>- *</code>&quot; would include
-only the foo directory and foo/bar.c (the foo directory must be explicitly
-included or it would be excluded by the &quot;<code>*</code>&quot;)</li>
+<li>Option <code>-f'- *.o'</code> would exclude all filenames ending with <code>.o</code></li>
+<li>Option <code>-f'- /foo'</code> would exclude a file (or directory) named foo in the
+transfer-root directory</li>
+<li>Option <code>-f'- foo/'</code> would exclude any directory named foo</li>
+<li>Option <code>-f'- foo/*/bar'</code> would exclude any file/dir named bar which is at two
+levels below a directory named foo (if foo is in the transfer)</li>
+<li>Option <code>-f'- /foo/**/bar'</code> would exclude any file/dir named bar that was two
+or more levels below a top-level directory named foo (note that /foo/bar is
+<strong>not</strong> excluded by this)</li>
+<li>Options <code>-f'+ */' -f'+ *.c' -f'- *'</code> would include all directories and .c
+source files but nothing else</li>
+<li>Options <code>-f'+ foo/' -f'+ foo/bar.c' -f'- *'</code> would include only the foo
+directory and foo/bar.c (the foo directory must be explicitly included or it
+would be excluded by the &quot;<code>- *</code>&quot;)</li>
 </ul>
-<p>The following modifiers are accepted after a &quot;<code>+</code>&quot; or &quot;<code>-</code>&quot;:</p>
+<h3 id="FILTER_RULE_MODIFIERS">FILTER RULE MODIFIERS<a href="#FILTER_RULE_MODIFIERS" class="tgt"></a></h3>
+<p>The following modifiers are accepted after an include (+) or exclude (-&#8288;) rule:</p>
 <ul>
 <li>A <code>/</code> specifies that the include/exclude rule should be matched against the
-absolute pathname of the current item.  For example, &quot;<code>-/ /etc/passwd</code>&quot; would
-exclude the passwd file any time the transfer was sending files from the
-&quot;/etc&quot; directory, and &quot;-&#8288;/ subdir/foo&quot; would always exclude &quot;foo&quot; when it is
-in a dir named &quot;subdir&quot;, even if &quot;foo&quot; is at the root of the current
+absolute pathname of the current item.  For example, <code>-f'-/ /etc/passwd'</code>
+would exclude the passwd file any time the transfer was sending files from
+the &quot;/etc&quot; directory, and &quot;-&#8288;/ subdir/foo&quot; would always exclude &quot;foo&quot; when it
+is in a dir named &quot;subdir&quot;, even if &quot;foo&quot; is at the root of the current
 transfer.</li>
 <li>A <code>!</code> specifies that the include/exclude should take effect if the pattern
-fails to match.  For instance, &quot;<code>-! */</code>&quot; would exclude all non-directories.</li>
+fails to match.  For instance, <code>-f'-! */'</code> would exclude all non-directories.</li>
 <li>A <code>C</code> is used to indicate that all the global CVS-exclude rules should be
 inserted as excludes in place of the &quot;-&#8288;C&quot;.  No arg should follow.</li>
 <li>An <code>s</code> is used to indicate that the rule applies to the sending side.  When a
-rule affects the sending side, it prevents files from being transferred.  The
-default is for a rule to affect both sides unless <code>--delete-excluded</code> was
-specified, in which case default rules become sender-side only.  See also the
-hide (H) and show (S) rules, which are an alternate way to specify
-sending-side includes/excludes.</li>
+rule affects the sending side, it affects what files are put into the
+sender's file list.  The default is for a rule to affect both sides unless
+<a href="#opt--delete-excluded"><code>--delete-excluded</code></a> was specified, in which case default rules become
+sender-side only.  See also the hide (H) and show (S) rules, which are an
+alternate way to specify sending-side includes/excludes.</li>
 <li>An <code>r</code> is used to indicate that the rule applies to the receiving side.  When
 a rule affects the receiving side, it prevents files from being deleted.  See
 the <code>s</code> modifier for more info.  See also the protect (P) and risk (R) rules,
 which are an alternate way to specify receiver-side includes/excludes.</li>
 <li>A <code>p</code> indicates that a rule is perishable, meaning that it is ignored in
-directories that are being deleted.  For instance, the <code>-C</code> option's default
-rules that exclude things like &quot;CVS&quot; and &quot;<code>*.o</code>&quot; are marked as perishable,
-and will not prevent a directory that was removed on the source from being
-deleted on the destination.</li>
+directories that are being deleted.  For instance, the
+<a href="#opt--cvs-exclude"><code>--cvs-exclude</code></a> (<code>-C</code>) option's default rules that exclude things
+like &quot;CVS&quot; and &quot;<code>*.o</code>&quot; are marked as perishable, and will not prevent a
+directory that was removed on the source from being deleted on the
+destination.</li>
 <li>An <code>x</code> indicates that a rule affects xattr names in xattr copy/delete
 operations (and is thus ignored when matching file/dir names).  If no
 xattr-matching rules are specified, a default xattr filtering rule is used
-(see the <code>--xattrs</code> option).</li>
+(see the <a href="#opt--xattrs"><code>--xattrs</code></a> option).</li>
 </ul>
-<h1>MERGE-FILE FILTER RULES</h1>
+<h3 id="MERGE-FILE_FILTER_RULES">MERGE-FILE FILTER RULES<a href="#MERGE-FILE_FILTER_RULES" class="tgt"></a></h3>
 <p>You can merge whole files into your filter rules by specifying either a merge
-(.) or a dir-merge (:) filter rule (as introduced in the FILTER RULES section
-above).</p>
+(.) or a dir-merge (:) filter rule (as introduced in the <a href="#FILTER_RULES">FILTER RULES</a>
+section above).</p>
 <p>There are two kinds of merged files&nbsp;-&#8288;-&#8288; single-instance ('.') and per-directory
 (':').  A single-instance merge file is read one time, and its rules are
 incorporated into the filter list in the place of the &quot;.&quot; rule.  For
@@ -3449,7 +3928,7 @@ list of inherited rules.  These per-directory rule files must be created on the
 sending side because it is the sending side that is being scanned for the
 available files to transfer.  These rule files may also need to be transferred
 to the receiving side if you want them to affect what files don't get deleted
-(see PER-DIRECTORY RULES AND DELETE below).</p>
+(see <a href="#PER-DIRECTORY_RULES_AND_DELETE">PER-DIRECTORY RULES AND DELETE</a> below).</p>
 <p>Some examples:</p>
 <blockquote>
 <pre><code>merge /etc/rsync/default.rules
@@ -3518,7 +3997,7 @@ transfer).</p>
 <p>If a per-directory merge-file is specified with a path that is a parent
 directory of the first transfer directory, rsync will scan all the parent dirs
 from that starting point to the transfer directory for the indicated
-per-directory file.  For instance, here is a common filter (see <code>-F</code>):</p>
+per-directory file.  For instance, here is a common filter (see <a href="#opt-F"><code>-F</code></a>):</p>
 <blockquote>
 <pre><code>--filter=': /.rsync-filter'
 </code></pre>
@@ -3542,11 +4021,11 @@ the &quot;.rsync-filter&quot; files in each directory that is a part of the tran
 <p>If you want to include the contents of a &quot;.cvsignore&quot; in your patterns, you
 should use the rule &quot;:C&quot;, which creates a dir-merge of the .cvsignore file, but
 parsed in a CVS-compatible manner.  You can use this to affect where the
-<code>--cvs-exclude</code> (<code>-C</code>) option's inclusion of the per-directory .cvsignore file
-gets placed into your rules by putting the &quot;:C&quot; wherever you like in your
-filter rules.  Without this, rsync would add the dir-merge rule for the
-.cvsignore file at the end of all your other rules (giving it a lower priority
-than your command-line rules).  For example:</p>
+<a href="#opt--cvs-exclude"><code>--cvs-exclude</code></a> (<code>-C</code>) option's inclusion of the per-directory
+.cvsignore file gets placed into your rules by putting the &quot;:C&quot; wherever you
+like in your filter rules.  Without this, rsync would add the dir-merge rule
+for the .cvsignore file at the end of all your other rules (giving it a lower
+priority than your command-line rules).  For example:</p>
 <blockquote>
 <pre><code>cat &lt;&lt;EOT | rsync -avC --filter='. -' a/ b
 + foo.o
@@ -3564,13 +4043,13 @@ exclude rules (i.e. the default list of exclusions, the contents of
 $HOME/.cvsignore, and the value of $CVSIGNORE) you should omit the <code>-C</code>
 command-line option and instead insert a &quot;-&#8288;C&quot; rule into your filter rules; e.g.
 &quot;<code>--filter=-C</code>&quot;.</p>
-<h1>LIST-CLEARING FILTER RULE</h1>
+<h3 id="LIST-CLEARING_FILTER_RULE">LIST-CLEARING FILTER RULE<a href="#LIST-CLEARING_FILTER_RULE" class="tgt"></a></h3>
 <p>You can clear the current include/exclude list by using the &quot;!&quot; filter rule (as
-introduced in the FILTER RULES section above).  The &quot;current&quot; list is either
+introduced in the <a href="#FILTER_RULES">FILTER RULES</a> section above).  The &quot;current&quot; list is either
 the global list of rules (if the rule is encountered while parsing the filter
 options) or a set of per-directory rules (which are inherited in their own
 sub-list, so a subdirectory can use this to clear out the parent's rules).</p>
-<h1>ANCHORING INCLUDE/EXCLUDE PATTERNS</h1>
+<h3 id="ANCHORING_INCLUDE_EXCLUDE_PATTERNS">ANCHORING INCLUDE/EXCLUDE PATTERNS<a href="#ANCHORING_INCLUDE_EXCLUDE_PATTERNS" class="tgt"></a></h3>
 <p>As mentioned earlier, global include/exclude patterns are anchored at the &quot;root
 of the transfer&quot; (as opposed to per-directory patterns, which are anchored at
 the merge-file's directory).  If you think of the transfer as a subtree of
@@ -3578,10 +4057,10 @@ names that are being sent from sender to receiver, the transfer-root is where
 the tree starts to be duplicated in the destination directory.  This root
 governs where patterns that start with a / match.</p>
 <p>Because the matching is relative to the transfer-root, changing the trailing
-slash on a source path or changing your use of the <code>--relative</code> option affects
-the path you need to use in your matching (in addition to changing how much of
-the file tree is duplicated on the destination host).  The following examples
-demonstrate this.</p>
+slash on a source path or changing your use of the <a href="#opt--relative"><code>--relative</code></a> option
+affects the path you need to use in your matching (in addition to changing how
+much of the file tree is duplicated on the destination host).  The following
+examples demonstrate this.</p>
 <p>Let's say that we want to match two source files, one with an absolute
 path of &quot;/home/me/foo/bar&quot;, and one with a path of &quot;/home/you/bar/baz&quot;.
 Here is how the various command choices differ for a 2-source transfer:</p>
@@ -3617,10 +4096,10 @@ Target file: /dest/me/foo/bar
 Target file: /dest/you/bar/baz
 </code></pre>
 </blockquote>
-<p>The easiest way to see what name you should filter is to just
-look at the output when using <code>--verbose</code> and put a / in front of the name
-(use the <code>--dry-run</code> option if you're not yet ready to copy any files).</p>
-<h1>PER-DIRECTORY RULES AND DELETE</h1>
+<p>The easiest way to see what name you should filter is to just look at the
+output when using <a href="#opt--verbose"><code>--verbose</code></a> and put a / in front of the name (use the
+<code>--dry-run</code> option if you're not yet ready to copy any files).</p>
+<h3 id="PER-DIRECTORY_RULES_AND_DELETE">PER-DIRECTORY RULES AND DELETE<a href="#PER-DIRECTORY_RULES_AND_DELETE" class="tgt"></a></h3>
 <p>Without a delete option, per-directory rules are only relevant on the sending
 side, so you can feel free to exclude the merge files themselves without
 affecting the transfer.  To make this easy, the 'e' modifier adds this exclude
@@ -3633,9 +4112,9 @@ rsync -av --filter=':e .excl' host:src/dir /dest
 <p>However, if you want to do a delete on the receiving side AND you want some
 files to be excluded from being deleted, you'll need to be sure that the
 receiving side knows what files to exclude.  The easiest way is to include the
-per-directory merge files in the transfer and use <code>--delete-after</code>, because
-this ensures that the receiving side gets all the same exclude rules as the
-sending side before it tries to delete anything:</p>
+per-directory merge files in the transfer and use <a href="#opt--delete-after"><code>--delete-after</code></a>,
+because this ensures that the receiving side gets all the same exclude rules as
+the sending side before it tries to delete anything:</p>
 <blockquote>
 <pre><code>rsync -avF --delete-after host:src/dir /dest
 </code></pre>
@@ -3666,7 +4145,33 @@ one of these commands:</p>
 rsync -avFF --delete host:src/dir /dest
 </code></pre>
 </blockquote>
-<h1>BATCH MODE</h1>
+<h2 id="TRANSFER_RULES">TRANSFER RULES<a href="#TRANSFER_RULES" class="tgt"></a></h2>
+<p>In addition to the <a href="#FILTER_RULES">FILTER RULES</a> that affect the recursive file scans that
+generate the file list on the sending and (when deleting) receiving sides,
+there are transfer rules. These rules affect which files the generator decides
+need to be transferred without the side effects of an exclude filter rule.
+Transfer rules affect only files and never directories.</p>
+<p>Because a transfer rule does not affect what goes into the sender's (and
+receiver's) file list, it cannot have any effect on which files get deleted on
+the receiving side.  For example, if the file &quot;foo&quot; is present in the sender's
+list but its size is such that it is omitted due to a transfer rule, the
+receiving side does not request the file.  However, its presence in the file
+list means that a delete pass will not remove a matching file named &quot;foo&quot; on
+the receiving side.  On the other hand, a server-side exclude (hide) of the
+file &quot;foo&quot; leaves the file out of the server's file list, and absent a
+receiver-side exclude (protect) the receiver will remove a matching file named
+&quot;foo&quot; if deletions are requested.</p>
+<p>Given that the files are still in the sender's file list, the
+<a href="#opt--prune-empty-dirs"><code>--prune-empty-dirs</code></a> option will not judge a directory as being empty
+even if it contains only files that the transfer rules omitted.</p>
+<p>Similarly, a transfer rule does not have any extra effect on which files are
+deleted on the receiving side, so setting a maximum file size for the transfer
+does not prevent big files from being deleted.</p>
+<p>Examples of transfer rules include the default &quot;quick check&quot; algorithm (which
+compares size &amp; modify time), the <a href="#opt--update"><code>--update</code></a> option, the
+<a href="#opt--max-size"><code>--max-size</code></a> option, the <a href="#opt--ignore-non-existing"><code>--ignore-non-existing</code></a> option, and a
+few others.</p>
+<h2 id="BATCH_MODE">BATCH MODE<a href="#BATCH_MODE" class="tgt"></a></h2>
 <p>Batch mode can be used to apply the same set of updates to many identical
 systems.  Suppose one has a tree which is replicated on a number of hosts.  Now
 suppose some changes have been made to this source tree and those changes need
@@ -3717,10 +4222,10 @@ syntax or rsync daemon syntax, as desired.</li>
 options when running the read-batch command on the remote host.</li>
 <li>The second example reads the batch data via standard input so that the batch
 file doesn't need to be copied to the remote machine first.  This example
-avoids the foo.sh script because it needed to use a modified <code>--read-batch</code>
-option, but you could edit the script file if you wished to make use of it
-(just be sure that no other option is trying to use standard input, such as
-the &quot;<code>--exclude-from=-</code>&quot; option).</li>
+avoids the foo.sh script because it needed to use a modified
+<a href="#opt--read-batch"><code>--read-batch</code></a> option, but you could edit the script file if you
+wished to make use of it (just be sure that no other option is trying to use
+standard input, such as the <a href="#opt--exclude-from"><code>--exclude-from=-</code></a> option).</li>
 </ul>
 <p>Caveats:</p>
 <p>The read-batch option expects the destination tree that it is updating to be
@@ -3731,65 +4236,77 @@ already) or the file-update may be attempted and then, if the file fails to
 verify, the update discarded with an error.  This means that it should be safe
 to re-run a read-batch operation if the command got interrupted.  If you wish
 to force the batched-update to always be attempted regardless of the file's
-size and date, use the <code>-I</code> option (when reading the batch).  If an error
-occurs, the destination tree will probably be in a partially updated state.  In
-that case, rsync can be used in its regular (non-batch) mode of operation to
-fix up the destination tree.</p>
+size and date, use the <a href="#opt-I"><code>-I</code></a> option (when reading the batch).  If an
+error occurs, the destination tree will probably be in a partially updated
+state.  In that case, rsync can be used in its regular (non-batch) mode of
+operation to fix up the destination tree.</p>
 <p>The rsync version used on all destinations must be at least as new as the one
 used to generate the batch file.  Rsync will die with an error if the protocol
 version in the batch file is too new for the batch-reading rsync to handle.
-See also the <code>--protocol</code> option for a way to have the creating rsync generate
-a batch file that an older rsync can understand.  (Note that batch files
-changed format in version 2.6.3, so mixing versions older than that with newer
-versions will not work.)</p>
+See also the <a href="#opt--protocol"><code>--protocol</code></a> option for a way to have the creating rsync
+generate a batch file that an older rsync can understand.  (Note that batch
+files changed format in version 2.6.3, so mixing versions older than that with
+newer versions will not work.)</p>
 <p>When reading a batch file, rsync will force the value of certain options to
 match the data in the batch file if you didn't set them to the same as the
 batch-writing command.  Other options can (and should) be changed.  For
-instance <code>--write-batch</code> changes to <code>--read-batch</code>, <code>--files-from</code> is dropped,
-and the <code>--filter</code> / <code>--include</code> / <code>--exclude</code> options are not needed unless
-one of the <code>--delete</code> options is specified.</p>
+instance <a href="#opt--write-batch"><code>--write-batch</code></a> changes to <a href="#opt--read-batch"><code>--read-batch</code></a>,
+<a href="#opt--files-from"><code>--files-from</code></a> is dropped, and the <a href="#opt--filter"><code>--filter</code></a> /
+<a href="#opt--include"><code>--include</code></a> / <a href="#opt--exclude"><code>--exclude</code></a> options are not needed unless one of
+the <a href="#opt--delete"><code>--delete</code></a> options is specified.</p>
 <p>The code that creates the BATCH.sh file transforms any filter/include/exclude
 options into a single list that is appended as a &quot;here&quot; document to the shell
 script file.  An advanced user can use this to modify the exclude list if a
-change in what gets deleted by <code>--delete</code> is desired.  A normal user can ignore
-this detail and just use the shell script as an easy way to run the appropriate
-<code>--read-batch</code> command for the batched data.</p>
+change in what gets deleted by <a href="#opt--delete"><code>--delete</code></a> is desired.  A normal user
+can ignore this detail and just use the shell script as an easy way to run the
+appropriate <a href="#opt--read-batch"><code>--read-batch</code></a> command for the batched data.</p>
 <p>The original batch mode in rsync was based on &quot;rsync+&quot;, but the latest
 version uses a new implementation.</p>
-<h1>SYMBOLIC LINKS</h1>
+<h2 id="SYMBOLIC_LINKS">SYMBOLIC LINKS<a href="#SYMBOLIC_LINKS" class="tgt"></a></h2>
 <p>Three basic behaviors are possible when rsync encounters a symbolic
 link in the source directory.</p>
 <p>By default, symbolic links are not transferred at all.  A message &quot;skipping
 non-regular&quot; file is emitted for any symlinks that exist.</p>
-<p>If <code>--links</code> is specified, then symlinks are recreated with the same target on
-the destination.  Note that <code>--archive</code> implies <code>--links</code>.</p>
-<p>If <code>--copy-links</code> is specified, then symlinks are &quot;collapsed&quot; by
+<p>If <a href="#opt--links"><code>--links</code></a> is specified, then symlinks are added to the transfer
+(instead of being noisily ignored), and the default handling is to recreate
+them with the same target on the destination.  Note that <a href="#opt--archive"><code>--archive</code></a>
+implies <a href="#opt--links"><code>--links</code></a>.</p>
+<p>If <a href="#opt--copy-links"><code>--copy-links</code></a> is specified, then symlinks are &quot;collapsed&quot; by
 copying their referent, rather than the symlink.</p>
 <p>Rsync can also distinguish &quot;safe&quot; and &quot;unsafe&quot; symbolic links.  An example
 where this might be used is a web site mirror that wishes to ensure that the
 rsync module that is copied does not include symbolic links to <code>/etc/passwd</code> in
-the public section of the site.  Using <code>--copy-unsafe-links</code> will cause any
-links to be copied as the file they point to on the destination.  Using
-<code>--safe-links</code> will cause unsafe links to be omitted altogether. (Note that you
-must specify <code>--links</code> for <code>--safe-links</code> to have any effect.)</p>
-<p>Symbolic links are considered unsafe if they are absolute symlinks
-(start with <code>/</code>), empty, or if they contain enough &quot;..&quot;
-components to ascend from the directory being copied.</p>
+the public section of the site.  Using <a href="#opt--copy-unsafe-links"><code>--copy-unsafe-links</code></a> will cause
+any links to be copied as the file they point to on the destination.  Using
+<a href="#opt--safe-links"><code>--safe-links</code></a> will cause unsafe links to be omitted by the receiver.
+(Note that you must specify or imply <a href="#opt--links"><code>--links</code></a> for
+<a href="#opt--safe-links"><code>--safe-links</code></a> to have any effect.)</p>
+<p>Symbolic links are considered unsafe if they are absolute symlinks (start with
+<code>/</code>), empty, or if they contain enough &quot;..&quot; components to ascend from the top
+of the transfer.</p>
 <p>Here's a summary of how the symlink options are interpreted.  The list is in
 order of precedence, so if your combination of options isn't mentioned, use the
 first line that is a complete subset of your options:</p>
 <dl>
-<dt><code>--copy-links</code></dt><dd> Turn all symlinks into normal files (leaving no symlinks for
-any other options to affect).</dd>
-<dt><code>--links --copy-unsafe-links</code></dt><dd> Turn all unsafe symlinks into files and
-duplicate all safe symlinks.</dd>
-<dt><code>--copy-unsafe-links</code></dt><dd> Turn all unsafe symlinks into files, noisily skip all
-safe symlinks.</dd>
-<dt><code>--links --safe-links</code></dt><dd> Duplicate safe symlinks and skip unsafe ones.</dd>
-<dt><code>--links</code></dt><dd> Duplicate all symlinks.</dd>
+<dt><code>--copy-links</code></dt><dd> Turn all symlinks into normal files and directories
+(leaving no symlinks in the transfer for any other options to affect).</dd>
+<dt><code>--copy-dirlinks</code></dt><dd> Turn just symlinks to directories into real
+directories, leaving all other symlinks to be handled as described below.</dd>
+<dt><code>--links --copy-unsafe-links</code></dt><dd> Turn all unsafe symlinks
+into files and create all safe symlinks.</dd>
+<dt><code>--copy-unsafe-links</code></dt><dd> Turn all unsafe symlinks into files, noisily
+skip all safe symlinks.</dd>
+<dt><code>--links --safe-links</code></dt><dd> The receiver skips creating
+unsafe symlinks found in the transfer and creates the safe ones.</dd>
+<dt><code>--links</code></dt><dd> Create all symlinks.</dd>
 </dl>
-<h1>DIAGNOSTICS</h1>
-<p>rsync occasionally produces error messages that may seem a little cryptic.  The
+<p>For the effect of <a href="#opt--munge-links"><code>--munge-links</code></a>, see the discussion in that option's
+section.</p>
+<p>Note that the <a href="#opt--keep-dirlinks"><code>--keep-dirlinks</code></a> option does not effect symlinks in the
+transfer but instead affects how rsync treats a symlink to a directory that
+already exists on the receiving side.  See that option's section for a warning.</p>
+<h2 id="DIAGNOSTICS">DIAGNOSTICS<a href="#DIAGNOSTICS" class="tgt"></a></h2>
+<p>Rsync occasionally produces error messages that may seem a little cryptic.  The
 one that seems to cause the most confusion is &quot;protocol version mismatch&nbsp;-&#8288;-&#8288; is
 your shell clean?&quot;.</p>
 <p>This message is usually caused by your startup scripts or remote shell facility
@@ -3808,123 +4325,187 @@ contain output statements for non-interactive logins.</p>
 <p>If you are having trouble debugging filter patterns, then try specifying the
 <code>-vv</code> option.  At this level of verbosity rsync will show why each individual
 file is included or excluded.</p>
-<h1>EXIT VALUES</h1>
-<dl>
-<dt><strong>0</strong></dt><dd> Success</dd>
-<dt><strong>1</strong></dt><dd> Syntax or usage error</dd>
-<dt><strong>2</strong></dt><dd> Protocol incompatibility</dd>
-<dt><strong>3</strong></dt><dd> Errors selecting input/output files, dirs</dd>
-<dt><strong>4</strong></dt><dd> Requested action not supported: an attempt was made to manipulate
-64-bit files on a platform that cannot support them; or an option was
-specified that is supported by the client and not by the server.</dd>
-<dt><strong>5</strong></dt><dd> Error starting client-server protocol</dd>
-<dt><strong>6</strong></dt><dd> Daemon unable to append to log-file</dd>
-<dt><strong>10</strong></dt><dd> Error in socket I/O</dd>
-<dt><strong>11</strong></dt><dd> Error in file I/O</dd>
-<dt><strong>12</strong></dt><dd> Error in rsync protocol data stream</dd>
-<dt><strong>13</strong></dt><dd> Errors with program diagnostics</dd>
-<dt><strong>14</strong></dt><dd> Error in IPC code</dd>
-<dt><strong>20</strong></dt><dd> Received SIGUSR1 or SIGINT</dd>
-<dt><strong>21</strong></dt><dd> Some error returned by <strong>waitpid()</strong></dd>
-<dt><strong>22</strong></dt><dd> Error allocating core memory buffers</dd>
-<dt><strong>23</strong></dt><dd> Partial transfer due to error</dd>
-<dt><strong>24</strong></dt><dd> Partial transfer due to vanished source files</dd>
-<dt><strong>25</strong></dt><dd> The -&#8288;-&#8288;max-delete limit stopped deletions</dd>
-<dt><strong>30</strong></dt><dd> Timeout in data send/receive</dd>
-<dt><strong>35</strong></dt><dd> Timeout waiting for daemon connection</dd>
-</dl>
-<h1>ENVIRONMENT VARIABLES</h1>
+<h2 id="EXIT_VALUES">EXIT VALUES<a href="#EXIT_VALUES" class="tgt"></a></h2>
+<ul>
+<li><strong>0</strong> -&#8288; Success</li>
+<li><strong>1</strong> -&#8288; Syntax or usage error</li>
+<li><strong>2</strong> -&#8288; Protocol incompatibility</li>
+<li><strong>3</strong> -&#8288; Errors selecting input/output files, dirs</li>
+<li><strong>4</strong> -&#8288; Requested action not supported. Either:
+<ul>
+<li>an attempt was made to manipulate 64-bit files on a platform that cannot support them</li>
+<li>an option was specified that is supported by the client and not by the server</li>
+</ul>
+</li>
+<li><strong>5</strong> -&#8288; Error starting client-server protocol</li>
+<li><strong>6</strong> -&#8288; Daemon unable to append to log-file</li>
+<li><strong>10</strong> -&#8288; Error in socket I/O</li>
+<li><strong>11</strong> -&#8288; Error in file I/O</li>
+<li><strong>12</strong> -&#8288; Error in rsync protocol data stream</li>
+<li><strong>13</strong> -&#8288; Errors with program diagnostics</li>
+<li><strong>14</strong> -&#8288; Error in IPC code</li>
+<li><strong>20</strong> -&#8288; Received SIGUSR1 or SIGINT</li>
+<li><strong>21</strong> -&#8288; Some error returned by <strong>waitpid()</strong></li>
+<li><strong>22</strong> -&#8288; Error allocating core memory buffers</li>
+<li><strong>23</strong> -&#8288; Partial transfer due to error</li>
+<li><strong>24</strong> -&#8288; Partial transfer due to vanished source files</li>
+<li><strong>25</strong> -&#8288; The -&#8288;-&#8288;max-delete limit stopped deletions</li>
+<li><strong>30</strong> -&#8288; Timeout in data send/receive</li>
+<li><strong>35</strong> -&#8288; Timeout waiting for daemon connection</li>
+</ul>
+<h2 id="ENVIRONMENT_VARIABLES">ENVIRONMENT VARIABLES<a href="#ENVIRONMENT_VARIABLES" class="tgt"></a></h2>
 <dl>
 
-<dt><code>CVSIGNORE</code></dt><dd>
+<dt id="CVSIGNORE"><code>CVSIGNORE</code><a href="#CVSIGNORE" class="tgt"></a></dt><dd>
 <p>The CVSIGNORE environment variable supplements any ignore patterns in
-.cvsignore files.  See the <code>--cvs-exclude</code> option for more details.</p>
+.cvsignore files.  See the <a href="#opt--cvs-exclude"><code>--cvs-exclude</code></a> option for more details.</p>
+</dd>
+
+<dt id="RSYNC_ICONV"><code>RSYNC_ICONV</code><a href="#RSYNC_ICONV" class="tgt"></a></dt><dd>
+<p>Specify a default <a href="#opt--iconv"><code>--iconv</code></a> setting using this environment
+variable. First supported in 3.0.0.</p>
 </dd>
 
-<dt><code>RSYNC_ICONV</code></dt><dd>
-<p>Specify a default <code>--iconv</code> setting using this environment variable. (First
-supported in 3.0.0.)</p>
+<dt id="RSYNC_OLD_ARGS"><code>RSYNC_OLD_ARGS</code><a href="#RSYNC_OLD_ARGS" class="tgt"></a></dt><dd>
+<p>Specify a &quot;1&quot; if you want the <a href="#opt--old-args"><code>--old-args</code></a> option to be enabled by
+default, a &quot;2&quot; (or more) if you want it to be enabled in the
+repeated-option state, or a &quot;0&quot; to make sure that it is disabled by
+default. When this environment variable is set to a non-zero value, it
+supersedes the <a href="#RSYNC_PROTECT_ARGS"><code>RSYNC_PROTECT_ARGS</code></a> variable.</p>
+<p>This variable is ignored if <a href="#opt--old-args"><code>--old-args</code></a>, <code>--no-old-args</code>, or
+<a href="#opt--secluded-args"><code>--secluded-args</code></a> is specified on the command line.</p>
+<p>First supported in 3.2.4.</p>
 </dd>
 
-<dt><code>RSYNC_PROTECT_ARGS</code></dt><dd>
-<p>Specify a non-zero numeric value if you want the <code>--protect-args</code> option to
-be enabled by default, or a zero value to make sure that it is disabled by
-default. (First supported in 3.1.0.)</p>
+<dt id="RSYNC_PROTECT_ARGS"><code>RSYNC_PROTECT_ARGS</code><a href="#RSYNC_PROTECT_ARGS" class="tgt"></a></dt><dd>
+<p>Specify a non-zero numeric value if you want the <a href="#opt--secluded-args"><code>--secluded-args</code></a>
+option to be enabled by default, or a zero value to make sure that it is
+disabled by default.</p>
+<p>This variable is ignored if <a href="#opt--secluded-args"><code>--secluded-args</code></a>, <code>--no-secluded-args</code>,
+or <a href="#opt--old-args"><code>--old-args</code></a> is specified on the command line.</p>
+<p>First supported in 3.1.0.  Starting in 3.2.4, this variable is ignored if
+<a href="#RSYNC_OLD_ARGS"><code>RSYNC_OLD_ARGS</code></a> is set to a non-zero value.</p>
 </dd>
 
-<dt><code>RSYNC_RSH</code></dt><dd>
-<p>The RSYNC_RSH environment variable allows you to override the default shell
-used as the transport for rsync.  Command line options are permitted after
-the command name, just as in the <code>-e</code> option.</p>
+<dt id="RSYNC_RSH"><code>RSYNC_RSH</code><a href="#RSYNC_RSH" class="tgt"></a></dt><dd>
+<p>This environment variable allows you to override the default shell used as
+the transport for rsync.  Command line options are permitted after the
+command name, just as in the <a href="#opt--rsh"><code>--rsh</code></a> (<code>-e</code>) option.</p>
 </dd>
 
-<dt><code>RSYNC_PROXY</code></dt><dd>
-<p>The RSYNC_PROXY environment variable allows you to redirect your rsync
-client to use a web proxy when connecting to a rsync daemon.  You should
-set RSYNC_PROXY to a hostname:port pair.</p>
+<dt id="RSYNC_PROXY"><code>RSYNC_PROXY</code><a href="#RSYNC_PROXY" class="tgt"></a></dt><dd>
+<p>This environment variable allows you to redirect your rsync
+client to use a web proxy when connecting to an rsync daemon.  You should
+set <code>RSYNC_PROXY</code> to a hostname:port pair.</p>
 </dd>
 
-<dt><code>RSYNC_PASSWORD</code></dt><dd>
-<p>Setting RSYNC_PASSWORD to the required password allows you to run
-authenticated rsync connections to an rsync daemon without user
-intervention.  Note that this does not supply a password to a remote shell
-transport such as ssh; to learn how to do that, consult the remote shell's
-documentation.</p>
+<dt id="RSYNC_PASSWORD"><code>RSYNC_PASSWORD</code><a href="#RSYNC_PASSWORD" class="tgt"></a></dt><dd>
+<p>This environment variable allows you to set the password for an rsync
+<strong>daemon</strong> connection, which avoids the password prompt.  Note that this
+does <strong>not</strong> supply a password to a remote shell transport such as ssh
+(consult its documentation for how to do that).</p>
 </dd>
 
-<dt><code>USER</code> or <code>LOGNAME</code></dt><dd>
+<span id="LOGNAME"></span><dt id="USER"><code>USER</code> or <code>LOGNAME</code><a href="#USER" class="tgt"></a></dt><dd>
 <p>The USER or LOGNAME environment variables are used to determine the default
 username sent to an rsync daemon.  If neither is set, the username defaults
-to &quot;nobody&quot;.</p>
+to &quot;nobody&quot;.  If both are set, <code>USER</code> takes precedence.</p>
+</dd>
+
+<dt id="RSYNC_PARTIAL_DIR"><code>RSYNC_PARTIAL_DIR</code><a href="#RSYNC_PARTIAL_DIR" class="tgt"></a></dt><dd>
+<p>This environment variable specifies the directory to use for a
+<a href="#opt--partial"><code>--partial</code></a> transfer without implying that partial transfers be
+enabled.  See the <a href="#opt--partial-dir"><code>--partial-dir</code></a> option for full details.</p>
 </dd>
 
-<dt><code>HOME</code></dt><dd>
-<p>The HOME environment variable is used to find the user's default .cvsignore
+<dt id="RSYNC_COMPRESS_LIST"><code>RSYNC_COMPRESS_LIST</code><a href="#RSYNC_COMPRESS_LIST" class="tgt"></a></dt><dd>
+<p>This environment variable allows you to customize the negotiation of the
+compression algorithm by specifying an alternate order or a reduced list of
+names.  Use the command <code>rsync --version</code> to see the available compression
+names.  See the <a href="#opt--compress"><code>--compress</code></a> option for full details.</p>
+</dd>
+
+<dt id="RSYNC_CHECKSUM_LIST"><code>RSYNC_CHECKSUM_LIST</code><a href="#RSYNC_CHECKSUM_LIST" class="tgt"></a></dt><dd>
+<p>This environment variable allows you to customize the negotiation of the
+checksum algorithm by specifying an alternate order or a reduced list of
+names.  Use the command <code>rsync --version</code> to see the available checksum
+names.  See the <a href="#opt--checksum-choice"><code>--checksum-choice</code></a> option for full details.</p>
+</dd>
+
+<dt id="RSYNC_MAX_ALLOC"><code>RSYNC_MAX_ALLOC</code><a href="#RSYNC_MAX_ALLOC" class="tgt"></a></dt><dd>
+<p>This environment variable sets an allocation maximum as if you had used the
+<a href="#opt--max-alloc"><code>--max-alloc</code></a> option.</p>
+</dd>
+
+<dt id="RSYNC_PORT"><code>RSYNC_PORT</code><a href="#RSYNC_PORT" class="tgt"></a></dt><dd>
+<p>This environment variable is not read by rsync, but is instead set in
+its sub-environment when rsync is running the remote shell in combination
+with a daemon connection.  This allows a script such as
+<a href="rsync-ssl.1"><code>rsync-ssl</code></a> to be able to know the port number that the user
+specified on the command line.</p>
+</dd>
+
+<dt id="HOME"><code>HOME</code><a href="#HOME" class="tgt"></a></dt><dd>
+<p>This environment variable is used to find the user's default .cvsignore
 file.</p>
 </dd>
+
+<dt id="RSYNC_CONNECT_PROG"><code>RSYNC_CONNECT_PROG</code><a href="#RSYNC_CONNECT_PROG" class="tgt"></a></dt><dd>
+<p>This environment variable is mainly used in debug setups to set the program
+to use when making a daemon connection.  See <a href="#CONNECTING_TO_AN_RSYNC_DAEMON">CONNECTING TO AN RSYNC
+DAEMON</a> for full details.</p>
+</dd>
+
+<dt id="RSYNC_SHELL"><code>RSYNC_SHELL</code><a href="#RSYNC_SHELL" class="tgt"></a></dt><dd>
+<p>This environment variable is mainly used in debug setups to set the program
+to use to run the program specified by <a href="#RSYNC_CONNECT_PROG"><code>RSYNC_CONNECT_PROG</code></a>.  See
+<a href="#CONNECTING_TO_AN_RSYNC_DAEMON">CONNECTING TO AN RSYNC DAEMON</a> for full details.</p>
+</dd>
 </dl>
-<h1>FILES</h1>
+<h2 id="FILES">FILES<a href="#FILES" class="tgt"></a></h2>
 <p>/etc/rsyncd.conf or rsyncd.conf</p>
-<h1>SEE ALSO</h1>
-<p><strong>rsync-ssl</strong>(1), <strong>rsyncd.conf</strong>(5)</p>
-<h1>BUGS</h1>
-<p>times are transferred as *nix time_t values</p>
-<p>When transferring to FAT filesystems rsync may re-sync
-unmodified files.
-See the comments on the <code>--modify-window</code> option.</p>
-<p>file permissions, devices, etc. are transferred as native numerical
-values</p>
-<p>see also the comments on the <code>--delete</code> option</p>
+<h2 id="SEE_ALSO">SEE ALSO<a href="#SEE_ALSO" class="tgt"></a></h2>
+<p><a href="rsync-ssl.1"><strong>rsync-ssl</strong>(1)</a>, <a href="rsyncd.conf.5"><strong>rsyncd.conf</strong>(5)</a>, <a href="rrsync.1"><strong>rrsync</strong>(1)</a></p>
+<h2 id="BUGS">BUGS<a href="#BUGS" class="tgt"></a></h2>
+<ul>
+<li>Times are transferred as *nix time_t values.</li>
+<li>When transferring to FAT filesystems rsync may re-sync unmodified files.  See
+the comments on the <a href="#opt--modify-window"><code>--modify-window</code></a> option.</li>
+<li>File permissions, devices, etc. are transferred as native numerical values.</li>
+<li>See also the comments on the <a href="#opt--delete"><code>--delete</code></a> option.</li>
+</ul>
 <p>Please report bugs! See the web site at <a href="https://rsync.samba.org/">https://rsync.samba.org/</a>.</p>
-<h1>VERSION</h1>
-<p>This man page is current for version 3.2.3 of rsync.</p>
-<h1>INTERNAL OPTIONS</h1>
+<h2 id="VERSION">VERSION<a href="#VERSION" class="tgt"></a></h2>
+<p>This manpage is current for version 3.2.7 of rsync.</p>
+<h2 id="INTERNAL_OPTIONS">INTERNAL OPTIONS<a href="#INTERNAL_OPTIONS" class="tgt"></a></h2>
 <p>The options <code>--server</code> and <code>--sender</code> are used internally by rsync, and should
 never be typed by a user under normal circumstances.  Some awareness of these
 options may be needed in certain scenarios, such as when setting up a login
 that can only run an rsync command.  For instance, the support directory of the
 rsync distribution has an example script named rrsync (for restricted rsync)
 that can be used with a restricted ssh login.</p>
-<h1>CREDITS</h1>
-<p>rsync is distributed under the GNU General Public License.  See the file
-COPYING for details.</p>
-<p>A web site is available at <a href="https://rsync.samba.org/">https://rsync.samba.org/</a>.  The site includes an
-FAQ-O-Matic which may cover questions unanswered by this manual page.</p>
+<h2 id="CREDITS">CREDITS<a href="#CREDITS" class="tgt"></a></h2>
+<p>Rsync is distributed under the GNU General Public License.  See the file
+<a href="COPYING">COPYING</a> for details.</p>
+<p>An rsync web site is available at <a href="https://rsync.samba.org/">https://rsync.samba.org/</a>.  The site
+includes an FAQ-O-Matic which may cover questions unanswered by this manual
+page.</p>
+<p>The rsync github project is <a href="https://github.com/WayneD/rsync">https://github.com/WayneD/rsync</a>.</p>
 <p>We would be delighted to hear from you if you like this program.  Please
 contact the mailing-list at <a href="mailto:rsync@lists.samba.org">rsync@lists.samba.org</a>.</p>
 <p>This program uses the excellent zlib compression library written by Jean-loup
 Gailly and Mark Adler.</p>
-<h1>THANKS</h1>
+<h2 id="THANKS">THANKS<a href="#THANKS" class="tgt"></a></h2>
 <p>Special thanks go out to: John Van Essen, Matt McCutchen, Wesley W. Terpstra,
 David Dykstra, Jos Backus, Sebastian Krahmer, Martin Pool, and our
 gone-but-not-forgotten compadre, J.W. Schultz.</p>
 <p>Thanks also to Richard Brent, Brendan Mackay, Bill Waite, Stephen Rothwell and
 David Bell.  I've probably missed some people, my apologies if I have.</p>
-<h1>AUTHOR</h1>
-<p>rsync was originally written by Andrew Tridgell and Paul Mackerras.  Many
+<h2 id="AUTHOR">AUTHOR<a href="#AUTHOR" class="tgt"></a></h2>
+<p>Rsync was originally written by Andrew Tridgell and Paul Mackerras.  Many
 people have later contributed to it. It is currently maintained by Wayne
 Davison.</p>
 <p>Mailing lists for support and development are available at
 <a href="https://lists.samba.org/">https://lists.samba.org/</a>.</p>
-<div style="float: right"><p><i>06 Aug 2020</i></p></div>
+<div style="float: right"><p><i>20 Oct 2022</i></p></div>
 </body></html>
index b1ef84e..ee0a4f3 100644 (file)
@@ -1,8 +1,8 @@
-# NAME
+## NAME
 
 rsync - a fast, versatile, remote (and local) file-copying tool
 
-# SYNOPSIS
+## SYNOPSIS
 
 ```
 Local:
@@ -26,7 +26,10 @@ Access via rsync daemon:
 Usages with just one SRC arg and no DEST arg will list the source files instead
 of copying.
 
-# DESCRIPTION
+The online version of this manpage (that includes cross-linking of topics)
+is available at <https://download.samba.org/pub/rsync/rsync.1>.
+
+## DESCRIPTION
 
 Rsync is a fast and extraordinarily versatile file copying tool.  It can copy
 locally, to/from another host over any remote shell, or to/from a remote rsync
@@ -54,7 +57,7 @@ Some of the additional features of rsync are:
 - pipelining of file transfers to minimize latency costs
 - support for anonymous or authenticated rsync daemons (ideal for mirroring)
 
-# GENERAL
+## GENERAL
 
 Rsync copies files either to or from a remote host, or locally on the current
 host (it does not support copying files between two remote hosts).
@@ -65,21 +68,21 @@ rsync daemon directly via TCP.  The remote-shell transport is used whenever the
 source or destination path contains a single colon (:) separator after a host
 specification.  Contacting an rsync daemon directly happens when the source or
 destination path contains a double colon (::) separator after a host
-specification, OR when an rsync:// URL is specified (see also the "USING
-RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION" section for an exception
-to this latter rule).
+specification, OR when an rsync:// URL is specified (see also the [USING
+RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION](#) section for an
+exception to this latter rule).
 
 As a special case, if a single source arg is specified without a destination,
 the files are listed in an output format similar to "`ls -l`".
 
 As expected, if neither the source or destination path specify a remote host,
-the copy occurs locally (see also the `--list-only` option).
+the copy occurs locally (see also the [`--list-only`](#opt) option).
 
 Rsync refers to the local side as the client and the remote side as the server.
 Don't confuse server with an rsync daemon.  A daemon is always a server, but a
 server can be either a daemon or a remote-shell spawned process.
 
-# SETUP
+## SETUP
 
 See the file README.md for installation instructions.
 
@@ -89,12 +92,12 @@ protocol).  For remote transfers, a modern rsync uses ssh for its
 communications, but it may have been configured to use a different remote shell
 by default, such as rsh or remsh.
 
-You can also specify any remote shell you like, either by using the `-e`
-command line option, or by setting the RSYNC_RSH environment variable.
+You can also specify any remote shell you like, either by using the [`-e`](#opt)
+command line option, or by setting the [`RSYNC_RSH`](#) environment variable.
 
 Note that rsync must be installed on both the source and destination machines.
 
-# USAGE
+## USAGE
 
 You use rsync in the same way you use rcp.  You must specify a source and a
 destination, one of which may be remote.
@@ -149,55 +152,161 @@ rsync daemon by leaving off the module name:
 
 >     rsync somehost.mydomain.com::
 
-See the following section for more details.
+## COPYING TO A DIFFERENT NAME
+
+When you want to copy a directory to a different name, use a trailing slash on
+the source directory to put the contents of the directory into any destination
+directory you like:
+
+>     rsync -ai foo/ bar/
+
+Rsync also has the ability to customize a destination file's name when copying
+a single item.  The rules for this are:
+
+- The transfer list must consist of a single item (either a file or an empty
+  directory)
+- The final element of the destination path must not exist as a directory
+- The destination path must not have been specified with a trailing slash
+
+Under those circumstances, rsync will set the name of the destination's single
+item to the last element of the destination path.  Keep in mind that it is best
+to only use this idiom when copying a file and use the above trailing-slash
+idiom when copying a directory.
+
+The following example copies the `foo.c` file as `bar.c` in the `save` dir
+(assuming that `bar.c` isn't a directory):
+
+>     rsync -ai src/foo.c save/bar.c
+
+The single-item copy rule might accidentally bite you if you unknowingly copy a
+single item and specify a destination dir that doesn't exist (without using a
+trailing slash).  For example, if `src/*.c` matches one file and `save/dir`
+doesn't exist, this will confuse you by naming the destination file `save/dir`:
+
+>     rsync -ai src/*.c save/dir
+
+To prevent such an accident, either make sure the destination dir exists or
+specify the destination path with a trailing slash:
+
+>     rsync -ai src/*.c save/dir/
+
+## SORTED TRANSFER ORDER
+
+Rsync always sorts the specified filenames into its internal transfer list.
+This handles the merging together of the contents of identically named
+directories, makes it easy to remove duplicate filenames. It can, however,
+confuse someone when the files are transferred in a different order than what
+was given on the command-line.
+
+If you need a particular file to be transferred prior to another, either
+separate the files into different rsync calls, or consider using
+[`--delay-updates`](#opt) (which doesn't affect the sorted transfer order, but
+does make the final file-updating phase happen much more rapidly).
+
+## MULTI-HOST SECURITY
+
+Rsync takes steps to ensure that the file requests that are shared in a
+transfer are protected against various security issues.  Most of the potential
+problems arise on the receiving side where rsync takes steps to ensure that the
+list of files being transferred remains within the bounds of what was
+requested.
+
+Toward this end, rsync 3.1.2 and later have aborted when a file list contains
+an absolute or relative path that tries to escape out of the top of the
+transfer.  Also, beginning with version 3.2.5, rsync does two more safety
+checks of the file list to (1) ensure that no extra source arguments were added
+into the transfer other than those that the client requested and (2) ensure
+that the file list obeys the exclude rules that were sent to the sender.
 
-# ADVANCED USAGE
+For those that don't yet have a 3.2.5 client rsync (or those that want to be
+extra careful), it is safest to do a copy into a dedicated destination
+directory for the remote files when you don't trust the remote host.  For
+example, instead of doing an rsync copy into your home directory:
+
+>     rsync -aiv host1:dir1 ~
+
+Dedicate a "host1-files" dir to the remote content:
+
+>     rsync -aiv host1:dir1 ~/host1-files
+
+See the [`--trust-sender`](#opt) option for additional details.
+
+CAUTION: it is not particularly safe to use rsync to copy files from a
+case-preserving filesystem to a case-ignoring filesystem.  If you must perform
+such a copy, you should either disable symlinks via `--no-links` or enable the
+munging of symlinks via [`--munge-links`](#opt) (and make sure you use the
+right local or remote option).  This will prevent rsync from doing potentially
+dangerous things if a symlink name overlaps with a file or directory. It does
+not, however, ensure that you get a full copy of all the files (since that may
+not be possible when the names overlap). A potentially better solution is to
+list all the source files and create a safe list of filenames that you pass to
+the [`--files-from`](#opt) option.  Any files that conflict in name would need
+to be copied to different destination directories using more than one copy.
+
+While a copy of a case-ignoring filesystem to a case-ignoring filesystem can
+work out fairly well, if no `--delete-during` or `--delete-before` option is
+active, rsync can potentially update an existing file on the receiveing side
+without noticing that the upper-/lower-case of the filename should be changed
+to match the sender.
+
+## ADVANCED USAGE
 
 The syntax for requesting multiple files from a remote host is done by
 specifying additional remote-host args in the same style as the first, or with
 the hostname omitted.  For instance, all these work:
 
->     rsync -av host:file1 :file2 host:file{3,4} /dest/
->     rsync -av host::modname/file{1,2} host::modname/file3 /dest/
->     rsync -av host::modname/file1 ::modname/file{3,4}
+>     rsync -aiv host:file1 :file2 host:file{3,4} /dest/
+>     rsync -aiv host::modname/file{1,2} host::modname/extra /dest/
+>     rsync -aiv host::modname/first ::extra-file{1,2} /dest/
 
-Older versions of rsync required using quoted spaces in the SRC, like these
-examples:
+Note that a daemon connection only supports accessing one module per copy
+command, so if the start of a follow-up path doesn't begin with the
+modname of the first path, it is assumed to be a path in the module (such as
+the extra-file1 & extra-file2 that are grabbed above).
 
->     rsync -av host:'dir1/file1 dir2/file2' /dest
->     rsync host::'modname/dir1/file1 modname/dir2/file2' /dest
+Really old versions of rsync (2.6.9 and before) only allowed specifying one
+remote-source arg, so some people have instead relied on the remote-shell
+performing space splitting to break up an arg into multiple paths. Such
+unintuitive behavior is no longer supported by default (though you can request
+it, as described below).
 
-This word-splitting still works (by default) in the latest rsync, but is not as
-easy to use as the first method.
+Starting in 3.2.4, filenames are passed to a remote shell in such a way as to
+preserve the characters you give it. Thus, if you ask for a file with spaces
+in the name, that's what the remote rsync looks for:
 
-If you need to transfer a filename that contains whitespace, you can either
-specify the `--protect-args` (`-s`) option, or you'll need to escape the
-whitespace in a way that the remote shell will understand.  For instance:
+>     rsync -aiv host:'a simple file.pdf' /dest/
 
->     rsync -av host:'file\ name\ with\ spaces' /dest
+If you use scripts that have been written to manually apply extra quoting to
+the remote rsync args (or to require remote arg splitting), you can ask rsync
+to let your script handle the extra escaping.  This is done by either adding
+the [`--old-args`](#opt) option to the rsync runs in the script (which requires
+a new rsync) or exporting [RSYNC_OLD_ARGS](#)=1 and [RSYNC_PROTECT_ARGS](#)=0
+(which works with old or new rsync versions).
 
-# CONNECTING TO AN RSYNC DAEMON
+## CONNECTING TO AN RSYNC DAEMON
 
 It is also possible to use rsync without a remote shell as the transport.  In
 this case you will directly connect to a remote rsync daemon, typically using
 TCP port 873. (This obviously requires the daemon to be running on the remote
-system, so refer to the STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS section
-below for information on that.)
+system, so refer to the [STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS](#)
+section below for information on that.)
 
 Using rsync in this way is the same as using it with a remote shell except
 that:
 
-- you either use a double colon :: instead of a single colon to separate the
-  hostname from the path, or you use an rsync:// URL.
-- the first word of the "path" is actually a module name.
-- the remote daemon may print a message of the day when you connect.
-- if you specify no path name on the remote daemon then the list of accessible
-  paths on the daemon will be shown.
-- if you specify no local destination then a listing of the specified files on
-  the remote daemon is provided.
-- you must not specify the `--rsh` (`-e`) option (since that overrides the
-  daemon connection to use ssh -- see USING RSYNC-DAEMON FEATURES VIA A
-  REMOTE-SHELL CONNECTION below).
+- Use either double-colon syntax or rsync:// URL syntax instead of the
+  single-colon (remote shell) syntax.
+- The first element of the "path" is actually a module name.
+- Additional remote source args can use an abbreviated syntax that omits the
+  hostname and/or the module name, as discussed in [ADVANCED USAGE](#).
+- The remote daemon may print a "message of the day" when you connect.
+- If you specify only the host (with no module or path) then a list of
+  accessible modules on the daemon is output.
+- If you specify a remote source path but no destination, a listing of the
+  matching files on the remote daemon is output.
+- The [`--rsh`](#opt) (`-e`) option must be omitted to avoid changing the
+  connection style from using a socket connection to [USING RSYNC-DAEMON
+  FEATURES VIA A REMOTE-SHELL CONNECTION](#).
 
 An example that copies all the files in a remote module named "src":
 
@@ -205,22 +314,23 @@ An example that copies all the files in a remote module named "src":
 
 Some modules on the remote daemon may require authentication.  If so, you will
 receive a password prompt when you connect.  You can avoid the password prompt
-by setting the environment variable RSYNC_PASSWORD to the password you want to
-use or using the `--password-file` option.  This may be useful when scripting
-rsync.
+by setting the environment variable [`RSYNC_PASSWORD`](#) to the password you
+want to use or using the [`--password-file`](#opt) option.  This may be useful
+when scripting rsync.
 
 WARNING: On some systems environment variables are visible to all users.  On
-those systems using `--password-file` is recommended.
+those systems using [`--password-file`](#opt) is recommended.
 
 You may establish the connection via a web proxy by setting the environment
-variable RSYNC_PROXY to a hostname:port pair pointing to your web proxy.  Note
-that your web proxy's configuration must support proxy connections to port 873.
+variable [`RSYNC_PROXY`](#) to a hostname:port pair pointing to your web proxy.
+Note that your web proxy's configuration must support proxy connections to port
+873.
 
 You may also establish a daemon connection using a program as a proxy by
-setting the environment variable RSYNC_CONNECT_PROG to the commands you wish to
-run in place of making a direct socket connection.  The string may contain the
-escape "%H" to represent the hostname specified in the rsync command (so use
-"%%" if you need a single "%" in your string).  For example:
+setting the environment variable [`RSYNC_CONNECT_PROG`](#) to the commands you
+wish to run in place of making a direct socket connection.  The string may
+contain the escape "%H" to represent the hostname specified in the rsync
+command (so use "%%" if you need a single "%" in your string).  For example:
 
 >     export RSYNC_CONNECT_PROG='ssh proxyhost nc %H 873'
 >     rsync -av targethost1::module/src/ /dest/
@@ -229,11 +339,11 @@ escape "%H" to represent the hostname specified in the rsync command (so use
 The command specified above uses ssh to run nc (netcat) on a proxyhost, which
 forwards all data to port 873 (the rsync daemon) on the targethost (%H).
 
-Note also that if the RSYNC_SHELL environment variable is set, that program
-will be used to run the RSYNC_CONNECT_PROG command instead of using the default
-shell of the **system()** call.
+Note also that if the [`RSYNC_SHELL`](#) environment variable is set, that
+program will be used to run the `RSYNC_CONNECT_PROG` command instead of using
+the default shell of the **system()** call.
 
-# USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION
+## USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION
 
 It is sometimes useful to use various features of an rsync daemon (such as
 named modules) without actually allowing any new socket connections into a
@@ -250,7 +360,7 @@ on that remote host to only allow connections from "localhost".)
 From the user's perspective, a daemon transfer via a remote-shell connection
 uses nearly the same command-line syntax as a normal rsync-daemon transfer,
 with the only exception being that you must explicitly set the remote shell
-program on the command-line with the `--rsh=COMMAND` option. (Setting the
+program on the command-line with the [`--rsh=COMMAND`](#opt) option. (Setting the
 RSYNC_RSH in the environment will not turn on this functionality.) For example:
 
 >     rsync -av --rsh=ssh host::module /dest
@@ -259,73 +369,47 @@ If you need to specify a different remote-shell user, keep in mind that the
 user@ prefix in front of the host is specifying the rsync-user value (for a
 module that requires user-based authentication).  This means that you must give
 the '-l user' option to ssh when specifying the remote-shell, as in this
-example that uses the short version of the `--rsh` option:
+example that uses the short version of the [`--rsh`](#opt) option:
 
 >     rsync -av -e "ssh -l ssh-user" rsync-user@host::module /dest
 
 The "ssh-user" will be used at the ssh level; the "rsync-user" will be used to
 log-in to the "module".
 
-# STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS
+In this setup, the daemon is started by the ssh command that is accessing the
+system (which can be forced via the `~/.ssh/authorized_keys` file, if desired).
+However, when accessing a daemon directly, it needs to be started beforehand.
+
+## STARTING AN RSYNC DAEMON TO ACCEPT CONNECTIONS
 
 In order to connect to an rsync daemon, the remote system needs to have a
 daemon already running (or it needs to have configured something like inetd to
 spawn an rsync daemon for incoming connections on a particular port).  For full
 information on how to start a daemon that will handling incoming socket
-connections, see the **rsyncd.conf**(5) man page -- that is the config file for
-the daemon, and it contains the full details for how to run the daemon
-(including stand-alone and inetd configurations).
+connections, see the [**rsyncd.conf**(5)](rsyncd.conf.5) manpage -- that is
+the config file for the daemon, and it contains the full details for how to run
+the daemon (including stand-alone and inetd configurations).
 
 If you're using one of the remote-shell transports for the transfer, there is
 no need to manually start an rsync daemon.
 
-# SORTED TRANSFER ORDER
+## EXAMPLES
 
-Rsync always sorts the specified filenames into its internal transfer list.
-This handles the merging together of the contents of identically named
-directories, makes it easy to remove duplicate filenames, and may confuse
-someone when the files are transferred in a different order than what was given
-on the command-line.
+Here are some examples of how rsync can be used.
 
-If you need a particular file to be transferred prior to another, either
-separate the files into different rsync calls, or consider using
-`--delay-updates` (which doesn't affect the sorted transfer order, but does
-make the final file-updating phase happen much more rapidly).
-
-# EXAMPLES
-
-Here are some examples of how I use rsync.
-
-To backup my wife's home directory, which consists of large MS Word files and
-mail folders, I use a cron job that runs
-
->     rsync -Cavz . arvidsjaur:backup
+To backup a home directory, which consists of large MS Word files and mail
+folders, a per-user cron job can be used that runs this each day:
 
-each night over a PPP connection to a duplicate directory on my machine
-"arvidsjaur".
+>     rsync -aiz . bkhost:backup/joe/
 
-To synchronize my samba source trees I use the following Makefile targets:
+To move some files from a remote host to the local host, you could run:
 
->     get:
->         rsync -avuzb --exclude '*~' samba:samba/ .
->     put:
->         rsync -Cavuzb . samba:samba/
->     sync: get put
+>     rsync -aiv --remove-source-files rhost:/tmp/{file1,file2}.c ~/src/
 
-This allows me to sync with a CVS directory at the other end of the connection.
-I then do CVS operations on the remote machine, which saves a lot of time as
-the remote CVS protocol isn't very efficient.
+## OPTION SUMMARY
 
-I mirror a directory between my "old" and "new" ftp sites with the command:
-
->     rsync -az -e ssh --delete ~ftp/pub/samba nimbus:"~ftp/pub/tridge"
-
-This is launched from cron every few hours.
-
-# OPTION SUMMARY
-
-Here is a short summary of the options available in rsync.  Please refer to the
-detailed description below for a complete description.
+Here is a short summary of the options available in rsync.  Each option also
+has its own detailed description later in this manpage.
 
 [comment]: # (help-rsync.h)
 [comment]: # (Keep these short enough that they'll be under 80 chars when indented by 7 chars.)
@@ -338,7 +422,7 @@ detailed description below for a complete description.
 --quiet, -q              suppress non-error messages
 --no-motd                suppress daemon-mode MOTD
 --checksum, -c           skip based on checksum, not mod-time & size
---archive, -a            archive mode; equals -rlptgoD (no -H,-A,-X)
+--archive, -a            archive mode is -rlptgoD (no -A,-X,-U,-N,-H)
 --no-OPTION              turn off an implied OPTION (e.g. --no-D)
 --recursive, -r          recurse into directories
 --relative, -R           use relative path names
@@ -351,7 +435,8 @@ detailed description below for a complete description.
 --append                 append data onto shorter files
 --append-verify          --append w/old data in file checksum
 --dirs, -d               transfer directories without recursing
---mkpath                 create the destination's path component
+--old-dirs, --old-d      works like --dirs when talking to old rsync
+--mkpath                 create destination's missing path components
 --links, -l              copy symlinks as symlinks
 --copy-links, -L         transform symlink into referent file/dir
 --copy-unsafe-links      only "unsafe" symlinks are transformed
@@ -368,6 +453,8 @@ detailed description below for a complete description.
 --owner, -o              preserve owner (super-user only)
 --group, -g              preserve group
 --devices                preserve device files (super-user only)
+--copy-devices           copy device contents as a regular file
+--write-devices          write to devices as files (implies --inplace)
 --specials               preserve special files
 -D                       same as --devices --specials
 --times, -t              preserve modification times
@@ -380,7 +467,6 @@ detailed description below for a complete description.
 --fake-super             store/recover privileged attrs using xattrs
 --sparse, -S             turn sequences of nulls into sparse blocks
 --preallocate            allocate dest files before writing them
---write-devices          write to devices as files (implies --inplace)
 --dry-run, -n            perform a trial run with no changes made
 --whole-file, -W         copy files whole (w/o delta-xfer algorithm)
 --checksum-choice=STR    choose the checksum algorithm (aka --cc)
@@ -438,7 +524,9 @@ detailed description below for a complete description.
 --include-from=FILE      read include patterns from FILE
 --files-from=FILE        read list of source-file names from FILE
 --from0, -0              all *-from/filter files are delimited by 0s
---protect-args, -s       no space-splitting; wildcard chars only
+--old-args               disable the modern arg-protection idiom
+--secluded-args, -s      use the protocol to safely send the args
+--trust-sender           trust the remote sender's file list
 --copy-as=USER[:GROUP]   specify user & optional group for the copy
 --address=ADDRESS        bind address for outgoing socket to daemon
 --port=PORT              specify double-colon alternate port number
@@ -461,6 +549,7 @@ detailed description below for a complete description.
 --bwlimit=RATE           limit socket I/O bandwidth
 --stop-after=MINS        Stop rsync after MINS minutes have elapsed
 --stop-at=y-m-dTh:m      Stop rsync at the specified point in time
+--fsync                  fsync every written file
 --write-batch=FILE       write a batched update to FILE
 --only-write-batch=FILE  like --write-batch but w/o updating dest
 --read-batch=FILE        read a batched update from FILE
@@ -495,35 +584,46 @@ accepted:
 --help, -h               show this help (when used with --daemon)
 ```
 
-# OPTIONS
+## OPTIONS
 
 Rsync accepts both long (double-dash + word) and short (single-dash + letter)
 options.  The full list of the available options are described below.  If an
 option can be specified in more than one way, the choices are comma-separated.
-Some options only have a long variant, not a short.  If the option takes a
-parameter, the parameter is only listed after the long variant, even though it
-must also be specified for the short.  When specifying a parameter, you can
-either use the form `--option=param` or replace the '=' with whitespace.  The
-parameter may need to be quoted in some manner for it to survive the shell's
-command-line parsing.  Keep in mind that a leading tilde (`~`) in a filename is
-substituted by your shell, so `--option=~/foo` will not change the tilde into
-your home directory (remove the '=' for that).
+Some options only have a long variant, not a short.
+
+If the option takes a parameter, the parameter is only listed after the long
+variant, even though it must also be specified for the short.  When specifying
+a parameter, you can either use the form `--option=param`, `--option param`,
+`-o=param`, `-o param`, or `-oparam` (the latter choices assume that your
+option has a short variant).
+
+The parameter may need to be quoted in some manner for it to survive the
+shell's command-line parsing.  Also keep in mind that a leading tilde (`~`) in
+a pathname is substituted by your shell, so make sure that you separate the
+option name from the pathname using a space if you want the local shell to
+expand it.
+
+[comment]: # (Some markup below uses a literal non-breakable space when a backtick string)
+[comment]: # (needs to contain a space since markdown strips spaces from the start/end)
 
 [comment]: # (An OL starting at 0 is converted into a DL by the parser.)
 
-0.  `--help`, `-h` `(*)`
+0.  `--help`
 
     Print a short help page describing the options available in rsync and exit.
-    (*) The `-h` short option will only invoke `--help` when used without other
-    options since it normally means `--human-readable`.
+    You can also use `-h` for `--help` when it is used without any other
+    options (since it normally means [`--human-readable`](#opt)).
 
 0.  `--version`, `-V`
 
-    Print the rsync version plus other info and exit.
+    Print the rsync version plus other info and exit.  When repeated, the
+    information is output is a JSON format that is still fairly readable
+    (client side only).
 
-    The output includes the default list of checksum algorithms, the default
-    list of compression algorithms, a list of compiled-in capabilities, a link
-    to the rsync web site, and some license/copyright info.
+    The output includes a list of compiled-in capabilities, a list of
+    optimizations, the default list of checksum algorithms, the default list of
+    compression algorithms, the default list of daemon auth digests, a link to
+    the rsync web site, and a few other items.
 
 0.  `--verbose`, `-v`
 
@@ -534,12 +634,24 @@ your home directory (remove the '=' for that).
     being skipped and slightly more information at the end.  More than two `-v`
     options should only be used if you are debugging rsync.
 
+    The end-of-run summary tells you the number of bytes sent to the remote
+    rsync (which is the receiving side on a local copy), the number of bytes
+    received from the remote host, and the average bytes per second of the
+    transferred data computed over the entire length of the rsync run. The
+    second line shows the total size (in bytes), which is the sum of all the
+    file sizes that rsync considered transferring.  It also shows a "speedup"
+    value, which is a ratio of the total file size divided by the sum of the
+    sent and received bytes (which is really just a feel-good bigger-is-better
+    number).  Note that these byte values can be made more (or less)
+    human-readable by using the [`--human-readable`](#opt) (or
+    `--no-human-readable`) options.
+
     In a modern rsync, the `-v` option is equivalent to the setting of groups
-    of `--info` and `--debug` options.  You can choose to use these newer
-    options in addition to, or in place of using `--verbose`, as any
-    fine-grained settings override the implied settings of `-v`.  Both `--info`
-    and `--debug` have a way to ask for help that tells you exactly what flags
-    are set for each increase in verbosity.
+    of [`--info`](#opt) and [`--debug`](#opt) options.  You can choose to use
+    these newer options in addition to, or in place of using `--verbose`, as
+    any fine-grained settings override the implied settings of `-v`.  Both
+    [`--info`](#opt) and [`--debug`](#opt) have a way to ask for help that
+    tells you exactly what flags are set for each increase in verbosity.
 
     However, do keep in mind that a daemon's "`max verbosity`" setting will limit
     how high of a level the various individual flags can be set on the daemon
@@ -560,9 +672,9 @@ your home directory (remove the '=' for that).
     >     rsync -a --info=progress2 src/ dest/
     >     rsync -avv --info=stats2,misc1,flist0 src/ dest/
 
-    Note that `--info=name`'s output is affected by the `--out-format` and
-    `--itemize-changes` (`-i`) options.  See those options for more information
-    on what is output and when.
+    Note that `--info=name`'s output is affected by the [`--out-format`](#opt)
+    and [`--itemize-changes`](#opt) (`-i`) options.  See those options for more
+    information on what is output and when.
 
     This option was added to 3.1.0, so an older rsync on the server side might
     reject your attempts at fine-grained control (if one or more flags needed
@@ -582,8 +694,8 @@ your home directory (remove the '=' for that).
     >     rsync -avvv --debug=none src/ dest/
     >     rsync -avA --del --debug=del2,acl src/ dest/
 
-    Note that some debug messages will only be output when `--stderr=all` is
-    specified, especially those pertaining to I/O and buffer debugging.
+    Note that some debug messages will only be output when the [`--stderr=all`](#opt)
+    option is specified, especially those pertaining to I/O and buffer debugging.
 
     Beginning in 3.2.0, this option is no longer auto-forwarded to the server
     side in order to allow you to specify different debug values for each side
@@ -613,8 +725,8 @@ your home directory (remove the '=' for that).
       divide up the info and error messages by file handle.  For those doing
       debugging or using several levels of verbosity, this option can help to
       avoid clogging up the transfer stream (which should prevent any chance of
-      a deadlock bug hanging things up).  It also enables the outputting of some
-      I/O related debug messages.
+      a deadlock bug hanging things up).  It also allows [`--debug`](#opt) to
+      enable some extra I/O related messages.
 
     - `client` - causes all rsync messages to be sent to the client side
       via the protocol stream.  One client process outputs all messages, with
@@ -651,6 +763,10 @@ your home directory (remove the '=' for that).
     the same modification timestamp.  This option turns off this "quick check"
     behavior, causing all files to be updated.
 
+    This option can be confusing compared to [`--ignore-existing`](#opt) and
+    [`--ignore-non-existing`](#opt) in that that they cause rsync to transfer
+    fewer files, while this option causes rsync to transfer more files.
+
 0.  `--size-only`
 
     This modifies rsync's "quick check" algorithm for finding files that need
@@ -705,62 +821,92 @@ your home directory (remove the '=' for that).
     before-the-transfer "Does this file need to be updated?" check.
 
     The checksum used is auto-negotiated between the client and the server, but
-    can be overridden using either the `--checksum-choice` (`--cc`) option or an
-    environment variable that is discussed in that option's section.
+    can be overridden using either the [`--checksum-choice`](#opt) (`--cc`)
+    option or an environment variable that is discussed in that option's
+    section.
 
 0.  `--archive`, `-a`
 
     This is equivalent to `-rlptgoD`.  It is a quick way of saying you want
-    recursion and want to preserve almost everything (with `-H` being a notable
-    omission).  The only exception to the above equivalence is when
-    `--files-from` is specified, in which case `-r` is not implied.
+    recursion and want to preserve almost everything.  Be aware that it does
+    **not** include preserving ACLs (`-A`), xattrs (`-X`), atimes (`-U`),
+    crtimes (`-N`), nor the finding and preserving of hardlinks (`-H`).
 
-    Note that `-a` **does not preserve hardlinks**, because finding
-    multiply-linked files is expensive.  You must separately specify `-H`.
+    The only exception to the above equivalence is when [`--files-from`](#opt)
+    is specified, in which case [`-r`](#opt) is not implied.
 
 0.  `--no-OPTION`
 
     You may turn off one or more implied options by prefixing the option name
-    with "no-".  Not all options may be prefixed with a "no-": only options that
-    are implied by other options (e.g. `--no-D`, `--no-perms`) or have
-    different defaults in various circumstances (e.g. `--no-whole-file`,
-    `--no-blocking-io`, `--no-dirs`).  You may specify either the short or the
-    long option name after the "no-" prefix (e.g. `--no-R` is the same as
-    `--no-relative`).
-
-    For example: if you want to use `-a` (`--archive`) but don't want `-o`
-    (`--owner`), instead of converting `-a` into `-rlptgD`, you could specify
-    `-a --no-o` (or `-a --no-owner`).
-
-    The order of the options is important: if you specify `--no-r -a`, the
-    `-r` option would end up being turned on, the opposite of `-a --no-r`.
-    Note also that the side-effects of the `--files-from` option are NOT
+    with "no-".  Not all positive options have a negated opposite, but a lot
+    do, including those that can be used to disable an implied option (e.g.
+    `--no-D`, `--no-perms`) or have different defaults in various circumstances
+    (e.g. [`--no-whole-file`](#opt), `--no-blocking-io`, `--no-dirs`).  Every
+    valid negated option accepts both the short and the long option name after
+    the "no-" prefix (e.g. `--no-R` is the same as `--no-relative`).
+
+    As an example, if you want to use [`--archive`](#opt) (`-a`) but don't want
+    [`--owner`](#opt) (`-o`), instead of converting `-a` into `-rlptgD`, you
+    can specify `-a --no-o` (aka `--archive --no-owner`).
+
+    The order of the options is important: if you specify `--no-r -a`, the `-r`
+    option would end up being turned on, the opposite of `-a --no-r`.  Note
+    also that the side-effects of the [`--files-from`](#opt) option are NOT
     positional, as it affects the default state of several options and slightly
-    changes the meaning of `-a` (see the `--files-from` option for more
-    details).
+    changes the meaning of [`-a`](#opt) (see the [`--files-from`](#opt) option
+    for more details).
 
 0.  `--recursive`, `-r`
 
-    This tells rsync to copy directories recursively.  See also `--dirs` (`-d`).
+    This tells rsync to copy directories recursively.  See also
+    [`--dirs`](#opt) (`-d`) for an option that allows the scanning of a single
+    directory.
 
-    Beginning with rsync 3.0.0, the recursive algorithm used is now an
-    incremental scan that uses much less memory than before and begins the
-    transfer after the scanning of the first few directories have been
-    completed.  This incremental scan only affects our recursion algorithm, and
-    does not change a non-recursive transfer.  It is also only possible when
-    both ends of the transfer are at least version 3.0.0.
+    See the [`--inc-recursive`](#opt) option for a discussion of the
+    incremental recursion for creating the list of files to transfer.
 
-    Some options require rsync to know the full file list, so these options
-    disable the incremental recursion mode.  These include: `--delete-before`,
-    `--delete-after`, `--prune-empty-dirs`, and `--delay-updates`.  Because of
-    this, the default delete mode when you specify `--delete` is now
-    `--delete-during` when both ends of the connection are at least 3.0.0 (use
-    `--del` or `--delete-during` to request this improved deletion mode
-    explicitly).  See also the `--delete-delay` option that is a better choice
-    than using `--delete-after`.
+0. `--inc-recursive`, `--i-r`
+
+    This option explicitly enables on incremental recursion when scanning for
+    files, which is enabled by default when using the [`--recursive`](#opt)
+    option and both sides of the transfer are running rsync 3.0.0 or newer.
 
-    Incremental recursion can be disabled using the `--no-inc-recursive` option
-    or its shorter `--no-i-r` alias.
+    Incremental recursion uses much less memory than non-incremental, while
+    also beginning the transfer more quickly (since it doesn't need to scan the
+    entire transfer hierarchy before it starts transferring files).  If no
+    recursion is enabled in the source files, this option has no effect.
+
+    Some options require rsync to know the full file list, so these options
+    disable the incremental recursion mode.  These include:
+    - [`--delete-before`](#opt) (the old default of [`--delete`](#opt))
+    - [`--delete-after`](#opt)
+    - [`--prune-empty-dirs`](#opt)
+    - [`--delay-updates`](#opt)
+
+    In order to make [`--delete`](#opt) compatible with incremental recursion,
+    rsync 3.0.0 made [`--delete-during`](#opt) the default delete mode (which
+    was first added in 2.6.4).
+
+    One side-effect of incremental recursion is that any missing
+    sub-directories inside a recursively-scanned directory are (by default)
+    created prior to recursing into the sub-dirs.  This earlier creation point
+    (compared to a non-incremental recursion) allows rsync to then set the
+    modify time of the finished directory right away (without having to delay
+    that until a bunch of recursive copying has finished).  However, these
+    early directories don't yet have their completed mode, mtime, or ownership
+    set -- they have more restrictive rights until the subdirectory's copying
+    actually begins.  This early-creation idiom can be avoided by using the
+    [`--omit-dir-times`](#opt) option.
+
+    Incremental recursion can be disabled using the
+    [`--no-inc-recursive`](#opt) (`--no-i-r`) option.
+
+0. `--no-inc-recursive`, `--no-i-r`
+
+    Disables the new incremental recursion algorithm of the
+    [`--recursive`](#opt) option.  This makes rsync scan the full file list
+    before it begins to transfer files.  See [`--inc-recursive`](#opt) for more
+    info.
 
 0.  `--relative`, `-R`
 
@@ -789,7 +935,7 @@ your home directory (remove the '=' for that).
     in its path.  If you want to duplicate a server-side symlink, include both
     the symlink via its path, and referent directory via its real path.  If
     you're dealing with an older rsync on the sending side, you may need to use
-    the `--no-implied-dirs` option.
+    the [`--no-implied-dirs`](#opt) option.
 
     It is also possible to limit the amount of path information that is sent as
     implied directories for each path you specify.  With a modern rsync on the
@@ -815,7 +961,7 @@ your home directory (remove the '=' for that).
 
 0.  `--no-implied-dirs`
 
-    This option affects the default behavior of the `--relative` option.  When
+    This option affects the default behavior of the [`--relative`](#opt) option.  When
     it is specified, the attributes of the implied directories from the source
     names are not included in the transfer.  This means that the corresponding
     path elements on the destination system are left unchanged if they exist,
@@ -825,13 +971,13 @@ your home directory (remove the '=' for that).
 
     For instance, if a command-line arg or a files-from entry told rsync to
     transfer the file "path/foo/file", the directories "path" and "path/foo"
-    are implied when `--relative` is used.  If "path/foo" is a symlink to "bar"
+    are implied when [`--relative`](#opt) is used.  If "path/foo" is a symlink to "bar"
     on the destination system, the receiving rsync would ordinarily delete
     "path/foo", recreate it as a directory, and receive the file into the new
     directory.  With `--no-implied-dirs`, the receiving rsync updates
     "path/foo/file" using the existing path elements, which means that the file
     ends up being created in "path/bar".  Another way to accomplish this link
-    preservation is to use the `--keep-dirlinks` option (which will also affect
+    preservation is to use the [`--keep-dirlinks`](#opt) option (which will also affect
     symlinks to directories in the rest of the transfer).
 
     When pulling files from an rsync older than 3.0.0, you may need to use this
@@ -842,27 +988,31 @@ your home directory (remove the '=' for that).
 
     With this option, preexisting destination files are renamed as each file is
     transferred or deleted.  You can control where the backup file goes and
-    what (if any) suffix gets appended using the `--backup-dir` and `--suffix`
-    options.
-
-    Note that if you don't specify `--backup-dir`, (1) the `--omit-dir-times`
-    option will be forced on, and (2) if `--delete` is also in effect (without
-    `--delete-excluded`), rsync will add a "protect" filter-rule for the backup
-    suffix to the end of all your existing excludes (e.g. `-f "P *~"`).  This
-    will prevent previously backed-up files from being deleted.  Note that if
-    you are supplying your own filter rules, you may need to manually insert
-    your own exclude/protect rule somewhere higher up in the list so that it
-    has a high enough priority to be effective (e.g., if your rules specify a
-    trailing inclusion/exclusion of `*`, the auto-added rule would never be
-    reached).
+    what (if any) suffix gets appended using the [`--backup-dir`](#opt) and
+    [`--suffix`](#opt) options.
+
+    If you don't specify [`--backup-dir`](#opt):
+
+    1. the [`--omit-dir-times`](#opt) option will be forced on
+    2. the use of [`--delete`](#opt) (without [`--delete-excluded`](#opt)),
+       causes rsync to add a "protect" [filter-rule](#FILTER_RULES) for the
+       backup suffix to the end of all your existing filters that looks like
+       this: `-f "P *~"`.  This rule prevents previously backed-up files from
+       being deleted.
+
+    Note that if you are supplying your own filter rules, you may need to
+    manually insert your own exclude/protect rule somewhere higher up in the
+    list so that it has a high enough priority to be effective (e.g. if your
+    rules specify a trailing inclusion/exclusion of `*`, the auto-added rule
+    would never be reached).
 
 0.  `--backup-dir=DIR`
 
-    This implies the `--backup` option, and tells rsync to store all
+    This implies the [`--backup`](#opt) option, and tells rsync to store all
     backups in the specified directory on the receiving side.  This can be used
     for incremental backups.  You can additionally specify a backup suffix
-    using the `--suffix` option (otherwise the files backed up in the specified
-    directory will keep their original filenames).
+    using the [`--suffix`](#opt) option (otherwise the files backed up in the
+    specified directory will keep their original filenames).
 
     Note that if you specify a relative path, the backup directory will be
     relative to the destination directory, so you probably want to specify
@@ -873,8 +1023,8 @@ your home directory (remove the '=' for that).
 0.  `--suffix=SUFFIX`
 
     This option allows you to override the default backup suffix used with the
-    `--backup` (`-b`) option.  The default suffix is a `~` if no `--backup-dir`
-    was specified, otherwise it is an empty string.
+    [`--backup`](#opt) (`-b`) option.  The default suffix is a `~` if no
+    [`--backup-dir`](#opt) was specified, otherwise it is an empty string.
 
 0.  `--update`, `-u`
 
@@ -890,9 +1040,15 @@ your home directory (remove the '=' for that).
     directory where the destination has a file, the transfer would occur
     regardless of the timestamps.
 
-    This option is a transfer rule, not an exclude, so it doesn't affect the
-    data that goes into the file-lists, and thus it doesn't affect deletions.
-    It just limits the files that the receiver requests to be transferred.
+    This option is a [TRANSFER RULE](#TRANSFER_RULES), so don't expect any
+    exclude side effects.
+
+    A caution for those that choose to combine [`--inplace`](#opt) with
+    `--update`: an interrupted transfer will leave behind a partial file on the
+    receiving side that has a very recent modified time, so re-running the
+    transfer will probably **not** continue the interrupted file.  As such, it
+    is usually best to avoid combining this with[ `--inplace`](#opt) unless you
+    have implemented manual steps to handle any interrupted in-progress files.
 
 0.  `--inplace`
 
@@ -919,7 +1075,7 @@ your home directory (remove the '=' for that).
       for the open of the file for writing to be successful.
     - The efficiency of rsync's delta-transfer algorithm may be reduced if some
       data in the destination file is overwritten before it can be copied to a
-      position later in the file.  This does not apply if you use `--backup`,
+      position later in the file.  This does not apply if you use [`--backup`](#opt),
       since rsync is smart enough to use the backup file as the basis file for
       the transfer.
 
@@ -931,10 +1087,10 @@ your home directory (remove the '=' for that).
     bound.  It can also help keep a copy-on-write filesystem snapshot from
     diverging the entire contents of a file that only has minor changes.
 
-    The option implies `--partial` (since an interrupted transfer does not
-    delete the file), but conflicts with `--partial-dir` and `--delay-updates`.
-    Prior to rsync 2.6.4 `--inplace` was also incompatible with
-    `--compare-dest` and `--link-dest`.
+    The option implies [`--partial`](#opt) (since an interrupted transfer does
+    not delete the file), but conflicts with [`--partial-dir`](#opt) and
+    [`--delay-updates`](#opt).  Prior to rsync 2.6.4 `--inplace` was also
+    incompatible with [`--compare-dest`](#opt) and [`--link-dest`](#opt).
 
 0.  `--append`
 
@@ -949,7 +1105,9 @@ your home directory (remove the '=' for that).
     existing content in the file (it only verifies the content that it is
     appending).  Rsync skips any files that exist on the receiving side that
     are not shorter than the associated file on the sending side (which means
-    that new files are trasnferred).
+    that new files are transferred).  It also skips any files whose size on the
+    sending side gets shorter during the send negotiations (rsync warns about a
+    "diminished" file when this happens).
 
     This does not interfere with the updating of a file's non-content
     attributes (e.g.  permissions, ownership, etc.) when the file does not need
@@ -958,13 +1116,13 @@ your home directory (remove the '=' for that).
 
 0.  `--append-verify`
 
-    This special copy mode works like `--append` except that all the data in
-    the file is included in the checksum verification (making it much less
+    This special copy mode works like [`--append`](#opt) except that all the
+    data in the file is included in the checksum verification (making it less
     efficient but also potentially safer).  This option **can be dangerous** if
     you aren't 100% sure that all the files in the transfer are shared, growing
-    files.  See the `--append` option for more details.
+    files.  See the [`--append`](#opt) option for more details.
 
-    Note: prior to rsync 3.0.0, the `--append` option worked like
+    Note: prior to rsync 3.0.0, the [`--append`](#opt) option worked like
     `--append-verify`, so if you are interacting with an older rsync (or the
     transfer is using a protocol prior to 30), specifying either append option
     will initiate an `--append-verify` transfer.
@@ -972,64 +1130,88 @@ your home directory (remove the '=' for that).
 0.  `--dirs`, `-d`
 
     Tell the sending side to include any directories that are encountered.
-    Unlike `--recursive`, a directory's contents are not copied unless the
-    directory name specified is "." or ends with a trailing slash (e.g. ".",
-    "dir/.", "dir/", etc.).  Without this option or the `--recursive` option,
-    rsync will skip all directories it encounters (and output a message to that
-    effect for each one).  If you specify both `--dirs` and `--recursive`,
-    `--recursive` takes precedence.
-
-    The `--dirs` option is implied by the `--files-from` option or the
-    `--list-only` option (including an implied `--list-only` usage) if
-    `--recursive` wasn't specified (so that directories are seen in the
-    listing).  Specify `--no-dirs` (or `--no-d`) if you want to turn this off.
-
-    There is also a backward-compatibility helper option, `--old-dirs` (or
-    `--old-d`) that tells rsync to use a hack of `-r --exclude='/*/*'` to get
+    Unlike [`--recursive`](#opt), a directory's contents are not copied unless
+    the directory name specified is "." or ends with a trailing slash (e.g.
+    ".", "dir/.", "dir/", etc.).  Without this option or the
+    [`--recursive`](#opt) option, rsync will skip all directories it encounters
+    (and output a message to that effect for each one).  If you specify both
+    `--dirs` and [`--recursive`](#opt), `--recursive` takes precedence.
+
+    The `--dirs` option is implied by the [`--files-from`](#opt) option or the
+    [`--list-only`](#opt) option (including an implied [`--list-only`](#opt)
+    usage) if [`--recursive`](#opt) wasn't specified (so that directories are
+    seen in the listing).  Specify `--no-dirs` (or `--no-d`) if you want to
+    turn this off.
+
+    There is also a backward-compatibility helper option, `--old-dirs`
+    (`--old-d`) that tells rsync to use a hack of `-r --exclude='/*/*'` to get
     an older rsync to list a single directory without recursing.
 
 0.  `--mkpath`
 
-    Create a missing path component of the destination arg.  This allows rsync
-    to create multiple levels of missing destination dirs and to create a path
-    in which to put a single renamed file.  Keep in mind that you'll need to
-    supply a trailing slash if you want the entire destination path to be
-    treated as a directory when copying a single arg (making rsync behave the
-    same way that it would if the path component of the destination had already
-    existed).
+    Create all missing path components of the destination path.
 
-    For example, the following creates a copy of file foo as bar in the sub/dir
-    directory, creating dirs "sub" and "sub/dir" if either do not yet exist:
+    By default, rsync allows only the final component of the destination path
+    to not exist, which is an attempt to help you to validate your destination
+    path.  With this option, rsync creates all the missing destination-path
+    components, just as if `mkdir -p $DEST_PATH` had been run on the receiving
+    side.
 
-    >     rsync -ai --mkpath foo sub/dir/bar
+    When specifying a destination path, including a trailing slash ensures that
+    the whole path is treated as directory names to be created, even when the
+    file list has a single item. See the [COPYING TO A DIFFERENT NAME](#)
+    section for full details on how rsync decides if a final destination-path
+    component should be created as a directory or not.
 
-    If you instead ran the following, it would have created file foo in the
-    sub/dir/bar directory:
+    If you would like the newly-created destination dirs to match the dirs on
+    the sending side, you should be using [`--relative`](#opt) (`-R`) instead
+    of `--mkpath`.  For instance, the following two commands result in the same
+    destination tree, but only the second command ensures that the
+    "some/extra/path" components match the dirs on the sending side:
 
-    >     rsync -ai --mkpath foo sub/dir/bar/
+    >     rsync -ai --mkpath host:some/extra/path/*.c some/extra/path/
+    >     rsync -aiR host:some/extra/path/*.c ./
 
 0.  `--links`, `-l`
 
-    When symlinks are encountered, recreate the symlink on the destination.
+    Add symlinks to the transferred files instead of noisily ignoring them with
+    a "non-regular file" warning for each symlink encountered.  You can
+    alternately silence the warning by specifying [`--info=nonreg0`](#opt).
+
+    The default handling of symlinks is to recreate each symlink's unchanged
+    value on the receiving side.
+
+    See the [SYMBOLIC LINKS](#) section for multi-option info.
 
 0.  `--copy-links`, `-L`
 
-    When symlinks are encountered, the item that they point to (the referent)
-    is copied, rather than the symlink.  In older versions of rsync, this
-    option also had the side-effect of telling the receiving side to follow
-    symlinks, such as symlinks to directories.  In a modern rsync such as this
-    one, you'll need to specify `--keep-dirlinks` (`-K`) to get this extra
-    behavior.  The only exception is when sending files to an rsync that is too
-    old to understand `-K` -- in that case, the `-L` option will still have the
-    side-effect of `-K` on that older receiving rsync.
+    The sender transforms each symlink encountered in the transfer into the
+    referent item, following the symlink chain to the file or directory that it
+    references.  If a symlink chain is broken, an error is output and the file
+    is dropped from the transfer.
+
+    This option supersedes any other options that affect symlinks in the
+    transfer, since there are no symlinks left in the transfer.
+
+    This option does not change the handling of existing symlinks on the
+    receiving side, unlike versions of rsync prior to 2.6.3 which had the
+    side-effect of telling the receiving side to also follow symlinks.  A
+    modern rsync won't forward this option to a remote receiver (since only the
+    sender needs to know about it), so this caveat should only affect someone
+    using an rsync client older than 2.6.7 (which is when `-L` stopped being
+    forwarded to the receiver).
+
+    See the [`--keep-dirlinks`](#opt) (`-K`) if you need a symlink to a
+    directory to be treated as a real directory on the receiving side.
+
+    See the [SYMBOLIC LINKS](#) section for multi-option info.
 
 0.  `--copy-unsafe-links`
 
     This tells rsync to copy the referent of symbolic links that point outside
     the copied tree.  Absolute symlinks are also treated like ordinary files,
-    and so are any symlinks in the source path itself when `--relative` is
-    used.  This option has no additional effect if `--copy-links` was also
-    specified.
+    and so are any symlinks in the source path itself when [`--relative`](#opt)
+    is used.
 
     Note that the cut-off point is the top of the transfer, which is the part
     of the path that rsync isn't mentioning in the verbose output.  If you copy
@@ -1040,50 +1222,88 @@ your home directory (remove the '=' for that).
     slash) to "/dest/subdir" that would not allow symlinks to any files outside
     of "subdir".
 
+    Note that safe symlinks are only copied if [`--links`](#opt) was also
+    specified or implied. The `--copy-unsafe-links` option has no extra effect
+    when combined with [`--copy-links`](#opt).
+
+    See the [SYMBOLIC LINKS](#) section for multi-option info.
+
 0.  `--safe-links`
 
-    This tells rsync to ignore any symbolic links which point outside the
-    copied tree.  All absolute symlinks are also ignored. Using this option in
-    conjunction with `--relative` may give unexpected results.
+    This tells the receiving rsync to ignore any symbolic links in the transfer
+    which point outside the copied tree.  All absolute symlinks are also
+    ignored.
 
-0.  `--munge-links`
+    Since this ignoring is happening on the receiving side, it will still be
+    effective even when the sending side has munged symlinks (when it is using
+    [`--munge-links`](#opt)). It also affects deletions, since the file being
+    present in the transfer prevents any matching file on the receiver from
+    being deleted when the symlink is deemed to be unsafe and is skipped.
 
-    This option tells rsync to (1) modify all symlinks on the receiving side in
-    a way that makes them unusable but recoverable (see below), or (2) to
-    unmunge symlinks on the sending side that had been stored in a munged
-    state.  This is useful if you don't quite trust the source of the data to
-    not try to slip in a symlink to a unexpected place.
+    This option must be combined with [`--links`](#opt) (or
+    [`--archive`](#opt)) to have any symlinks in the transfer to conditionally
+    ignore. Its effect is superseded by [`--copy-unsafe-links`](#opt).
 
-    The way rsync disables the use of symlinks is to prefix each one with the
-    string "/rsyncd-munged/".  This prevents the links from being used as long
-    as that directory does not exist.  When this option is enabled, rsync will
-    refuse to run if that path is a directory or a symlink to a directory.
+    Using this option in conjunction with [`--relative`](#opt) may give
+    unexpected results.
 
-    The option only affects the client side of the transfer, so if you need it
-    to affect the server, specify it via `--remote-option`. (Note that in a
-    local transfer, the client side is the sender.)
+    See the [SYMBOLIC LINKS](#) section for multi-option info.
 
-    This option has no affect on a daemon, since the daemon configures whether
-    it wants munged symlinks via its "`munge symlinks`" parameter.  See also the
-    "munge-symlinks" perl script in the support directory of the source code.
+0.  `--munge-links`
+
+    This option affects just one side of the transfer and tells rsync to munge
+    symlink values when it is receiving files or unmunge symlink values when it
+    is sending files.  The munged values make the symlinks unusable on disk but
+    allows the original contents of the symlinks to be recovered.
+
+    The server-side rsync often enables this option without the client's
+    knowledge, such as in an rsync daemon's configuration file or by an option
+    given to the rrsync (restricted rsync) script.  When specified on the
+    client side, specify the option normally if it is the client side that
+    has/needs the munged symlinks, or use `-M--munge-links` to give the option
+    to the server when it has/needs the munged symlinks.  Note that on a local
+    transfer, the client is the sender, so specifying the option directly
+    unmunges symlinks while specifying it as a remote option munges symlinks.
+
+    This option has no effect when sent to a daemon via [`--remote-option`](#opt)
+    because the daemon configures whether it wants munged symlinks via its
+    "`munge symlinks`" parameter.
+
+    The symlink value is munged/unmunged once it is in the transfer, so any
+    option that transforms symlinks into non-symlinks occurs prior to the
+    munging/unmunging **except** for [`--safe-links`](#opt), which is a choice
+    that the receiver makes, so it bases its decision on the munged/unmunged
+    value.  This does mean that if a receiver has munging enabled, that using
+    [`--safe-links`](#opt) will cause all symlinks to be ignored (since they
+    are all absolute).
+
+    The method that rsync uses to munge the symlinks is to prefix each one's
+    value with the string "/rsyncd-munged/".  This prevents the links from
+    being used as long as the directory does not exist.  When this option is
+    enabled, rsync will refuse to run if that path is a directory or a symlink
+    to a directory (though it only checks at startup).  See also the
+    "munge-symlinks" python script in the support directory of the source code
+    for a way to munge/unmunge one or more symlinks in-place.
 
 0.  `--copy-dirlinks`, `-k`
 
     This option causes the sending side to treat a symlink to a directory as
     though it were a real directory.  This is useful if you don't want symlinks
-    to non-directories to be affected, as they would be using `--copy-links`.
+    to non-directories to be affected, as they would be using
+    [`--copy-links`](#opt).
 
     Without this option, if the sending side has replaced a directory with a
     symlink to a directory, the receiving side will delete anything that is in
     the way of the new symlink, including a directory hierarchy (as long as
-    `--force` or `--delete` is in effect).
+    [`--force`](#opt) or [`--delete`](#opt) is in effect).
 
-    See also `--keep-dirlinks` for an analogous option for the receiving side.
+    See also [`--keep-dirlinks`](#opt) for an analogous option for the
+    receiving side.
 
     `--copy-dirlinks` applies to all symlinks to directories in the source.  If
     you want to follow only a few specified symlinks, a trick you can use is to
     pass them as additional source args with a trailing slash, using
-    `--relative` to make the paths match up right.  For example:
+    [`--relative`](#opt) to make the paths match up right.  For example:
 
     >     rsync -r --relative src/./ src/./follow-me/ dest/
 
@@ -1092,6 +1312,8 @@ your home directory (remove the '=' for that).
     directory in the file-list which overrides the symlink found during the
     scan of "src/./".
 
+    See the [SYMBOLIC LINKS](#) section for multi-option info.
+
 0.  `--keep-dirlinks`, `-K`
 
     This option causes the receiving side to treat a symlink to a directory as
@@ -1107,14 +1329,18 @@ your home directory (remove the '=' for that).
     "bar".
 
     One note of caution: if you use `--keep-dirlinks`, you must trust all the
-    symlinks in the copy! If it is possible for an untrusted user to create
-    their own symlink to any directory, the user could then (on a subsequent
+    symlinks in the copy or enable the [`--munge-links`](#opt) option on the
+    receiving side!  If it is possible for an untrusted user to create their
+    own symlink to any real directory, the user could then (on a subsequent
     copy) replace the symlink with a real directory and affect the content of
     whatever directory the symlink references.  For backup copies, you are
     better off using something like a bind mount instead of a symlink to modify
     your receiving hierarchy.
 
-    See also `--copy-dirlinks` for an analogous option for the sending side.
+    See also [`--copy-dirlinks`](#opt) for an analogous option for the sending
+    side.
+
+    See the [SYMBOLIC LINKS](#) section for multi-option info.
 
 0.  `--hard-links`, `-H`
 
@@ -1131,41 +1357,42 @@ your home directory (remove the '=' for that).
       is present in the source file list), the copying algorithm will not break
       them explicitly.  However, if one or more of the paths have content
       differences, the normal file-update process will break those extra links
-      (unless you are using the `--inplace` option).
-    - If you specify a `--link-dest` directory that contains hard links, the
-      linking of the destination files against the `--link-dest` files can
-      cause some paths in the destination to become linked together due to the
-      `--link-dest` associations.
+      (unless you are using the [`--inplace`](#opt) option).
+    - If you specify a [`--link-dest`](#opt) directory that contains hard
+      links, the linking of the destination files against the
+      [`--link-dest`](#opt) files can cause some paths in the destination to
+      become linked together due to the [`--link-dest`](#opt) associations.
 
     Note that rsync can only detect hard links between files that are inside
     the transfer set.  If rsync updates a file that has extra hard-link
     connections to files outside the transfer, that linkage will be broken.  If
-    you are tempted to use the `--inplace` option to avoid this breakage, be
+    you are tempted to use the [`--inplace`](#opt) option to avoid this breakage, be
     very careful that you know how your files are being updated so that you are
     certain that no unintended changes happen due to lingering hard links (and
-    see the `--inplace` option for more caveats).
+    see the [`--inplace`](#opt) option for more caveats).
 
-    If incremental recursion is active (see `--recursive`), rsync may transfer
-    a missing hard-linked file before it finds that another link for that
-    contents exists elsewhere in the hierarchy.  This does not affect the
-    accuracy of the transfer (i.e. which files are hard-linked together), just
-    its efficiency (i.e. copying the data for a new, early copy of a
+    If incremental recursion is active (see [`--inc-recursive`](#opt)), rsync
+    may transfer a missing hard-linked file before it finds that another link
+    for that contents exists elsewhere in the hierarchy.  This does not affect
+    the accuracy of the transfer (i.e. which files are hard-linked together),
+    just its efficiency (i.e. copying the data for a new, early copy of a
     hard-linked file that could have been found later in the transfer in
     another member of the hard-linked set of files).  One way to avoid this
     inefficiency is to disable incremental recursion using the
-    `--no-inc-recursive` option.
+    [`--no-inc-recursive`](#opt) option.
 
 0.  `--perms`, `-p`
 
     This option causes the receiving rsync to set the destination permissions
-    to be the same as the source permissions. (See also the `--chmod` option
-    for a way to modify what rsync considers to be the source permissions.)
+    to be the same as the source permissions. (See also the [`--chmod`](#opt)
+    option for a way to modify what rsync considers to be the source
+    permissions.)
 
     When this option is _off_, permissions are set as follows:
 
     - Existing files (including updated files) retain their existing
-      permissions, though the `--executability` option might change just the
-      execute permission for the file.
+      permissions, though the [`--executability`](#opt) option might change
+      just the execute permission for the file.
     - New files get their "normal" permission bits set to the source file's
       permissions masked with the receiving directory's default permissions
       (either the receiving process's umask, or the permissions specified via
@@ -1173,18 +1400,19 @@ your home directory (remove the '=' for that).
       bits disabled except in the case where a new directory inherits a setgid
       bit from its parent directory.
 
-    Thus, when `--perms` and `--executability` are both disabled, rsync's
+    Thus, when `--perms` and [`--executability`](#opt) are both disabled, rsync's
     behavior is the same as that of other file-copy utilities, such as **cp**(1)
     and **tar**(1).
 
     In summary: to give destination files (both old and new) the source
     permissions, use `--perms`.  To give new files the destination-default
     permissions (while leaving existing files unchanged), make sure that the
-    `--perms` option is off and use `--chmod=ugo=rwX` (which ensures that all
-    non-masked bits get enabled).  If you'd care to make this latter behavior
-    easier to type, you could define a popt alias for it, such as putting this
-    line in the file `~/.popt` (the following defines the `-Z` option, and
-    includes `--no-g` to use the default group of the destination dir):
+    `--perms` option is off and use [`--chmod=ugo=rwX`](#opt) (which ensures
+    that all non-masked bits get enabled).  If you'd care to make this latter
+    behavior easier to type, you could define a popt alias for it, such as
+    putting this line in the file `~/.popt` (the following defines the `-Z`
+    option, and includes `--no-g` to use the default group of the destination
+    dir):
 
     >      rsync alias -Z --no-p --no-g --chmod=ugo=rwX
 
@@ -1208,8 +1436,8 @@ your home directory (remove the '=' for that).
 0.  `--executability`, `-E`
 
     This option causes rsync to preserve the executability (or
-    non-executability) of regular files when `--perms` is not enabled.  A
-    regular file is considered to be executable if at least one 'x' is turned
+    non-executability) of regular files when [`--perms`](#opt) is not enabled.
+    regular file is considered to be executable if at least one 'x' is turned
     on in its permissions.  When an existing destination file's executability
     differs from that of the corresponding source file, rsync modifies the
     destination file's permissions as follows:
@@ -1218,16 +1446,16 @@ your home directory (remove the '=' for that).
     - To make a file executable, rsync turns on each 'x' permission that has a
       corresponding 'r' permission enabled.
 
-    If `--perms` is enabled, this option is ignored.
+    If [`--perms`](#opt) is enabled, this option is ignored.
 
 0.  `--acls`, `-A`
 
     This option causes rsync to update the destination ACLs to be the same as
-    the source ACLs.  The option also implies `--perms`.
+    the source ACLs.  The option also implies [`--perms`](#opt).
 
     The source and destination systems must have compatible ACL entries for
-    this option to work properly.  See the `--fake-super` option for a way to
-    backup and restore ACLs that are not compatible.
+    this option to work properly.  See the [`--fake-super`](#opt) option for a
+    way to backup and restore ACLs that are not compatible.
 
 0.  `--xattrs`, `-X`
 
@@ -1237,7 +1465,7 @@ your home directory (remove the '=' for that).
     For systems that support extended-attribute namespaces, a copy being done
     by a super-user copies all namespaces except system.\*.  A normal user only
     copies the user.\* namespace.  To be able to backup and restore non-user
-    namespaces as a normal user, see the `--fake-super` option.
+    namespaces as a normal user, see the [`--fake-super`](#opt) option.
 
     The above name filtering can be overridden by using one or more filter
     options with the **x** modifier.  When you specify an xattr-affecting
@@ -1259,8 +1487,8 @@ your home directory (remove the '=' for that).
     >     --filter='-xr *'
 
     Note that the `-X` option does not copy rsync's special xattr values (e.g.
-    those used by `--fake-super`) unless you repeat the option (e.g. `-XX`).
-    This "copy all xattrs" mode cannot be used with `--fake-super`.
+    those used by [`--fake-super`](#opt)) unless you repeat the option (e.g. `-XX`).
+    This "copy all xattrs" mode cannot be used with [`--fake-super`](#opt).
 
 0.  `--chmod=CHMOD`
 
@@ -1268,7 +1496,7 @@ your home directory (remove the '=' for that).
     to the permission of the files in the transfer.  The resulting value is
     treated as though it were the permissions that the sending side supplied
     for the file, which means that this option can seem to have no effect on
-    existing files if `--perms` is not enabled.
+    existing files if [`--perms`](#opt) is not enabled.
 
     In addition to the normal parsing rules specified in the **chmod**(1)
     manpage, you can specify an item that should only apply to a directory by
@@ -1287,20 +1515,20 @@ your home directory (remove the '=' for that).
     It is also legal to specify multiple `--chmod` options, as each additional
     option is just appended to the list of changes to make.
 
-    See the `--perms` and `--executability` options for how the resulting
-    permission value can be applied to the files in the transfer.
+    See the [`--perms`](#opt) and [`--executability`](#opt) options for how the
+    resulting permission value can be applied to the files in the transfer.
 
 0.  `--owner`, `-o`
 
     This option causes rsync to set the owner of the destination file to be the
     same as the source file, but only if the receiving rsync is being run as
-    the super-user (see also the `--super` and `--fake-super` options).  Without
-    this option, the owner of new and/or transferred files are set to the
-    invoking user on the receiving side.
+    the super-user (see also the [`--super`](#opt) and [`--fake-super`](#opt)
+    options).  Without this option, the owner of new and/or transferred files
+    are set to the invoking user on the receiving side.
 
     The preservation of ownership will associate matching names by default, but
     may fall back to using the ID number in some circumstances (see also the
-    `--numeric-ids` option for a full discussion).
+    [`--numeric-ids`](#opt) option for a full discussion).
 
 0.  `--group`, `-g`
 
@@ -1313,60 +1541,88 @@ your home directory (remove the '=' for that).
 
     The preservation of group information will associate matching names by
     default, but may fall back to using the ID number in some circumstances
-    (see also the `--numeric-ids` option for a full discussion).
+    (see also the [`--numeric-ids`](#opt) option for a full discussion).
 
 0.  `--devices`
 
     This option causes rsync to transfer character and block device files to
-    the remote system to recreate these devices.  This option has no effect if
-    the receiving rsync is not run as the super-user (see also the `--super`
-    and `--fake-super` options).
+    the remote system to recreate these devices.  If the receiving rsync is not
+    being run as the super-user, rsync silently skips creating the device files
+    (see also the [`--super`](#opt) and [`--fake-super`](#opt) options).
+
+    By default, rsync generates a "non-regular file" warning for each device
+    file encountered when this option is not set.  You can silence the warning
+    by specifying [`--info=nonreg0`](#opt).
 
 0.  `--specials`
 
-    This option causes rsync to transfer special files such as named sockets
-    and fifos.
+    This option causes rsync to transfer special files, such as named sockets
+    and fifos.  If the receiving rsync is not being run as the super-user,
+    rsync silently skips creating the special files (see also the
+    [`--super`](#opt) and [`--fake-super`](#opt) options).
+
+    By default, rsync generates a "non-regular file" warning for each special
+    file encountered when this option is not set.  You can silence the warning
+    by specifying [`--info=nonreg0`](#opt).
 
 0.  `-D`
 
-    The `-D` option is equivalent to `--devices --specials`.
+    The `-D` option is equivalent to "[`--devices`](#opt)
+    [`--specials`](#opt)".
+
+0.  `--copy-devices`
+
+    This tells rsync to treat a device on the sending side as a regular file,
+    allowing it to be copied to a normal destination file (or another device
+    if `--write-devices` was also specified).
+
+    This option is refused by default by an rsync daemon.
 
 0.  `--write-devices`
 
     This tells rsync to treat a device on the receiving side as a regular file,
     allowing the writing of file data into a device.
 
-    This option implies the `--inplace` option.
+    This option implies the [`--inplace`](#opt) option.
 
     Be careful using this, as you should know what devices are present on the
-    receiving side of the transfer, especially if running rsync as root.
+    receiving side of the transfer, especially when running rsync as root.
 
-    This option is refused by an rsync daemon.
+    This option is refused by default by an rsync daemon.
 
 0.  `--times`, `-t`
 
     This tells rsync to transfer modification times along with the files and
     update them on the remote system.  Note that if this option is not used,
     the optimization that excludes files that have not been modified cannot be
-    effective; in other words, a missing `-t` or `-a` will cause the next
-    transfer to behave as if it used `-I`, causing all files to be updated
-    (though rsync's delta-transfer algorithm will make the update fairly
-    efficient if the files haven't actually changed, you're much better off
-    using `-t`).
+    effective; in other words, a missing `-t` (or [`-a`](#opt)) will cause the
+    next transfer to behave as if it used [`--ignore-times`](#opt) (`-I`),
+    causing all files to be updated (though rsync's delta-transfer algorithm
+    will make the update fairly efficient if the files haven't actually
+    changed, you're much better off using `-t`).
+
+    A modern rsync that is using transfer protocol 30 or 31 conveys a modify
+    time using up to 8-bytes. If rsync is forced to speak an older protocol
+    (perhaps due to the remote rsync being older than 3.0.0) a modify time is
+    conveyed using 4-bytes. Prior to 3.2.7, these shorter values could convey
+    a date range of 13-Dec-1901 to 19-Jan-2038.  Beginning with 3.2.7, these
+    4-byte values now convey a date range of 1-Jan-1970 to 7-Feb-2106.  If you
+    have files dated older than 1970, make sure your rsync executables are
+    upgraded so that the full range of dates can be conveyed.
 
 0.  `--atimes`, `-U`
 
     This tells rsync to set the access (use) times of the destination files to
     the same value as the source files.
 
-    If repeated, it also sets the `--open-noatime` option, which can help you
+    If repeated, it also sets the [`--open-noatime`](#opt) option, which can help you
     to make the sending and receiving systems have the same access times on the
     transferred files without needing to run rsync an extra time after a file
     is transferred.
 
     Note that some older rsync versions (prior to 3.2.0) may have been built
-    with a pre-release `--atimes` patch that does not imply `--open-noatime`
-    when this option is repeated.
+    with a pre-release `--atimes` patch that does not imply
+    [`--open-noatime`](#opt) when this option is repeated.
 
 0.  `--open-noatime`
 
@@ -1384,37 +1640,31 @@ your home directory (remove the '=' for that).
 
 0.  `--omit-dir-times`, `-O`
 
-    This tells rsync to omit directories when it is preserving modification
-    times (see `--times`).  If NFS is sharing the directories on the receiving
+    This tells rsync to omit directories when it is preserving modification,
+    access, and create times.  If NFS is sharing the directories on the receiving
     side, it is a good idea to use `-O`.  This option is inferred if you use
-    `--backup` without `--backup-dir`.
-
-    This option also has the side-effect of avoiding early creation of
-    directories in incremental recursion copies.  The default `--inc-recursive`
-    copying normally does an early-create pass of all the sub-directories in a
-    parent directory in order for it to be able to then set the modify time of
-    the parent directory right away (without having to delay that until a bunch
-    of recursive copying has finished).  This early-create idiom is not
-    necessary if directory modify times are not being preserved, so it is
-    skipped.  Since early-create directories don't have accurate mode, mtime,
-    or ownership, the use of this option can help when someone wants to avoid
-    these partially-finished directories.
+    [`--backup`](#opt) without [`--backup-dir`](#opt).
+
+    This option also has the side-effect of avoiding early creation of missing
+    sub-directories when incremental recursion is enabled, as discussed in the
+    [`--inc-recursive`](#opt) section.
 
 0.  `--omit-link-times`, `-J`
 
-    This tells rsync to omit symlinks when it is preserving modification times
-    (see `--times`).
+    This tells rsync to omit symlinks when it is preserving modification,
+    access, and create times.
 
 0.  `--super`
 
     This tells the receiving side to attempt super-user activities even if the
     receiving rsync wasn't run by the super-user.  These activities include:
-    preserving users via the `--owner` option, preserving all groups (not just
-    the current user's groups) via the `--groups` option, and copying devices
-    via the `--devices` option.  This is useful for systems that allow such
-    activities without being the super-user, and also for ensuring that you
-    will get errors if the receiving side isn't being run as the super-user.
-    To turn off super-user activities, the super-user can use `--no-super`.
+    preserving users via the [`--owner`](#opt) option, preserving all groups
+    (not just the current user's groups) via the [`--group`](#opt) option, and
+    copying devices via the [`--devices`](#opt) option.  This is useful for
+    systems that allow such activities without being the super-user, and also
+    for ensuring that you will get errors if the receiving side isn't being run
+    as the super-user.  To turn off super-user activities, the super-user can
+    use `--no-super`.
 
 0.  `--fake-super`
 
@@ -1427,15 +1677,15 @@ your home directory (remove the '=' for that).
     u-s,g-s,o-t for safety) or that would limit the owner's access (since the
     real super-user can always access/change a file, the files we create can
     always be accessed/changed by the creating user).  This option also handles
-    ACLs (if `--acls` was specified) and non-user extended attributes (if
-    `--xattrs` was specified).
+    ACLs (if [`--acls`](#opt) was specified) and non-user extended attributes
+    (if [`--xattrs`](#opt) was specified).
 
     This is a good way to backup data without using a super-user, and to store
     ACLs from incompatible systems.
 
     The `--fake-super` option only affects the side where the option is used.
     To affect the remote side of a remote-shell connection, use the
-    `--remote-option` (`-M`) option:
+    [`--remote-option`](#opt) (`-M`) option:
 
     >     rsync -av -M--fake-super /src/ host:/dest/
 
@@ -1444,21 +1694,22 @@ your home directory (remove the '=' for that).
     files, specify `-M--fake-super`.  If you wish a local copy to enable this
     option just for the source files, combine `--fake-super` with `-M--super`.
 
-    This option is overridden by both `--super` and `--no-super`.
+    This option is overridden by both [`--super`](#opt) and `--no-super`.
 
-    See also the "`fake super`" setting in the daemon's rsyncd.conf file.
+    See also the [`fake super`](rsyncd.conf.5#fake_super) setting in the
+    daemon's rsyncd.conf file.
 
 0.  `--sparse`, `-S`
 
     Try to handle sparse files efficiently so they take up less space on the
-    destination.  If combined with `--inplace` the file created might not end
-    up with sparse blocks with some combinations of kernel version and/or
-    filesystem type.  If `--whole-file` is in effect (e.g. for a local copy)
-    then it will always work because rsync truncates the file prior to writing
-    out the updated version.
+    destination.  If combined with [`--inplace`](#opt) the file created might
+    not end up with sparse blocks with some combinations of kernel version
+    and/or filesystem type.  If [`--whole-file`](#opt) is in effect (e.g. for a
+    local copy) then it will always work because rsync truncates the file prior
+    to writing out the updated version.
 
     Note that versions of rsync older than 3.1.3 will reject the combination of
-    `--sparse` and `--inplace`.
+    `--sparse` and [`--inplace`](#opt).
 
 0.  `--preallocate`
 
@@ -1473,26 +1724,26 @@ your home directory (remove the '=' for that).
     the destination is not an extent-supporting filesystem (such as ext4, xfs,
     NTFS, etc.), this option may have no positive effect at all.
 
-    If combined with `--sparse`, the file will only have sparse blocks (as
-    opposed to allocated sequences of null bytes) if the kernel version and
+    If combined with [`--sparse`](#opt), the file will only have sparse blocks
+    (as opposed to allocated sequences of null bytes) if the kernel version and
     filesystem type support creating holes in the allocated data.
 
 0.  `--dry-run`, `-n`
 
     This makes rsync perform a trial run that doesn't make any changes (and
     produces mostly the same output as a real run).  It is most commonly used
-    in combination with the `--verbose`, `-v` and/or `--itemize-changes`, `-i`
-    options to see what an rsync command is going to do before one actually
-    runs it.
-
-    The output of `--itemize-changes` is supposed to be exactly the same on a
-    dry run and a subsequent real run (barring intentional trickery and system
-    call failures); if it isn't, that's a bug.  Other output should be mostly
-    unchanged, but may differ in some areas.  Notably, a dry run does not send
-    the actual data for file transfers, so `--progress` has no effect, the
-    "bytes sent", "bytes received", "literal data", and "matched data"
-    statistics are too small, and the "speedup" value is equivalent to a run
-    where no file transfers were needed.
+    in combination with the [`--verbose`](#opt) (`-v`) and/or
+    [`--itemize-changes`](#opt) (`-i`) options to see what an rsync command is
+    going to do before one actually runs it.
+
+    The output of [`--itemize-changes`](#opt) is supposed to be exactly the
+    same on a dry run and a subsequent real run (barring intentional trickery
+    and system call failures); if it isn't, that's a bug.  Other output should
+    be mostly unchanged, but may differ in some areas.  Notably, a dry run does
+    not send the actual data for file transfers, so [`--progress`](#opt) has no
+    effect, the "bytes sent", "bytes received", "literal data", and "matched
+    data" statistics are too small, and the "speedup" value is equivalent to a
+    run where no file transfers were needed.
 
 0.  `--whole-file`, `-W`
 
@@ -1504,11 +1755,20 @@ your home directory (remove the '=' for that).
     source and destination are specified as local paths, but only if no
     batch-writing option is in effect.
 
+0. `--no-whole-file`, `--no-W`
+
+    Disable whole-file updating when it is enabled by default for a local
+    transfer.  This usually slows rsync down, but it can be useful if you are
+    trying to minimize the writes to the destination file (if combined with
+    [`--inplace`](#opt)) or for testing the checksum-based update algorithm.
+
+    See also the [`--whole-file`](#opt) option.
+
 0.  `--checksum-choice=STR`, `--cc=STR`
 
     This option overrides the checksum algorithms.  If one algorithm name is
     specified, it is used for both the transfer checksums and (assuming
-    `--checksum` is specified) the pre-transfer checksums.  If two
+    [`--checksum`](#opt) is specified) the pre-transfer checksums.  If two
     comma-separated names are supplied, the first name affects the transfer
     checksums, and the second name affects the pre-transfer checksums (`-c`).
 
@@ -1520,15 +1780,16 @@ your home directory (remove the '=' for that).
     - `xxh64` (aka `xxhash`)
     - `md5`
     - `md4`
+    - `sha1`
     - `none`
 
     Run `rsync --version` to see the default checksum list compiled into your
     version (which may differ from the list above).
 
-    If "none" is specified for the first (or only) name, the `--whole-file`
+    If "none" is specified for the first (or only) name, the [`--whole-file`](#opt)
     option is forced on and no checksum verification is performed on the
     transferred data.  If "none" is specified for the second (or only) name,
-    the `--checksum` option cannot be used.
+    the [`--checksum`](#opt) option cannot be used.
 
     The "auto" option is the default, where rsync bases its algorithm choice on
     a negotiation between the client and the server as follows:
@@ -1541,14 +1802,14 @@ your home directory (remove the '=' for that).
     and various flavors of MD4 based on protocol age).
 
     The default order can be customized by setting the environment variable
-    RSYNC_CHECKSUM_LIST to a space-separated list of acceptable checksum names.
-    If the string contains a "`&`" character, it is separated into the "client
-    string & server string", otherwise the same string
-    applies to both.  If the string (or string portion) contains no
-    non-whitespace characters, the default checksum list is used.  This method
-    does not allow you to specify the transfer checksum separately from the
-    pre-transfer checksum, and it discards "auto" and all unknown checksum
-    names.  A list with only invalid names results in a failed negotiation.
+    [`RSYNC_CHECKSUM_LIST`](#) to a space-separated list of acceptable checksum
+    names.  If the string contains a "`&`" character, it is separated into the
+    "client string & server string", otherwise the same string applies to both.
+    If the string (or string portion) contains no non-whitespace characters,
+    the default checksum list is used.  This method does not allow you to
+    specify the transfer checksum separately from the pre-transfer checksum,
+    and it discards "auto" and all unknown checksum names.  A list with only
+    invalid names results in a failed negotiation.
 
     The use of the `--checksum-choice` option overrides this environment list.
 
@@ -1566,39 +1827,45 @@ your home directory (remove the '=' for that).
     encounters (using the attributes of the mounted directory because those of
     the underlying mount-point directory are inaccessible).
 
-    If rsync has been told to collapse symlinks (via `--copy-links` or
-    `--copy-unsafe-links`), a symlink to a directory on another device is
-    treated like a mount-point.  Symlinks to non-directories are unaffected by
-    this option.
+    If rsync has been told to collapse symlinks (via [`--copy-links`](#opt) or
+    [`--copy-unsafe-links`](#opt)), a symlink to a directory on another device
+    is treated like a mount-point.  Symlinks to non-directories are unaffected
+    by this option.
 
-0.  `--existing`, `--ignore-non-existing`
+0.  `--ignore-non-existing`, `--existing`
 
     This tells rsync to skip creating files (including directories) that do not
     exist yet on the destination.  If this option is combined with the
-    `--ignore-existing` option, no files will be updated (which can be useful
-    if all you want to do is delete extraneous files).
+    [`--ignore-existing`](#opt) option, no files will be updated (which can be
+    useful if all you want to do is delete extraneous files).
 
-    This option is a transfer rule, not an exclude, so it doesn't affect the
-    data that goes into the file-lists, and thus it doesn't affect deletions.
-    It just limits the files that the receiver requests to be transferred.
+    This option is a [TRANSFER RULE](#TRANSFER_RULES), so don't expect any
+    exclude side effects.
 
 0.  `--ignore-existing`
 
     This tells rsync to skip updating files that already exist on the
     destination (this does _not_ ignore existing directories, or nothing would
-    get done).  See also `--existing`.
-
-    This option is a transfer rule, not an exclude, so it doesn't affect the
-    data that goes into the file-lists, and thus it doesn't affect deletions.
-    It just limits the files that the receiver requests to be transferred.
-
-    This option can be useful for those doing backups using the `--link-dest`
-    option when they need to continue a backup run that got interrupted.  Since
-    a `--link-dest` run is copied into a new directory hierarchy (when it is
-    used properly), using `--ignore-existing` will ensure that the
-    already-handled files don't get tweaked (which avoids a change in
-    permissions on the hard-linked files).  This does mean that this option is
-    only looking at the existing files in the destination hierarchy itself.
+    get done).  See also [`--ignore-non-existing`](#opt).
+
+    This option is a [TRANSFER RULE](#TRANSFER_RULES), so don't expect any
+    exclude side effects.
+
+    This option can be useful for those doing backups using the
+    [`--link-dest`](#opt) option when they need to continue a backup run that
+    got interrupted.  Since a [`--link-dest`](#opt) run is copied into a new
+    directory hierarchy (when it is used properly), using [`--ignore-existing`
+    will ensure that the already-handled files don't get tweaked (which avoids
+    a change in permissions on the hard-linked files).  This does mean that
+    this option is only looking at the existing files in the destination
+    hierarchy itself.
+
+    When [`--info=skip2`](#opt) is used rsync will output "FILENAME exists
+    (INFO)" messages where the INFO indicates one of "type change", "sum
+    change" (requires [`-c`](#opt)), "file change" (based on the quick check),
+    "attr change", or "uptodate".  Using [`--info=skip1`](#opt) (which is also
+    implied by 2 [`-v`](#opt) options) outputs the exists message without the
+    INFO suffix.
 
 0.  `--remove-source-files`
 
@@ -1614,12 +1881,16 @@ your home directory (remove the '=' for that).
     If you can't first write the files into a different directory, you should
     use a naming idiom that lets rsync avoid transferring files that are not
     yet finished (e.g. name the file "foo.new" when it is written, rename it to
-    "foo" when it is done, and then use the option `--exclude='*.new'` for the
-    rsync transfer).
+    "foo" when it is done, and then use the option [`--exclude='*.new'`](#opt)
+    for the rsync transfer).
 
     Starting with 3.1.0, rsync will skip the sender-side removal (and output an
     error) if the file's size or modify time has not stayed unchanged.
 
+    Starting with 3.2.6, a local rsync copy will ensure that the sender does
+    not remove a file the receiver just verified, such as when the user
+    accidentally makes the source and destination directory the same path.
+
 0.  `--delete`
 
     This tells rsync to delete extraneous files from the receiving side (ones
@@ -1629,70 +1900,71 @@ your home directory (remove the '=' for that).
     contents (e.g. "`dir/*`") since the wildcard is expanded by the shell and
     rsync thus gets a request to transfer individual files, not the files'
     parent directory.  Files that are excluded from the transfer are also
-    excluded from being deleted unless you use the `--delete-excluded` option
-    or mark the rules as only matching on the sending side (see the
-    include/exclude modifiers in the FILTER RULES section).
+    excluded from being deleted unless you use the [`--delete-excluded`](#opt)
+    option or mark the rules as only matching on the sending side (see the
+    include/exclude modifiers in the [FILTER RULES](#) section).
 
-    Prior to rsync 2.6.7, this option would have no effect unless `--recursive`
-    was enabled.  Beginning with 2.6.7, deletions will also occur when `--dirs`
-    (`-d`) is enabled, but only for directories whose contents are being
-    copied.
+    Prior to rsync 2.6.7, this option would have no effect unless
+    [`--recursive`](#opt) was enabled.  Beginning with 2.6.7, deletions will
+    also occur when [`--dirs`](#opt) (`-d`) is enabled, but only for
+    directories whose contents are being copied.
 
     This option can be dangerous if used incorrectly! It is a very good idea to
-    first try a run using the `--dry-run` option (`-n`) to see what files are
-    going to be deleted.
+    first try a run using the [`--dry-run`](#opt) (`-n`) option to see what
+    files are going to be deleted.
 
     If the sending side detects any I/O errors, then the deletion of any files
     at the destination will be automatically disabled.  This is to prevent
     temporary filesystem failures (such as NFS errors) on the sending side from
     causing a massive deletion of files on the destination.  You can override
-    this with the `--ignore-errors` option.
+    this with the [`--ignore-errors`](#opt) option.
 
     The `--delete` option may be combined with one of the --delete-WHEN options
-    without conflict, as well as `--delete-excluded`.  However, if none of the
-    `--delete-WHEN` options are specified, rsync will choose the
-    `--delete-during` algorithm when talking to rsync 3.0.0 or newer, and the
-    `--delete-before` algorithm when talking to an older rsync.  See also
-    `--delete-delay` and `--delete-after`.
+    without conflict, as well as [`--delete-excluded`](#opt).  However, if none
+    of the `--delete-WHEN` options are specified, rsync will choose the
+    [`--delete-during`](#opt) algorithm when talking to rsync 3.0.0 or newer,
+    or the [`--delete-before`](#opt) algorithm when talking to an older rsync.
+    See also [`--delete-delay`](#opt) and [`--delete-after`](#opt).
 
 0.  `--delete-before`
 
     Request that the file-deletions on the receiving side be done before the
-    transfer starts.  See `--delete` (which is implied) for more details on
-    file-deletion.
+    transfer starts.  See [`--delete`](#opt) (which is implied) for more
+    details on file-deletion.
 
     Deleting before the transfer is helpful if the filesystem is tight for
     space and removing extraneous files would help to make the transfer
     possible.  However, it does introduce a delay before the start of the
     transfer, and this delay might cause the transfer to timeout (if
-    `--timeout` was specified).  It also forces rsync to use the old,
+    [`--timeout`](#opt) was specified).  It also forces rsync to use the old,
     non-incremental recursion algorithm that requires rsync to scan all the
-    files in the transfer into memory at once (see `--recursive`).
+    files in the transfer into memory at once (see [`--recursive`](#opt)).
 
 0.  `--delete-during`, `--del`
 
     Request that the file-deletions on the receiving side be done incrementally
     as the transfer happens.  The per-directory delete scan is done right
     before each directory is checked for updates, so it behaves like a more
-    efficient `--delete-before`, including doing the deletions prior to any
-    per-directory filter files being updated.  This option was first added in
-    rsync version 2.6.4.  See `--delete` (which is implied) for more details on
-    file-deletion.
+    efficient [`--delete-before`](#opt), including doing the deletions prior to
+    any per-directory filter files being updated.  This option was first added
+    in rsync version 2.6.4.  See [`--delete`](#opt) (which is implied) for more
+    details on file-deletion.
 
 0.  `--delete-delay`
 
     Request that the file-deletions on the receiving side be computed during
-    the transfer (like `--delete-during`), and then removed after the transfer
-    completes.  This is useful when combined with `--delay-updates` and/or
-    `--fuzzy`, and is more efficient than using `--delete-after` (but can
-    behave differently, since `--delete-after` computes the deletions in a
-    separate pass after all updates are done).  If the number of removed files
-    overflows an internal buffer, a temporary file will be created on the
-    receiving side to hold the names (it is removed while open, so you
-    shouldn't see it during the transfer).  If the creation of the temporary
-    file fails, rsync will try to fall back to using `--delete-after` (which it
-    cannot do if `--recursive` is doing an incremental scan).  See `--delete`
-    (which is implied) for more details on file-deletion.
+    the transfer (like [`--delete-during`](#opt)), and then removed after the
+    transfer completes.  This is useful when combined with
+    [`--delay-updates`](#opt) and/or [`--fuzzy`](#opt), and is more efficient
+    than using [`--delete-after`](#opt) (but can behave differently, since
+    [`--delete-after`](#opt) computes the deletions in a separate pass after
+    all updates are done).  If the number of removed files overflows an
+    internal buffer, a temporary file will be created on the receiving side to
+    hold the names (it is removed while open, so you shouldn't see it during
+    the transfer).  If the creation of the temporary file fails, rsync will try
+    to fall back to using [`--delete-after`](#opt) (which it cannot do if
+    [`--recursive`](#opt) is doing an incremental scan).  See
+    [`--delete`](#opt) (which is implied) for more details on file-deletion.
 
 0.  `--delete-after`
 
@@ -1702,53 +1974,70 @@ your home directory (remove the '=' for that).
     exclusions to take effect for the delete phase of the current transfer.  It
     also forces rsync to use the old, non-incremental recursion algorithm that
     requires rsync to scan all the files in the transfer into memory at once
-    (see `--recursive`). See `--delete` (which is implied) for more details on
-    file-deletion.
+    (see [`--recursive`](#opt)). See [`--delete`](#opt) (which is implied) for
+    more details on file-deletion.
+
+    See also the [`--delete-delay`](#opt) option that might be a faster choice
+    for those that just want the deletions to occur at the end of the transfer.
 
 0.  `--delete-excluded`
 
-    In addition to deleting the files on the receiving side that are not on the
-    sending side, this tells rsync to also delete any files on the receiving
-    side that are excluded (see `--exclude`).  See the FILTER RULES section for
-    a way to make individual exclusions behave this way on the receiver, and
-    for a way to protect files from `--delete-excluded`.  See `--delete` (which
-    is implied) for more details on file-deletion.
+    This option turns any unqualified exclude/include rules into server-side
+    rules that do not affect the receiver's deletions.
+
+    By default, an exclude or include has both a server-side effect (to "hide"
+    and "show" files when building the server's file list) and a receiver-side
+    effect (to "protect" and "risk" files when deletions are occurring).  Any
+    rule that has no modifier to specify what sides it is executed on will be
+    instead treated as if it were a server-side rule only, avoiding any
+    "protect" effects of the rules.
+
+    A rule can still apply to both sides even with this option specified if the
+    rule is given both the sender & receiver modifier letters (e.g., `-f'-sr
+    foo'`).  Receiver-side protect/risk rules can also be explicitly specified
+    to limit the deletions.  This saves you from having to edit a bunch of
+    `-f'- foo'` rules into `-f'-s foo'` (aka `-f'H foo'`) rules (not to mention
+    the corresponding includes).
+
+    See the [FILTER RULES](#) section for more information.  See
+    [`--delete`](#opt) (which is implied) for more details on deletion.
 
 0.  `--ignore-missing-args`
 
     When rsync is first processing the explicitly requested source files (e.g.
-    command-line arguments or `--files-from` entries), it is normally an error
-    if the file cannot be found.  This option suppresses that error, and does
-    not try to transfer the file.  This does not affect subsequent
+    command-line arguments or [`--files-from`](#opt) entries), it is normally
+    an error if the file cannot be found.  This option suppresses that error,
+    and does not try to transfer the file.  This does not affect subsequent
     vanished-file errors if a file was initially found to be present and later
     is no longer there.
 
 0.  `--delete-missing-args`
 
-    This option takes the behavior of (the implied) `--ignore-missing-args`
-    option a step farther: each missing arg will become a deletion request of
-    the corresponding destination file on the receiving side (should it exist).
-    If the destination file is a non-empty directory, it will only be
-    successfully deleted if `--force` or `--delete` are in effect.  Other than
-    that, this option is independent of any other type of delete processing.
+    This option takes the behavior of the (implied)
+    [`--ignore-missing-args`](#opt) option a step farther: each missing arg
+    will become a deletion request of the corresponding destination file on the
+    receiving side (should it exist).  If the destination file is a non-empty
+    directory, it will only be successfully deleted if [`--force`](#opt) or
+    [`--delete`](#opt) are in effect.  Other than that, this option is
+    independent of any other type of delete processing.
 
     The missing source files are represented by special file-list entries which
-    display as a "`*missing`" entry in the `--list-only` output.
+    display as a "`*missing`" entry in the [`--list-only`](#opt) output.
 
 0.  `--ignore-errors`
 
-    Tells `--delete` to go ahead and delete files even when there are I/O
-    errors.
+    Tells [`--delete`](#opt) to go ahead and delete files even when there are
+    I/O errors.
 
 0.  `--force`
 
     This option tells rsync to delete a non-empty directory when it is to be
     replaced by a non-directory.  This is only relevant if deletions are not
-    active (see `--delete` for details).
+    active (see [`--delete`](#opt) for details).
 
     Note for older rsync versions: `--force` used to still be required when
-    using `--delete-after`, and it used to be non-functional unless the
-    `--recursive` option was also enabled.
+    using [`--delete-after`](#opt), and it used to be non-functional unless the
+    [`--recursive`](#opt) option was also enabled.
 
 0.  `--max-delete=NUM`
 
@@ -1772,9 +2061,8 @@ your home directory (remove the '=' for that).
     the numeric units or left unqualified to specify bytes.  Feel free to use a
     fractional value along with the units, such as `--max-size=1.5m`.
 
-    This option is a transfer rule, not an exclude, so it doesn't affect the
-    data that goes into the file-lists, and thus it doesn't affect deletions.
-    It just limits the files that the receiver requests to be transferred.
+    This option is a [TRANSFER RULE](#TRANSFER_RULES), so don't expect any
+    exclude side effects.
 
     The first letter of a units string can be `B` (bytes), `K` (kilo), `M`
     (mega), `G` (giga), `T` (tera), or `P` (peta).  If the string is a single
@@ -1796,7 +2084,7 @@ your home directory (remove the '=' for that).
 
     This tells rsync to avoid transferring any file that is smaller than the
     specified SIZE, which can help in not transferring small, junk files.  See
-    the `--max-size` option for a description of SIZE and other information.
+    the [`--max-size`](#opt) option for a description of SIZE and other info.
 
     Note that rsync versions prior to 3.1.0 did not allow `--min-size=0`.
 
@@ -1813,16 +2101,17 @@ your home directory (remove the '=' for that).
     Keep in mind that this is not a limit on the total size of allocated
     memory.  It is a sanity-check value for each individual allocation.
 
-    See the `--max-size` option for a description of how SIZE can be specified.
-    The default suffix if none is given is bytes.
+    See the [`--max-size`](#opt) option for a description of how SIZE can be
+    specified.  The default suffix if none is given is bytes.
 
     Beginning in 3.2.3, a value of 0 specifies no limit.
 
-    You can set a default value using the environment variable RSYNC_MAX_ALLOC
-    using the same SIZE values as supported by this option.  If the remote
-    rsync doesn't understand the `--max-alloc` option, you can override an
-    environmental value by specifying `--max-alloc=1g`, which will make rsync
-    avoid sending the option to the remote side (because "1G" is the default).
+    You can set a default value using the environment variable
+    [`RSYNC_MAX_ALLOC`](#) using the same SIZE values as supported by this
+    option.  If the remote rsync doesn't understand the `--max-alloc` option,
+    you can override an environmental value by specifying `--max-alloc=1g`,
+    which will make rsync avoid sending the option to the remote side (because
+    "1G" is the default).
 
 0.  `--block-size=SIZE`, `-B`
 
@@ -1831,7 +2120,7 @@ your home directory (remove the '=' for that).
     updated.  See the technical report for details.
 
     Beginning in 3.2.3 the SIZE can be specified with a suffix as detailed in
-    the `--max-size` option.  Older versions only accepted a byte count.
+    the [`--max-size`](#opt) option.  Older versions only accepted a byte count.
 
 0.  `--rsh=COMMAND`, `-e`
 
@@ -1844,17 +2133,17 @@ your home directory (remove the '=' for that).
     shell _COMMAND_ will be used to run an rsync daemon on the remote host, and
     all data will be transmitted through that remote shell connection, rather
     than through a direct socket connection to a running rsync daemon on the
-    remote host.  See the section "USING RSYNC-DAEMON FEATURES VIA A
-    REMOTE-SHELL CONNECTION" above.
-
-    Beginning with rsync 3.2.0, the RSYNC_PORT environment variable will be set
-    when a daemon connection is being made via a remote-shell connection.  It
-    is set to 0 if the default daemon port is being assumed, or it is set to
-    the value of the rsync port that was specified via either the `--port`
-    option or a non-empty port value in an rsync:// URL.  This allows the
-    script to discern if a non-default port is being requested, allowing for
-    things such as an SSL or stunnel helper script to connect to a default or
-    alternate port.
+    remote host.  See the [USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL
+    CONNECTION](#) section above.
+
+    Beginning with rsync 3.2.0, the [`RSYNC_PORT`](#) environment variable will
+    be set when a daemon connection is being made via a remote-shell
+    connection.  It is set to 0 if the default daemon port is being assumed, or
+    it is set to the value of the rsync port that was specified via either the
+    [`--port`](#opt) option or a non-empty port value in an `rsync://` URL.
+    This allows the script to discern if a non-default port is being requested,
+    allowing for things such as an SSL or stunnel helper script to connect to a
+    default or alternate port.
 
     Command-line arguments are permitted in COMMAND provided that COMMAND is
     presented to rsync as a single argument.  You must use spaces (not tabs or
@@ -1871,10 +2160,11 @@ your home directory (remove the '=' for that).
     (Note that ssh users can alternately customize site-specific connect
     options in their .ssh/config file.)
 
-    You can also choose the remote shell program using the RSYNC_RSH
+    You can also choose the remote shell program using the [`RSYNC_RSH`](#)
     environment variable, which accepts the same range of values as `-e`.
 
-    See also the `--blocking-io` option which is affected by this option.
+    See also the [`--blocking-io`](#opt) option which is affected by this
+    option.
 
 0.  `--rsync-path=PROGRAM`
 
@@ -1886,7 +2176,7 @@ your home directory (remove the '=' for that).
     & standard-out that rsync is using to communicate.
 
     One tricky example is to set a different default directory on the remote
-    machine for use with the `--relative` option.  For instance:
+    machine for use with the [`--relative`](#opt) option.  For instance:
 
     >     rsync -avR --rsync-path="cd /a/b && rsync" host:c/d /e/
 
@@ -1894,8 +2184,8 @@ your home directory (remove the '=' for that).
 
     This option is used for more advanced situations where you want certain
     effects to be limited to one side of the transfer only.  For instance, if
-    you want to pass `--log-file=FILE` and `--fake-super` to the remote system,
-    specify it like this:
+    you want to pass [`--log-file=FILE`](#opt) and [`--fake-super`](#opt) to
+    the remote system, specify it like this:
 
     >     rsync -av -M --log-file=foo -M--fake-super src/ dest/
 
@@ -1909,11 +2199,10 @@ your home directory (remove the '=' for that).
     cause rsync to have a different idea about what data to expect next over
     the socket, and that will make it fail in a cryptic fashion.
 
-    Note that it is best to use a separate `--remote-option` for each option
-    you want to pass.  This makes your usage compatible with the
-    `--protect-args` option.  If that option is off, any spaces in your remote
-    options will be split by the remote shell unless you take steps to protect
-    them.
+    Note that you should use a separate `-M` option for each remote option you
+    want to pass.  On older rsync versions, the presence of any spaces in the
+    remote-option arg could cause it to be split into separate remote args, but
+    this requires the use of [`--old-args`](#opt) in a modern rsync.
 
     When performing a local transfer, the "local" side is the sender and the
     "remote" side is the receiver.
@@ -1931,7 +2220,8 @@ your home directory (remove the '=' for that).
     to CVS to determine if a file should be ignored.
 
     The exclude list is initialized to exclude the following items (these
-    initial items are marked as perishable -- see the FILTER RULES section):
+    initial items are marked as perishable -- see the [FILTER RULES](#)
+    section):
 
     [comment]: # (This list gets used for the default-cvsignore.h file.)
 
@@ -1981,17 +2271,17 @@ your home directory (remove the '=' for that).
     filter/exclude files, these patterns are split on whitespace.  See the
     **cvs**(1) manual for more information.
 
-    If you're combining `-C` with your own `--filter` rules, you should note
-    that these CVS excludes are appended at the end of your own rules,
+    If you're combining `-C` with your own [`--filter`](#opt) rules, you should
+    note that these CVS excludes are appended at the end of your own rules,
     regardless of where the `-C` was placed on the command-line.  This makes
     them a lower priority than any rules you specified explicitly.  If you want
     to control where these CVS excludes get inserted into your filter rules,
     you should omit the `-C` as a command-line option and use a combination of
-    `--filter=:C` and `--filter=-C` (either on your command-line or by putting
-    the ":C" and "-C" rules into a filter file with your other rules).  The
-    first option turns on the per-directory scanning for the .cvsignore file.
-    The second option does a one-time import of the CVS excludes mentioned
-    above.
+    [`--filter=:C`](#opt) and [`--filter=-C`](#opt) (either on your
+    command-line or by putting the ":C" and "-C" rules into a filter file with
+    your other rules).  The first option turns on the per-directory scanning
+    for the .cvsignore file.  The second option does a one-time import of the
+    CVS excludes mentioned above.
 
 0.  `--filter=RULE`, `-f`
 
@@ -2005,12 +2295,12 @@ your home directory (remove the '=' for that).
     argument.  The text below also mentions that you can use an underscore to
     replace the space that separates a rule from its arg.
 
-    See the FILTER RULES section for detailed information on this option.
+    See the [FILTER RULES](#) section for detailed information on this option.
 
 0.  `-F`
 
-    The `-F` option is a shorthand for adding two `--filter` rules to your
-    command.  The first time it is used is a shorthand for this rule:
+    The `-F` option is a shorthand for adding two [`--filter`](#opt) rules to
+    your command.  The first time it is used is a shorthand for this rule:
 
     >     --filter='dir-merge /.rsync-filter'
 
@@ -2023,38 +2313,56 @@ your home directory (remove the '=' for that).
 
     This filters out the .rsync-filter files themselves from the transfer.
 
-    See the FILTER RULES section for detailed information on how these options
-    work.
+    See the [FILTER RULES](#) section for detailed information on how these
+    options work.
 
 0.  `--exclude=PATTERN`
 
-    This option is a simplified form of the `--filter` option that defaults to
-    an exclude rule and does not allow the full rule-parsing syntax of normal
-    filter rules.
+    This option is a simplified form of the [`--filter`](#opt) option that
+    specifies an exclude rule and does not allow the full rule-parsing syntax
+    of normal filter rules.  This is equivalent to specifying `-f'- PATTERN'`.
 
-    See the FILTER RULES section for detailed information on this option.
+    See the [FILTER RULES](#) section for detailed information on this option.
 
 0.  `--exclude-from=FILE`
 
-    This option is related to the `--exclude` option, but it specifies a FILE
-    that contains exclude patterns (one per line).  Blank lines in the file and
-    lines starting with '`;`' or '`#`' are ignored.  If _FILE_ is '`-`', the
-    list will be read from standard input.
+    This option is related to the [`--exclude`](#opt) option, but it specifies
+    a FILE that contains exclude patterns (one per line).  Blank lines in the
+    file are ignored, as are whole-line comments that start with '`;`' or '`#`'
+    (filename rules that contain those characters are unaffected).
+
+    If a line begins with "`- `" (dash, space) or "`+ `" (plus, space), then
+    the type of rule is being explicitly specified as an exclude or an include
+    (respectively).  Any rules without such a prefix are taken to be an exclude.
+
+    If a line consists of just "`!`", then the current filter rules are cleared
+    before adding any further rules.
+
+    If _FILE_ is '`-`', the list will be read from standard input.
 
 0.  `--include=PATTERN`
 
-    This option is a simplified form of the `--filter` option that defaults to
-    an include rule and does not allow the full rule-parsing syntax of normal
-    filter rules.
+    This option is a simplified form of the [`--filter`](#opt) option that
+    specifies an include rule and does not allow the full rule-parsing syntax
+    of normal filter rules.  This is equivalent to specifying `-f'+ PATTERN'`.
 
-    See the FILTER RULES section for detailed information on this option.
+    See the [FILTER RULES](#) section for detailed information on this option.
 
 0.  `--include-from=FILE`
 
-    This option is related to the `--include` option, but it specifies a FILE
-    that contains include patterns (one per line).  Blank lines in the file and
-    lines starting with '`;`' or '`#`' are ignored.  If _FILE_ is '`-`', the
-    list will be read from standard input.
+    This option is related to the [`--include`](#opt) option, but it specifies
+    a FILE that contains include patterns (one per line).  Blank lines in the
+    file are ignored, as are whole-line comments that start with '`;`' or '`#`'
+    (filename rules that contain those characters are unaffected).
+
+    If a line begins with "`- `" (dash, space) or "`+ `" (plus, space), then
+    the type of rule is being explicitly specified as an exclude or an include
+    (respectively).  Any rules without such a prefix are taken to be an include.
+
+    If a line consists of just "`!`", then the current filter rules are cleared
+    before adding any further rules.
+
+    If _FILE_ is '`-`', the list will be read from standard input.
 
 0.  `--files-from=FILE`
 
@@ -2063,17 +2371,17 @@ your home directory (remove the '=' for that).
     tweaks the default behavior of rsync to make transferring just the
     specified files and directories easier:
 
-    - The `--relative` (`-R`) option is implied, which preserves the path
-      information that is specified for each item in the file (use
+    - The [`--relative`](#opt) (`-R`) option is implied, which preserves the
+      path information that is specified for each item in the file (use
       `--no-relative` or `--no-R` if you want to turn that off).
-    - The `--dirs` (`-d`) option is implied, which will create directories
-      specified in the list on the destination rather than noisily skipping
-      them (use `--no-dirs` or `--no-d` if you want to turn that off).
-    - The `--archive` (`-a`) option's behavior does not imply `--recursive`
-      (`-r`), so specify it explicitly, if you want it.
+    - The [`--dirs`](#opt) (`-d`) option is implied, which will create
+      directories specified in the list on the destination rather than noisily
+      skipping them (use `--no-dirs` or `--no-d` if you want to turn that off).
+    - The [`--archive`](#opt) (`-a`) option's behavior does not imply
+      [`--recursive`](#opt) (`-r`), so specify it explicitly, if you want it.
     - These side-effects change the default state of rsync, so the position of
       the `--files-from` option on the command-line has no bearing on how other
-      options are parsed (e.g. `-a` works the same before or after
+      options are parsed (e.g. [`-a`](#opt) works the same before or after
       `--files-from`, as does `--no-R` and all other options).
 
     The filenames that are read from the FILE are all relative to the source
@@ -2086,13 +2394,13 @@ your home directory (remove the '=' for that).
     directory will be created as /backup/bin on the remote host.  If it
     contains "bin/" (note the trailing slash), the immediate contents of the
     directory would also be sent (without needing to be explicitly mentioned in
-    the file -- this began in version 2.6.4).  In both cases, if the `-r`
-    option was enabled, that dir's entire hierarchy would also be transferred
-    (keep in mind that `-r` needs to be specified explicitly with
-    `--files-from`, since it is not implied by `-a`).  Also note that the
-    effect of the (enabled by default) `--relative` option is to duplicate only
-    the path info that is read from the file -- it does not force the
-    duplication of the source-spec path (/usr in this case).
+    the file -- this began in version 2.6.4).  In both cases, if the
+    [`-r`](#opt) option was enabled, that dir's entire hierarchy would also be
+    transferred (keep in mind that [`-r`](#opt) needs to be specified
+    explicitly with `--files-from`, since it is not implied by [`-a`](#opt).
+    Also note that the effect of the (enabled by default) [`-r`](#opt) option
+    is to duplicate only the path info that is read from the file -- it does
+    not force the duplication of the source-spec path (/usr in this case).
 
     In addition, the `--files-from` file can be read from the remote host
     instead of the local host if you specify a "host:" in front of the file
@@ -2105,9 +2413,9 @@ your home directory (remove the '=' for that).
     This would copy all the files specified in the /path/file-list file that
     was located on the remote "src" host.
 
-    If the `--iconv` and `--protect-args` options are specified and the
-    `--files-from` filenames are being sent from one host to another, the
-    filenames will be translated from the sending host's charset to the
+    If the [`--iconv`](#opt) and [`--secluded-args`](#opt) options are specified
+    and the `--files-from` filenames are being sent from one host to another,
+    the filenames will be translated from the sending host's charset to the
     receiving host's charset.
 
     NOTE: sorting the list of files in the `--files-from` input helps rsync to
@@ -2121,40 +2429,117 @@ your home directory (remove the '=' for that).
 
     This tells rsync that the rules/filenames it reads from a file are
     terminated by a null ('\\0') character, not a NL, CR, or CR+LF.  This
-    affects `--exclude-from`, `--include-from`, `--files-from`, and any merged
-    files specified in a `--filter` rule.  It does not affect `--cvs-exclude`
-    (since all names read from a .cvsignore file are split on whitespace).
+    affects [`--exclude-from`](#opt), [`--include-from`](#opt),
+    [`--files-from`](#opt), and any merged files specified in a
+    [`--filter`](#opt) rule.  It does not affect [`--cvs-exclude`](#opt) (since
+    all names read from a .cvsignore file are split on whitespace).
+
+0. `--old-args`
+
+    This option tells rsync to stop trying to protect the arg values on the
+    remote side from unintended word-splitting or other misinterpretation.
+    It also allows the client to treat an empty arg as a "." instead of
+    generating an error.
+
+    The default in a modern rsync is for "shell-active" characters (including
+    spaces) to be backslash-escaped in the args that are sent to the remote
+    shell.  The wildcard characters `*`, `?`, `[`, & `]` are not escaped in
+    filename args (allowing them to expand into multiple filenames) while being
+    protected in option args, such as [`--usermap`](#opt).
+
+    If you have a script that wants to use old-style arg splitting in its
+    filenames, specify this option once.  If the remote shell has a problem
+    with any backslash escapes at all, specify this option twice.
+
+    You may also control this setting via the [`RSYNC_OLD_ARGS`](#) environment
+    variable.  If it has the value "1", rsync will default to a single-option
+    setting.  If it has the value "2" (or more), rsync will default to a
+    repeated-option setting.  If it is "0", you'll get the default escaping
+    behavior.  The environment is always overridden by manually specified
+    positive or negative options (the negative is `--no-old-args`).
+
+    Note that this option also disables the extra safety check added in 3.2.5
+    that ensures that a remote sender isn't including extra top-level items in
+    the file-list that you didn't request.  This side-effect is necessary
+    because we can't know for sure what names to expect when the remote shell
+    is interpreting the args.
+
+    This option conflicts with the [`--secluded-args`](#opt) option.
+
+0.  `--secluded-args`, `-s`
+
+    This option sends all filenames and most options to the remote rsync via
+    the protocol (not the remote shell command line) which avoids letting the
+    remote shell modify them.  Wildcards are expanded on the remote host by
+    rsync instead of a shell.
+
+    This is similar to the default backslash-escaping of args that was added
+    in 3.2.4 (see [`--old-args`](#opt)) in that it prevents things like space
+    splitting and unwanted special-character side-effects. However, it has the
+    drawbacks of being incompatible with older rsync versions (prior to 3.0.0)
+    and of being refused by restricted shells that want to be able to inspect
+    all the option values for safety.
+
+    This option is useful for those times that you need the argument's
+    character set to be converted for the remote host, if the remote shell is
+    incompatible with the default backslash-escpaing method, or there is some
+    other reason that you want the majority of the options and arguments to
+    bypass the command-line of the remote shell.
+
+    If you combine this option with [`--iconv`](#opt), the args related to the
+    remote side will be translated from the local to the remote character-set.
+    The translation happens before wild-cards are expanded.  See also the
+    [`--files-from`](#opt) option.
+
+    You may also control this setting via the [`RSYNC_PROTECT_ARGS`](#)
+    environment variable.  If it has a non-zero value, this setting will be
+    enabled by default, otherwise it will be disabled by default.  Either state
+    is overridden by a manually specified positive or negative version of this
+    option (note that `--no-s` and `--no-secluded-args` are the negative
+    versions).  This environment variable is also superseded by a non-zero
+    [`RSYNC_OLD_ARGS`](#) export.
 
-0.  `--protect-args`, `-s`
+    This option conflicts with the [`--old-args`](#opt) option.
 
-    This option sends all filenames and most options to the remote rsync
-    without allowing the remote shell to interpret them.  This means that
-    spaces are not split in names, and any non-wildcard special characters are
-    not translated (such as `~`, `$`, `;`, `&`, etc.).  Wildcards are expanded
-    on the remote host by rsync (instead of the shell doing it).
+    This option used to be called `--protect-args` (before 3.2.6) and that
+    older name can still be used (though specifying it as `-s` is always the
+    easiest and most compatible choice).
 
-    If you use this option with `--iconv`, the args related to the remote side
-    will also be translated from the local to the remote character-set.  The
-    translation happens before wild-cards are expanded.  See also the
-    `--files-from` option.
+0.  `--trust-sender`
 
-    You may also control this option via the RSYNC_PROTECT_ARGS environment
-    variable.  If this variable has a non-zero value, this option will be
-    enabled by default, otherwise it will be disabled by default.  Either state
-    is overridden by a manually specified positive or negative version of this
-    option (note that `--no-s` and `--no-protect-args` are the negative
-    versions).  Since this option was first introduced in 3.0.0, you'll need to
-    make sure it's disabled if you ever need to interact with a remote rsync
-    that is older than that.
+    This option disables two extra validation checks that a local client
+    performs on the file list generated by a remote sender.  This option should
+    only be used if you trust the sender to not put something malicious in the
+    file list (something that could possibly be done via a modified rsync, a
+    modified shell, or some other similar manipulation).
+
+    Normally, the rsync client (as of version 3.2.5) runs two extra validation
+    checks when pulling files from a remote rsync:
+
+    - It verifies that additional arg items didn't get added at the top of the
+      transfer.
+    - It verifies that none of the items in the file list are names that should
+      have been excluded (if filter rules were specified).
 
-    Rsync can also be configured (at build time) to have this option enabled by
-    default (with is overridden by both the environment and the command-line).
-    Run `rsync --version` to check if this is the case, as it will display
-    "default protect-args" or "optional protect-args" depending on how it was
-    compiled.
+    Note that various options can turn off one or both of these checks if the
+    option interferes with the validation.  For instance:
 
-    This option will eventually become a new default setting at some
-    as-yet-undetermined point in the future.
+    - Using a per-directory filter file reads filter rules that only the server
+      knows about, so the filter checking is disabled.
+    - Using the [`--old-args`](#opt) option allows the sender to manipulate the
+      requested args, so the arg checking is disabled.
+    - Reading the files-from list from the server side means that the client
+      doesn't know the arg list, so the arg checking is disabled.
+    - Using [`--read-batch`](#opt) disables both checks since the batch file's
+      contents will have been verified when it was created.
+
+    This option may help an under-powered client server if the extra pattern
+    matching is slowing things down on a huge transfer.  It can also be used to
+    work around a currently-unknown bug in the verification logic for a transfer
+    from a trusted sender.
+
+    When using this option it is a good idea to specify a dedicated destination
+    directory, as discussed in the [MULTI-HOST SECURITY](#) section.
 
 0.  `--copy-as=USER[:GROUP]`
 
@@ -2172,14 +2557,14 @@ your home directory (remove the '=' for that).
     operation after the remote-shell or daemon connection is established.
 
     The option only affects one side of the transfer unless the transfer is
-    local, in which case it affects both sides.  Use the `--remote-option` to
-    affect the remote side, such as `-M--copy-as=joe`.  For a local transfer,
-    the lsh (or lsh.sh) support file provides a local-shell helper script that
-    can be used to allow a "localhost:" or "lh:" host-spec to be specified
-    without needing to setup any remote shells, allowing you to specify remote
-    options that affect the side of the transfer that is using the host-spec
-    (and using hostname "lh" avoids the overriding of the remote directory to
-    the user's home dir).
+    local, in which case it affects both sides.  Use the
+    [`--remote-option`](#opt) to affect the remote side, such as
+    `-M--copy-as=joe`.  For a local transfer, the lsh (or lsh.sh) support file
+    provides a local-shell helper script that can be used to allow a
+    "localhost:" or "lh:" host-spec to be specified without needing to setup
+    any remote shells, allowing you to specify remote options that affect the
+    side of the transfer that is using the host-spec (and using hostname "lh"
+    avoids the overriding of the remote directory to the user's home dir).
 
     For example, the following rsync writes the local files as user "joe":
 
@@ -2219,17 +2604,17 @@ your home directory (remove the '=' for that).
     new version on the disk at the same time.
 
     If you are using this option for reasons other than a shortage of disk
-    space, you may wish to combine it with the `--delay-updates` option, which
-    will ensure that all copied files get put into subdirectories in the
-    destination hierarchy, awaiting the end of the transfer.  If you don't have
-    enough room to duplicate all the arriving files on the destination
-    partition, another way to tell rsync that you aren't overly concerned about
-    disk space is to use the `--partial-dir` option with a relative path;
-    because this tells rsync that it is OK to stash off a copy of a single file
-    in a subdir in the destination hierarchy, rsync will use the partial-dir as
-    a staging area to bring over the copied file, and then rename it into place
-    from there. (Specifying a `--partial-dir` with an absolute path does not
-    have this side-effect.)
+    space, you may wish to combine it with the [`--delay-updates`](#opt)
+    option, which will ensure that all copied files get put into subdirectories
+    in the destination hierarchy, awaiting the end of the transfer.  If you
+    don't have enough room to duplicate all the arriving files on the
+    destination partition, another way to tell rsync that you aren't overly
+    concerned about disk space is to use the [`--partial-dir`](#opt) option
+    with a relative path; because this tells rsync that it is OK to stash off a
+    copy of a single file in a subdir in the destination hierarchy, rsync will
+    use the partial-dir as a staging area to bring over the copied file, and
+    then rename it into place from there. (Specifying a [`--partial-dir`](#opt)
+    with an absolute path does not have this side-effect.)
 
 0.  `--fuzzy`, `-y`
 
@@ -2240,12 +2625,12 @@ your home directory (remove the '=' for that).
     the fuzzy basis file to try to speed up the transfer.
 
     If the option is repeated, the fuzzy scan will also be done in any matching
-    alternate destination directories that are specified via `--compare-dest`,
-    `--copy-dest`, or `--link-dest`.
+    alternate destination directories that are specified via
+    [`--compare-dest`](#opt), [`--copy-dest`](#opt), or [`--link-dest`](#opt).
 
-    Note that the use of the `--delete` option might get rid of any potential
-    fuzzy-match files, so either use `--delete-after` or specify some filename
-    exclusions if you need to prevent this.
+    Note that the use of the [`--delete`](#opt) option might get rid of any
+    potential fuzzy-match files, so either use [`--delete-after`](#opt) or
+    specify some filename exclusions if you need to prevent this.
 
 0.  `--compare-dest=DIR`
 
@@ -2266,7 +2651,7 @@ your home directory (remove the '=' for that).
     transfer.
 
     If _DIR_ is a relative path, it is relative to the destination directory.
-    See also `--copy-dest` and `--link-dest`.
+    See also [`--copy-dest`](#opt) and [`--link-dest`](#opt).
 
     NOTE: beginning with version 3.1.0, rsync will remove a file from a
     non-empty destination hierarchy if an exact match is found in one of the
@@ -2275,7 +2660,7 @@ your home directory (remove the '=' for that).
 
 0.  `--copy-dest=DIR`
 
-    This option behaves like `--compare-dest`, but rsync will also copy
+    This option behaves like [`--compare-dest`](#opt), but rsync will also copy
     unchanged files found in _DIR_ to the destination directory using a local
     copy.  This is useful for doing transfers to a new destination while
     leaving existing files intact, and then doing a flash-cutover when all
@@ -2287,18 +2672,18 @@ your home directory (remove the '=' for that).
     try to speed up the transfer.
 
     If _DIR_ is a relative path, it is relative to the destination directory.
-    See also `--compare-dest` and `--link-dest`.
+    See also [`--compare-dest`](#opt) and [`--link-dest`](#opt).
 
 0.  `--link-dest=DIR`
 
-    This option behaves like `--copy-dest`, but unchanged files are hard linked
-    from _DIR_ to the destination directory.  The files must be identical in
-    all preserved attributes (e.g. permissions, possibly ownership) in order
-    for the files to be linked together.  An example:
+    This option behaves like [`--copy-dest`](#opt), but unchanged files are
+    hard linked from _DIR_ to the destination directory.  The files must be
+    identical in all preserved attributes (e.g. permissions, possibly
+    ownership) in order for the files to be linked together.  An example:
 
     >     rsync -av --link-dest=$PWD/prior_dir host:src_dir/ new_dir/
 
-    If file's aren't linking, double-check their attributes.  Also check if
+    If files aren't linking, double-check their attributes.  Also check if
     some attributes are getting forced outside of rsync's control, such a mount
     option that squishes root to a single user, or mounts a removable drive
     with generic ownership (such as OS X's "Ignore ownership on this volume"
@@ -2318,18 +2703,19 @@ your home directory (remove the '=' for that).
     alternate-directory exact match would never be found (nor linked into the
     destination) when a destination file already exists.
 
-    Note that if you combine this option with `--ignore-times`, rsync will not
+    Note that if you combine this option with [`--ignore-times`](#opt), rsync will not
     link any files together because it only links identical files together as a
     substitute for transferring the file, never as an additional check after
     the file is updated.
 
     If _DIR_ is a relative path, it is relative to the destination directory.
-    See also `--compare-dest` and `--copy-dest`.
+    See also [`--compare-dest`](#opt) and [`--copy-dest`](#opt).
 
     Note that rsync versions prior to 2.6.1 had a bug that could prevent
-    `--link-dest` from working properly for a non-super-user when `-o` was
-    specified (or implied by `-a`).  You can work-around this bug by avoiding
-    the `-o` option when sending to an old rsync.
+    `--link-dest` from working properly for a non-super-user when
+    [`--owner`](#opt) (`-o`) was specified (or implied).  You can work-around
+    this bug by avoiding the `-o` option (or using `--no-o`) when sending to an
+    old rsync.
 
 0.  `--compress`, `-z`
 
@@ -2338,7 +2724,8 @@ your home directory (remove the '=' for that).
     something that is useful over a slow connection.
 
     Rsync supports multiple compression methods and will choose one for you
-    unless you force the choice using the `--compress-choice` (`--zc`) option.
+    unless you force the choice using the [`--compress-choice`](#opt) (`--zc`)
+    option.
 
     Run `rsync --version` to see the default compress list compiled into your
     version.
@@ -2350,10 +2737,10 @@ your home directory (remove the '=' for that).
     its list is assumed to be "zlib".
 
     The default order can be customized by setting the environment variable
-    RSYNC_COMPRESS_LIST to a space-separated list of acceptable compression
-    names.  If the string contains a "`&`" character, it is separated into the
-    "client string & server string", otherwise the same string applies to both.
-    If the string (or string portion) contains no
+    [`RSYNC_COMPRESS_LIST`](#) to a space-separated list of acceptable
+    compression names.  If the string contains a "`&`" character, it is
+    separated into the "client string & server string", otherwise the same
+    string applies to both.  If the string (or string portion) contains no
     non-whitespace characters, the default compress list is used.  Any unknown
     compression names are discarded from the list, but a list with only invalid
     names results in a failed negotiation.
@@ -2364,15 +2751,12 @@ your home directory (remove the '=' for that).
     ignore this weirdness unless the rsync server complains and tells you to
     specify `-zz`.
 
-    See also the `--skip-compress` option for the default list of file suffixes
-    that will be transferred with no (or minimal) compression.
-
 0.  `--compress-choice=STR`, `--zc=STR`
 
     This option can be used to override the automatic negotiation of the
-    compression algorithm that occurs when `--compress` is used.  The option
-    implies `--compress` unless "none" was specified, which instead implies
-    `--no-compress`.
+    compression algorithm that occurs when [`--compress`](#opt) is used.  The
+    option implies [`--compress`](#opt) unless "none" was specified, which
+    instead implies `--no-compress`.
 
     The compression options that you may be able to use are:
 
@@ -2397,22 +2781,23 @@ your home directory (remove the '=' for that).
 
 0.  `--compress-level=NUM`, `--zl=NUM`
 
-    Explicitly set the compression level to use (see `--compress`, `-z`)
-    instead of letting it default.  The `--compress` option is implied as long
-    as the level chosen is not a "don't compress" level for the compression
-    algorithm that is in effect (e.g. zlib compression treats level 0 as
-    "off").
+    Explicitly set the compression level to use (see [`--compress`](#opt),
+    `-z`) instead of letting it default.  The [`--compress`](#opt) option is
+    implied as long as the level chosen is not a "don't compress" level for the
+    compression algorithm that is in effect (e.g. zlib compression treats level
+    0 as "off").
 
     The level values vary depending on the checksum in effect.  Because rsync
     will negotiate a checksum choice by default (when the remote rsync is new
-    enough), it can be good to combine this option with a `--compress-choice`
-    (`--zc`) option unless you're sure of the choice in effect.  For example:
+    enough), it can be good to combine this option with a
+    [`--compress-choice`](#opt) (`--zc`) option unless you're sure of the
+    choice in effect.  For example:
 
     >     rsync -aiv --zc=zstd --zl=22 host:src/ dest/
 
     For zlib & zlibx compression the valid values are from 1 to 9 with 6 being
-    the default.  Specifying 0 turns compression off, and specifying -1 chooses
-    the default of 6.
+    the default.  Specifying `--zl=0` turns compression off, and specifying
+    `--zl=-1` chooses the default level of 6.
 
     For zstd compression the valid values are from -131072 to 22 with 3 being
     the default. Specifying 0 chooses the default of 3.
@@ -2425,20 +2810,21 @@ your home directory (remove the '=' for that).
     compression level no matter what algorithm was chosen.
 
     If you want to know the compression level that is in effect, specify
-    `--debug=nstr` to see the "negotiated string" results.  This will report
-    something like "`Client compress: zstd (level 3)`" (along with the checksum
-    choice in effect).
+    [`--debug=nstr`](#opt) to see the "negotiated string" results.  This will
+    report something like "`Client compress: zstd (level 3)`" (along with the
+    checksum choice in effect).
 
 0.  `--skip-compress=LIST`
 
+    **NOTE:** no compression method currently supports per-file compression
+    changes, so this option has no effect.
+
     Override the list of file suffixes that will be compressed as little as
     possible.  Rsync sets the compression level on a per-file basis based on
-    the file's suffix.  If the compression algorithm has an "off" level (such
-    as zlib/zlibx) then no compression occurs for those files.  Other
-    algorithms that support changing the streaming level on-the-fly will have
-    the level minimized to reduces the CPU usage as much as possible for a
-    matching file.  At this time, only zlib & zlibx compression support this
-    changing of levels on a per-file basis.
+    the file's suffix.  If the compression algorithm has an "off" level, then
+    no compression occurs for those files.  Other algorithms that support
+    changing the streaming level on-the-fly will have the level minimized to
+    reduces the CPU usage as much as possible for a matching file.
 
     The **LIST** should be one or more file suffixes (without the dot) separated
     by slashes (`/`).  You may specify an empty string to indicate that no files
@@ -2574,10 +2960,10 @@ your home directory (remove the '=' for that).
 
     If a user or group has no name on the source system or it has no match on
     the destination system, then the numeric ID from the source system is used
-    instead.  See also the comments on the "`use chroot`" setting in the
-    rsyncd.conf manpage for information on how the chroot setting affects
-    rsync's ability to look up the names of the users and groups and what you
-    can do about it.
+    instead.  See also the [`use chroot`](rsyncd.conf.5#use_chroot) setting
+    in the rsyncd.conf manpage for some comments on how the chroot setting
+    affects rsync's ability to look up the names of the users and groups and
+    what you can do about it.
 
 0.  `--usermap=STRING`, `--groupmap=STRING`
 
@@ -2610,31 +2996,39 @@ your home directory (remove the '=' for that).
 
     >     --usermap=:nobody --groupmap=*:nobody
 
-    When the `--numeric-ids` option is used, the sender does not send any
+    When the [`--numeric-ids`](#opt) option is used, the sender does not send any
     names, so all the IDs are treated as having an empty name.  This means that
     you will need to specify numeric **FROM** values if you want to map these
     nameless IDs to different values.
 
-    For the `--usermap` option to have any effect, the `-o` (`--owner`) option
-    must be used (or implied), and the receiver will need to be running as a
-    super-user (see also the `--fake-super` option).  For the `--groupmap`
-    option to have any effect, the `-g` (`--groups`) option must be used (or
-    implied), and the receiver will need to have permissions to set that group.
+    For the `--usermap` option to work, the receiver will need to be running as
+    a super-user (see also the [`--super`](#opt) and [`--fake-super`](#opt)
+    options).  For the `--groupmap` option to work, the receiver will need to
+    have permissions to set that group.
+
+    Starting with rsync 3.2.4, the `--usermap` option implies the
+    [`--owner`](#opt) (`-o`) option while the `--groupmap` option implies the
+    [`--group`](#opt) (`-g`) option (since rsync needs to have those options
+    enabled for the mapping options to work).
 
-    If your shell complains about the wildcards, use `--protect-args` (`-s`).
+    An older rsync client may need to use [`-s`](#opt) to avoid a complaint
+    about wildcard characters, but a modern rsync handles this automatically.
 
 0.  `--chown=USER:GROUP`
 
     This option forces all files to be owned by USER with group GROUP.  This is
-    a simpler interface than using `--usermap` and `--groupmap` directly, but
-    it is implemented using those options internally, so you cannot mix them.
-    If either the USER or GROUP is empty, no mapping for the omitted user/group
-    will occur.  If GROUP is empty, the trailing colon may be omitted, but if
-    USER is empty, a leading colon must be supplied.
+    a simpler interface than using [`--usermap`](#opt) & [`--groupmap`](#opt)
+    directly, but it is implemented using those options internally so they
+    cannot be mixed.  If either the USER or GROUP is empty, no mapping for the
+    omitted user/group will occur.  If GROUP is empty, the trailing colon may
+    be omitted, but if USER is empty, a leading colon must be supplied.
 
     If you specify "`--chown=foo:bar`", this is exactly the same as specifying
-    "`--usermap=*:foo --groupmap=*:bar`", only easier.  If your shell complains
-    about the wildcards, use `--protect-args` (`-s`).
+    "`--usermap=*:foo --groupmap=*:bar`", only easier (and with the same
+    implied [`--owner`](#opt) and/or [`--group`](#opt) options).
+
+    An older rsync client may need to use [`-s`](#opt) to avoid a complaint
+    about wildcard characters, but a modern rsync handles this automatically.
 
 0.  `--timeout=SECONDS`
 
@@ -2652,27 +3046,29 @@ your home directory (remove the '=' for that).
 
     By default rsync will bind to the wildcard address when connecting to an
     rsync daemon.  The `--address` option allows you to specify a specific IP
-    address (or hostname) to bind to.  See also this option in the `--daemon`
-    mode section.
+    address (or hostname) to bind to.
+
+    See also [the daemon version of the `--address` option](#dopt--address).
 
 0.  `--port=PORT`
 
     This specifies an alternate TCP port number to use rather than the default
     of 873.  This is only needed if you are using the double-colon (::) syntax
     to connect with an rsync daemon (since the URL syntax has a way to specify
-    the port as a part of the URL).  See also this option in the `--daemon`
-    mode section.
+    the port as a part of the URL).
+
+    See also [the daemon version of the `--port` option](#dopt--port).
 
 0.  `--sockopts=OPTIONS`
 
     This option can provide endless fun for people who like to tune their
     systems to the utmost degree.  You can set all sorts of socket options
-    which may make transfers faster (or slower!).  Read the man page for the
+    which may make transfers faster (or slower!).  Read the manpage for the
     `setsockopt()` system call for details on some of the options you may be
     able to set.  By default no special socket options are set.  This only
     affects direct socket connections to a remote rsync daemon.
 
-    This option also exists in the `--daemon` mode section.
+    See also [the daemon version of the `--sockopts` option](#dopt--sockopts).
 
 0.  `--blocking-io`
 
@@ -2694,10 +3090,10 @@ your home directory (remove the '=' for that).
 
     Requests a simple itemized list of the changes that are being made to each
     file, including attribute changes.  This is exactly the same as specifying
-    `--out-format='%i %n%L'`.  If you repeat the option, unchanged files will
-    also be output, but only if the receiving rsync is at least version 2.6.7
-    (you can use `-vv` with older versions of rsync, but that also turns on the
-    output of other verbose messages).
+    [`--out-format='%i %n%L'`](#opt).  If you repeat the option, unchanged
+    files will also be output, but only if the receiving rsync is at least
+    version 2.6.7 (you can use `-vv` with older versions of rsync, but that
+    also turns on the output of other verbose messages).
 
     The "%i" escape has a cryptic output that is 11 letters long.  The general
     format is like the string `YXcstpoguax`, where **Y** is replaced by the type
@@ -2712,7 +3108,7 @@ your home directory (remove the '=' for that).
     - A `c` means that a local change/creation is occurring for the item (such
       as the creation of a directory or the changing of a symlink, etc.).
     - A `h` means that the item is a hard link to another item (requires
-      `--hard-links`).
+      [`--hard-links`](#opt)).
     - A `.` means that the item is not being updated (though it might have
       attributes that are being modified).
     - A `*` means that the rest of the itemized-output area contains a message
@@ -2734,30 +3130,32 @@ your home directory (remove the '=' for that).
     The attribute that is associated with each letter is as follows:
 
     - A `c` means either that a regular file has a different checksum (requires
-      `--checksum`) or that a symlink, device, or special file has a changed
-      value.  Note that if you are sending files to an rsync prior to 3.0.1,
-      this change flag will be present only for checksum-differing regular
-      files.
+      [`--checksum`](#opt)) or that a symlink, device, or special file has a
+      changed value.  Note that if you are sending files to an rsync prior to
+      3.0.1, this change flag will be present only for checksum-differing
+      regular files.
     - A `s` means the size of a regular file is different and will be updated
       by the file transfer.
     - A `t` means the modification time is different and is being updated to
-      the sender's value (requires `--times`).  An alternate value of `T` means
-      that the modification time will be set to the transfer time, which
-      happens when a file/symlink/device is updated without `--times` and when
-      a symlink is changed and the receiver can't set its time. (Note: when
-      using an rsync 3.0.0 client, you might see the `s` flag combined with `t`
-      instead of the proper `T` flag for this time-setting failure.)
+      the sender's value (requires [`--times`](#opt)).  An alternate value of
+      `T` means that the modification time will be set to the transfer time,
+      which happens when a file/symlink/device is updated without
+      [`--times`](#opt) and when a symlink is changed and the receiver can't
+      set its time. (Note: when using an rsync 3.0.0 client, you might see the
+      `s` flag combined with `t` instead of the proper `T` flag for this
+      time-setting failure.)
     - A `p` means the permissions are different and are being updated to the
-      sender's value (requires `--perms`).
+      sender's value (requires [`--perms`](#opt)).
     - An `o` means the owner is different and is being updated to the sender's
-      value (requires `--owner` and super-user privileges).
+      value (requires [`--owner`](#opt) and super-user privileges).
     - A `g` means the group is different and is being updated to the sender's
-      value (requires `--group` and the authority to set the group).
-    - A `u`|`n`|`b` indicates the following information: `u`  means the access
-      (use) time is different and is being updated to the sender's value
-      (requires `--atimes`); `n` means the create time (newness) is different
-      and is being updated to the sender's value (requires `--crtimes`); `b`
-      means that both the access and create times are being updated.
+      value (requires [`--group`](#opt) and the authority to set the group).
+    - A `u`|`n`|`b` indicates the following information:
+      - `u`  means the access (use) time is different and is being updated to
+       the sender's value (requires [`--atimes`](#opt))
+      - `n` means the create time (newness) is different and is being updated
+       to the sender's value (requires [`--crtimes`](#opt))
+      - `b` means that both the access and create times are being updated
     - The `a` means that the ACL information is being changed.
     - The `x` means that the extended attribute information is being changed.
 
@@ -2771,26 +3169,27 @@ your home directory (remove the '=' for that).
     This allows you to specify exactly what the rsync client outputs to the
     user on a per-update basis.  The format is a text string containing
     embedded single-character escape sequences prefixed with a percent (%)
-    character.  A default format of "%n%L" is assumed if either `--info=name`
-    or `-v` is specified (this tells you just the name of the file and, if the
-    item is a link, where it points).  For a full list of the possible escape
-    characters, see the "`log format`" setting in the rsyncd.conf manpage.
-
-    Specifying the `--out-format` option implies the `--info=name` option,
-    which will mention each file, dir, etc. that gets updated in a significant
-    way (a transferred file, a recreated symlink/device, or a touched
-    directory).  In addition, if the itemize-changes escape (%i) is included in
-    the string (e.g. if the `--itemize-changes` option was used), the logging
-    of names increases to mention any item that is changed in any way (as long
-    as the receiving side is at least 2.6.4).  See the `--itemize-changes`
-    option for a description of the output of "%i".
+    character.  A default format of "%n%L" is assumed if either
+    [`--info=name`](#opt) or [`-v`](#opt) is specified (this tells you just the
+    name of the file and, if the item is a link, where it points).  For a full
+    list of the possible escape characters, see the [`log
+    format`](rsyncd.conf.5#log_format) setting in the rsyncd.conf manpage.
+
+    Specifying the `--out-format` option implies the [`--info=name`](#opt)
+    option, which will mention each file, dir, etc. that gets updated in a
+    significant way (a transferred file, a recreated symlink/device, or a
+    touched directory).  In addition, if the itemize-changes escape (%i) is
+    included in the string (e.g. if the [`--itemize-changes`](#opt) option was
+    used), the logging of names increases to mention any item that is changed
+    in any way (as long as the receiving side is at least 2.6.4).  See the
+    [`--itemize-changes`](#opt) option for a description of the output of "%i".
 
     Rsync will output the out-format string prior to a file's transfer unless
     one of the transfer-statistic escapes is requested, in which case the
     logging is done at the end of the file's transfer.  When this late logging
-    is in effect and `--progress` is also specified, rsync will also output the
-    name of the file being transferred prior to its progress information
-    (followed, of course, by the out-format output).
+    is in effect and [`--progress`](#opt) is also specified, rsync will also
+    output the name of the file being transferred prior to its progress
+    information (followed, of course, by the out-format output).
 
 0.  `--log-file=FILE`
 
@@ -2798,10 +3197,10 @@ your home directory (remove the '=' for that).
     similar to the logging that a daemon does, but can be requested for the
     client side and/or the server side of a non-daemon transfer.  If specified
     as a client option, transfer logging will be enabled with a default format
-    of "%i %n%L".  See the `--log-file-format` option if you wish to override
-    this.
+    of "%i %n%L".  See the [`--log-file-format`](#opt) option if you wish to
+    override this.
 
-    Here's a example command that requests the remote side to log what is
+    Here's an example command that requests the remote side to log what is
     happening:
 
     >     rsync -av --remote-option=--log-file=/tmp/rlog src/ dest/
@@ -2809,24 +3208,30 @@ your home directory (remove the '=' for that).
     This is very useful if you need to debug why a connection is closing
     unexpectedly.
 
+    See also [the daemon version of the `--log-file` option](#dopt--log-file).
+
 0.  `--log-file-format=FORMAT`
 
     This allows you to specify exactly what per-update logging is put into the
-    file specified by the `--log-file` option (which must also be specified for
-    this option to have any effect).  If you specify an empty string, updated
-    files will not be mentioned in the log file.  For a list of the possible
-    escape characters, see the "`log format`" setting in the rsyncd.conf manpage.
+    file specified by the [`--log-file`](#opt) option (which must also be
+    specified for this option to have any effect).  If you specify an empty
+    string, updated files will not be mentioned in the log file.  For a list of
+    the possible escape characters, see the [`log format`](rsyncd.conf.5#log_format)
+    setting in the rsyncd.conf manpage.
+
+    The default FORMAT used if [`--log-file`](#opt) is specified and this
+    option is not is '%i %n%L'.
 
-    The default FORMAT used if `--log-file` is specified and this option is not
-    is '%i %n%L'.
+    See also [the daemon version of the `--log-file-format`
+    option](#dopt--log-file-format).
 
 0.  `--stats`
 
     This tells rsync to print a verbose set of statistics on the file transfer,
     allowing you to tell how effective rsync's delta-transfer algorithm is for
-    your data.  This option is equivalent to `--info=stats2` if combined with 0
-    or 1 `-v` options, or `--info=stats3` if combined with 2 or more `-v`
-    options.
+    your data.  This option is equivalent to [`--info=stats2`](#opt) if
+    combined with 0 or 1 [`-v`](#opt) options, or [`--info=stats3`](#opt) if
+    combined with 2 or more [`-v`](#opt) options.
 
     The current statistics are as follows:
 
@@ -2840,7 +3245,7 @@ your home directory (remove the '=' for that).
       sense) were created (as opposed to updated).  The total count will be
       followed by a list of counts by filetype (if the total is non-zero).
     - `Number of deleted files` is the count of how many "files" (generic
-      sense) were created (as opposed to updated).  The total count will be
+      sense) were deleted.  The total count will be
       followed by a list of counts by filetype (if the total is non-zero).
       Note that this line is only output if deletions are in effect, and only
       if protocol 31 is being used (the default for rsync 3.1.x).
@@ -2887,12 +3292,14 @@ your home directory (remove the '=' for that).
 
 0.  `--human-readable`, `-h`
 
-    Output numbers in a more human-readable format.  There are 3 possible
-    levels: (1) output numbers with a separator between each set of 3 digits
-    (either a comma or a period, depending on if the decimal point is
-    represented by a period or a comma); (2) output numbers in units of 1000
-    (with a character suffix for larger units -- see below); (3) output
-    numbers in units of 1024.
+    Output numbers in a more human-readable format.  There are 3 possible levels:
+
+    1. output numbers with a separator between each set of 3 digits (either a
+       comma or a period, depending on if the decimal point is represented by a
+       period or a comma).
+    2. output numbers in units of 1000 (with a character suffix for larger
+       units -- see below).
+    3. output numbers in units of 1024.
 
     The default is human-readable level 1.  Each `-h` option increases the
     level by one.  You can take the level down to 0 (to output numbers as pure
@@ -2907,7 +3314,7 @@ your home directory (remove the '=' for that).
     support human-readable level 1, and they default to level 0.  Thus,
     specifying one or two `-h` options will behave in a comparable manner in
     old and new versions as long as you didn't specify a `--no-h` option prior
-    to one or more `-h` options.  See the `--list-only` option for one
+    to one or more `-h` options.  See the [`--list-only`](#opt) option for one
     difference.
 
 0.  `--partial`
@@ -2920,56 +3327,64 @@ your home directory (remove the '=' for that).
 
 0.  `--partial-dir=DIR`
 
-    A better way to keep partial files than the `--partial` option is to
-    specify a _DIR_ that will be used to hold the partial data (instead of
-    writing it out to the destination file).  On the next transfer, rsync will
-    use a file found in this dir as data to speed up the resumption of the
+    This option modifies the behavior of the [`--partial`](#opt) option while
+    also implying that it be enabled.  This enhanced partial-file method puts
+    any partially transferred files into the specified _DIR_ instead of writing
+    the partial file out to the destination file.  On the next transfer, rsync
+    will use a file found in this dir as data to speed up the resumption of the
     transfer and then delete it after it has served its purpose.
 
-    Note that if `--whole-file` is specified (or implied), any partial-dir file
-    that is found for a file that is being updated will simply be removed
-    (since rsync is sending files without using rsync's delta-transfer
-    algorithm).
+    Note that if [`--whole-file`](#opt) is specified (or implied), any
+    partial-dir files that are found for a file that is being updated will
+    simply be removed (since rsync is sending files without using rsync's
+    delta-transfer algorithm).
 
-    Rsync will create the _DIR_ if it is missing (just the last dir -- not the
-    whole path).  This makes it easy to use a relative path (such as
+    Rsync will create the _DIR_ if it is missing, but just the last dir -- not
+    the whole path.  This makes it easy to use a relative path (such as
     "`--partial-dir=.rsync-partial`") to have rsync create the
-    partial-directory in the destination file's directory when needed, and then
-    remove it again when the partial file is deleted.  Note that the directory
-    is only removed if it is a relative pathname, as it is expected that an
-    absolute path is to a directory that is reserved for partial-dir work.
+    partial-directory in the destination file's directory when it is needed,
+    and then remove it again when the partial file is deleted.  Note that this
+    directory removal is only done for a relative pathname, as it is expected
+    that an absolute path is to a directory that is reserved for partial-dir
+    work.
 
     If the partial-dir value is not an absolute path, rsync will add an exclude
     rule at the end of all your existing excludes.  This will prevent the
     sending of any partial-dir files that may exist on the sending side, and
     will also prevent the untimely deletion of partial-dir items on the
     receiving side.  An example: the above `--partial-dir` option would add the
-    equivalent of "`-f '-p .rsync-partial/'`" at the end of any other filter
-    rules.
+    equivalent of this "perishable" exclude at the end of any other filter
+    rules: `-f '-p .rsync-partial/'`
 
     If you are supplying your own exclude rules, you may need to add your own
-    exclude/hide/protect rule for the partial-dir because (1) the auto-added
-    rule may be ineffective at the end of your other rules, or (2) you may wish
-    to override rsync's exclude choice.  For instance, if you want to make
-    rsync clean-up any left-over partial-dirs that may be lying around, you
-    should specify `--delete-after` and add a "risk" filter rule, e.g.
-    `-f 'R .rsync-partial/'`. (Avoid using `--delete-before` or
-    `--delete-during` unless you don't need rsync to use any of the left-over
-    partial-dir data during the current run.)
+    exclude/hide/protect rule for the partial-dir because:
+
+    1. the auto-added rule may be ineffective at the end of your other rules, or
+    2. you may wish to override rsync's exclude choice.
+
+    For instance, if you want to make rsync clean-up any left-over partial-dirs
+    that may be lying around, you should specify [`--delete-after`](#opt) and
+    add a "risk" filter rule, e.g.  `-f 'R .rsync-partial/'`. Avoid using
+    [`--delete-before`](#opt) or [`--delete-during`](#opt) unless you don't
+    need rsync to use any of the left-over partial-dir data during the current
+    run.
 
     IMPORTANT: the `--partial-dir` should not be writable by other users or it
-    is a security risk.  E.g. AVOID "/tmp".
-
-    You can also set the partial-dir value the RSYNC_PARTIAL_DIR environment
-    variable.  Setting this in the environment does not force `--partial` to be
-    enabled, but rather it affects where partial files go when `--partial` is
-    specified.  For instance, instead of using `--partial-dir=.rsync-tmp` along
-    with `--progress`, you could set RSYNC_PARTIAL_DIR=.rsync-tmp in your
-    environment and then just use the `-P` option to turn on the use of the
-    .rsync-tmp dir for partial transfers.  The only times that the `--partial`
-    option does not look for this environment value are (1) when `--inplace`
-    was specified (since `--inplace` conflicts with `--partial-dir`), and (2)
-    when `--delay-updates` was specified (see below).
+    is a security risk!  E.g. AVOID "/tmp"!
+
+    You can also set the partial-dir value the [`RSYNC_PARTIAL_DIR`](#)
+    environment variable.  Setting this in the environment does not force
+    [`--partial`](#opt) to be enabled, but rather it affects where partial
+    files go when [`--partial`](#opt) is specified.  For instance, instead of
+    using `--partial-dir=.rsync-tmp` along with [`--progress`](#opt), you could
+    set [`RSYNC_PARTIAL_DIR=.rsync-tmp`](#) in your environment and then use
+    the [`-P`](#opt) option to turn on the use of the .rsync-tmp dir for
+    partial transfers.  The only times that the [`--partial`](#opt) option does
+    not look for this environment value are:
+
+    1. when [`--inplace`](#opt) was specified (since [`--inplace`](#opt)
+       conflicts with `--partial-dir`), and
+    2. when [`--delay-updates`](#opt) was specified (see below).
 
     When a modern rsync resumes the transfer of a file in the partial-dir, that
     partial file is now updated in-place instead of creating yet another
@@ -2978,10 +3393,10 @@ your home directory (remove the '=' for that).
     3.2.0.
 
     For the purposes of the daemon-config's "`refuse options`" setting,
-    `--partial-dir` does _not_ imply `--partial`.  This is so that a refusal of
-    the `--partial` option can be used to disallow the overwriting of
-    destination files with a partial transfer, while still allowing the safer
-    idiom provided by `--partial-dir`.
+    `--partial-dir` does _not_ imply [`--partial`](#opt).  This is so that a
+    refusal of the [`--partial`](#opt) option can be used to disallow the
+    overwriting of destination files with a partial transfer, while still
+    allowing the safer idiom provided by `--partial-dir`.
 
 0.  `--delay-updates`
 
@@ -2990,27 +3405,30 @@ your home directory (remove the '=' for that).
     renamed into place in rapid succession.  This attempts to make the updating
     of the files a little more atomic.  By default the files are placed into a
     directory named `.~tmp~` in each file's destination directory, but if
-    you've specified the `--partial-dir` option, that directory will be used
-    instead.  See the comments in the `--partial-dir` section for a discussion
-    of how this `.~tmp~` dir will be excluded from the transfer, and what you
-    can do if you want rsync to cleanup old `.~tmp~` dirs that might be lying
-    around.  Conflicts with `--inplace` and `--append`.
+    you've specified the [`--partial-dir`](#opt) option, that directory will be
+    used instead.  See the comments in the [`--partial-dir`](#opt) section for
+    a discussion of how this `.~tmp~` dir will be excluded from the transfer,
+    and what you can do if you want rsync to cleanup old `.~tmp~` dirs that
+    might be lying around.  Conflicts with [`--inplace`](#opt) and
+    [`--append`](#opt).
 
-    This option implies `--no-inc-recursive` since it needs the full file list
-    in memory in order to be able to iterate over it at the end.
+    This option implies [`--no-inc-recursive`](#opt) since it needs the full
+    file list in memory in order to be able to iterate over it at the end.
 
     This option uses more memory on the receiving side (one bit per file
     transferred) and also requires enough free disk space on the receiving side
     to hold an additional copy of all the updated files.  Note also that you
-    should not use an absolute path to `--partial-dir` unless (1) there is no
-    chance of any of the files in the transfer having the same name (since all
-    the updated files will be put into a single directory if the path is
-    absolute) and (2) there are no mount points in the hierarchy (since the
-    delayed updates will fail if they can't be renamed into place).
+    should not use an absolute path to [`--partial-dir`](#opt) unless:
 
-    See also the "atomic-rsync" perl script in the "support" subdir for an
-    update algorithm that is even more atomic (it uses `--link-dest` and a
-    parallel hierarchy of files).
+    1. there is no chance of any of the files in the transfer having the same
+       name (since all the updated files will be put into a single directory if
+       the path is absolute), and
+    2. there are no mount points in the hierarchy (since the delayed updates
+       will fail if they can't be renamed into place).
+
+    See also the "atomic-rsync" python script in the "support" subdir for an
+    update algorithm that is even more atomic (it uses [`--link-dest`](#opt)
+    and a parallel hierarchy of files).
 
 0.  `--prune-empty-dirs`, `-m`
 
@@ -3020,10 +3438,8 @@ your home directory (remove the '=' for that).
     directories when the sending rsync is recursively scanning a hierarchy of
     files using include/exclude/filter rules.
 
-    Note that the use of transfer rules, such as the `--min-size` option, does
-    not affect what goes into the file list, and thus does not leave
-    directories empty, even if none of the files in a directory match the
-    transfer rule.
+    This option can still leave empty directories on the receiving side if you
+    make use of [TRANSFER_RULES](#).
 
     Because the file-list is actually being pruned, this option also affects
     what directories get deleted when a delete is active.  However, keep in
@@ -3053,9 +3469,9 @@ your home directory (remove the '=' for that).
 
     This option tells rsync to print information showing the progress of the
     transfer.  This gives a bored user something to watch.  With a modern rsync
-    this is the same as specifying `--info=flist2,name,progress`, but any
-    user-supplied settings for those info flags takes precedence (e.g.
-    "`--info=flist0 --progress`").
+    this is the same as specifying [`--info=flist2,name,progress`](#opt), but
+    any user-supplied settings for those info flags takes precedence (e.g.
+    [`--info=flist0 --progress`](#opt)).
 
     While rsync is transferring a regular file, it updates a progress line that
     looks like this:
@@ -3098,16 +3514,17 @@ your home directory (remove the '=' for that).
 
 0.  `-P`
 
-    The `-P` option is equivalent to `--partial --progress`.  Its purpose is
-    to make it much easier to specify these two options for a long transfer
-    that may be interrupted.
+    The `-P` option is equivalent to "[`--partial`](#opt)
+    [`--progress`](#opt)".  Its purpose is to make it much easier to specify
+    these two options for a long transfer that may be interrupted.
 
-    There is also a `--info=progress2` option that outputs statistics based on
-    the whole transfer, rather than individual files.  Use this flag without
-    outputting a filename (e.g. avoid `-v` or specify `--info=name0`) if you
-    want to see how the transfer is doing without scrolling the screen with a
-    lot of names. (You don't need to specify the `--progress` option in order
-    to use `--info=progress2`.)
+    There is also a [`--info=progress2`](#opt) option that outputs statistics
+    based on the whole transfer, rather than individual files.  Use this flag
+    without outputting a filename (e.g. avoid `-v` or specify
+    [`--info=name0`](#opt)) if you want to see how the transfer is doing
+    without scrolling the screen with a lot of names. (You don't need to
+    specify the [`--progress`](#opt) option in order to use
+    [`--info=progress2`](#opt).)
 
     Finally, you can get an instant progress report by sending rsync a signal
     of either SIGINFO or SIGVTALRM.  On BSD systems, a SIGINFO is generated by
@@ -3116,8 +3533,8 @@ your home directory (remove the '=' for that).
     output a single progress report which is output when the current file
     transfer finishes (so it may take a little time if a big file is being
     handled when the signal arrives).  A filename is output (if needed)
-    followed by the `--info=progress2` format of progress info.  If you don't
-    know which of the 3 rsync processes is the client process, it's OK to
+    followed by the [`--info=progress2`](#opt) format of progress info.  If you
+    don't know which of the 3 rsync processes is the client process, it's OK to
     signal all of them (since the non-client processes ignore the signal).
 
     CAUTION: sending SIGVTALRM to an older rsync (pre-3.2.0) will kill it.
@@ -3150,40 +3567,48 @@ your home directory (remove the '=' for that).
 
     This option will cause the source files to be listed instead of
     transferred.  This option is inferred if there is a single source arg and
-    no destination specified, so its main uses are: (1) to turn a copy command
-    that includes a destination arg into a file-listing command, or (2) to be
-    able to specify more than one source arg (note: be sure to include the
-    destination).  Caution: keep in mind that a source arg with a wild-card is
-    expanded by the shell into multiple args, so it is never safe to try to
-    list such an arg without using this option. For example:
+    no destination specified, so its main uses are:
+
+    1. to turn a copy command that includes a destination arg into a
+       file-listing command, or
+    2. to be able to specify more than one source arg.  Note: be sure to
+       include the destination.
+
+    CAUTION: keep in mind that a source arg with a wild-card is expanded by the
+    shell into multiple args, so it is never safe to try to specify a single
+    wild-card arg to try to infer this option. A safe example is:
 
     >     rsync -av --list-only foo* dest/
 
-    Starting with rsync 3.1.0, the sizes output by `--list-only` are affected
-    by the `--human-readable` option.  By default they will contain digit
-    separators, but higher levels of readability will output the sizes with
-    unit suffixes.  Note also that the column width for the size output has
-    increased from 11 to 14 characters for all human-readable levels.  Use
-    `--no-h` if you want just digits in the sizes, and the old column width of
-    11 characters.
+    This option always uses an output format that looks similar to this:
+
+    >     drwxrwxr-x          4,096 2022/09/30 12:53:11 support
+    >     -rw-rw-r--             80 2005/01/11 10:37:37 support/Makefile
+
+    The only option that affects this output style is (as of 3.1.0) the
+    [`--human-readable`](#opt) (`-h`) option.  The default is to output sizes
+    as byte counts with digit separators (in a 14-character-width column).
+    Specifying at least one `-h` option makes the sizes output with unit
+    suffixes.  If you want old-style bytecount sizes without digit separators
+    (and an 11-character-width column) use `--no-h`.
 
     Compatibility note: when requesting a remote listing of files from an rsync
     that is version 2.6.3 or older, you may encounter an error if you ask for a
-    non-recursive listing.  This is because a file listing implies the `--dirs`
-    option w/o `--recursive`, and older rsyncs don't have that option.  To
-    avoid this problem, either specify the `--no-dirs` option (if you don't
-    need to expand a directory's content), or turn on recursion and exclude the
-    content of subdirectories: `-r --exclude='/*/*'`.
+    non-recursive listing.  This is because a file listing implies the
+    [`--dirs`](#opt) option w/o [`--recursive`](#opt), and older rsyncs don't
+    have that option.  To avoid this problem, either specify the `--no-dirs`
+    option (if you don't need to expand a directory's content), or turn on
+    recursion and exclude the content of subdirectories: `-r --exclude='/*/*'`.
 
 0.  `--bwlimit=RATE`
 
     This option allows you to specify the maximum transfer rate for the data
     sent over the socket, specified in units per second.  The RATE value can be
     suffixed with a string to indicate a size multiplier, and may be a
-    fractional value (e.g. "`--bwlimit=1.5m`").  If no suffix is specified, the
+    fractional value (e.g. `--bwlimit=1.5m`).  If no suffix is specified, the
     value will be assumed to be in units of 1024 bytes (as if "K" or "KiB" had
-    been appended).  See the `--max-size` option for a description of all the
-    available suffixes.  A value of 0 specifies no limit.
+    been appended).  See the [`--max-size`](#opt) option for a description of
+    all the available suffixes.  A value of 0 specifies no limit.
 
     For backward-compatibility reasons, the rate limit will be rounded to the
     nearest KiB unit, so no rate smaller than 1024 bytes per second is
@@ -3195,26 +3620,28 @@ your home directory (remove the '=' for that).
     rsync writes out a block of data and then sleeps to bring the average rate
     into compliance.
 
-    Due to the internal buffering of data, the `--progress` option may not be
-    an accurate reflection on how fast the data is being sent.  This is because
-    some files can show up as being rapidly sent when the data is quickly
-    buffered, while other can show up as very slow when the flushing of the
-    output buffer occurs.  This may be fixed in a future version.
+    Due to the internal buffering of data, the [`--progress`](#opt) option may
+    not be an accurate reflection on how fast the data is being sent.  This is
+    because some files can show up as being rapidly sent when the data is
+    quickly buffered, while other can show up as very slow when the flushing of
+    the output buffer occurs.  This may be fixed in a future version.
 
-0.  `--stop-after=MINS
+    See also [the daemon version of the `--bwlimit` option](#dopt--bwlimit).
+
+0.  `--stop-after=MINS`, (`--time-limit=MINS`)
 
     This option tells rsync to stop copying when the specified number of
     minutes has elapsed.
 
-    Rsync also accepts an earlier version of this option: `--time-limit=MINS`.
-
     For maximal flexibility, rsync does not communicate this option to the
     remote rsync since it is usually enough that one side of the connection
     quits as specified.  This allows the option's use even when only one side
     of the connection supports it.  You can tell the remote side about the time
-    limit using `--remote-option` (`-M`), should the need arise.
+    limit using [`--remote-option`](#opt) (`-M`), should the need arise.
 
-0.  `--stop-at=y-m-dTh:m
+    The `--time-limit` version of this option is deprecated.
+
+0.  `--stop-at=y-m-dTh:m`
 
     This option tells rsync to stop copying when the specified point in time
     has been reached. The date & time can be fully specified in a numeric
@@ -3237,27 +3664,33 @@ your home directory (remove the '=' for that).
     remote rsync since it is usually enough that one side of the connection
     quits as specified.  This allows the option's use even when only one side
     of the connection supports it.  You can tell the remote side about the time
-    limit using `--remote-option` (`-M`), should the need arise.  Do keep in
-    mind that the remote host may have a different default timezone than your
-    local host.
+    limit using [`--remote-option`](#opt) (`-M`), should the need arise.  Do
+    keep in mind that the remote host may have a different default timezone
+    than your local host.
+
+0.  `--fsync`
+
+    Cause the receiving side to fsync each finished file.  This may slow down
+    the transfer, but can help to provide peace of mind when updating critical
+    files.
 
 0.  `--write-batch=FILE`
 
     Record a file that can later be applied to another identical destination
-    with `--read-batch`.  See the "BATCH MODE" section for details, and also
-    the `--only-write-batch` option.
+    with [`--read-batch`](#opt).  See the "BATCH MODE" section for details, and
+    also the [`--only-write-batch`](#opt) option.
 
     This option overrides the negotiated checksum & compress lists and always
     negotiates a choice based on old-school md5/md4/zlib choices.  If you want
-    a more modern choice, use the `--checksum-choice` (`--cc`) and/or
-    `--compress-choice` (`--zc`) options.
+    a more modern choice, use the [`--checksum-choice`](#opt) (`--cc`) and/or
+    [`--compress-choice`](#opt) (`--zc`) options.
 
 0.  `--only-write-batch=FILE`
 
-    Works like `--write-batch`, except that no updates are made on the
+    Works like [`--write-batch`](#opt), except that no updates are made on the
     destination system when creating the batch.  This lets you transport the
     changes to the destination system via some other means and then apply the
-    changes via `--read-batch`.
+    changes via [`--read-batch`](#opt).
 
     Note that you can feel free to write the batch directly to some portable
     media: if this media fills to capacity before the end of the transfer, you
@@ -3274,18 +3707,18 @@ your home directory (remove the '=' for that).
 0.  `--read-batch=FILE`
 
     Apply all of the changes stored in FILE, a file previously generated by
-    `--write-batch`.  If _FILE_ is `-`, the batch data will be read from
-    standard input. See the "BATCH MODE" section for details.
+    [`--write-batch`](#opt).  If _FILE_ is `-`, the batch data will be read
+    from standard input. See the "BATCH MODE" section for details.
 
 0.  `--protocol=NUM`
 
     Force an older protocol version to be used.  This is useful for creating a
     batch file that is compatible with an older version of rsync.  For
-    instance, if rsync 2.6.4 is being used with the `--write-batch` option, but
-    rsync 2.6.3 is what will be used to run the `--read-batch` option, you
-    should use "--protocol=28" when creating the batch file to force the older
-    protocol version to be used in the batch file (assuming you can't upgrade
-    the rsync on the reading system).
+    instance, if rsync 2.6.4 is being used with the [`--write-batch`](#opt)
+    option, but rsync 2.6.3 is what will be used to run the
+    [`--read-batch`](#opt) option, you should use "--protocol=28" when creating
+    the batch file to force the older protocol version to be used in the batch
+    file (assuming you can't upgrade the rsync on the reading system).
 
 0.  `--iconv=CONVERT_SPEC`
 
@@ -3297,15 +3730,15 @@ your home directory (remove the '=' for that).
     This order ensures that the option will stay the same whether you're
     pushing or pulling files.  Finally, you can specify either `--no-iconv` or
     a CONVERT_SPEC of "-" to turn off any conversion.  The default setting of
-    this option is site-specific, and can also be affected via the RSYNC_ICONV
-    environment variable.
+    this option is site-specific, and can also be affected via the
+    [`RSYNC_ICONV`](#) environment variable.
 
     For a list of what charset names your local iconv library supports, you can
     run "`iconv --list`".
 
-    If you specify the `--protect-args` option (`-s`), rsync will translate the
-    filenames you specify on the command-line that are being sent to the remote
-    host.  See also the `--files-from` option.
+    If you specify the [`--secluded-args`](#opt) (`-s`) option, rsync will
+    translate the filenames you specify on the command-line that are being sent
+    to the remote host.  See also the [`--files-from`](#opt) option.
 
     Note that rsync does not do any conversion of names in filter files
     (including include/exclude files).  It is up to you to ensure that you're
@@ -3326,12 +3759,12 @@ your home directory (remove the '=' for that).
     socket when directly contacting an rsync daemon, as well as the forwarding
     of the `-4` or `-6` option to ssh when rsync can deduce that ssh is being
     used as the remote shell.  For other remote shells you'll need to specify
-    the "`--rsh SHELL -4`" option directly (or whatever ipv4/ipv6 hint options
+    the "`--rsh SHELL -4`" option directly (or whatever IPv4/IPv6 hint options
     it uses).
 
-    These options also exist in the `--daemon` mode section.
+    See also [the daemon version of these options](#dopt--ipv4).
 
-    If rsync was complied without support for IPv6, the `--ipv6` option will
+    If rsync was compiled without support for IPv6, the `--ipv6` option will
     have no effect.  The `rsync --version` output will contain "`no IPv6`" if
     is the case.
 
@@ -3346,7 +3779,7 @@ your home directory (remove the '=' for that).
     user wants a more random checksum seed.  Setting NUM to 0 causes rsync to
     use the default of **time**() for checksum seed.
 
-# DAEMON OPTIONS
+## DAEMON OPTIONS
 
 The options allowed when starting an rsync daemon are as follows:
 
@@ -3359,31 +3792,37 @@ The options allowed when starting an rsync daemon are as follows:
     If standard input is a socket then rsync will assume that it is being run
     via inetd, otherwise it will detach from the current terminal and become a
     background daemon.  The daemon will read the config file (rsyncd.conf) on
-    each connect made by a client and respond to requests accordingly.  See the
-    **rsyncd.conf**(5) man page for more details.
+    each connect made by a client and respond to requests accordingly.
+
+    See the [**rsyncd.conf**(5)](rsyncd.conf.5) manpage for more details.
 
 0.  `--address=ADDRESS`
 
     By default rsync will bind to the wildcard address when run as a daemon
     with the `--daemon` option.  The `--address` option allows you to specify a
     specific IP address (or hostname) to bind to.  This makes virtual hosting
-    possible in conjunction with the `--config` option.  See also the "address"
-    global option in the rsyncd.conf manpage.
+    possible in conjunction with the `--config` option.
+
+    See also the [address](rsyncd.conf.5#address) global option in the
+    rsyncd.conf manpage and the [client version of the `--address`
+    option](#opt--address).
 
 0.  `--bwlimit=RATE`
 
     This option allows you to specify the maximum transfer rate for the data
     the daemon sends over the socket.  The client can still specify a smaller
-    `--bwlimit` value, but no larger value will be allowed.  See the client
-    version of this option (above) for some extra details.
+    `--bwlimit` value, but no larger value will be allowed.
+
+    See the [client version of the `--bwlimit` option](#opt--bwlimit) for some
+    extra details.
 
 0.  `--config=FILE`
 
     This specifies an alternate config file than the default.  This is only
-    relevant when `--daemon` is specified.  The default is /etc/rsyncd.conf
-    unless the daemon is running over a remote shell program and the remote
-    user is not the super-user; in that case the default is rsyncd.conf in the
-    current directory (typically $HOME).
+    relevant when [`--daemon`](#dopt) is specified.  The default is
+    /etc/rsyncd.conf unless the daemon is running over a remote shell program
+    and the remote user is not the super-user; in that case the default is
+    rsyncd.conf in the current directory (typically $HOME).
 
 0.  `--dparam=OVERRIDE`, `-M`
 
@@ -3407,14 +3846,18 @@ The options allowed when starting an rsync daemon are as follows:
 0.  `--port=PORT`
 
     This specifies an alternate TCP port number for the daemon to listen on
-    rather than the default of 873.  See also the "port" global option in the
-    rsyncd.conf manpage.
+    rather than the default of 873.
+
+    See also [the client version of the `--port` option](#opt--port) and the
+    [port](rsyncd.conf.5#port) global setting in the rsyncd.conf manpage.
 
 0.  `--log-file=FILE`
 
     This option tells the rsync daemon to use the given log-file name instead
     of using the "`log file`" setting in the config file.
 
+    See also [the client version of the `--log-file` option](#opt--log-file).
+
 0.  `--log-file-format=FORMAT`
 
     This option tells the rsync daemon to use the given FORMAT string instead
@@ -3422,10 +3865,15 @@ The options allowed when starting an rsync daemon are as follows:
     "`transfer logging`" unless the string is empty, in which case transfer
     logging is turned off.
 
+    See also [the client version of the `--log-file-format`
+    option](#opt--log-file-format).
+
 0.  `--sockopts`
 
-    This overrides the `socket options` setting in the rsyncd.conf file and has
-    the same syntax.
+    This overrides the [`socket options`](rsyncd.conf.5#socket_options)
+    setting in the rsyncd.conf file and has the same syntax.
+
+    See also [the client version of the `--sockopts` option](#opt--sockopts).
 
 0.  `--verbose`, `-v`
 
@@ -3434,6 +3882,8 @@ The options allowed when starting an rsync daemon are as follows:
     will be controlled by the options that the client used and the
     "`max verbosity`" setting in the module's config section.
 
+    See also [the client version of the `--verbose` option](#opt--verbose).
+
 0.  `--ipv4`, `-4` or `--ipv6`, `-6`
 
     Tells rsync to prefer IPv4/IPv6 when creating the incoming sockets that the
@@ -3443,9 +3893,9 @@ The options allowed when starting an rsync daemon are as follows:
     using the port, try specifying `--ipv6` or `--ipv4` when starting the
     daemon).
 
-    These options also exist in the regular rsync options section.
+    See also [the client version of these options](#opt--ipv4).
 
-    If rsync was complied without support for IPv6, the `--ipv6` option will
+    If rsync was compiled without support for IPv6, the `--ipv6` option will
     have no effect.  The `rsync --version` output will contain "`no IPv6`" if
     is the case.
 
@@ -3454,21 +3904,148 @@ The options allowed when starting an rsync daemon are as follows:
     When specified after `--daemon`, print a short help page describing the
     options available for starting an rsync daemon.
 
-# FILTER RULES
+## FILTER RULES
 
-The filter rules allow for flexible selection of which files to transfer
-(include) and which files to skip (exclude).  The rules either directly specify
-include/exclude patterns or they specify a way to acquire more include/exclude
-patterns (e.g. to read them from a file).
+The filter rules allow for custom control of several aspects of how files are
+handled:
 
-As the list of files/directories to transfer is built, rsync checks each name
-to be transferred against the list of include/exclude patterns in turn, and the
-first matching pattern is acted on: if it is an exclude pattern, then that file
-is skipped; if it is an include pattern then that filename is not skipped; if
-no matching pattern is found, then the filename is not skipped.
+- Control which files the sending side puts into the file list that describes
+  the transfer hierarchy
+- Control which files the receiving side protects from deletion when the file
+  is not in the sender's file list
+- Control which extended attribute names are skipped when copying xattrs
+
+The rules are either directly specified via option arguments or they can be
+read in from one or more files.  The filter-rule files can even be a part of
+the hierarchy of files being copied, affecting different parts of the tree in
+different ways.
+
+### SIMPLE INCLUDE/EXCLUDE RULES
+
+We will first cover the basics of how include & exclude rules affect what files
+are transferred, ignoring any deletion side-effects.  Filter rules mainly
+affect the contents of directories that rsync is "recursing" into, but they can
+also affect a top-level item in the transfer that was specified as a argument.
+
+The default for any unmatched file/dir is for it to be included in the
+transfer, which puts the file/dir into the sender's file list.  The use of an
+exclude rule causes one or more matching files/dirs to be left out of the
+sender's file list.  An include rule can be used to limit the effect of an
+exclude rule that is matching too many files.
+
+The order of the rules is important because the first rule that matches is the
+one that takes effect.  Thus, if an early rule excludes a file, no include rule
+that comes after it can have any effect. This means that you must place any
+include overrides somewhere prior to the exclude that it is intended to limit.
 
-Rsync builds an ordered list of filter rules as specified on the command-line.
-Filter rules have the following syntax:
+When a directory is excluded, all its contents and sub-contents are also
+excluded.  The sender doesn't scan through any of it at all, which can save a
+lot of time when skipping large unneeded sub-trees.
+
+It is also important to understand that the include/exclude rules are applied
+to every file and directory that the sender is recursing into. Thus, if you
+want a particular deep file to be included, you have to make sure that none of
+the directories that must be traversed on the way down to that file are
+excluded or else the file will never be discovered to be included. As an
+example, if the directory "`a/path`" was given as a transfer argument and you
+want to ensure that the file "`a/path/down/deep/wanted.txt`" is a part of the
+transfer, then the sender must not exclude the directories "`a/path`",
+"`a/path/down`", or "`a/path/down/deep`" as it makes it way scanning through
+the file tree.
+
+When you are working on the rules, it can be helpful to ask rsync to tell you
+what is being excluded/included and why.  Specifying `--debug=FILTER` or (when
+pulling files) `-M--debug=FILTER` turns on level 1 of the FILTER debug
+information that will output a message any time that a file or directory is
+included or excluded and which rule it matched.  Beginning in 3.2.4 it will
+also warn if a filter rule has trailing whitespace, since an exclude of "foo "
+(with a trailing space) will not exclude a file named "foo".
+
+Exclude and include rules can specify wildcard [PATTERN MATCHING RULES](#)
+(similar to shell wildcards) that allow you to match things like a file suffix
+or a portion of a filename.
+
+A rule can be limited to only affecting a directory by putting a trailing slash
+onto the filename.
+
+### SIMPLE INCLUDE/EXCLUDE EXAMPLE
+
+With the following file tree created on the sending side:
+
+>     mkdir x/
+>     touch x/file.txt
+>     mkdir x/y/
+>     touch x/y/file.txt
+>     touch x/y/zzz.txt
+>     mkdir x/z/
+>     touch x/z/file.txt
+
+Then the following rsync command will transfer the file "`x/y/file.txt`" and
+the directories needed to hold it, resulting in the path "`/tmp/x/y/file.txt`"
+existing on the remote host:
+
+>     rsync -ai -f'+ x/' -f'+ x/y/' -f'+ x/y/file.txt' -f'- *' x host:/tmp/
+
+Aside: this copy could also have been accomplished using the [`-R`](#opt)
+option (though the 2 commands behave differently if deletions are enabled):
+
+>     rsync -aiR x/y/file.txt host:/tmp/
+
+The following command does not need an include of the "x" directory because it
+is not a part of the transfer (note the traililng slash).  Running this command
+would copy just "`/tmp/x/file.txt`" because the "y" and "z" dirs get excluded:
+
+>     rsync -ai -f'+ file.txt' -f'- *' x/ host:/tmp/x/
+
+This command would omit the zzz.txt file while copying "x" and everything else
+it contains:
+
+>     rsync -ai -f'- zzz.txt' x host:/tmp/
+
+### FILTER RULES WHEN DELETING
+
+By default the include & exclude filter rules affect both the sender
+(as it creates its file list)
+and the receiver (as it creates its file lists for calculating deletions).  If
+no delete option is in effect, the receiver skips creating the delete-related
+file lists.  This two-sided default can be manually overridden so that you are
+only specifying sender rules or receiver rules, as described in the [FILTER
+RULES IN DEPTH](#) section.
+
+When deleting, an exclude protects a file from being removed on the receiving
+side while an include overrides that protection (putting the file at risk of
+deletion). The default is for a file to be at risk -- its safety depends on it
+matching a corresponding file from the sender.
+
+An example of the two-sided exclude effect can be illustrated by the copying of
+a C development directory between 2 systems.  When doing a touch-up copy, you
+might want to skip copying the built executable and the `.o` files (sender
+hide) so that the receiving side can build their own and not lose any object
+files that are already correct (receiver protect).  For instance:
+
+>     rsync -ai --del -f'- *.o' -f'- cmd' src host:/dest/
+
+Note that using `-f'-p *.o'` is even better than `-f'- *.o'` if there is a
+chance that the directory structure may have changed.  The "p" modifier is
+discussed in [FILTER RULE MODIFIERS](#).
+
+One final note, if your shell doesn't mind unexpanded wildcards, you could
+simplify the typing of the filter options by using an underscore in place of
+the space and leaving off the quotes.  For instance, `-f -_*.o -f -_cmd` (and
+similar) could be used instead of the filter options above.
+
+### FILTER RULES IN DEPTH
+
+Rsync supports old-style include/exclude rules and new-style filter rules.  The
+older rules are specified using [`--include`](#opt) and [`--exclude`](#opt) as
+well as the [`--include-from`](#opt) and [`--exclude-from`](#opt). These are
+limited in behavior but they don't require a "-" or "+" prefix.  An old-style
+exclude rule is turned into a "`- name`" filter rule (with no modifiers) and an
+old-style include rule is turned into a "`+ name`" filter rule (with no
+modifiers).
+
+Rsync builds an ordered list of filter rules as specified on the command-line
+and/or read-in from files.  New style filter rules have the following syntax:
 
 >     RULE [PATTERN_OR_FILENAME]
 >     RULE,MODIFIERS [PATTERN_OR_FILENAME]
@@ -3476,173 +4053,147 @@ Filter rules have the following syntax:
 You have your choice of using either short or long RULE names, as described
 below.  If you use a short-named rule, the ',' separating the RULE from the
 MODIFIERS is optional.  The PATTERN or FILENAME that follows (when present)
-must come after either a single space or an underscore (\_).  Here are the
-available rule prefixes:
-
-0.  `exclude, '-'` specifies an exclude pattern.
-0.  `include, '+'` specifies an include pattern.
-0.  `merge, '.'` specifies a merge-file to read for more rules.
-0.  `dir-merge, ':'` specifies a per-directory merge-file.
+must come after either a single space or an underscore (\_). Any additional
+spaces and/or underscores are considered to be a part of the pattern name.
+Here are the available rule prefixes:
+
+0.  `exclude, '-'` specifies an exclude pattern that (by default) is both a
+    `hide` and a `protect`.
+0.  `include, '+'` specifies an include pattern that (by default) is both a
+    `show` and a `risk`.
+0.  `merge, '.'` specifies a merge-file on the client side to read for more
+    rules.
+0.  `dir-merge, ':'` specifies a per-directory merge-file.  Using this kind of
+    filter rule requires that you trust the sending side's filter checking, so
+    it has the side-effect mentioned under the [`--trust-sender`](#opt) option.
 0.  `hide, 'H'` specifies a pattern for hiding files from the transfer.
-0.  `show, 'S'` files that match the pattern are not hidden.
+    Equivalent to a sender-only exclude, so `-f'H foo'` could also be specified
+    as `-f'-s foo'`.
+0.  `show, 'S'` files that match the pattern are not hidden. Equivalent to a
+    sender-only include, so `-f'S foo'` could also be specified as `-f'+s
+    foo'`.
 0.  `protect, 'P'` specifies a pattern for protecting files from deletion.
-0.  `risk, 'R'` files that match the pattern are not protected.
+    Equivalent to a receiver-only exclude, so `-f'P foo'` could also be
+    specified as `-f'-r foo'`.
+0.  `risk, 'R'` files that match the pattern are not protected. Equivalent to a
+    receiver-only include, so `-f'R foo'` could also be specified as `-f'+r
+    foo'`.
 0.  `clear, '!'` clears the current include/exclude list (takes no arg)
 
-When rules are being read from a file, empty lines are ignored, as are comment
-lines that start with a "#".
-
-[comment]: # (Remember that markdown strips spaces from start/end of ` ... ` sequences!)
-[comment]: # (Thus, the `x ` sequences below use a literal non-breakable space!)
-
-Note that the `--include` & `--exclude` command-line options do not allow the
-full range of rule parsing as described above -- they only allow the
-specification of include / exclude patterns plus a "`!`" token to clear the
-list (and the normal comment parsing when rules are read from a file).  If a
-pattern does not begin with "`- `" (dash, space) or "`+ `" (plus, space), then
-the rule will be interpreted as if "`+ `" (for an include option) or "`- `"
-(for an exclude option) were prefixed to the string.  A `--filter` option, on
-the other hand, must always contain either a short or long rule name at the
-start of the rule.
-
-Note also that the `--filter`, `--include`, and `--exclude` options take one
-rule/pattern each.  To add multiple ones, you can repeat the options on the
-command-line, use the merge-file syntax of the `--filter` option, or the
-`--include-from` / `--exclude-from` options.
-
-# INCLUDE/EXCLUDE PATTERN RULES
-
-You can include and exclude files by specifying patterns using the "+", "-",
-etc. filter rules (as introduced in the FILTER RULES section above).  The
-include/exclude rules each specify a pattern that is matched against the names
-of the files that are going to be transferred.  These patterns can take several
-forms:
-
-- if the pattern starts with a `/` then it is anchored to a particular spot in
-  the hierarchy of files, otherwise it is matched against the end of the
-  pathname.  This is similar to a leading `^` in regular expressions.  Thus
-  `/foo` would match a name of "foo" at either the "root of the transfer" (for
-  a global rule) or in the merge-file's directory (for a per-directory rule).
-  An unqualified `foo` would match a name of "foo" anywhere in the tree because
-  the algorithm is applied recursively from the top down; it behaves as if each
-  path component gets a turn at being the end of the filename.  Even the
-  unanchored "sub/foo" would match at any point in the hierarchy where a "foo"
-  was found within a directory named "sub".  See the section on ANCHORING
-  INCLUDE/EXCLUDE PATTERNS for a full discussion of how to specify a pattern
-  that matches at the root of the transfer.
-- if the pattern ends with a `/` then it will only match a directory, not a
-  regular file, symlink, or device.
-- rsync chooses between doing a simple string match and wildcard matching by
-  checking if the pattern contains one of these three wildcard characters:
-  '`*`', '`?`', and '`[`' .
-- a '`*`' matches any path component, but it stops at slashes.
-- use '`**`' to match anything, including slashes.
-- a '`?`' matches any character except a slash (`/`).
-- a '`[`' introduces a character class, such as `[a-z]` or `[[:alpha:]]`.
-- in a wildcard pattern, a backslash can be used to escape a wildcard
-  character, but it is matched literally when no wildcards are present.  This
-  means that there is an extra level of backslash removal when a pattern
-  contains wildcard characters compared to a pattern that has none.  e.g. if
-  you add a wildcard to "`foo\bar`" (which matches the backslash) you would
-  need to use "`foo\\bar*`" to avoid the "`\b`" becoming just "b".
-- if the pattern contains a `/` (not counting a trailing /) or a "`**`", then it
-  is matched against the full pathname, including any leading directories.  If
-  the pattern doesn't contain a `/` or a "`**`", then it is matched only against
-  the final component of the filename. (Remember that the algorithm is applied
-  recursively so "full filename" can actually be any portion of a path from the
-  starting directory on down.)
-- a trailing "`dir_name/***`" will match both the directory (as if "dir_name/"
+When rules are being read from a file (using merge or dir-merge), empty lines
+are ignored, as are whole-line comments that start with a '`#`' (filename rules
+that contain a hash character are unaffected).
+
+Note also that the [`--filter`](#opt), [`--include`](#opt), and
+[`--exclude`](#opt) options take one rule/pattern each.  To add multiple ones,
+you can repeat the options on the command-line, use the merge-file syntax of
+the [`--filter`](#opt) option, or the [`--include-from`](#opt) /
+[`--exclude-from`](#opt) options.
+
+### PATTERN MATCHING RULES
+
+Most of the rules mentioned above take an argument that specifies what the rule
+should match.  If rsync is recursing through a directory hierarchy, keep in
+mind that each pattern is matched against the name of every directory in the
+descent path as rsync finds the filenames to send.
+
+The matching rules for the pattern argument take several forms:
+
+- If a pattern contains a `/` (not counting a trailing slash) or a "`**`"
+  (which can match a slash), then the pattern is matched against the full
+  pathname, including any leading directories within the transfer.  If the
+  pattern doesn't contain a (non-trailing) `/` or a "`**`", then it is matched
+  only against the final component of the filename or pathname. For example,
+  `foo` means that the final path component must be "foo" while `foo/bar` would
+  match the last 2 elements of the path (as long as both elements are within
+  the transfer).
+- A pattern that ends with a `/` only matches a directory, not a regular file,
+  symlink, or device.
+- A pattern that starts with a `/` is anchored to the start of the transfer
+  path instead of the end.  For example, `/foo/**` or `/foo/bar/**` match only
+  leading elements in the path.  If the rule is read from a per-directory
+  filter file, the transfer path being matched will begin at the level of the
+  filter file instead of the top of the transfer.  See the section on
+  [ANCHORING INCLUDE/EXCLUDE PATTERNS](#) for a full discussion of how to
+  specify a pattern that matches at the root of the transfer.
+
+Rsync chooses between doing a simple string match and wildcard matching by
+checking if the pattern contains one of these three wildcard characters: '`*`',
+'`?`', and '`[`' :
+
+- a '`?`' matches any single character except a slash (`/`).
+- a '`*`' matches zero or more non-slash characters.
+- a '`**`' matches zero or more characters, including slashes.
+- a '`[`' introduces a character class, such as `[a-z]` or `[[:alpha:]]`, that
+  must match one character.
+- a trailing `***` in the pattern is a shorthand that allows you to match a
+  directory and all its contents using a single rule.  For example, specifying
+  "`dir_name/***`" will match both the "dir_name" directory (as if "`dir_name/`"
   had been specified) and everything in the directory (as if "`dir_name/**`"
-  had been specified).  This behavior was added in version 2.6.7.
-
-Note that, when using the `--recursive` (`-r`) option (which is implied by
-`-a`), every subdir component of every path is visited left to right, with each
-directory having a chance for exclusion before its content.  In this way
-include/exclude patterns are applied recursively to the pathname of each node
-in the filesystem's tree (those inside the transfer).  The exclude patterns
-short-circuit the directory traversal stage as rsync finds the files to send.
-
-For instance, to include "`/foo/bar/baz`", the directories "`/foo`" and "`/foo/bar`"
-must not be excluded.  Excluding one of those parent directories prevents the
-examination of its content, cutting off rsync's recursion into those paths and
-rendering the include for "`/foo/bar/baz`" ineffectual (since rsync can't match
-something it never sees in the cut-off section of the directory hierarchy).
-
-The concept path exclusion is particularly important when using a trailing '`*`'
-rule.  For instance, this won't work:
-
->     + /some/path/this-file-will-not-be-found
->     + /file-is-included
->     - *
-
-This fails because the parent directory "some" is excluded by the '`*`' rule, so
-rsync never visits any of the files in the "some" or "some/path" directories.
-One solution is to ask for all directories in the hierarchy to be included by
-using a single rule: "`+ */`" (put it somewhere before the "`- *`" rule), and
-perhaps use the `--prune-empty-dirs` option.  Another solution is to add
-specific include rules for all the parent dirs that need to be visited.  For
-instance, this set of rules works fine:
-
->     + /some/
->     + /some/path/
->     + /some/path/this-file-is-found
->     + /file-also-included
->     - *
+  had been specified).
+- a backslash can be used to escape a wildcard character, but it is only
+  interpreted as an escape character if at least one wildcard character is
+  present in the match pattern. For instance, the pattern "`foo\bar`" matches
+  that single backslash literally, while the pattern "`foo\bar*`" would need to
+  be changed to "`foo\\bar*`" to avoid the "`\b`" becoming just "b".
 
 Here are some examples of exclude/include matching:
 
-- "`- *.o`" would exclude all names matching `*.o`
-- "`- /foo`" would exclude a file (or directory) named foo in the transfer-root
-  directory
-- "`- foo/`" would exclude any directory named foo
-- "`- /foo/*/bar`" would exclude any file named bar which is at two levels
-  below a directory named foo in the transfer-root directory
-- "`- /foo/**/bar`" would exclude any file named bar two or more levels below a
-  directory named foo in the transfer-root directory
-- The combination of "`+ */`", "`+ *.c`", and "`- *`" would include all
-  directories and C source files but nothing else (see also the
-  `--prune-empty-dirs` option)
-- The combination of "`+ foo/`", "`+ foo/bar.c`", and "`- *`" would include
-  only the foo directory and foo/bar.c (the foo directory must be explicitly
-  included or it would be excluded by the "`*`")
-
-The following modifiers are accepted after a "`+`" or "`-`":
+- Option `-f'- *.o'` would exclude all filenames ending with `.o`
+- Option `-f'- /foo'` would exclude a file (or directory) named foo in the
+  transfer-root directory
+- Option `-f'- foo/'` would exclude any directory named foo
+- Option `-f'- foo/*/bar'` would exclude any file/dir named bar which is at two
+  levels below a directory named foo (if foo is in the transfer)
+- Option `-f'- /foo/**/bar'` would exclude any file/dir named bar that was two
+  or more levels below a top-level directory named foo (note that /foo/bar is
+  **not** excluded by this)
+- Options `-f'+ */' -f'+ *.c' -f'- *'` would include all directories and .c
+  source files but nothing else
+- Options `-f'+ foo/' -f'+ foo/bar.c' -f'- *'` would include only the foo
+  directory and foo/bar.c (the foo directory must be explicitly included or it
+  would be excluded by the "`- *`")
+
+### FILTER RULE MODIFIERS
+
+The following modifiers are accepted after an include (+) or exclude (-) rule:
 
 - A `/` specifies that the include/exclude rule should be matched against the
-  absolute pathname of the current item.  For example, "`-/ /etc/passwd`" would
-  exclude the passwd file any time the transfer was sending files from the
-  "/etc" directory, and "-/ subdir/foo" would always exclude "foo" when it is
-  in a dir named "subdir", even if "foo" is at the root of the current
+  absolute pathname of the current item.  For example, `-f'-/ /etc/passwd'`
+  would exclude the passwd file any time the transfer was sending files from
+  the "/etc" directory, and "-/ subdir/foo" would always exclude "foo" when it
+  is in a dir named "subdir", even if "foo" is at the root of the current
   transfer.
 - A `!` specifies that the include/exclude should take effect if the pattern
-  fails to match.  For instance, "`-! */`" would exclude all non-directories.
+  fails to match.  For instance, `-f'-! */'` would exclude all non-directories.
 - A `C` is used to indicate that all the global CVS-exclude rules should be
   inserted as excludes in place of the "-C".  No arg should follow.
 - An `s` is used to indicate that the rule applies to the sending side.  When a
-  rule affects the sending side, it prevents files from being transferred.  The
-  default is for a rule to affect both sides unless `--delete-excluded` was
-  specified, in which case default rules become sender-side only.  See also the
-  hide (H) and show (S) rules, which are an alternate way to specify
-  sending-side includes/excludes.
+  rule affects the sending side, it affects what files are put into the
+  sender's file list.  The default is for a rule to affect both sides unless
+  [`--delete-excluded`](#opt) was specified, in which case default rules become
+  sender-side only.  See also the hide (H) and show (S) rules, which are an
+  alternate way to specify sending-side includes/excludes.
 - An `r` is used to indicate that the rule applies to the receiving side.  When
   a rule affects the receiving side, it prevents files from being deleted.  See
   the `s` modifier for more info.  See also the protect (P) and risk (R) rules,
   which are an alternate way to specify receiver-side includes/excludes.
 - A `p` indicates that a rule is perishable, meaning that it is ignored in
-  directories that are being deleted.  For instance, the `-C` option's default
-  rules that exclude things like "CVS" and "`*.o`" are marked as perishable,
-  and will not prevent a directory that was removed on the source from being
-  deleted on the destination.
+  directories that are being deleted.  For instance, the
+  [`--cvs-exclude`](#opt) (`-C`) option's default rules that exclude things
+  like "CVS" and "`*.o`" are marked as perishable, and will not prevent a
+  directory that was removed on the source from being deleted on the
+  destination.
 - An `x` indicates that a rule affects xattr names in xattr copy/delete
   operations (and is thus ignored when matching file/dir names).  If no
   xattr-matching rules are specified, a default xattr filtering rule is used
-  (see the `--xattrs` option).
+  (see the [`--xattrs`](#opt) option).
 
-# MERGE-FILE FILTER RULES
+### MERGE-FILE FILTER RULES
 
 You can merge whole files into your filter rules by specifying either a merge
-(.) or a dir-merge (:) filter rule (as introduced in the FILTER RULES section
-above).
+(.) or a dir-merge (:) filter rule (as introduced in the [FILTER RULES](#)
+section above).
 
 There are two kinds of merged files -- single-instance ('.') and per-directory
 (':').  A single-instance merge file is read one time, and its rules are
@@ -3653,7 +4204,7 @@ list of inherited rules.  These per-directory rule files must be created on the
 sending side because it is the sending side that is being scanned for the
 available files to transfer.  These rule files may also need to be transferred
 to the receiving side if you want them to affect what files don't get deleted
-(see PER-DIRECTORY RULES AND DELETE below).
+(see [PER-DIRECTORY RULES AND DELETE](#) below).
 
 Some examples:
 
@@ -3724,7 +4275,7 @@ transfer).
 If a per-directory merge-file is specified with a path that is a parent
 directory of the first transfer directory, rsync will scan all the parent dirs
 from that starting point to the transfer directory for the indicated
-per-directory file.  For instance, here is a common filter (see `-F`):
+per-directory file.  For instance, here is a common filter (see [`-F`](#opt)):
 
 >     --filter=': /.rsync-filter'
 
@@ -3748,11 +4299,11 @@ the ".rsync-filter" files in each directory that is a part of the transfer.
 If you want to include the contents of a ".cvsignore" in your patterns, you
 should use the rule ":C", which creates a dir-merge of the .cvsignore file, but
 parsed in a CVS-compatible manner.  You can use this to affect where the
-`--cvs-exclude` (`-C`) option's inclusion of the per-directory .cvsignore file
-gets placed into your rules by putting the ":C" wherever you like in your
-filter rules.  Without this, rsync would add the dir-merge rule for the
-.cvsignore file at the end of all your other rules (giving it a lower priority
-than your command-line rules).  For example:
+[`--cvs-exclude`](#opt) (`-C`) option's inclusion of the per-directory
+.cvsignore file gets placed into your rules by putting the ":C" wherever you
+like in your filter rules.  Without this, rsync would add the dir-merge rule
+for the .cvsignore file at the end of all your other rules (giving it a lower
+priority than your command-line rules).  For example:
 
 > ```
 > cat <<EOT | rsync -avC --filter='. -' a/ b
@@ -3772,15 +4323,15 @@ $HOME/.cvsignore, and the value of $CVSIGNORE) you should omit the `-C`
 command-line option and instead insert a "-C" rule into your filter rules; e.g.
 "`--filter=-C`".
 
-# LIST-CLEARING FILTER RULE
+### LIST-CLEARING FILTER RULE
 
 You can clear the current include/exclude list by using the "!" filter rule (as
-introduced in the FILTER RULES section above).  The "current" list is either
+introduced in the [FILTER RULES](#) section above).  The "current" list is either
 the global list of rules (if the rule is encountered while parsing the filter
 options) or a set of per-directory rules (which are inherited in their own
 sub-list, so a subdirectory can use this to clear out the parent's rules).
 
-# ANCHORING INCLUDE/EXCLUDE PATTERNS
+### ANCHORING INCLUDE/EXCLUDE PATTERNS
 
 As mentioned earlier, global include/exclude patterns are anchored at the "root
 of the transfer" (as opposed to per-directory patterns, which are anchored at
@@ -3790,10 +4341,10 @@ the tree starts to be duplicated in the destination directory.  This root
 governs where patterns that start with a / match.
 
 Because the matching is relative to the transfer-root, changing the trailing
-slash on a source path or changing your use of the `--relative` option affects
-the path you need to use in your matching (in addition to changing how much of
-the file tree is duplicated on the destination host).  The following examples
-demonstrate this.
+slash on a source path or changing your use of the [`--relative`](#opt) option
+affects the path you need to use in your matching (in addition to changing how
+much of the file tree is duplicated on the destination host).  The following
+examples demonstrate this.
 
 Let's say that we want to match two source files, one with an absolute
 path of "/home/me/foo/bar", and one with a path of "/home/you/bar/baz".
@@ -3831,11 +4382,11 @@ Here is how the various command choices differ for a 2-source transfer:
 > Target file: /dest/you/bar/baz
 > ```
 
-The easiest way to see what name you should filter is to just
-look at the output when using `--verbose` and put a / in front of the name
-(use the `--dry-run` option if you're not yet ready to copy any files).
+The easiest way to see what name you should filter is to just look at the
+output when using [`--verbose`](#opt) and put a / in front of the name (use the
+`--dry-run` option if you're not yet ready to copy any files).
 
-# PER-DIRECTORY RULES AND DELETE
+### PER-DIRECTORY RULES AND DELETE
 
 Without a delete option, per-directory rules are only relevant on the sending
 side, so you can feel free to exclude the merge files themselves without
@@ -3848,9 +4399,9 @@ for you, as seen in these two equivalent commands:
 However, if you want to do a delete on the receiving side AND you want some
 files to be excluded from being deleted, you'll need to be sure that the
 receiving side knows what files to exclude.  The easiest way is to include the
-per-directory merge files in the transfer and use `--delete-after`, because
-this ensures that the receiving side gets all the same exclude rules as the
-sending side before it tries to delete anything:
+per-directory merge files in the transfer and use [`--delete-after`](#opt),
+because this ensures that the receiving side gets all the same exclude rules as
+the sending side before it tries to delete anything:
 
 >     rsync -avF --delete-after host:src/dir /dest
 
@@ -3881,7 +4432,39 @@ one of these commands:
 > rsync -avFF --delete host:src/dir /dest
 > ```
 
-# BATCH MODE
+## TRANSFER RULES
+
+In addition to the [FILTER RULES](#) that affect the recursive file scans that
+generate the file list on the sending and (when deleting) receiving sides,
+there are transfer rules. These rules affect which files the generator decides
+need to be transferred without the side effects of an exclude filter rule.
+Transfer rules affect only files and never directories.
+
+Because a transfer rule does not affect what goes into the sender's (and
+receiver's) file list, it cannot have any effect on which files get deleted on
+the receiving side.  For example, if the file "foo" is present in the sender's
+list but its size is such that it is omitted due to a transfer rule, the
+receiving side does not request the file.  However, its presence in the file
+list means that a delete pass will not remove a matching file named "foo" on
+the receiving side.  On the other hand, a server-side exclude (hide) of the
+file "foo" leaves the file out of the server's file list, and absent a
+receiver-side exclude (protect) the receiver will remove a matching file named
+"foo" if deletions are requested.
+
+Given that the files are still in the sender's file list, the
+[`--prune-empty-dirs`](#opt) option will not judge a directory as being empty
+even if it contains only files that the transfer rules omitted.
+
+Similarly, a transfer rule does not have any extra effect on which files are
+deleted on the receiving side, so setting a maximum file size for the transfer
+does not prevent big files from being deleted.
+
+Examples of transfer rules include the default "quick check" algorithm (which
+compares size & modify time), the [`--update`](#opt) option, the
+[`--max-size`](#opt) option, the [`--ignore-non-existing`](#opt) option, and a
+few others.
+
+## BATCH MODE
 
 Batch mode can be used to apply the same set of updates to many identical
 systems.  Suppose one has a tree which is replicated on a number of hosts.  Now
@@ -3934,10 +4517,10 @@ flexibility you have in how you deal with batches:
   options when running the read-batch command on the remote host.
 - The second example reads the batch data via standard input so that the batch
   file doesn't need to be copied to the remote machine first.  This example
-  avoids the foo.sh script because it needed to use a modified `--read-batch`
-  option, but you could edit the script file if you wished to make use of it
-  (just be sure that no other option is trying to use standard input, such as
-  the "`--exclude-from=-`" option).
+  avoids the foo.sh script because it needed to use a modified
+  [`--read-batch`](#opt) option, but you could edit the script file if you
+  wished to make use of it (just be sure that no other option is trying to use
+  standard input, such as the [`--exclude-from=-`](#opt) option).
 
 Caveats:
 
@@ -3949,37 +4532,38 @@ already) or the file-update may be attempted and then, if the file fails to
 verify, the update discarded with an error.  This means that it should be safe
 to re-run a read-batch operation if the command got interrupted.  If you wish
 to force the batched-update to always be attempted regardless of the file's
-size and date, use the `-I` option (when reading the batch).  If an error
-occurs, the destination tree will probably be in a partially updated state.  In
-that case, rsync can be used in its regular (non-batch) mode of operation to
-fix up the destination tree.
+size and date, use the [`-I`](#opt) option (when reading the batch).  If an
+error occurs, the destination tree will probably be in a partially updated
+state.  In that case, rsync can be used in its regular (non-batch) mode of
+operation to fix up the destination tree.
 
 The rsync version used on all destinations must be at least as new as the one
 used to generate the batch file.  Rsync will die with an error if the protocol
 version in the batch file is too new for the batch-reading rsync to handle.
-See also the `--protocol` option for a way to have the creating rsync generate
-a batch file that an older rsync can understand.  (Note that batch files
-changed format in version 2.6.3, so mixing versions older than that with newer
-versions will not work.)
+See also the [`--protocol`](#opt) option for a way to have the creating rsync
+generate a batch file that an older rsync can understand.  (Note that batch
+files changed format in version 2.6.3, so mixing versions older than that with
+newer versions will not work.)
 
 When reading a batch file, rsync will force the value of certain options to
 match the data in the batch file if you didn't set them to the same as the
 batch-writing command.  Other options can (and should) be changed.  For
-instance `--write-batch` changes to `--read-batch`, `--files-from` is dropped,
-and the `--filter` / `--include` / `--exclude` options are not needed unless
-one of the `--delete` options is specified.
+instance [`--write-batch`](#opt) changes to [`--read-batch`](#opt),
+[`--files-from`](#opt) is dropped, and the [`--filter`](#opt) /
+[`--include`](#opt) / [`--exclude`](#opt) options are not needed unless one of
+the [`--delete`](#opt) options is specified.
 
 The code that creates the BATCH.sh file transforms any filter/include/exclude
 options into a single list that is appended as a "here" document to the shell
 script file.  An advanced user can use this to modify the exclude list if a
-change in what gets deleted by `--delete` is desired.  A normal user can ignore
-this detail and just use the shell script as an easy way to run the appropriate
-`--read-batch` command for the batched data.
+change in what gets deleted by [`--delete`](#opt) is desired.  A normal user
+can ignore this detail and just use the shell script as an easy way to run the
+appropriate [`--read-batch`](#opt) command for the batched data.
 
 The original batch mode in rsync was based on "rsync+", but the latest
 version uses a new implementation.
 
-# SYMBOLIC LINKS
+## SYMBOLIC LINKS
 
 Three basic behaviors are possible when rsync encounters a symbolic
 link in the source directory.
@@ -3987,40 +4571,53 @@ link in the source directory.
 By default, symbolic links are not transferred at all.  A message "skipping
 non-regular" file is emitted for any symlinks that exist.
 
-If `--links` is specified, then symlinks are recreated with the same target on
-the destination.  Note that `--archive` implies `--links`.
+If [`--links`](#opt) is specified, then symlinks are added to the transfer
+(instead of being noisily ignored), and the default handling is to recreate
+them with the same target on the destination.  Note that [`--archive`](#opt)
+implies [`--links`](#opt).
 
-If `--copy-links` is specified, then symlinks are "collapsed" by
+If [`--copy-links`](#opt) is specified, then symlinks are "collapsed" by
 copying their referent, rather than the symlink.
 
 Rsync can also distinguish "safe" and "unsafe" symbolic links.  An example
 where this might be used is a web site mirror that wishes to ensure that the
 rsync module that is copied does not include symbolic links to `/etc/passwd` in
-the public section of the site.  Using `--copy-unsafe-links` will cause any
-links to be copied as the file they point to on the destination.  Using
-`--safe-links` will cause unsafe links to be omitted altogether. (Note that you
-must specify `--links` for `--safe-links` to have any effect.)
+the public section of the site.  Using [`--copy-unsafe-links`](#opt) will cause
+any links to be copied as the file they point to on the destination.  Using
+[`--safe-links`](#opt) will cause unsafe links to be omitted by the receiver.
+(Note that you must specify or imply [`--links`](#opt) for
+[`--safe-links`](#opt) to have any effect.)
 
-Symbolic links are considered unsafe if they are absolute symlinks
-(start with `/`), empty, or if they contain enough ".."
-components to ascend from the directory being copied.
+Symbolic links are considered unsafe if they are absolute symlinks (start with
+`/`), empty, or if they contain enough ".." components to ascend from the top
+of the transfer.
 
 Here's a summary of how the symlink options are interpreted.  The list is in
 order of precedence, so if your combination of options isn't mentioned, use the
 first line that is a complete subset of your options:
 
-0.  `--copy-links` Turn all symlinks into normal files (leaving no symlinks for
-    any other options to affect).
-0.  `--links --copy-unsafe-links` Turn all unsafe symlinks into files and
-    duplicate all safe symlinks.
-0.  `--copy-unsafe-links` Turn all unsafe symlinks into files, noisily skip all
-    safe symlinks.
-0.  `--links --safe-links` Duplicate safe symlinks and skip unsafe ones.
-0.  `--links` Duplicate all symlinks.
+0.  `--copy-links` Turn all symlinks into normal files and directories
+    (leaving no symlinks in the transfer for any other options to affect).
+0.  `--copy-dirlinks` Turn just symlinks to directories into real
+    directories, leaving all other symlinks to be handled as described below.
+0.  `--links --copy-unsafe-links` Turn all unsafe symlinks
+    into files and create all safe symlinks.
+0.  `--copy-unsafe-links` Turn all unsafe symlinks into files, noisily
+    skip all safe symlinks.
+0.  `--links --safe-links` The receiver skips creating
+    unsafe symlinks found in the transfer and creates the safe ones.
+0.  `--links` Create all symlinks.
+
+For the effect of [`--munge-links`](#opt), see the discussion in that option's
+section.
 
-# DIAGNOSTICS
+Note that the [`--keep-dirlinks`](#opt) option does not effect symlinks in the
+transfer but instead affects how rsync treats a symlink to a directory that
+already exists on the receiving side.  See that option's section for a warning.
 
-rsync occasionally produces error messages that may seem a little cryptic.  The
+## DIAGNOSTICS
+
+Rsync occasionally produces error messages that may seem a little cryptic.  The
 one that seems to cause the most confusion is "protocol version mismatch -- is
 your shell clean?".
 
@@ -4041,108 +4638,166 @@ If you are having trouble debugging filter patterns, then try specifying the
 `-vv` option.  At this level of verbosity rsync will show why each individual
 file is included or excluded.
 
-# EXIT VALUES
-
-0.  **0** Success
-0.  **1** Syntax or usage error
-0.  **2** Protocol incompatibility
-0.  **3** Errors selecting input/output files, dirs
-0.  **4** Requested action not supported: an attempt was made to manipulate
-    64-bit files on a platform that cannot support them; or an option was
-    specified that is supported by the client and not by the server.
-0.  **5** Error starting client-server protocol
-0.  **6** Daemon unable to append to log-file
-0.  **10** Error in socket I/O
-0.  **11** Error in file I/O
-0.  **12** Error in rsync protocol data stream
-0.  **13** Errors with program diagnostics
-0.  **14** Error in IPC code
-0.  **20** Received SIGUSR1 or SIGINT
-0.  **21** Some error returned by **waitpid()**
-0.  **22** Error allocating core memory buffers
-0.  **23** Partial transfer due to error
-0.  **24** Partial transfer due to vanished source files
-0.  **25** The --max-delete limit stopped deletions
-0.  **30** Timeout in data send/receive
-0.  **35** Timeout waiting for daemon connection
-
-# ENVIRONMENT VARIABLES
+## EXIT VALUES
+
+- **0** - Success
+- **1** - Syntax or usage error
+- **2** - Protocol incompatibility
+- **3** - Errors selecting input/output files, dirs
+- **4** - Requested action not supported. Either:
+  - an attempt was made to manipulate 64-bit files on a platform that cannot support them
+  - an option was specified that is supported by the client and not by the server
+- **5** - Error starting client-server protocol
+- **6** - Daemon unable to append to log-file
+- **10** - Error in socket I/O
+- **11** - Error in file I/O
+- **12** - Error in rsync protocol data stream
+- **13** - Errors with program diagnostics
+- **14** - Error in IPC code
+- **20** - Received SIGUSR1 or SIGINT
+- **21** - Some error returned by **waitpid()**
+- **22** - Error allocating core memory buffers
+- **23** - Partial transfer due to error
+- **24** - Partial transfer due to vanished source files
+- **25** - The --max-delete limit stopped deletions
+- **30** - Timeout in data send/receive
+- **35** - Timeout waiting for daemon connection
+
+## ENVIRONMENT VARIABLES
 
 0.  `CVSIGNORE`
 
     The CVSIGNORE environment variable supplements any ignore patterns in
-    .cvsignore files.  See the `--cvs-exclude` option for more details.
+    .cvsignore files.  See the [`--cvs-exclude`](#opt) option for more details.
 
 0.  `RSYNC_ICONV`
 
-    Specify a default `--iconv` setting using this environment variable. (First
-    supported in 3.0.0.)
+    Specify a default [`--iconv`](#opt) setting using this environment
+    variable. First supported in 3.0.0.
+
+0.  `RSYNC_OLD_ARGS`
+
+    Specify a "1" if you want the [`--old-args`](#opt) option to be enabled by
+    default, a "2" (or more) if you want it to be enabled in the
+    repeated-option state, or a "0" to make sure that it is disabled by
+    default. When this environment variable is set to a non-zero value, it
+    supersedes the [`RSYNC_PROTECT_ARGS`](#) variable.
+
+    This variable is ignored if [`--old-args`](#opt), `--no-old-args`, or
+    [`--secluded-args`](#opt) is specified on the command line.
+
+    First supported in 3.2.4.
 
 0.  `RSYNC_PROTECT_ARGS`
 
-    Specify a non-zero numeric value if you want the `--protect-args` option to
-    be enabled by default, or a zero value to make sure that it is disabled by
-    default. (First supported in 3.1.0.)
+    Specify a non-zero numeric value if you want the [`--secluded-args`](#opt)
+    option to be enabled by default, or a zero value to make sure that it is
+    disabled by default.
+
+    This variable is ignored if [`--secluded-args`](#opt), `--no-secluded-args`,
+    or [`--old-args`](#opt) is specified on the command line.
+
+    First supported in 3.1.0.  Starting in 3.2.4, this variable is ignored if
+    [`RSYNC_OLD_ARGS`](#) is set to a non-zero value.
 
 0.  `RSYNC_RSH`
 
-    The RSYNC_RSH environment variable allows you to override the default shell
-    used as the transport for rsync.  Command line options are permitted after
-    the command name, just as in the `-e` option.
+    This environment variable allows you to override the default shell used as
+    the transport for rsync.  Command line options are permitted after the
+    command name, just as in the [`--rsh`](#opt) (`-e`) option.
 
 0.  `RSYNC_PROXY`
 
-    The RSYNC_PROXY environment variable allows you to redirect your rsync
-    client to use a web proxy when connecting to a rsync daemon.  You should
-    set RSYNC_PROXY to a hostname:port pair.
+    This environment variable allows you to redirect your rsync
+    client to use a web proxy when connecting to an rsync daemon.  You should
+    set `RSYNC_PROXY` to a hostname:port pair.
 
 0.  `RSYNC_PASSWORD`
 
-    Setting RSYNC_PASSWORD to the required password allows you to run
-    authenticated rsync connections to an rsync daemon without user
-    intervention.  Note that this does not supply a password to a remote shell
-    transport such as ssh; to learn how to do that, consult the remote shell's
-    documentation.
+    This environment variable allows you to set the password for an rsync
+    **daemon** connection, which avoids the password prompt.  Note that this
+    does **not** supply a password to a remote shell transport such as ssh
+    (consult its documentation for how to do that).
 
 0.  `USER` or `LOGNAME`
 
     The USER or LOGNAME environment variables are used to determine the default
     username sent to an rsync daemon.  If neither is set, the username defaults
-    to "nobody".
+    to "nobody".  If both are set, `USER` takes precedence.
+
+0. `RSYNC_PARTIAL_DIR`
+
+    This environment variable specifies the directory to use for a
+    [`--partial`](#opt) transfer without implying that partial transfers be
+    enabled.  See the [`--partial-dir`](#opt) option for full details.
+
+0. `RSYNC_COMPRESS_LIST`
+
+    This environment variable allows you to customize the negotiation of the
+    compression algorithm by specifying an alternate order or a reduced list of
+    names.  Use the command `rsync --version` to see the available compression
+    names.  See the [`--compress`](#opt) option for full details.
+
+0. `RSYNC_CHECKSUM_LIST`
+
+    This environment variable allows you to customize the negotiation of the
+    checksum algorithm by specifying an alternate order or a reduced list of
+    names.  Use the command `rsync --version` to see the available checksum
+    names.  See the [`--checksum-choice`](#opt) option for full details.
+
+0. `RSYNC_MAX_ALLOC`
+
+    This environment variable sets an allocation maximum as if you had used the
+    [`--max-alloc`](#opt) option.
+
+0. `RSYNC_PORT`
+
+    This environment variable is not read by rsync, but is instead set in
+    its sub-environment when rsync is running the remote shell in combination
+    with a daemon connection.  This allows a script such as
+    [`rsync-ssl`](rsync-ssl.1) to be able to know the port number that the user
+    specified on the command line.
 
 0.  `HOME`
 
-    The HOME environment variable is used to find the user's default .cvsignore
+    This environment variable is used to find the user's default .cvsignore
     file.
 
-# FILES
+0. `RSYNC_CONNECT_PROG`
 
-/etc/rsyncd.conf or rsyncd.conf
+    This environment variable is mainly used in debug setups to set the program
+    to use when making a daemon connection.  See [CONNECTING TO AN RSYNC
+    DAEMON](#) for full details.
 
-# SEE ALSO
+0. `RSYNC_SHELL`
 
-**rsync-ssl**(1), **rsyncd.conf**(5)
+    This environment variable is mainly used in debug setups to set the program
+    to use to run the program specified by [`RSYNC_CONNECT_PROG`](#).  See
+    [CONNECTING TO AN RSYNC DAEMON](#) for full details.
 
-# BUGS
+## FILES
 
-times are transferred as \*nix time_t values
+/etc/rsyncd.conf or rsyncd.conf
 
-When transferring to FAT filesystems rsync may re-sync
-unmodified files.
-See the comments on the `--modify-window` option.
+## SEE ALSO
 
-file permissions, devices, etc. are transferred as native numerical
-values
+[**rsync-ssl**(1)](rsync-ssl.1), [**rsyncd.conf**(5)](rsyncd.conf.5), [**rrsync**(1)](rrsync.1)
 
-see also the comments on the `--delete` option
+## BUGS
+
+- Times are transferred as \*nix time_t values.
+- When transferring to FAT filesystems rsync may re-sync unmodified files.  See
+  the comments on the [`--modify-window`](#opt) option.
+- File permissions, devices, etc. are transferred as native numerical values.
+- See also the comments on the [`--delete`](#opt) option.
 
 Please report bugs! See the web site at <https://rsync.samba.org/>.
 
-# VERSION
+## VERSION
 
-This man page is current for version @VERSION@ of rsync.
+This manpage is current for version @VERSION@ of rsync.
 
-# INTERNAL OPTIONS
+## INTERNAL OPTIONS
 
 The options `--server` and `--sender` are used internally by rsync, and should
 never be typed by a user under normal circumstances.  Some awareness of these
@@ -4151,13 +4806,16 @@ that can only run an rsync command.  For instance, the support directory of the
 rsync distribution has an example script named rrsync (for restricted rsync)
 that can be used with a restricted ssh login.
 
-# CREDITS
+## CREDITS
+
+Rsync is distributed under the GNU General Public License.  See the file
+[COPYING](COPYING) for details.
 
-rsync is distributed under the GNU General Public License.  See the file
-COPYING for details.
+An rsync web site is available at <https://rsync.samba.org/>.  The site
+includes an FAQ-O-Matic which may cover questions unanswered by this manual
+page.
 
-A web site is available at <https://rsync.samba.org/>.  The site includes an
-FAQ-O-Matic which may cover questions unanswered by this manual page.
+The rsync github project is <https://github.com/WayneD/rsync>.
 
 We would be delighted to hear from you if you like this program.  Please
 contact the mailing-list at <rsync@lists.samba.org>.
@@ -4165,7 +4823,7 @@ contact the mailing-list at <rsync@lists.samba.org>.
 This program uses the excellent zlib compression library written by Jean-loup
 Gailly and Mark Adler.
 
-# THANKS
+## THANKS
 
 Special thanks go out to: John Van Essen, Matt McCutchen, Wesley W. Terpstra,
 David Dykstra, Jos Backus, Sebastian Krahmer, Martin Pool, and our
@@ -4174,9 +4832,9 @@ gone-but-not-forgotten compadre, J.W. Schultz.
 Thanks also to Richard Brent, Brendan Mackay, Bill Waite, Stephen Rothwell and
 David Bell.  I've probably missed some people, my apologies if I have.
 
-# AUTHOR
+## AUTHOR
 
-rsync was originally written by Andrew Tridgell and Paul Mackerras.  Many
+Rsync was originally written by Andrew Tridgell and Paul Mackerras.  Many
 people have later contributed to it. It is currently maintained by Wayne
 Davison.
 
diff --git a/rsync.c b/rsync.c
index e7f1f96..cd288f5 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -32,7 +32,9 @@ extern int preserve_acls;
 extern int preserve_xattrs;
 extern int preserve_perms;
 extern int preserve_executability;
-extern int preserve_times;
+extern int preserve_mtimes;
+extern int omit_dir_times;
+extern int omit_link_times;
 extern int am_root;
 extern int am_server;
 extern int am_daemon;
@@ -63,8 +65,7 @@ extern char *iconv_opt;
 #define UPDATED_ATIME (1<<3)
 #define UPDATED_ACLS  (1<<4)
 #define UPDATED_MODE  (1<<5)
-
-#define UPDATED_TIMES (UPDATED_MTIME|UPDATED_ATIME)
+#define UPDATED_CRTIME (1<<6)
 
 #ifdef ICONV_CONST
 iconv_t ic_chck = (iconv_t)-1;
@@ -576,17 +577,20 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                set_xattr(fname, file, fnamecmp, sxp);
 #endif
 
-       if (!preserve_times
-        || (!(preserve_times & PRESERVE_DIR_TIMES) && S_ISDIR(sxp->st.st_mode))
-        || (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(sxp->st.st_mode)))
-               flags |= ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME;
-       else if (sxp != &sx2)
-               memcpy(&sx2.st, &sxp->st, sizeof (sx2.st));
-       if (!atimes_ndx || S_ISDIR(sxp->st.st_mode))
-               flags |= ATTRS_SKIP_ATIME;
-       /* Don't set the creation date on the root folder of an HFS+ volume. */
-       if (sxp->st.st_ino == 2 && S_ISDIR(sxp->st.st_mode))
-               flags |= ATTRS_SKIP_CRTIME;
+       if ((omit_dir_times && S_ISDIR(sxp->st.st_mode))
+        || (omit_link_times && S_ISLNK(sxp->st.st_mode)))
+               flags |= ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME | ATTRS_SKIP_CRTIME;
+       else {
+               if (!preserve_mtimes)
+                       flags |= ATTRS_SKIP_MTIME;
+               if (!atimes_ndx || S_ISDIR(sxp->st.st_mode))
+                       flags |= ATTRS_SKIP_ATIME;
+               /* Don't set the creation date on the root folder of an HFS+ volume. */
+               if (sxp->st.st_ino == 2 && S_ISDIR(sxp->st.st_mode))
+                       flags |= ATTRS_SKIP_CRTIME;
+       }
+       if (sxp != &sx2)
+               memcpy(&sx2.st, &sxp->st, sizeof sx2.st);
        if (!(flags & ATTRS_SKIP_MTIME) && !same_mtime(file, &sxp->st, flags & ATTRS_ACCURATE_TIME)) {
                sx2.st.st_mtime = file->modtime;
 #ifdef ST_MTIME_NSEC
@@ -604,33 +608,41 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                        updated |= UPDATED_ATIME;
                }
        }
-       if (updated & UPDATED_TIMES) {
+#ifdef SUPPORT_CRTIMES
+       if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) {
+               time_t file_crtime = F_CRTIME(file);
+               if (sxp->crtime == 0)
+                       sxp->crtime = get_create_time(fname, &sxp->st);
+               if (!same_time(sxp->crtime, 0L, file_crtime, 0L)) {
+                       if (
+#ifdef HAVE_GETATTRLIST
+                            do_setattrlist_crtime(fname, file_crtime) == 0
+#elif defined __CYGWIN__
+                            do_SetFileTime(fname, file_crtime) == 0
+#else
+#error Unknown crtimes implementation
+#endif
+                       )
+                               updated |= UPDATED_CRTIME;
+               }
+       }
+#endif
+       if (updated & (UPDATED_MTIME|UPDATED_ATIME)) {
                int ret = set_times(fname, &sx2.st);
                if (ret < 0) {
-                       rsyserr(FERROR_XFER, errno, "failed to set times on %s",
-                               full_fname(fname));
+                       rsyserr(FERROR_XFER, errno, "failed to set times on %s", full_fname(fname));
                        goto cleanup;
                }
                if (ret > 0) { /* ret == 1 if symlink could not be set */
-                       updated &= ~UPDATED_TIMES;
+                       updated &= ~(UPDATED_MTIME|UPDATED_ATIME);
                        file->flags |= FLAG_TIME_FAILED;
                }
        }
-#ifdef SUPPORT_CRTIMES
-       if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) {
-               time_t file_crtime = F_CRTIME(file);
-               if (sxp->crtime == 0)
-                       sxp->crtime = get_create_time(fname);
-               if (!same_time(sxp->crtime, 0L, file_crtime, 0L)
-                && set_create_time(fname, file_crtime) == 0)
-                       updated = 1;
-       }
-#endif
 
 #ifdef SUPPORT_ACLS
        /* It's OK to call set_acl() now, even for a dir, as the generator
         * will enable owner-writability using chmod, if necessary.
-        * 
+        *
         * If set_acl() changes permission bits in the process of setting
         * an access ACL, it changes sxp->st.st_mode so we know whether we
         * need to chmod(). */
diff --git a/rsync.h b/rsync.h
index 0f5304e..d3709fe 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -2,7 +2,7 @@
  * Copyright (C) 1996, 2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
 #define BITS_EQUAL(b1,b2,mask) (((unsigned)(b1) & (unsigned)(mask)) \
                             == ((unsigned)(b2) & (unsigned)(mask)))
 
-/* update this if you make incompatible changes */
+/* Update this if you make incompatible changes and ALSO update the
+ * SUBPROTOCOL_VERSION if it is not a final (official) release. */
 #define PROTOCOL_VERSION 31
 
-/* This is used when working on a new protocol version in CVS, and should
- * be a new non-zero value for each CVS change that affects the protocol.
- * It must ALWAYS be 0 when the protocol goes final (and NEVER before)! */
+/* This is used when working on a new protocol version or for any unofficial
+ * protocol tweaks.  It should be a non-zero value for each pre-release repo
+ * change that affects the protocol. The official pre-release versions should
+ * start with 1 (after incrementing the PROTOCOL_VERSION) and go up by 1 for
+ * each new protocol change.  For unofficial changes, pick a fairly large
+ * random number that will hopefully not collide with anyone else's unofficial
+ * protocol.  It must ALWAYS be 0 when the protocol goes final (and official)
+ * and NEVER before!  When rsync negotiates a protocol match, it will only
+ * allow the newest protocol to be used if the SUBPROTOCOL_VERSION matches.
+ * All older protocol versions MUST be compatible with the final, official
+ * release of the protocol, so don't tweak the code to change the protocol
+ * behavior for an older protocol version. */
 #define SUBPROTOCOL_VERSION 0
 
 /* We refuse to interoperate with versions that are not in this range.
@@ -267,6 +277,10 @@ enum msgcode {
        MSG_NO_SEND=102,/* sender failed to open a file we wanted */
 };
 
+enum filetype {
+       FT_UNSUPPORTED, FT_REG, FT_DIR, FT_SYMLINK, FT_SPECIAL, FT_DEVICE
+};
+
 #define NDX_DONE -1
 #define NDX_FLIST_EOF -2
 #define NDX_DEL_STATS -3
@@ -300,7 +314,6 @@ enum delret {
 #include "errcode.h"
 
 #include "config.h"
-#include "version.h"
 
 /* The default RSYNC_RSH is always set in config.h. */
 
@@ -325,6 +338,9 @@ enum delret {
 # endif
 # include <string.h>
 #endif
+#ifdef HAVE_BSD_STRING_H
+# include <bsd/string.h>
+#endif
 #ifdef HAVE_STRINGS_H
 # include <strings.h>
 #endif
@@ -350,16 +366,10 @@ enum delret {
 #include <sys/socket.h>
 #endif
 
-#ifdef TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#else
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
-#else
-#include <time.h>
-#endif
 #endif
+#include <time.h>
 
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
@@ -478,7 +488,6 @@ enum delret {
 #ifndef __TANDEM
 #define MAKEDEV(devmajor,devminor) makedev(devmajor,devminor)
 #else
-# include <sys/stat.h>
 # define major DEV_TO_MAJOR
 # define minor DEV_TO_MINOR
 # define MAKEDEV MAJORMINOR_TO_DEV
@@ -570,11 +579,11 @@ typedef unsigned int size_t;
 #endif
 #endif
 
-#ifndef __APPLE__ /* Do we need a configure check for this? */
+#if !defined __APPLE__ || defined HAVE_GETATTRLIST
 #define SUPPORT_ATIMES 1
 #endif
 
-#ifdef HAVE_GETATTRLIST
+#if defined HAVE_GETATTRLIST || defined __CYGWIN__
 #define SUPPORT_CRTIMES 1
 #endif
 
@@ -766,6 +775,11 @@ struct ht_int64_node {
 
 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
 #define USE_FLEXIBLE_ARRAY 1
+#define SIZE_T_FMT_MOD "z" /* printf supports %zd */
+#define SIZE_T_FMT_CAST size_t
+#else
+#define SIZE_T_FMT_MOD "l" /* printf supports %ld */
+#define SIZE_T_FMT_CAST long
 #endif
 
 union file_extras {
@@ -806,6 +820,7 @@ extern int uid_ndx;
 extern int gid_ndx;
 extern int acls_ndx;
 extern int xattrs_ndx;
+extern int file_sum_extra_cnt;
 
 #ifdef USE_FLEXIBLE_ARRAY
 #define FILE_STRUCT_LEN (sizeof (struct file_struct))
@@ -816,7 +831,7 @@ extern int xattrs_ndx;
 #define DEV_EXTRA_CNT 2
 #define DIRNODE_EXTRA_CNT 3
 #define EXTRA64_CNT ((sizeof (union file_extras64) + EXTRA_LEN - 1) / EXTRA_LEN)
-#define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN)
+#define SUM_EXTRA_CNT file_sum_extra_cnt
 
 #define REQ_EXTRA(f,ndx) ((union file_extras*)(f) - (ndx))
 #define OPT_EXTRA(f,bump) ((union file_extras*)(f) - file_extra_cnt - 1 - (bump))
@@ -904,8 +919,9 @@ extern int xattrs_ndx;
  * Start the flist array at FLIST_START entries and grow it
  * by doubling until FLIST_LINEAR then grow by FLIST_LINEAR
  */
-#define FLIST_START    (32 * 1024)
-#define FLIST_LINEAR   (FLIST_START * 512)
+#define FLIST_START            (32)
+#define FLIST_START_LARGE      (32 * 1024)
+#define FLIST_LINEAR           (FLIST_START_LARGE * 512)
 
 /*
  * Extent size for allocation pools: A minimum size of 128KB
@@ -1002,6 +1018,7 @@ typedef struct filter_struct {
                int slash_cnt;
                struct filter_list_struct *mergelist;
        } u;
+       uchar elide;
 } filter_rule;
 
 typedef struct filter_list_struct {
@@ -1141,19 +1158,23 @@ typedef struct {
 #define NSTR_COMPRESS 1
 
 struct name_num_item {
-       int num;
-       const char *name, *main_name;
+       int num, flags;
+       const char *name;
+       struct name_num_item *main_nni;
 };
 
 struct name_num_obj {
        const char *type;
-       const char *negotiated_name;
+       struct name_num_item *negotiated_nni;
        uchar *saw;
        int saw_len;
-       int negotiated_num;
-       struct name_num_item list[8]; /* A big-enough len (we'll get a compile error if it is ever too small) */
+       struct name_num_item *list;
 };
 
+#ifdef EXTERNAL_ZLIB
+#define read_buf read_buf_
+#endif
+
 #ifndef __cplusplus
 #include "proto.h"
 #endif
@@ -1312,10 +1333,6 @@ extern int errno;
 #define IS_SPECIAL(mode) (S_ISSOCK(mode) || S_ISFIFO(mode))
 #define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode))
 
-#define PRESERVE_FILE_TIMES    (1<<0)
-#define PRESERVE_DIR_TIMES     (1<<1)
-#define PRESERVE_LINK_TIMES    (1<<2)
-
 /* Initial mask on permissions given to temporary files.  Mask off setuid
      bits and group access because of potential race-condition security
      holes, and mask other access because mode 707 is bizarre */
@@ -1405,7 +1422,8 @@ extern short info_levels[], debug_levels[];
 #define INFO_MISC (INFO_FLIST+1)
 #define INFO_MOUNT (INFO_MISC+1)
 #define INFO_NAME (INFO_MOUNT+1)
-#define INFO_PROGRESS (INFO_NAME+1)
+#define INFO_NONREG (INFO_NAME+1)
+#define INFO_PROGRESS (INFO_NONREG+1)
 #define INFO_REMOVE (INFO_PROGRESS+1)
 #define INFO_SKIP (INFO_REMOVE+1)
 #define INFO_STATS (INFO_SKIP+1)
@@ -1460,3 +1478,9 @@ const char *get_panic_action(void);
     fprintf(stderr, "%s in %s at line %d\n", msg, __FILE__, __LINE__); \
     exit_cleanup(RERR_UNSUPPORTED); \
 } while (0)
+
+#ifdef HAVE_MALLINFO2
+#define MEM_ALLOC_INFO mallinfo2
+#elif defined HAVE_MALLINFO
+#define MEM_ALLOC_INFO mallinfo
+#endif
index e20b3c6..249edd4 100644 (file)
@@ -1,4 +1,5 @@
-.TH "rsyncd.conf" "5" "06 Aug 2020" "rsyncd.conf 3.2.3" "User Commands"
+.TH "rsyncd.conf" "5" "20 Oct 2022" "rsyncd.conf from rsync 3.2.7" "User Commands"
+.\" prefix=/usr
 .P
 .SH "NAME"
 .P
@@ -8,6 +9,9 @@ rsyncd.conf \- configuration file for rsync in daemon mode
 .P
 rsyncd.conf
 .P
+The online version of this manpage (that includes cross-linking of topics)
+is available at https://download.samba.org/pub/rsync/rsyncd.conf.5.
+.P
 .SH "DESCRIPTION"
 .P
 The rsyncd.conf file is the runtime configuration file for rsync when run as an
@@ -44,8 +48,7 @@ Case is not significant in boolean values, but is preserved in string values.
 .P
 .SH "LAUNCHING THE RSYNC DAEMON"
 .P
-The rsync daemon is launched by specifying the \fB\-\-daemon\fP option to
-rsync.
+The rsync daemon is launched by specifying the \fB\-\-daemon\fP option to rsync.
 .P
 The daemon must run with root privileges if you wish to use chroot, to bind to
 a port numbered under 1024 (as is the default 873), or to set file ownership.
@@ -103,9 +106,9 @@ string in a path could result in a very unsafe path).  The safest way to insert
 a literal % into a value is to use %%.
 .P
 .IP "\fBmotd\ file\fP"
-This parameter allows you to specify a "message of the day" to display to
-clients on each connect. This usually contains site information and any
-legal notices. The default is no motd file.  This can be overridden by the
+This parameter allows you to specify a "message of the day" (MOTD) to display
+to clients on each connect. This usually contains site information and any
+legal notices. The default is no MOTD file.  This can be overridden by the
 \fB\-\-dparam=motdfile=FILE\fP command-line option when starting the daemon.
 .IP "\fBpid\ file\fP"
 This parameter tells the rsync daemon to write its process ID to that file.
@@ -125,7 +128,7 @@ inetd, and is superseded by the \fB\-\-address\fP command-line option.
 .IP "\fBsocket\ options\fP"
 This parameter can provide endless fun for people who like to tune their
 systems to the utmost degree. You can set all sorts of socket options which
-may make transfers faster (or slower!). Read the man page for the
+may make transfers faster (or slower!). Read the manpage for the
 \fBsetsockopt()\fP system call for details on some of the options you may be
 able to set. By default no special socket options are set.  These settings
 can also be specified via the \fB\-\-sockopts\fP command-line option.
@@ -156,6 +159,20 @@ This parameter specifies the directory in the daemon's filesystem to make
 available in this module.  You must specify this parameter for each module
 in \fBrsyncd.conf\fP.
 .IP
+If the value contains a "/./" element then the path will be divided at that
+point into a chroot dir and an inner-chroot subdir.  If \fBuse\ chroot\fP
+is set to false, though, the extraneous dot dir is just cleaned out of the
+path.  An example of this idiom is:
+.RS 4
+.IP
+.nf
+path = /var/rsync/./module1
+.fi
+.RE
+.IP
+This will (when chrooting) chroot to "/var/rsync" and set the inside-chroot
+path to "/module1".
+.IP
 You may base the path's value off of an environment variable by surrounding
 the variable name with percent signs.  You can even reference a variable
 that is set by rsync when the user connects.  For example, this would use
@@ -181,29 +198,47 @@ follow symbolic links that are either absolute or outside of the new root
 path, and of complicating the preservation of users and groups by name (see
 below).
 .IP
-As an additional safety feature, you can specify a dot-dir in the module's
-"path" to indicate the point where the chroot should occur.  This allows
-rsync to run in a chroot with a non-"/" path for the top of the transfer
-hierarchy.  Doing this guards against unintended library loading (since
-those absolute paths will not be inside the transfer hierarchy unless you
-have used an unwise pathname), and lets you setup libraries for the chroot
-that are outside of the transfer.  For example, specifying
-"/var/rsync/./module1" will chroot to the "/var/rsync" directory and set
-the inside-chroot path to "/module1".  If you had omitted the dot-dir, the
-chroot would have used the whole path, and the inside-chroot path would
-have been "/".
-.IP
-When both "use chroot" and "daemon chroot" are false, OR the inside-chroot
-path of "use chroot" is not "/", rsync will: (1) munge symlinks by default
-for security reasons (see "munge symlinks" for a way to turn this off, but
-only if you trust your users), (2) substitute leading slashes in absolute
-paths with the module's path (so that options such as \fB\-\-backup-dir\fP,
-\fB\-\-compare-dest\fP, etc. interpret an absolute path as rooted in the module's
-"path" dir), and (3) trim ".." path elements from args if rsync believes
-they would escape the module hierarchy.  The default for "use chroot" is
-true, and is the safer choice (especially if the module is not read-only).
-.IP
-When this parameter is enabled \fIand\fP the "name converter" parameter is
+If \fBuse\ chroot\fP is not set, it defaults to trying to enable a chroot but
+allows the daemon to continue (after logging a warning) if it fails. The
+one exception to this is when a module's \fBpath\fP has a "/./" chroot
+divider in it\ \-\- this causes an unset value to be treated as true for that
+module.
+.IP
+Prior to rsync 3.2.7, the default value was "true".  The new "unset"
+default makes it easier to setup an rsync daemon as a non-root user or to
+run a daemon on a system where chroot fails.  Explicitly setting the value
+to "true" in rsyncd.conf will always require the chroot to succeed.
+.IP
+It is also possible to specify a dot-dir in the module's "path" to
+indicate that you want to chdir to the earlier part of the path and then
+serve files from inside the latter part of the path (with sanitizing and
+default symlink munging).  This can be useful if you need some library dirs
+inside the chroot (typically for uid & gid lookups) but don't want to put
+the lib dir into the top of the served path (even though they can be hidden
+with an \fBexclude\fP directive).  However, a better choice for a modern
+rsync setup is to use a \fBname\ converter\fP" and try to avoid inner lib
+dirs altogether.  See also the \fBdaemon\ chroot\fP parameter, which causes
+rsync to chroot into its own chroot area before doing any path-related
+chrooting.
+.IP
+If the daemon is serving the "/" dir (either directly or due to being
+chrooted to the module's path), rsync does not do any path sanitizing or
+(default) munging.
+.IP
+When it has to limit access to a particular subdir (either due to chroot
+being disabled or having an inside-chroot path set), rsync will munge
+symlinks (by default) and sanitize paths.  Those that dislike munged
+symlinks (and really, really trust their users to not break out of the
+subdir) can disable the symlink munging via the "munge symlinks"
+parameter.
+.IP
+When rsync is sanitizing paths, it trims ".." path elements from args that
+it believes would escape the module hierarchy. It also substitutes leading
+slashes in absolute paths with the module's path (so that options such as
+\fB\-\-backup-dir\fP & \fB\-\-compare-dest\fP interpret an absolute path as rooted in
+the module's "path" dir).
+.IP
+When a chroot is in effect \fIand\fP the "name converter" parameter is
 \fInot\fP set, the "numeric ids" parameter will default to being enabled
 (disabling name lookups).  This means that if you manually setup
 name-lookup libraries in your chroot (instead of using a name converter)
@@ -501,7 +536,7 @@ triple-star pattern like "\fB/secret/***\fP".
 .IP
 The "filter" parameter takes a space-separated list of daemon filter rules,
 though it is smart enough to know not to split a token at an internal space
-in a rule (e.g. "\fB\-\ /foo\ \-\ /bar\fP" is parsed as two rules).  You may specify
+in a rule (e.g. "\fB\-\ /foo\ \ \-\ /bar\fP" is parsed as two rules).  You may specify
 one or more merge-file rules using the normal syntax.  Only one "filter"
 parameter can apply to a given module in the config file, so put all the
 rules you want in a single parameter.  Note that per-directory merge-file
@@ -511,8 +546,8 @@ the per-dir merge files are included in the transfer and the client
 requests that they be used.
 .IP "\fBexclude\fP"
 This parameter takes a space-separated list of daemon exclude patterns.  As
-with the client \fB\-\-exclude\fP option, patterns can be qualified with "\fB\-\fP" or
-"\fB+\fP" to explicitly indicate exclude/include.  Only one "exclude" parameter
+with the client \fB\-\-exclude\fP option, patterns can be qualified with "\fB\-\ \fP" or
+"\fB+\ \fP" to explicitly indicate exclude/include.  Only one "exclude" parameter
 can apply to a given module.  See the "filter" parameter for a description
 of how excluded files affect the daemon.
 .IP "\fBinclude\fP"
@@ -634,7 +669,7 @@ passwords.
 There is no default for the "secrets file" parameter, you must choose a
 name (such as \fB/etc/rsyncd.secrets\fP).  The file must normally not be
 readable by "other"; see "strict modes".  If the file is not found or is
-rejected, no logins for a "user auth" module will be possible.
+rejected, no logins for an "auth users" module will be possible.
 .IP "\fBstrict\ modes\fP"
 This parameter determines whether or not the permissions on the secrets
 file will be checked.  If "strict modes" is true, then the secrets file
@@ -667,7 +702,7 @@ addresses which match the masked IP address will be allowed in.
 .IP o
 a hostname pattern using wildcards. If the hostname of the connecting IP
 (as determined by a reverse lookup) matches the wildcarded name (using
-the same rules as normal unix filename matching), the client is allowed
+the same rules as normal Unix filename matching), the client is allowed
 in.  This only works if "reverse lookup" is enabled (the default).
 .IP o
 a hostname. A plain hostname is matched against the reverse DNS of the
@@ -756,7 +791,7 @@ made more human-readable.  The 3 supported levels are the same as for the
 human-readability to be off.  Each added apostrophe increases the level
 (e.g. "\fB%''l\ %'b\ %f\fP").
 .IP
-The default log format is "\fB%o\ %h\ [%a]\ %m\ (%u)\ %f\ %l\fP", and a "\fB%t\ [%p]\fP"
+The default log format is "\fB%o\ %h\ [%a]\ %m\ (%u)\ %f\ %l\fP", and a "\fB%t\ [%p]\ \fP"
 is always prefixed when using the "log file" parameter.  (A perl script
 that will summarize this default log format is included in the rsync source
 code distribution in the "support" subdirectory: rsyncstats.)
@@ -791,7 +826,7 @@ See the \fB\-\-checksum-choice\fP option for a way to choose the algorithm.
 .IP o
 %l the length of the file in bytes
 .IP o
-%L the string "\fB\->\ SYMLINK\fP", "\fB=>\ HARDLINK\fP", or "" (where \fBSYMLINK\fP
+%L the string "\fB\ \->\ SYMLINK\fP", "\fB\ =>\ HARDLINK\fP", or "" (where \fBSYMLINK\fP
 or \fBHARDLINK\fP is a filename)
 .IP o
 %m the module name
@@ -868,7 +903,7 @@ refuse options = * !a !v !compress*
 .RE
 .IP
 Don't worry that the "\fB*\fP" will refuse certain vital options such as
-\fB\-\-dry-run\fP, \fB\-\-server\fP, \fB\-\-no-iconv\fP, \fB\-\-protect-args\fP, etc. These
+\fB\-\-dry-run\fP, \fB\-\-server\fP, \fB\-\-no-iconv\fP, \fB\-\-seclude-args\fP, etc. These
 important options are not matched by wild-card, so they must be overridden
 by their exact name.  For instance, if you're forcing iconv transfers you
 could use something like this:
@@ -910,17 +945,19 @@ refuse options = * !a !delete* delete-after
 .fi
 .RE
 .IP
-A note on refusing "compress"\ \-\- it is better to set the "dont compress"
-daemon parameter to "\fB*\fP" because that disables compression silently
+A note on refusing "compress": it may be better to set the "dont compress"
+daemon parameter to "\fB*\fP" and ensure that \fBRSYNC_COMPRESS_LIST=zlib\fP is set
+in the environment of the daemon in order to disable compression silently
 instead of returning an error that forces the client to remove the \fB\-z\fP
 option.
 .IP
-If you are un-refusing the compress option, you probably want to match
-"\fB!compress*\fP" so that you also accept the \fB\-\-compress-level\fP option.
+If you are un-refusing the compress option, you may want to match
+"\fB!compress*\fP" if you also want to allow the \fB\-\-compress-level\fP option.
 .IP
-Note that the "write-devices" option is refused by default, but can be
-explicitly accepted with "\fB!write-devices\fP".  The options "log-file" and
-"log-file-format" are forcibly refused and cannot be accepted.
+Note that the "copy-devices" & "write-devices" options are refused by
+default, but they can be explicitly accepted with "\fB!copy-devices\fP" and/or
+"\fB!write-devices\fP".  The options "log-file" and "log-file-format" are
+forcibly refused and cannot be accepted.
 .IP
 Here are all the options that are not matched by wild-cards:
 .IP
@@ -939,7 +976,7 @@ compatibility reasons, this options should not be confused with
 .IP o
 \fB\-\-dry-run\fP, \fB\-n\fP: Who would want to disable this?
 .IP o
-\fB\-\-protect-args\fP, \fB\-s\fP: This actually makes transfers safer.
+\fB\-\-seclude-args\fP, \fB\-s\fP: Is the oldest arg-protection method.
 .IP o
 \fB\-\-from0\fP, \fB\-0\fP: Makes it easier to accept/refuse \fB\-\-files-from\fP without
 affecting this helpful modifier.
@@ -953,6 +990,10 @@ affecting this helpful modifier.
 \fB\-\-write-devices\fP: Is non-wild but also auto-disabled.
 .RE
 .IP "\fBdont\ compress\fP"
+\fBNOTE:\fP This parameter currently has no effect except in one instance: if
+it is set to "\fB*\fP" then it minimizes or disables compression for all files
+(for those that don't want to refuse the \fB\-\-compress\fP option completely).
+.IP
 This parameter allows you to select filenames based on wildcard patterns
 that should not be compressed when pulling files from the daemon (no
 analogous parameter exists to govern the pushing of files to a daemon).
@@ -963,14 +1004,14 @@ compressed files.
 The "dont compress" parameter takes a space-separated list of
 case-insensitive wildcard patterns. Any source filename matching one of the
 patterns will be compressed as little as possible during the transfer.  If
-the compression algorithm has an "off" level (such as zlib/zlibx) then no
-compression occurs for those files.  Other algorithms have the level
-minimized to reduces the CPU usage as much as possible.
+the compression algorithm has an "off" level, then no compression occurs
+for those files.  If an algorithms has the ability to change the level in
+mid-stream, it will be minimized to reduce the CPU usage as much as
+possible.
 .IP
 See the \fB\-\-skip-compress\fP parameter in the \fBrsync\fP(1) manpage for the
-list of file suffixes that are not compressed by default.  Specifying a
-value for the "dont compress" parameter changes the default when the daemon
-is the sender.
+list of file suffixes that are skipped by default if this parameter is not
+set.
 .IP "\fBearly\ exec\fP, \fBpre-xfer\ exec\fP, \fBpost-xfer\ exec\fP"
 You may specify a command to be run in the early stages of the connection,
 or right before and/or after the transfer.  If the \fBearly\ exec\fP or
@@ -1127,17 +1168,17 @@ SSL proxy.
 .SH "SSL/TLS Daemon Setup"
 .P
 When setting up an rsync daemon for access via SSL/TLS, you will need to
-configure a proxy (such as haproxy or nginx) as the front-end that handles the
-encryption.
+configure a TCP proxy (such as haproxy or nginx) as the front-end that handles
+the encryption.
 .P
 .IP o
 You should limit the access to the backend-rsyncd port to only allow the
 proxy to connect.  If it is on the same host as the proxy, then configuring
 it to only listen on localhost is a good idea.
 .IP o
-You should consider turning on the \fBproxy\ protocol\fP parameter if your proxy
-supports sending that information.  The examples below assume that this is
-enabled.
+You should consider turning on the \fBproxy\ protocol\fP rsync-daemon parameter if
+your proxy supports sending that information.  The examples below assume that
+this is enabled.
 .P
 An example haproxy setup is as follows:
 .RS 4
@@ -1167,7 +1208,7 @@ stream {
        ssl_certificate_key /etc/letsencrypt/example.com/privkey.pem;
 
        proxy_pass localhost:873;
-       proxy_protocol on; # Requires "proxy protocol = true"
+       proxy_protocol on; # Requires rsyncd.conf "proxy protocol = true"
        proxy_timeout 1m;
        proxy_connect_timeout 5s;
    }
@@ -1175,7 +1216,7 @@ stream {
 .fi
 .RE
 .P
-.SH "EXAMPLES"
+.SH "DAEMON CONFIG EXAMPLES"
 .P
 A simple rsyncd.conf file that allow anonymous rsync to a ftp area at
 \fB/home/ftp\fP would be:
@@ -1247,21 +1288,15 @@ https://rsync.samba.org/.
 .P
 .SH "VERSION"
 .P
-This man page is current for version 3.2.3 of rsync.
+This manpage is current for version 3.2.7 of rsync.
 .P
 .SH "CREDITS"
 .P
-rsync is distributed under the GNU General Public License.  See the file
+Rsync is distributed under the GNU General Public License.  See the file
 COPYING for details.
 .P
-The primary ftp site for rsync is ftp://rsync.samba.org/pub/rsync
-.P
-A web site is available at https://rsync.samba.org/.
-.P
-We would be delighted to hear from you if you like this program.
-.P
-This program uses the zlib compression library written by Jean-loup Gailly and
-Mark Adler.
+An rsync web site is available at https://rsync.samba.org/ and its github
+project is https://github.com/WayneD/rsync.
 .P
 .SH "THANKS"
 .P
@@ -1270,8 +1305,9 @@ Thanks to Karsten Thygesen for his many suggestions and documentation!
 .P
 .SH "AUTHOR"
 .P
-rsync was written by Andrew Tridgell and Paul Mackerras.  Many people have
-later contributed to it.
+Rsync was originally written by Andrew Tridgell and Paul Mackerras.  Many
+people have later contributed to it. It is currently maintained by Wayne
+Davison.
 .P
 Mailing lists for support and development are available at
 https://lists.samba.org/.
index 0f07a2f..02f67ed 100644 (file)
@@ -1,5 +1,6 @@
 <html><head>
-<title>rsyncd.conf(5) man page</title>
+<title>rsyncd.conf(5) manpage</title>
+<meta charset="UTF-8"/>
 <link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap" rel="stylesheet">
 <style>
 body {
@@ -9,6 +10,10 @@ body {
 body, b, strong, u {
   font-family: 'Roboto', sans-serif;
 }
+a.tgt { font-face: symbol; font-weight: 400; font-size: 70%; visibility: hidden; text-decoration: none; color: #ddd; padding: 0 4px; border: 0; }
+a.tgt:after { content: '🔗'; }
+a.tgt:hover { color: #444; background-color: #eaeaea; }
+h1:hover > a.tgt, h2:hover > a.tgt, h3:hover > a.tgt, dt:hover > a.tgt { visibility: visible; }
 code {
   font-family: 'Roboto Mono', monospace;
   font-weight: bold;
@@ -26,16 +31,18 @@ dd p:first-of-type {
 }
 </style>
 </head><body>
-<h1>NAME</h1>
+<h2 id="NAME">NAME<a href="#NAME" class="tgt"></a></h2>
 <p>rsyncd.conf -&#8288; configuration file for rsync in daemon mode</p>
-<h1>SYNOPSIS</h1>
+<h2 id="SYNOPSIS">SYNOPSIS<a href="#SYNOPSIS" class="tgt"></a></h2>
 <p>rsyncd.conf</p>
-<h1>DESCRIPTION</h1>
+<p>The online version of this manpage (that includes cross-linking of topics)
+is available at <a href="https://download.samba.org/pub/rsync/rsyncd.conf.5">https://download.samba.org/pub/rsync/rsyncd.conf.5</a>.</p>
+<h2 id="DESCRIPTION">DESCRIPTION<a href="#DESCRIPTION" class="tgt"></a></h2>
 <p>The rsyncd.conf file is the runtime configuration file for rsync when run as an
 rsync daemon.</p>
 <p>The rsyncd.conf file controls authentication, access, logging and available
 modules.</p>
-<h1>FILE FORMAT</h1>
+<h2 id="FILE_FORMAT">FILE FORMAT<a href="#FILE_FORMAT" class="tgt"></a></h2>
 <p>The file consists of modules and parameters. A module begins with the name of
 the module in square brackets and continues until the next module begins.
 Modules contain parameters of the form <code>name = value</code>.</p>
@@ -54,9 +61,8 @@ fashion.</p>
 <p>The values following the equals sign in parameters are all either a string (no
 quotes needed) or a boolean, which may be given as yes/no, 0/1 or true/false.
 Case is not significant in boolean values, but is preserved in string values.</p>
-<h1>LAUNCHING THE RSYNC DAEMON</h1>
-<p>The rsync daemon is launched by specifying the <code>--daemon</code> option to
-rsync.</p>
+<h2 id="LAUNCHING_THE_RSYNC_DAEMON">LAUNCHING THE RSYNC DAEMON<a href="#LAUNCHING_THE_RSYNC_DAEMON" class="tgt"></a></h2>
+<p>The rsync daemon is launched by specifying the <code>--daemon</code> option to rsync.</p>
 <p>The daemon must run with root privileges if you wish to use chroot, to bind to
 a port numbered under 1024 (as is the default 873), or to set file ownership.
 Otherwise, it must just have permission to read and write the appropriate data,
@@ -79,7 +85,7 @@ your system.  You will then need to send inetd a HUP signal to tell it to
 reread its config file.</p>
 <p>Note that you should <strong>not</strong> send the rsync daemon a HUP signal to force it to
 reread the <code>rsyncd.conf</code> file. The file is re-read on each client connection.</p>
-<h1>GLOBAL PARAMETERS</h1>
+<h2 id="GLOBAL_PARAMETERS">GLOBAL PARAMETERS<a href="#GLOBAL_PARAMETERS" class="tgt"></a></h2>
 <p>The first parameters in the file (before a [module] header) are the global
 parameters.  Rsync also allows for the use of a &quot;[global]&quot; module name to
 indicate the start of one or more global-parameter sections (the name must be
@@ -100,14 +106,14 @@ string in a path could result in a very unsafe path).  The safest way to insert
 a literal % into a value is to use %%.</p>
 <dl>
 
-<dt><code>motd file</code></dt><dd>
-<p>This parameter allows you to specify a &quot;message of the day&quot; to display to
-clients on each connect. This usually contains site information and any
-legal notices. The default is no motd file.  This can be overridden by the
+<dt id="motd_file"><code>motd file</code><a href="#motd_file" class="tgt"></a></dt><dd>
+<p>This parameter allows you to specify a &quot;message of the day&quot; (MOTD) to display
+to clients on each connect. This usually contains site information and any
+legal notices. The default is no MOTD file.  This can be overridden by the
 <code>--dparam=motdfile=FILE</code> command-line option when starting the daemon.</p>
 </dd>
 
-<dt><code>pid file</code></dt><dd>
+<dt id="pid_file"><code>pid file</code><a href="#pid_file" class="tgt"></a></dt><dd>
 <p>This parameter tells the rsync daemon to write its process ID to that file.
 The rsync keeps the file locked so that it can know when it is safe to
 overwrite an existing file.</p>
@@ -115,33 +121,33 @@ overwrite an existing file.</p>
 option when starting the daemon.</p>
 </dd>
 
-<dt><code>port</code></dt><dd>
+<dt id="port"><code>port</code><a href="#port" class="tgt"></a></dt><dd>
 <p>You can override the default port the daemon will listen on by specifying
 this value (defaults to 873).  This is ignored if the daemon is being run
 by inetd, and is superseded by the <code>--port</code> command-line option.</p>
 </dd>
 
-<dt><code>address</code></dt><dd>
+<dt id="address"><code>address</code><a href="#address" class="tgt"></a></dt><dd>
 <p>You can override the default IP address the daemon will listen on by
 specifying this value.  This is ignored if the daemon is being run by
 inetd, and is superseded by the <code>--address</code> command-line option.</p>
 </dd>
 
-<dt><code>socket options</code></dt><dd>
+<dt id="socket_options"><code>socket options</code><a href="#socket_options" class="tgt"></a></dt><dd>
 <p>This parameter can provide endless fun for people who like to tune their
 systems to the utmost degree. You can set all sorts of socket options which
-may make transfers faster (or slower!). Read the man page for the
+may make transfers faster (or slower!). Read the manpage for the
 <strong>setsockopt()</strong> system call for details on some of the options you may be
 able to set. By default no special socket options are set.  These settings
 can also be specified via the <code>--sockopts</code> command-line option.</p>
 </dd>
 
-<dt><code>listen backlog</code></dt><dd>
+<dt id="listen_backlog"><code>listen backlog</code><a href="#listen_backlog" class="tgt"></a></dt><dd>
 <p>You can override the default backlog value when the daemon listens for
 connections.  It defaults to 5.</p>
 </dd>
 </dl>
-<h1>MODULE PARAMETERS</h1>
+<h2 id="MODULE_PARAMETERS">MODULE PARAMETERS<a href="#MODULE_PARAMETERS" class="tgt"></a></h2>
 <p>After the global parameters you should define a number of modules, each module
 exports a directory tree as a symbolic name. Modules are exported by specifying
 a module name in square brackets [module] followed by the parameters for that
@@ -154,16 +160,26 @@ global parameters follow (see above).</p>
 the values of parameters.  See the GLOBAL PARAMETERS section for more details.</p>
 <dl>
 
-<dt><code>comment</code></dt><dd>
+<dt id="comment"><code>comment</code><a href="#comment" class="tgt"></a></dt><dd>
 <p>This parameter specifies a description string that is displayed next to the
 module name when clients obtain a list of available modules. The default is
 no comment.</p>
 </dd>
 
-<dt><code>path</code></dt><dd>
+<dt id="path"><code>path</code><a href="#path" class="tgt"></a></dt><dd>
 <p>This parameter specifies the directory in the daemon's filesystem to make
 available in this module.  You must specify this parameter for each module
 in <code>rsyncd.conf</code>.</p>
+<p>If the value contains a &quot;/./&quot; element then the path will be divided at that
+point into a chroot dir and an inner-chroot subdir.  If <a href="#use_chroot"><code>use chroot</code></a>
+is set to false, though, the extraneous dot dir is just cleaned out of the
+path.  An example of this idiom is:</p>
+<blockquote>
+<pre><code>path = /var/rsync/./module1
+</code></pre>
+</blockquote>
+<p>This will (when chrooting) chroot to &quot;/var/rsync&quot; and set the inside-chroot
+path to &quot;/module1&quot;.</p>
 <p>You may base the path's value off of an environment variable by surrounding
 the variable name with percent signs.  You can even reference a variable
 that is set by rsync when the user connects.  For example, this would use
@@ -179,36 +195,50 @@ wish to fix), append a trailing slash to the path to avoid losing the
 trailing whitespace.</p>
 </dd>
 
-<dt><code>use chroot</code></dt><dd>
-<p>If &quot;use chroot&quot; is true, the rsync daemon will chroot to the &quot;path&quot; before
+<dt id="use_chroot"><code>use chroot</code><a href="#use_chroot" class="tgt"></a></dt><dd>
+<p>If &quot;use chroot&quot; is true, the rsync daemon will chroot to the &quot;<a href="#path">path</a>&quot; before
 starting the file transfer with the client.  This has the advantage of
 extra protection against possible implementation security holes, but it has
 the disadvantages of requiring super-user privileges, of not being able to
 follow symbolic links that are either absolute or outside of the new root
 path, and of complicating the preservation of users and groups by name (see
 below).</p>
-<p>As an additional safety feature, you can specify a dot-dir in the module's
-&quot;path&quot; to indicate the point where the chroot should occur.  This allows
-rsync to run in a chroot with a non-&quot;/&quot; path for the top of the transfer
-hierarchy.  Doing this guards against unintended library loading (since
-those absolute paths will not be inside the transfer hierarchy unless you
-have used an unwise pathname), and lets you setup libraries for the chroot
-that are outside of the transfer.  For example, specifying
-&quot;/var/rsync/./module1&quot; will chroot to the &quot;/var/rsync&quot; directory and set
-the inside-chroot path to &quot;/module1&quot;.  If you had omitted the dot-dir, the
-chroot would have used the whole path, and the inside-chroot path would
-have been &quot;/&quot;.</p>
-<p>When both &quot;use chroot&quot; and &quot;daemon chroot&quot; are false, OR the inside-chroot
-path of &quot;use chroot&quot; is not &quot;/&quot;, rsync will: (1) munge symlinks by default
-for security reasons (see &quot;munge symlinks&quot; for a way to turn this off, but
-only if you trust your users), (2) substitute leading slashes in absolute
-paths with the module's path (so that options such as <code>--backup-dir</code>,
-<code>--compare-dest</code>, etc. interpret an absolute path as rooted in the module's
-&quot;path&quot; dir), and (3) trim &quot;..&quot; path elements from args if rsync believes
-they would escape the module hierarchy.  The default for &quot;use chroot&quot; is
-true, and is the safer choice (especially if the module is not read-only).</p>
-<p>When this parameter is enabled <u>and</u> the &quot;name converter&quot; parameter is
-<u>not</u> set, the &quot;numeric ids&quot; parameter will default to being enabled
+<p>If <code>use chroot</code> is not set, it defaults to trying to enable a chroot but
+allows the daemon to continue (after logging a warning) if it fails. The
+one exception to this is when a module's <a href="#path"><code>path</code></a> has a &quot;/./&quot; chroot
+divider in it&nbsp;-&#8288;-&#8288; this causes an unset value to be treated as true for that
+module.</p>
+<p>Prior to rsync 3.2.7, the default value was &quot;true&quot;.  The new &quot;unset&quot;
+default makes it easier to setup an rsync daemon as a non-root user or to
+run a daemon on a system where chroot fails.  Explicitly setting the value
+to &quot;true&quot; in rsyncd.conf will always require the chroot to succeed.</p>
+<p>It is also possible to specify a dot-dir in the module's &quot;<a href="#path">path</a>&quot; to
+indicate that you want to chdir to the earlier part of the path and then
+serve files from inside the latter part of the path (with sanitizing and
+default symlink munging).  This can be useful if you need some library dirs
+inside the chroot (typically for uid &amp; gid lookups) but don't want to put
+the lib dir into the top of the served path (even though they can be hidden
+with an <a href="#exclude"><code>exclude</code></a> directive).  However, a better choice for a modern
+rsync setup is to use a <a href="#name_converter"><code>name converter</code></a>&quot; and try to avoid inner lib
+dirs altogether.  See also the <a href="#daemon_chroot"><code>daemon chroot</code></a> parameter, which causes
+rsync to chroot into its own chroot area before doing any path-related
+chrooting.</p>
+<p>If the daemon is serving the &quot;/&quot; dir (either directly or due to being
+chrooted to the module's path), rsync does not do any path sanitizing or
+(default) munging.</p>
+<p>When it has to limit access to a particular subdir (either due to chroot
+being disabled or having an inside-chroot path set), rsync will munge
+symlinks (by default) and sanitize paths.  Those that dislike munged
+symlinks (and really, really trust their users to not break out of the
+subdir) can disable the symlink munging via the &quot;<a href="#munge_symlinks">munge symlinks</a>&quot;
+parameter.</p>
+<p>When rsync is sanitizing paths, it trims &quot;..&quot; path elements from args that
+it believes would escape the module hierarchy. It also substitutes leading
+slashes in absolute paths with the module's path (so that options such as
+<code>--backup-dir</code> &amp; <code>--compare-dest</code> interpret an absolute path as rooted in
+the module's &quot;<a href="#path">path</a>&quot; dir).</p>
+<p>When a chroot is in effect <u>and</u> the &quot;<a href="#name_converter">name converter</a>&quot; parameter is
+<u>not</u> set, the &quot;<a href="#numeric_ids">numeric ids</a>&quot; parameter will default to being enabled
 (disabling name lookups).  This means that if you manually setup
 name-lookup libraries in your chroot (instead of using a name converter)
 that you need to explicitly set <code>numeric ids = false</code> for rsync to do name
@@ -216,22 +246,22 @@ lookups.</p>
 <p>If you copy library resources into the module's chroot area, you should
 protect them through your OS's normal user/group or ACL settings (to
 prevent the rsync module's user from being able to change them), and then
-hide them from the user's view via &quot;exclude&quot; (see how in the discussion of
+hide them from the user's view via &quot;<a href="#exclude">exclude</a>&quot; (see how in the discussion of
 that parameter).  However, it's easier and safer to setup a name converter.</p>
 </dd>
 
-<dt><code>daemon chroot</code></dt><dd>
+<dt id="daemon_chroot"><code>daemon chroot</code><a href="#daemon_chroot" class="tgt"></a></dt><dd>
 <p>This parameter specifies a path to which the daemon will chroot before
-beginning communication with clients. Module paths (and any &quot;use chroot&quot;
+beginning communication with clients. Module paths (and any &quot;<a href="#use_chroot">use chroot</a>&quot;
 settings) will then be related to this one. This lets you choose if you
 want the whole daemon to be chrooted (with this setting), just the
-transfers to be chrooted (with &quot;use chroot&quot;), or both.  Keep in mind that
+transfers to be chrooted (with &quot;<a href="#use_chroot">use chroot</a>&quot;), or both.  Keep in mind that
 the &quot;daemon chroot&quot; area may need various OS/lib/etc files installed to
 allow the daemon to function.  By default the daemon runs without any
 chrooting.</p>
 </dd>
 
-<dt><code>proxy protocol</code></dt><dd>
+<dt id="proxy_protocol"><code>proxy protocol</code><a href="#proxy_protocol" class="tgt"></a></dt><dd>
 <p>When this parameter is enabled, all incoming connections must start with a
 V1 or V2 proxy protocol header.  If the header is not found, the connection
 is closed.</p>
@@ -252,7 +282,7 @@ others, then you will need to setup multiple rsync daemon processes on
 different ports.</p>
 </dd>
 
-<dt><code>name converter</code></dt><dd>
+<dt id="name_converter"><code>name converter</code><a href="#name_converter" class="tgt"></a></dt><dd>
 <p>This parameter lets you specify a program that will be run by the rsync
 daemon to do user &amp; group conversions between names &amp; ids.  This script
 is started prior to any chroot being setup, and runs as the daemon user
@@ -270,31 +300,31 @@ implements the normal user &amp; group lookups.  Feel free to customize it or
 just use it as documentation to implement your own.</p>
 </dd>
 
-<dt><code>numeric ids</code></dt><dd>
+<dt id="numeric_ids"><code>numeric ids</code><a href="#numeric_ids" class="tgt"></a></dt><dd>
 <p>Enabling this parameter disables the mapping of users and groups by name
 for the current daemon module.  This prevents the daemon from trying to
 load any user/group-related files or libraries.  This enabling makes the
 transfer behave as if the client had passed the <code>--numeric-ids</code>
 command-line option.  By default, this parameter is enabled for chroot
 modules and disabled for non-chroot modules.  Also keep in mind that
-uid/gid preservation requires the module to be running as root (see &quot;uid&quot;)
-or for &quot;fake super&quot; to be configured.</p>
+uid/gid preservation requires the module to be running as root (see &quot;<a href="#uid">uid</a>&quot;)
+or for &quot;<a href="#fake_super">fake super</a>&quot; to be configured.</p>
 <p>A chroot-enabled module should not have this parameter set to false unless
-you're using a &quot;name converter&quot; program <u>or</u> you've taken steps to ensure
+you're using a &quot;<a href="#name_converter">name converter</a>&quot; program <u>or</u> you've taken steps to ensure
 that the module has the necessary resources it needs to translate names and
 that it is not possible for a user to change those resources.</p>
 </dd>
 
-<dt><code>munge symlinks</code></dt><dd>
+<dt id="munge_symlinks"><code>munge symlinks</code><a href="#munge_symlinks" class="tgt"></a></dt><dd>
 <p>This parameter tells rsync to modify all symlinks in the same way as the
 (non-daemon-affecting) <code>--munge-links</code> command-line option (using a method
 described below).  This should help protect your files from user trickery
 when your daemon module is writable.  The default is disabled when
-&quot;use chroot&quot; is on with an inside-chroot path of &quot;/&quot;, OR if &quot;daemon chroot&quot;
+&quot;<a href="#use_chroot">use chroot</a>&quot; is on with an inside-chroot path of &quot;/&quot;, OR if &quot;<a href="#daemon_chroot">daemon chroot</a>&quot;
 is on, otherwise it is enabled.</p>
 <p>If you disable this parameter on a daemon that is not read-only, there are
 tricks that a user can play with uploaded symlinks to access
-daemon-excluded items (if your module has any), and, if &quot;use chroot&quot; is
+daemon-excluded items (if your module has any), and, if &quot;<a href="#use_chroot">use chroot</a>&quot; is
 off, rsync can even be tricked into showing or changing data that is
 outside the module's path (as access-permissions allow).</p>
 <p>The way rsync disables the use of symlinks is to prefix each one with the
@@ -312,7 +342,7 @@ symlinks from being abused by prefixing &quot;/rsyncd-munged/&quot; to the start
 every symlink's value.  There is a perl script in the support directory of
 the source code named &quot;munge-symlinks&quot; that can be used to add or remove
 this prefix from your symlinks.</p>
-<p>When this parameter is disabled on a writable module and &quot;use chroot&quot; is
+<p>When this parameter is disabled on a writable module and &quot;<a href="#use_chroot">use chroot</a>&quot; is
 off (or the inside-chroot path is not &quot;/&quot;), incoming symlinks will be
 modified to drop a leading slash and to remove &quot;..&quot; path elements that
 rsync believes will allow a symlink to escape the module's hierarchy.
@@ -320,7 +350,7 @@ There are tricky ways to work around this, though, so you had better trust
 your users if you choose this combination of parameters.</p>
 </dd>
 
-<dt><code>charset</code></dt><dd>
+<dt id="charset"><code>charset</code><a href="#charset" class="tgt"></a></dt><dd>
 <p>This specifies the name of the character set in which the module's
 filenames are stored.  If the client uses an <code>--iconv</code> option, the daemon
 will use the value of the &quot;charset&quot; parameter regardless of the character
@@ -328,21 +358,21 @@ set the client actually passed.  This allows the daemon to support charset
 conversion in a chroot module without extra files in the chroot area, and
 also ensures that name-translation is done in a consistent manner.  If the
 &quot;charset&quot; parameter is not set, the <code>--iconv</code> option is refused, just as if
-&quot;iconv&quot; had been specified via &quot;refuse options&quot;.</p>
+&quot;iconv&quot; had been specified via &quot;<a href="#refuse_options">refuse options</a>&quot;.</p>
 <p>If you wish to force users to always use <code>--iconv</code> for a particular module,
-add &quot;no-iconv&quot; to the &quot;refuse options&quot; parameter.  Keep in mind that this
+add &quot;no-iconv&quot; to the &quot;<a href="#refuse_options">refuse options</a>&quot; parameter.  Keep in mind that this
 will restrict access to your module to very new rsync clients.</p>
 </dd>
 
-<dt><code>max connections</code></dt><dd>
+<dt id="max_connections"><code>max connections</code><a href="#max_connections" class="tgt"></a></dt><dd>
 <p>This parameter allows you to specify the maximum number of simultaneous
 connections you will allow.  Any clients connecting when the maximum has
 been reached will receive a message telling them to try later.  The default
 is 0, which means no limit.  A negative value disables the module.  See
-also the &quot;lock file&quot; parameter.</p>
+also the &quot;<a href="#lock_file">lock file</a>&quot; parameter.</p>
 </dd>
 
-<dt><code>log file</code></dt><dd>
+<dt id="log_file"><code>log file</code><a href="#log_file" class="tgt"></a></dt><dd>
 <p>When the &quot;log file&quot; parameter is set to a non-empty string, the rsync
 daemon will log messages to the indicated file rather than using syslog.
 This is particularly useful on systems (such as AIX) where <strong>syslog()</strong>
@@ -360,21 +390,21 @@ the daemon's log file and the default for all the modules, which still
 allows modules to override the default setting.</p>
 </dd>
 
-<dt><code>syslog facility</code></dt><dd>
+<dt id="syslog_facility"><code>syslog facility</code><a href="#syslog_facility" class="tgt"></a></dt><dd>
 <p>This parameter allows you to specify the syslog facility name to use when
 logging messages from the rsync daemon. You may use any standard syslog
 facility name which is defined on your system. Common names are auth,
 authpriv, cron, daemon, ftp, kern, lpr, mail, news, security, syslog, user,
 uucp, local0, local1, local2, local3, local4, local5, local6 and local7.
-The default is daemon.  This setting has no effect if the &quot;log file&quot;
+The default is daemon.  This setting has no effect if the &quot;<a href="#log_file">log file</a>&quot;
 setting is a non-empty string (either set in the per-modules settings, or
 inherited from the global settings).</p>
 </dd>
 
-<dt><code>syslog tag</code></dt><dd>
+<dt id="syslog_tag"><code>syslog tag</code><a href="#syslog_tag" class="tgt"></a></dt><dd>
 <p>This parameter allows you to specify the syslog tag to use when logging
 messages from the rsync daemon. The default is &quot;rsyncd&quot;.  This setting has
-no effect if the &quot;log file&quot; setting is a non-empty string (either set in
+no effect if the &quot;<a href="#log_file">log file</a>&quot; setting is a non-empty string (either set in
 the per-modules settings, or inherited from the global settings).</p>
 <p>For example, if you wanted each authenticated user's name to be included in
 the syslog tag, you could do something like this:</p>
@@ -384,7 +414,7 @@ the syslog tag, you could do something like this:</p>
 </blockquote>
 </dd>
 
-<dt><code>max verbosity</code></dt><dd>
+<dt id="max_verbosity"><code>max verbosity</code><a href="#max_verbosity" class="tgt"></a></dt><dd>
 <p>This parameter allows you to control the maximum amount of verbose
 information that you'll allow the daemon to generate (since the information
 goes into the log file). The default is 1, which allows the client to
@@ -398,22 +428,22 @@ accept for a particular info/debug level, refer to <code>rsync --info=help</code
 output debug TIME2 and FLIST3.</p>
 </dd>
 
-<dt><code>lock file</code></dt><dd>
-<p>This parameter specifies the file to use to support the &quot;max connections&quot;
+<dt id="lock_file"><code>lock file</code><a href="#lock_file" class="tgt"></a></dt><dd>
+<p>This parameter specifies the file to use to support the &quot;<a href="#max_connections">max connections</a>&quot;
 parameter. The rsync daemon uses record locking on this file to ensure that
 the max connections limit is not exceeded for the modules sharing the lock
 file.  The default is <code>/var/run/rsyncd.lock</code>.</p>
 </dd>
 
-<dt><code>read only</code></dt><dd>
+<dt id="read_only"><code>read only</code><a href="#read_only" class="tgt"></a></dt><dd>
 <p>This parameter determines whether clients will be able to upload files or
 not. If &quot;read only&quot; is true then any attempted uploads will fail. If
 &quot;read only&quot; is false then uploads will be possible if file permissions on
 the daemon side allow them. The default is for all modules to be read only.</p>
-<p>Note that &quot;auth users&quot; can override this setting on a per-user basis.</p>
+<p>Note that &quot;<a href="#auth_users">auth users</a>&quot; can override this setting on a per-user basis.</p>
 </dd>
 
-<dt><code>write only</code></dt><dd>
+<dt id="write_only"><code>write only</code><a href="#write_only" class="tgt"></a></dt><dd>
 <p>This parameter determines whether clients will be able to download files or
 not. If &quot;write only&quot; is true then any attempted downloads will fail. If
 &quot;write only&quot; is false then downloads will be possible if file permissions
@@ -423,7 +453,7 @@ disabled.</p>
 write-only module.</p>
 </dd>
 
-<dt><code>open noatime</code></dt><dd>
+<dt id="open_noatime"><code>open noatime</code><a href="#open_noatime" class="tgt"></a></dt><dd>
 <p>When set to True, this parameter tells the rsync daemon to open files with
 the O_NOATIME flag
 (on systems that support it) to avoid changing the access time of the files
@@ -437,24 +467,24 @@ opened with O_NOATIME.</p>
 <code>--open-noatime</code>.</p>
 </dd>
 
-<dt><code>list</code></dt><dd>
+<dt id="list"><code>list</code><a href="#list" class="tgt"></a></dt><dd>
 <p>This parameter determines whether this module is listed when the client
 asks for a listing of available modules.  In addition, if this is false,
 the daemon will pretend the module does not exist when a client denied by
-&quot;hosts allow&quot; or &quot;hosts deny&quot; attempts to access it.  Realize that if
-&quot;reverse lookup&quot; is disabled globally but enabled for the module, the
+&quot;<a href="#hosts_allow">hosts allow</a>&quot; or &quot;<a href="#hosts_deny">hosts deny</a>&quot; attempts to access it.  Realize that if
+&quot;<a href="#reverse_lookup">reverse lookup</a>&quot; is disabled globally but enabled for the module, the
 resulting reverse lookup to a potentially client-controlled DNS server may
 still reveal to the client that it hit an existing module.  The default is
 for modules to be listable.</p>
 </dd>
 
-<dt><code>uid</code></dt><dd>
+<dt id="uid"><code>uid</code><a href="#uid" class="tgt"></a></dt><dd>
 <p>This parameter specifies the user name or user ID that file transfers to
 and from that module should take place as when the daemon was run as root.
-In combination with the &quot;gid&quot; parameter this determines what file
+In combination with the &quot;<a href="#gid">gid</a>&quot; parameter this determines what file
 permissions are available. The default when run by a super-user is to
 switch to the system's &quot;nobody&quot; user.  The default for a non-super-user is
-to not try to change the user.  See also the &quot;gid&quot; parameter.</p>
+to not try to change the user.  See also the &quot;<a href="#gid">gid</a>&quot; parameter.</p>
 <p>The RSYNC_USER_NAME environment variable may be used to request that rsync
 run as the authorizing user.  For example, if you want a rsync to run as
 the same user that was received for the rsync authentication, this setup is
@@ -466,12 +496,12 @@ gid = *
 </blockquote>
 </dd>
 
-<dt><code>gid</code></dt><dd>
+<dt id="gid"><code>gid</code><a href="#gid" class="tgt"></a></dt><dd>
 <p>This parameter specifies one or more group names/IDs that will be used when
 accessing the module.  The first one will be the default group, and any
 extra ones be set as supplemental groups.  You may also specify a &quot;<code>*</code>&quot; as
 the first gid in the list, which will be replaced by all the normal groups
-for the transfer's user (see &quot;uid&quot;).  The default when run by a super-user
+for the transfer's user (see &quot;<a href="#uid">uid</a>&quot;).  The default when run by a super-user
 is to switch to your OS's &quot;nobody&quot; (or perhaps &quot;nogroup&quot;) group with no
 other supplementary groups.  The default for a non-super-user is to not
 change any group attributes (and indeed, your OS may not allow a
@@ -483,26 +513,26 @@ case any leading and/or trailing whitespace is removed from the tokens and
 empty tokens are ignored.</p>
 </dd>
 
-<dt><code>daemon uid</code></dt><dd>
+<dt id="daemon_uid"><code>daemon uid</code><a href="#daemon_uid" class="tgt"></a></dt><dd>
 <p>This parameter specifies a uid under which the daemon will run. The daemon
 usually runs as user root, and when this is left unset the user is left
-unchanged. See also the &quot;uid&quot; parameter.</p>
+unchanged. See also the &quot;<a href="#uid">uid</a>&quot; parameter.</p>
 </dd>
 
-<dt><code>daemon gid</code></dt><dd>
+<dt id="daemon_gid"><code>daemon gid</code><a href="#daemon_gid" class="tgt"></a></dt><dd>
 <p>This parameter specifies a gid under which the daemon will run. The daemon
 usually runs as group root, and when this is left unset, the group is left
-unchanged. See also the &quot;gid&quot; parameter.</p>
+unchanged. See also the &quot;<a href="#gid">gid</a>&quot; parameter.</p>
 </dd>
 
-<dt><code>fake super</code></dt><dd>
+<dt id="fake_super"><code>fake super</code><a href="#fake_super" class="tgt"></a></dt><dd>
 <p>Setting &quot;fake super = yes&quot; for a module causes the daemon side to behave as
 if the <code>--fake-super</code> command-line option had been specified.  This allows
 the full attributes of a file to be stored without having to have the
 daemon actually running as root.</p>
 </dd>
 
-<dt><code>filter</code></dt><dd>
+<dt id="filter"><code>filter</code><a href="#filter" class="tgt"></a></dt><dd>
 <p>The daemon has its own filter chain that determines what files it will let
 the client access.  This chain is not sent to the client and is independent
 of any filters the client may have specified.  Files excluded by the daemon
@@ -512,15 +542,15 @@ tries to push them (triggering exit code 23), and are never deleted from
 the module.  You can use daemon filters to prevent clients from downloading
 or tampering with private administrative files, such as files you may add
 to support uid/gid name translations.</p>
-<p>The daemon filter chain is built from the &quot;filter&quot;, &quot;include from&quot;,
-&quot;include&quot;, &quot;exclude from&quot;, and &quot;exclude&quot; parameters, in that order of
+<p>The daemon filter chain is built from the &quot;filter&quot;, &quot;<a href="#include_from">include from</a>&quot;,
+&quot;<a href="#include">include</a>&quot;, &quot;<a href="#exclude_from">exclude from</a>&quot;, and &quot;<a href="#exclude">exclude</a>&quot; parameters, in that order of
 priority.  Anchored patterns are anchored at the root of the module.  To
 prevent access to an entire subtree, for example, &quot;<code>/secret</code>&quot;, you <strong>must</strong>
 exclude everything in the subtree; the easiest way to do this is with a
 triple-star pattern like &quot;<code>/secret/***</code>&quot;.</p>
 <p>The &quot;filter&quot; parameter takes a space-separated list of daemon filter rules,
 though it is smart enough to know not to split a token at an internal space
-in a rule (e.g. &quot;<code>- /foo - /bar</code>&quot; is parsed as two rules).  You may specify
+in a rule (e.g. &quot;<code>- /foo  - /bar</code>&quot; is parsed as two rules).  You may specify
 one or more merge-file rules using the normal syntax.  Only one &quot;filter&quot;
 parameter can apply to a given module in the config file, so put all the
 rules you want in a single parameter.  Note that per-directory merge-file
@@ -530,36 +560,36 @@ the per-dir merge files are included in the transfer and the client
 requests that they be used.</p>
 </dd>
 
-<dt><code>exclude</code></dt><dd>
+<dt id="exclude"><code>exclude</code><a href="#exclude" class="tgt"></a></dt><dd>
 <p>This parameter takes a space-separated list of daemon exclude patterns.  As
-with the client <code>--exclude</code> option, patterns can be qualified with &quot;<code>-</code>&quot; or
-&quot;<code>+</code>&quot; to explicitly indicate exclude/include.  Only one &quot;exclude&quot; parameter
+with the client <code>--exclude</code> option, patterns can be qualified with &quot;<code>- </code>&quot; or
+&quot;<code>+ </code>&quot; to explicitly indicate exclude/include.  Only one &quot;exclude&quot; parameter
 can apply to a given module.  See the &quot;filter&quot; parameter for a description
 of how excluded files affect the daemon.</p>
 </dd>
 
-<dt><code>include</code></dt><dd>
-<p>Use an &quot;include&quot; to override the effects of the &quot;exclude&quot; parameter.  Only
-one &quot;include&quot; parameter can apply to a given module.  See the &quot;filter&quot;
+<dt id="include"><code>include</code><a href="#include" class="tgt"></a></dt><dd>
+<p>Use an &quot;include&quot; to override the effects of the &quot;<a href="#exclude">exclude</a>&quot; parameter.  Only
+one &quot;include&quot; parameter can apply to a given module.  See the &quot;<a href="#filter">filter</a>&quot;
 parameter for a description of how excluded files affect the daemon.</p>
 </dd>
 
-<dt><code>exclude from</code></dt><dd>
+<dt id="exclude_from"><code>exclude from</code><a href="#exclude_from" class="tgt"></a></dt><dd>
 <p>This parameter specifies the name of a file on the daemon that contains
 daemon exclude patterns, one per line.  Only one &quot;exclude from&quot; parameter
 can apply to a given module; if you have multiple exclude-from files, you
-can specify them as a merge file in the &quot;filter&quot; parameter.  See the
-&quot;filter&quot; parameter for a description of how excluded files affect the
+can specify them as a merge file in the &quot;<a href="#filter">filter</a>&quot; parameter.  See the
+&quot;<a href="#filter">filter</a>&quot; parameter for a description of how excluded files affect the
 daemon.</p>
 </dd>
 
-<dt><code>include from</code></dt><dd>
-<p>Analogue of &quot;exclude from&quot; for a file of daemon include patterns.  Only one
-&quot;include from&quot; parameter can apply to a given module.  See the &quot;filter&quot;
+<dt id="include_from"><code>include from</code><a href="#include_from" class="tgt"></a></dt><dd>
+<p>Analogue of &quot;<a href="#exclude_from">exclude from</a>&quot; for a file of daemon include patterns.  Only one
+&quot;include from&quot; parameter can apply to a given module.  See the &quot;<a href="#filter">filter</a>&quot;
 parameter for a description of how excluded files affect the daemon.</p>
 </dd>
 
-<dt><code>incoming chmod</code></dt><dd>
+<dt id="incoming_chmod"><code>incoming chmod</code><a href="#incoming_chmod" class="tgt"></a></dt><dd>
 <p>This parameter allows you to specify a set of comma-separated chmod strings
 that will affect the permissions of all incoming files (files that are
 being received by the daemon).  These changes happen after all other
@@ -569,7 +599,7 @@ See the description of the <code>--chmod</code> rsync option and the <strong>chm
 manpage for information on the format of this string.</p>
 </dd>
 
-<dt><code>outgoing chmod</code></dt><dd>
+<dt id="outgoing_chmod"><code>outgoing chmod</code><a href="#outgoing_chmod" class="tgt"></a></dt><dd>
 <p>This parameter allows you to specify a set of comma-separated chmod strings
 that will affect the permissions of all outgoing files (files that are
 being sent out from the daemon).  These changes happen first, making the
@@ -580,7 +610,7 @@ of the <code>--chmod</code> rsync option and the <strong>chmod</strong>(1) manpa
 on the format of this string.</p>
 </dd>
 
-<dt><code>auth users</code></dt><dd>
+<dt id="auth_users"><code>auth users</code><a href="#auth_users" class="tgt"></a></dt><dd>
 <p>This parameter specifies a comma and/or space-separated list of
 authorization rules.  In its simplest form, you list the usernames that
 will be allowed to connect to this module. The usernames do not need to
@@ -590,7 +620,7 @@ authentication. If &quot;auth users&quot; is set then the client will be challen
 to supply a username and password to connect to the module. A challenge
 response authentication protocol is used for this exchange. The plain text
 usernames and passwords are stored in the file specified by the
-&quot;secrets file&quot; parameter. The default is for all users to be able to
+&quot;<a href="#secrets_file">secrets file</a>&quot; parameter. The default is for all users to be able to
 connect without a password (this is called &quot;anonymous rsync&quot;).</p>
 <p>In addition to username matching, you can specify groupname matching via a
 '@' prefix.  When using groupname matching, the authenticating username
@@ -600,7 +630,7 @@ user if the named user is a member of the rsync group.</p>
 <p>Finally, options may be specified after a colon (:).  The options allow you
 to &quot;deny&quot; a user or a group, set the access to &quot;ro&quot; (read-only), or set the
 access to &quot;rw&quot; (read/write).  Setting an auth-rule-specific ro/rw setting
-overrides the module's &quot;read only&quot; setting.</p>
+overrides the module's &quot;<a href="#read_only">read only</a>&quot; setting.</p>
 <p>Be sure to put the rules in the order you want them to be matched, because
 the checking stops at the first matching user or group, and that is the
 only auth that is checked.  For example:</p>
@@ -634,10 +664,10 @@ rsyncd.conf-level username that differs from the remote-shell-level
 username when using a remote shell to connect to an rsync daemon.</p>
 </dd>
 
-<dt><code>secrets file</code></dt><dd>
+<dt id="secrets_file"><code>secrets file</code><a href="#secrets_file" class="tgt"></a></dt><dd>
 <p>This parameter specifies the name of a file that contains the
 username:password and/or @groupname:password pairs used for authenticating
-this module. This file is only consulted if the &quot;auth users&quot; parameter is
+this module. This file is only consulted if the &quot;<a href="#auth_users">auth users</a>&quot; parameter is
 specified.  The file is line-based and contains one name:password pair per
 line.  Any line has a hash (#) as the very first character on the line is
 considered a comment and is skipped.  The passwords can contain any
@@ -649,16 +679,16 @@ authorized using a matching &quot;@groupname&quot; rule.  When that happens, the
 can be authorized via either their &quot;username:password&quot; line or the
 &quot;@groupname:password&quot; line for the group that triggered the authentication.</p>
 <p>It is up to you what kind of password entries you want to include, either
-users, groups, or both.  The use of group rules in &quot;auth users&quot; does not
+users, groups, or both.  The use of group rules in &quot;<a href="#auth_users">auth users</a>&quot; does not
 require that you specify a group password if you do not want to use shared
 passwords.</p>
 <p>There is no default for the &quot;secrets file&quot; parameter, you must choose a
 name (such as <code>/etc/rsyncd.secrets</code>).  The file must normally not be
-readable by &quot;other&quot;; see &quot;strict modes&quot;.  If the file is not found or is
-rejected, no logins for a &quot;user auth&quot; module will be possible.</p>
+readable by &quot;other&quot;; see &quot;<a href="#strict_modes">strict modes</a>&quot;.  If the file is not found or is
+rejected, no logins for an &quot;<a href="#auth_users">auth users</a>&quot; module will be possible.</p>
 </dd>
 
-<dt><code>strict modes</code></dt><dd>
+<dt id="strict_modes"><code>strict modes</code><a href="#strict_modes" class="tgt"></a></dt><dd>
 <p>This parameter determines whether or not the permissions on the secrets
 file will be checked.  If &quot;strict modes&quot; is true, then the secrets file
 must not be readable by any user ID other than the one that the rsync
@@ -667,7 +697,7 @@ performed.  The default is true.  This parameter was added to accommodate
 rsync running on the Windows operating system.</p>
 </dd>
 
-<dt><code>hosts allow</code></dt><dd>
+<dt id="hosts_allow"><code>hosts allow</code><a href="#hosts_allow" class="tgt"></a></dt><dd>
 <p>This parameter allows you to specify a list of comma- and/or
 whitespace-separated patterns that are matched against a connecting
 client's hostname and IP address.  If none of the patterns match, then the
@@ -686,11 +716,11 @@ or similar for IPv6, e.g. ffff:ffff:ffff:ffff:: instead of /64. All IP
 addresses which match the masked IP address will be allowed in.</li>
 <li>a hostname pattern using wildcards. If the hostname of the connecting IP
 (as determined by a reverse lookup) matches the wildcarded name (using
-the same rules as normal unix filename matching), the client is allowed
-in.  This only works if &quot;reverse lookup&quot; is enabled (the default).</li>
+the same rules as normal Unix filename matching), the client is allowed
+in.  This only works if &quot;<a href="#reverse_lookup">reverse lookup</a>&quot; is enabled (the default).</li>
 <li>a hostname. A plain hostname is matched against the reverse DNS of the
-connecting IP (if &quot;reverse lookup&quot; is enabled), and/or the IP of the
-given hostname is matched against the connecting IP (if &quot;forward lookup&quot;
+connecting IP (if &quot;<a href="#reverse_lookup">reverse lookup</a>&quot; is enabled), and/or the IP of the
+given hostname is matched against the connecting IP (if &quot;<a href="#forward_lookup">forward lookup</a>&quot;
 is enabled, as it is by default).  Any match will be allowed in.</li>
 <li>an '@' followed by a netgroup name, which will match if the reverse DNS
 of the connecting IP is in the specified netgroup.</li>
@@ -703,29 +733,29 @@ fe80::%link1/64
 fe80::%link1/ffff:ffff:ffff:ffff::
 </code></pre>
 </blockquote>
-<p>You can also combine &quot;hosts allow&quot; with &quot;hosts deny&quot; as a way to add
+<p>You can also combine &quot;hosts allow&quot; with &quot;<a href="#hosts_deny">hosts deny</a>&quot; as a way to add
 exceptions to your deny list.  When both parameters are specified, the
 &quot;hosts allow&quot; parameter is checked first and a match results in the client
 being able to connect.  A non-allowed host is then matched against the
-&quot;hosts deny&quot; list to see if it should be rejected.  A host that does not
+&quot;<a href="#hosts_deny">hosts deny</a>&quot; list to see if it should be rejected.  A host that does not
 match either list is allowed to connect.</p>
 <p>The default is no &quot;hosts allow&quot; parameter, which means all hosts can
 connect.</p>
 </dd>
 
-<dt><code>hosts deny</code></dt><dd>
+<dt id="hosts_deny"><code>hosts deny</code><a href="#hosts_deny" class="tgt"></a></dt><dd>
 <p>This parameter allows you to specify a list of comma- and/or
 whitespace-separated patterns that are matched against a connecting clients
 hostname and IP address. If the pattern matches then the connection is
-rejected. See the &quot;hosts allow&quot; parameter for more information.</p>
+rejected. See the &quot;<a href="#hosts_allow">hosts allow</a>&quot; parameter for more information.</p>
 <p>The default is no &quot;hosts deny&quot; parameter, which means all hosts can
 connect.</p>
 </dd>
 
-<dt><code>reverse lookup</code></dt><dd>
+<dt id="reverse_lookup"><code>reverse lookup</code><a href="#reverse_lookup" class="tgt"></a></dt><dd>
 <p>Controls whether the daemon performs a reverse lookup on the client's IP
-address to determine its hostname, which is used for &quot;hosts allow&quot; &amp;
-&quot;hosts deny&quot; checks and the &quot;%h&quot; log escape.  This is enabled by default,
+address to determine its hostname, which is used for &quot;<a href="#hosts_allow">hosts allow</a>&quot; &amp;
+&quot;<a href="#hosts_deny">hosts deny</a>&quot; checks and the &quot;%h&quot; log escape.  This is enabled by default,
 but you may wish to disable it to save time if you know the lookup will not
 return a useful result, in which case the daemon will use the name
 &quot;UNDETERMINED&quot; instead.</p>
@@ -735,14 +765,14 @@ avoid the lookup.  Thus, you probably want to disable it globally and then
 enable it for modules that need the information.</p>
 </dd>
 
-<dt><code>forward lookup</code></dt><dd>
+<dt id="forward_lookup"><code>forward lookup</code><a href="#forward_lookup" class="tgt"></a></dt><dd>
 <p>Controls whether the daemon performs a forward lookup on any hostname
 specified in an hosts allow/deny setting.  By default this is enabled,
 allowing the use of an explicit hostname that would not be returned by
 reverse DNS of the connecting IP.</p>
 </dd>
 
-<dt><code>ignore errors</code></dt><dd>
+<dt id="ignore_errors"><code>ignore errors</code><a href="#ignore_errors" class="tgt"></a></dt><dd>
 <p>This parameter tells rsyncd to ignore I/O errors on the daemon when
 deciding whether to run the delete phase of the transfer. Normally rsync
 skips the <code>--delete</code> step if any I/O errors have occurred in order to
@@ -751,22 +781,22 @@ I/O error. In some cases this test is counter productive so you can use
 this parameter to turn off this behavior.</p>
 </dd>
 
-<dt><code>ignore nonreadable</code></dt><dd>
+<dt id="ignore_nonreadable"><code>ignore nonreadable</code><a href="#ignore_nonreadable" class="tgt"></a></dt><dd>
 <p>This tells the rsync daemon to completely ignore files that are not
 readable by the user. This is useful for public archives that may have some
 non-readable files among the directories, and the sysadmin doesn't want
 those files to be seen at all.</p>
 </dd>
 
-<dt><code>transfer logging</code></dt><dd>
+<dt id="transfer_logging"><code>transfer logging</code><a href="#transfer_logging" class="tgt"></a></dt><dd>
 <p>This parameter enables per-file logging of downloads and uploads in a
 format somewhat similar to that used by ftp daemons.  The daemon always
 logs the transfer at the end, so if a transfer is aborted, no mention will
 be made in the log file.</p>
-<p>If you want to customize the log lines, see the &quot;log format&quot; parameter.</p>
+<p>If you want to customize the log lines, see the &quot;<a href="#log_format">log format</a>&quot; parameter.</p>
 </dd>
 
-<dt><code>log format</code></dt><dd>
+<dt id="log_format"><code>log format</code><a href="#log_format" class="tgt"></a></dt><dd>
 <p>This parameter allows you to specify the format used for logging file
 transfers when transfer logging is enabled.  The format is a text string
 containing embedded single-character escape sequences prefixed with a
@@ -778,8 +808,8 @@ made more human-readable.  The 3 supported levels are the same as for the
 <code>--human-readable</code> command-line option, though the default is for
 human-readability to be off.  Each added apostrophe increases the level
 (e.g. &quot;<code>%''l %'b %f</code>&quot;).</p>
-<p>The default log format is &quot;<code>%o %h [%a] %m (%u) %f %l</code>&quot;, and a &quot;<code>%t [%p]</code>&quot;
-is always prefixed when using the &quot;log file&quot; parameter.  (A perl script
+<p>The default log format is &quot;<code>%o %h [%a] %m (%u) %f %l</code>&quot;, and a &quot;<code>%t [%p] </code>&quot;
+is always prefixed when using the &quot;<a href="#log_file">log file</a>&quot; parameter.  (A perl script
 that will summarize this default log format is included in the rsync source
 code distribution in the &quot;support&quot; subdirectory: rsyncstats.)</p>
 <p>The single-character escapes that are understood are as follows:</p>
@@ -800,7 +830,7 @@ See the <code>--checksum-choice</code> option for a way to choose the algorithm.
 <li>%h the remote host name (only available for a daemon)</li>
 <li>%i an itemized list of what is being updated</li>
 <li>%l the length of the file in bytes</li>
-<li>%L the string &quot;<code>-&gt; SYMLINK</code>&quot;, &quot;<code>=&gt; HARDLINK</code>&quot;, or &quot;&quot; (where <code>SYMLINK</code>
+<li>%L the string &quot;<code> -&gt; SYMLINK</code>&quot;, &quot;<code> =&gt; HARDLINK</code>&quot;, or &quot;&quot; (where <code>SYMLINK</code>
 or <code>HARDLINK</code> is a filename)</li>
 <li>%m the module name</li>
 <li>%M the last-modified time of the file</li>
@@ -820,7 +850,7 @@ versions.  For instance, deleted files were only output as verbose messages
 prior to rsync 2.6.4.</p>
 </dd>
 
-<dt><code>timeout</code></dt><dd>
+<dt id="timeout"><code>timeout</code><a href="#timeout" class="tgt"></a></dt><dd>
 <p>This parameter allows you to override the clients choice for I/O timeout
 for this module. Using this parameter you can ensure that rsync won't wait
 on a dead client forever. The timeout is specified in seconds. A value of
@@ -828,7 +858,7 @@ zero means no timeout and is the default. A good choice for anonymous rsync
 daemons may be 600 (giving a 10 minute timeout).</p>
 </dd>
 
-<dt><code>refuse options</code></dt><dd>
+<dt id="refuse_options"><code>refuse options</code><a href="#refuse_options" class="tgt"></a></dt><dd>
 <p>This parameter allows you to specify a space-separated list of rsync
 command-line options that will be refused by your rsync daemon.  You may
 specify the full option name, its one-letter abbreviation, or a wild-card
@@ -858,7 +888,7 @@ example:</p>
 </code></pre>
 </blockquote>
 <p>Don't worry that the &quot;<code>*</code>&quot; will refuse certain vital options such as
-<code>--dry-run</code>, <code>--server</code>, <code>--no-iconv</code>, <code>--protect-args</code>, etc. These
+<code>--dry-run</code>, <code>--server</code>, <code>--no-iconv</code>, <code>--seclude-args</code>, etc. These
 important options are not matched by wild-card, so they must be overridden
 by their exact name.  For instance, if you're forcing iconv transfers you
 could use something like this:</p>
@@ -889,15 +919,17 @@ such as:</p>
 <pre><code>refuse options = * !a !delete* delete-after
 </code></pre>
 </blockquote>
-<p>A note on refusing &quot;compress&quot;&nbsp;-&#8288;-&#8288; it is better to set the &quot;dont compress&quot;
-daemon parameter to &quot;<code>*</code>&quot; because that disables compression silently
+<p>A note on refusing &quot;compress&quot;: it may be better to set the &quot;<a href="#dont_compress">dont compress</a>&quot;
+daemon parameter to &quot;<code>*</code>&quot; and ensure that <code>RSYNC_COMPRESS_LIST=zlib</code> is set
+in the environment of the daemon in order to disable compression silently
 instead of returning an error that forces the client to remove the <code>-z</code>
 option.</p>
-<p>If you are un-refusing the compress option, you probably want to match
-&quot;<code>!compress*</code>&quot; so that you also accept the <code>--compress-level</code> option.</p>
-<p>Note that the &quot;write-devices&quot; option is refused by default, but can be
-explicitly accepted with &quot;<code>!write-devices</code>&quot;.  The options &quot;log-file&quot; and
-&quot;log-file-format&quot; are forcibly refused and cannot be accepted.</p>
+<p>If you are un-refusing the compress option, you may want to match
+&quot;<code>!compress*</code>&quot; if you also want to allow the <code>--compress-level</code> option.</p>
+<p>Note that the &quot;copy-devices&quot; &amp; &quot;write-devices&quot; options are refused by
+default, but they can be explicitly accepted with &quot;<code>!copy-devices</code>&quot; and/or
+&quot;<code>!write-devices</code>&quot;.  The options &quot;log-file&quot; and &quot;log-file-format&quot; are
+forcibly refused and cannot be accepted.</p>
 <p>Here are all the options that are not matched by wild-cards:</p>
 <ul>
 <li><code>--server</code>: Required for rsync to even work.</li>
@@ -906,19 +938,22 @@ explicitly accepted with &quot;<code>!write-devices</code>&quot;.  The options &
 receiver.  While rsync passes the older alias <code>--log-format</code> for
 compatibility reasons, this options should not be confused with
 <code>--log-file-format</code>.</li>
-<li><code>--sender</code>: Use &quot;write only&quot; parameter instead of refusing this.</li>
+<li><code>--sender</code>: Use &quot;<a href="#write_only">write only</a>&quot; parameter instead of refusing this.</li>
 <li><code>--dry-run</code>, <code>-n</code>: Who would want to disable this?</li>
-<li><code>--protect-args</code>, <code>-s</code>: This actually makes transfers safer.</li>
+<li><code>--seclude-args</code>, <code>-s</code>: Is the oldest arg-protection method.</li>
 <li><code>--from0</code>, <code>-0</code>: Makes it easier to accept/refuse <code>--files-from</code> without
 affecting this helpful modifier.</li>
-<li><code>--iconv</code>: This is auto-disabled based on &quot;charset&quot; parameter.</li>
+<li><code>--iconv</code>: This is auto-disabled based on &quot;<a href="#charset">charset</a>&quot; parameter.</li>
 <li><code>--no-iconv</code>: Most transfers use this option.</li>
 <li><code>--checksum-seed</code>: Is a fairly rare, safe option.</li>
 <li><code>--write-devices</code>: Is non-wild but also auto-disabled.</li>
 </ul>
 </dd>
 
-<dt><code>dont compress</code></dt><dd>
+<dt id="dont_compress"><code>dont compress</code><a href="#dont_compress" class="tgt"></a></dt><dd>
+<p><strong>NOTE:</strong> This parameter currently has no effect except in one instance: if
+it is set to &quot;<code>*</code>&quot; then it minimizes or disables compression for all files
+(for those that don't want to refuse the <code>--compress</code> option completely).</p>
 <p>This parameter allows you to select filenames based on wildcard patterns
 that should not be compressed when pulling files from the daemon (no
 analogous parameter exists to govern the pushing of files to a daemon).
@@ -928,16 +963,16 @@ compressed files.</p>
 <p>The &quot;dont compress&quot; parameter takes a space-separated list of
 case-insensitive wildcard patterns. Any source filename matching one of the
 patterns will be compressed as little as possible during the transfer.  If
-the compression algorithm has an &quot;off&quot; level (such as zlib/zlibx) then no
-compression occurs for those files.  Other algorithms have the level
-minimized to reduces the CPU usage as much as possible.</p>
+the compression algorithm has an &quot;off&quot; level, then no compression occurs
+for those files.  If an algorithms has the ability to change the level in
+mid-stream, it will be minimized to reduce the CPU usage as much as
+possible.</p>
 <p>See the <code>--skip-compress</code> parameter in the <strong>rsync</strong>(1) manpage for the
-list of file suffixes that are not compressed by default.  Specifying a
-value for the &quot;dont compress&quot; parameter changes the default when the daemon
-is the sender.</p>
+list of file suffixes that are skipped by default if this parameter is not
+set.</p>
 </dd>
 
-<dt><code>early exec</code>, <code>pre-xfer exec</code>, <code>post-xfer exec</code></dt><dd>
+<span id="post-xfer_exec"></span><span id="pre-xfer_exec"></span><dt id="early_exec"><code>early exec</code>, <code>pre-xfer exec</code>, <code>post-xfer exec</code><a href="#early_exec" class="tgt"></a></dt><dd>
 <p>You may specify a command to be run in the early stages of the connection,
 or right before and/or after the transfer.  If the <code>early exec</code> or
 <code>pre-xfer exec</code> command returns an error code, the transfer is aborted
@@ -993,7 +1028,7 @@ shell to use when running the command (which otherwise uses your
 both options completely.</p>
 </dd>
 </dl>
-<h1>CONFIG DIRECTIVES</h1>
+<h2 id="CONFIG_DIRECTIVES">CONFIG DIRECTIVES<a href="#CONFIG_DIRECTIVES" class="tgt"></a></h2>
 <p>There are currently two config directives available that allow a config file to
 incorporate the contents of other files:  <code>&amp;include</code> and <code>&amp;merge</code>.  Both allow
 a reference to either a file or a directory.  They differ in how segregated the
@@ -1043,7 +1078,7 @@ pid file = /var/lock/rsync.lock
 <p>This would merge any <code>/etc/rsyncd.d/*.inc</code> files (for global values that should
 stay in effect), and then include any <code>/etc/rsyncd.d/*.conf</code> files (defining
 modules without any global-value cross-talk).</p>
-<h1>AUTHENTICATION STRENGTH</h1>
+<h2 id="AUTHENTICATION_STRENGTH">AUTHENTICATION STRENGTH<a href="#AUTHENTICATION_STRENGTH" class="tgt"></a></h2>
 <p>The authentication protocol used in rsync is a 128 bit MD4 based challenge
 response system. This is fairly weak protection, though (with at least one
 brute-force hash-finding algorithm publicly available), so if you want really
@@ -1054,17 +1089,17 @@ encryption of the data that is transferred over the connection. Only
 authentication is provided. Use ssh as the transport if you want encryption.</p>
 <p>You can also make use of SSL/TLS encryption if you put rsync behind an
 SSL proxy.</p>
-<h1>SSL/TLS Daemon Setup</h1>
+<h2 id="SSL_TLS_Daemon_Setup">SSL/TLS Daemon Setup<a href="#SSL_TLS_Daemon_Setup" class="tgt"></a></h2>
 <p>When setting up an rsync daemon for access via SSL/TLS, you will need to
-configure a proxy (such as haproxy or nginx) as the front-end that handles the
-encryption.</p>
+configure a TCP proxy (such as haproxy or nginx) as the front-end that handles
+the encryption.</p>
 <ul>
 <li>You should limit the access to the backend-rsyncd port to only allow the
 proxy to connect.  If it is on the same host as the proxy, then configuring
 it to only listen on localhost is a good idea.</li>
-<li>You should consider turning on the <code>proxy protocol</code> parameter if your proxy
-supports sending that information.  The examples below assume that this is
-enabled.</li>
+<li>You should consider turning on the <code>proxy protocol</code> rsync-daemon parameter if
+your proxy supports sending that information.  The examples below assume that
+this is enabled.</li>
 </ul>
 <p>An example haproxy setup is as follows:</p>
 <blockquote>
@@ -1089,14 +1124,14 @@ backend be_rsync
        ssl_certificate_key /etc/letsencrypt/example.com/privkey.pem;
 
        proxy_pass localhost:873;
-       proxy_protocol on; # Requires &quot;proxy protocol = true&quot;
+       proxy_protocol on; # Requires rsyncd.conf &quot;proxy protocol = true&quot;
        proxy_timeout 1m;
        proxy_connect_timeout 5s;
    }
 }
 </code></pre>
 </blockquote>
-<h1>EXAMPLES</h1>
+<h2 id="DAEMON_CONFIG_EXAMPLES">DAEMON CONFIG EXAMPLES<a href="#DAEMON_CONFIG_EXAMPLES" class="tgt"></a></h2>
 <p>A simple rsyncd.conf file that allow anonymous rsync to a ftp area at
 <code>/home/ftp</code> would be:</p>
 <blockquote>
@@ -1143,30 +1178,28 @@ pid file = /var/run/rsyncd.pid
 susan:herpass
 </code></pre>
 </blockquote>
-<h1>FILES</h1>
+<h2 id="FILES">FILES<a href="#FILES" class="tgt"></a></h2>
 <p>/etc/rsyncd.conf or rsyncd.conf</p>
-<h1>SEE ALSO</h1>
-<p><strong>rsync</strong>(1), <strong>rsync-ssl</strong>(1)</p>
-<h1>BUGS</h1>
+<h2 id="SEE_ALSO">SEE ALSO<a href="#SEE_ALSO" class="tgt"></a></h2>
+<p><a href="rsync.1"><strong>rsync</strong>(1)</a>, <a href="rsync-ssl.1"><strong>rsync-ssl</strong>(1)</a></p>
+<h2 id="BUGS">BUGS<a href="#BUGS" class="tgt"></a></h2>
 <p>Please report bugs! The rsync bug tracking system is online at
 <a href="https://rsync.samba.org/">https://rsync.samba.org/</a>.</p>
-<h1>VERSION</h1>
-<p>This man page is current for version 3.2.3 of rsync.</p>
-<h1>CREDITS</h1>
-<p>rsync is distributed under the GNU General Public License.  See the file
-COPYING for details.</p>
-<p>The primary ftp site for rsync is <a href="ftp://rsync.samba.org/pub/rsync">ftp://rsync.samba.org/pub/rsync</a></p>
-<p>A web site is available at <a href="https://rsync.samba.org/">https://rsync.samba.org/</a>.</p>
-<p>We would be delighted to hear from you if you like this program.</p>
-<p>This program uses the zlib compression library written by Jean-loup Gailly and
-Mark Adler.</p>
-<h1>THANKS</h1>
+<h2 id="VERSION">VERSION<a href="#VERSION" class="tgt"></a></h2>
+<p>This manpage is current for version 3.2.7 of rsync.</p>
+<h2 id="CREDITS">CREDITS<a href="#CREDITS" class="tgt"></a></h2>
+<p>Rsync is distributed under the GNU General Public License.  See the file
+<a href="COPYING">COPYING</a> for details.</p>
+<p>An rsync web site is available at <a href="https://rsync.samba.org/">https://rsync.samba.org/</a> and its github
+project is <a href="https://github.com/WayneD/rsync">https://github.com/WayneD/rsync</a>.</p>
+<h2 id="THANKS">THANKS<a href="#THANKS" class="tgt"></a></h2>
 <p>Thanks to Warren Stanley for his original idea and patch for the rsync daemon.
 Thanks to Karsten Thygesen for his many suggestions and documentation!</p>
-<h1>AUTHOR</h1>
-<p>rsync was written by Andrew Tridgell and Paul Mackerras.  Many people have
-later contributed to it.</p>
+<h2 id="AUTHOR">AUTHOR<a href="#AUTHOR" class="tgt"></a></h2>
+<p>Rsync was originally written by Andrew Tridgell and Paul Mackerras.  Many
+people have later contributed to it. It is currently maintained by Wayne
+Davison.</p>
 <p>Mailing lists for support and development are available at
 <a href="https://lists.samba.org/">https://lists.samba.org/</a>.</p>
-<div style="float: right"><p><i>06 Aug 2020</i></p></div>
+<div style="float: right"><p><i>20 Oct 2022</i></p></div>
 </body></html>
index b70532b..91aaf6f 100644 (file)
@@ -1,12 +1,15 @@
-# NAME
+## NAME
 
 rsyncd.conf - configuration file for rsync in daemon mode
 
-# SYNOPSIS
+## SYNOPSIS
 
 rsyncd.conf
 
-# DESCRIPTION
+The online version of this manpage (that includes cross-linking of topics)
+is available at <https://download.samba.org/pub/rsync/rsyncd.conf.5>.
+
+## DESCRIPTION
 
 The rsyncd.conf file is the runtime configuration file for rsync when run as an
 rsync daemon.
@@ -14,7 +17,7 @@ rsync daemon.
 The rsyncd.conf file controls authentication, access, logging and available
 modules.
 
-# FILE FORMAT
+## FILE FORMAT
 
 The file consists of modules and parameters. A module begins with the name of
 the module in square brackets and continues until the next module begins.
@@ -40,10 +43,9 @@ The values following the equals sign in parameters are all either a string (no
 quotes needed) or a boolean, which may be given as yes/no, 0/1 or true/false.
 Case is not significant in boolean values, but is preserved in string values.
 
-# LAUNCHING THE RSYNC DAEMON
+## LAUNCHING THE RSYNC DAEMON
 
-The rsync daemon is launched by specifying the `--daemon` option to
-rsync.
+The rsync daemon is launched by specifying the `--daemon` option to rsync.
 
 The daemon must run with root privileges if you wish to use chroot, to bind to
 a port numbered under 1024 (as is the default 873), or to set file ownership.
@@ -60,16 +62,16 @@ When run via inetd you should add a line like this to /etc/services:
 
 and a single line something like this to /etc/inetd.conf:
 
->     rsync   stream  tcp     nowait  root   /usr/bin/rsync rsyncd --daemon
+>     rsync   stream  tcp     nowait  root   @BINDIR@/rsync rsyncd --daemon
 
-Replace "/usr/bin/rsync" with the path to where you have rsync installed on
+Replace "@BINDIR@/rsync" with the path to where you have rsync installed on
 your system.  You will then need to send inetd a HUP signal to tell it to
 reread its config file.
 
 Note that you should **not** send the rsync daemon a HUP signal to force it to
 reread the `rsyncd.conf` file. The file is re-read on each client connection.
 
-# GLOBAL PARAMETERS
+## GLOBAL PARAMETERS
 
 The first parameters in the file (before a [module] header) are the global
 parameters.  Rsync also allows for the use of a "[global]" module name to
@@ -96,9 +98,9 @@ a literal % into a value is to use %%.
 
 0.  `motd file`
 
-    This parameter allows you to specify a "message of the day" to display to
-    clients on each connect. This usually contains site information and any
-    legal notices. The default is no motd file.  This can be overridden by the
+    This parameter allows you to specify a "message of the day" (MOTD) to display
+    to clients on each connect. This usually contains site information and any
+    legal notices. The default is no MOTD file.  This can be overridden by the
     `--dparam=motdfile=FILE` command-line option when starting the daemon.
 
 0.  `pid file`
@@ -126,7 +128,7 @@ a literal % into a value is to use %%.
 
     This parameter can provide endless fun for people who like to tune their
     systems to the utmost degree. You can set all sorts of socket options which
-    may make transfers faster (or slower!). Read the man page for the
+    may make transfers faster (or slower!). Read the manpage for the
     **setsockopt()** system call for details on some of the options you may be
     able to set. By default no special socket options are set.  These settings
     can also be specified via the `--sockopts` command-line option.
@@ -136,7 +138,7 @@ a literal % into a value is to use %%.
     You can override the default backlog value when the daemon listens for
     connections.  It defaults to 5.
 
-# MODULE PARAMETERS
+## MODULE PARAMETERS
 
 After the global parameters you should define a number of modules, each module
 exports a directory tree as a symbolic name. Modules are exported by specifying
@@ -162,6 +164,16 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     available in this module.  You must specify this parameter for each module
     in `rsyncd.conf`.
 
+    If the value contains a "/./" element then the path will be divided at that
+    point into a chroot dir and an inner-chroot subdir.  If [`use chroot`](#)
+    is set to false, though, the extraneous dot dir is just cleaned out of the
+    path.  An example of this idiom is:
+
+    >     path = /var/rsync/./module1
+
+    This will (when chrooting) chroot to "/var/rsync" and set the inside-chroot
+    path to "/module1".
+
     You may base the path's value off of an environment variable by surrounding
     the variable name with percent signs.  You can even reference a variable
     that is set by rsync when the user connects.  For example, this would use
@@ -177,7 +189,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 
 0.  `use chroot`
 
-    If "use chroot" is true, the rsync daemon will chroot to the "path" before
+    If "use chroot" is true, the rsync daemon will chroot to the "[path](#)" before
     starting the file transfer with the client.  This has the advantage of
     extra protection against possible implementation security holes, but it has
     the disadvantages of requiring super-user privileges, of not being able to
@@ -185,30 +197,48 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     path, and of complicating the preservation of users and groups by name (see
     below).
 
-    As an additional safety feature, you can specify a dot-dir in the module's
-    "path" to indicate the point where the chroot should occur.  This allows
-    rsync to run in a chroot with a non-"/" path for the top of the transfer
-    hierarchy.  Doing this guards against unintended library loading (since
-    those absolute paths will not be inside the transfer hierarchy unless you
-    have used an unwise pathname), and lets you setup libraries for the chroot
-    that are outside of the transfer.  For example, specifying
-    "/var/rsync/./module1" will chroot to the "/var/rsync" directory and set
-    the inside-chroot path to "/module1".  If you had omitted the dot-dir, the
-    chroot would have used the whole path, and the inside-chroot path would
-    have been "/".
-
-    When both "use chroot" and "daemon chroot" are false, OR the inside-chroot
-    path of "use chroot" is not "/", rsync will: (1) munge symlinks by default
-    for security reasons (see "munge symlinks" for a way to turn this off, but
-    only if you trust your users), (2) substitute leading slashes in absolute
-    paths with the module's path (so that options such as `--backup-dir`,
-    `--compare-dest`, etc. interpret an absolute path as rooted in the module's
-    "path" dir), and (3) trim ".." path elements from args if rsync believes
-    they would escape the module hierarchy.  The default for "use chroot" is
-    true, and is the safer choice (especially if the module is not read-only).
-
-    When this parameter is enabled *and* the "name converter" parameter is
-    *not* set, the "numeric ids" parameter will default to being enabled
+    If `use chroot` is not set, it defaults to trying to enable a chroot but
+    allows the daemon to continue (after logging a warning) if it fails. The
+    one exception to this is when a module's [`path`](#) has a "/./" chroot
+    divider in it -- this causes an unset value to be treated as true for that
+    module.
+
+    Prior to rsync 3.2.7, the default value was "true".  The new "unset"
+    default makes it easier to setup an rsync daemon as a non-root user or to
+    run a daemon on a system where chroot fails.  Explicitly setting the value
+    to "true" in rsyncd.conf will always require the chroot to succeed.
+
+    It is also possible to specify a dot-dir in the module's "[path](#)" to
+    indicate that you want to chdir to the earlier part of the path and then
+    serve files from inside the latter part of the path (with sanitizing and
+    default symlink munging).  This can be useful if you need some library dirs
+    inside the chroot (typically for uid & gid lookups) but don't want to put
+    the lib dir into the top of the served path (even though they can be hidden
+    with an [`exclude`](#) directive).  However, a better choice for a modern
+    rsync setup is to use a [`name converter`](#)" and try to avoid inner lib
+    dirs altogether.  See also the [`daemon chroot`](#) parameter, which causes
+    rsync to chroot into its own chroot area before doing any path-related
+    chrooting.
+
+    If the daemon is serving the "/" dir (either directly or due to being
+    chrooted to the module's path), rsync does not do any path sanitizing or
+    (default) munging.
+
+    When it has to limit access to a particular subdir (either due to chroot
+    being disabled or having an inside-chroot path set), rsync will munge
+    symlinks (by default) and sanitize paths.  Those that dislike munged
+    symlinks (and really, really trust their users to not break out of the
+    subdir) can disable the symlink munging via the "[munge symlinks](#)"
+    parameter.
+
+    When rsync is sanitizing paths, it trims ".." path elements from args that
+    it believes would escape the module hierarchy. It also substitutes leading
+    slashes in absolute paths with the module's path (so that options such as
+    `--backup-dir` & `--compare-dest` interpret an absolute path as rooted in
+    the module's "[path](#)" dir).
+
+    When a chroot is in effect *and* the "[name converter](#)" parameter is
+    *not* set, the "[numeric ids](#)" parameter will default to being enabled
     (disabling name lookups).  This means that if you manually setup
     name-lookup libraries in your chroot (instead of using a name converter)
     that you need to explicitly set `numeric ids = false` for rsync to do name
@@ -217,16 +247,16 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     If you copy library resources into the module's chroot area, you should
     protect them through your OS's normal user/group or ACL settings (to
     prevent the rsync module's user from being able to change them), and then
-    hide them from the user's view via "exclude" (see how in the discussion of
+    hide them from the user's view via "[exclude](#)" (see how in the discussion of
     that parameter).  However, it's easier and safer to setup a name converter.
 
 0.  `daemon chroot`
 
     This parameter specifies a path to which the daemon will chroot before
-    beginning communication with clients. Module paths (and any "use chroot"
+    beginning communication with clients. Module paths (and any "[use chroot](#)"
     settings) will then be related to this one. This lets you choose if you
     want the whole daemon to be chrooted (with this setting), just the
-    transfers to be chrooted (with "use chroot"), or both.  Keep in mind that
+    transfers to be chrooted (with "[use chroot](#)"), or both.  Keep in mind that
     the "daemon chroot" area may need various OS/lib/etc files installed to
     allow the daemon to function.  By default the daemon runs without any
     chrooting.
@@ -284,11 +314,11 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     transfer behave as if the client had passed the `--numeric-ids`
     command-line option.  By default, this parameter is enabled for chroot
     modules and disabled for non-chroot modules.  Also keep in mind that
-    uid/gid preservation requires the module to be running as root (see "uid")
-    or for "fake super" to be configured.
+    uid/gid preservation requires the module to be running as root (see "[uid](#)")
+    or for "[fake super](#)" to be configured.
 
     A chroot-enabled module should not have this parameter set to false unless
-    you're using a "name converter" program *or* you've taken steps to ensure
+    you're using a "[name converter](#)" program *or* you've taken steps to ensure
     that the module has the necessary resources it needs to translate names and
     that it is not possible for a user to change those resources.
 
@@ -298,12 +328,12 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     (non-daemon-affecting) `--munge-links` command-line option (using a method
     described below).  This should help protect your files from user trickery
     when your daemon module is writable.  The default is disabled when
-    "use chroot" is on with an inside-chroot path of "/", OR if "daemon chroot"
+    "[use chroot](#)" is on with an inside-chroot path of "/", OR if "[daemon chroot](#)"
     is on, otherwise it is enabled.
 
     If you disable this parameter on a daemon that is not read-only, there are
     tricks that a user can play with uploaded symlinks to access
-    daemon-excluded items (if your module has any), and, if "use chroot" is
+    daemon-excluded items (if your module has any), and, if "[use chroot](#)" is
     off, rsync can even be tricked into showing or changing data that is
     outside the module's path (as access-permissions allow).
 
@@ -324,7 +354,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     the source code named "munge-symlinks" that can be used to add or remove
     this prefix from your symlinks.
 
-    When this parameter is disabled on a writable module and "use chroot" is
+    When this parameter is disabled on a writable module and "[use chroot](#)" is
     off (or the inside-chroot path is not "/"), incoming symlinks will be
     modified to drop a leading slash and to remove ".." path elements that
     rsync believes will allow a symlink to escape the module's hierarchy.
@@ -340,10 +370,10 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     conversion in a chroot module without extra files in the chroot area, and
     also ensures that name-translation is done in a consistent manner.  If the
     "charset" parameter is not set, the `--iconv` option is refused, just as if
-    "iconv" had been specified via "refuse options".
+    "iconv" had been specified via "[refuse options](#)".
 
     If you wish to force users to always use `--iconv` for a particular module,
-    add "no-iconv" to the "refuse options" parameter.  Keep in mind that this
+    add "no-iconv" to the "[refuse options](#)" parameter.  Keep in mind that this
     will restrict access to your module to very new rsync clients.
 
 0.  `max connections`
@@ -352,7 +382,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     connections you will allow.  Any clients connecting when the maximum has
     been reached will receive a message telling them to try later.  The default
     is 0, which means no limit.  A negative value disables the module.  See
-    also the "lock file" parameter.
+    also the "[lock file](#)" parameter.
 
 0.  `log file`
 
@@ -381,7 +411,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     facility name which is defined on your system. Common names are auth,
     authpriv, cron, daemon, ftp, kern, lpr, mail, news, security, syslog, user,
     uucp, local0, local1, local2, local3, local4, local5, local6 and local7.
-    The default is daemon.  This setting has no effect if the "log file"
+    The default is daemon.  This setting has no effect if the "[log file](#)"
     setting is a non-empty string (either set in the per-modules settings, or
     inherited from the global settings).
 
@@ -389,7 +419,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 
     This parameter allows you to specify the syslog tag to use when logging
     messages from the rsync daemon. The default is "rsyncd".  This setting has
-    no effect if the "log file" setting is a non-empty string (either set in
+    no effect if the "[log file](#)" setting is a non-empty string (either set in
     the per-modules settings, or inherited from the global settings).
 
     For example, if you wanted each authenticated user's name to be included in
@@ -414,7 +444,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 
 0.  `lock file`
 
-    This parameter specifies the file to use to support the "max connections"
+    This parameter specifies the file to use to support the "[max connections](#)"
     parameter. The rsync daemon uses record locking on this file to ensure that
     the max connections limit is not exceeded for the modules sharing the lock
     file.  The default is `/var/run/rsyncd.lock`.
@@ -426,7 +456,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     "read only" is false then uploads will be possible if file permissions on
     the daemon side allow them. The default is for all modules to be read only.
 
-    Note that "auth users" can override this setting on a per-user basis.
+    Note that "[auth users](#)" can override this setting on a per-user basis.
 
 0.  `write only`
 
@@ -460,8 +490,8 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     This parameter determines whether this module is listed when the client
     asks for a listing of available modules.  In addition, if this is false,
     the daemon will pretend the module does not exist when a client denied by
-    "hosts allow" or "hosts deny" attempts to access it.  Realize that if
-    "reverse lookup" is disabled globally but enabled for the module, the
+    "[hosts allow](#)" or "[hosts deny](#)" attempts to access it.  Realize that if
+    "[reverse lookup](#)" is disabled globally but enabled for the module, the
     resulting reverse lookup to a potentially client-controlled DNS server may
     still reveal to the client that it hit an existing module.  The default is
     for modules to be listable.
@@ -470,10 +500,10 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 
     This parameter specifies the user name or user ID that file transfers to
     and from that module should take place as when the daemon was run as root.
-    In combination with the "gid" parameter this determines what file
+    In combination with the "[gid](#)" parameter this determines what file
     permissions are available. The default when run by a super-user is to
     switch to the system's "nobody" user.  The default for a non-super-user is
-    to not try to change the user.  See also the "gid" parameter.
+    to not try to change the user.  See also the "[gid](#)" parameter.
 
     The RSYNC_USER_NAME environment variable may be used to request that rsync
     run as the authorizing user.  For example, if you want a rsync to run as
@@ -489,7 +519,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     accessing the module.  The first one will be the default group, and any
     extra ones be set as supplemental groups.  You may also specify a "`*`" as
     the first gid in the list, which will be replaced by all the normal groups
-    for the transfer's user (see "uid").  The default when run by a super-user
+    for the transfer's user (see "[uid](#)").  The default when run by a super-user
     is to switch to your OS's "nobody" (or perhaps "nogroup") group with no
     other supplementary groups.  The default for a non-super-user is to not
     change any group attributes (and indeed, your OS may not allow a
@@ -505,13 +535,13 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 
     This parameter specifies a uid under which the daemon will run. The daemon
     usually runs as user root, and when this is left unset the user is left
-    unchanged. See also the "uid" parameter.
+    unchanged. See also the "[uid](#)" parameter.
 
 0.  `daemon gid`
 
     This parameter specifies a gid under which the daemon will run. The daemon
     usually runs as group root, and when this is left unset, the group is left
-    unchanged. See also the "gid" parameter.
+    unchanged. See also the "[gid](#)" parameter.
 
 0.  `fake super`
 
@@ -532,8 +562,8 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     or tampering with private administrative files, such as files you may add
     to support uid/gid name translations.
 
-    The daemon filter chain is built from the "filter", "include from",
-    "include", "exclude from", and "exclude" parameters, in that order of
+    The daemon filter chain is built from the "filter", "[include from](#)",
+    "[include](#)", "[exclude from](#)", and "[exclude](#)" parameters, in that order of
     priority.  Anchored patterns are anchored at the root of the module.  To
     prevent access to an entire subtree, for example, "`/secret`", you **must**
     exclude everything in the subtree; the easiest way to do this is with a
@@ -560,8 +590,8 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 
 0.  `include`
 
-    Use an "include" to override the effects of the "exclude" parameter.  Only
-    one "include" parameter can apply to a given module.  See the "filter"
+    Use an "include" to override the effects of the "[exclude](#)" parameter.  Only
+    one "include" parameter can apply to a given module.  See the "[filter](#)"
     parameter for a description of how excluded files affect the daemon.
 
 0.  `exclude from`
@@ -569,14 +599,14 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     This parameter specifies the name of a file on the daemon that contains
     daemon exclude patterns, one per line.  Only one "exclude from" parameter
     can apply to a given module; if you have multiple exclude-from files, you
-    can specify them as a merge file in the "filter" parameter.  See the
-    "filter" parameter for a description of how excluded files affect the
+    can specify them as a merge file in the "[filter](#)" parameter.  See the
+    "[filter](#)" parameter for a description of how excluded files affect the
     daemon.
 
 0.  `include from`
 
-    Analogue of "exclude from" for a file of daemon include patterns.  Only one
-    "include from" parameter can apply to a given module.  See the "filter"
+    Analogue of "[exclude from](#)" for a file of daemon include patterns.  Only one
+    "include from" parameter can apply to a given module.  See the "[filter](#)"
     parameter for a description of how excluded files affect the daemon.
 
 0.  `incoming chmod`
@@ -611,7 +641,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     to supply a username and password to connect to the module. A challenge
     response authentication protocol is used for this exchange. The plain text
     usernames and passwords are stored in the file specified by the
-    "secrets file" parameter. The default is for all users to be able to
+    "[secrets file](#)" parameter. The default is for all users to be able to
     connect without a password (this is called "anonymous rsync").
 
     In addition to username matching, you can specify groupname matching via a
@@ -623,7 +653,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     Finally, options may be specified after a colon (:).  The options allow you
     to "deny" a user or a group, set the access to "ro" (read-only), or set the
     access to "rw" (read/write).  Setting an auth-rule-specific ro/rw setting
-    overrides the module's "read only" setting.
+    overrides the module's "[read only](#)" setting.
 
     Be sure to put the rules in the order you want them to be matched, because
     the checking stops at the first matching user or group, and that is the
@@ -661,7 +691,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 
     This parameter specifies the name of a file that contains the
     username:password and/or @groupname:password pairs used for authenticating
-    this module. This file is only consulted if the "auth users" parameter is
+    this module. This file is only consulted if the "[auth users](#)" parameter is
     specified.  The file is line-based and contains one name:password pair per
     line.  Any line has a hash (#) as the very first character on the line is
     considered a comment and is skipped.  The passwords can contain any
@@ -675,14 +705,14 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     "@groupname:password" line for the group that triggered the authentication.
 
     It is up to you what kind of password entries you want to include, either
-    users, groups, or both.  The use of group rules in "auth users" does not
+    users, groups, or both.  The use of group rules in "[auth users](#)" does not
     require that you specify a group password if you do not want to use shared
     passwords.
 
     There is no default for the "secrets file" parameter, you must choose a
     name (such as `/etc/rsyncd.secrets`).  The file must normally not be
-    readable by "other"; see "strict modes".  If the file is not found or is
-    rejected, no logins for a "user auth" module will be possible.
+    readable by "other"; see "[strict modes](#)".  If the file is not found or is
+    rejected, no logins for an "[auth users](#)" module will be possible.
 
 0.  `strict modes`
 
@@ -714,11 +744,11 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
       addresses which match the masked IP address will be allowed in.
     - a hostname pattern using wildcards. If the hostname of the connecting IP
       (as determined by a reverse lookup) matches the wildcarded name (using
-      the same rules as normal unix filename matching), the client is allowed
-      in.  This only works if "reverse lookup" is enabled (the default).
+      the same rules as normal Unix filename matching), the client is allowed
+      in.  This only works if "[reverse lookup](#)" is enabled (the default).
     - a hostname. A plain hostname is matched against the reverse DNS of the
-      connecting IP (if "reverse lookup" is enabled), and/or the IP of the
-      given hostname is matched against the connecting IP (if "forward lookup"
+      connecting IP (if "[reverse lookup](#)" is enabled), and/or the IP of the
+      given hostname is matched against the connecting IP (if "[forward lookup](#)"
       is enabled, as it is by default).  Any match will be allowed in.
     - an '@' followed by a netgroup name, which will match if the reverse DNS
       of the connecting IP is in the specified netgroup.
@@ -730,11 +760,11 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     >     fe80::%link1/64
     >     fe80::%link1/ffff:ffff:ffff:ffff::
 
-    You can also combine "hosts allow" with "hosts deny" as a way to add
+    You can also combine "hosts allow" with "[hosts deny](#)" as a way to add
     exceptions to your deny list.  When both parameters are specified, the
     "hosts allow" parameter is checked first and a match results in the client
     being able to connect.  A non-allowed host is then matched against the
-    "hosts deny" list to see if it should be rejected.  A host that does not
+    "[hosts deny](#)" list to see if it should be rejected.  A host that does not
     match either list is allowed to connect.
 
     The default is no "hosts allow" parameter, which means all hosts can
@@ -745,7 +775,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     This parameter allows you to specify a list of comma- and/or
     whitespace-separated patterns that are matched against a connecting clients
     hostname and IP address. If the pattern matches then the connection is
-    rejected. See the "hosts allow" parameter for more information.
+    rejected. See the "[hosts allow](#)" parameter for more information.
 
     The default is no "hosts deny" parameter, which means all hosts can
     connect.
@@ -753,8 +783,8 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 0.  `reverse lookup`
 
     Controls whether the daemon performs a reverse lookup on the client's IP
-    address to determine its hostname, which is used for "hosts allow" &
-    "hosts deny" checks and the "%h" log escape.  This is enabled by default,
+    address to determine its hostname, which is used for "[hosts allow](#)" &
+    "[hosts deny](#)" checks and the "%h" log escape.  This is enabled by default,
     but you may wish to disable it to save time if you know the lookup will not
     return a useful result, in which case the daemon will use the name
     "UNDETERMINED" instead.
@@ -794,7 +824,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     logs the transfer at the end, so if a transfer is aborted, no mention will
     be made in the log file.
 
-    If you want to customize the log lines, see the "log format" parameter.
+    If you want to customize the log lines, see the "[log format](#)" parameter.
 
 0.  `log format`
 
@@ -811,7 +841,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     (e.g. "`%''l %'b %f`").
 
     The default log format is "`%o %h [%a] %m (%u) %f %l`", and a "`%t [%p] `"
-    is always prefixed when using the "log file" parameter.  (A perl script
+    is always prefixed when using the "[log file](#)" parameter.  (A perl script
     that will summarize this default log format is included in the rsync source
     code distribution in the "support" subdirectory: rsyncstats.)
 
@@ -892,7 +922,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     >     refuse options = * !a !v !compress*
 
     Don't worry that the "`*`" will refuse certain vital options such as
-    `--dry-run`, `--server`, `--no-iconv`, `--protect-args`, etc. These
+    `--dry-run`, `--server`, `--no-iconv`, `--seclude-args`, etc. These
     important options are not matched by wild-card, so they must be overridden
     by their exact name.  For instance, if you're forcing iconv transfers you
     could use something like this:
@@ -922,17 +952,19 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 
     >     refuse options = * !a !delete* delete-after
 
-    A note on refusing "compress" -- it is better to set the "dont compress"
-    daemon parameter to "`*`" because that disables compression silently
+    A note on refusing "compress": it may be better to set the "[dont compress](#)"
+    daemon parameter to "`*`" and ensure that `RSYNC_COMPRESS_LIST=zlib` is set
+    in the environment of the daemon in order to disable compression silently
     instead of returning an error that forces the client to remove the `-z`
     option.
 
-    If you are un-refusing the compress option, you probably want to match
-    "`!compress*`" so that you also accept the `--compress-level` option.
+    If you are un-refusing the compress option, you may want to match
+    "`!compress*`" if you also want to allow the `--compress-level` option.
 
-    Note that the "write-devices" option is refused by default, but can be
-    explicitly accepted with "`!write-devices`".  The options "log-file" and
-    "log-file-format" are forcibly refused and cannot be accepted.
+    Note that the "copy-devices" & "write-devices" options are refused by
+    default, but they can be explicitly accepted with "`!copy-devices`" and/or
+    "`!write-devices`".  The options "log-file" and "log-file-format" are
+    forcibly refused and cannot be accepted.
 
     Here are all the options that are not matched by wild-cards:
 
@@ -942,18 +974,22 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
       receiver.  While rsync passes the older alias `--log-format` for
       compatibility reasons, this options should not be confused with
       `--log-file-format`.
-    - `--sender`: Use "write only" parameter instead of refusing this.
+    - `--sender`: Use "[write only](#)" parameter instead of refusing this.
     - `--dry-run`, `-n`: Who would want to disable this?
-    - `--protect-args`, `-s`: This actually makes transfers safer.
+    - `--seclude-args`, `-s`: Is the oldest arg-protection method.
     - `--from0`, `-0`: Makes it easier to accept/refuse `--files-from` without
       affecting this helpful modifier.
-    - `--iconv`: This is auto-disabled based on "charset" parameter.
+    - `--iconv`: This is auto-disabled based on "[charset](#)" parameter.
     - `--no-iconv`: Most transfers use this option.
     - `--checksum-seed`: Is a fairly rare, safe option.
     - `--write-devices`: Is non-wild but also auto-disabled.
 
 0.  `dont compress`
 
+    **NOTE:** This parameter currently has no effect except in one instance: if
+    it is set to "`*`" then it minimizes or disables compression for all files
+    (for those that don't want to refuse the `--compress` option completely).
+
     This parameter allows you to select filenames based on wildcard patterns
     that should not be compressed when pulling files from the daemon (no
     analogous parameter exists to govern the pushing of files to a daemon).
@@ -964,14 +1000,14 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     The "dont compress" parameter takes a space-separated list of
     case-insensitive wildcard patterns. Any source filename matching one of the
     patterns will be compressed as little as possible during the transfer.  If
-    the compression algorithm has an "off" level (such as zlib/zlibx) then no
-    compression occurs for those files.  Other algorithms have the level
-    minimized to reduces the CPU usage as much as possible.
+    the compression algorithm has an "off" level, then no compression occurs
+    for those files.  If an algorithms has the ability to change the level in
+    mid-stream, it will be minimized to reduce the CPU usage as much as
+    possible.
 
     See the `--skip-compress` parameter in the **rsync**(1) manpage for the
-    list of file suffixes that are not compressed by default.  Specifying a
-    value for the "dont compress" parameter changes the default when the daemon
-    is the sender.
+    list of file suffixes that are skipped by default if this parameter is not
+    set.
 
 0.  `early exec`, `pre-xfer exec`, `post-xfer exec`
 
@@ -1033,7 +1069,7 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
     **system()** call's default shell), and use RSYNC_NO_XFER_EXEC to disable
     both options completely.
 
-# CONFIG DIRECTIVES
+## CONFIG DIRECTIVES
 
 There are currently two config directives available that allow a config file to
 incorporate the contents of other files:  `&include` and `&merge`.  Both allow
@@ -1088,7 +1124,7 @@ This would merge any `/etc/rsyncd.d/*.inc` files (for global values that should
 stay in effect), and then include any `/etc/rsyncd.d/*.conf` files (defining
 modules without any global-value cross-talk).
 
-# AUTHENTICATION STRENGTH
+## AUTHENTICATION STRENGTH
 
 The authentication protocol used in rsync is a 128 bit MD4 based challenge
 response system. This is fairly weak protection, though (with at least one
@@ -1103,18 +1139,18 @@ authentication is provided. Use ssh as the transport if you want encryption.
 You can also make use of SSL/TLS encryption if you put rsync behind an
 SSL proxy.
 
-# SSL/TLS Daemon Setup
+## SSL/TLS Daemon Setup
 
 When setting up an rsync daemon for access via SSL/TLS, you will need to
-configure a proxy (such as haproxy or nginx) as the front-end that handles the
-encryption.
+configure a TCP proxy (such as haproxy or nginx) as the front-end that handles
+the encryption.
 
 - You should limit the access to the backend-rsyncd port to only allow the
   proxy to connect.  If it is on the same host as the proxy, then configuring
   it to only listen on localhost is a good idea.
-- You should consider turning on the `proxy protocol` parameter if your proxy
-  supports sending that information.  The examples below assume that this is
-  enabled.
+- You should consider turning on the `proxy protocol` rsync-daemon parameter if
+  your proxy supports sending that information.  The examples below assume that
+  this is enabled.
 
 An example haproxy setup is as follows:
 
@@ -1141,14 +1177,14 @@ An example nginx proxy setup is as follows:
 >        ssl_certificate_key /etc/letsencrypt/example.com/privkey.pem;
 >
 >        proxy_pass localhost:873;
->        proxy_protocol on; # Requires "proxy protocol = true"
+>        proxy_protocol on; # Requires rsyncd.conf "proxy protocol = true"
 >        proxy_timeout 1m;
 >        proxy_connect_timeout 5s;
 >    }
 > }
 > ```
 
-# EXAMPLES
+## DAEMON CONFIG EXAMPLES
 
 A simple rsyncd.conf file that allow anonymous rsync to a ftp area at
 `/home/ftp` would be:
@@ -1197,46 +1233,41 @@ The /etc/rsyncd.secrets file would look something like this:
 >     tridge:mypass
 >     susan:herpass
 
-# FILES
+## FILES
 
 /etc/rsyncd.conf or rsyncd.conf
 
-# SEE ALSO
+## SEE ALSO
 
-**rsync**(1), **rsync-ssl**(1)
+[**rsync**(1)](rsync.1), [**rsync-ssl**(1)](rsync-ssl.1)
 
-# BUGS
+## BUGS
 
 Please report bugs! The rsync bug tracking system is online at
 <https://rsync.samba.org/>.
 
-# VERSION
-
-This man page is current for version @VERSION@ of rsync.
-
-# CREDITS
-
-rsync is distributed under the GNU General Public License.  See the file
-COPYING for details.
+## VERSION
 
-The primary ftp site for rsync is <ftp://rsync.samba.org/pub/rsync>
+This manpage is current for version @VERSION@ of rsync.
 
-A web site is available at <https://rsync.samba.org/>.
+## CREDITS
 
-We would be delighted to hear from you if you like this program.
+Rsync is distributed under the GNU General Public License.  See the file
+[COPYING](COPYING) for details.
 
-This program uses the zlib compression library written by Jean-loup Gailly and
-Mark Adler.
+An rsync web site is available at <https://rsync.samba.org/> and its github
+project is <https://github.com/WayneD/rsync>.
 
-# THANKS
+## THANKS
 
 Thanks to Warren Stanley for his original idea and patch for the rsync daemon.
 Thanks to Karsten Thygesen for his many suggestions and documentation!
 
-# AUTHOR
+## AUTHOR
 
-rsync was written by Andrew Tridgell and Paul Mackerras.  Many people have
-later contributed to it.
+Rsync was originally written by Andrew Tridgell and Paul Mackerras.  Many
+people have later contributed to it. It is currently maintained by Wayne
+Davison.
 
 Mailing lists for support and development are available at
 <https://lists.samba.org/>.
index ecb383e..0c463be 100755 (executable)
@@ -1,7 +1,7 @@
 #! /bin/sh
 
 # Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
-# Copyright (C) 2003-2020 Wayne Davison
+# Copyright (C) 2003-2022 Wayne Davison
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version
@@ -155,7 +155,7 @@ if test x"$TOOLDIR" = x; then
     TOOLDIR=`pwd`
 fi
 srcdir=`dirname $0`
-if test x"$srcdir" = x -o x"$srcdir" = x.; then
+if test x"$srcdir" = x || test x"$srcdir" = x.; then
     srcdir="$TOOLDIR"
 fi
 if test x"$rsync_bin" = x; then
@@ -167,10 +167,10 @@ RSYNC="$rsync_bin $*"
 #RSYNC="valgrind $rsync_bin $*"
 
 TLS_ARGS=''
-if egrep '^#define HAVE_LUTIMES 1' config.h >/dev/null; then
+if grep -E '^#define HAVE_LUTIMES 1' config.h >/dev/null; then
     TLS_ARGS="$TLS_ARGS -l"
 fi
-if egrep '#undef CHOWN_MODIFIES_SYMLINK' config.h >/dev/null; then
+if grep -E '#undef CHOWN_MODIFIES_SYMLINK' config.h >/dev/null; then
     TLS_ARGS="$TLS_ARGS -L"
 fi
 
@@ -226,6 +226,8 @@ if [ ! -d "$srcdir" ]; then
     exit 2
 fi
 
+expect_skipped="${RSYNC_EXPECT_SKIPPED-IGNORE}"
+skipped_list=''
 skipped=0
 missing=0
 passed=0
@@ -236,7 +238,7 @@ failed=0
 # failure to aid investigation.  We don't remove the testtmp subdir at
 # the end so that it can be configured as a symlink to a filesystem that
 # has ACLs and xattr support enabled (if desired).
-scratchbase="$TOOLDIR"/testtmp
+scratchbase="${scratchbase:-$TOOLDIR}"/testtmp
 echo "    scratchbase=$scratchbase"
 [ -d "$scratchbase" ] || mkdir "$scratchbase"
 
@@ -265,10 +267,12 @@ maybe_discard_scratch() {
 
 if [ "x$whichtests" = x ]; then
     whichtests="*.test"
+    full_run=yes
+else
+    full_run=no
 fi
 
-for testscript in $suitedir/$whichtests
-do
+for testscript in $suitedir/$whichtests; do
     testbase=`echo $testscript | sed -e 's!.*/!!' -e 's/.test\$//'`
     scratchdir="$scratchbase/$testbase"
 
@@ -284,7 +288,7 @@ do
     result=$?
     set -e
 
-    if [ "x$always_log" = xyes -o \( $result != 0 -a $result != 77 -a $result != 78 \) ]
+    if [ "x$always_log" = xyes ] || ( [ $result != 0 ] && [ $result != 77 ] && [ $result != 78 ] )
     then
        echo "----- $testbase log follows"
        cat "$scratchdir/test.log"
@@ -306,6 +310,7 @@ do
        # backticks will fill the whole file onto one line, which is a feature
        whyskipped=`cat "$scratchdir/whyskipped"`
        echo "SKIP    $testbase ($whyskipped)"
+       skipped_list="$skipped_list,$testbase"
        skipped=`expr $skipped + 1`
        maybe_discard_scratch
        ;;
@@ -331,6 +336,15 @@ echo "      $passed passed"
 [ "$failed" -gt 0 ]  && echo "      $failed failed"
 [ "$skipped" -gt 0 ] && echo "      $skipped skipped"
 [ "$missing" -gt 0 ] && echo "      $missing missing"
+if [ "$full_run" = yes ] && [ "$expect_skipped" != IGNORE ]; then
+    skipped_list=`echo "$skipped_list" | sed 's/^,//'`
+    echo "----- skipped results:"
+    echo "      expected: $expect_skipped"
+    echo "      got:      $skipped_list"
+else
+    skipped_list=''
+    expect_skipped=''
+fi
 echo '------------------------------------------------------------'
 
 # OK, so expr exits with 0 if the result is neither null nor zero; and
@@ -339,7 +353,7 @@ echo '------------------------------------------------------------'
 # because -e is set.
 
 result=`expr $failed + $missing || true`
-if [ "$result" = 0 -a "$skipped" -gt "${RSYNC_MAX_SKIPPED:-9999}" ]; then
+if [ "$result" = 0 ] && [ "$skipped_list" != "$expect_skipped" ]; then
     result=1
 fi
 echo "overall result is $result"
index 94761c2..3d4f052 100644 (file)
--- a/sender.c
+++ b/sender.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -25,6 +25,7 @@
 extern int do_xfers;
 extern int am_server;
 extern int am_daemon;
+extern int local_server;
 extern int inc_recurse;
 extern int log_before_transfer;
 extern int stdout_format_has_i;
@@ -35,7 +36,9 @@ extern int append_mode;
 extern int copy_links;
 extern int io_error;
 extern int flist_eof;
+extern int whole_file;
 extern int allowed_lull;
+extern int copy_devices;
 extern int preserve_xattrs;
 extern int protocol_version;
 extern int remove_source_files;
@@ -49,6 +52,7 @@ extern int file_old_total;
 extern BOOL want_progress_now;
 extern struct stats stats;
 extern struct file_list *cur_flist, *first_flist, *dir_flist;
+extern char num_dev_ino_buf[4 + 8 + 8];
 
 BOOL extra_flist_sending_enabled;
 
@@ -142,6 +146,13 @@ void successful_send(int ndx)
                goto failed;
        }
 
+       if (local_server
+        && (int64)st.st_dev == IVAL64(num_dev_ino_buf, 4)
+        && (int64)st.st_ino == IVAL64(num_dev_ino_buf, 4 + 8)) {
+               rprintf(FERROR_XFER, "ERROR: Skipping sender remove of destination file: %s\n", fname);
+               return;
+       }
+
        if (st.st_size != F_LENGTH(file) || st.st_mtime != file->modtime
 #ifdef ST_MTIME_NSEC
         || (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file))
@@ -204,6 +215,9 @@ void send_files(int f_in, int f_out)
        if (DEBUG_GTE(SEND, 1))
                rprintf(FINFO, "send_files starting\n");
 
+       if (whole_file < 0)
+               whole_file = 0;
+
        progress_init();
 
        while (1) {
@@ -362,6 +376,25 @@ void send_files(int f_in, int f_out)
                        exit_cleanup(RERR_FILEIO);
                }
 
+               if (IS_DEVICE(st.st_mode)) {
+                       if (!copy_devices) {
+                               rprintf(FERROR, "attempt to copy device contents without --copy-devices\n");
+                               exit_cleanup(RERR_PROTOCOL);
+                       }
+                       if (st.st_size == 0)
+                               st.st_size = get_device_size(fd, fname);
+               }
+
+               if (append_mode > 0 && st.st_size < F_LENGTH(file)) {
+                       rprintf(FWARNING, "skipped diminished file: %s\n",
+                               full_fname(fname));
+                       free_sums(s);
+                       close(fd);
+                       if (protocol_version >= 30)
+                               send_msg_int(MSG_NO_SEND, ndx);
+                       continue;
+               }
+
                if (st.st_size) {
                        int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE);
                        mbuf = map_file(fd, st.st_size, read_size, s->blength);
diff --git a/simd-checksum-avx2.S b/simd-checksum-avx2.S
new file mode 100644 (file)
index 0000000..549cc3e
--- /dev/null
@@ -0,0 +1,177 @@
+#include "config.h"
+
+#ifdef USE_ROLL_ASM /* { */
+
+#define CHAR_OFFSET 0 /* Keep this the same as rsync.h, which isn't likely to change. */
+
+#ifdef __APPLE__
+#define get_checksum1_avx2_asm  _get_checksum1_avx2_asm
+#endif
+
+.intel_syntax noprefix
+.text
+
+       .p2align 5
+       .globl get_checksum1_avx2_asm
+
+# rdi=*buf, esi=len, edx=i, rcx= *ps1, r8= *ps2
+get_checksum1_avx2_asm:
+       vmovd   xmm6,[rcx] # load *ps1
+       lea     eax, [rsi-128] # at least 128 bytes to process?
+       cmp     edx, eax
+       jg      .exit
+       lea     rax, .mul_T2[rip]
+       vmovntdqa ymm7, [rax]   # load T2 multiplication constants
+       vmovntdqa ymm12,[rax+32]# from memory.
+       vpcmpeqd  ymm15, ymm15, ymm15 # set all elements to -1.
+
+#if CHAR_OFFSET != 0
+       mov     eax, 32*CHAR_OFFSET
+       vmovd   xmm10, eax
+       vpbroadcastd    ymm10, xmm10
+       mov     eax, 528*CHAR_OFFSET
+       vmovd   xmm13, eax
+       vpbroadcastd ymm13, xmm13
+#endif
+       vpabsb  ymm15, ymm15  # set all byte size elements to 1.
+       add     rdi, rdx
+       vmovdqu ymm2, [rdi]   # preload the first 64 bytes.
+       vmovdqu ymm3, [rdi+32]
+       and     esi, ~63   # only needed during final reduction, 
+                          # done here to avoid a longer nop for 
+                          # alignment below.
+       add     edx, esi
+       shr     rsi, 6     # longer opcode for alignment
+       add     rdi, 64
+       vpxor   xmm1, xmm1, xmm1 # reset both partial sums accumulators.
+       vpxor   xmm4, xmm4, xmm4
+       mov     eax, [r8]
+       .p2align 4              # should fit into the LSD allocation queue.
+.loop:
+       vpmaddubsw      ymm0, ymm15, ymm2  # s1 partial sums
+       vpmaddubsw      ymm5, ymm15, ymm3 
+       vmovdqu ymm8,  [rdi]    # preload the next 
+       vmovdqu ymm9,  [rdi+32] # 64 bytes.
+       add     rdi, 64
+       vpaddd  ymm4, ymm4, ymm6
+       vpaddw  ymm5, ymm5, ymm0
+       vpsrld  ymm0, ymm5, 16
+       vpaddw  ymm5, ymm0, ymm5
+       vpaddd  ymm6, ymm5, ymm6
+       vpmaddubsw      ymm2, ymm7, ymm2  # s2 partial sums
+       vpmaddubsw      ymm3, ymm12, ymm3
+       prefetcht0      [rdi+384] # prefetch 6 cachelines ahead.
+       vpaddw  ymm3, ymm2, ymm3
+       vpsrldq ymm2, ymm3, 2
+       vpaddd  ymm3, ymm2, ymm3
+       vpaddd  ymm1, ymm1, ymm3
+
+#if CHAR_OFFSET != 0
+       vpaddd ymm6, ymm10, ymm6  #  32*CHAR_OFFSET
+       vpaddd ymm1, ymm13, ymm1  # 528*CHAR_OFFSET
+#endif
+       vmovdqa ymm2, ymm8   # move the next 64 bytes 
+       vmovdqa ymm3, ymm9   # into the right registers
+       sub     esi, 1
+       jnz     .loop
+
+       # now we reduce the partial sums.
+       vpslld  ymm3, ymm4, 6
+       vpsrldq ymm2, ymm6, 4
+       
+       vpaddd  ymm0, ymm3, ymm1
+       vpaddd  ymm6, ymm2, ymm6
+       vpsrlq  ymm3, ymm0, 32
+       
+       vpsrldq ymm2, ymm6, 8
+       vpaddd  ymm0, ymm3, ymm0
+       vpsrldq ymm3, ymm0, 8
+       vpaddd  ymm6, ymm2, ymm6
+       vpaddd  ymm0, ymm3, ymm0
+       vextracti128    xmm2, ymm6, 0x1
+       vextracti128    xmm1, ymm0, 0x1
+       vpaddd  xmm6, xmm2, xmm6
+       vmovd   [rcx], xmm6
+       vpaddd  xmm1, xmm1, xmm0
+       vmovd   ecx, xmm1
+       add     eax, ecx
+       mov     [r8], eax
+.exit:
+       vzeroupper
+       mov     eax, edx
+       ret
+
+#ifdef __APPLE__
+.data
+       .align 6
+#else
+.section       .rodata
+       .p2align 6 
+#endif
+.mul_T2: 
+       .byte 64
+       .byte 63
+       .byte 62
+       .byte 61
+       .byte 60
+       .byte 59
+       .byte 58
+       .byte 57
+       .byte 56
+       .byte 55
+       .byte 54
+       .byte 53
+       .byte 52
+       .byte 51
+       .byte 50
+       .byte 49
+       .byte 48
+       .byte 47
+       .byte 46
+       .byte 45
+       .byte 44
+       .byte 43
+       .byte 42
+       .byte 41
+       .byte 40
+       .byte 39
+       .byte 38
+       .byte 37
+       .byte 36
+       .byte 35
+       .byte 34
+       .byte 33
+       .byte 32
+       .byte 31
+       .byte 30
+       .byte 29
+       .byte 28
+       .byte 27
+       .byte 26
+       .byte 25
+       .byte 24
+       .byte 23
+       .byte 22
+       .byte 21
+       .byte 20
+       .byte 19
+       .byte 18
+       .byte 17
+       .byte 16
+       .byte 15
+       .byte 14
+       .byte 13
+       .byte 12
+       .byte 11
+       .byte 10
+       .byte 9
+       .byte 8
+       .byte 7
+       .byte 6
+       .byte 5
+       .byte 4
+       .byte 3
+       .byte 2
+       .byte 1
+
+#endif /* } USE_ROLL_ASM */
index a1f5c50..33f26e9 100644 (file)
  * GCC 4.x are not supported to ease configure.ac logic.
  */
 
-#ifdef __x86_64__
-#ifdef __cplusplus
+#ifdef __x86_64__ /* { */
+#ifdef __cplusplus /* { */
 
 #include "rsync.h"
 
-#ifdef HAVE_SIMD
+#ifdef USE_ROLL_SIMD /* { */
 
 #include <immintrin.h>
 
@@ -85,7 +85,9 @@ typedef long long __m256i_u __attribute__((__vector_size__(32), __may_alias__, _
 #define SSE2_HADDS_EPI16(a, b) _mm_adds_epi16(SSE2_INTERLEAVE_EVEN_EPI16(a, b), SSE2_INTERLEAVE_ODD_EPI16(a, b))
 #define SSE2_MADDUBS_EPI16(a, b) _mm_adds_epi16(SSE2_MULU_EVEN_EPI8(a, b), SSE2_MULU_ODD_EPI8(a, b))
 
+#ifndef USE_ROLL_ASM
 __attribute__ ((target("default"))) MVSTATIC int32 get_checksum1_avx2_64(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2) { return i; }
+#endif
 __attribute__ ((target("default"))) MVSTATIC int32 get_checksum1_ssse3_32(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2) { return i; }
 __attribute__ ((target("default"))) MVSTATIC int32 get_checksum1_sse2_32(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2) { return i; }
 
@@ -311,6 +313,12 @@ __attribute__ ((target("sse2"))) MVSTATIC int32 get_checksum1_sse2_32(schar* buf
     return i;
 }
 
+#ifdef USE_ROLL_ASM /* { */
+
+extern "C" __attribute__ ((target("avx2"))) int32 get_checksum1_avx2_asm(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2);
+
+#else /* } { */
+
 /*
   AVX2 loop per 64 bytes:
     int16 t1[16];
@@ -326,113 +334,107 @@ __attribute__ ((target("sse2"))) MVSTATIC int32 get_checksum1_sse2_32(schar* buf
     s1 += (uint32)(t1[0] + t1[1] + t1[2] + t1[3] + t1[4] + t1[5] + t1[6] + t1[7] + t1[8] + t1[9] + t1[10] + t1[11] + t1[12] + t1[13] + t1[14] + t1[15]) +
           64*CHAR_OFFSET;
  */
+
 __attribute__ ((target("avx2"))) MVSTATIC int32 get_checksum1_avx2_64(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
 {
     if (len > 64) {
-        // Instructions reshuffled compared to SSE2 for slightly better performance
-        int aligned = ((uintptr_t)buf & 31) == 0;
 
-        uint32 x[8] = {0};
-        x[0] = *ps1;
-        __m256i ss1 = _mm256_lddqu_si256((__m256i_u*)x);
-        x[0] = *ps2;
-        __m256i ss2 = _mm256_lddqu_si256((__m256i_u*)x);
+        uint32 x[4] = {0};
+        __m128i ss1 = _mm_cvtsi32_si128(*ps1);
+        __m128i ss2 = _mm_cvtsi32_si128(*ps2);
 
-        // The order gets shuffled compared to SSE2
-        const int16 mul_t1_buf[16] = {60, 56, 52, 48, 28, 24, 20, 16, 44, 40, 36, 32, 12, 8, 4, 0};
-        __m256i mul_t1 = _mm256_lddqu_si256((__m256i_u*)mul_t1_buf);
+        const char mul_t1_buf[16] = {60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0};
+       __m128i tmp = _mm_load_si128((__m128i*) mul_t1_buf);
+        __m256i mul_t1 = _mm256_cvtepu8_epi16(tmp);
+       __m256i mul_const = _mm256_broadcastd_epi32(_mm_cvtsi32_si128(4 | (3 << 8) | (2 << 16) | (1 << 24)));
+        __m256i mul_one;
+                   mul_one = _mm256_abs_epi8(_mm256_cmpeq_epi16(mul_one,mul_one)); // set all vector elements to 1
 
         for (; i < (len-64); i+=64) {
-            // Load ... 2*[int8*32]
+            // Load ... 4*[int8*16]
             __m256i in8_1, in8_2;
-            if (!aligned) {
-                in8_1 = _mm256_lddqu_si256((__m256i_u*)&buf[i]);
-                in8_2 = _mm256_lddqu_si256((__m256i_u*)&buf[i + 32]);
-            } else {
-                in8_1 = _mm256_load_si256((__m256i_u*)&buf[i]);
-                in8_2 = _mm256_load_si256((__m256i_u*)&buf[i + 32]);
-            }
-
-            // Prefetch for next loops. This has no observable effect on the
-            // tested AMD but makes as much as 20% difference on the Intel.
-            // Curiously that same Intel sees no benefit from this with SSE2
-            // or SSSE3.
-            _mm_prefetch(&buf[i + 64], _MM_HINT_T0);
-            _mm_prefetch(&buf[i + 96], _MM_HINT_T0);
-            _mm_prefetch(&buf[i + 128], _MM_HINT_T0);
-            _mm_prefetch(&buf[i + 160], _MM_HINT_T0);
+           __m128i in8_1_low, in8_2_low, in8_1_high, in8_2_high;
+           in8_1_low = _mm_loadu_si128((__m128i_u*)&buf[i]);
+           in8_2_low = _mm_loadu_si128((__m128i_u*)&buf[i+16]);
+           in8_1_high = _mm_loadu_si128((__m128i_u*)&buf[i+32]);
+           in8_2_high = _mm_loadu_si128((__m128i_u*)&buf[i+48]);
+           in8_1 = _mm256_inserti128_si256(_mm256_castsi128_si256(in8_1_low), in8_1_high,1);
+           in8_2 = _mm256_inserti128_si256(_mm256_castsi128_si256(in8_2_low), in8_2_high,1);
 
-            // (1*buf[i] + 1*buf[i+1]), (1*buf[i+2], 1*buf[i+3]), ... 2*[int16*16]
+            // (1*buf[i] + 1*buf[i+1]), (1*buf[i+2], 1*buf[i+3]), ... 2*[int16*8]
             // Fastest, even though multiply by 1
-            __m256i mul_one = _mm256_set1_epi8(1);
             __m256i add16_1 = _mm256_maddubs_epi16(mul_one, in8_1);
             __m256i add16_2 = _mm256_maddubs_epi16(mul_one, in8_2);
 
-            // (4*buf[i] + 3*buf[i+1]), (2*buf[i+2], buf[i+3]), ... 2*[int16*16]
-            __m256i mul_const = _mm256_set1_epi32(4 + (3 << 8) + (2 << 16) + (1 << 24));
+            // (4*buf[i] + 3*buf[i+1]), (2*buf[i+2], buf[i+3]), ... 2*[int16*8]
             __m256i mul_add16_1 = _mm256_maddubs_epi16(mul_const, in8_1);
             __m256i mul_add16_2 = _mm256_maddubs_epi16(mul_const, in8_2);
 
             // s2 += 64*s1
-            ss2 = _mm256_add_epi32(ss2, _mm256_slli_epi32(ss1, 6));
+            ss2 = _mm_add_epi32(ss2, _mm_slli_epi32(ss1, 6));
 
-            // [t1[0] + t1[1], t1[2] + t1[3] ...] [int16*16]
-            __m256i add16 = _mm256_hadds_epi16(add16_1, add16_2);
+            // [sum(t1[0]..t1[7]), X, X, X] [int32*4]; faster than multiple _mm_hadds_epi16
+            __m256i sum_add32 = _mm256_add_epi16(add16_1, add16_2);
+            sum_add32 = _mm256_add_epi16(sum_add32, _mm256_srli_epi32(sum_add32, 16));
+            sum_add32 = _mm256_add_epi16(sum_add32, _mm256_srli_si256(sum_add32, 4));
+            sum_add32 = _mm256_add_epi16(sum_add32, _mm256_srli_si256(sum_add32, 8));
 
-            // [t1[0], t1[1], ...] -> [t1[0]*60 + t1[1]*56, ...] [int32*8]
-            __m256i mul32 = _mm256_madd_epi16(add16, mul_t1);
+            // [sum(t2[0]..t2[7]), X, X, X] [int32*4]; faster than multiple _mm_hadds_epi16
+            __m256i sum_mul_add32 = _mm256_add_epi16(mul_add16_1, mul_add16_2);
+            sum_mul_add32 = _mm256_add_epi16(sum_mul_add32, _mm256_srli_epi32(sum_mul_add32, 16));
+            sum_mul_add32 = _mm256_add_epi16(sum_mul_add32, _mm256_srli_si256(sum_mul_add32, 4));
+            sum_mul_add32 = _mm256_add_epi16(sum_mul_add32, _mm256_srli_si256(sum_mul_add32, 8));
 
-            // [sum(t1[0]..t1[15]), X, X, X, X, X, X, X] [int32*8]
-            __m256i sum_add32 = _mm256_add_epi16(add16_1, add16_2);
-            sum_add32 = _mm256_add_epi16(sum_add32, _mm256_permute4x64_epi64(sum_add32, 2 + (3 << 2) + (0 << 4) + (1 << 6)));
-            sum_add32 = _mm256_add_epi16(sum_add32, _mm256_slli_si256(sum_add32, 2));
-            sum_add32 = _mm256_add_epi16(sum_add32, _mm256_slli_si256(sum_add32, 4));
-            sum_add32 = _mm256_add_epi16(sum_add32, _mm256_slli_si256(sum_add32, 8));
-            sum_add32 = _mm256_srai_epi32(sum_add32, 16);
-            sum_add32 = _mm256_shuffle_epi32(sum_add32, 3);
+            // s1 += t1[0] + t1[1] + t1[2] + t1[3] + t1[4] + t1[5] + t1[6] + t1[7]
+           __m128i sum_add32_hi = _mm256_extracti128_si256(sum_add32, 0x1);
+            ss1 = _mm_add_epi32(ss1, _mm256_castsi256_si128(sum_add32));
+            ss1 = _mm_add_epi32(ss1, sum_add32_hi);
 
-            // s1 += t1[0] + t1[1] + t1[2] + t1[3] + t1[4] + t1[5] + t1[6] + t1[7] + t1[8] + t1[9] + t1[10] + t1[11] + t1[12] + t1[13] + t1[14] + t1[15]
-            ss1 = _mm256_add_epi32(ss1, sum_add32);
+            // s2 += t2[0] + t2[1] + t2[2] + t2[3] + t2[4] + t2[5] + t2[6] + t2[7]
+           __m128i sum_mul_add32_hi = _mm256_extracti128_si256(sum_mul_add32, 0x1);
+            ss2 = _mm_add_epi32(ss2, _mm256_castsi256_si128(sum_mul_add32));
+            ss2 = _mm_add_epi32(ss2, sum_mul_add32_hi);
 
-            // [sum(t2[0]..t2[15]), X, X, X, X, X, X, X] [int32*8]
-            __m256i sum_mul_add32 = _mm256_add_epi16(mul_add16_1, mul_add16_2);
-            sum_mul_add32 = _mm256_add_epi16(sum_mul_add32, _mm256_permute4x64_epi64(sum_mul_add32, 2 + (3 << 2) + (0 << 4) + (1 << 6)));
-            sum_mul_add32 = _mm256_add_epi16(sum_mul_add32, _mm256_slli_si256(sum_mul_add32, 2));
-            sum_mul_add32 = _mm256_add_epi16(sum_mul_add32, _mm256_slli_si256(sum_mul_add32, 4));
-            sum_mul_add32 = _mm256_add_epi16(sum_mul_add32, _mm256_slli_si256(sum_mul_add32, 8));
-            sum_mul_add32 = _mm256_srai_epi32(sum_mul_add32, 16);
-            sum_mul_add32 = _mm256_shuffle_epi32(sum_mul_add32, 3);
-
-            // s2 += t2[0] + t2[1] + t2[2] + t2[3] + t2[4] + t2[5] + t2[6] + t2[7] + t2[8] + t2[9] + t2[10] + t2[11] + t2[12] + t2[13] + t2[14] + t2[15]
-            ss2 = _mm256_add_epi32(ss2, sum_mul_add32);
-
-            // [sum(mul32), X, X, X, X, X, X, X] [int32*8]
-            mul32 = _mm256_add_epi32(mul32, _mm256_permute2x128_si256(mul32, mul32, 1));
+            // [t1[0] + t1[1], t1[2] + t1[3] ...] [int16*8]
+            // We could've combined this with generating sum_add32 above and
+            // save an instruction but benchmarking shows that as being slower
+            __m256i add16 = _mm256_hadds_epi16(add16_1, add16_2);
+
+            // [t1[0], t1[1], ...] -> [t1[0]*28 + t1[1]*24, ...] [int32*4]
+            __m256i mul32 = _mm256_madd_epi16(add16, mul_t1);
+
+            // [sum(mul32), X, X, X] [int32*4]; faster than multiple _mm_hadd_epi32
             mul32 = _mm256_add_epi32(mul32, _mm256_srli_si256(mul32, 4));
             mul32 = _mm256_add_epi32(mul32, _mm256_srli_si256(mul32, 8));
+           // prefetch 2 cacheline ahead
+            _mm_prefetch(&buf[i + 160], _MM_HINT_T0);
 
-            // s2 += 60*t1[0] + 56*t1[1] + 52*t1[2] + 48*t1[3] + 44*t1[4] + 40*t1[5] + 36*t1[6] + 32*t1[7] + 28*t1[8] + 24*t1[9] + 20*t1[10] + 16*t1[11] + 12*t1[12] + 8*t1[13] + 4*t1[14]
-            ss2 = _mm256_add_epi32(ss2, mul32);
+            // s2 += 28*t1[0] + 24*t1[1] + 20*t1[2] + 16*t1[3] + 12*t1[4] + 8*t1[5] + 4*t1[6]
+           __m128i mul32_hi = _mm256_extracti128_si256(mul32, 0x1);
+            ss2 = _mm_add_epi32(ss2, _mm256_castsi256_si128(mul32));
+            ss2 = _mm_add_epi32(ss2, mul32_hi);
 
 #if CHAR_OFFSET != 0
-            // s1 += 64*CHAR_OFFSET
-            __m256i char_offset_multiplier = _mm256_set1_epi32(64 * CHAR_OFFSET);
-            ss1 = _mm256_add_epi32(ss1, char_offset_multiplier);
+            // s1 += 32*CHAR_OFFSET
+            __m128i char_offset_multiplier = _mm_set1_epi32(32 * CHAR_OFFSET);
+            ss1 = _mm_add_epi32(ss1, char_offset_multiplier);
 
-            // s2 += 2080*CHAR_OFFSET
-            char_offset_multiplier = _mm256_set1_epi32(2080 * CHAR_OFFSET);
-            ss2 = _mm256_add_epi32(ss2, char_offset_multiplier);
+            // s2 += 528*CHAR_OFFSET
+            char_offset_multiplier = _mm_set1_epi32(528 * CHAR_OFFSET);
+            ss2 = _mm_add_epi32(ss2, char_offset_multiplier);
 #endif
         }
 
-        _mm256_store_si256((__m256i_u*)x, ss1);
+        _mm_store_si128((__m128i_u*)x, ss1);
         *ps1 = x[0];
-        _mm256_store_si256((__m256i_u*)x, ss2);
+        _mm_store_si128((__m128i_u*)x, ss2);
         *ps2 = x[0];
     }
     return i;
 }
 
+#endif /* } !USE_ROLL_ASM */
+
 static int32 get_checksum1_default_1(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
 {
     uint32 s1 = *ps1;
@@ -459,7 +461,11 @@ static inline uint32 get_checksum1_cpp(char *buf1, int32 len)
     uint32 s2 = 0;
 
     // multiples of 64 bytes using AVX2 (if available)
+#ifdef USE_ROLL_ASM
+    i = get_checksum1_avx2_asm((schar*)buf1, len, i, &s1, &s2);
+#else
     i = get_checksum1_avx2_64((schar*)buf1, len, i, &s1, &s2);
+#endif
 
     // multiples of 32 bytes using SSSE3 (if available)
     i = get_checksum1_ssse3_32((schar*)buf1, len, i, &s1, &s2);
@@ -521,14 +527,18 @@ static int32 get_checksum1_auto(schar* buf, int32 len, int32 i, uint32* ps1, uin
 
 int main() {
     int i;
-    unsigned char* buf = (unsigned char*)malloc(BLOCK_LEN);
+    unsigned char* buf = (unsigned char*)aligned_alloc(64,BLOCK_LEN);
     for (i = 0; i < BLOCK_LEN; i++) buf[i] = (i + (i % 3) + (i % 11)) % 256;
 
     benchmark("Auto", get_checksum1_auto, (schar*)buf, BLOCK_LEN);
     benchmark("Raw-C", get_checksum1_default_1, (schar*)buf, BLOCK_LEN);
     benchmark("SSE2", get_checksum1_sse2_32, (schar*)buf, BLOCK_LEN);
     benchmark("SSSE3", get_checksum1_ssse3_32, (schar*)buf, BLOCK_LEN);
+#ifdef USE_ROLL_ASM
+    benchmark("AVX2-ASM", get_checksum1_avx2_asm, (schar*)buf, BLOCK_LEN);
+#else
     benchmark("AVX2", get_checksum1_avx2_64, (schar*)buf, BLOCK_LEN);
+#endif
 
     free(buf);
     return 0;
@@ -538,6 +548,6 @@ int main() {
 #pragma clang optimize on
 #endif /* BENCHMARK_SIMD_CHECKSUM1 */
 
-#endif /* HAVE_SIMD */
-#endif /* __cplusplus */
-#endif /* __x86_64__ */
+#endif /* } USE_ROLL_SIMD */
+#endif /* __cplusplus */
+#endif /* __x86_64__ */
index 0346fb4..1964090 100755 (executable)
@@ -1,92 +1,94 @@
-#!/usr/bin/env perl
-#
+#!/usr/bin/env python3
 # This script lets you update a hierarchy of files in an atomic way by
 # first creating a new hierarchy using rsync's --link-dest option, and
 # then swapping the hierarchy into place.  **See the usage message for
 # more details and some important caveats!**
 
-use strict;
-use warnings;
-use Cwd 'abs_path';
-
-my $RSYNC_PROG = '/usr/bin/rsync';
-my $RM_PROG = '/bin/rm';
-
-my $dest_dir = $ARGV[-1];
-&usage if !defined $dest_dir || $dest_dir =~ /(^-|^$)/ || grep(/^--help/, @ARGV);
-$dest_dir =~ s{(?<=.)/+$} {};
-
-if (!-d $dest_dir) {
-    die "$dest_dir is not a directory.\nUse --help for help.\n";
-}
-
-if (@_ = grep(/^--[a-z]+-dest\b/, @ARGV)) {
-    $_ = join(' or ', @_);
-    die "You cannot use the $_ option with atomic-rsync.\nUse --help for help.\n";
-}
-
-my $symlink_content = readlink $dest_dir; # undef when a real dir
-
-my $dest_arg = $dest_dir;
-# This gives us the real destination dir, with all symlinks dereferenced.
-$dest_dir = abs_path($dest_dir);
-if ($dest_dir eq '/') {
-    die qq|You must not use "/" as the destination directory.\nUse --help for help.\n|;
-}
-
-my($old_dir, $new_dir);
-if (defined $symlink_content && $dest_dir =~ /-([12])$/) {
-    my $num = 3 - $1;
-    $old_dir = undef;
-    ($new_dir = $dest_dir) =~ s/-[12]$/-$num/;
-    $symlink_content =~ s/-[12]$/-$num/;
-} else {
-    $old_dir = "$dest_dir~old~";
-    $new_dir = "$dest_dir~new~";
-}
-
-$ARGV[-1] = "$new_dir/";
-
-system($RM_PROG, '-rf', $old_dir) if defined $old_dir && -d $old_dir;
-system($RM_PROG, '-rf', $new_dir) if -d $new_dir;
-
-if (system($RSYNC_PROG, "--link-dest=$dest_dir", @ARGV)) {
-    if ($? == -1) {
-       print "failed to execute $RSYNC_PROG: $!\n";
-    } elsif ($? & 127) {
-       printf "child died with signal %d, %s coredump\n",
-           ($? & 127),  ($? & 128) ? 'with' : 'without';
-    } else {
-       printf "child exited with value %d\n", $? >> 8;
-    }
-    exit 1;
-}
-
-if (!defined $old_dir) {
-    atomic_symlink($symlink_content, $dest_arg);
-    exit;
-}
-
-rename($dest_dir, $old_dir) or die "Unable to rename $dest_dir to $old_dir: $!";
-rename($new_dir, $dest_dir) or die "Unable to rename $new_dir to $dest_dir: $!";
-
-exit;
-
-sub atomic_symlink
-{
-    my($target, $link) = @_;
-    my $newlink = "$link~new~";
-
-    unlink($newlink); # Just in case
-    symlink($target, $newlink) or die "Unable to symlink $newlink -> $target: $!\n";
-    rename($newlink, $link) or die "Unable to rename $newlink to $link: $!\n";
-}
-
-
-sub usage
-{
-    die <<EOT;
-Usage: atomic-rsync [RSYNC-OPTIONS] HOST:/SOURCE/DIR/ /DEST/DIR/
+import os, sys, re, subprocess, shutil
+
+ALT_DEST_ARG_RE = re.compile('^--[a-z][^ =]+-dest(=|$)')
+
+RSYNC_PROG = '/usr/bin/rsync'
+
+def main():
+    cmd_args = sys.argv[1:]
+    if '--help' in cmd_args:
+        usage_and_exit()
+
+    if len(cmd_args) < 2:
+        usage_and_exit(True)
+
+    dest_dir = cmd_args[-1].rstrip('/')
+    if dest_dir == '' or dest_dir.startswith('-'):
+        usage_and_exit(True)
+
+    if not os.path.isdir(dest_dir):
+        die(dest_dir, "is not a directory or a symlink to a dir.\nUse --help for help.")
+
+    bad_args = [ arg for arg in cmd_args if ALT_DEST_ARG_RE.match(arg) ]
+    if bad_args:
+        die("You cannot use the", ' or '.join(bad_args), "option with atomic-rsync.\nUse --help for help.")
+
+    # We ignore exit-code 24 (file vanished) by default.
+    allowed_exit_codes = '0 ' + os.environ.get('ATOMIC_RSYNC_OK_CODES', '24')
+    try:
+        allowed_exit_codes = set(int(num) for num in re.split(r'[, ]+', allowed_exit_codes) if num != '')
+    except ValueError:
+        die('Invalid integer in ATOMIC_RSYNC_OK_CODES:', allowed_exit_codes[2:])
+
+    symlink_content = os.readlink(dest_dir) if os.path.islink(dest_dir) else None
+
+    dest_arg = dest_dir
+    dest_dir = os.path.realpath(dest_dir) # The real destination dir with all symlinks dereferenced
+    if dest_dir == '/':
+        die('You must not use "/" as the destination directory.\nUse --help for help.')
+
+    old_dir = new_dir = None
+    if symlink_content is not None and dest_dir.endswith(('-1','-2')):
+        if not symlink_content.endswith(dest_dir[-2:]):
+            die("Symlink suffix out of sync with dest_dir name:", symlink_content, 'vs', dest_dir)
+        num = 3 - int(dest_dir[-1]);
+        old_dir = None
+        new_dir = dest_dir[:-1] + str(num)
+        symlink_content = symlink_content[:-1] + str(num)
+    else:
+        old_dir = dest_dir + '~old~'
+        new_dir = dest_dir + '~new~'
+
+    cmd_args[-1] = new_dir + '/'
+
+    if old_dir is not None and os.path.isdir(old_dir):
+        shutil.rmtree(old_dir)
+    if os.path.isdir(new_dir):
+        shutil.rmtree(new_dir)
+
+    child = subprocess.run([RSYNC_PROG, '--link-dest=' + dest_dir, *cmd_args])
+    if child.returncode not in allowed_exit_codes:
+        die('The rsync copy failed with code', child.returncode, exitcode=child.returncode)
+
+    if not os.path.isdir(new_dir):
+        die('The rsync copy failed to create:', new_dir)
+
+    if old_dir is None:
+        atomic_symlink(symlink_content, dest_arg)
+    else:
+        os.rename(dest_dir, old_dir)
+        os.rename(new_dir, dest_dir)
+
+
+def atomic_symlink(target, link):
+    newlink = link + "~new~"
+    try:
+        os.unlink(newlink); # Just in case
+    except OSError:
+        pass
+    os.symlink(target, newlink)
+    os.rename(newlink, link)
+
+
+def usage_and_exit(use_stderr=False):
+    usage_msg = """\
+Usage: atomic-rsync [RSYNC-OPTIONS] [HOST:]/SOURCE/DIR/ /DEST/DIR/
        atomic-rsync [RSYNC-OPTIONS] HOST::MOD/DIR/ /DEST/DIR/
 
 This script lets you update a hierarchy of files in an atomic way by first
@@ -96,27 +98,41 @@ to a local directory, and that directory must already exist.  For example:
 
     mkdir /local/files-1
     ln -s files-1 /local/files
-    atomic-rsync -av host:/remote/files/ /local/files/
+    atomic-rsync -aiv host:/remote/files/ /local/files/
 
-If /local/files is a symlink to a directory that ends in -1 or -2, the
-copy will go to the alternate suffix and the symlink will be changed to
-point to the new dir.  This is a fully atomic update.  If the destination
-is not a symlink (or not a symlink to a *-1 or a *-2 directory), this
-will instead create a directory with "~new~" suffixed, move the current
-directory to a name with "~old~" suffixed, and then move the ~new~
-directory to the original destination name (this double rename is not
-fully atomic, but is rapid).  In both cases, the prior destintaion
-directory will be preserved until the next update, at which point it
-will be deleted.
+If /local/files is a symlink to a directory that ends in -1 or -2, the copy
+will go to the alternate suffix and the symlink will be changed to point to
+the new dir.  This is a fully atomic update.  If the destination is not a
+symlink (or not a symlink to a *-1 or a *-2 directory), this will instead
+create a directory with "~new~" suffixed, move the current directory to a
+name with "~old~" suffixed, and then move the ~new~ directory to the original
+destination name (this double rename is not fully atomic, but is rapid).  In
+both cases, the prior destintaion directory will be preserved until the next
+update, at which point it will be deleted.
 
-In all likelihood, you do NOT want to specify this command:
+By default, rsync exit-code 24 (file vanished) is allowed without halting the
+atomic update.  If you want to change that, specify the environment variable
+ATOMIC_RSYNC_OK_CODES with numeric values separated by spaces and/or commas.
+Specify an empty string to only allow a successful copy.  An override example:
 
-    atomic-rsync -av host:/remote/files /local/
+    ATOMIC_RSYNC_OK_CODES='23 24' atomic-rsync -aiv host:src/ dest/
 
-... UNLESS you want the entire /local dir to be swapped out!
+See the errcode.h file for a list of all the exit codes.
 
 See the "rsync" command for its list of options.  You may not use the
 --link-dest, --compare-dest, or --copy-dest options (since this script
 uses --link-dest to make the transfer efficient).
-EOT
-}
+"""
+    print(usage_msg, file=sys.stderr if use_stderr else sys.stdout)
+    sys.exit(1 if use_stderr else 0)
+
+
+def die(*args, exitcode=1):
+    print(*args, file=sys.stderr)
+    sys.exit(exitcode)
+
+
+if __name__ == '__main__':
+    main()
+
+# vim: sw=4 et
index 51962d3..e06f073 100755 (executable)
@@ -27,17 +27,18 @@ def main():
 
     if not args.tree:
         # All modified files keep their current mtime.
-        proc = subprocess.Popen(git + 'ls-files -m -z'.split(), stdout=subprocess.PIPE, encoding='utf-8')
+        proc = subprocess.Popen(git + 'status -z --no-renames'.split(), stdout=subprocess.PIPE, encoding='utf-8')
         out = proc.communicate()[0]
         for fn in out.split('\0'):
-            if fn == '':
+            if fn == '' or (fn[0] != 'M' and fn[1] != 'M'):
                 continue
+            fn = fn[3:]
             if args.list:
                 mtime = os.lstat(fn).st_mtime
                 print_line(fn, mtime, mtime)
             ls.discard(fn)
 
-    cmd = git + 'log -r --name-only --no-color --pretty=raw --no-renames -z'.split()
+    cmd = git + 'log -r --name-only --format=%x00commit%x20%H%n%x00commit_time%x20%ct%n --no-renames -z'.split()
     if args.tree:
         cmd.append(args.tree)
     cmd += ['--'] + args.files
@@ -45,7 +46,7 @@ def main():
     proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, encoding='utf-8')
     for line in proc.stdout:
         line = line.strip()
-        m = re.match(r'^committer .*? (\d+) [-+]\d+$', line)
+        m = re.match(r'^\0commit_time (\d+)$', line)
         if m:
             commit_time = int(m[1])
         elif NULL_COMMIT_RE.search(line):
diff --git a/support/json-rsync-version b/support/json-rsync-version
new file mode 100755 (executable)
index 0000000..31fed7f
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/python3
+
+import sys, argparse, subprocess, json
+
+TWEAK_NAME = {
+        'asm': 'asm_roll',
+        'ASM': 'asm_roll',
+        'hardlink_special': 'hardlink_specials',
+        'protect_args': 'secluded_args',
+        'protected_args': 'secluded_args',
+        'SIMD': 'SIMD_roll',
+    }
+
+MOVE_OPTIM = set('asm_roll SIMD_roll'.split())
+
+def main():
+    if not args.rsync or args.rsync == '-':
+        ver_out = sys.stdin.read().strip()
+    else:
+        ver_out = subprocess.check_output([args.rsync, '--version', '--version'], encoding='utf-8').strip()
+    if ver_out.startswith('{'):
+        print(ver_out)
+        return
+    info = { }
+    misplaced_optims = { }
+    for line in ver_out.splitlines():
+        if line.startswith('rsync '):
+            prog, vstr, ver, pstr, vstr2, proto = line.split()
+            info['program'] = prog
+            if ver.startswith('v'):
+                ver = ver[1:]
+            info[vstr] = ver
+            if '.' not in proto:
+                proto += '.0'
+            else:
+                proto = proto.replace('.PR', '.')
+            info[pstr] = proto
+        elif line.startswith('Copyright '):
+            info['copyright'] = line[10:]
+        elif line.startswith('Web site: '):
+            info['url'] = line[10:]
+        elif line.startswith('  '):
+            if not saw_comma and ',' in line:
+                saw_comma = True
+                info[sect_name] = { }
+            if saw_comma:
+                for x in line.strip(' ,').split(', '):
+                    if ' ' in x:
+                        val, var = x.split(' ', 1)
+                        if val == 'no':
+                            val = False
+                        elif val.endswith('-bit'):
+                            var = var[:-1] + '_bits'
+                            val = int(val.split('-')[0])
+                    else:
+                        var = x
+                        val = True
+                    var = var.replace(' ', '_').replace('-', '_')
+                    if var in TWEAK_NAME:
+                        var = TWEAK_NAME[var]
+                    if sect_name[0] != 'o' and var in MOVE_OPTIM:
+                        misplaced_optims[var] = val
+                    else:
+                        info[sect_name][var] = val
+            else:
+                info[sect_name] += [ x for x in line.split() if not x.startswith('(') ]
+        elif line == '':
+            break
+        else:
+            sect_name = line.strip(' :').replace(' ', '_').lower()
+            info[sect_name] = [ ]
+            saw_comma = False
+    for chk in 'capabilities optimizations'.split():
+        if chk not in info:
+            info[chk] = { }
+    if misplaced_optims:
+        info['optimizations'].update(misplaced_optims)
+    for chk in 'checksum_list compress_list daemon_auth_list'.split():
+        if chk not in info:
+            info[chk] = [ ]
+    info['license'] = 'GPLv3' if ver[0] == '3' else 'GPLv2'
+    info['caveat'] = 'rsync comes with ABSOLUTELY NO WARRANTY'
+    print(json.dumps(info))
+
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description="Output rsync's version data in JSON format, even if the rsync doesn't support a native json-output method.", add_help=False)
+    parser.add_argument('rsync', nargs='?', help="Specify an rsync command to run. Otherwise stdin is consumed.")
+    parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
+    args = parser.parse_args()
+    main()
+
+# vim: sw=4 et
index be29310..7b3c065 100755 (executable)
@@ -15,6 +15,8 @@ GetOptions(
     'b|c|D|e|F|i|L|m|O|o|p|R|S|w=s' => sub { }, # Ignore
     'no-cd' => \( my $no_chdir ),
     'sudo' => \( my $use_sudo ),
+    'rrsync=s' => \( my $rrsync_dir ),
+    'rropts=s' => \( my $rrsync_opts ),
 ) or &usage;
 &usage unless @ARGV > 1;
 
@@ -67,22 +69,40 @@ unless ($no_chdir) {
     chdir $home_dir or die "Unable to chdir to $home_dir: $!\n";
 }
 
-push @cmd, '/bin/sh', '-c', "@ARGV";
+if ($rrsync_dir) {
+    $ENV{SSH_ORIGINAL_COMMAND} = join(' ', @ARGV);
+    push @cmd, 'rrsync';
+    if ($rrsync_opts) {
+       foreach my $opt (split(/[ ,]+/, $rrsync_opts)) {
+           $opt = "-$opt" unless $opt =~ /^-/;
+           push @cmd, $opt;
+       }
+    }
+    push @cmd, $rrsync_dir;
+} else {
+    push @cmd, '/bin/sh', '-c', "@ARGV";
+}
 exec @cmd;
 die "Failed to exec: $!\n";
 
 sub usage
 {
     die <<EOT;
-Usage: lsh [-l USER] [--sudo] [--no-cd] localhost COMMAND [...]
+Usage: lsh [OPTIONS] localhost|lh COMMAND [...]
 
 This is a "local shell" command that works like a remote shell but only for the
 local host.  This is useful for rsync testing or for running a local copy where
 the sender and the receiver need to use different options (e.g. --fake-super).
-If the -l option is used, we try to become the USER, either directly (when
-root) or by using "sudo -H -u USER" (requires --sudo option).
 
-Note that if you pass hostname "lh" instead of "localhost" that the --no-cd
-option is implied.  The default is to "cd \$HOME" to simulate ssh behavior.
+Options:
+
+-l USER        Choose the USER that lsh tries to become.
+--no-cd        Skip the chdir \$HOME (the default with hostname "lh")
+--sudo         Use sudo -H -l USER to become root or the specified USER.
+--rrsync=DIR   Test rrsync restricted copying without using ssh.
+--rropts=STR   The string "munge,no-del,no-lock" would pass 3 options to
+               rrsync (must be combined with --rrsync=DIR).
+
+The script also ignores a bunch of single-letter ssh options.
 EOT
 }
index f74a8ef..db03422 100755 (executable)
@@ -4,7 +4,8 @@
 # for testing or for running a local copy where the sender and the
 # receiver needs to use different options (e.g. --fake-super).  If
 # we get a -l USER option, we try to use "sudo -u USER" to run the
-# command.
+# command.  Supports only the hostnames "localhost" and "lh", with
+# the latter implying the --no-cd option.
 
 user=''
 do_cd=y # Default path is user's home dir (just like ssh) unless host is "lh".
index 3e5f3ad..e7a5474 100755 (executable)
@@ -1,60 +1,71 @@
-#!/usr/bin/env perl
+#!/usr/bin/env python3
 # This script will either prefix all symlink values with the string
 # "/rsyncd-munged/" or remove that prefix.
 
-use strict;
-use Getopt::Long;
-
-my $SYMLINK_PREFIX = '/rsyncd-munged/';
-
-my $munge_opt;
-
-&GetOptions(
-    'munge' => sub { $munge_opt = 1 },
-    'unmunge' => sub { $munge_opt = 0 },
-    'all' => \( my $all_opt ),
-    'help|h' => \( my $help_opt ),
-) or &usage;
-
-&usage if $help_opt || !defined $munge_opt;
-
-my $munged_re = $all_opt ? qr/^($SYMLINK_PREFIX)+(?=.)/ : qr/^$SYMLINK_PREFIX(?=.)/;
-
-push(@ARGV, '.') unless @ARGV;
-
-open(PIPE, '-|', 'find', @ARGV, '-type', 'l') or die $!;
-
-while (<PIPE>) {
-    chomp;
-    my $lnk = readlink($_) or next;
-    if ($munge_opt) {
-       next if !$all_opt && $lnk =~ /$munged_re/;
-       $lnk =~ s/^/$SYMLINK_PREFIX/;
-    } else {
-       next unless $lnk =~ s/$munged_re//;
-    }
-    if (!unlink($_)) {
-       warn "Unable to unlink symlink: $_ ($!)\n";
-    } elsif (!symlink($lnk, $_)) {
-       warn "Unable to recreate symlink: $_ -> $lnk ($!)\n";
-    } else {
-       print "$_ -> $lnk\n";
-    }
-}
-
-close PIPE;
-exit;
-
-sub usage
-{
-    die <<EOT;
-Usage: munge-symlinks --munge|--unmunge [--all] [DIR|SYMLINK...]
-
---munge      Add the $SYMLINK_PREFIX prefix to symlinks if not already
-             present, or always when combined with --all.
---unmunge    Remove one $SYMLINK_PREFIX prefix from symlinks or all
-             such prefixes with --all.
-
-See the "munge symlinks" option in the rsyncd.conf manpage for more details.
-EOT
-}
+import os, sys, argparse
+
+SYMLINK_PREFIX = '/rsyncd-munged/'
+PREFIX_LEN = len(SYMLINK_PREFIX)
+
+def main():
+    for arg in args.names:
+        if os.path.islink(arg):
+            process_one_arg(arg)
+        elif os.path.isdir(arg):
+            for fn in find_symlinks(arg):
+                process_one_arg(fn)
+        else:
+            print("Arg is not a symlink or a dir:", arg, file=sys.stderr)
+
+
+def find_symlinks(path):
+    for entry in os.scandir(path):
+        if entry.is_symlink():
+            yield entry.path
+        elif entry.is_dir(follow_symlinks=False):
+            yield from find_symlinks(entry.path)
+
+
+def process_one_arg(fn):
+    lnk = os.readlink(fn)
+    if args.unmunge:
+        if not lnk.startswith(SYMLINK_PREFIX):
+            return
+        lnk = lnk[PREFIX_LEN:]
+        while args.all and lnk.startswith(SYMLINK_PREFIX):
+            lnk = lnk[PREFIX_LEN:]
+    else:
+        if not args.all and lnk.startswith(SYMLINK_PREFIX):
+            return
+        lnk = SYMLINK_PREFIX + lnk
+
+    try:
+        os.unlink(fn)
+    except OSError as e:
+        print("Unable to unlink symlink:", str(e), file=sys.stderr)
+        return
+    try:
+        os.symlink(lnk, fn)
+    except OSError as e:
+        print("Unable to recreate symlink", fn, '->', lnk + ':', str(e), file=sys.stderr)
+        return
+    print(fn, '->', lnk)
+
+
+if __name__ == '__main__':
+    our_desc = """\
+Adds or removes the %s prefix to/from the start of each symlink's value.
+When given the name of a directory, affects all the symlinks in that directory hierarchy.
+""" % SYMLINK_PREFIX
+    epilog = 'See the "munge symlinks" option in the rsyncd.conf manpage for more details.'
+    parser = argparse.ArgumentParser(description=our_desc, epilog=epilog, add_help=False)
+    uniq_group = parser.add_mutually_exclusive_group()
+    uniq_group.add_argument('--munge', action='store_true', help="Add the prefix to symlinks (the default).")
+    uniq_group.add_argument('--unmunge', action='store_true', help="Remove the prefix from symlinks.")
+    parser.add_argument('--all', action='store_true', help="Always adds the prefix when munging (even if already munged) or removes multiple instances of the prefix when unmunging.")
+    parser.add_argument('--help', '-h', action='help', help="Output this help message and exit.")
+    parser.add_argument('names', metavar='NAME', nargs='+', help="One or more directories and/or symlinks to process.")
+    args = parser.parse_args()
+    main()
+
+# vim: sw=4 et
old mode 100644 (file)
new mode 100755 (executable)
index eabec3d..94c85f5
-#!/usr/bin/env perl
-# Name: /usr/local/bin/rrsync (should also have a symlink in /usr/bin)
-# Purpose: Restricts rsync to subdirectory declared in .ssh/authorized_keys
-# Author: Joe Smith <js-cgi@inwap.com> 30-Sep-2004
-# Modified by: Wayne Davison <wayne@opencoder.net>
-use strict;
-
-use Socket;
-use Cwd 'abs_path';
-use File::Glob ':glob';
-
-# You may configure these values to your liking.  See also the section
-# of options if you want to disable any options that rsync accepts.
-use constant RSYNC => '/usr/bin/rsync';
-use constant LOGFILE => 'rrsync.log';
-
-my $Usage = <<EOM;
-Use 'command="$0 [-ro|-wo] SUBDIR"'
-       in front of lines in $ENV{HOME}/.ssh/authorized_keys
-EOM
-
-# Handle the -ro and -wo options.
-our $only = '';
-while (@ARGV && $ARGV[0] =~ /^-([rw])o$/) {
-    my $r_or_w = $1;
-    if ($only && $only ne $r_or_w) {
-       die "$0: the -ro and -wo options conflict.\n";
-    }
-    $only = $r_or_w;
-    shift;
-}
+#!/usr/bin/env python3
+
+# Restricts rsync to subdirectory declared in .ssh/authorized_keys.  See
+# the rrsync man page for details of how to make use of this script.
+
+# NOTE: install python3 braceexpand to support brace expansion in the args!
+
+# Originally a perl script by: Joe Smith <js-cgi@inwap.com> 30-Sep-2004
+# Python version by: Wayne Davison <wayne@opencoder.net>
+
+# You may configure these 2 values to your liking.  See also the section of
+# short & long options if you want to disable any options that rsync accepts.
+RSYNC = '/usr/bin/rsync'
+LOGFILE = 'rrsync.log' # NOTE: the file must exist for a line to be appended!
+
+# The following options are mainly the options that a client rsync can send
+# to the server, and usually just in the one option format that the stock
+# rsync produces. However, there are some additional convenience options
+# added as well, and thus a few options are present in both the short and
+# long lists (such as --group, --owner, and --perms).
 
-our $subdir = shift;
-die "$0: No subdirectory specified\n$Usage" unless defined $subdir;
-$subdir = abs_path($subdir);
-die "$0: Restricted directory does not exist!\n" if $subdir ne '/' && !-d $subdir;
-
-# The client uses "rsync -av -e ssh src/ server:dir/", and sshd on the server
-# executes this program when .ssh/authorized_keys has 'command="..."'.
-# For example:
-# command="rrsync logs/client" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAzGhEeNlPr...
-# command="rrsync -ro results" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAmkHG1WCjC...
-#
-# Format of the environment variables set by sshd:
-# SSH_ORIGINAL_COMMAND=rsync --server          -vlogDtpr --partial . ARG # push
-# SSH_ORIGINAL_COMMAND=rsync --server --sender -vlogDtpr --partial . ARGS # pull
-# SSH_CONNECTION=client_addr client_port server_port
-
-my $command = $ENV{SSH_ORIGINAL_COMMAND};
-die "$0: Not invoked via sshd\n$Usage" unless defined $command;
-die "$0: SSH_ORIGINAL_COMMAND='$command' is not rsync\n" unless $command =~ s/^rsync\s+//;
-die "$0: --server option is not first\n" unless $command =~ /^--server\s/;
-our $am_sender = $command =~ /^--server\s+--sender\s/; # Restrictive on purpose!
-die "$0 sending to read-only server not allowed\n" if $only eq 'r' && !$am_sender;
-die "$0 reading from write-only server not allowed\n" if $only eq 'w' && $am_sender;
-
-### START of options data produced by the cull_options script. ###
-
-# These options are the only options that rsync might send to the server,
-# and only in the option format that the stock rsync produces.
+# NOTE when disabling: check for both a short & long version of the option!
+
+### START of options data produced by the cull-options script. ###
 
 # To disable a short-named option, add its letter to this string:
-our $short_disabled = 's';
+short_disabled = 's'
+
+# These are also disabled when the restricted dir is not "/":
+short_disabled_subdir = 'KLk'
 
-our $short_no_arg = 'ACDEHIJKLORSUWXbcdgklmnopqrstuvxyz'; # DO NOT REMOVE ANY
-our $short_with_num = '@B'; # DO NOT REMOVE ANY
+# These are all possible short options that we will accept (when not disabled above):
+short_no_arg = 'ACDEHIJKLNORSUWXbcdgklmnopqrstuvxyz' # DO NOT REMOVE ANY
+short_with_num = '@B' # DO NOT REMOVE ANY
 
 # To disable a long-named option, change its value to a -1.  The values mean:
 # 0 = the option has no arg; 1 = the arg doesn't need any checking; 2 = only
 # check the arg when receiving; and 3 = always check the arg.
-our %long_opt = (
-  'append' => 0,
-  'backup-dir' => 2,
-  'block-size' => 1,
-  'bwlimit' => 1,
-  'checksum-choice' => 1,
-  'checksum-seed' => 1,
-  'compare-dest' => 2,
-  'compress-choice' => 1,
-  'compress-level' => 1,
-  'copy-dest' => 2,
-  'copy-unsafe-links' => 0,
-  'daemon' => -1,
-  'debug' => 1,
-  'delay-updates' => 0,
-  'delete' => 0,
-  'delete-after' => 0,
-  'delete-before' => 0,
-  'delete-delay' => 0,
-  'delete-during' => 0,
-  'delete-excluded' => 0,
-  'delete-missing-args' => 0,
-  'existing' => 0,
-  'fake-super' => 0,
-  'files-from' => 3,
-  'force' => 0,
-  'from0' => 0,
-  'fuzzy' => 0,
-  'group' => 0,
-  'groupmap' => 1,
-  'hard-links' => 0,
-  'iconv' => 1,
-  'ignore-errors' => 0,
-  'ignore-existing' => 0,
-  'ignore-missing-args' => 0,
-  'ignore-times' => 0,
-  'info' => 1,
-  'inplace' => 0,
-  'link-dest' => 2,
-  'links' => 0,
-  'list-only' => 0,
-  'log-file' => $only eq 'r' ? -1 : 3,
-  'log-format' => 1,
-  'max-alloc' => 1,
-  'max-delete' => 1,
-  'max-size' => 1,
-  'min-size' => 1,
-  'modify-window' => 1,
-  'new-compress' => 0,
-  'no-implied-dirs' => 0,
-  'no-r' => 0,
-  'no-relative' => 0,
-  'no-specials' => 0,
-  'numeric-ids' => 0,
-  'old-compress' => 0,
-  'one-file-system' => 0,
-  'only-write-batch' => 1,
-  'open-noatime' => 0,
-  'owner' => 0,
-  'partial' => 0,
-  'partial-dir' => 2,
-  'perms' => 0,
-  'preallocate' => 0,
-  'recursive' => 0,
-  'remove-sent-files' => $only eq 'r' ? -1 : 0,
-  'remove-source-files' => $only eq 'r' ? -1 : 0,
-  'safe-links' => 0,
-  'sender' => $only eq 'w' ? -1 : 0,
-  'server' => 0,
-  'size-only' => 0,
-  'skip-compress' => 1,
-  'specials' => 0,
-  'stats' => 0,
-  'suffix' => 1,
-  'super' => 0,
-  'temp-dir' => 2,
-  'timeout' => 1,
-  'times' => 0,
-  'use-qsort' => 0,
-  'usermap' => 1,
-  'write-devices' => -1,
-);
-
-### END of options data produced by the cull_options script. ###
-
-if ($short_disabled ne '') {
-    $short_no_arg =~ s/[$short_disabled]//go;
-    $short_with_num =~ s/[$short_disabled]//go;
-}
-$short_no_arg = "[$short_no_arg]" if length($short_no_arg) > 1;
-$short_with_num = "[$short_with_num]" if length($short_with_num) > 1;
-
-my $write_log = -f LOGFILE && open(LOG, '>>', LOGFILE);
-
-chdir($subdir) or die "$0: Unable to chdir to restricted dir: $!\n";
-
-my(@opts, @args);
-my $in_options = 1;
-my $last_opt = '';
-my $check_type;
-while ($command =~ /((?:[^\s\\]+|\\.[^\s\\]*)+)/g) {
-  $_ = $1;
-  if ($check_type) {
-    push(@opts, check_arg($last_opt, $_, $check_type));
-    $check_type = 0;
-  } elsif ($in_options) {
-    push(@opts, $_);
-    if ($_ eq '.') {
-      $in_options = 0;
-    } else {
-      die "$0: invalid option: '-'\n" if $_ eq '-';
-      next if /^-$short_no_arg*(e\d*\.\w*)?$/o || /^-$short_with_num\d+$/o;
-
-      my($opt,$arg) = /^--([^=]+)(?:=(.*))?$/;
-      my $disabled;
-      if (defined $opt) {
-       my $ct = $long_opt{$opt};
-       last unless defined $ct;
-       next if $ct == 0;
-       if ($ct > 0) {
-         if (!defined $arg) {
-           $check_type = $ct;
-           $last_opt = $opt;
-           next;
-         }
-         $arg = check_arg($opt, $arg, $ct);
-         $opts[-1] =~ s/=.*/=$arg/;
-         next;
-       }
-       $disabled = 1;
-       $opt = "--$opt";
-      } elsif ($short_disabled ne '') {
-       $disabled = /^-$short_no_arg*([$short_disabled])/o;
-       $opt = "-$1";
-      }
-
-      last unless $disabled; # Generate generic failure
-      die "$0: option $opt has been disabled on this server.\n";
-    }
-  } else {
-    if ($subdir ne '/') {
-      # Validate args to ensure they don't try to leave our restricted dir.
-      s{//+}{/}g;
-      s{^/}{};
-      s{^$}{.};
-    }
-    push(@args, bsd_glob($_, GLOB_LIMIT|GLOB_NOCHECK|GLOB_BRACE|GLOB_QUOTE));
-  }
+long_opts = {
+  'append': 0,
+  'backup-dir': 2,
+  'block-size': 1,
+  'bwlimit': 1,
+  'checksum-choice': 1,
+  'checksum-seed': 1,
+  'compare-dest': 2,
+  'compress-choice': 1,
+  'compress-level': 1,
+  'copy-dest': 2,
+  'copy-devices': -1,
+  'copy-unsafe-links': 0,
+  'daemon': -1,
+  'debug': 1,
+  'delay-updates': 0,
+  'delete': 0,
+  'delete-after': 0,
+  'delete-before': 0,
+  'delete-delay': 0,
+  'delete-during': 0,
+  'delete-excluded': 0,
+  'delete-missing-args': 0,
+  'existing': 0,
+  'fake-super': 0,
+  'files-from': 3,
+  'force': 0,
+  'from0': 0,
+  'fsync': 0,
+  'fuzzy': 0,
+  'group': 0,
+  'groupmap': 1,
+  'hard-links': 0,
+  'iconv': 1,
+  'ignore-errors': 0,
+  'ignore-existing': 0,
+  'ignore-missing-args': 0,
+  'ignore-times': 0,
+  'info': 1,
+  'inplace': 0,
+  'link-dest': 2,
+  'links': 0,
+  'list-only': 0,
+  'log-file': 3,
+  'log-format': 1,
+  'max-alloc': 1,
+  'max-delete': 1,
+  'max-size': 1,
+  'min-size': 1,
+  'mkpath': 0,
+  'modify-window': 1,
+  'msgs2stderr': 0,
+  'munge-links': 0,
+  'new-compress': 0,
+  'no-W': 0,
+  'no-implied-dirs': 0,
+  'no-msgs2stderr': 0,
+  'no-munge-links': -1,
+  'no-r': 0,
+  'no-relative': 0,
+  'no-specials': 0,
+  'numeric-ids': 0,
+  'old-compress': 0,
+  'one-file-system': 0,
+  'only-write-batch': 1,
+  'open-noatime': 0,
+  'owner': 0,
+  'partial': 0,
+  'partial-dir': 2,
+  'perms': 0,
+  'preallocate': 0,
+  'recursive': 0,
+  'remove-sent-files': 0,
+  'remove-source-files': 0,
+  'safe-links': 0,
+  'sender': 0,
+  'server': 0,
+  'size-only': 0,
+  'skip-compress': 1,
+  'specials': 0,
+  'stats': 0,
+  'stderr': 1,
+  'suffix': 1,
+  'super': 0,
+  'temp-dir': 2,
+  'timeout': 1,
+  'times': 0,
+  'use-qsort': 0,
+  'usermap': 1,
+  'write-devices': -1,
 }
-die "$0: invalid rsync-command syntax or options\n" if $in_options;
 
-if ($subdir ne '/') {
-    die "$0: do not use .. in any path!\n" if grep m{(^|/)\.\.(/|$)}, @args;
-}
+### END of options data produced by the cull-options script. ###
 
-@args = ( '.' ) if !@args;
+import os, sys, re, argparse, glob, socket, time, subprocess
+from argparse import RawTextHelpFormatter
 
-if ($write_log) {
-  my ($mm,$hh) = (localtime)[1,2];
-  my $host = $ENV{SSH_CONNECTION} || 'unknown';
-  $host =~ s/ .*//; # Keep only the client's IP addr
-  $host =~ s/^::ffff://;
-  $host = gethostbyaddr(inet_aton($host),AF_INET) || $host;
-  printf LOG "%02d:%02d %-13s [%s]\n", $hh, $mm, $host, "@opts @args";
-  close LOG;
-}
+try:
+    from braceexpand import braceexpand
+except:
+    braceexpand = lambda x: [ DE_BACKSLASH_RE.sub(r'\1', x) ]
 
-# Note: This assumes that the rsync protocol will not be maliciously hijacked.
-exec(RSYNC, @opts, '--', @args) or die "exec(rsync @opts -- @args) failed: $? $!";
-
-sub check_arg
-{
-  my($opt, $arg, $type) = @_;
-  $arg =~ s/\\(.)/$1/g;
-  if ($subdir ne '/' && ($type == 3 || ($type == 2 && !$am_sender))) {
-    $arg =~ s{//}{/}g;
-    die "Do not use .. in --$opt; anchor the path at the root of your restricted dir.\n"
-      if $arg =~ m{(^|/)\.\.(/|$)};
-    $arg =~ s{^/}{$subdir/};
-  }
-  $arg;
-}
+HAS_DOT_DOT_RE = re.compile(r'(^|/)\.\.(/|$)')
+LONG_OPT_RE = re.compile(r'^--([^=]+)(?:=(.*))?$')
+DE_BACKSLASH_RE = re.compile(r'\\(.)')
+
+def main():
+    if not os.path.isdir(args.dir):
+        die("Restricted directory does not exist!")
+
+    # The format of the environment variables set by sshd:
+    #   SSH_ORIGINAL_COMMAND:
+    #     rsync --server          -vlogDtpre.iLsfxCIvu --etc . ARG  # push
+    #     rsync --server --sender -vlogDtpre.iLsfxCIvu --etc . ARGS # pull
+    #   SSH_CONNECTION (client_ip client_port server_ip server_port):
+    #     192.168.1.100 64106 192.168.1.2 22
+
+    command = os.environ.get('SSH_ORIGINAL_COMMAND', None)
+    if not command:
+        die("Not invoked via sshd")
+    command = command.split(' ', 2)
+    if command[0:1] != ['rsync']:
+        die("SSH_ORIGINAL_COMMAND does not run rsync")
+    if command[1:2] != ['--server']:
+        die("--server option is not the first arg")
+    command = '' if len(command) < 3 else command[2]
+
+    global am_sender
+    am_sender = command.startswith("--sender ") # Restrictive on purpose!
+    if args.ro and not am_sender:
+        die("sending to read-only server is not allowed")
+    if args.wo and am_sender:
+        die("reading from write-only server is not allowed")
+
+    if args.wo or not am_sender:
+        long_opts['sender'] = -1
+    if args.no_del:
+        for opt in long_opts:
+            if opt.startswith(('remove', 'delete')):
+                long_opts[opt] = -1
+    if args.ro:
+        long_opts['log-file'] = -1
+
+    if args.dir != '/':
+        global short_disabled
+        short_disabled += short_disabled_subdir
+
+    short_no_arg_re = short_no_arg
+    short_with_num_re = short_with_num
+    if short_disabled:
+        for ltr in short_disabled:
+            short_no_arg_re = short_no_arg_re.replace(ltr, '')
+            short_with_num_re = short_with_num_re.replace(ltr, '')
+        short_disabled_re = re.compile(r'^-[%s]*([%s])' % (short_no_arg_re, short_disabled))
+    short_no_arg_re = re.compile(r'^-(?=.)[%s]*(e\d*\.\w*)?$' % short_no_arg_re)
+    short_with_num_re = re.compile(r'^-[%s]\d+$' % short_with_num_re)
+
+    log_fh = open(LOGFILE, 'a') if os.path.isfile(LOGFILE) else None
+
+    try:
+        os.chdir(args.dir)
+    except OSError as e:
+        die('unable to chdir to restricted dir:', str(e))
+
+    rsync_opts = [ '--server' ]
+    rsync_args = [ ]
+    saw_the_dot_arg = False
+    last_opt = check_type = None
+
+    for arg in re.findall(r'(?:[^\s\\]+|\\.[^\s\\]*)+', command):
+        if check_type:
+            rsync_opts.append(validated_arg(last_opt, arg, check_type))
+            check_type = None
+        elif saw_the_dot_arg:
+            # NOTE: an arg that starts with a '-' is safe due to our use of "--" in the cmd tuple.
+            try:
+                b_e = braceexpand(arg) # Also removes backslashes
+            except: # Handle errors such as unbalanced braces by just de-backslashing the arg:
+                b_e = [ DE_BACKSLASH_RE.sub(r'\1', arg) ]
+            for xarg in b_e:
+                rsync_args += validated_arg('arg', xarg, wild=True)
+        else: # parsing the option args
+            if arg == '.':
+                saw_the_dot_arg = True
+                continue
+            rsync_opts.append(arg)
+            if short_no_arg_re.match(arg) or short_with_num_re.match(arg):
+                continue
+            disabled = False
+            m = LONG_OPT_RE.match(arg)
+            if m:
+                opt = m.group(1)
+                opt_arg = m.group(2)
+                ct = long_opts.get(opt, None)
+                if ct is None:
+                    break # Generate generic failure due to unfinished arg parsing
+                if ct == 0:
+                    continue
+                opt = '--' + opt
+                if ct > 0:
+                    if opt_arg is not None:
+                        rsync_opts[-1] = opt + '=' + validated_arg(opt, opt_arg, ct)
+                    else:
+                        check_type = ct
+                        last_opt = opt
+                    continue
+                disabled = True
+            elif short_disabled:
+                m = short_disabled_re.match(arg)
+                if m:
+                    disabled = True
+                    opt = '-' + m.group(1)
+
+            if disabled:
+                die("option", opt, "has been disabled on this server.")
+            break # Generate a generic failure
+
+    if not saw_the_dot_arg:
+        die("invalid rsync-command syntax or options")
+
+    if args.munge:
+        rsync_opts.append('--munge-links')
+
+    if not rsync_args:
+        rsync_args = [ '.' ]
+
+    cmd = (RSYNC, *rsync_opts, '--', '.', *rsync_args)
+
+    if log_fh:
+        now = time.localtime()
+        host = os.environ.get('SSH_CONNECTION', 'unknown').split()[0] # Drop everything after the IP addr
+        if host.startswith('::ffff:'):
+            host = host[7:]
+        try:
+            host = socket.gethostbyaddr(socket.inet_aton(host))
+        except:
+            pass
+        log_fh.write("%02d:%02d:%02d %-16s %s\n" % (now.tm_hour, now.tm_min, now.tm_sec, host, str(cmd)))
+        log_fh.close()
+
+    # NOTE: This assumes that the rsync protocol will not be maliciously hijacked.
+    if args.no_lock:
+        os.execlp(RSYNC, *cmd)
+        die("execlp(", RSYNC, *cmd, ')  failed')
+    child = subprocess.run(cmd)
+    if child.returncode != 0:
+        sys.exit(child.returncode)
+
+
+def validated_arg(opt, arg, typ=3, wild=False):
+    if opt != 'arg': # arg values already have their backslashes removed.
+        arg = DE_BACKSLASH_RE.sub(r'\1', arg)
+
+    orig_arg = arg
+    if arg.startswith('./'):
+        arg = arg[1:]
+    arg = arg.replace('//', '/')
+    if args.dir != '/':
+        if HAS_DOT_DOT_RE.search(arg):
+            die("do not use .. in", opt, "(anchor the path at the root of your restricted dir)")
+        if arg.startswith('/'):
+            arg = args.dir + arg
+
+    if wild:
+        got = glob.glob(arg)
+        if not got:
+            got = [ arg ]
+    else:
+        got = [ arg ]
+
+    ret = [ ]
+    for arg in got:
+        if args.dir != '/' and arg != '.' and (typ == 3 or (typ == 2 and not am_sender)):
+            arg_has_trailing_slash = arg.endswith('/')
+            if arg_has_trailing_slash:
+                arg = arg[:-1]
+            else:
+                arg_has_trailing_slash_dot = arg.endswith('/.')
+                if arg_has_trailing_slash_dot:
+                    arg = arg[:-2]
+            real_arg = os.path.realpath(arg)
+            if arg != real_arg and not real_arg.startswith(args.dir_slash):
+                die('unsafe arg:', orig_arg, [arg, real_arg])
+            if arg_has_trailing_slash:
+                arg += '/'
+            elif arg_has_trailing_slash_dot:
+                arg += '/.'
+            if opt == 'arg' and arg.startswith(args.dir_slash):
+                arg = arg[args.dir_slash_len:]
+                if arg == '':
+                    arg = '.'
+        ret.append(arg)
+
+    return ret if wild else ret[0]
+
+
+def lock_or_die(dirname):
+    import fcntl
+    global lock_handle
+    lock_handle = os.open(dirname, os.O_RDONLY)
+    try:
+        fcntl.flock(lock_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
+    except:
+        die('Another instance of rrsync is already accessing this directory.')
+
+
+def die(*msg):
+    print(sys.argv[0], 'error:', *msg, file=sys.stderr)
+    if sys.stdin.isatty():
+        arg_parser.print_help(sys.stderr)
+    sys.exit(1)
+
+
+# This class displays the --help to the user on argparse error IFF they're running it interactively.
+class OurArgParser(argparse.ArgumentParser):
+    def error(self, msg):
+        die(msg)
+
+
+if __name__ == '__main__':
+    our_desc = """Use "man rrsync" to learn how to restrict ssh users to using a restricted rsync command."""
+    arg_parser = OurArgParser(description=our_desc, add_help=False)
+    only_group = arg_parser.add_mutually_exclusive_group()
+    only_group.add_argument('-ro', action='store_true', help="Allow only reading from the DIR. Implies -no-del and -no-lock.")
+    only_group.add_argument('-wo', action='store_true', help="Allow only writing to the DIR.")
+    arg_parser.add_argument('-munge', action='store_true', help="Enable rsync's --munge-links on the server side.")
+    arg_parser.add_argument('-no-del', action='store_true', help="Disable rsync's --delete* and --remove* options.")
+    arg_parser.add_argument('-no-lock', action='store_true', help="Avoid the single-run (per-user) lock check.")
+    arg_parser.add_argument('-help', '-h', action='help', help="Output this help message and exit.")
+    arg_parser.add_argument('dir', metavar='DIR', help="The restricted directory to use.")
+    args = arg_parser.parse_args()
+    args.dir = os.path.realpath(args.dir)
+    args.dir_slash = args.dir + '/'
+    args.dir_slash_len = len(args.dir_slash)
+    if args.ro:
+        args.no_del = True
+    elif not args.no_lock:
+        lock_or_die(args.dir)
+    main()
+
+# vim: sw=4 et
diff --git a/support/rrsync.1.md b/support/rrsync.1.md
new file mode 100644 (file)
index 0000000..98f2cab
--- /dev/null
@@ -0,0 +1,166 @@
+## NAME
+
+rrsync - a script to setup restricted rsync users via ssh logins
+
+## SYNOPSIS
+
+```
+rrsync [-ro|-rw] [-munge] [-no-del] [-no-lock] DIR
+```
+
+The single non-option argument specifies the restricted _DIR_ to use. It can be
+relative to the user's home directory or an absolute path.
+
+The online version of this manpage (that includes cross-linking of topics)
+is available at <https://download.samba.org/pub/rsync/rrsync.1>.
+
+## DESCRIPTION
+
+A user's ssh login can be restricted to only allow the running of an rsync
+transfer in one of two easy ways:
+
+* forcing the running of the rrsync script
+* forcing the running of an rsync daemon-over-ssh command.
+
+Both of these setups use a feature of ssh that allows a command to be forced to
+run instead of an interactive shell.  However, if the user's home shell is bash,
+please see [BASH SECURITY ISSUE](#) for a potential issue.
+
+To use the rrsync script, edit the user's `~/.ssh/authorized_keys` file and add
+a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:
+
+> ```
+> command="rrsync DIR"
+> command="rrsync -ro DIR"
+> command="rrsync -munge -no-del DIR"
+> ```
+
+Then, ensure that the rrsync script has your desired option restrictions. You
+may want to copy the script to a local bin dir with a unique name if you want
+to have multiple configurations. One or more rrsync options can be specified
+prior to the _DIR_ if you want to further restrict the transfer.
+
+To use an rsync daemon setup, edit the user's `~/.ssh/authorized_keys` file and
+add a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:
+
+> ```
+> command="rsync --server --daemon ."
+> command="rsync --server --daemon --config=/PATH/TO/rsyncd.conf ."
+> ```
+
+Then, ensure that the rsyncd.conf file is created with one or more module names
+with the appropriate path and option restrictions.  If rsync's
+[`--config`](rsync.1#dopt) option is omitted, it defaults to `~/rsyncd.conf`.
+See the [**rsyncd.conf**(5)](rsyncd.conf.5) manpage for details of how to
+configure an rsync daemon.
+
+When using rrsync, there can be just one restricted dir per authorized key.  A
+daemon setup, on the other hand, allows multiple module names inside the config
+file, each one with its own path setting.
+
+The remainder of this manpage is dedicated to using the rrsync script.
+
+## OPTIONS
+
+0.  `-ro`
+
+    Allow only reading from the DIR. Implies [`-no-del`](#opt) and
+    [`-no-lock`](#opt).
+
+0.  `-wo`
+
+    Allow only writing to the DIR.
+
+0.  `-munge`
+
+    Enable rsync's [`--munge-links`](rsync.1#opt) on the server side.
+
+0.  `-no-del`
+
+    Disable rsync's `--delete*` and `--remove*` options.
+
+0.  `-no-lock`
+
+    Avoid the single-run (per-user) lock check.  Useful with [`-munge`](#opt).
+
+0.  `-help`, `-h`
+
+    Output this help message and exit.
+
+## SECURITY RESTRICTIONS
+
+The rrsync script validates the path arguments it is sent to try to restrict
+them to staying within the specified DIR.
+
+The rrsync script rejects rsync's [`--copy-links`](rsync.1#opt) option (by
+default) so that a copy cannot dereference a symlink within the DIR to get to a
+file outside the DIR.
+
+The rrsync script rejects rsync's [`--protect-args`](rsync.1#opt) (`-s`) option
+because it would allow options to be sent to the server-side that the script
+cannot check.  If you want to support `--protect-args`, use a daemon-over-ssh
+setup.
+
+The rrsync script accepts just a subset of rsync's options that the real rsync
+uses when running the server command.  A few extra convenience options are also
+included to help it to interact with BackupPC and accept some convenient user
+overrides.
+
+The script (or a copy of it) can be manually edited if you want it to customize
+the option handling.
+
+## BASH SECURITY ISSUE
+
+If your users have bash set as their home shell, bash may try to be overly
+helpful and ensure that the user's login bashrc files are run prior to
+executing the forced command.  This can be a problem if the user can somehow
+update their home bashrc files, perhaps via the restricted copy, a shared home
+directory, or something similar.
+
+One simple way to avoid the issue is to switch the user to a simpler shell,
+such as dash.  When choosing the new home shell, make sure that you're not
+choosing bash in disguise, as it is unclear if it avoids the security issue.
+
+Another potential fix is to ensure that the user's home directory is not a
+shared mount and that they have no means of copying files outside of their
+restricted directories.  This may require you to force the enabling of symlink
+munging on the server side.
+
+A future version of openssh may have a change to the handling of forced
+commands that allows it to avoid using the user's home shell.
+
+## EXAMPLES
+
+The `~/.ssh/authorized_keys` file might have lines in it like this:
+
+> ```
+> command="rrsync client/logs" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAzG...
+> command="rrsync -ro results" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAmk...
+> ```
+
+## FILES
+
+~/.ssh/authorized_keys
+
+## SEE ALSO
+
+[**rsync**(1)](rsync.1), [**rsyncd.conf**(5)](rsyncd.conf.5)
+
+## VERSION
+
+This manpage is current for version @VERSION@ of rsync.
+
+## CREDITS
+
+rsync is distributed under the GNU General Public License.  See the file
+[COPYING](COPYING) for details.
+
+An rsync web site is available at <https://rsync.samba.org/> and its github
+project is <https://github.com/WayneD/rsync>.
+
+## AUTHOR
+
+The original rrsync perl script was written by Joe Smith.  Many people have
+later contributed to it.  The python version was created by Wayne Davison.
index cc3c29c..b31a5d2 100755 (executable)
@@ -1,12 +1,21 @@
 #!/usr/bin/env bash
 
+REAL_RSYNC=/usr/bin/rsync
 IGNOREEXIT=24
 IGNOREOUT='^(file has vanished: |rsync warning: some files vanished before they could be transferred)'
 
+# If someone installs this as "rsync", make sure we don't affect a server run.
+for arg in "${@}"; do
+    if [[ "$arg" == --server ]]; then
+       exec $REAL_RSYNC "${@}"
+       exit $? # Not reached
+    fi
+done
+
 set -o pipefail
 
-rsync "${@}" 2>&1 | (egrep -v "$IGNOREOUT" || true)
-ret=$?
+# This filters stderr without merging it with stdout:
+{ $REAL_RSYNC "${@}" 2>&1 1>&3 3>&- | grep -E -v "$IGNOREOUT"; ret=${PIPESTATUS[0]}; } 3>&1 1>&2
 
 if [[ $ret == $IGNOREEXIT ]]; then
     ret=0
index 2869e45..b57e61c 100755 (executable)
@@ -6,12 +6,19 @@
 #
 # To use this, name it something like "rs", put it somewhere in your path, and
 # then use "rs" in place of "rsync" when you are typing your copy commands.
+
+REAL_RSYNC=/usr/bin/rsync
+
 args=()
 for arg in "${@}"; do
+    if [[ "$arg" == --server ]]; then
+       exec $REAL_RSYNC "${@}"
+       exit $? # Not reached
+    fi
     if [[ "$arg" == / ]]; then
        args=("${args[@]}" /)
     else
        args=("${args[@]}" "${arg%/}")
     fi
 done
-exec /usr/bin/rsync "${args[@]}"
+exec $REAL_RSYNC "${args[@]}"
index b9c3b4e..d92074a 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1998 Andrew Tridgell
  * Copyright (C) 2002 Martin Pool
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -55,12 +55,16 @@ extern int open_noatime;
 #endif
 
 #ifdef SUPPORT_CRTIMES
+#ifdef HAVE_GETATTRLIST
 #pragma pack(push, 4)
 struct create_time {
        uint32 length;
        struct timespec crtime;
 };
 #pragma pack(pop)
+#elif defined __CYGWIN__
+#include <windows.h>
+#endif
 #endif
 
 #define RETURN_ERROR_IF(x,e) \
@@ -73,15 +77,15 @@ struct create_time {
 
 #define RETURN_ERROR_IF_RO_OR_LO RETURN_ERROR_IF(read_only || list_only, EROFS)
 
-int do_unlink(const char *fname)
+int do_unlink(const char *path)
 {
        if (dry_run) return 0;
        RETURN_ERROR_IF_RO_OR_LO;
-       return unlink(fname);
+       return unlink(path);
 }
 
 #ifdef SUPPORT_LINKS
-int do_symlink(const char *lnk, const char *fname)
+int do_symlink(const char *lnk, const char *path)
 {
        if (dry_run) return 0;
        RETURN_ERROR_IF_RO_OR_LO;
@@ -91,7 +95,7 @@ int do_symlink(const char *lnk, const char *fname)
         * and write the lnk into it. */
        if (am_root < 0) {
                int ok, len = strlen(lnk);
-               int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
+               int fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
                if (fd < 0)
                        return -1;
                ok = write(fd, lnk, len) == len;
@@ -101,7 +105,7 @@ int do_symlink(const char *lnk, const char *fname)
        }
 #endif
 
-       return symlink(lnk, fname);
+       return symlink(lnk, path);
 }
 
 #if defined NO_SYMLINK_XATTRS || defined NO_SYMLINK_USER_XATTRS
@@ -227,27 +231,43 @@ int do_open(const char *pathname, int flags, mode_t mode)
 #ifdef HAVE_CHMOD
 int do_chmod(const char *path, mode_t mode)
 {
+       static int switch_step = 0;
        int code;
+
        if (dry_run) return 0;
        RETURN_ERROR_IF_RO_OR_LO;
+
+       switch (switch_step) {
 #ifdef HAVE_LCHMOD
-       code = lchmod(path, mode & CHMOD_BITS);
-#else
-       if (S_ISLNK(mode)) {
+       case 0:
+               if ((code = lchmod(path, mode & CHMOD_BITS)) == 0)
+                       break;
+               if (errno == ENOSYS)
+                       switch_step++;
+               else if (errno != ENOTSUP)
+                       break;
+#endif
+               /* FALLTHROUGH */
+       default:
+               if (S_ISLNK(mode)) {
 # if defined HAVE_SETATTRLIST
-               struct attrlist attrList;
-               uint32_t m = mode & CHMOD_BITS; /* manpage is wrong: not mode_t! */
-
-               memset(&attrList, 0, sizeof attrList);
-               attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
-               attrList.commonattr = ATTR_CMN_ACCESSMASK;
-               code = setattrlist(path, &attrList, &m, sizeof m, FSOPT_NOFOLLOW);
+                       struct attrlist attrList;
+                       uint32_t m = mode & CHMOD_BITS; /* manpage is wrong: not mode_t! */
+
+                       memset(&attrList, 0, sizeof attrList);
+                       attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
+                       attrList.commonattr = ATTR_CMN_ACCESSMASK;
+                       if ((code = setattrlist(path, &attrList, &m, sizeof m, FSOPT_NOFOLLOW)) == 0)
+                               break;
+                       if (errno == ENOTSUP)
+                               code = 1;
 # else
-               code = 1;
+                       code = 1;
 # endif
-       } else
-               code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */
-#endif /* !HAVE_LCHMOD */
+               } else
+                       code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */
+               break;
+       }
        if (code != 0 && (preserve_perms || preserve_executability))
                return code;
        return 0;
@@ -295,12 +315,12 @@ void trim_trailing_slashes(char *name)
        }
 }
 
-int do_mkdir(char *fname, mode_t mode)
+int do_mkdir(char *path, mode_t mode)
 {
        if (dry_run) return 0;
        RETURN_ERROR_IF_RO_OR_LO;
-       trim_trailing_slashes(fname);
-       return mkdir(fname, mode);
+       trim_trailing_slashes(path);
+       return mkdir(path, mode);
 }
 
 /* like mkstemp but forces permissions */
@@ -334,25 +354,25 @@ int do_mkstemp(char *template, mode_t perms)
 #endif
 }
 
-int do_stat(const char *fname, STRUCT_STAT *st)
+int do_stat(const char *path, STRUCT_STAT *st)
 {
 #ifdef USE_STAT64_FUNCS
-       return stat64(fname, st);
+       return stat64(path, st);
 #else
-       return stat(fname, st);
+       return stat(path, st);
 #endif
 }
 
-int do_lstat(const char *fname, STRUCT_STAT *st)
+int do_lstat(const char *path, STRUCT_STAT *st)
 {
 #ifdef SUPPORT_LINKS
 # ifdef USE_STAT64_FUNCS
-       return lstat64(fname, st);
+       return lstat64(path, st);
 # else
-       return lstat(fname, st);
+       return lstat(path, st);
 # endif
 #else
-       return do_stat(fname, st);
+       return do_stat(path, st);
 #endif
 }
 
@@ -380,7 +400,29 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
 }
 
 #ifdef HAVE_SETATTRLIST
-int do_setattrlist_times(const char *fname, STRUCT_STAT *stp)
+int do_setattrlist_times(const char *path, STRUCT_STAT *stp)
+{
+       struct attrlist attrList;
+       struct timespec ts[2];
+
+       if (dry_run) return 0;
+       RETURN_ERROR_IF_RO_OR_LO;
+
+       /* Yes, this is in the opposite order of utime and similar. */
+       ts[0].tv_sec = stp->st_mtime;
+       ts[0].tv_nsec = stp->ST_MTIME_NSEC;
+
+       ts[1].tv_sec = stp->st_atime;
+       ts[1].tv_nsec = stp->ST_ATIME_NSEC;
+
+       memset(&attrList, 0, sizeof attrList);
+       attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
+       attrList.commonattr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME;
+       return setattrlist(path, &attrList, ts, sizeof ts, FSOPT_NOFOLLOW);
+}
+
+#ifdef SUPPORT_CRTIMES
+int do_setattrlist_crtime(const char *path, time_t crtime)
 {
        struct attrlist attrList;
        struct timespec ts;
@@ -388,52 +430,70 @@ int do_setattrlist_times(const char *fname, STRUCT_STAT *stp)
        if (dry_run) return 0;
        RETURN_ERROR_IF_RO_OR_LO;
 
-       ts.tv_sec = stp->st_mtime;
-       ts.tv_nsec = stp->ST_MTIME_NSEC;
+       ts.tv_sec = crtime;
+       ts.tv_nsec = 0;
 
        memset(&attrList, 0, sizeof attrList);
        attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
-       attrList.commonattr = ATTR_CMN_MODTIME;
-       return setattrlist(fname, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW);
+       attrList.commonattr = ATTR_CMN_CRTIME;
+       return setattrlist(path, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW);
 }
 #endif
+#endif /* HAVE_SETATTRLIST */
 
 #ifdef SUPPORT_CRTIMES
-time_t get_create_time(const char *path)
+time_t get_create_time(const char *path, STRUCT_STAT *stp)
 {
+#ifdef HAVE_GETATTRLIST
        static struct create_time attrBuf;
        struct attrlist attrList;
 
+       (void)stp;
        memset(&attrList, 0, sizeof attrList);
        attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
        attrList.commonattr = ATTR_CMN_CRTIME;
        if (getattrlist(path, &attrList, &attrBuf, sizeof attrBuf, FSOPT_NOFOLLOW) < 0)
                return 0;
        return attrBuf.crtime.tv_sec;
-}
+#elif defined __CYGWIN__
+       (void)path;
+       return stp->st_birthtime;
+#else
+#error Unknown crtimes implementation
 #endif
+}
 
-#ifdef SUPPORT_CRTIMES
-int set_create_time(const char *path, time_t crtime)
+#if defined __CYGWIN__
+int do_SetFileTime(const char *path, time_t crtime)
 {
-       struct attrlist attrList;
-       struct timespec ts;
-
        if (dry_run) return 0;
        RETURN_ERROR_IF_RO_OR_LO;
 
-       ts.tv_sec = crtime;
-       ts.tv_nsec = 0;
-
-       memset(&attrList, 0, sizeof attrList);
-       attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
-       attrList.commonattr = ATTR_CMN_CRTIME;
-       return setattrlist(path, &attrList, &ts, sizeof ts, FSOPT_NOFOLLOW);
+       int cnt = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
+       if (cnt == 0)
+           return -1;
+       WCHAR *pathw = new_array(WCHAR, cnt);
+       if (!pathw)
+           return -1;
+       MultiByteToWideChar(CP_UTF8, 0, path, -1, pathw, cnt);
+       HANDLE handle = CreateFileW(pathw, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                                   NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+       free(pathw);
+       if (handle == INVALID_HANDLE_VALUE)
+           return -1;
+       int64 temp_time = Int32x32To64(crtime, 10000000) + 116444736000000000LL;
+       FILETIME birth_time;
+       birth_time.dwLowDateTime = (DWORD)temp_time;
+       birth_time.dwHighDateTime = (DWORD)(temp_time >> 32);
+       int ok = SetFileTime(handle, &birth_time, NULL, NULL);
+       CloseHandle(handle);
+       return ok ? 0 : -1;
 }
 #endif
+#endif /* SUPPORT_CRTIMES */
 
 #ifdef HAVE_UTIMENSAT
-int do_utimensat(const char *fname, STRUCT_STAT *stp)
+int do_utimensat(const char *path, STRUCT_STAT *stp)
 {
        struct timespec t[2];
 
@@ -452,12 +512,12 @@ int do_utimensat(const char *fname, STRUCT_STAT *stp)
 #else
        t[1].tv_nsec = 0;
 #endif
-       return utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW);
+       return utimensat(AT_FDCWD, path, t, AT_SYMLINK_NOFOLLOW);
 }
 #endif
 
 #ifdef HAVE_LUTIMES
-int do_lutimes(const char *fname, STRUCT_STAT *stp)
+int do_lutimes(const char *path, STRUCT_STAT *stp)
 {
        struct timeval t[2];
 
@@ -476,12 +536,12 @@ int do_lutimes(const char *fname, STRUCT_STAT *stp)
 #else
        t[1].tv_usec = 0;
 #endif
-       return lutimes(fname, t);
+       return lutimes(path, t);
 }
 #endif
 
 #ifdef HAVE_UTIMES
-int do_utimes(const char *fname, STRUCT_STAT *stp)
+int do_utimes(const char *path, STRUCT_STAT *stp)
 {
        struct timeval t[2];
 
@@ -500,11 +560,11 @@ int do_utimes(const char *fname, STRUCT_STAT *stp)
 #else
        t[1].tv_usec = 0;
 #endif
-       return utimes(fname, t);
+       return utimes(path, t);
 }
 
 #elif defined HAVE_UTIME
-int do_utime(const char *fname, STRUCT_STAT *stp)
+int do_utime(const char *path, STRUCT_STAT *stp)
 {
 #ifdef HAVE_STRUCT_UTIMBUF
        struct utimbuf tbuf;
@@ -518,11 +578,11 @@ int do_utime(const char *fname, STRUCT_STAT *stp)
 # ifdef HAVE_STRUCT_UTIMBUF
        tbuf.actime = stp->st_atime;
        tbuf.modtime = stp->st_mtime;
-       return utime(fname, &tbuf);
+       return utime(path, &tbuf);
 # else
        t[0] = stp->st_atime;
        t[1] = stp->st_mtime;
-       return utime(fname, t);
+       return utime(path, t);
 # endif
 }
 
index 1e1e404..085378a 100644 (file)
--- a/t_stub.c
+++ b/t_stub.c
@@ -3,7 +3,7 @@
  * functions, so that module test harnesses can run standalone.
  *
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -21,6 +21,7 @@
 
 #include "rsync.h"
 
+int do_fsync = 0;
 int inplace = 0;
 int modify_window = 0;
 int preallocate_files = 0;
@@ -28,10 +29,10 @@ int protect_args = 0;
 int module_id = -1;
 int relative_paths = 0;
 int module_dirlen = 0;
-int preserve_times = 0;
 int preserve_xattrs = 0;
 int preserve_perms = 0;
 int preserve_executability = 0;
+int omit_link_times = 0;
 int open_noatime = 0;
 size_t max_alloc = 0; /* max_alloc is needed when combined with util2.o */
 char *partial_dir;
index ecb2634..ebd0683 100644 (file)
@@ -1,9 +1,11 @@
-#! /bin/sh
+#!/bin/sh
 
-test_fail() {
-    echo "$@" >&2
-    exit 1
-}
+# Test some foundational things.
+
+. "$suitedir/rsync.fns"
+
+RSYNC_RSH="$scratchdir/src/support/lsh.sh"
+export RSYNC_RSH
 
 echo $0 running
 
@@ -12,3 +14,48 @@ $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
index d2fbe90..782cb1c 100644 (file)
@@ -26,5 +26,3 @@ you could include the log messages when reporting a failure.
 
 These tests also run automatically on the build farm, and you can see
 the results on http://build.samba.org/.
-
-
similarity index 93%
rename from testsuite/default-acls.test
rename to testsuite/acls-default.test
index 17893f9..d8fba7f 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
@@ -7,7 +7,7 @@
 
 . $suitedir/rsync.fns
 
-$RSYNC --version | grep "[, ] ACLs" >/dev/null || test_skipped "Rsync is configured without ACL support"
+$RSYNC -VV | grep '"ACLs": true' >/dev/null || test_skipped "Rsync is configured without ACL support"
 
 case "$setfacl_nodef" in
 true) test_skipped "I don't know how to use your setfacl command" ;;
@@ -21,7 +21,7 @@ testit() {
     todir="$scratchdir/$1"
     mkdir "$todir"
     $setfacl_nodef "$todir"
-    if [ "$2" ]; then
+    if [ -n "$2" ]; then
        case "$setfacl_nodef" in
        *-k*) opts="-dm $2" ;;
        *) opts="-m `echo $2 | sed 's/\([ugom]:\)/d:\1/g'`"
index 5728cd5..693da66 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
@@ -7,7 +7,7 @@
 
 . $suitedir/rsync.fns
 
-$RSYNC --version | grep "[, ] ACLs" >/dev/null || test_skipped "Rsync is configured without ACL support"
+$RSYNC -VV | grep '"ACLs": true' >/dev/null || test_skipped "Rsync is configured without ACL support"
 
 makepath "$fromdir/foo"
 echo something >"$fromdir/file1"
@@ -17,8 +17,8 @@ files='foo file1 file2'
 
 case "$setfacl_nodef" in
 true)
-    if ! chmod --help 2>&1 | fgrep +a >/dev/null; then
-       test_skipped "I don't know how to use setfacl or chmod for ACLs"
+    if ! chmod --help 2>&1 | grep -F +a >/dev/null; then
+        test_skipped "I don't know how to use setfacl or chmod for ACLs"
     fi
     chmod +a "root allow read,write,execute" "$fromdir/foo" || test_skipped "Your filesystem has ACLs disabled"
     chmod +a "root allow read,execute" "$fromdir/file1"
@@ -27,7 +27,7 @@ true)
     chmod +a "root allow read,execute" "$fromdir/file2"
 
     see_acls() {
-       ls -le "${@}"
+        ls -le "${@}"
     }
     ;;
 *)
@@ -45,7 +45,7 @@ true)
     setfacl -m u:0:5 "$fromdir/file2"
 
     see_acls() {
-       getfacl "${@}"
+        getfacl "${@}"
     }
     ;;
 esac
diff --git a/testsuite/alt-dest.test b/testsuite/alt-dest.test
new file mode 100644 (file)
index 0000000..d2fb5a1
--- /dev/null
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+# Copyright (C) 2004-2022 Wayne Davison
+
+# This program is distributable under the terms of the GNU GPL (see
+# COPYING).
+
+# Test rsync handling of --compare-dest and similar options.
+
+. "$suitedir/rsync.fns"
+
+alt1dir="$tmpdir/alt1"
+alt2dir="$tmpdir/alt2"
+alt3dir="$tmpdir/alt3"
+
+SSH="$scratchdir/src/support/lsh.sh"
+
+# Build some files/dirs/links to copy
+
+hands_setup
+
+# Setup the alt and chk dirs
+$RSYNC -av --include=text --include='*/' --exclude='*' "$fromdir/" "$alt1dir/"
+$RSYNC -av --include=etc-ltr-list --include='*/' --exclude='*' "$fromdir/" "$alt2dir/"
+
+# Create a side dir where there is a candidate destfile of the same name as a sourcefile
+echo "This is a test file" >"$fromdir/likely"
+
+mkdir "$alt3dir"
+echo "This is a test file" >"$alt3dir/likely"
+
+sleep 1
+touch "$fromdir/dir/text" "$fromdir/likely"
+
+$RSYNC -av --exclude=/text --exclude=etc-ltr-list "$fromdir/" "$chkdir/"
+
+# Let's do it!
+checkit "$RSYNC -avv --no-whole-file \
+    --compare-dest='$alt1dir' --compare-dest='$alt2dir' \
+    '$fromdir/' '$todir/'" "$chkdir" "$todir"
+
+rm -rf "$todir"
+checkit "$RSYNC -avv --no-whole-file \
+    --copy-dest='$alt1dir' --copy-dest='$alt2dir' \
+    '$fromdir/' '$todir/'" "$fromdir" "$todir"
+
+# Test that copy_file() works correctly with tmpfiles
+for maybe_inplace in '' --inplace; do
+    rm -rf "$todir"
+    checkit "$RSYNC -av $maybe_inplace --copy-dest='$alt3dir' \
+       '$fromdir/' '$todir/'" "$fromdir" "$todir"
+
+    for srchost in '' 'localhost:'; do
+       if [ -z "$srchost" ]; then
+           desthost='localhost:'
+       else
+           desthost=''
+       fi
+
+       rm -rf "$todir"
+       checkit "$RSYNC -ave '$SSH' --rsync-path='$RSYNC' $maybe_inplace \
+           --copy-dest='$alt3dir' '$srchost$fromdir/' '$desthost$todir/'" \
+           "$fromdir" "$todir"
+    done
+done
+
+# The script would have aborted on error, so getting here means we've won.
+exit 0
index 6dd5813..4d46eb0 100644 (file)
@@ -1,10 +1,10 @@
-#! /bin/sh
+#!/bin/sh
 
 # Test rsync copying atimes
 
 . "$suitedir/rsync.fns"
 
-$RSYNC --version | grep "[, ] atimes" >/dev/null || test_skipped "Rsync is configured without atimes support"
+$RSYNC -VV | grep '"atimes": true' >/dev/null || test_skipped "Rsync is configured without atimes support"
 
 mkdir "$fromdir"
 
index 87db33e..4de3867 100644 (file)
@@ -1,6 +1,6 @@
-#! /bin/sh
+#!/bin/sh
 
-# Copyright (C) 2004-2020 Wayne Davison
+# Copyright (C) 2004-2022 Wayne Davison
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
@@ -15,8 +15,6 @@ makepath "$fromdir/deep" "$bakdir/dname"
 name1="$fromdir/deep/name1"
 name2="$fromdir/deep/name2"
 
-outfile="$scratchdir/rsync.out"
-
 cat "$srcdir"/[gr]*.[ch] > "$name1"
 cat "$srcdir"/[et]*.[ch] > "$name2"
 
@@ -26,8 +24,7 @@ checkit "$RSYNC -ai --info=backup '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
 cat "$srcdir"/[fgpr]*.[ch] > "$name1"
 cat "$srcdir"/[etw]*.[ch] > "$name2"
 
-$RSYNC -ai --info=backup --no-whole-file --backup "$fromdir/" "$todir/" \
-    | tee "$outfile"
+checktee "$RSYNC -ai --info=backup --no-whole-file --backup '$fromdir/' '$todir/'"
 for fn in deep/name1 deep/name2; do
     grep "backed up $fn to $fn~" "$outfile" >/dev/null || test_fail "no backup message output for $fn"
     diff $diffopt "$fromdir/$fn" "$todir/$fn" || test_fail "copy of $fn failed"
index 7f92e48..cf4e94d 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2004 by Chris Shoemaker <c.shoemaker@cox.net>
 
index 8cd6c10..467d402 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2002 by Martin Pool <mbp@samba.org>
 
@@ -16,8 +16,7 @@
 mygrps="`rsync_getgroups`" || test_fail "Can't get groups"
 mkdir "$fromdir"
 
-for g in $mygrps
-do
+for g in $mygrps; do
     name="$fromdir/foo-$g"
     date > "$name"
     chgrp "$g" "$name" || test_fail "Can't chgrp"
index 81fd38c..ddf764c 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2002 by Martin Pool <mbp@samba.org>
 
@@ -31,7 +31,7 @@ chmod 770 "$dir2"
 # Copy the files we've created over to another directory
 checkit "$RSYNC -avv '$fromdir/' '$checkdir/'" "$fromdir" "$checkdir"
 
-# And then manually make the changes which should occur 
+# And then manually make the changes which should occur
 umask 002
 chmod ug-s,a+rX "$checkdir"/*
 chmod +w "$checkdir" "$checkdir"/dir*
index d31a1bd..362d9d9 100644 (file)
@@ -1,6 +1,6 @@
-#! /bin/sh
+#!/bin/sh
 
-# Copyright (C) 2004-2020 Wayne Davison
+# Copyright (C) 2004-2022 Wayne Davison
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
@@ -17,7 +17,7 @@ sdev=`$TOOLDIR/getfsdev $scratchdir`
 tdev=$sdev
 
 for tmpdir2 in "${RSYNC_TEST_TMP:-/override-tmp-not-specified}" /run/shm /var/tmp /tmp; do
-    [ -d "$tmpdir2" -a -w "$tmpdir2" ] || continue
+    [ -d "$tmpdir2" ] && [ -w "$tmpdir2" ] || continue
     tdev=`$TOOLDIR/getfsdev "$tmpdir2"`
     [ x$sdev != x$tdev ] && break
 done
index f2dd439..1646a9c 100644 (file)
@@ -1,6 +1,6 @@
-#! /bin/sh
+#!/bin/sh
 
-# Copyright (C) 2004-2020 Wayne Davison
+# Copyright (C) 2004-2022 Wayne Davison
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
index 3aec55a..b53413e 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2002 by Martin Pool <mbp@samba.org>
 
@@ -15,7 +15,7 @@
 
 case $0 in
 *fake*)
-    $RSYNC --version | grep "[, ] xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests"
+    $RSYNC -VV | grep '"xattrs": true' >/dev/null || test_skipped "Rsync needs xattrs for fake device tests"
     RSYNC="$RSYNC --fake-super"
     TLS_ARGS="$TLS_ARGS --fake-super"
     case "$HOST_OS" in
diff --git a/testsuite/compare-dest.test b/testsuite/compare-dest.test
deleted file mode 100644 (file)
index 7f193c5..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#! /bin/sh
-
-# Copyright (C) 2004-2020 Wayne Davison
-
-# This program is distributable under the terms of the GNU GPL (see
-# COPYING).
-
-# Test rsync handling of the --compare-dest option.
-
-. "$suitedir/rsync.fns"
-
-alt1dir="$tmpdir/alt1"
-alt2dir="$tmpdir/alt2"
-
-# Build some files/dirs/links to copy
-
-hands_setup
-
-# Setup the alt and chk dirs
-$RSYNC -av --include=text --include='*/' --exclude='*' "$fromdir/" "$alt1dir/"
-$RSYNC -av --include=etc-ltr-list --include='*/' --exclude='*' "$fromdir/" "$alt2dir/"
-
-sleep 1
-touch "$fromdir/dir/text"
-
-$RSYNC -av --exclude=/text --exclude=etc-ltr-list "$fromdir/" "$chkdir/"
-
-# Let's do it!
-checkit "$RSYNC -avv --no-whole-file \
-    --compare-dest='$alt1dir' --compare-dest='$alt2dir' \
-    '$fromdir/' '$todir/'" "$chkdir" "$todir"
-checkit "$RSYNC -avv --no-whole-file \
-    --copy-dest='$alt1dir' --copy-dest='$alt2dir' \
-    '$fromdir/' '$todir/'" "$fromdir" "$todir"
-
-# The script would have aborted on error, so getting here means we've won.
-exit 0
index aa71b45..456f0a5 100644 (file)
@@ -1,16 +1,16 @@
-#! /bin/sh
+#!/bin/sh
 
 # Test rsync copying create times
 
 . "$suitedir/rsync.fns"
 
-$RSYNC --version | grep "[, ] crtimes" >/dev/null || test_skipped "Rsync is configured without crtimes support"
+$RSYNC -VV | grep '"crtimes": true' >/dev/null || test_skipped "Rsync is configured without crtimes support"
 
 # Setting an older time via touch sets the create time to the mtime.
 # Setting it to a newer time affects just the mtime.
 
 mkdir "$fromdir"
-echo hiho "$fromdir/foo"
+echo hiho >"$fromdir/foo"
 
 touch -t 200101011111.11 "$fromdir"
 touch -t 200202022222.22 "$fromdir"
index 836ce33..60aa334 100644 (file)
@@ -21,9 +21,6 @@
 
 . "$suitedir/rsync.fns"
 
-chkfile="$scratchdir/rsync.chk"
-outfile="$scratchdir/rsync.out"
-
 SSH="src/support/lsh.sh --no-cd"
 FILE_REPL='s/^\([^d][^ ]*\) *\(..........[0-9]\) /\1 \2 /'
 DIR_REPL='s/^\(d[^ ]*\)  *[0-9][.,0-9]* /\1         DIR /'
@@ -57,21 +54,17 @@ test-to             r/w
 test-scratch           NOCOMMENT
 EOT
 
-$RSYNC -ve "$SSH" --rsync-path="$RSYNC$confopt" localhost:: | tee "$outfile"
+checkdiff2 "$RSYNC -ve '$SSH' --rsync-path='$RSYNC$confopt' localhost::"
 echo '===='
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 0 failed"
 
 RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
 export RSYNC_CONNECT_PROG
 
-$RSYNC -v localhost:: | tee "$outfile"
+checkdiff2 "$RSYNC -v localhost::"
 echo '===='
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
 
-$RSYNC -r localhost::test-hidden \
-    | sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -r localhost::test-hidden" \
+       "sed -e '$FILE_REPL' -e '$DIR_REPL' -e '$LS_REPL'" <<EOT
 drwxr-xr-x         DIR ####/##/## ##:##:## .
 drwxr-xr-x         DIR ####/##/## ##:##:## bar
 -rw-r--r--           4 ####/##/## ##:##:## bar/two
@@ -80,24 +73,18 @@ drwxr-xr-x         DIR ####/##/## ##:##:## bar/baz
 drwxr-xr-x         DIR ####/##/## ##:##:## foo
 -rw-r--r--           4 ####/##/## ##:##:## foo/one
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
 
-$RSYNC -r localhost::test-from/f* \
-    | sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -r localhost::test-from/f*" \
+       "sed -e '$FILE_REPL' -e '$DIR_REPL' -e '$LS_REPL'" <<EOT
 drwxr-xr-x         DIR ####/##/## ##:##:## foo
 -rw-r--r--           4 ####/##/## ##:##:## foo/one
 EOT
 diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
 
-if $RSYNC --version | grep "[, ] atimes" >/dev/null; then
-    $RSYNC -rU localhost::test-from/f* \
-       | sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \
-       | tee "$outfile"
-    cat <<EOT >"$chkfile"
+if $RSYNC -VV | grep '"atimes": true' >/dev/null; then
+    checkdiff "$RSYNC -rU localhost::test-from/f*" \
+       "sed -e '$FILE_REPL' -e '$DIR_REPL' -e '$LS_REPL'" <<EOT
 drwxr-xr-x         DIR ####/##/## ##:##:##                     foo
 -rw-r--r--           4 ####/##/## ##:##:## ####/##/## ##:##:## foo/one
 EOT
-    diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
 fi
diff --git a/testsuite/delay-updates.test b/testsuite/delay-updates.test
new file mode 100644 (file)
index 0000000..3b6226b
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Test rsync --delay-updates
+
+. "$suitedir/rsync.fns"
+
+mkdir "$fromdir"
+
+echo 1 > "$fromdir/foo"
+
+checkit "$RSYNC -aiv --delay-updates \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
+
+mkdir "$todir/.~tmp~"
+echo 2 > "$todir/.~tmp~/foo"
+touch -r .. "$todir/.~tmp~/foo" "$todir/foo"
+echo 3 > "$fromdir/foo"
+
+checkit "$RSYNC -aiv --delay-updates \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
+
+# The script would have aborted on error, so getting here means we've won.
+exit 0
index 8c19827..2a9df7c 100644 (file)
@@ -1,11 +1,11 @@
-#! /bin/sh
+#!/bin/sh
 
-# Copyright (C) 2005-2020 Wayne Davison
+# Copyright (C) 2005-2022 Wayne Davison
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
 
-# Test rsync handling of various delete directives.  
+# Test rsync handling of various delete directives.
 
 . "$suitedir/rsync.fns"
 
@@ -23,12 +23,12 @@ echo extra >"$todir"/emptydir/subdir/remove4
 # Also, make sure that --dry-run --del doesn't output anything extraneous.
 $RSYNC -av "$fromdir/" "$chkdir/copy/" >"$tmpdir/copy.out" 2>&1
 cat "$tmpdir/copy.out"
-egrep -v '^(created directory|sent|total size) ' "$tmpdir/copy.out" >"$tmpdir/copy.new"
+grep -E -v '^(created directory|sent|total size) ' "$tmpdir/copy.out" >"$tmpdir/copy.new"
 mv "$tmpdir/copy.new" "$tmpdir/copy.out"
 
 $RSYNC -avn --del "$fromdir/" "$chkdir/copy2/" >"$tmpdir/copy2.out" 2>&1 || true
 cat "$tmpdir/copy2.out"
-egrep -v '^(created directory|sent|total size) ' "$tmpdir/copy2.out" >"$tmpdir/copy2.new"
+grep -E -v '^(created directory|sent|total size) ' "$tmpdir/copy2.out" >"$tmpdir/copy2.new"
 mv "$tmpdir/copy2.new" "$tmpdir/copy2.out"
 
 diff $diffopt "$tmpdir/copy.out" "$tmpdir/copy2.out"
index 56ab2c5..ad5f936 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2002 by Martin Pool <mbp@samba.org>
 
@@ -9,14 +9,11 @@
 
 . "$suitedir/rsync.fns"
 
-chkfile="$scratchdir/rsync.chk"
-outfile="$scratchdir/rsync.out"
-
 # Build some hardlinks
 
 case $0 in
 *fake*)
-    $RSYNC --version | grep "[, ] xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests"
+    $RSYNC -VV | grep '"xattrs": true' >/dev/null || test_skipped "Rsync needs xattrs for fake device tests"
     RSYNC="$RSYNC --fake-super"
     TLS_ARGS="$TLS_ARGS --fake-super"
     case "$HOST_OS" in
@@ -97,7 +94,7 @@ esac
 
 # TODO: Need to test whether hardlinks are possible on this OS/filesystem
 
-$RSYNC --version | grep "[, ] hardlink-special" >/dev/null && CAN_HLINK_SPECIAL=yes || CAN_HLINK_SPECIAL=no
+$RSYNC -VV | grep '"hardlink_specials": true' >/dev/null && CAN_HLINK_SPECIAL=yes || CAN_HLINK_SPECIAL=no
 
 mkdir "$fromdir"
 mkdir "$todir"
@@ -116,33 +113,21 @@ mkfifo "$fromdir/fifo" || mknod "$fromdir/fifo" p || test_skipped "Can't run mkf
 # Work around time rounding/truncating issue by touching both files.
 touch -r "$fromdir/block" "$fromdir/block" "$fromdir/block2"
 
-$RSYNC -ai "$fromdir/block" "$todir/block2" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -ai '$fromdir/block' '$todir/block2'" <<EOT
 cD$all_plus block
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
 
-$RSYNC -ai "$fromdir/block2" "$todir/block" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -ai '$fromdir/block2' '$todir/block'" <<EOT
 cD$all_plus block2
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
 
 sleep 1
 
-$RSYNC -Di "$fromdir/block3" "$todir/block" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -Di '$fromdir/block3' '$todir/block'" <<EOT
 cDc.T.$dots block3
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
 
-$RSYNC -aiHvv "$fromdir/" "$todir/" \
-    | tee "$outfile"
-filter_outfile
-cat <<EOT >"$chkfile"
+cat >"$chkfile" <<EOT
 .d..t.$dots ./
 cDc.t.$dots block
 cDc...$dots block2
@@ -157,7 +142,8 @@ if test "$CAN_HLINK_SPECIAL" = no; then
     grep -v block3.5 <"$chkfile" >"$chkfile.new"
     mv "$chkfile.new" "$chkfile"
 fi
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
+
+checkdiff2 "$RSYNC -aiHvv '$fromdir/' '$todir/'" v_filt
 
 echo "check how the directory listings compare with diff:"
 echo ""
@@ -167,9 +153,8 @@ diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to"
 
 if test "$CAN_HLINK_SPECIAL" = yes; then
     set -x
-    $RSYNC -aii --link-dest="$todir" "$fromdir/" "$chkdir/" \
-       | tee "$outfile"
-    cat <<EOT >"$chkfile"
+    checkdiff "$RSYNC -aii --link-dest='$todir' '$fromdir/' '$chkdir/'" <<EOT
+created directory $chkdir
 cd$allspace ./
 hD$allspace block
 hD$allspace block2
@@ -180,7 +165,6 @@ hD$allspace char2
 hD$allspace char3
 hS$allspace fifo
 EOT
-    diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
 fi
 
 # The script would have aborted on error, so getting here means we've won.
index dadc550..d6b9a3c 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
index e64b808..3317e72 100644 (file)
@@ -1,11 +1,11 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2002 by Martin Pool <mbp@samba.org>
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
 
-# Test rsync handling of duplicate filenames.  
+# Test rsync handling of duplicate filenames.
 
 # It's quite possible that the user might specify the same source file
 # more than once on the command line, perhaps through shell variables
@@ -29,18 +29,14 @@ name2="$fromdir/name2"
 echo "This is the file" > "$name1"
 ln -s "$name1" "$name2" || test_fail "can't create symlink"
 
-outfile="$scratchdir/rsync.out"
-
 checkit "$RSYNC -avv '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$todir/'" "$fromdir" "$todir" \
     | tee "$outfile"
 
 # Make sure each file was only copied once...
-if [ `grep -c '^name1$' "$outfile"` != 1 ]
-then
+if [ `grep -c '^name1$' "$outfile"` != 1 ]; then
     test_fail "name1 was not copied exactly once"
 fi
-if [ `grep -c '^name2 -> ' "$outfile"` != 1 ]
-then
+if [ `grep -c '^name2 -> ' "$outfile"` != 1 ]; then
     test_fail "name2 was not copied exactly once"
 fi
 
diff --git a/testsuite/exclude-lsh.test b/testsuite/exclude-lsh.test
new file mode 120000 (symlink)
index 0000000..84bc98a
--- /dev/null
@@ -0,0 +1 @@
+exclude.test
\ No newline at end of file
index fad4fd7..56b68b8 100644 (file)
@@ -1,6 +1,6 @@
-#! /bin/sh
+#!/bin/sh
 
-# Copyright (C) 2003-2020 Wayne Davison
+# Copyright (C) 2003-2022 Wayne Davison
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
 
 . "$suitedir/rsync.fns"
 
-chkfile="$scratchdir/rsync.chk"
-outfile="$scratchdir/rsync.out"
-
 CVSIGNORE='*.junk'
 export CVSIGNORE
 
+case $0 in
+*-lsh.*)
+    RSYNC_RSH="$scratchdir/src/support/lsh.sh"
+    export RSYNC_RSH
+    rpath=" --rsync-path='$RSYNC'"
+    host='lh:'
+    ;;
+*)
+    rpath=''
+    host=''
+    ;;
+esac
+
 # Build some files/dirs/links to copy
 
 makepath "$fromdir/foo/down/to/you"
@@ -109,8 +119,8 @@ home-cvs-exclude
 EOF
 
 # Start with a check of --prune-empty-dirs:
-$RSYNC -av -f -_foo/too/ -f -_foo/down/ -f -_foo/and/ -f -_new/ "$fromdir/" "$chkdir/"
-checkit "$RSYNC -av --prune-empty-dirs '$fromdir/' '$todir/'" "$chkdir" "$todir"
+$RSYNC -av --rsync-path="$RSYNC" -f -_foo/too/ -f -_foo/down/ -f -_foo/and/ -f -_new/ "$host$fromdir/" "$chkdir/"
+checkit "$RSYNC -av$rpath --prune-empty-dirs '$host$fromdir/' '$todir/'" "$chkdir" "$todir"
 rm -rf "$todir"
 
 # Add a directory symlink.
@@ -118,11 +128,12 @@ ln -s too "$fromdir/bar/down/to/foo/sym"
 
 # Start to prep an --update test dir
 mkdir "$scratchdir/up1" "$scratchdir/up2"
-touch "$scratchdir/up1/older" "$scratchdir/up2/newer"
+touch "$scratchdir/up1/dst-newness" "$scratchdir/up2/src-newness"
+touch "$scratchdir/up1/same-newness" "$scratchdir/up2/same-newness"
 touch "$scratchdir/up1/extra-src" "$scratchdir/up2/extra-dest"
 
 # Create chkdir with what we expect to be excluded.
-checkit "$RSYNC -avv '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
+checkit "$RSYNC -avv$rpath '$host$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
 sleep 1 # Ensures that the rm commands will tweak the directory times.
 rm -r "$chkdir"/foo/down
 rm -r "$chkdir"/mid/for/foo/and
@@ -133,16 +144,16 @@ rm "$chkdir"/bar/down/to/foo/to "$chkdir"/bar/down/to/foo/file[235-9]
 rm "$chkdir"/mid/for/foo/extra
 
 # Finish prep for the --update test (run last)
-touch "$scratchdir/up1/newer" "$scratchdir/up2/older"
+touch "$scratchdir/up1/src-newness" "$scratchdir/up2/dst-newness"
 
 # Un-tweak the directory times in our first (weak) exclude test (though
 # it's a good test of the --existing option).
-$RSYNC -av --existing --include='*/' --exclude='*' "$fromdir/" "$chkdir/"
+$RSYNC -av --rsync-path="$RSYNC" --existing --include='*/' --exclude='*' "$host$fromdir/" "$chkdir/"
 
 # Now, test if rsync excludes the same files.
 
-checkit "$RSYNC -avv --exclude-from='$excl' \
-    --delete-during '$fromdir/' '$todir/'" "$chkdir" "$todir"
+checkit "$RSYNC -avv$rpath --exclude-from='$excl' \
+    --delete-during '$host$fromdir/' '$todir/'" "$chkdir" "$todir"
 
 # Modify the chk dir by removing cvs-ignored files and then tweaking the dir times.
 
@@ -152,13 +163,15 @@ rm "$chkdir"/bar/down/to/foo/*.junk
 rm "$chkdir"/bar/down/to/home-cvs-exclude
 rm "$chkdir"/mid/one-in-one-out
 
-$RSYNC -av --existing --filter='exclude,! */' "$fromdir/" "$chkdir/"
+$RSYNC -av --rsync-path="$RSYNC" --existing --filter='exclude,! */' "$host$fromdir/" "$chkdir/"
 
 # Now, test if rsync excludes the same files, this time with --cvs-exclude
 # and --delete-excluded.
 
-checkit "$RSYNC -avvC --filter='merge $excl' --delete-excluded \
-    --delete-during '$fromdir/' '$todir/'" "$chkdir" "$todir"
+# The -C option gets applied in a different order when pushing & pulling, so we instead
+# add the 2 --cvs-exclude filter rules (":C" & "-C") via -f to keep the order the same.
+checkit "$RSYNC -avv$rpath --filter='merge $excl' -f:C -f-C --delete-excluded \
+    --delete-during '$host$fromdir/' '$todir/'" "$chkdir" "$todir"
 
 # Modify the chk dir for our merge-exclude test and then tweak the dir times.
 
@@ -167,19 +180,19 @@ rm "$chkdir"/bar/down/to/bar/baz/*.deep
 cp_touch "$fromdir"/bar/down/to/foo/*.junk "$chkdir"/bar/down/to/foo
 cp_touch "$fromdir"/bar/down/to/foo/to "$chkdir"/bar/down/to/foo
 
-$RSYNC -av --existing -f 'show .filt*' -f 'hide,! */' --del "$fromdir/" "$todir/"
+$RSYNC -av --rsync-path="$RSYNC" --existing -f 'show .filt*' -f 'hide,! */' --del "$host$fromdir/" "$todir/"
 
 echo retained >"$todir"/bar/down/to/bar/baz/nodel.deep
 cp_touch "$todir"/bar/down/to/bar/baz/nodel.deep "$chkdir"/bar/down/to/bar/baz
 
-$RSYNC -av --existing --filter='-! */' "$fromdir/" "$chkdir/"
+$RSYNC -av --rsync-path="$RSYNC" --existing --filter='-! */' "$host$fromdir/" "$chkdir/"
 
 # Now, test if rsync excludes the same files, this time with a merge-exclude
 # file.
 
 checkit "sed '/!/d' '$excl' |
-    $RSYNC -avv -f dir-merge_.filt -f merge_- \
-    --delete-during '$fromdir/' '$todir/'" "$chkdir" "$todir"
+    $RSYNC -avv$rpath -f dir-merge_.filt -f merge_- \
+    --delete-during '$host$fromdir/' '$todir/'" "$chkdir" "$todir"
 
 # Remove the files that will be deleted.
 
@@ -190,14 +203,14 @@ rm "$chkdir"/bar/down/to/foo/.filt2
 rm "$chkdir"/bar/down/to/bar/.filt2
 rm "$chkdir"/mid/.filt
 
-$RSYNC -av --protocol=28 --existing --include='*/' --exclude='*' "$fromdir/" "$chkdir/"
+$RSYNC -av --rsync-path="$RSYNC" --existing --include='*/' --exclude='*' "$host$fromdir/" "$chkdir/"
 
 # Now, try the prior command with --delete-before and some side-specific
 # rules.
 
 checkit "sed '/!/d' '$excl' |
-    $RSYNC -avv -f :s_.filt -f .s_- -f P_nodel.deep \
-    --delete-before '$fromdir/' '$todir/'" "$chkdir" "$todir"
+    $RSYNC -avv$rpath -f :s_.filt -f .s_- -f P_nodel.deep \
+    --delete-before '$host$fromdir/' '$todir/'" "$chkdir" "$todir"
 
 # Next, we'll test some rule-restricted filter files.
 
@@ -208,32 +221,32 @@ cat >"$fromdir/bar/down/to/foo/.excl" <<EOF
 + file3
 *.bak
 EOF
-$RSYNC -av --del "$fromdir/" "$chkdir/"
+$RSYNC -av --rsync-path="$RSYNC" --del "$host$fromdir/" "$chkdir/"
 rm "$chkdir/bar/down/to/foo/file1.bak"
 rm "$chkdir/bar/down/to/foo/file3"
 rm "$chkdir/bar/down/to/foo/+ file3"
-$RSYNC -av --existing --filter='-! */' "$fromdir/" "$chkdir/"
-$RSYNC -av --delete-excluded --exclude='*' "$fromdir/" "$todir/"
+$RSYNC -av --rsync-path="$RSYNC" --existing --filter='-! */' "$host$fromdir/" "$chkdir/"
+$RSYNC -av --rsync-path="$RSYNC" --delete-excluded --exclude='*' "$host$fromdir/" "$todir/"
 
-checkit "$RSYNC -avv -f dir-merge,-_.excl \
-    '$fromdir/' '$todir/'" "$chkdir" "$todir"
+checkit "$RSYNC -avv$rpath -f dir-merge,-_.excl \
+    '$host$fromdir/' '$todir/'" "$chkdir" "$todir"
 
 relative_opts='--relative --chmod=Du+w --copy-unsafe-links'
-$RSYNC -av $relative_opts "$fromdir/foo" "$chkdir/"
+$RSYNC -av --rsync-path="$RSYNC" $relative_opts "$host$fromdir/foo" "$chkdir/"
 rm -rf "$chkdir$fromdir/foo/down"
 $RSYNC -av $relative_opts --existing --filter='-! */' "$fromdir/foo" "$chkdir/"
 
-checkit "$RSYNC -avv $relative_opts --exclude='$fromdir/foo/down' \
-    '$fromdir/foo' '$todir'" "$chkdir$fromdir/foo" "$todir$fromdir/foo"
+checkit "$RSYNC -avv$rpath $relative_opts --exclude='$fromdir/foo/down' \
+    '$host$fromdir/foo' '$todir'" "$chkdir$fromdir/foo" "$todir$fromdir/foo"
 
 # Now we'll test the --update option.
-$RSYNC -aiO --update touch "$scratchdir/up1/" "$scratchdir/up2/" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -aiiO$rpath --update --info=skip '$host$scratchdir/up1/' '$scratchdir/up2/'" \
+       "grep -v '^\.d$allspace'" <<EOT
+dst-newness is newer
 >f$all_plus extra-src
->f..t.$dots newer
+.f$allspace same-newness
+>f..t.$dots src-newness
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "--update test failed"
 
 # The script would have aborted on error, so getting here means we've won.
 exit 0
index 05a64e4..8f09d8f 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
index 05c5b06..101ffd3 100644 (file)
@@ -1,6 +1,6 @@
-#! /bin/sh
+#!/bin/sh
 
-# Copyright (C) 2005-2020 Wayne Davison
+# Copyright (C) 2005-2022 Wayne Davison
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
index 740d725..af2ea40 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2002 by Martin Pool <mbp@samba.org>
 
@@ -13,8 +13,6 @@
 
 SSH="$scratchdir/src/support/lsh.sh"
 
-outfile="$scratchdir/rsync.out"
-
 # Build some hardlinks
 
 fromdir="$scratchdir/from"
@@ -70,7 +68,7 @@ echo "This is another file" >"$fromdir/solo"
 ln "$fromdir/solo" "$chkdir/solo" || test_fail "Can't create hardlink"
 
 # Make sure that the checksum data doesn't slide due to an HLINK_BUMP() change.
-$RSYNC -aHivc --debug=HLINK5 "$fromdir/" "$chkdir/" | tee "$outfile"
+checktee "$RSYNC -aHivc --debug=HLINK5 '$fromdir/' '$chkdir/'"
 grep solo "$outfile" && test_fail "Erroneous copy of solo file occurred!"
 
 # Make sure there's nothing wrong with sending a single file with -H
index 9988cb7..c1c57c5 100644 (file)
@@ -1,6 +1,6 @@
-#! /bin/sh
+#!/bin/sh
 
-# Copyright (C) 2005-2020 Wayne Davison
+# Copyright (C) 2005-2022 Wayne Davison
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
@@ -12,9 +12,6 @@
 
 to2dir="$tmpdir/to2"
 
-chkfile="$scratchdir/rsync.chk"
-outfile="$scratchdir/rsync.out"
-
 makepath "$fromdir/foo"
 makepath "$fromdir/bar/baz"
 cp_p "$srcdir/configure.ac" "$fromdir/foo/config1"
@@ -28,10 +25,18 @@ ln "$fromdir/foo/config1" "$fromdir/foo/extra"
 rm -f "$to2dir"
 
 # Check if rsync is set to hard-link symlinks.
-if egrep '^#define CAN_HARDLINK_SYMLINK 1' config.h >/dev/null; then
+if $RSYNC -VV | grep '"hardlink_symlinks": true' >/dev/null; then
     L=hL
+    sym_dots="$allspace"
+    L_sym_dots=".L$allspace"
+    is_uptodate='is uptodate'
+    touch "$chkfile.extra"
 else
     L=cL
+    sym_dots="c.t.$dots"
+    L_sym_dots="cL$sym_dots"
+    is_uptodate='-> ../bar/baz/rsync'
+    echo "cL$sym_dots foo/sym $is_uptodate" >"$chkfile.extra"
 fi
 
 # Check if rsync can preserve time on symlinks
@@ -40,7 +45,7 @@ case "$RSYNC" in
     T=.T
     ;;
 *)
-    if $RSYNC --version | grep "[, ] symtimes" >/dev/null; then
+    if $RSYNC -VV | grep '"symtimes": true' >/dev/null; then
        T=.t
     else
        T=.T
@@ -48,9 +53,8 @@ case "$RSYNC" in
     ;;
 esac
 
-$RSYNC -iplr "$fromdir/" "$todir/" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -iplr '$fromdir/' '$todir/'" <<EOT
+created directory $todir
 cd$all_plus ./
 cd$all_plus bar/
 cd$all_plus bar/baz/
@@ -61,22 +65,18 @@ cd$all_plus foo/
 >f$all_plus foo/extra
 cL$all_plus foo/sym -> ../bar/baz/rsync
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
 
 # Ensure there are no accidental directory-time problems.
 $RSYNC -a -f '-! */' "$fromdir/" "$todir"
 
 cp_p "$srcdir/configure.ac" "$fromdir/foo/config2"
 chmod 601 "$fromdir/foo/config2"
-$RSYNC -iplrH "$fromdir/" "$todir/" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -iplrH '$fromdir/' '$todir/'" <<EOT
 >f..T.$dots bar/baz/rsync
 >f..T.$dots foo/config1
 >f.sTp$dots foo/config2
 hf..T.$dots foo/extra => foo/config1
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
 
 $RSYNC -a -f '-! */' "$fromdir/" "$todir"
 cp_p "$srcdir/config.sub" "$fromdir/foo/config2"
@@ -88,38 +88,30 @@ umask 022
 chmod 600 "$fromdir/foo/config2"
 chmod 777 "$todir/bar/baz/rsync"
 
-$RSYNC -iplrtc "$fromdir/" "$todir/" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -iplrtc '$fromdir/' '$todir/'" <<EOT
 .f..tp$dots bar/baz/rsync
 .d..t.$dots foo/
 .f..t.$dots foo/config1
 >fcstp$dots foo/config2
 cLc$T.$dots foo/sym -> ../bar/baz/rsync
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
 
 cp_p "$srcdir/configure.ac" "$fromdir/foo/config2"
 chmod 600 "$fromdir/foo/config2"
 # Lack of -t is for unchanged hard-link stress-test!
-$RSYNC -vvplrH "$fromdir/" "$todir/" \
-    | tee "$outfile"
-filter_outfile
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -vvplrH '$fromdir/' '$todir/'" \
+       v_filt <<EOT
 bar/baz/rsync is uptodate
 foo/config1 is uptodate
 foo/extra is uptodate
 foo/sym is uptodate
 foo/config2
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
 
 chmod 747 "$todir/bar/baz/rsync"
 $RSYNC -a -f '-! */' "$fromdir/" "$todir"
-$RSYNC -ivvplrtH "$fromdir/" "$todir/" \
-    | tee "$outfile"
-filter_outfile
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -ivvplrtH '$fromdir/' '$todir/'" \
+       v_filt <<EOT
 .d$allspace ./
 .d$allspace bar/
 .d$allspace bar/baz/
@@ -130,47 +122,23 @@ cat <<EOT >"$chkfile"
 hf$allspace foo/extra
 .L$allspace foo/sym -> ../bar/baz/rsync
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
 
 chmod 757 "$todir/foo/config1"
 touch "$todir/foo/config2"
-$RSYNC -vplrtH "$fromdir/" "$todir/" \
-    | tee "$outfile"
-filter_outfile
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -vplrtH '$fromdir/' '$todir/'" \
+       v_filt <<EOT
 foo/config2
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 6 failed"
 
 chmod 757 "$todir/foo/config1"
 touch "$todir/foo/config2"
-$RSYNC -iplrtH "$fromdir/" "$todir/" \
-    | tee "$outfile"
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -iplrtH '$fromdir/' '$todir/'" <<EOT
 .f...p$dots foo/config1
 >f..t.$dots foo/config2
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
 
-$RSYNC -ivvplrtH --copy-dest=../to "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
-filter_outfile
-case `tail -1 "$outfile"` in
-cLc.t*)
-    sym_dots="c.t.$dots"
-    L_sym_dots="cL$sym_dots"
-    is_uptodate='-> ../bar/baz/rsync'
-    echo "cL$sym_dots foo/sym $is_uptodate" >"$chkfile.extra"
-    L=cL
-    ;;
-*)
-    sym_dots="$allspace"
-    L_sym_dots=".L$allspace"
-    is_uptodate='is uptodate'
-    touch "$chkfile.extra"
-    ;;
-esac
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -ivvplrtH --copy-dest=../to '$fromdir/' '$to2dir/'" \
+       v_filt <<EOT
 cd$allspace ./
 cd$allspace bar/
 cd$allspace bar/baz/
@@ -181,21 +149,17 @@ cf$allspace foo/config2
 hf$allspace foo/extra => foo/config1
 cL$sym_dots foo/sym -> ../bar/baz/rsync
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
 
 rm -rf "$to2dir"
-$RSYNC -iplrtH --copy-dest=../to "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
 cat - "$chkfile.extra" <<EOT >"$chkfile"
+created directory $to2dir
 hf$allspace foo/extra => foo/config1
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
+checkdiff2 "$RSYNC -iplrtH --copy-dest=../to '$fromdir/' '$to2dir/'"
 
 rm -rf "$to2dir"
-$RSYNC -vvplrtH --copy-dest="$todir" "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
-filter_outfile
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -vvplrtH --copy-dest='$todir' '$fromdir/' '$to2dir/'" \
+       v_filt <<EOT
 ./ is uptodate
 bar/ is uptodate
 bar/baz/ is uptodate
@@ -206,13 +170,10 @@ foo/config2 is uptodate
 foo/sym $is_uptodate
 foo/extra => foo/config1
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 10 failed"
 
 rm -rf "$to2dir"
-$RSYNC -ivvplrtH --link-dest="$todir" "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
-filter_outfile
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -ivvplrtH --link-dest='$todir' '$fromdir/' '$to2dir/'" \
+       v_filt <<EOT
 cd$allspace ./
 cd$allspace bar/
 cd$allspace bar/baz/
@@ -223,27 +184,19 @@ hf$allspace foo/config2
 hf$allspace foo/extra => foo/config1
 $L$sym_dots foo/sym -> ../bar/baz/rsync
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
 
 rm -rf "$to2dir"
-$RSYNC -iplrtH --dry-run --link-dest=../to "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
 cat - "$chkfile.extra" <<EOT >"$chkfile"
+created directory $to2dir
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 12 failed"
+checkdiff2 "$RSYNC -iplrtH --dry-run --link-dest=../to '$fromdir/' '$to2dir/'"
 
 rm -rf "$to2dir"
-$RSYNC -iplrtH --link-dest=../to "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
-cat - "$chkfile.extra" <<EOT >"$chkfile"
-EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 13 failed"
+checkdiff2 "$RSYNC -iplrtH --link-dest=../to '$fromdir/' '$to2dir/'"
 
 rm -rf "$to2dir"
-$RSYNC -vvplrtH --link-dest="$todir" "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
-filter_outfile
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -vvplrtH --link-dest='$todir' '$fromdir/' '$to2dir/'" \
+       v_filt <<EOT
 ./ is uptodate
 bar/ is uptodate
 bar/baz/ is uptodate
@@ -254,13 +207,10 @@ foo/config2 is uptodate
 foo/extra is uptodate
 foo/sym $is_uptodate
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
 
 rm -rf "$to2dir"
-$RSYNC -ivvplrtH --compare-dest="$todir" "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
-filter_outfile
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -ivvplrtH --compare-dest='$todir' '$fromdir/' '$to2dir/'" \
+       v_filt <<EOT
 cd$allspace ./
 cd$allspace bar/
 cd$allspace bar/baz/
@@ -271,20 +221,16 @@ cd$allspace foo/
 .f$allspace foo/extra
 $L_sym_dots foo/sym -> ../bar/baz/rsync
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
 
 rm -rf "$to2dir"
-$RSYNC -iplrtH --compare-dest="$todir" "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
 cat - "$chkfile.extra" <<EOT >"$chkfile"
+created directory $to2dir
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 16 failed"
+checkdiff2 "$RSYNC -iplrtH --compare-dest='$todir' '$fromdir/' '$to2dir/'"
 
 rm -rf "$to2dir"
-$RSYNC -vvplrtH --compare-dest="$todir" "$fromdir/" "$to2dir/" \
-    | tee "$outfile"
-filter_outfile
-cat <<EOT >"$chkfile"
+checkdiff "$RSYNC -vvplrtH --compare-dest='$todir' '$fromdir/' '$to2dir/'" \
+       v_filt <<EOT
 ./ is uptodate
 bar/ is uptodate
 bar/baz/ is uptodate
@@ -295,7 +241,6 @@ foo/config2 is uptodate
 foo/extra is uptodate
 foo/sym $is_uptodate
 EOT
-diff $diffopt "$chkfile" "$outfile" || test_fail "test 17 failed"
 
 # The script would have aborted on error, so getting here means we've won.
 exit 0
index 9b20f73..17050a1 100644 (file)
@@ -1,6 +1,6 @@
-#! /bin/sh
+#!/bin/sh
 
-# Copyright (C) 2004-2020 Wayne Davison
+# Copyright (C) 2004-2022 Wayne Davison
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
index c6c8e57..2fbf461 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
old mode 100755 (executable)
new mode 100644 (file)
index 6efb210..8046345
@@ -25,6 +25,10 @@ rm $deep_dir/text
 mkdir $deep_dir/new
 $RSYNC -aiv --mkpath from/text $deep_dir/new
 test -f $deep_dir/new/text || test_fail "'text' file not found in $deep_dir/new dir"
+
+# ... and an existing path when an alternate dest filename is specified
+$RSYNC -aiv --mkpath from/text $deep_dir/new/text2
+test -f $deep_dir/new/text2 || test_fail "'text2' file not found in $deep_dir/new dir"
 rm -rf to/foo
 
 # Try the tests again with multiple source args
diff --git a/testsuite/protected-regular.test b/testsuite/protected-regular.test
new file mode 100644 (file)
index 0000000..40416b0
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# Copyright (C) 2021 by Achim Leitner <aleitner@lis-engineering.de>
+# This program is distributable under the terms of the GNU GPL (see COPYING)
+#
+# Modern linux systems have the protected_regular feature set to 1 or 2
+# See https://www.kernel.org/doc/Documentation/sysctl/fs.txt
+# Make sure we can still write these files in --inplace mode
+
+. "$suitedir/rsync.fns"
+
+test -f /proc/sys/fs/protected_regular || test_skipped "Can't find protected_regular setting (only available on Linux)"
+pr_lvl=`cat /proc/sys/fs/protected_regular 2>/dev/null` || test_skipped "Can't check if fs.protected_regular is enabled (probably need root)"
+test "$pr_lvl" != 0 || test_skipped "fs.protected_regular is not enabled"
+
+workdir="$tmpdir/files"
+mkdir "$workdir"
+chmod 1777 "$workdir"
+
+echo "Source" > "$workdir/src"
+echo ""       > "$workdir/dst"
+chown 5001 "$workdir/dst" || test_skipped "Can't chown (probably need root)"
+
+# Output is only shown in case of an error
+echo "Contents of $workdir:"
+ls -al "$workdir"
+
+$RSYNC --inplace "$workdir/src" "$workdir/dst" || test_fail
+
+# The script would have aborted on error, so getting here means we've won.
+exit 0
index 89e4ce1..5546291 100644 (file)
@@ -20,8 +20,6 @@ echo wowza >"$extrafile"
 
 $RSYNC -av --existing --include='*/' --exclude='*' "$fromdir/" "$extradir/"
 
-outfile="$scratchdir/rsync.out"
-
 cd "$fromdir"
 
 # Main script starts here
index 68389e7..2ab97b6 100644 (file)
@@ -12,7 +12,7 @@
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU Lesser General Public
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -22,6 +22,9 @@ fromdir="$tmpdir/from"
 todir="$tmpdir/to"
 chkdir="$tmpdir/chk"
 
+chkfile="$scratchdir/rsync.chk"
+outfile="$scratchdir/rsync.out"
+
 # For itemized output:
 all_plus='+++++++++'
 allspace='         '
@@ -42,13 +45,12 @@ export HOME
 
 runtest() {
     echo $ECHO_N "Test $1: $ECHO_C"
-    if eval "$2"
-    then
-       echo "$ECHO_T   done."
-       return 0
+    if eval "$2"; then
+        echo "$ECHO_T  done."
+        return 0
     else
-       echo "$ECHO_T failed!"
-       return 1
+        echo "$ECHO_T failed!"
+        return 1
     fi
 }
 
@@ -63,7 +65,7 @@ set_cp_destdir() {
 # even if the copy rounded microsecond times on the destination file.
 cp_touch() {
     cp_p "${@}"
-    if test $# -gt 2 -o -d "$2"; then
+    if test $# -gt 2 || test -d "$2"; then
        set_cp_destdir "${@}" # sets destdir var
        while test $# -gt 1; do
            destname="$destdir/`basename $1`"
@@ -75,10 +77,10 @@ cp_touch() {
     fi
 }
 
-# Call this if you want to filter out verbose messages (-v or -vv) from
-# the output of an rsync run (whittling the output down to just the file
-# messages).  This isn't needed if you use -i without -v.
-filter_outfile() {
+# Call this if you want to filter (stdin -> stdout) verbose messages (-v or
+# -vv) from an rsync run (whittling the output down to just the file messages).
+# This isn't needed if you use -i without -v.
+v_filt() {
     sed -e '/^building file list /d' \
        -e '/^sending incremental file list/d' \
        -e '/^created directory /d' \
@@ -87,9 +89,7 @@ filter_outfile() {
        -e '/^total: /d' \
        -e '/^client charset: /d' \
        -e '/^server charset: /d' \
-       -e '/^$/,$d' \
-       <"$outfile" >"$outfile.new"
-    mv "$outfile.new" "$outfile"
+       -e '/^$/,$d'
 }
 
 printmsg() {
@@ -149,7 +149,7 @@ check_perms() {
     test_fail "failed test $3"
 }
 
-rsync_getgroups() { 
+rsync_getgroups() {
     "$TOOLDIR/getgroups"
 }
 
@@ -171,7 +171,7 @@ hands_setup() {
     # the links behave in the future, and it cannot be changed using
     # chmod!  rsync always sets its umask to 000 so that it can
     # accurately recreate permissions, but this script is probably run
-    # with a different umask. 
+    # with a different umask.
 
     # This causes a little problem that "ls -l" of the two will not be
     # the same.  So, we need to set our umask before doing any creations.
@@ -213,22 +213,19 @@ hands_setup() {
 
 ####################
 # Many machines do not have "mkdir -p", so we have to build up long paths.
-# How boring.  
+# How boring.
 makepath() {
     for p in "${@}"; do
        (echo "        makepath $p"
 
        # Absolute Unix path.
-       if echo $p | grep '^/' >/dev/null
-       then
+       if echo $p | grep '^/' >/dev/null; then
            cd /
        fi
-    
+
        # This will break if $p contains a space.
-       for c in `echo $p | tr '/' ' '`
-       do 
-           if [ -d "$c" ] || mkdir "$c" 
-           then
+       for c in `echo $p | tr '/' ' '`; do
+           if [ -d "$c" ] || mkdir "$c"; then
                cd "$c" || return $?
            else
                echo "failed to create $c" >&2; return $?
@@ -238,7 +235,6 @@ makepath() {
 }
 
 
-
 ###########################
 # Run a test (in '$1') then compare directories $2 and $3 to see if
 # there are any difference.  If there are, explain them.
@@ -262,8 +258,8 @@ checkit() {
        ;;
     esac
 
-    echo "Running: \"$1\""  
-    eval "$1" 
+    echo "Running: \"$1\""
+    eval "$1"
     status=$?
     if [ $status != 0 ]; then
        failed="$failed status=$status"
@@ -293,7 +289,7 @@ checkit() {
     fi
 
     echo "-------------"
-    if [ -z "$failed" ] ; then
+    if [ -z "$failed" ]; then
        return 0
     fi
 
@@ -302,6 +298,57 @@ checkit() {
 }
 
 
+# Run a test in $1 and make sure it has a zero exit status.  Capture the
+# output into $outfile and echo it to stdout.
+checktee() {
+    echo "Running: \"$1\""
+    eval "$1" >"$outfile"
+    status=$?
+    cat "$outfile"
+    if [ $status != 0 ]; then
+       echo "Failed: status=$status"
+       return 1
+    fi
+    return 0
+}
+
+
+# Slurp stdin into $chkfile and then call checkdiff2().
+checkdiff() {
+    cat >"$chkfile" # Save off stdin
+    checkdiff2 "${@}"
+}
+
+
+# Run a test in $1 and make sure it has a zero exit status.  Capture the output
+# into $outfile.  If $2 is set, use it to filter the outfile.  If resulting
+# outfile differs from the chkfile data, fail with an error.
+checkdiff2() {
+    failed=
+
+    echo "Running: \"$1\""
+    eval "$1" >"$outfile"
+    status=$?
+    cat "$outfile"
+    if [ $status != 0 ]; then
+       failed="$failed status=$status"
+    fi
+
+    if [ -n "$2" ]; then
+       eval "cat '$outfile' | $2 >'$outfile.new'"
+       mv "$outfile.new" "$outfile"
+    fi
+
+    diff $diffopt "$chkfile" "$outfile" || failed="$failed output differs"
+
+    if [ -n "$failed" ]; then
+       echo "Failed:$failed"
+       return 1
+    fi
+    return 0
+}
+
+
 build_rsyncd_conf() {
     # Build an appropriate configuration file
     conf="$scratchdir/test-rsyncd.conf"
@@ -404,7 +451,7 @@ test_skipped() {
     exit 77
 }
 
-# It failed, but we expected that.  don't dump out error logs, 
+# It failed, but we expected that.  Don't dump out error logs,
 # because most users won't want to see them.  But do leave
 # the working directory around.
 test_xfail() {
@@ -414,30 +461,26 @@ test_xfail() {
 
 # Determine what shell command will appropriately test for links.
 ln -s foo "$scratchdir/testlink"
-for cmd in test /bin/test /usr/bin/test /usr/ucb/bin/test /usr/ucb/test
-do
-    for switch in -h -L
-    do
-        if $cmd $switch "$scratchdir/testlink" 2>/dev/null
-       then
-           # how nice
-           TEST_SYMLINK_CMD="$cmd $switch"
-           # i wonder if break 2 is portable?
-           break 2
-       fi
-   done
+for cmd in test /bin/test /usr/bin/test /usr/ucb/bin/test /usr/ucb/test; do
+    for switch in -h -L; do
+        if $cmd $switch "$scratchdir/testlink" 2>/dev/null; then
+            # how nice
+            TEST_SYMLINK_CMD="$cmd $switch"
+            # i wonder if break 2 is portable?
+            break 2
+        fi
+    done
 done
 # ok, now get rid of it
 rm "$scratchdir/testlink"
 
 
-if [ "x$TEST_SYMLINK_CMD" = 'x' ]
-then
+if [ "x$TEST_SYMLINK_CMD" = 'x' ]; then
     test_fail "Couldn't determine how to test for symlinks"
 else
     echo "Testing for symlinks using '$TEST_SYMLINK_CMD'"
 fi
-       
+
 
 # Test whether something is a link, allowing for shell peculiarities
 is_a_link() {
@@ -451,5 +494,5 @@ is_a_link() {
 # directory has to be writable by the nobody user in some cases.  The
 # best thing is probably to explicitly chmod those directories after
 # creation.
+
 umask 022
index 4bcbdfe..1559ca2 100644 (file)
@@ -13,7 +13,7 @@
 SSH="$scratchdir/src/support/lsh.sh"
 
 if test x"$rsync_enable_ssh_tests" = xyes; then
-    if type ssh >/dev/null ; then
+    if type ssh >/dev/null; then
        SSH=ssh
     fi
 fi
index eec7a30..7055a92 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2001 by Martin Pool <mbp@samba.org>
 
@@ -18,18 +18,15 @@ $RSYNC -r "$fromdir/" "$todir" || test_fail "$RSYNC returned $?"
 
 [ -f "$todir/referent" ] || test_fail "referent was not copied"
 [ -d "$todir/from" ] && test_fail "extra level of directories"
-if is_a_link "$todir/dangling" 
-then 
+if is_a_link "$todir/dangling"; then
     test_fail "dangling symlink was copied"
 fi
 
-if is_a_link "$todir/relative" 
-then
-    test_fail "relative symlink was copied" 
+if is_a_link "$todir/relative"; then
+    test_fail "relative symlink was copied"
 fi
 
-if is_a_link "$todir/absolute" 
-then
+if is_a_link "$todir/absolute"; then
     test_fail "absolute symlink was copied"
 fi
 
index ec551e6..2efaa07 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2002 by Martin Pool <mbp@samba.org>
 
index 55df086..75e7201 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Copyright (C) 2002 by Martin Pool
 
@@ -13,9 +13,8 @@ test_unsafe() {
     # or "unsafe" otherwise
 
     result=`"$TOOLDIR/t_unsafe" "$1" "$2"` || test_fail "Failed to check $1 $2"
-    if [ "$result" != "$3" ]
-    then
-       test_fail "t_unsafe $1 $2 returned \"$result\", expected \"$3\""
+    if [ "$result" != "$3" ]; then
+        test_fail "t_unsafe $1 $2 returned \"$result\", expected \"$3\""
     fi
 }
 
index 479d606..2d209eb 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # Originally by Vladimír Michl <Vladimir.Michl@hlubocky.del.cz>
 
@@ -6,13 +6,13 @@
 
 test_symlink() {
        is_a_link "$1" || test_fail "File $1 is not a symlink"
-};
+}
 
 test_regular() {
        if [ ! -f "$1" ]; then
-               test_fail "File $1 is not regular file or not exists";
-       fi;
-};
+               test_fail "File $1 is not regular file or not exists"
+       fi
+}
 
 cd "$tmpdir"
 
@@ -32,7 +32,7 @@ ln -s ../files/file1 "from/safe/links/"
 ln -s ../files/file2 "from/safe/links/"
 ln -s ../../unsafe/unsafefile "from/safe/links/"
 
-echo "rsync with relative path and just -a";
+echo "rsync with relative path and just -a"
 $RSYNC -avv from/safe/ to
 test_symlink to/links/file1
 test_symlink to/links/file2
@@ -44,23 +44,22 @@ test_regular to/links/file1
 test_regular to/links/file2
 test_regular to/links/unsafefile
 
-echo "rsync with relative path and --copy-unsafe-links";
+echo "rsync with relative path and --copy-unsafe-links"
 $RSYNC -avv --copy-unsafe-links from/safe/ to
 test_symlink to/links/file1
 test_symlink to/links/file2
 test_regular to/links/unsafefile
 
 rm -rf to
-echo "rsync with relative2 path";
+echo "rsync with relative2 path"
 (cd from; $RSYNC -avv --copy-unsafe-links safe/ ../to)
 test_symlink to/links/file1
 test_symlink to/links/file2
 test_regular to/links/unsafefile
 
 rm -rf to
-echo "rsync with absolute path";
+echo "rsync with absolute path"
 $RSYNC -avv --copy-unsafe-links `pwd`/from/safe/ to
 test_symlink to/links/file1
 test_symlink to/links/file2
 test_regular to/links/unsafefile
-
index 12b872c..cfe7584 100644 (file)
@@ -1,6 +1,6 @@
-#! /bin/sh
+#!/bin/sh
 
-# Copyright (C) 2003-2020 Wayne Davison
+# Copyright (C) 2003-2022 Wayne Davison
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
index 59fe160..d94d5f9 100644 (file)
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 # This program is distributable under the terms of the GNU GPL (see
 # COPYING).
@@ -8,7 +8,7 @@
 . $suitedir/rsync.fns
 lnkdir="$tmpdir/lnk"
 
-$RSYNC --version | grep "[, ] xattrs" >/dev/null || test_skipped "Rsync is configured without xattr support"
+$RSYNC -VV | grep '"xattrs": true' >/dev/null || test_skipped "Rsync is configured without xattr support"
 
 case "$HOST_OS" in
 darwin*)
@@ -150,7 +150,7 @@ xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" -
 
 cd "$fromdir"
 
-if [ "$dashH" ]; then
+if [ -n "$dashH" ]; then
     for fn in $files; do
        name=`basename $fn`
        ln $fn ../lnk/$name
@@ -162,7 +162,7 @@ checkit "$RSYNC -aiX $XFILT $dashH --super $altDest=../chk . ../to" "$fromdir" "
 cd "$todir"
 xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" -
 
-[ "$dashH" ] && rm -rf "$lnkdir"
+[ -n "$dashH" ] && rm -rf "$lnkdir"
 
 cd "$fromdir"
 rm -rf "$todir"
@@ -177,7 +177,7 @@ cd "$todir"
 xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" -
 
 sed -n -e '/^[^d ][^ ]*  *[^ ][^ ]*  *[^ ][^ ]*  *1 /p' "$scratchdir/ls-to" >"$scratchdir/ls-diff-all"
-fgrep -v './file1' "$scratchdir/ls-diff-all" >"$scratchdir/ls-diff" || :
+grep -F -v './file1' "$scratchdir/ls-diff-all" >"$scratchdir/ls-diff" || :
 if [ -s "$scratchdir/ls-diff" ]; then
     echo "Missing hard links on:"
     cat "$scratchdir/ls-diff"
@@ -213,13 +213,13 @@ $RSYNC -aX file1 file2
 $RSYNC -aX file1 file2 ../chk/
 $RSYNC -aX --del ../chk/ .
 $RSYNC -aX file1 ../lnk/
-[ "$dashH" ] && ln "$chkdir/file1" ../lnk/extra-link
+[ -n "$dashH" ] && ln "$chkdir/file1" ../lnk/extra-link
 
 xls file1 file2 >"$scratchdir/xattrs.txt"
 
 checkit "$RSYNC -aiiX $XFILT $dashH $altDest=../lnk . ../to" "$chkdir" "$todir"
 
-[ "$dashH" ] && rm ../lnk/extra-link
+[ -n "$dashH" ] && rm ../lnk/extra-link
 
 cd "$todir"
 xls file1 file2 | diff $diffopt "$scratchdir/xattrs.txt" -
diff --git a/tls.c b/tls.c
index c50fa6c..e6b0708 100644 (file)
--- a/tls.c
+++ b/tls.c
@@ -2,7 +2,7 @@
  * Trivial ls for comparing two directories after running an rsync.
  *
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -60,7 +60,8 @@ int nsec_times = 0;
 
 static int stat_xattr(const char *fname, STRUCT_STAT *fst)
 {
-       int mode, rdev_major, rdev_minor, uid, gid, len;
+       unsigned int mode;
+       int rdev_major, rdev_minor, uid, gid, len;
        char buf[256];
 
        if (am_root >= 0 || IS_DEVICE(fst->st_mode) || IS_SPECIAL(fst->st_mode))
@@ -159,7 +160,7 @@ static void list_file(const char *fname)
        if (do_lstat(fname, &buf) < 0)
                failed("stat", fname);
 #ifdef SUPPORT_CRTIMES
-       if (display_crtimes && (crtime = get_create_time(fname)) == 0)
+       if (display_crtimes && (crtime = get_create_time(fname, &buf)) == 0)
                failed("get_create_time", fname);
 #endif
 #ifdef SUPPORT_XATTRS
diff --git a/token.c b/token.c
index 61be8dd..c108b3a 100644 (file)
--- a/token.c
+++ b/token.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
@@ -39,7 +39,6 @@ extern char *skip_compress;
 #define Z_INSERT_ONLY Z_SYNC_FLUSH
 #endif
 
-static int compression_level; /* The compression level for the current file. */
 static int skip_compression_level; /* The least possible compressing for handling skip-compress files. */
 static int per_file_default_level; /* The default level that each new file gets prior to checking its suffix. */
 
@@ -224,9 +223,11 @@ static void init_set_compression(void)
 /* determine the compression level based on a wildcard filename list */
 void set_compression(const char *fname)
 {
+#if 0 /* No compression algorithms currently allow mid-stream changing of the level. */
        const struct suffix_tree *node;
        const char *s;
        char ltr;
+#endif
 
        if (!do_compression)
                return;
@@ -234,6 +235,7 @@ void set_compression(const char *fname)
        if (!match_list)
                init_set_compression();
 
+#if 0
        compression_level = per_file_default_level;
 
        if (!*match_list && !suftree)
@@ -270,6 +272,9 @@ void set_compression(const char *fname)
                if (!(node = node->child))
                        return;
        }
+#else
+       (void)fname;
+#endif
 }
 
 /* non-compressing recv token */
@@ -361,7 +366,7 @@ send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset, in
                        tx_strm.next_in = NULL;
                        tx_strm.zalloc = NULL;
                        tx_strm.zfree = NULL;
-                       if (deflateInit2(&tx_strm, compression_level,
+                       if (deflateInit2(&tx_strm, per_file_default_level,
                                         Z_DEFLATED, -15, 8,
                                         Z_DEFAULT_STRATEGY) != Z_OK) {
                                rprintf(FERROR, "compression init failed\n");
@@ -570,7 +575,7 @@ static int32 recv_deflated_token(int f, char **data)
                                rx_strm.avail_in = 4;
                                rx_strm.next_in = (Bytef *)cbuf;
                                cbuf[0] = cbuf[1] = 0;
-                               cbuf[2] = cbuf[3] = 0xff;
+                               cbuf[2] = cbuf[3] = (char)0xff;
                                inflate(&rx_strm, Z_SYNC_FLUSH);
                                recv_state = r_idle;
                        }
index 8884742..99a3467 100644 (file)
--- a/uidlist.c
+++ b/uidlist.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
- * Copyright (C) 2004-2020 Wayne Davison
+ * Copyright (C) 2004-2022 Wayne Davison
  *
  * 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
@@ -63,6 +63,16 @@ struct idlist {
 static struct idlist *uidlist, *uidmap;
 static struct idlist *gidlist, *gidmap;
 
+static inline int id_eq_uid(id_t id, uid_t uid)
+{
+       return id == (id_t)uid;
+}
+
+static inline int id_eq_gid(id_t id, gid_t gid)
+{
+       return id == (id_t)gid;
+}
+
 static id_t id_parse(const char *num_str)
 {
        id_t tmp, num = 0;
@@ -200,7 +210,7 @@ static int is_in_group(gid_t gid)
                        ngroups = getgroups(ngroups, gidset);
                /* The default gid might not be in the list on some systems. */
                for (n = 0; n < ngroups; n++) {
-                       if (gidset[n] == our_gid)
+                       if ((gid_t)gidset[n] == our_gid)
                                break;
                }
                if (n == ngroups)
@@ -219,7 +229,7 @@ static int is_in_group(gid_t gid)
 
        last_in = gid;
        for (n = 0; n < ngroups; n++) {
-               if (gidset[n] == gid)
+               if ((gid_t)gidset[n] == gid)
                        return last_out = 1;
        }
        return last_out = 0;
@@ -263,10 +273,10 @@ static struct idlist *recv_add_id(struct idlist **idlist_ptr, struct idlist *idm
        else if (*name && id) {
                if (idlist_ptr == &uidlist) {
                        uid_t uid;
-                       id2 = user_to_uid(name, &uid, False) ? uid : id;
+                       id2 = user_to_uid(name, &uid, False) ? (id_t)uid : id;
                } else {
                        gid_t gid;
-                       id2 = group_to_gid(name, &gid, False) ? gid : id;
+                       id2 = group_to_gid(name, &gid, False) ? (id_t)gid : id;
                }
        } else
                id2 = id;
@@ -289,11 +299,11 @@ uid_t match_uid(uid_t uid)
        static struct idlist *last = NULL;
        struct idlist *list;
 
-       if (last && uid == last->id)
+       if (last && id_eq_uid(last->id, uid))
                return last->id2;
 
        for (list = uidlist; list; list = list->next) {
-               if (list->id == uid)
+               if (id_eq_uid(list->id, uid))
                        break;
        }
 
@@ -309,11 +319,11 @@ gid_t match_gid(gid_t gid, uint16 *flags_ptr)
        static struct idlist *last = NULL;
        struct idlist *list;
 
-       if (last && gid == last->id)
+       if (last && id_eq_gid(last->id, gid))
                list = last;
        else {
                for (list = gidlist; list; list = list->next) {
-                       if (list->id == gid)
+                       if (id_eq_gid(list->id, gid))
                                break;
                }
                if (!list)
@@ -334,7 +344,7 @@ const char *add_uid(uid_t uid)
        union name_or_id noiu;
 
        for (list = uidlist; list; list = list->next) {
-               if (list->id == uid)
+               if (id_eq_uid(list->id, uid))
                        return NULL;
        }
 
@@ -351,7 +361,7 @@ const char *add_gid(gid_t gid)
        union name_or_id noiu;
 
        for (list = gidlist; list; list = list->next) {
-               if (list->id == gid)
+               if (id_eq_gid(list->id, gid))
                        return NULL;
        }
 
diff --git a/usage.c b/usage.c
index 66857bb..a5b59ad 100644 (file)
--- a/usage.c
+++ b/usage.c
@@ -1,7 +1,7 @@
 /*
  * Some usage & version related functions.
  *
- * Copyright (C) 2002-2020 Wayne Davison
+ * Copyright (C) 2002-2022 Wayne Davison
  *
  * 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
  */
 
 #include "rsync.h"
+#include "version.h"
 #include "latest-year.h"
 #include "git-version.h"
 #include "default-cvsignore.h"
+#include "itypes.h"
 
-extern struct name_num_obj valid_checksums;
-extern struct name_num_obj valid_compressions;
+extern struct name_num_obj valid_checksums, valid_compressions, valid_auth_checksums;
 
 static char *istring(const char *fmt, int val)
 {
@@ -36,7 +37,8 @@ static char *istring(const char *fmt, int val)
 static void print_info_flags(enum logcode f)
 {
        STRUCT_STAT *dumstat;
-       char line_buf[75];
+       BOOL as_json = f == FNONE ? 1 : 0; /* We use 1 == first attribute, 2 == need closing array */
+       char line_buf[75], item_buf[32];
        int line_len, j;
        char *info_flags[] = {
 
@@ -52,6 +54,16 @@ static void print_info_flags(enum logcode f)
 #endif
                        "socketpairs",
 
+#ifndef SUPPORT_LINKS
+               "no "
+#endif
+                       "symlinks",
+
+#ifndef CAN_SET_SYMLINK_TIMES
+               "no "
+#endif
+                       "symtimes",
+
 #ifndef SUPPORT_HARD_LINKS
                "no "
 #endif
@@ -62,10 +74,10 @@ static void print_info_flags(enum logcode f)
 #endif
                        "hardlink-specials",
 
-#ifndef SUPPORT_LINKS
+#ifndef CAN_HARDLINK_SYMLINK
                "no "
 #endif
-                       "symlinks",
+                       "hardlink-symlinks",
 
 #ifndef INET6
                "no "
@@ -99,23 +111,18 @@ static void print_info_flags(enum logcode f)
 #endif
                        "xattrs",
 
-#ifdef RSYNC_USE_PROTECTED_ARGS
+#ifdef RSYNC_USE_SECLUDED_ARGS
                "default "
 #else
                "optional "
 #endif
-                       "protect-args",
+                       "secluded-args",
 
 #ifndef ICONV_OPTION
                "no "
 #endif
                        "iconv",
 
-#ifndef CAN_SET_SYMLINK_TIMES
-               "no "
-#endif
-                       "symtimes",
-
 #ifndef SUPPORT_PREALLOCATION
                "no "
 #endif
@@ -133,64 +140,161 @@ static void print_info_flags(enum logcode f)
 
        "*Optimizations",
 
-#ifndef HAVE_SIMD
+#ifndef USE_ROLL_SIMD
                "no "
 #endif
-                       "SIMD",
+                       "SIMD-roll",
 
-#ifndef HAVE_ASM
+#ifndef USE_ROLL_ASM
                "no "
 #endif
-                       "asm",
+                       "asm-roll",
 
 #ifndef USE_OPENSSL
                "no "
 #endif
                        "openssl-crypto",
 
+#ifndef USE_MD5_ASM
+               "no "
+#endif
+                       "asm-MD5",
+
                NULL
        };
 
        for (line_len = 0, j = 0; ; j++) {
                char *str = info_flags[j], *next_nfo = str ? info_flags[j+1] : NULL;
-               int str_len = str && *str != '*' ? strlen(str) : 1000;
                int need_comma = next_nfo && *next_nfo != '*' ? 1 : 0;
-               if (line_len && line_len + 1 + str_len + need_comma >= (int)sizeof line_buf) {
-                       rprintf(f, "   %s\n", line_buf);
+               int item_len;
+               if (!str || *str == '*')
+                       item_len = 1000;
+               else if (as_json) {
+                       char *space = strchr(str, ' ');
+                       int is_no = space && strncmp(str, "no ", 3) == 0;
+                       int is_bits = space && isDigit(str);
+                       char *quot = space && !is_no && !is_bits ? "\"" : "";
+                       char *item = space ? space + 1 : str;
+                       char *val = !space ? "true" : is_no ? "false" : str;
+                       int val_len = !space ? 4 : is_no ? 5 : space - str;
+                       if (is_bits && (space = strchr(val, '-')) != NULL)
+                           val_len = space - str;
+                       item_len = snprintf(item_buf, sizeof item_buf,
+                                          " \"%s%s\": %s%.*s%s%s", item, is_bits ? "bits" : "",
+                                          quot, val_len, val, quot, need_comma ? "," : "");
+                       if (is_bits)
+                               item_buf[strlen(item)+2-1] = '_'; /* Turn the 's' into a '_' */
+                       for (space = item; (space = strpbrk(space, " -")) != NULL; space++)
+                               item_buf[space - item + 2] = '_';
+               } else
+                       item_len = snprintf(item_buf, sizeof item_buf, " %s%s", str, need_comma ? "," : "");
+               if (line_len && line_len + item_len >= (int)sizeof line_buf) {
+                       if (as_json)
+                               printf("   %s\n", line_buf);
+                       else
+                               rprintf(f, "   %s\n", line_buf);
                        line_len = 0;
                }
                if (!str)
                        break;
                if (*str == '*') {
-                       rprintf(f, "%s:\n", str+1);
-                       continue;
+                       if (as_json) {
+                               if (as_json == 2)
+                                       printf("  }");
+                               else
+                                       as_json = 2;
+                               printf(",\n  \"%c%s\": {\n", toLower(str+1), str+2);
+                       } else
+                               rprintf(f, "%s:\n", str+1);
+               } else {
+                       strlcpy(line_buf + line_len, item_buf, sizeof line_buf - line_len);
+                       line_len += item_len;
                }
-               line_len += snprintf(line_buf+line_len, sizeof line_buf - line_len, " %s%s", str, need_comma ? "," : "");
        }
+       if (as_json == 2)
+               printf("  }");
 }
 
-void print_rsync_version(enum logcode f)
+static void output_nno_list(enum logcode f, const char *name, struct name_num_obj *nno)
 {
-       char tmpbuf[256], *subprotocol = "";
+       char namebuf[64], tmpbuf[256];
+       char *tok, *next_tok, *comma = ",";
+       char *cp;
+
+       /* Using '(' ensures that we get a trailing "none" but also includes aliases. */
+       get_default_nno_list(nno, tmpbuf, sizeof tmpbuf - 1, '(');
+       if (f != FNONE) {
+               rprintf(f, "%s:\n", name);
+               rprintf(f, "    %s\n", tmpbuf);
+               return;
+       }
+
+       strlcpy(namebuf, name, sizeof namebuf);
+       for (cp = namebuf; *cp; cp++) {
+               if (*cp == ' ')
+                       *cp = '_';
+               else if (isUpper(cp))
+                       *cp = toLower(cp);
+       }
+
+       printf(",\n  \"%s\": [\n   ", namebuf);
+
+       for (tok = strtok(tmpbuf, " "); tok; tok = next_tok) {
+               next_tok = strtok(NULL, " ");
+               if (*tok != '(') /* Ignore the alises in the JSON output */
+                       printf(" \"%s\"%s", tok, comma + (next_tok ? 0 : 1));
+       }
+
+       printf("\n  ]");
+}
 
+/* A request of f == FNONE wants json on stdout. */
+void print_rsync_version(enum logcode f)
+{
+       char copyright[] = "(C) 1996-" LATEST_YEAR " by Andrew Tridgell, Wayne Davison, and others.";
+       char url[] = "https://rsync.samba.org/";
+       BOOL first_line = 1;
+
+#define json_line(name, value) \
+       do { \
+               printf("%c\n  \"%s\": \"%s\"", first_line ? '{' : ',', name, value); \
+               first_line = 0; \
+       } while (0)
+
+       if (f == FNONE) {
+               char verbuf[32];
+               json_line("program", RSYNC_NAME);
+               json_line("version", rsync_version());
+               (void)snprintf(verbuf, sizeof verbuf, "%d.%d", PROTOCOL_VERSION, SUBPROTOCOL_VERSION);
+               json_line("protocol", verbuf);
+               json_line("copyright", copyright);
+               json_line("url", url);
+       } else {
 #if SUBPROTOCOL_VERSION != 0
-       subprotocol = istring(".PR%d", SUBPROTOCOL_VERSION);
+               char *subprotocol = istring(".PR%d", SUBPROTOCOL_VERSION);
+#else
+               char *subprotocol = "";
 #endif
-       rprintf(f, "%s  version %s  protocol version %d%s\n",
-               RSYNC_NAME, rsync_version(), PROTOCOL_VERSION, subprotocol);
-
-       rprintf(f, "Copyright (C) 1996-" LATEST_YEAR " by Andrew Tridgell, Wayne Davison, and others.\n");
-       rprintf(f, "Web site: https://rsync.samba.org/\n");
+               rprintf(f, "%s  version %s  protocol version %d%s\n",
+                       RSYNC_NAME, rsync_version(), PROTOCOL_VERSION, subprotocol);
+               rprintf(f, "Copyright %s\n", copyright);
+               rprintf(f, "Web site: %s\n", url);
+       }
 
        print_info_flags(f);
 
-       rprintf(f, "Checksum list:\n");
-       get_default_nno_list(&valid_checksums, tmpbuf, sizeof tmpbuf, '(');
-       rprintf(f, "    %s\n", tmpbuf);
+       init_checksum_choices();
 
-       rprintf(f, "Compress list:\n");
-       get_default_nno_list(&valid_compressions, tmpbuf, sizeof tmpbuf, '(');
-       rprintf(f, "    %s\n", tmpbuf);
+       output_nno_list(f, "Checksum list", &valid_checksums);
+       output_nno_list(f, "Compress list", &valid_compressions);
+       output_nno_list(f, "Daemon auth list", &valid_auth_checksums);
+
+       if (f == FNONE) {
+               json_line("license", "GPLv3");
+               json_line("caveat", "rsync comes with ABSOLUTELY NO WARRANTY");
+               printf("\n}\n");
+               return;
+       }
 
 #ifdef MAINTAINER_MODE
        rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
@@ -234,7 +338,7 @@ void usage(enum logcode F)
 #include "help-rsync.h"
   rprintf(F,"\n");
   rprintf(F,"Use \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
-  rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
+  rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) manpages for full documentation.\n");
   rprintf(F,"See https://rsync.samba.org/ for updates, bug reports, and answers\n");
 }
 
@@ -247,12 +351,18 @@ void daemon_usage(enum logcode F)
 #include "help-rsyncd.h"
   rprintf(F,"\n");
   rprintf(F,"If you were not trying to invoke rsync as a daemon, avoid using any of the\n");
-  rprintf(F,"daemon-specific rsync options.  See also the rsyncd.conf(5) man page.\n");
+  rprintf(F,"daemon-specific rsync options.  See also the rsyncd.conf(5) manpage.\n");
 }
 
 const char *rsync_version(void)
 {
-       return RSYNC_GITVER;
+       char *ver;
+#ifdef RSYNC_GITVER
+       ver = RSYNC_GITVER;
+#else
+       ver = RSYNC_VERSION;
+#endif
+       return *ver == 'v' ? ver+1 : ver;
 }
 
 const char *default_cvsignore(void)
diff --git a/util.c b/util1.c
similarity index 94%
rename from util.c
rename to util1.c
index b2b1989..da50ff1 100644 (file)
--- a/util.c
+++ b/util1.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2022 Wayne Davison
  *
  * 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
 
 extern int dry_run;
 extern int module_id;
+extern int do_fsync;
 extern int protect_args;
 extern int modify_window;
 extern int relative_paths;
-extern int preserve_times;
 extern int preserve_xattrs;
+extern int omit_link_times;
 extern int preallocate_files;
 extern char *module_dir;
 extern unsigned int module_dirlen;
@@ -158,8 +159,8 @@ int set_times(const char *fname, STRUCT_STAT *stp)
 
 #include "case_N.h"
                switch_step++;
-               if (preserve_times & PRESERVE_LINK_TIMES) {
-                       preserve_times &= ~PRESERVE_LINK_TIMES;
+               if (!omit_link_times) {
+                       omit_link_times = 1;
                        if (S_ISLNK(stp->st_mode))
                                return 1;
                }
@@ -318,16 +319,48 @@ static int safe_read(int desc, char *ptr, size_t len)
        return n_chars;
 }
 
-/* Copy a file.  If ofd < 0, copy_file unlinks and opens the "dest" file.
- * Otherwise, it just writes to and closes the provided file descriptor.
+/* Remove existing file @dest and reopen, creating a new file with @mode */
+static int unlink_and_reopen(const char *dest, mode_t mode)
+{
+       int ofd;
+
+       if (robust_unlink(dest) && errno != ENOENT) {
+               int save_errno = errno;
+               rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest));
+               errno = save_errno;
+               return -1;
+       }
+
+#ifdef SUPPORT_XATTRS
+       if (preserve_xattrs)
+               mode |= S_IWUSR;
+#endif
+       mode &= INITACCESSPERMS;
+       if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0) {
+               int save_errno = errno;
+               rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(dest));
+               errno = save_errno;
+               return -1;
+       }
+       return ofd;
+}
+
+/* Copy contents of file @source to file @dest with mode @mode.
+ *
+ * If @tmpfilefd is < 0, copy_file unlinks @dest and then opens a new
+ * file with name @dest.
+ *
+ * Otherwise, copy_file writes to and closes the provided file
+ * descriptor.
+ *
  * In either case, if --xattrs are being preserved, the dest file will
  * have its xattrs set from the source file.
  *
  * This is used in conjunction with the --temp-dir, --backup, and
  * --copy-dest options. */
-int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
+int copy_file(const char *source, const char *dest, int tmpfilefd, mode_t mode)
 {
-       int ifd;
+       int ifd, ofd;
        char buf[1024 * 8];
        int len;   /* Number of bytes read into `buf'. */
        OFF_T prealloc_len = 0, offset = 0;
@@ -339,23 +372,12 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
                return -1;
        }
 
-       if (ofd < 0) {
-               if (robust_unlink(dest) && errno != ENOENT) {
-                       int save_errno = errno;
-                       rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest));
-                       close(ifd);
-                       errno = save_errno;
-                       return -1;
-               }
-
-#ifdef SUPPORT_XATTRS
-               if (preserve_xattrs)
-                       mode |= S_IWUSR;
-#endif
-               mode &= INITACCESSPERMS;
-               if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0) {
+       if (tmpfilefd >= 0) {
+               ofd = tmpfilefd;
+       } else {
+               ofd = unlink_and_reopen(dest, mode);
+               if (ofd < 0) {
                        int save_errno = errno;
-                       rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(dest));
                        close(ifd);
                        errno = save_errno;
                        return -1;
@@ -406,16 +428,28 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
 
        /* Source file might have shrunk since we fstatted it.
         * Cut off any extra preallocated zeros from dest file. */
-       if (offset < prealloc_len && do_ftruncate(ofd, offset) < 0) {
+       if (offset < prealloc_len) {
+#ifdef HAVE_FTRUNCATE
                /* If we fail to truncate, the dest file may be wrong, so we
                 * must trigger the "partial transfer" error. */
-               rsyserr(FERROR_XFER, errno, "ftruncate %s", full_fname(dest));
+               if (do_ftruncate(ofd, offset) < 0)
+                       rsyserr(FERROR_XFER, errno, "ftruncate %s", full_fname(dest));
+#else
+               rprintf(FERROR_XFER, "no ftruncate for over-long pre-alloc: %s", full_fname(dest));
+#endif
+       }
+
+       if (do_fsync && fsync(ofd) < 0) {
+               int save_errno = errno;
+               rsyserr(FERROR, errno, "fsync failed on %s", full_fname(dest));
+               close(ofd);
+               errno = save_errno;
+               return -1;
        }
 
        if (close(ofd) < 0) {
                int save_errno = errno;
-               rsyserr(FERROR_XFER, errno, "close failed on %s",
-                       full_fname(dest));
+               rsyserr(FERROR_XFER, errno, "close failed on %s", full_fname(dest));
                errno = save_errno;
                return -1;
        }
@@ -1349,7 +1383,7 @@ int same_time(time_t f1_sec, unsigned long f1_nsec, time_t f2_sec, unsigned long
                return f1_sec == f2_sec;
        if (modify_window < 0)
                return f1_sec == f2_sec && f1_nsec == f2_nsec;
-       /* The nano seconds doesn't figure into these checks -- time windows don't care about that. */
+       /* The nanoseconds do not figure into these checks -- time windows don't care about that. */
        if (f2_sec > f1_sec)
                return f2_sec - f1_sec <= modify_window;
        return f1_sec - f2_sec <= modify_window;
@@ -1453,12 +1487,19 @@ const char *find_filename_suffix(const char *fn, int fn_len, int *len_ptr)
 
 #define UNIT (1 << 16)
 
-uint32 fuzzy_distance(const char *s1, unsigned len1, const char *s2, unsigned len2)
+uint32 fuzzy_distance(const char *s1, unsigned len1, const char *s2, unsigned len2, uint32 upperlimit)
 {
        uint32 a[MAXPATHLEN], diag, above, left, diag_inc, above_inc, left_inc;
        int32 cost;
        unsigned i1, i2;
 
+       /* Check to see if the Levenshtein distance must be greater than the
+        * upper limit defined by the previously found lowest distance using
+        * the heuristic that the Levenshtein distance is greater than the
+        * difference in length of the two strings */
+       if ((len1 > len2 ? len1 - len2 : len2 - len1) * UNIT > upperlimit)
+               return 0xFFFFU * UNIT + 1;
+
        if (!len1 || !len2) {
                if (!len1) {
                        s1 = s2;
index e2fb963..fdfce4c 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1 +1,2 @@
-#define RSYNC_VERSION "3.2.3"
+#define RSYNC_VERSION "3.2.7"
+#define MAINTAINER_TZ_OFFSET -7.0
index bcb4bca..26e50a6 100644 (file)
--- a/xattrs.c
+++ b/xattrs.c
@@ -3,7 +3,7 @@
  * Written by Jay Fenlason, vaguely based on the ACLs patch.
  *
  * Copyright (C) 2004 Red Hat, Inc.
- * Copyright (C) 2006-2020 Wayne Davison
+ * Copyright (C) 2006-2022 Wayne Davison
  *
  * 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
@@ -39,9 +39,13 @@ extern int preserve_specials;
 extern int checksum_seed;
 extern int saw_xattr_filter;
 
+extern struct name_num_item *xattr_sum_nni;
+extern int xattr_sum_len;
+
 #define RSYNC_XAL_INITIAL 5
 #define RSYNC_XAL_LIST_INITIAL 100
 
+#define MAX_XATTR_DIGEST_LEN MD5_DIGEST_LEN
 #define MAX_FULL_DATUM 32
 
 #define HAS_PREFIX(str, prfx) (*(str) == *(prfx) && strncmp(str, prfx, sizeof (prfx) - 1) == 0)
@@ -269,8 +273,8 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
 
                if (datum_len > MAX_FULL_DATUM) {
                        /* For large datums, we store a flag and a checksum. */
-                       name_offset = 1 + MAX_DIGEST_LEN;
-                       sum_init(-1, checksum_seed);
+                       name_offset = 1 + MAX_XATTR_DIGEST_LEN;
+                       sum_init(xattr_sum_nni, checksum_seed);
                        sum_update(ptr, datum_len);
                        free(ptr);
 
@@ -377,20 +381,14 @@ static int64 xattr_lookup_hash(const item_list *xalp)
 {
        const rsync_xa *rxas = xalp->items;
        size_t i;
-       int64 key = hashlittle(&xalp->count, sizeof xalp->count);
+       int64 key = hashlittle2(&xalp->count, sizeof xalp->count);
 
        for (i = 0; i < xalp->count; i++) {
-               key += hashlittle(rxas[i].name, rxas[i].name_len);
+               key += hashlittle2(rxas[i].name, rxas[i].name_len);
                if (rxas[i].datum_len > MAX_FULL_DATUM)
-                       key += hashlittle(rxas[i].datum, MAX_DIGEST_LEN);
+                       key += hashlittle2(rxas[i].datum, xattr_sum_len);
                else
-                       key += hashlittle(rxas[i].datum, rxas[i].datum_len);
-       }
-
-       if (key == 0) {
-               /* This is very unlikely, but we should never
-                * return 0 as hashtable_find() doesn't like it. */
-               return 1;
+                       key += hashlittle2(rxas[i].datum, rxas[i].datum_len);
        }
 
        return key;
@@ -435,7 +433,7 @@ static int find_matching_xattr(const item_list *xalp)
                        if (rxas1[j].datum_len > MAX_FULL_DATUM) {
                                if (memcmp(rxas1[j].datum + 1,
                                           rxas2[j].datum + 1,
-                                          MAX_DIGEST_LEN) != 0)
+                                          xattr_sum_len) != 0)
                                        break;
                        } else {
                                if (memcmp(rxas1[j].datum, rxas2[j].datum,
@@ -471,8 +469,6 @@ static int rsync_xal_store(item_list *xalp)
 
        if (rsync_xal_h == NULL)
                rsync_xal_h = hashtable_create(512, HT_KEY64);
-       if (rsync_xal_h == NULL)
-               out_of_memory("rsync_xal_h hashtable_create()");
 
        new_ref = new0(rsync_xa_list_ref);
        new_ref->ndx = ndx;
@@ -535,7 +531,7 @@ int send_xattr(int f, stat_x *sxp)
 #endif
                        write_buf(f, name, name_len);
                        if (rxa->datum_len > MAX_FULL_DATUM)
-                               write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
+                               write_buf(f, rxa->datum + 1, xattr_sum_len);
                        else
                                write_bigbuf(f, rxa->datum, rxa->datum_len);
                }
@@ -588,7 +584,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
                else if (snd_rxa->datum_len > MAX_FULL_DATUM) {
                        same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
                            && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
-                                     MAX_DIGEST_LEN) == 0;
+                                     xattr_sum_len) == 0;
                        /* Flag unrequested items that we need. */
                        if (!same && find_all && snd_rxa->datum[0] == XSTATE_ABBREV)
                                snd_rxa->datum[0] = XSTATE_TODO;
@@ -797,7 +793,7 @@ void receive_xattr(int f, struct file_struct *file)
                rsync_xa *rxa;
                size_t name_len = read_varint(f);
                size_t datum_len = read_varint(f);
-               size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
+               size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + (size_t)xattr_sum_len : datum_len;
                size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
                if (SIZE_MAX - dget_len < extra_len || SIZE_MAX - dget_len - extra_len < name_len)
                        overflow_exit("receive_xattr");
@@ -812,7 +808,7 @@ void receive_xattr(int f, struct file_struct *file)
                        read_buf(f, ptr, dget_len);
                else {
                        *ptr = XSTATE_ABBREV;
-                       read_buf(f, ptr + 1, MAX_DIGEST_LEN);
+                       read_buf(f, ptr + 1, xattr_sum_len);
                }
 
                if (saw_xattr_filter) {
@@ -943,7 +939,7 @@ static int rsync_xal_set(const char *fname, item_list *xalp,
        rsync_xa *rxas = xalp->items;
        ssize_t list_len;
        size_t i, len;
-       char *name, *ptr, sum[MAX_DIGEST_LEN];
+       char *name, *ptr, sum[MAX_XATTR_DIGEST_LEN];
 #ifdef HAVE_LINUX_XATTRS
        int user_only = am_root <= 0;
 #endif
@@ -958,7 +954,6 @@ static int rsync_xal_set(const char *fname, item_list *xalp,
                name = rxas[i].name;
 
                if (XATTR_ABBREV(rxas[i])) {
-                       int sum_len;
                        /* See if the fnamecmp version is identical. */
                        len = name_len = rxas[i].name_len;
                        if ((ptr = get_xattr_data(fnamecmp, name, &len, 1)) == NULL) {
@@ -975,10 +970,10 @@ static int rsync_xal_set(const char *fname, item_list *xalp,
                                goto still_abbrev;
                        }
 
-                       sum_init(-1, checksum_seed);
+                       sum_init(xattr_sum_nni, checksum_seed);
                        sum_update(ptr, len);
-                       sum_len = sum_end(sum);
-                       if (memcmp(sum, rxas[i].datum + 1, sum_len) != 0) {
+                       sum_end(sum);
+                       if (memcmp(sum, rxas[i].datum + 1, xattr_sum_len) != 0) {
                                free(ptr);
                                goto still_abbrev;
                        }
@@ -1055,7 +1050,7 @@ int set_xattr(const char *fname, const struct file_struct *file, const char *fna
 {
        rsync_xa_list *glst = rsync_xal_l.items;
        item_list *lst;
-       int ndx;
+       int ndx, added_write_perm = 0;
 
        if (dry_run)
                return 1; /* FIXME: --dry-run needs to compute this value */
@@ -1084,10 +1079,23 @@ int set_xattr(const char *fname, const struct file_struct *file, const char *fna
        }
 #endif
 
+       /* If the target file lacks write permission, we try to add it
+        * temporarily so we can change the extended attributes. */
+       if (!am_root
+#ifdef SUPPORT_LINKS
+        && !S_ISLNK(sxp->st.st_mode)
+#endif
+        && access(fname, W_OK) < 0
+        && do_chmod(fname, (sxp->st.st_mode & CHMOD_BITS) | S_IWUSR) == 0)
+               added_write_perm = 1;
+
        ndx = F_XATTR(file);
        glst += ndx;
        lst = &glst->xa_items;
-       return rsync_xal_set(fname, lst, fnamecmp, sxp);
+       int return_value = rsync_xal_set(fname, lst, fnamecmp, sxp);
+       if (added_write_perm) /* remove the temporary write permission */
+               do_chmod(fname, sxp->st.st_mode);
+       return return_value;
 }
 
 #ifdef SUPPORT_ACLS
@@ -1118,7 +1126,8 @@ int del_def_xattr_acl(const char *fname)
 
 int get_stat_xattr(const char *fname, int fd, STRUCT_STAT *fst, STRUCT_STAT *xst)
 {
-       int mode, rdev_major, rdev_minor, uid, gid, len;
+       unsigned int mode;
+       int rdev_major, rdev_minor, uid, gid, len;
        char buf[256];
 
        if (am_root >= 0 || IS_DEVICE(fst->st_mode) || IS_SPECIAL(fst->st_mode))
index 529c5e8..2cbc4fc 100644 (file)
@@ -227,11 +227,6 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
     int wrap = 1;
     static const char my_version[] = ZLIB_VERSION;
 
-    ushf *overlay;
-    /* We overlay pending_buf and d_buf+l_buf. This works since the average
-     * output size for (length,distance) codes is <= 24 bits.
-     */
-
     if (version == Z_NULL || version[0] != my_version[0] ||
         stream_size != sizeof(z_stream)) {
         return Z_VERSION_ERROR;
@@ -300,9 +295,47 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
 
     s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
 
-    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
-    s->pending_buf = (uchf *) overlay;
-    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+    /* We overlay pending_buf and sym_buf. This works since the average size
+     * for length/distance pairs over any compressed block is assured to be 31
+     * bits or less.
+     *
+     * Analysis: The longest fixed codes are a length code of 8 bits plus 5
+     * extra bits, for lengths 131 to 257. The longest fixed distance codes are
+     * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
+     * possible fixed-codes length/distance pair is then 31 bits total.
+     *
+     * sym_buf starts one-fourth of the way into pending_buf. So there are
+     * three bytes in sym_buf for every four bytes in pending_buf. Each symbol
+     * in sym_buf is three bytes -- two for the distance and one for the
+     * literal/length. As each symbol is consumed, the pointer to the next
+     * sym_buf value to read moves forward three bytes. From that symbol, up to
+     * 31 bits are written to pending_buf. The closest the written pending_buf
+     * bits gets to the next sym_buf symbol to read is just before the last
+     * code is written. At that time, 31*(n-2) bits have been written, just
+     * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at
+     * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1
+     * symbols are written.) The closest the writing gets to what is unread is
+     * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and
+     * can range from 128 to 32768.
+     *
+     * Therefore, at a minimum, there are 142 bits of space between what is
+     * written and what is read in the overlain buffers, so the symbols cannot
+     * be overwritten by the compressed data. That space is actually 139 bits,
+     * due to the three-bit fixed-code block header.
+     *
+     * That covers the case where either Z_FIXED is specified, forcing fixed
+     * codes, or when the use of fixed codes is chosen, because that choice
+     * results in a smaller compressed block than dynamic codes. That latter
+     * condition then assures that the above analysis also covers all dynamic
+     * blocks. A dynamic-code block will only be chosen to be emitted if it has
+     * fewer bits than a fixed-code block would for the same set of symbols.
+     * Therefore its average symbol length is assured to be less than 31. So
+     * the compressed data for a dynamic block also cannot overwrite the
+     * symbols from which it is being constructed.
+     */
+
+    s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
+    s->pending_buf_size = (ulg)s->lit_bufsize * 4;
 
     if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
         s->pending_buf == Z_NULL) {
@@ -311,8 +344,12 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
         deflateEnd (strm);
         return Z_MEM_ERROR;
     }
-    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
-    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+    s->sym_buf = s->pending_buf + s->lit_bufsize;
+    s->sym_end = (s->lit_bufsize - 1) * 3;
+    /* We avoid equality with lit_bufsize*3 because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
 
     s->level = level;
     s->strategy = strategy;
@@ -473,7 +510,7 @@ int ZEXPORT deflatePrime (strm, bits, value)
 
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     s = strm->state;
-    if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+    if (s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
         return Z_BUF_ERROR;
     do {
         put = Buf_size - s->bi_valid;
@@ -1022,7 +1059,6 @@ int ZEXPORT deflateCopy (dest, source)
 #else
     deflate_state *ds;
     deflate_state *ss;
-    ushf *overlay;
 
 
     if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
@@ -1042,8 +1078,7 @@ int ZEXPORT deflateCopy (dest, source)
     ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
     ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
     ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
-    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
-    ds->pending_buf = (uchf *) overlay;
+    ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
 
     if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
         ds->pending_buf == Z_NULL) {
@@ -1057,8 +1092,7 @@ int ZEXPORT deflateCopy (dest, source)
     zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
 
     ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
-    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
-    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+    ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
 
     ds->l_desc.dyn_tree = ds->dyn_ltree;
     ds->d_desc.dyn_tree = ds->dyn_dtree;
@@ -1737,7 +1771,7 @@ local block_state deflate_fast(s, flush)
         FLUSH_BLOCK(s, 1);
         return finish_done;
     }
-    if (s->last_lit)
+    if (s->sym_next)
         FLUSH_BLOCK(s, 0);
     return block_done;
 }
@@ -1878,7 +1912,7 @@ local block_state deflate_slow(s, flush)
         FLUSH_BLOCK(s, 1);
         return finish_done;
     }
-    if (s->last_lit)
+    if (s->sym_next)
         FLUSH_BLOCK(s, 0);
     return block_done;
 }
@@ -1953,7 +1987,7 @@ local block_state deflate_rle(s, flush)
         FLUSH_BLOCK(s, 1);
         return finish_done;
     }
-    if (s->last_lit)
+    if (s->sym_next)
         FLUSH_BLOCK(s, 0);
     return block_done;
 }
@@ -1992,7 +2026,7 @@ local block_state deflate_huff(s, flush)
         FLUSH_BLOCK(s, 1);
         return finish_done;
     }
-    if (s->last_lit)
+    if (s->sym_next)
         FLUSH_BLOCK(s, 0);
     return block_done;
 }
index ce0299e..a300a28 100644 (file)
@@ -214,7 +214,7 @@ typedef struct internal_state {
     /* Depth of each subtree used as tie breaker for trees of equal frequency
      */
 
-    uchf *l_buf;          /* buffer for literals or lengths */
+    uchf *sym_buf;        /* buffer for distances and literals/lengths */
 
     uInt  lit_bufsize;
     /* Size of match buffer for literals/lengths.  There are 4 reasons for
@@ -236,13 +236,8 @@ typedef struct internal_state {
      *   - I can't count above 4
      */
 
-    uInt last_lit;      /* running index in l_buf */
-
-    ushf *d_buf;
-    /* Buffer for distances. To simplify the code, d_buf and l_buf have
-     * the same number of elements. To use different lengths, an extra flag
-     * array would be necessary.
-     */
+    uInt sym_next;      /* running index in sym_buf */
+    uInt sym_end;       /* symbol table full when sym_next reaches this */
 
     ulg opt_len;        /* bit length of current block with optimal trees */
     ulg static_len;     /* bit length of current block with static trees */
@@ -322,20 +317,22 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
 
 # define _tr_tally_lit(s, c, flush) \
   { uch cc = (c); \
-    s->d_buf[s->last_lit] = 0; \
-    s->l_buf[s->last_lit++] = cc; \
+    s->sym_buf[s->sym_next++] = 0; \
+    s->sym_buf[s->sym_next++] = 0; \
+    s->sym_buf[s->sym_next++] = cc; \
     s->dyn_ltree[cc].Freq++; \
-    flush = (s->last_lit == s->lit_bufsize-1); \
+    flush = (s->sym_next == s->sym_end); \
    }
 # define _tr_tally_dist(s, distance, length, flush) \
   { uch len = (length); \
     ush dist = (distance); \
-    s->d_buf[s->last_lit] = dist; \
-    s->l_buf[s->last_lit++] = len; \
+    s->sym_buf[s->sym_next++] = dist; \
+    s->sym_buf[s->sym_next++] = dist >> 8; \
+    s->sym_buf[s->sym_next++] = len; \
     dist--; \
     s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
     s->dyn_dtree[d_code(dist)].Freq++; \
-    flush = (s->last_lit == s->lit_bufsize-1); \
+    flush = (s->sym_next == s->sym_end); \
   }
 #else
 # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
index e43abd9..e9840b6 100644 (file)
@@ -740,8 +740,9 @@ int flush;
                 if (copy > have) copy = have;
                 if (copy) {
                     if (state->head != Z_NULL &&
-                        state->head->extra != Z_NULL) {
-                        len = state->head->extra_len - state->length;
+                        state->head->extra != Z_NULL &&
+                        (len = state->head->extra_len - state->length) <
+                            state->head->extra_max) {
                         zmemcpy(state->head->extra + len, next,
                                 len + copy > state->head->extra_max ?
                                 state->head->extra_max - len : copy);
index 1fd7759..9c66770 100644 (file)
@@ -418,7 +418,7 @@ local void init_block(s)
 
     s->dyn_ltree[END_BLOCK].Freq = 1;
     s->opt_len = s->static_len = 0L;
-    s->last_lit = s->matches = 0;
+    s->sym_next = s->matches = 0;
 }
 
 #define SMALLEST 1
@@ -943,7 +943,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
 
         Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
                 opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
-                s->last_lit));
+                s->sym_next / 3));
 
         if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
 
@@ -1012,8 +1012,9 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
     unsigned dist;  /* distance of matched string */
     unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
 {
-    s->d_buf[s->last_lit] = (ush)dist;
-    s->l_buf[s->last_lit++] = (uch)lc;
+    s->sym_buf[s->sym_next++] = dist;
+    s->sym_buf[s->sym_next++] = dist >> 8;
+    s->sym_buf[s->sym_next++] = lc;
     if (dist == 0) {
         /* lc is the unmatched char */
         s->dyn_ltree[lc].Freq++;
@@ -1028,30 +1029,7 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc)
         s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
         s->dyn_dtree[d_code(dist)].Freq++;
     }
-
-#ifdef TRUNCATE_BLOCK
-    /* Try to guess if it is profitable to stop the current block here */
-    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
-        /* Compute an upper bound for the compressed length */
-        ulg out_length = (ulg)s->last_lit*8L;
-        ulg in_length = (ulg)((long)s->strstart - s->block_start);
-        int dcode;
-        for (dcode = 0; dcode < D_CODES; dcode++) {
-            out_length += (ulg)s->dyn_dtree[dcode].Freq *
-                (5L+extra_dbits[dcode]);
-        }
-        out_length >>= 3;
-        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
-               s->last_lit, in_length, out_length,
-               100L - out_length*100L/in_length));
-        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
-    }
-#endif
-    return (s->last_lit == s->lit_bufsize-1);
-    /* We avoid equality with lit_bufsize because of wraparound at 64K
-     * on 16 bit machines and because stored blocks are restricted to
-     * 64K-1 bytes.
-     */
+    return (s->sym_next == s->sym_end);
 }
 
 /* ===========================================================================
@@ -1064,13 +1042,14 @@ local void compress_block(s, ltree, dtree)
 {
     unsigned dist;      /* distance of matched string */
     int lc;             /* match length or unmatched char (if dist == 0) */
-    unsigned lx = 0;    /* running index in l_buf */
+    unsigned sx = 0;    /* running index in sym_buf */
     unsigned code;      /* the code to send */
     int extra;          /* number of extra bits to send */
 
-    if (s->last_lit != 0) do {
-        dist = s->d_buf[lx];
-        lc = s->l_buf[lx++];
+    if (s->sym_next != 0) do {
+        dist = s->sym_buf[sx++] & 0xff;
+        dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
+        lc = s->sym_buf[sx++];
         if (dist == 0) {
             send_code(s, lc, ltree); /* send a literal byte */
             Tracecv(isgraph(lc), (stderr," '%c' ", lc));
@@ -1095,11 +1074,10 @@ local void compress_block(s, ltree, dtree)
             }
         } /* literal or match pair ? */
 
-        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
-        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
-               "pendingBuf overflow");
+        /* Check that the overlay between pending_buf and sym_buf is ok: */
+        Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
 
-    } while (lx < s->last_lit);
+    } while (sx < s->sym_next);
 
     send_code(s, END_BLOCK, ltree);
 }