mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-25 07:15:35 -04:00
Compare commits
215 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e94bad1c15 | ||
|
|
617d726a3d | ||
|
|
020eda887f | ||
|
|
b5f8021a12 | ||
|
|
7b6947576a | ||
|
|
9375a8c4c2 | ||
|
|
7f5c4084c7 | ||
|
|
6c89f00d1b | ||
|
|
dee0993286 | ||
|
|
47351c2b16 | ||
|
|
16b7670614 | ||
|
|
72b2a81f90 | ||
|
|
d73c26d2b7 | ||
|
|
e83bbeb673 | ||
|
|
b6aa9c5cfe | ||
|
|
dfe3b77cb5 | ||
|
|
cbe3b2bfe5 | ||
|
|
b1ae7fc941 | ||
|
|
8695bcc2b1 | ||
|
|
4ae6f708b1 | ||
|
|
14c4656fb8 | ||
|
|
13cec31f7f | ||
|
|
5db7e4b1ee | ||
|
|
54693fa992 | ||
|
|
3f83bcb4af | ||
|
|
e1e546d67e | ||
|
|
3714084f48 | ||
|
|
eb2c3a5e18 | ||
|
|
f6967eca58 | ||
|
|
8455bf66c2 | ||
|
|
00e59e01e3 | ||
|
|
91eaffe13f | ||
|
|
2066024981 | ||
|
|
d274b2096f | ||
|
|
0327a2526b | ||
|
|
f43412f1d5 | ||
|
|
b9010ec617 | ||
|
|
21ecc833ea | ||
|
|
f9bb8f76ee | ||
|
|
a5a9f268fe | ||
|
|
0a255771f4 | ||
|
|
e07d79ad50 | ||
|
|
2f74eb7584 | ||
|
|
39741c7d50 | ||
|
|
3f016888fd | ||
|
|
e5a012c959 | ||
|
|
c3cf174e5e | ||
|
|
a0a7c9f2e3 | ||
|
|
a8f61ba937 | ||
|
|
842d6edfdc | ||
|
|
92a8855ff3 | ||
|
|
def96fd7c4 | ||
|
|
f624a73bbc | ||
|
|
93a373f6ba | ||
|
|
01742c07e6 | ||
|
|
e00662f263 | ||
|
|
491ddb08a4 | ||
|
|
918cb39fed | ||
|
|
1369fe43e1 | ||
|
|
150f3416ac | ||
|
|
d8941be8cb | ||
|
|
592059c8fd | ||
|
|
37f4a23f60 | ||
|
|
27be94c889 | ||
|
|
974f49e22a | ||
|
|
9f7506ac1b | ||
|
|
8779d6c8bb | ||
|
|
96be713fd2 | ||
|
|
13d8fc9542 | ||
|
|
f74473b151 | ||
|
|
5eda68f11b | ||
|
|
f635207347 | ||
|
|
64f7e893f3 | ||
|
|
31556ec7a8 | ||
|
|
9ad3f4385f | ||
|
|
e9899dbdb4 | ||
|
|
18cffa8aa9 | ||
|
|
7e07a32504 | ||
|
|
be11a496bb | ||
|
|
c6f5f0b505 | ||
|
|
f553da1730 | ||
|
|
40753bcbf7 | ||
|
|
33df361d52 | ||
|
|
f4db970718 | ||
|
|
ab3928898f | ||
|
|
13f274fd02 | ||
|
|
b51fe50e7f | ||
|
|
1829a2ee0d | ||
|
|
65370a0f56 | ||
|
|
23213099e9 | ||
|
|
25e08110d5 | ||
|
|
95f683039d | ||
|
|
129d7195ff | ||
|
|
044339d6b4 | ||
|
|
4c4fc7462a | ||
|
|
22cb57ee20 | ||
|
|
4c0be4da13 | ||
|
|
4549855126 | ||
|
|
284c28c773 | ||
|
|
d2406ae372 | ||
|
|
1e9c34972a | ||
|
|
116bd19324 | ||
|
|
883de22c29 | ||
|
|
18f500a7a4 | ||
|
|
d14b0ca4db | ||
|
|
4156e7d464 | ||
|
|
9e48da65c1 | ||
|
|
2cdf9416ee | ||
|
|
cd0c83e485 | ||
|
|
0e814e956c | ||
|
|
f47e5a7732 | ||
|
|
91fff802b9 | ||
|
|
3c8ac20d63 | ||
|
|
38a521defd | ||
|
|
2f13049600 | ||
|
|
af531cf787 | ||
|
|
d495e343c0 | ||
|
|
de7e4d00ab | ||
|
|
374cc1be74 | ||
|
|
8b25488fe9 | ||
|
|
4f5742baa0 | ||
|
|
2b416de4ca | ||
|
|
1f41b7dca1 | ||
|
|
486e7852db | ||
|
|
a68a92793c | ||
|
|
a84e8aced7 | ||
|
|
3bc2d9aeaa | ||
|
|
6214c26bd3 | ||
|
|
da7a350667 | ||
|
|
66ca4fc97b | ||
|
|
7d63f8b249 | ||
|
|
bb1365dd77 | ||
|
|
bcc273d460 | ||
|
|
a6da3c67f8 | ||
|
|
ab110fc8fb | ||
|
|
7265d96116 | ||
|
|
560b63b051 | ||
|
|
0eb82a7c90 | ||
|
|
f92a5182fc | ||
|
|
fb6fabc116 | ||
|
|
c3269275a8 | ||
|
|
7e47855d47 | ||
|
|
d2d6ad481a | ||
|
|
5dcb49c7dd | ||
|
|
19d8550cf4 | ||
|
|
7610f76aea | ||
|
|
59cb358fda | ||
|
|
bb16db1747 | ||
|
|
d6f0342a34 | ||
|
|
6f6e5b51cc | ||
|
|
28de25a664 | ||
|
|
052b34dceb | ||
|
|
748b5c5d53 | ||
|
|
e1e4ffe057 | ||
|
|
1b53b2ff4b | ||
|
|
da45cecfc8 | ||
|
|
87b5d233e9 | ||
|
|
194cee671d | ||
|
|
b7c5520add | ||
|
|
2bee307592 | ||
|
|
85e62c330d | ||
|
|
0add026a5d | ||
|
|
f4184849c4 | ||
|
|
565cde84a7 | ||
|
|
f0e670b4c6 | ||
|
|
ef8951779d | ||
|
|
e285f8f9d2 | ||
|
|
cb383673f6 | ||
|
|
0768d620a5 | ||
|
|
d640d78f91 | ||
|
|
544b3d8b3b | ||
|
|
ce12142c45 | ||
|
|
c83a81ca38 | ||
|
|
d88db22ae8 | ||
|
|
a1cc50ba96 | ||
|
|
feb2fff894 | ||
|
|
7d30490ef4 | ||
|
|
317beebef8 | ||
|
|
7a413c9722 | ||
|
|
5be7363297 | ||
|
|
646784f0e5 | ||
|
|
18ed3f0279 | ||
|
|
00dd50a00c | ||
|
|
7039d14616 | ||
|
|
ec3c9f2f5a | ||
|
|
3b4f5fb891 | ||
|
|
76064b1bf2 | ||
|
|
8df766917e | ||
|
|
299430a6c1 | ||
|
|
dcbe005a6a | ||
|
|
af57b55bdb | ||
|
|
967e6426b9 | ||
|
|
61971acbe1 | ||
|
|
5bd0b6cf71 | ||
|
|
0eec25f75b | ||
|
|
3a6f06003c | ||
|
|
f805d1a7f7 | ||
|
|
ab29ee9c44 | ||
|
|
d07c2992d1 | ||
|
|
b1a8b09c21 | ||
|
|
fe2ef556d9 | ||
|
|
11eb67eec9 | ||
|
|
39a083b16b | ||
|
|
202b7b18af | ||
|
|
20934382e3 | ||
|
|
1bdf68b905 | ||
|
|
89827e49bc | ||
|
|
f157ff3b3a | ||
|
|
d15cfef935 | ||
|
|
28f9c960d5 | ||
|
|
323c42d51e | ||
|
|
d1fdf9ff8d | ||
|
|
e93f40d8b4 | ||
|
|
4df1b1d4fe | ||
|
|
1af58f6b77 |
22
.cirrus.yml
Normal file
22
.cirrus.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
freebsd_task:
|
||||
name: FreeBSD
|
||||
freebsd_instance:
|
||||
image: freebsd-12-1-release-amd64
|
||||
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
|
||||
configure_script:
|
||||
- CPPFLAGS=-I/usr/local/include/ LDFLAGS=-L/usr/local/lib/ ./configure --disable-md2man
|
||||
make_script:
|
||||
- make
|
||||
install_script:
|
||||
- make install
|
||||
info_script:
|
||||
- rsync --version
|
||||
test_script:
|
||||
- RSYNC_MAX_SKIPPED=3 make check
|
||||
ssl_file_list_script:
|
||||
- rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
||||
117
.github/workflows/build.yml
vendored
Normal file
117
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore: [ .cirrus.yml ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore: [ .cirrus.yml ]
|
||||
schedule:
|
||||
- cron: '42 8 * * *'
|
||||
|
||||
jobs:
|
||||
|
||||
ubuntu-build:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: prep
|
||||
run: |
|
||||
sudo apt-get install acl libacl1-dev attr libattr1-dev liblz4-dev libzstd-dev libxxhash-dev python3-cmarkgfm openssl
|
||||
echo "::add-path::/usr/local/bin"
|
||||
- name: configure
|
||||
run: ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: install
|
||||
run: sudo make install
|
||||
- name: info
|
||||
run: rsync --version
|
||||
- name: check
|
||||
run: sudo RSYNC_MAX_SKIPPED=1 make check
|
||||
- name: check30
|
||||
run: sudo RSYNC_MAX_SKIPPED=1 make check30
|
||||
- name: check29
|
||||
run: sudo RSYNC_MAX_SKIPPED=1 make check29
|
||||
- name: ssl file list
|
||||
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||
- name: save artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ubuntu-bin
|
||||
path: |
|
||||
rsync
|
||||
rsync-ssl
|
||||
rsync.1
|
||||
rsync-ssl.1
|
||||
rsyncd.conf.5
|
||||
|
||||
macos-build:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: prep
|
||||
run: |
|
||||
brew install automake openssl xxhash zstd lz4
|
||||
sudo pip3 install commonmark
|
||||
echo "::add-path::/usr/local/bin"
|
||||
- name: configure
|
||||
run: CPPFLAGS=-I/usr/local/opt/openssl/include/ LDFLAGS=-L/usr/local/opt/openssl/lib/ ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: install
|
||||
run: sudo make install
|
||||
- name: info
|
||||
run: rsync --version
|
||||
- name: check
|
||||
run: sudo make check
|
||||
- name: ssl file list
|
||||
run: rsync-ssl --no-motd download.samba.org::rsyncftp/ || true
|
||||
- name: save artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: macos-bin
|
||||
path: |
|
||||
rsync
|
||||
rsync-ssl
|
||||
rsync.1
|
||||
rsync-ssl.1
|
||||
rsyncd.conf.5
|
||||
|
||||
cygwin-build:
|
||||
runs-on: windows-latest
|
||||
if: (github.event_name == 'schedule' || contains(github.event.head_commit.message, '[buildall]'))
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: crazy-max/ghaction-chocolatey@v1.2.2
|
||||
with:
|
||||
args: install -y --no-progress cygwin cyg-get
|
||||
- name: prep
|
||||
run: |
|
||||
cyg-get make autoconf automake gcc-core attr libattr-devel python3 python36-commonmark libzstd-devel liblz4-devel libssl-devel
|
||||
echo "::add-path::C:/tools/cygwin/bin"
|
||||
- name: configure
|
||||
run: bash -c './configure --disable-xxhash'
|
||||
- name: make
|
||||
run: bash -c 'make'
|
||||
- name: install
|
||||
run: bash -c 'make install'
|
||||
- name: info
|
||||
run: bash -c '/usr/local/bin/rsync --version'
|
||||
- name: check
|
||||
run: bash -c 'make check'
|
||||
- name: ssl file list
|
||||
run: bash -c 'PATH="/usr/local/bin:$PATH" rsync-ssl --no-motd download.samba.org::rsyncftp/ || true'
|
||||
- name: save artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cygwin-bin
|
||||
path: |
|
||||
rsync.exe
|
||||
rsync-ssl
|
||||
rsync.1
|
||||
rsync-ssl.1
|
||||
rsyncd.conf.5
|
||||
31
.github/workflows/ccpp.yml
vendored
31
.github/workflows/ccpp.yml
vendored
@@ -1,31 +0,0 @@
|
||||
name: C CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: prepare-packages
|
||||
run: sudo apt-get install fakeroot acl libacl1-dev attr libattr1-dev liblz4-dev libzstd-dev libxxhash-dev python3-cmarkgfm
|
||||
- name: prepare-source
|
||||
run: ./prepare-source
|
||||
- name: configure
|
||||
run: ./configure --with-included-popt --with-included-zlib
|
||||
- name: make
|
||||
run: make
|
||||
- name: version-summary
|
||||
run: ./rsync --version
|
||||
- name: make check
|
||||
run: make check
|
||||
- name: make check30
|
||||
run: make check30
|
||||
- name: make check29
|
||||
run: make check29
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -21,6 +21,7 @@ aclocal.m4
|
||||
/help-rsync*.h
|
||||
/default-cvsignore.h
|
||||
/default-dont-compress.h
|
||||
/daemon-parm.h
|
||||
/.md2man-works
|
||||
/autom4te*.cache
|
||||
/confdefs.h
|
||||
@@ -31,6 +32,7 @@ aclocal.m4
|
||||
/rsync
|
||||
/stunnel-rsyncd.conf
|
||||
/shconfig
|
||||
/git-version.h
|
||||
/testdir
|
||||
/tests-dont-exist
|
||||
/testtmp
|
||||
@@ -48,5 +50,8 @@ aclocal.m4
|
||||
/testsuite/devices-fake.test
|
||||
/testsuite/xattrs-hlink.test
|
||||
/patches
|
||||
/SaVeDiR
|
||||
/patches.gen
|
||||
/build
|
||||
/auto-build-save
|
||||
.deps
|
||||
/*.exe
|
||||
|
||||
215
INSTALL.md
215
INSTALL.md
@@ -1,13 +1,165 @@
|
||||
To build and install rsync:
|
||||
# How to build and install rsync
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
# make install
|
||||
When building rsync, you'll want to install various libraries in order to get
|
||||
all the features enabled. The configure script will alert you when the
|
||||
newest libraries are missing and tell you the appropriate `--disable-LIB`
|
||||
option to use if you want to just skip that feature. What follows are various
|
||||
support libraries that you may want to install to build rsync with the maximum
|
||||
features (the impatient can skip down to the package summary):
|
||||
|
||||
You may set the installation directory and other parameters by options
|
||||
to ./configure. To see them, use:
|
||||
## The basic setup
|
||||
|
||||
$ ./configure --help
|
||||
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
|
||||
|
||||
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).
|
||||
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
|
||||
|
||||
You can test if you've got it fixed by running (from the src dir):
|
||||
|
||||
> ./md2man --test rsync-ssl.1.md
|
||||
|
||||
Alternately, you can avoid generating the man pages 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:
|
||||
|
||||
> ./prepare-source fetchgen
|
||||
|
||||
[6]: https://download.samba.org/pub/rsync/generated-files/
|
||||
|
||||
## ACL support
|
||||
|
||||
To support copying ACL file information, make sure you have an acl
|
||||
development library installed. It also helps to have the helper programs
|
||||
installed to manipulate ACLs and to run the rsync testsuite.
|
||||
|
||||
## Xattr support
|
||||
|
||||
To support copying xattr file information, make sure you have an attr
|
||||
development library installed. It also helps to have the helper programs
|
||||
installed to manipulate xattrs and to run the rsync testsuite.
|
||||
|
||||
## xxhash
|
||||
|
||||
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.
|
||||
|
||||
[1]: https://cyan4973.github.io/xxHash/
|
||||
|
||||
## zstd
|
||||
|
||||
The [zstd library][2] compression algorithm that uses less CPU than
|
||||
the default zlib algorithm at the same compression level. Note that you
|
||||
need at least version 1.4, so you might need to skip the zstd compression if
|
||||
you can only install a 1.3 release. Installing this development library
|
||||
adds zstd compression as the default compression algorithm.
|
||||
|
||||
[2]: http://facebook.github.io/zstd/
|
||||
|
||||
## lz4
|
||||
|
||||
The [lz4 library][3] compression algorithm that uses very little CPU, though
|
||||
it also has the smallest compression ratio of other algorithms. Installing
|
||||
this development library adds lz4 compression as an available compression
|
||||
algorithm.
|
||||
|
||||
[3]: https://lz4.github.io/lz4/
|
||||
|
||||
## openssl crypto
|
||||
|
||||
The [openssl crypto library][4] provides some hardware accelerated checksum
|
||||
algorithms for MD4 and MD5. Installing this development library makes rsync
|
||||
use the (potentially) faster checksum routines when computing MD4 & MD5
|
||||
checksums.
|
||||
|
||||
[4]: https://www.openssl.org/docs/man1.0.2/man3/crypto.html
|
||||
|
||||
## Package summary
|
||||
|
||||
To help you get the libraries installed, here are some package install commands
|
||||
for various OSes. The commands are split up to correspond with the above
|
||||
items, but feel free to combine the package names into a single install, if you
|
||||
like.
|
||||
|
||||
- For Debian and Ubuntu (Debian Buster users may want to briefly(?) enable
|
||||
buster-backports to update zstd from 1.3 to 1.4):
|
||||
|
||||
> sudo apt install -y gcc g++ gawk autoconf automake python3-cmarkgfm
|
||||
> sudo apt install -y acl libacl1-dev
|
||||
> 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 libssl-dev
|
||||
|
||||
- For CentOS (use EPEL for python3-pip):
|
||||
|
||||
> sudo yum -y install epel-release
|
||||
> sudo yum -y install gcc g++ gawk autoconf automake python3-pip
|
||||
> sudo yum -y install acl libacl-devel
|
||||
> sudo yum -y install attr libattr-devel
|
||||
> sudo yum -y install xxhash-devel
|
||||
> sudo yum -y install libzstd-devel
|
||||
> sudo yum -y install lz4-devel
|
||||
> sudo yum -y install openssl-devel
|
||||
> pip3 install --user commonmark
|
||||
|
||||
- For Fedora 33:
|
||||
|
||||
> sudo dnf -y install acl libacl-devel
|
||||
> sudo dnf -y install attr libattr-devel
|
||||
> sudo dnf -y install xxhash-devel
|
||||
> sudo dnf -y install libzstd-devel
|
||||
> sudo dnf -y install lz4-devel
|
||||
> sudo dnf -y install openssl-devel
|
||||
|
||||
- For FreeBSD (this assumes that the python3 version is 3.7):
|
||||
|
||||
> sudo pkg install -y autotools python3 py37-CommonMark
|
||||
> sudo pkg install -y xxhash
|
||||
> sudo pkg install -y zstd
|
||||
> sudo pkg install -y liblz4
|
||||
|
||||
- For macOS:
|
||||
|
||||
> brew install automake
|
||||
> brew install xxhash
|
||||
> brew install zstd
|
||||
> brew install lz4
|
||||
> brew install openssl
|
||||
|
||||
- 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 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
|
||||
|
||||
## Build and install
|
||||
|
||||
After installing the various libraries, you need to configure, build, and
|
||||
install the source:
|
||||
|
||||
> ./configure
|
||||
> make
|
||||
> sudo make install
|
||||
|
||||
The default install path is /usr/local/bin, but you can set the installation
|
||||
directory and other parameters using options to ./configure. To see them, use:
|
||||
|
||||
> ./configure --help
|
||||
|
||||
Configure tries to figure out if the local system uses group "nobody" or
|
||||
"nogroup" by looking in the /etc/group file. (This is only used for the
|
||||
@@ -25,50 +177,59 @@ 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.
|
||||
|
||||
MAKE COMPATIBILITY
|
||||
------------------
|
||||
If you want to automatically use a separate "build" directory based on
|
||||
the current git branch name, start with a pristine git checkout and run
|
||||
"mkdir auto-build-save" before you run the first ./configure command.
|
||||
That will cause a fresh build dir to spring into existence along with a
|
||||
special Makefile symlink that allows you to run "make" and "./configure"
|
||||
from the source dir (the "build" dir gets auto switched based on branch).
|
||||
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 .
|
||||
|
||||
## Make compatibility
|
||||
|
||||
Note that Makefile.in has a rule that uses a wildcard in a prerequisite. If
|
||||
your make has a problem with this rule, you will see an error like this:
|
||||
|
||||
Don't know how to make ./*.c
|
||||
|
||||
You can change the "proto.h-tstamp" target in Makefile.in to list all the *.c
|
||||
You can change the "proto.h-tstamp" target in Makefile.in to list all the \*.c
|
||||
filenames explicitly in order to avoid this issue.
|
||||
|
||||
RPM NOTES
|
||||
---------
|
||||
## RPM notes
|
||||
|
||||
Under packaging you will find .spec files for several distributions.
|
||||
The .spec file in packaging/lsb can be used for Linux systems that
|
||||
adhere to the Linux Standards Base (e.g., RedHat and others).
|
||||
|
||||
HP-UX NOTES
|
||||
-----------
|
||||
## HP-UX notes
|
||||
|
||||
The HP-UX 10.10 "bundled" C compiler seems not to be able to cope with
|
||||
ANSI C. You may see this error message in config.log if ./configure
|
||||
fails:
|
||||
|
||||
(Bundled) cc: "configure", line 2162: error 1705: Function prototypes are an ANSI feature.
|
||||
(Bundled) cc: "configure", line 2162: error 1705: Function prototypes are an ANSI feature.
|
||||
|
||||
Install gcc or HP's "ANSI/C Compiler".
|
||||
|
||||
MAC OSX NOTES
|
||||
-------------
|
||||
## Mac OS X notes
|
||||
|
||||
Some versions of Mac OS X (Darwin) seem to have an IPv6 stack, but do
|
||||
not completely implement the "New Sockets" API.
|
||||
not completely implement the "New Sockets" API.
|
||||
|
||||
<http://www.ipv6.org/impl/mac.html> says that Apple started to support
|
||||
IPv6 in 10.2 (Jaguar). If your build fails, try again after running
|
||||
configure with --disable-ipv6.
|
||||
[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.
|
||||
|
||||
IBM AIX NOTES
|
||||
-------------
|
||||
[5]: http://www.ipv6.org/impl/mac.html
|
||||
|
||||
## IBM AIX notes
|
||||
|
||||
IBM AIX has a largefile problem with mkstemp. See IBM PR-51921.
|
||||
The workaround is to append the below to config.h
|
||||
#ifdef _LARGE_FILES
|
||||
#undef HAVE_SECURE_MKSTEMP
|
||||
#endif
|
||||
The workaround is to append the following to config.h:
|
||||
|
||||
> #ifdef _LARGE_FILES
|
||||
> #undef HAVE_SECURE_MKSTEMP
|
||||
> #endif
|
||||
|
||||
82
Makefile.in
82
Makefile.in
@@ -1,5 +1,4 @@
|
||||
# Makefile for rsync. This is processed by configure to produce the final
|
||||
# Makefile
|
||||
# The Makefile for rsync (configure creates it from Makefile.in).
|
||||
|
||||
prefix=@prefix@
|
||||
datarootdir=@datarootdir@
|
||||
@@ -27,18 +26,16 @@ MKDIR_P=@MKDIR_P@
|
||||
VPATH=$(srcdir)
|
||||
SHELL=/bin/sh
|
||||
|
||||
VERSION=@RSYNC_VERSION@
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
SIMD_x86_64=simd-checksum-x86_64.o
|
||||
ASM_x86_64=lib/md5-asm-x86_64.o
|
||||
|
||||
GENFILES=configure.sh aclocal.m4 config.h.in proto.h proto.h-tstamp rsync.1 rsync.1.html \
|
||||
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
|
||||
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
|
||||
lib/pool_alloc.h lib/mdigest.h lib/md-defines.h version.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 \
|
||||
@@ -46,7 +43,7 @@ zlib_OBJS=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.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
|
||||
OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o \
|
||||
fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
|
||||
usage.o fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
|
||||
OBJS3=progress.o pipe.o @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 \
|
||||
@@ -70,28 +67,28 @@ 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@
|
||||
|
||||
.PHONY: all
|
||||
all: Makefile rsync$(EXEEXT) stunnel-rsyncd.conf @MAKE_MAN@
|
||||
.PHONY: all
|
||||
|
||||
.PHONY: install
|
||||
install: all
|
||||
-${MKDIR_P} ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} -m 755 rsync-ssl ${DESTDIR}${bindir}
|
||||
-${MKDIR_P} ${DESTDIR}${mandir}/man1
|
||||
-${MKDIR_P} ${DESTDIR}${mandir}/man5
|
||||
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
|
||||
-$(MKDIR_P) $(DESTDIR)$(bindir)
|
||||
$(INSTALLCMD) $(INSTALL_STRIP) -m 755 rsync$(EXEEXT) $(DESTDIR)$(bindir)
|
||||
$(INSTALLCMD) -m 755 $(srcdir)/rsync-ssl $(DESTDIR)$(bindir)
|
||||
-$(MKDIR_P) $(DESTDIR)$(mandir)/man1
|
||||
-$(MKDIR_P) $(DESTDIR)$(mandir)/man5
|
||||
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
|
||||
|
||||
install-ssl-daemon: stunnel-rsyncd.conf
|
||||
-${MKDIR_P} ${DESTDIR}/etc/stunnel
|
||||
${INSTALLCMD} -m 644 stunnel-rsyncd.conf ${DESTDIR}/etc/stunnel/rsyncd.conf
|
||||
-$(MKDIR_P) $(DESTDIR)/etc/stunnel
|
||||
$(INSTALLCMD) -m 644 stunnel-rsyncd.conf $(DESTDIR)/etc/stunnel/rsyncd.conf
|
||||
@if ! ls /etc/rsync-ssl/certs/server.* >/dev/null 2>/dev/null; then \
|
||||
echo "Note that you'll need to install the certificate used by /etc/stunnel/rsyncd.conf"; \
|
||||
fi
|
||||
|
||||
install-all: install install-ssl-client install-ssl-daemon
|
||||
install-all: install install-ssl-daemon
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_STRIP='-s' install
|
||||
@@ -102,9 +99,8 @@ rsync$(EXEEXT): $(OBJS)
|
||||
$(OBJS): $(HEADERS)
|
||||
$(CHECK_OBJS): $(HEADERS)
|
||||
tls.o xattrs.o: lib/sysxattrs.h
|
||||
options.o: latest-year.h help-rsync.h help-rsyncd.h
|
||||
exclude.o: default-cvsignore.h
|
||||
loadparm.o: default-dont-compress.h
|
||||
usage.o: 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
|
||||
|
||||
@@ -114,6 +110,9 @@ default-cvsignore.h default-dont-compress.h: rsync.1.md define-from-md.awk
|
||||
help-rsync.h help-rsyncd.h: rsync.1.md help-from-md.awk
|
||||
$(AWK) -f $(srcdir)/help-from-md.awk -v hfile=$@ $(srcdir)/rsync.1.md
|
||||
|
||||
daemon-parm.h: daemon-parm.txt daemon-parm.awk
|
||||
$(AWK) -f $(srcdir)/daemon-parm.awk $(srcdir)/daemon-parm.txt
|
||||
|
||||
rounding.h: rounding.c rsync.h proto.h
|
||||
@for r in 0 1 3; do \
|
||||
if $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o rounding -DEXTRA_ROUNDING=$$r -I. $(srcdir)/rounding.c >rounding.out 2>&1; then \
|
||||
@@ -132,6 +131,12 @@ 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)
|
||||
$(srcdir)/mkgitver
|
||||
|
||||
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
|
||||
|
||||
@@ -203,6 +208,10 @@ reconfigure: configure.sh
|
||||
./config.status --recheck
|
||||
./config.status
|
||||
|
||||
.PHONY: restatus
|
||||
restatus:
|
||||
./config.status
|
||||
|
||||
Makefile: Makefile.in config.status configure.sh config.h.in
|
||||
@if test -f Makefile; then cp -p Makefile Makefile.old; else touch Makefile.old; fi
|
||||
@./config.status
|
||||
@@ -227,25 +236,26 @@ proto: proto.h-tstamp
|
||||
proto.h: proto.h-tstamp
|
||||
@if test -f proto.h; then :; else cp -p $(srcdir)/proto.h .; fi
|
||||
|
||||
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c config.h
|
||||
$(AWK) -f $(srcdir)/mkproto.awk $(srcdir)/*.c $(srcdir)/lib/compat.c
|
||||
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
|
||||
|
||||
rsync.1: rsync.1.md md2man NEWS.md Makefile
|
||||
rsync.1: rsync.1.md md2man version.h Makefile
|
||||
@$(srcdir)/maybe-make-man $(srcdir) rsync.1.md
|
||||
|
||||
rsync-ssl.1: rsync-ssl.1.md md2man NEWS.md Makefile
|
||||
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 md2man NEWS.md Makefile
|
||||
rsyncd.conf.5: rsyncd.conf.5.md md2man version.h Makefile
|
||||
@$(srcdir)/maybe-make-man $(srcdir) rsyncd.conf.5.md
|
||||
|
||||
.PHONY: clean
|
||||
clean: cleantests
|
||||
rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) \
|
||||
rounding rounding.h *.old rsync*.1 rsync*.5 rsync*.html
|
||||
rounding rounding.h *.old rsync*.1 rsync*.5 rsync*.html \
|
||||
daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
|
||||
|
||||
.PHONY: cleantests
|
||||
cleantests:
|
||||
@@ -256,16 +266,11 @@ cleantests:
|
||||
# the source directory.
|
||||
.PHONY: distclean
|
||||
distclean: clean
|
||||
rm -f Makefile config.h config.status
|
||||
rm -f stunnel-rsyncd.conf
|
||||
rm -f lib/dummy popt/dummy zlib/dummy
|
||||
rm -f $(srcdir)/Makefile $(srcdir)/config.h $(srcdir)/config.status
|
||||
rm -f $(srcdir)/lib/dummy $(srcdir)/popt/dummy $(srcdir)/zlib/dummy
|
||||
rm -f config.cache config.log
|
||||
rm -f $(srcdir)/config.cache $(srcdir)/config.log
|
||||
rm -f shconfig $(srcdir)/shconfig
|
||||
rm -f $(GENFILES)
|
||||
rm -rf autom4te.cache
|
||||
for dir in $(srcdir) . ; do \
|
||||
(cd "$$dir" && rm -rf Makefile config.h config.status stunnel-rsyncd.conf \
|
||||
lib/dummy popt/dummy zlib/dummy config.cache config.log shconfig \
|
||||
$(GENFILES) autom4te.cache) ; \
|
||||
done
|
||||
|
||||
# this target is really just for my use. It only works on a limited
|
||||
# range of machines and is used to produce a list of potentially
|
||||
@@ -275,6 +280,7 @@ finddead:
|
||||
nm *.o */*.o |grep 'U ' | awk '{print $$2}' | sort -u > nmused.txt
|
||||
nm *.o */*.o |grep 'T ' | awk '{print $$3}' | sort -u > nmfns.txt
|
||||
comm -13 nmused.txt nmfns.txt
|
||||
@rm nmused.txt nmfns.txt
|
||||
|
||||
# 'check' is the GNU name, 'test' is the name for everybody else :-)
|
||||
.PHONY: test
|
||||
|
||||
389
NEWS.md
389
NEWS.md
@@ -1,10 +1,185 @@
|
||||
<a name="3.2.3"></a>
|
||||
|
||||
# NEWS for rsync 3.2.3 (6 Aug 2020)
|
||||
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
- Fixed a bug in the xattr code that was freeing the wrong object when trying
|
||||
to cleanup the xattr list.
|
||||
|
||||
- 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.)
|
||||
|
||||
- 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 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.
|
||||
|
||||
- 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 `--block-size=SIZE` 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
|
||||
linkat() function when it is available.
|
||||
|
||||
- Output file+line info on out-of-memory & overflow errors while also avoiding
|
||||
the output of alternate build-dir path info that is not useful to the user.
|
||||
|
||||
- Change configure to know that Cygwin supports Linux xattrs.
|
||||
|
||||
- Improved the testsuite on FreeBSD & Cygwin.
|
||||
|
||||
- Added some compatibility code for HPE NonStop platforms.
|
||||
|
||||
- Improved the INSTALL.md info.
|
||||
|
||||
- Added a few more suffixes to the default skip-compress list.
|
||||
|
||||
- Improved configure's error handling to notify about several issues at once
|
||||
instead of one by one (for the newest optional features).
|
||||
|
||||
### INTERNAL:
|
||||
|
||||
- Use a simpler overflow check idiom in a few spots.
|
||||
|
||||
- Use a C99 Flexible Array for a trailing variable-size filename in a struct
|
||||
(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)
|
||||
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
- Avoid a crash when a daemon module enables `transfer logging` without
|
||||
setting a `log format` value.
|
||||
|
||||
- Fixed installing rsync-ssl script from an alternate build dir.
|
||||
|
||||
- Fixed the updating of configure.sh from an alternate build dir.
|
||||
|
||||
- Apple requires the asm function name to begin with an underscore.
|
||||
|
||||
- Avoid a test failure in the daemon test when `--atimes` is disabled.
|
||||
|
||||
### ENHANCEMENTS:
|
||||
|
||||
- Allow the server side to restrict checksum & compression choices via the
|
||||
same environment variables the client uses. The env vars can be divided
|
||||
into "client list & server list" by the "`&`" char or the same list can
|
||||
apply to both.
|
||||
|
||||
- Simplify how the negotiation environment variables apply when interacting
|
||||
with an older rsync and also when a list contains only invalid names.
|
||||
|
||||
- Do not allow a negotiated checksum or compression choice of "none" unless
|
||||
the user authorized it via an environment variable or command-line option.
|
||||
|
||||
- Added the `--max-alloc=SIZE` option to be able to override the memory
|
||||
allocator's sanity-check limit. It defaults to 1G (as before) but the error
|
||||
message when exceeding it specifically mentions the new option so that you
|
||||
can differentiate an out-of-memory error from a failure of this limit. It
|
||||
also allows you to specify the value via the RSYNC_MAX_ALLOC environment
|
||||
variable.
|
||||
|
||||
- Add the "open atime" daemon parameter to allow a daemon to always enable or
|
||||
disable the use of O_NOATIME (the default is to let the user control it).
|
||||
|
||||
- The default systemd config was changed to remove the `ProtectHome=on`
|
||||
setting since rsync is often used to serve files in /home and /root and this
|
||||
seemed a bit too strict. Feel free to use `systemctl edit rsync` to add
|
||||
that restriction (or maybe `ProtectHome=read-only`), if you like. See the
|
||||
3.2.0 NEWS for the other restrictions that were added compared to 3.1.3.
|
||||
|
||||
- The memory allocation functions now automatically check for a failure and
|
||||
die when out of memory. This eliminated some caller-side check-and-die
|
||||
code and added some missing sanity-checking of allocations.
|
||||
|
||||
- Put optimizations into their own list in the `--version` output.
|
||||
|
||||
- Improved the man page a bit more.
|
||||
|
||||
### PACKAGING RELATED:
|
||||
|
||||
- Prepared the checksum code for an upcoming xxHash release that provides new
|
||||
XXH3 (64-bit) & XXH128 (128-bit) checksum routines. These will not be
|
||||
compiled into rsync until the xxhash v0.8.0 include files are installed on
|
||||
the build host, and that release is a few weeks away at the time this was
|
||||
written. So, if it's now the future and you have packaged and installed
|
||||
xxhash-0.8.0-devel, a fresh rebuild of rsync 3.2.2 will give you the new
|
||||
checksum routines. Just make sure that the new rsync package depends on
|
||||
xxhash >= 0.8.0.
|
||||
|
||||
### DEVELOPER RELATED:
|
||||
|
||||
- Moved the version number out of configure.ac into its own version.h file so
|
||||
that we don't need to reconfigure just because the version number changes.
|
||||
|
||||
- Moved the daemon parameter list into daemon-parm.txt so that an awk script
|
||||
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)
|
||||
|
||||
Protocol: 31 (unchanged)
|
||||
|
||||
## Changes since 3.2.0:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -23,7 +198,7 @@ Protocol: 31 (unchanged)
|
||||
their buggy compiler (since the configure test is apparently not finding
|
||||
all the compilers that will to crash and burn).
|
||||
|
||||
- Fix an issue in the md2man script when building from an external dir.
|
||||
- Fixed an issue in the md2man script when building from an alternate dir.
|
||||
|
||||
- Disable `--atimes` on macOS (it apparently just ignores the atime change).
|
||||
|
||||
@@ -67,9 +242,7 @@ Protocol: 31 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.2.0 (19 Jun 2020)
|
||||
|
||||
Protocol: 31 (unchanged)
|
||||
|
||||
## Changes since 3.1.3:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -122,10 +295,17 @@ Protocol: 31 (unchanged)
|
||||
|
||||
### ENHANCEMENTS:
|
||||
|
||||
- The default systemd config was made stricter by default. For instance,
|
||||
`ProtectHome=on` (which hides content in /root and /home/USER dirs),
|
||||
`ProtectSystem=full` (which makes /usr, /boot, & /etc dirs read-only), and
|
||||
`PrivateDevices=on` (which hides devices). You can override any of these
|
||||
using the standard `systemctl edit rsync` and add one or more directives
|
||||
under a `[Service]` heading (and restart the rsync service).
|
||||
|
||||
- Various checksum enhancements, including the optional use of openssl's MD4 &
|
||||
MD5 checksum algorithms, some x86-64 optimizations for the rolling checksum,
|
||||
some x86-64 optimizations for the (non-openssl) MD5 checksum, the addition
|
||||
of xxhash checksum support, and a negotiation heuristic that ensures that it
|
||||
of xxHash checksum support, and a negotiation heuristic that ensures that it
|
||||
is easier to add new checksum algorithms in the future. The environment
|
||||
variable `RSYNC_CHECKSUM_LIST` can be used to customize the preference order
|
||||
of the negotiation, or use `--checksum-choice` (`--cc`) to force a choice.
|
||||
@@ -217,7 +397,7 @@ Protocol: 31 (unchanged)
|
||||
|
||||
### PACKAGING RELATED:
|
||||
|
||||
- Add installed binary: /usr/bin/rsync-ssl
|
||||
- Add installed bash script: /usr/bin/rsync-ssl
|
||||
|
||||
- Add installed man page: /usr/man/man1/rsync-ssl.1
|
||||
|
||||
@@ -257,7 +437,7 @@ Protocol: 31 (unchanged)
|
||||
|
||||
- Converted the man pages 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 has gotten obscure.
|
||||
should make it easier to package rsync, since yodl is rather obscure.
|
||||
|
||||
- Improved some configure checks to work better with strict C99 compilers.
|
||||
|
||||
@@ -274,9 +454,7 @@ Protocol: 31 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.1.3 (28 Jan 2018)
|
||||
|
||||
Protocol: 31 (unchanged)
|
||||
|
||||
## Changes since 3.1.2:
|
||||
## Changes in this version:
|
||||
|
||||
### SECURITY FIXES:
|
||||
|
||||
@@ -308,7 +486,7 @@ Protocol: 31 (unchanged)
|
||||
disallowing transfers.
|
||||
|
||||
- Don't force nanoseconds to match if a non-transferred, non-checksummed file
|
||||
only passed the quick-check w/o comparing nanosecods.
|
||||
only passed the quick-check w/o comparing nanoseconds.
|
||||
|
||||
### ENHANCEMENTS:
|
||||
|
||||
@@ -346,9 +524,7 @@ Protocol: 31 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.1.2 (21 Dec 2015)
|
||||
|
||||
Protocol: 31 (unchanged)
|
||||
|
||||
## Changes since 3.1.1:
|
||||
## Changes in this version:
|
||||
|
||||
### SECURITY FIXES:
|
||||
|
||||
@@ -392,7 +568,7 @@ Protocol: 31 (unchanged)
|
||||
- Added a few extra long-option names to rrsync script, which will make
|
||||
BackupPC happier.
|
||||
|
||||
- Made configure choose to use linux xattrs on netbsd (rather than not
|
||||
- Made configure choose to use Linux xattrs on NetBSD (rather than not
|
||||
supporting xattrs).
|
||||
|
||||
- Added `-wo` (write-only) option to rrsync support script.
|
||||
@@ -414,9 +590,7 @@ Protocol: 31 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.1.1 (22 Jun 2014)
|
||||
|
||||
Protocol: 31 (unchanged)
|
||||
|
||||
## Changes since 3.1.0:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -536,9 +710,11 @@ Protocol: 31 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.1.0 (28 Sep 2013)
|
||||
|
||||
Protocol: 31 (changed)
|
||||
## Changes in this version:
|
||||
|
||||
## Changes since 3.0.9:
|
||||
### PROTOCOL NUMBER:
|
||||
|
||||
- The protocol number was changed to 31.
|
||||
|
||||
### OUTPUT CHANGES:
|
||||
|
||||
@@ -754,7 +930,7 @@ Protocol: 31 (changed)
|
||||
- A daemon can now inform a client about a daemon-configured timeout value so
|
||||
that the client can assist in the keep-alive activity (protocol 31).
|
||||
|
||||
- The filter code received some refactoring to make it more extendible, to
|
||||
- The filter code received some refactoring to make it more extendable, to
|
||||
read better, and do better sanity checking.
|
||||
|
||||
- Really big numbers are now output using our own big-num routine rather than
|
||||
@@ -778,16 +954,14 @@ Protocol: 31 (changed)
|
||||
|
||||
- Added more conditional debug output.
|
||||
|
||||
- Fixed some build issues for android and minix.
|
||||
- Fixed some build issues for Android and Minix.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
<a name="3.0.9"></a>
|
||||
|
||||
# NEWS for rsync 3.0.9 (23 Sep 2011)
|
||||
|
||||
Protocol: 30 (unchanged)
|
||||
|
||||
## Changes since 3.0.8:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -832,7 +1006,7 @@ Protocol: 30 (unchanged)
|
||||
- Fix a compilation issue on older C compilers (due to a misplaced var
|
||||
declaration).
|
||||
|
||||
- Make configure avoid finding socketpair on cygwin.
|
||||
- Make configure avoid finding socketpair on Cygwin.
|
||||
|
||||
- Avoid trying to reference `SO_BROADCAST` if the OS doesn't support it.
|
||||
|
||||
@@ -847,9 +1021,7 @@ Protocol: 30 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.0.8 (26 Mar 2011)
|
||||
|
||||
Protocol: 30 (unchanged)
|
||||
|
||||
## Changes since 3.0.7:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -988,9 +1160,7 @@ Protocol: 30 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.0.7 (31 Dec 2009)
|
||||
|
||||
Protocol: 30 (unchanged)
|
||||
|
||||
## Changes since 3.0.6:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -1035,7 +1205,7 @@ Protocol: 30 (unchanged)
|
||||
- Improved the error-exit reporting when rsync gets an error trying to cleanup
|
||||
after an error: the initial error is reported.
|
||||
|
||||
- Improved configure's detection of IPv6 for solaris and cygwin.
|
||||
- Improved configure's detection of IPv6 for Solaris and Cygwin.
|
||||
|
||||
- The AIX sysacls routines will now return ENOSYS if ENOTSUP is missing.
|
||||
|
||||
@@ -1051,16 +1221,14 @@ Protocol: 30 (unchanged)
|
||||
|
||||
- The Makefile now ensures that proto.h will be rebuilt if config.h changes.
|
||||
|
||||
- The testsuite no longer uses `id -u`, so it works better on solaris.
|
||||
- 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)
|
||||
|
||||
Protocol: 30 (unchanged)
|
||||
|
||||
## Changes since 3.0.5:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -1119,9 +1287,7 @@ Protocol: 30 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.0.5 (28 Dec 2008)
|
||||
|
||||
Protocol: 30 (unchanged)
|
||||
|
||||
## Changes since 3.0.4:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -1186,9 +1352,7 @@ Protocol: 30 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.0.4 (6 Sep 2008)
|
||||
|
||||
Protocol: 30 (unchanged)
|
||||
|
||||
## Changes since 3.0.3:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -1256,9 +1420,7 @@ Protocol: 30 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.0.3 (29 Jun 2008)
|
||||
|
||||
Protocol: 30 (unchanged)
|
||||
|
||||
## Changes since 3.0.2:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -1275,7 +1437,7 @@ Protocol: 30 (unchanged)
|
||||
|
||||
- Fixed the combination of `--xattrs` and `--backup`.
|
||||
|
||||
- The generator no longer allows a '.' dir to be excluded by a daemon- exclude
|
||||
- The generator no longer allows a '.' dir to be excluded by a daemon-exclude
|
||||
rule.
|
||||
|
||||
- Fixed deletion handling when copying a single, empty directory (with no
|
||||
@@ -1349,9 +1511,7 @@ Protocol: 30 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.0.2 (8 Apr 2008)
|
||||
|
||||
Protocol: 30 (unchanged)
|
||||
|
||||
## Changes since 3.0.1:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -1373,9 +1533,7 @@ Protocol: 30 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.0.1 (3 Apr 2008)
|
||||
|
||||
Protocol: 30 (unchanged)
|
||||
|
||||
## Changes since 3.0.0:
|
||||
## Changes in this version:
|
||||
|
||||
### NOTABLE CHANGES IN BEHAVIOR:
|
||||
|
||||
@@ -1439,7 +1597,7 @@ Protocol: 30 (unchanged)
|
||||
- Fixed a glitch in the itemizing of permissions with the `-E` option.
|
||||
|
||||
- The `--append` option's restricting of transfers to those that add data no
|
||||
longer prevents the updating of non-content changes to otherwise up-to- date
|
||||
longer prevents the updating of non-content changes to otherwise up-to-date
|
||||
files (i.e. those with the same content but differing permissions,
|
||||
ownership, xattrs, etc.).
|
||||
|
||||
@@ -1513,9 +1671,11 @@ Protocol: 30 (unchanged)
|
||||
|
||||
# NEWS for rsync 3.0.0 (1 Mar 2008)
|
||||
|
||||
Protocol: 30 (changed)
|
||||
## Changes in this version:
|
||||
|
||||
## Changes since 2.6.9:
|
||||
### PROTOCOL NUMBER:
|
||||
|
||||
- The protocol number was changed to 30.
|
||||
|
||||
### NOTABLE CHANGES IN BEHAVIOR:
|
||||
|
||||
@@ -1561,7 +1721,7 @@ Protocol: 30 (changed)
|
||||
a per-module basis. This avoids a potential problem with a writable daemon
|
||||
module that has `use chroot` enabled -- if precautions weren't taken, a user
|
||||
could try to add a missing library and get rsync to use it. This makes rsync
|
||||
safer by default, and more configurable when id- translation is not desired.
|
||||
safer by default, and more configurable when id-translation is not desired.
|
||||
See the daemon's `numeric ids` parameter for full details.
|
||||
|
||||
- A chroot daemon can now indicate which part of its path should affect the
|
||||
@@ -1771,7 +1931,7 @@ Protocol: 30 (changed)
|
||||
|
||||
### INTERNAL:
|
||||
|
||||
- The file-list sorting algorithm now uses a sort that keeps any same- named
|
||||
- The file-list sorting algorithm now uses a sort that keeps any same-named
|
||||
items in the same order as they were specified. This allows rsync to always
|
||||
ensure that the first of the duplicates is the one that will be included in
|
||||
the copy. The new sort is also faster than the glibc version of qsort() and
|
||||
@@ -1862,9 +2022,7 @@ Protocol: 30 (changed)
|
||||
|
||||
# NEWS for rsync 2.6.9 (6 Nov 2006)
|
||||
|
||||
Protocol: 29 (unchanged)
|
||||
|
||||
## Changes since 2.6.8:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -2024,9 +2182,7 @@ Protocol: 29 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.6.8 (22 Apr 2006)
|
||||
|
||||
Protocol: 29 (unchanged)
|
||||
|
||||
## Changes since 2.6.7:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -2096,9 +2252,7 @@ Protocol: 29 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.6.7 (11 Mar 2006)
|
||||
|
||||
Protocol: 29 (unchanged)
|
||||
|
||||
## Changes since 2.6.6:
|
||||
## Changes in this version:
|
||||
|
||||
### OUTPUT CHANGES:
|
||||
|
||||
@@ -2214,7 +2368,7 @@ Protocol: 29 (unchanged)
|
||||
- Fixed a bug in the debug output (`-vvvvv`) that could mention the wrong
|
||||
checksum for the current file offset.
|
||||
|
||||
- Rsync no longer allows a single directory to be copied over a non- directory
|
||||
- Rsync no longer allows a single directory to be copied over a non-directory
|
||||
destination arg.
|
||||
|
||||
### ENHANCEMENTS:
|
||||
@@ -2373,7 +2527,7 @@ Protocol: 29 (unchanged)
|
||||
signals that it needs, just in case it was started in a masked state.
|
||||
|
||||
- Some buffer sizes were expanded a bit, particularly on systems where
|
||||
MAXPATHLEN is overly small (e.g. cygwin).
|
||||
MAXPATHLEN is overly small (e.g. Cygwin).
|
||||
|
||||
- If `io_printf()` tries to format more data than fits in the buffer, exit
|
||||
with an error instead of transmitting a truncated buffer.
|
||||
@@ -2422,9 +2576,7 @@ Protocol: 29 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.6.6 (28 Jul 2005)
|
||||
|
||||
Protocol: 29 (unchanged)
|
||||
|
||||
## Changes since 2.6.5:
|
||||
## Changes in this version:
|
||||
|
||||
### SECURITY FIXES:
|
||||
|
||||
@@ -2449,7 +2601,7 @@ Protocol: 29 (unchanged)
|
||||
- When backing up a changed symlink or device, get rid of any old backup item
|
||||
so that we don't get an `already exists` error.
|
||||
|
||||
- A couple places that were comparing a local and a remote modification- time
|
||||
- A couple places that were comparing a local and a remote modification-time
|
||||
were not honoring the `--modify-window` option.
|
||||
|
||||
- Fixed a bug where the 'p' (permissions) itemized-changes flag might get set
|
||||
@@ -2490,13 +2642,11 @@ Protocol: 29 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.6.5 (1 Jun 2005)
|
||||
|
||||
Protocol: 29 (unchanged)
|
||||
|
||||
## Changes since 2.6.4:
|
||||
## Changes in this version:
|
||||
|
||||
### OUTPUT CHANGES:
|
||||
|
||||
- Non-printable chars in filenames are now output using backslash- escaped
|
||||
- Non-printable chars in filenames are now output using backslash-escaped
|
||||
characters rather than '?'s. Any non-printable character is output using 3
|
||||
digits of octal (e.g. `\n` -> `\012`), and a backslash is now output as
|
||||
`\\`. Rsync also uses your locale setting, which can make it treat fewer
|
||||
@@ -2673,9 +2823,11 @@ Protocol: 29 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.6.4 (30 March 2005)
|
||||
|
||||
Protocol: 29 (changed)
|
||||
## Changes in this version:
|
||||
|
||||
## Changes since 2.6.3:
|
||||
### PROTOCOL NUMBER:
|
||||
|
||||
- The protocol number was changed to 29.
|
||||
|
||||
### OUTPUT CHANGES:
|
||||
|
||||
@@ -2716,9 +2868,9 @@ Protocol: 29 (changed)
|
||||
- Avoid a mkdir warning when removing a directory in the destination that
|
||||
already exists in the `--backup-dir`.
|
||||
|
||||
- An OS that has a binary mode for its files (such as cygwin) needed
|
||||
- An OS that has a binary mode for its files (such as Cygwin) needed
|
||||
`setmode(fd, O_BINARY)` called on the temp-file we opened with mkstemp().
|
||||
(Fix derived from cygwin's 2.6.3 rsync package.)
|
||||
(Fix derived from Cygwin's 2.6.3 rsync package.)
|
||||
|
||||
- Fixed a potential hang when verbosity is high, the client side is the
|
||||
sender, and the file-list is large.
|
||||
@@ -3053,9 +3205,7 @@ Protocol: 29 (changed)
|
||||
|
||||
# NEWS for rsync 2.6.3 (30 Sep 2004)
|
||||
|
||||
Protocol: 28 (unchanged)
|
||||
|
||||
## Changes since 2.6.2:
|
||||
## Changes in this version:
|
||||
|
||||
### SECURITY FIXES:
|
||||
|
||||
@@ -3178,7 +3328,7 @@ Protocol: 28 (unchanged)
|
||||
### ENHANCEMENTS:
|
||||
|
||||
- Added the `--partial-dir=DIR` option that lets you specify where to
|
||||
(temporarily) put a partially transferred file (instead of over- writing the
|
||||
(temporarily) put a partially transferred file (instead of overwriting the
|
||||
destination file). E.g. `--partial-dir=.rsync-partial` Also added support
|
||||
for the `RSYNC_PARTIAL_DIR` environment variable that, when found,
|
||||
transforms a regular `--partial` option (such as the convenient `-P` option)
|
||||
@@ -3299,9 +3449,7 @@ Protocol: 28 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.6.2 (30 Apr 2004)
|
||||
|
||||
Protocol: 28 (unchanged)
|
||||
|
||||
## Changes since 2.6.1:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -3343,9 +3491,11 @@ Protocol: 28 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.6.1 (26 Apr 2004)
|
||||
|
||||
Protocol: 28 (changed)
|
||||
## Changes in this version:
|
||||
|
||||
## Changes since 2.6.0:
|
||||
### PROTOCOL NUMBER:
|
||||
|
||||
- The protocol number was changed to 28.
|
||||
|
||||
### SECURITY FIXES:
|
||||
|
||||
@@ -3367,7 +3517,7 @@ Protocol: 28 (changed)
|
||||
file-count that we've processed. It also shows better
|
||||
current-rate-of-transfer and remaining-transfer-time values.
|
||||
|
||||
- Documentation changes now attempt to describe some often mis- understood
|
||||
- Documentation changes now attempt to describe some often misunderstood
|
||||
features more clearly.
|
||||
|
||||
### BUG FIXES:
|
||||
@@ -3410,9 +3560,9 @@ Protocol: 28 (changed)
|
||||
|
||||
- Fixed the `refuse options` setting in the rsyncd.conf file.
|
||||
|
||||
- Improved the `-x` (`--one-file-system`) flag's handling of any mount- point
|
||||
- Improved the `-x` (`--one-file-system`) flag's handling of any mount-point
|
||||
directories we encounter. It is both more optimal (in that it no longer does
|
||||
a useless scan of the contents of the mount- point dirs) and also fixes a
|
||||
a useless scan of the contents of the mount-point dirs) and also fixes a
|
||||
bug where a remapped mount of the original filesystem could get discovered
|
||||
in a subdir we should be ignoring.
|
||||
|
||||
@@ -3533,9 +3683,12 @@ Protocol: 28 (changed)
|
||||
|
||||
# NEWS for rsync 2.6.0 (1 Jan 2004)
|
||||
|
||||
Protocol: 27 (changed)
|
||||
## Changes in this version:
|
||||
|
||||
## Changes since 2.5.7:
|
||||
### PROTOCOL NUMBER:
|
||||
|
||||
- The protocol number was changed to 27. The maximum accepted protocol number
|
||||
was increased from 30 to 40.
|
||||
|
||||
### ENHANCEMENTS:
|
||||
|
||||
@@ -3670,9 +3823,7 @@ Protocol: 27 (changed)
|
||||
|
||||
# NEWS for rsync 2.5.7 (4 Dec 2003)
|
||||
|
||||
Protocol: 26 (unchanged)
|
||||
|
||||
## Changes since 2.5.6:
|
||||
## Changes in this version:
|
||||
|
||||
### SECURITY FIXES:
|
||||
|
||||
@@ -3684,9 +3835,7 @@ Protocol: 26 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.5.6, aka "the dwd-between-jobs release" (26 Jan 2003)
|
||||
|
||||
Protocol: 26 (unchanged)
|
||||
|
||||
## Changes since 2.5.5:
|
||||
## Changes in this version:
|
||||
|
||||
### ENHANCEMENTS:
|
||||
|
||||
@@ -3781,9 +3930,7 @@ Protocol: 26 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.5.5, aka Snowy River (2 Apr 2002)
|
||||
|
||||
Protocol: 26 (unchanged)
|
||||
|
||||
## Changes since 2.5.4:
|
||||
## Changes in this version:
|
||||
|
||||
### ENHANCEMENTS:
|
||||
|
||||
@@ -3822,9 +3969,7 @@ Protocol: 26 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.5.4, aka "Imitation lizard skin" (13 Mar 2002)
|
||||
|
||||
Protocol: 26 (unchanged)
|
||||
|
||||
## Changes since 2.5.3:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -3844,9 +3989,7 @@ Protocol: 26 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.5.3, aka "Happy 26" (11 Mar 2002)
|
||||
|
||||
Protocol: 26 (unchanged)
|
||||
|
||||
## Changes since 2.5.2:
|
||||
## Changes in this version:
|
||||
|
||||
### SECURITY FIXES:
|
||||
|
||||
@@ -3895,9 +4038,7 @@ Protocol: 26 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.5.2 (26 Jan 2002)
|
||||
|
||||
Protocol: 26 (changed)
|
||||
|
||||
## Changes since 2.5.1:
|
||||
## Changes in this version:
|
||||
|
||||
### SECURITY FIXES:
|
||||
|
||||
@@ -3905,6 +4046,10 @@ Protocol: 26 (changed)
|
||||
some cases we were not sufficiently careful about reading integers from the
|
||||
network.
|
||||
|
||||
### PROTOCOL NUMBER:
|
||||
|
||||
- The protocol number was changed to 26.
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
- Fix possible string mangling in log files.
|
||||
@@ -3942,9 +4087,7 @@ Protocol: 26 (changed)
|
||||
|
||||
# NEWS for rsync 2.5.1 (3 Jan 2002)
|
||||
|
||||
Protocol: 25 (unchanged)
|
||||
|
||||
## Changes since 2.5.0:
|
||||
## Changes in this version:
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
@@ -3979,9 +4122,11 @@ Protocol: 25 (unchanged)
|
||||
|
||||
# NEWS for rsync 2.5.0 (30 Nov 2001)
|
||||
|
||||
Protocol: 25 (changed)
|
||||
## Changes in this version:
|
||||
|
||||
## Changes since 2.4.6:
|
||||
### PROTOCOL NUMBER:
|
||||
|
||||
- The protocol number was changed to 25.
|
||||
|
||||
### ANNOUNCEMENTS:
|
||||
|
||||
@@ -4099,6 +4244,8 @@ Protocol: 25 (changed)
|
||||
|
||||
| RELEASE DATE | VER. | DATE OF COMMIT\* | PROTOCOL |
|
||||
|--------------|--------|------------------|-------------|
|
||||
| 06 Aug 2020 | 3.2.3 | | 31 |
|
||||
| 04 Jul 2020 | 3.2.2 | | 31 |
|
||||
| 22 Jun 2020 | 3.2.1 | | 31 |
|
||||
| 19 Jun 2020 | 3.2.0 | | 31 |
|
||||
| 28 Jan 2018 | 3.1.3 | | 31 |
|
||||
|
||||
61
README.md
61
README.md
@@ -26,6 +26,15 @@ options. To get a complete list of supported options type:
|
||||
See the manpage for more detailed information.
|
||||
|
||||
|
||||
BUILDING AND INSTALLING
|
||||
-----------------------
|
||||
|
||||
If you need to build rsync yourself, check out the [INSTALL][1] page for
|
||||
information on what libraries and packages you can use to get the maximum
|
||||
features in your build.
|
||||
|
||||
[1]: https://github.com/WayneD/rsync/blob/master/INSTALL.md
|
||||
|
||||
SETUP
|
||||
-----
|
||||
|
||||
@@ -63,9 +72,9 @@ connect to an rsync daemon.
|
||||
WEB SITE
|
||||
--------
|
||||
|
||||
The main rsync web site is here:
|
||||
For more information, visit the [main rsync web site][2].
|
||||
|
||||
> https://rsync.samba.org/
|
||||
[2]: https://rsync.samba.org/
|
||||
|
||||
You'll find a FAQ list, downloads, resources, HTML versions of the
|
||||
manpages, etc.
|
||||
@@ -77,25 +86,25 @@ MAILING LISTS
|
||||
There is a mailing list for the discussion of rsync and its applications
|
||||
that is open to anyone to join. New releases are announced on this
|
||||
list, and there is also an announcement-only mailing list for those that
|
||||
want official announcements. See the mailing-list page for full
|
||||
details:
|
||||
want official announcements. See the [mailing-list page][3] for full
|
||||
details.
|
||||
|
||||
> https://rsync.samba.org/lists.html
|
||||
[3]: https://rsync.samba.org/lists.html
|
||||
|
||||
|
||||
BUG REPORTS
|
||||
-----------
|
||||
|
||||
To visit this web page for full the details on bug reporting:
|
||||
The [bug-tracking web page][4] has full details on bug reporting.
|
||||
|
||||
> https://rsync.samba.org/bugtracking.html
|
||||
[4]: https://rsync.samba.org/bug-tracking.html
|
||||
|
||||
That page contains links to the current bug list, and information on how
|
||||
to report a bug well. You might also like to try searching the Internet
|
||||
for the error message you've received, or looking in the mailing list
|
||||
archives at:
|
||||
That page contains links to the current bug list, and information on how to
|
||||
do a good job when reporting a bug. You might also like to try searching
|
||||
the Internet for the error message you've received, or looking in the
|
||||
[mailing list archives][5].
|
||||
|
||||
> https://mail-archive.com/rsync@lists.samba.org/
|
||||
[5]: https://mail-archive.com/rsync@lists.samba.org/
|
||||
|
||||
To send a bug report, follow the instructions on the bug-tracking
|
||||
page of the web site.
|
||||
@@ -108,18 +117,15 @@ GIT REPOSITORY
|
||||
|
||||
If you want to get the very latest version of rsync direct from the
|
||||
source code repository, then you will need to use git. The git repo
|
||||
is hosted on github and on samba's site. Feel free to access it here:
|
||||
is hosted [on GitHub][6] and [on Samba's site][7].
|
||||
|
||||
> https://github.com/WayneD/rsync
|
||||
[6]: https://github.com/WayneD/rsync
|
||||
[7]: https://git.samba.org/?p=rsync.git;a=summary
|
||||
|
||||
A backup git repo is available on the samba site:
|
||||
See [the download page][8] for full details on all the ways to grab the
|
||||
source.
|
||||
|
||||
> git clone git://git.samba.org/rsync.git
|
||||
|
||||
See the download page for full details on all the ways to grab the
|
||||
source:
|
||||
|
||||
> https://rsync.samba.org/download.html
|
||||
[8]: https://rsync.samba.org/download.html
|
||||
|
||||
|
||||
COPYRIGHT
|
||||
@@ -130,13 +136,8 @@ maintained by Wayne Davison. It has been improved by many developers
|
||||
from around the world.
|
||||
|
||||
Rsync may be used, modified and redistributed only under the terms of
|
||||
the GNU General Public License, found in the file COPYING in this
|
||||
distribution, or at:
|
||||
the GNU General Public License, found in the file [COPYING][9] in this
|
||||
distribution, or at [the Free Software Foundation][10].
|
||||
|
||||
> https://www.fsf.org/licenses/gpl.html
|
||||
|
||||
|
||||
AVAILABILITY
|
||||
------------
|
||||
|
||||
The main web site for rsync is https://rsync.samba.org/
|
||||
[9]: https://github.com/WayneD/rsync/blob/master/COPYING
|
||||
[10]: https://www.fsf.org/licenses/gpl.html
|
||||
|
||||
15
access.c
15
access.c
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
static int allow_forward_dns;
|
||||
|
||||
@@ -33,6 +34,11 @@ static int match_hostname(const char **host_ptr, const char *addr, const char *t
|
||||
if (!host || !*host)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_INNETGR
|
||||
if (*tok == '@' && tok[1])
|
||||
return innetgr(tok + 1, host, NULL, NULL);
|
||||
#endif
|
||||
|
||||
/* First check if the reverse-DNS-determined hostname matches. */
|
||||
if (iwildmatch(tok, host))
|
||||
return 1;
|
||||
@@ -52,10 +58,8 @@ static int match_hostname(const char **host_ptr, const char *addr, const char *t
|
||||
if (strcmp(addr, inet_ntoa(*(struct in_addr*)(hp->h_addr_list[i]))) == 0) {
|
||||
/* If reverse lookups are off, we'll use the conf-specified
|
||||
* hostname in preference to UNDETERMINED. */
|
||||
if (host == undetermined_hostname) {
|
||||
if (!(*host_ptr = strdup(tok)))
|
||||
*host_ptr = undetermined_hostname;
|
||||
}
|
||||
if (host == undetermined_hostname)
|
||||
*host_ptr = strdup(tok);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -241,9 +245,6 @@ static int access_match(const char *list, const char *addr, const char **host_pt
|
||||
char *tok;
|
||||
char *list2 = strdup(list);
|
||||
|
||||
if (!list2)
|
||||
out_of_memory("access_match");
|
||||
|
||||
strlower(list2);
|
||||
|
||||
for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
|
||||
|
||||
16
acls.c
16
acls.c
@@ -168,8 +168,6 @@ static rsync_acl *create_racl(void)
|
||||
{
|
||||
rsync_acl *racl = new(rsync_acl);
|
||||
|
||||
if (!racl)
|
||||
out_of_memory("create_racl");
|
||||
*racl = empty_rsync_acl;
|
||||
|
||||
return racl;
|
||||
@@ -335,8 +333,7 @@ static BOOL unpack_smb_acl(SMB_ACL_T sacl, rsync_acl *racl)
|
||||
qsort(temp_ida_list.items, temp_ida_list.count, sizeof (id_access), id_access_sorter);
|
||||
}
|
||||
#endif
|
||||
if (!(racl->names.idas = new_array(id_access, temp_ida_list.count)))
|
||||
out_of_memory("unpack_smb_acl");
|
||||
racl->names.idas = new_array(id_access, temp_ida_list.count);
|
||||
memcpy(racl->names.idas, temp_ida_list.items, temp_ida_list.count * sizeof (id_access));
|
||||
} else
|
||||
racl->names.idas = NULL;
|
||||
@@ -505,9 +502,7 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl,
|
||||
|
||||
if (cnt) {
|
||||
char *bp = buf + 4*4;
|
||||
id_access *ida;
|
||||
if (!(ida = racl->names.idas = new_array(id_access, cnt)))
|
||||
out_of_memory("get_rsync_acl");
|
||||
id_access *ida = racl->names.idas = new_array(id_access, cnt);
|
||||
racl->names.count = cnt;
|
||||
for ( ; cnt--; ida++, bp += 4+4) {
|
||||
ida->id = IVAL(bp, 0);
|
||||
@@ -703,12 +698,7 @@ static uchar recv_ida_entries(int f, ida_entries *ent)
|
||||
uchar computed_mask_bits = 0;
|
||||
int i, count = read_varint(f);
|
||||
|
||||
if (count) {
|
||||
if (!(ent->idas = new_array(id_access, count)))
|
||||
out_of_memory("recv_ida_entries");
|
||||
} else
|
||||
ent->idas = NULL;
|
||||
|
||||
ent->idas = count ? new_array(id_access, count) : NULL;
|
||||
ent->count = count;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int read_only;
|
||||
extern char *password_file;
|
||||
@@ -118,7 +119,7 @@ static const char *check_secret(int module, const char *user, const char *group,
|
||||
if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
|
||||
ok = 0;
|
||||
} else if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
} else if (MY_UID() == ROOT_UID && st.st_uid != ROOT_UID) {
|
||||
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
|
||||
ok = 0;
|
||||
}
|
||||
@@ -195,7 +196,7 @@ static const char *getpassf(const char *filename)
|
||||
rprintf(FERROR, "ERROR: password file must not be other-accessible\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
if (MY_UID() == ROOT_UID && st.st_uid != ROOT_UID) {
|
||||
rprintf(FERROR, "ERROR: password file must be owned by root when running as root\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
@@ -226,7 +227,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
|
||||
char *users = lp_auth_users(module);
|
||||
char challenge[MAX_DIGEST_LEN*2];
|
||||
char line[BIGPATHBUFLEN];
|
||||
char **auth_uid_groups = NULL;
|
||||
const char **auth_uid_groups = NULL;
|
||||
int auth_uid_groups_cnt = -1;
|
||||
const char *err = NULL;
|
||||
int group_match = -1;
|
||||
@@ -250,8 +251,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
|
||||
}
|
||||
*pass++ = '\0';
|
||||
|
||||
if (!(users = strdup(users)))
|
||||
out_of_memory("auth_server");
|
||||
users = strdup(users);
|
||||
|
||||
for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
|
||||
char *opts;
|
||||
@@ -287,8 +287,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
|
||||
else {
|
||||
gid_t *gid_array = gid_list.items;
|
||||
auth_uid_groups_cnt = gid_list.count;
|
||||
if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
|
||||
out_of_memory("auth_server");
|
||||
auth_uid_groups = new_array(const char *, auth_uid_groups_cnt);
|
||||
for (j = 0; j < auth_uid_groups_cnt; j++)
|
||||
auth_uid_groups[j] = gid_to_group(gid_array[j]);
|
||||
}
|
||||
@@ -314,7 +313,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
|
||||
else if (opt_ch == 'd')
|
||||
err = "denied by rule";
|
||||
else {
|
||||
char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
|
||||
const char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
|
||||
err = check_secret(module, line, group, challenge, pass);
|
||||
}
|
||||
|
||||
@@ -325,7 +324,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
|
||||
int j;
|
||||
for (j = 0; j < auth_uid_groups_cnt; j++) {
|
||||
if (auth_uid_groups[j])
|
||||
free(auth_uid_groups[j]);
|
||||
free((char*)auth_uid_groups[j]);
|
||||
}
|
||||
free(auth_uid_groups);
|
||||
}
|
||||
|
||||
11
batch.c
11
batch.c
@@ -38,13 +38,10 @@ extern int do_compression;
|
||||
extern int inplace;
|
||||
extern int append_mode;
|
||||
extern int write_batch;
|
||||
extern int xfersum_type;
|
||||
extern int protocol_version;
|
||||
extern int raw_argc, cooked_argc;
|
||||
extern char **raw_argv, **cooked_argv;
|
||||
extern char *batch_name;
|
||||
extern const char *checksum_choice;
|
||||
extern const char *compress_choice;
|
||||
#ifdef ICONV_OPTION
|
||||
extern char *iconv_opt;
|
||||
#endif
|
||||
@@ -269,14 +266,6 @@ void write_batch_shell_file(void)
|
||||
err |= write_opt("--exclude-from", "-");
|
||||
}
|
||||
|
||||
/* We need to make sure that any protocol-based or negotiated choices get accurately
|
||||
* reflected in the options we save AND that we avoid any need for --read-batch to
|
||||
* do a string-based negotiation (since we don't write them into the file). */
|
||||
if (do_compression)
|
||||
err |= write_opt("--compress-choice", compress_choice);
|
||||
if (strchr(checksum_choice, ',') || xfersum_type != parse_csum_name(NULL, -1))
|
||||
err |= write_opt("--checksum-choice", checksum_choice);
|
||||
|
||||
/* Elide the filename args from the option list, but scan for them in reverse. */
|
||||
for (i = raw_argc-1, j = cooked_argc-1; i > 0 && j >= 0; i--) {
|
||||
if (strcmp(raw_argv[i], cooked_argv[j]) == 0) {
|
||||
|
||||
109
checksum.c
109
checksum.c
@@ -27,8 +27,12 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#ifdef SUPPORT_XXHASH
|
||||
#include "xxhash.h"
|
||||
#include <xxhash.h>
|
||||
# if XXH_VERSION_NUMBER >= 800
|
||||
# define SUPPORT_XXH3 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
extern int am_server;
|
||||
@@ -40,6 +44,10 @@ extern const char *checksum_choice;
|
||||
|
||||
struct name_num_obj valid_checksums = {
|
||||
"checksum", NULL, NULL, 0, 0, {
|
||||
#ifdef SUPPORT_XXH3
|
||||
{ CSUM_XXH3_128, "xxh128", NULL },
|
||||
{ CSUM_XXH3_64, "xxh3", NULL },
|
||||
#endif
|
||||
#ifdef SUPPORT_XXHASH
|
||||
{ CSUM_XXH64, "xxh64", NULL },
|
||||
{ CSUM_XXH64, "xxhash", NULL },
|
||||
@@ -85,7 +93,7 @@ static const char *checksum_name(int num)
|
||||
{
|
||||
struct name_num_item *nni = get_nni_by_num(&valid_checksums, num);
|
||||
|
||||
return nni ? nni->name : num < CSUM_MD4 ? "MD4" : "UNKNOWN";
|
||||
return nni ? nni->name : num < CSUM_MD4 ? "md4" : "UNKNOWN";
|
||||
}
|
||||
|
||||
void parse_checksum_choice(int final_call)
|
||||
@@ -99,6 +107,8 @@ void parse_checksum_choice(int final_call)
|
||||
checksum_type = parse_csum_name(cp+1, -1);
|
||||
} else
|
||||
xfersum_type = checksum_type = parse_csum_name(checksum_choice, -1);
|
||||
if (am_server && checksum_choice)
|
||||
validate_choice_vs_env(NSTR_CHECKSUM, xfersum_type, checksum_type);
|
||||
}
|
||||
|
||||
if (xfersum_type == CSUM_NONE)
|
||||
@@ -133,10 +143,11 @@ int csum_len_for_type(int cst, BOOL flist_csum)
|
||||
return MD4_DIGEST_LEN;
|
||||
case CSUM_MD5:
|
||||
return MD5_DIGEST_LEN;
|
||||
#ifdef SUPPORT_XXHASH
|
||||
case CSUM_XXH64:
|
||||
case CSUM_XXH3_64:
|
||||
return 64/8;
|
||||
#endif
|
||||
case CSUM_XXH3_128:
|
||||
return 128/8;
|
||||
default: /* paranoia to prevent missing case values */
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
@@ -158,10 +169,10 @@ int canonical_checksum(int csum_type)
|
||||
case CSUM_MD4:
|
||||
case CSUM_MD5:
|
||||
return -1;
|
||||
#ifdef SUPPORT_XXHASH
|
||||
case CSUM_XXH64:
|
||||
case CSUM_XXH3_64:
|
||||
case CSUM_XXH3_128:
|
||||
return 1;
|
||||
#endif
|
||||
default: /* paranoia to prevent missing case values */
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
@@ -198,6 +209,17 @@ void get_checksum2(char *buf, int32 len, char *sum)
|
||||
case CSUM_XXH64:
|
||||
SIVAL64(sum, 0, XXH64(buf, len, checksum_seed));
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64:
|
||||
SIVAL64(sum, 0, XXH3_64bits_withSeed(buf, len, checksum_seed));
|
||||
break;
|
||||
case CSUM_XXH3_128: {
|
||||
XXH128_hash_t digest = XXH3_128bits_withSeed(buf, len, checksum_seed);
|
||||
SIVAL64(sum, 0, digest.low64);
|
||||
SIVAL64(sum, 8, digest.high64);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CSUM_MD5: {
|
||||
MD5_CTX m5;
|
||||
@@ -249,8 +271,6 @@ void get_checksum2(char *buf, int32 len, char *sum)
|
||||
free(buf1);
|
||||
buf1 = new_array(char, len+4);
|
||||
len1 = len;
|
||||
if (!buf1)
|
||||
out_of_memory("get_checksum2");
|
||||
}
|
||||
|
||||
memcpy(buf1, buf, len);
|
||||
@@ -313,6 +333,45 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
|
||||
SIVAL64(sum, 0, XXH64_digest(state));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64: {
|
||||
static XXH3_state_t* state = NULL;
|
||||
if (!state && !(state = XXH3_createState()))
|
||||
out_of_memory("file_checksum");
|
||||
|
||||
XXH3_64bits_reset(state);
|
||||
|
||||
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
|
||||
XXH3_64bits_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
|
||||
|
||||
remainder = (int32)(len - i);
|
||||
if (remainder > 0)
|
||||
XXH3_64bits_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
SIVAL64(sum, 0, XXH3_64bits_digest(state));
|
||||
break;
|
||||
}
|
||||
case CSUM_XXH3_128: {
|
||||
XXH128_hash_t digest;
|
||||
static XXH3_state_t* state = NULL;
|
||||
if (!state && !(state = XXH3_createState()))
|
||||
out_of_memory("file_checksum");
|
||||
|
||||
XXH3_128bits_reset(state);
|
||||
|
||||
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
|
||||
XXH3_128bits_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
|
||||
|
||||
remainder = (int32)(len - i);
|
||||
if (remainder > 0)
|
||||
XXH3_128bits_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
digest = XXH3_128bits_digest(state);
|
||||
SIVAL64(sum, 0, digest.low64);
|
||||
SIVAL64(sum, 8, digest.high64);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CSUM_MD5: {
|
||||
MD5_CTX m5;
|
||||
@@ -389,6 +448,9 @@ static union {
|
||||
#ifdef SUPPORT_XXHASH
|
||||
static XXH64_state_t* xxh64_state;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
static XXH3_state_t* xxh3_state;
|
||||
#endif
|
||||
static int cursum_type;
|
||||
|
||||
void sum_init(int csum_type, int seed)
|
||||
@@ -406,6 +468,18 @@ void sum_init(int csum_type, int seed)
|
||||
out_of_memory("sum_init");
|
||||
XXH64_reset(xxh64_state, 0);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64:
|
||||
if (!xxh3_state && !(xxh3_state = XXH3_createState()))
|
||||
out_of_memory("sum_init");
|
||||
XXH3_64bits_reset(xxh3_state);
|
||||
break;
|
||||
case CSUM_XXH3_128:
|
||||
if (!xxh3_state && !(xxh3_state = XXH3_createState()))
|
||||
out_of_memory("sum_init");
|
||||
XXH3_128bits_reset(xxh3_state);
|
||||
break;
|
||||
#endif
|
||||
case CSUM_MD5:
|
||||
MD5_Init(&ctx.m5);
|
||||
@@ -448,6 +522,14 @@ void sum_update(const char *p, int32 len)
|
||||
case CSUM_XXH64:
|
||||
XXH64_update(xxh64_state, p, len);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64:
|
||||
XXH3_64bits_update(xxh3_state, p, len);
|
||||
break;
|
||||
case CSUM_XXH3_128:
|
||||
XXH3_128bits_update(xxh3_state, p, len);
|
||||
break;
|
||||
#endif
|
||||
case CSUM_MD5:
|
||||
MD5_Update(&ctx.m5, (uchar *)p, len);
|
||||
@@ -502,6 +584,17 @@ int sum_end(char *sum)
|
||||
case CSUM_XXH64:
|
||||
SIVAL64(sum, 0, XXH64_digest(xxh64_state));
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_XXH3
|
||||
case CSUM_XXH3_64:
|
||||
SIVAL64(sum, 0, XXH3_64bits_digest(xxh3_state));
|
||||
break;
|
||||
case CSUM_XXH3_128: {
|
||||
XXH128_hash_t digest = XXH3_128bits_digest(xxh3_state);
|
||||
SIVAL64(sum, 0, digest.low64);
|
||||
SIVAL64(sum, 8, digest.high64);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case CSUM_MD5:
|
||||
MD5_Final((uchar *)sum, &ctx.m5);
|
||||
|
||||
@@ -137,7 +137,7 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
if (DEBUG_GTE(EXIT, 2)) {
|
||||
rprintf(FINFO,
|
||||
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
who_am_i(), code, file, line);
|
||||
who_am_i(), code, src_file(file), line);
|
||||
}
|
||||
|
||||
#include "case_N.h"
|
||||
@@ -221,8 +221,9 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
/* If line < 0, this exit is after a MSG_ERROR_EXIT event, so
|
||||
* we don't want to output a duplicate error. */
|
||||
if ((exit_code && line > 0)
|
||||
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1))))
|
||||
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1)))) {
|
||||
log_exit(exit_code, exit_file, exit_line);
|
||||
}
|
||||
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
@@ -139,7 +139,7 @@ char *client_name(const char *ipaddr)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
NOISY_DEATH("Unknown ai_family value");
|
||||
}
|
||||
freeaddrinfo(answer);
|
||||
|
||||
@@ -156,7 +156,7 @@ char *client_name(const char *ipaddr)
|
||||
}
|
||||
|
||||
|
||||
/* Try to read an proxy protocol header (V1 or V2). Returns 1 on success or 0 on failure. */
|
||||
/* Try to read a proxy protocol header (V1 or V2). Returns 1 on success or 0 on failure. */
|
||||
int read_proxy_protocol_header(int fd)
|
||||
{
|
||||
union {
|
||||
|
||||
137
clientserver.c
137
clientserver.c
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int quiet;
|
||||
extern int dry_run;
|
||||
@@ -36,8 +37,8 @@ extern int protect_args;
|
||||
extern int ignore_errors;
|
||||
extern int preserve_xattrs;
|
||||
extern int kluge_around_eof;
|
||||
extern int daemon_over_rsh;
|
||||
extern int munge_symlinks;
|
||||
extern int open_noatime;
|
||||
extern int sanitize_paths;
|
||||
extern int numeric_ids;
|
||||
extern int filesfrom_fd;
|
||||
@@ -70,6 +71,7 @@ int module_id = -1;
|
||||
int pid_file_fd = -1;
|
||||
int early_input_len = 0;
|
||||
char *early_input = NULL;
|
||||
pid_t namecvt_pid = 0;
|
||||
struct chmod_mode_struct *daemon_chmod_modes;
|
||||
|
||||
#define EARLY_INPUT_CMD "#early_input="
|
||||
@@ -84,6 +86,7 @@ unsigned int module_dirlen = 0;
|
||||
char *full_module_path;
|
||||
|
||||
static int rl_nulls = 0;
|
||||
static int namecvt_fd_req = -1, namecvt_fd_ans = -1;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
static struct sigaction sigact;
|
||||
@@ -235,8 +238,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
|
||||
else
|
||||
modlen = p - *argv;
|
||||
|
||||
if (!(modname = new_array(char, modlen+1+1))) /* room for '/' & '\0' */
|
||||
out_of_memory("start_inband_exchange");
|
||||
modname = new_array(char, modlen+1+1); /* room for '/' & '\0' */
|
||||
strlcpy(modname, *argv, modlen + 1);
|
||||
modname[modlen] = '/';
|
||||
modname[modlen+1] = '\0';
|
||||
@@ -279,10 +281,6 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/* set daemon_over_rsh to false since we need to build the
|
||||
* true set of args passed through the rsh/ssh connection;
|
||||
* this is a no-op for direct-socket-connection mode */
|
||||
daemon_over_rsh = 0;
|
||||
server_options(sargs, &sargc);
|
||||
|
||||
if (sargc >= MAX_ARGS - 2)
|
||||
@@ -425,7 +423,7 @@ void set_env_num(const char *var, long num)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Used for both early exec & pre-xfer exec */
|
||||
/* 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)
|
||||
{
|
||||
int arg_fds[2], error_fds[2], arg_fd;
|
||||
@@ -492,7 +490,7 @@ static pid_t start_pre_exec(const char *cmd, int *arg_fd_ptr, int *error_fd_ptr)
|
||||
return pid;
|
||||
}
|
||||
|
||||
static void write_pre_exec_args(int write_fd, char *request, char **early_argv, char **argv, int am_early)
|
||||
static void write_pre_exec_args(int write_fd, char *request, char **early_argv, char **argv, int exec_type)
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
@@ -511,10 +509,11 @@ static void write_pre_exec_args(int write_fd, char *request, char **early_argv,
|
||||
}
|
||||
write_byte(write_fd, 0);
|
||||
|
||||
if (am_early && early_input_len)
|
||||
if (exec_type == 1 && early_input_len)
|
||||
write_buf(write_fd, early_input, early_input_len);
|
||||
|
||||
close(write_fd);
|
||||
if (exec_type != 2) /* the name converter needs this left open */
|
||||
close(write_fd);
|
||||
}
|
||||
|
||||
static char *finish_pre_exec(const char *desc, pid_t pid, int read_fd)
|
||||
@@ -696,17 +695,17 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
|
||||
module_id = i;
|
||||
|
||||
if (lp_transfer_logging(i) && !logfile_format)
|
||||
logfile_format = lp_log_format(i);
|
||||
if (lp_transfer_logging(module_id) && !logfile_format)
|
||||
logfile_format = lp_log_format(module_id);
|
||||
if (log_format_has(logfile_format, 'i'))
|
||||
logfile_format_has_i = 1;
|
||||
if (logfile_format_has_i || log_format_has(logfile_format, 'o'))
|
||||
logfile_format_has_o_or_i = 1;
|
||||
|
||||
uid = MY_UID();
|
||||
am_root = (uid == 0);
|
||||
am_root = (uid == ROOT_UID);
|
||||
|
||||
p = *lp_uid(i) ? lp_uid(i) : am_root ? NOBODY_USER : NULL;
|
||||
p = *lp_uid(module_id) ? lp_uid(module_id) : am_root ? NOBODY_USER : NULL;
|
||||
if (p) {
|
||||
if (!user_to_uid(p, &uid, True)) {
|
||||
rprintf(FLOG, "Invalid uid %s\n", p);
|
||||
@@ -717,7 +716,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
} else
|
||||
set_uid = 0;
|
||||
|
||||
p = *lp_gid(i) ? conf_strtok(lp_gid(i)) : NULL;
|
||||
p = *lp_gid(module_id) ? conf_strtok(lp_gid(module_id)) : NULL;
|
||||
if (p) {
|
||||
/* The "*" gid must be the first item in the list. */
|
||||
if (strcmp(p, "*") == 0) {
|
||||
@@ -750,7 +749,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
return -1;
|
||||
}
|
||||
|
||||
module_dir = lp_path(i);
|
||||
module_dir = lp_path(module_id);
|
||||
if (*module_dir == '\0') {
|
||||
rprintf(FLOG, "No path specified for module %s\n", name);
|
||||
io_printf(f_out, "@ERROR: no path setting.\n");
|
||||
@@ -787,38 +786,39 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
} else
|
||||
set_filter_dir(module_dir, module_dirlen);
|
||||
|
||||
p = lp_filter(i);
|
||||
p = lp_filter(module_id);
|
||||
parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3);
|
||||
|
||||
p = lp_include_from(i);
|
||||
p = lp_include_from(module_id);
|
||||
parse_filter_file(&daemon_filter_list, p, rule_template(FILTRULE_INCLUDE),
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
|
||||
|
||||
p = lp_include(i);
|
||||
p = lp_include(module_id);
|
||||
parse_filter_str(&daemon_filter_list, p,
|
||||
rule_template(FILTRULE_INCLUDE | FILTRULE_WORD_SPLIT),
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES);
|
||||
|
||||
p = lp_exclude_from(i);
|
||||
p = lp_exclude_from(module_id);
|
||||
parse_filter_file(&daemon_filter_list, p, rule_template(0),
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
|
||||
|
||||
p = lp_exclude(i);
|
||||
p = lp_exclude(module_id);
|
||||
parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES);
|
||||
|
||||
log_init(1);
|
||||
|
||||
#ifdef HAVE_PUTENV
|
||||
if ((*lp_early_exec(i) || *lp_prexfer_exec(i) || *lp_postxfer_exec(i))
|
||||
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")) {
|
||||
set_env_num("RSYNC_PID", (long)getpid());
|
||||
|
||||
/* For post-xfer exec, fork a new process to run the rsync
|
||||
* daemon while this process waits for the exit status and
|
||||
* runs the indicated command at that point. */
|
||||
if (*lp_postxfer_exec(i)) {
|
||||
if (*lp_postxfer_exec(module_id)) {
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
rsyserr(FLOG, errno, "fork failed");
|
||||
@@ -838,7 +838,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
else
|
||||
status = -1;
|
||||
set_env_num("RSYNC_EXIT_STATUS", status);
|
||||
if (shell_exec(lp_postxfer_exec(i)) < 0)
|
||||
if (shell_exec(lp_postxfer_exec(module_id)) < 0)
|
||||
status = -1;
|
||||
_exit(status);
|
||||
}
|
||||
@@ -846,9 +846,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
|
||||
/* For early exec, fork a child process to run the indicated
|
||||
* command and wait for it to exit. */
|
||||
if (*lp_early_exec(i)) {
|
||||
if (*lp_early_exec(module_id)) {
|
||||
int arg_fd;
|
||||
pid_t pid = start_pre_exec(lp_early_exec(i), &arg_fd, NULL);
|
||||
pid_t pid = start_pre_exec(lp_early_exec(module_id), &arg_fd, NULL);
|
||||
if (pid == (pid_t)-1) {
|
||||
rsyserr(FLOG, errno, "early exec preparation failed");
|
||||
io_printf(f_out, "@ERROR: early exec preparation failed\n");
|
||||
@@ -865,14 +865,23 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
/* For pre-xfer exec, fork a child process to run the indicated
|
||||
* command, though it first waits for the parent process to
|
||||
* send us the user's request via a pipe. */
|
||||
if (*lp_prexfer_exec(i)) {
|
||||
pre_exec_pid = start_pre_exec(lp_prexfer_exec(i), &pre_exec_arg_fd, &pre_exec_error_fd);
|
||||
if (*lp_prexfer_exec(module_id)) {
|
||||
pre_exec_pid = start_pre_exec(lp_prexfer_exec(module_id), &pre_exec_arg_fd, &pre_exec_error_fd);
|
||||
if (pre_exec_pid == (pid_t)-1) {
|
||||
rsyserr(FLOG, errno, "pre-xfer exec preparation failed");
|
||||
io_printf(f_out, "@ERROR: pre-xfer exec preparation failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (*lp_name_converter(module_id)) {
|
||||
namecvt_pid = start_pre_exec(lp_name_converter(module_id), &namecvt_fd_req, &namecvt_fd_ans);
|
||||
if (namecvt_pid == (pid_t)-1) {
|
||||
rsyserr(FLOG, errno, "name-converter exec preparation failed");
|
||||
io_printf(f_out, "@ERROR: name-converter exec preparation failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -907,7 +916,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
if (module_dirlen || (!use_chroot && !*lp_daemon_chroot()))
|
||||
sanitize_paths = 1;
|
||||
|
||||
if ((munge_symlinks = lp_munge_symlinks(i)) < 0)
|
||||
if ((munge_symlinks = lp_munge_symlinks(module_id)) < 0)
|
||||
munge_symlinks = !use_chroot || module_dirlen;
|
||||
if (munge_symlinks) {
|
||||
STRUCT_STAT st;
|
||||
@@ -959,11 +968,11 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
}
|
||||
|
||||
our_uid = MY_UID();
|
||||
am_root = (our_uid == 0);
|
||||
am_root = (our_uid == ROOT_UID);
|
||||
}
|
||||
|
||||
if (lp_temp_dir(i) && *lp_temp_dir(i)) {
|
||||
tmpdir = lp_temp_dir(i);
|
||||
if (lp_temp_dir(module_id) && *lp_temp_dir(module_id)) {
|
||||
tmpdir = lp_temp_dir(module_id);
|
||||
if (strlen(tmpdir) >= MAXPATHLEN - 10) {
|
||||
rprintf(FLOG,
|
||||
"the 'temp dir' value for %s is WAY too long -- ignoring.\n",
|
||||
@@ -990,7 +999,12 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
} else
|
||||
orig_early_argv = NULL;
|
||||
|
||||
/* The default is to use the user's setting unless the module sets True or False. */
|
||||
if (lp_open_noatime(module_id) >= 0)
|
||||
open_noatime = lp_open_noatime(module_id);
|
||||
|
||||
munge_symlinks = save_munge_symlinks; /* The client mustn't control this. */
|
||||
|
||||
if (am_daemon > 0)
|
||||
msgs2stderr = 0; /* A non-rsh-run daemon doesn't have stderr for msgs. */
|
||||
|
||||
@@ -999,6 +1013,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
err_msg = finish_pre_exec("pre-xfer exec", pre_exec_pid, pre_exec_error_fd);
|
||||
}
|
||||
|
||||
if (namecvt_pid)
|
||||
write_pre_exec_args(namecvt_fd_req, request, orig_early_argv, orig_argv, 2);
|
||||
|
||||
if (orig_early_argv)
|
||||
free(orig_early_argv);
|
||||
|
||||
@@ -1009,7 +1026,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
if (write_batch < 0)
|
||||
dry_run = 1;
|
||||
|
||||
if (lp_fake_super(i)) {
|
||||
if (lp_fake_super(module_id)) {
|
||||
if (preserve_xattrs > 1)
|
||||
preserve_xattrs = 1;
|
||||
am_root = -1;
|
||||
@@ -1034,7 +1051,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
|
||||
#ifndef DEBUG
|
||||
/* don't allow the logs to be flooded too fast */
|
||||
limit_output_verbosity(lp_max_verbosity(i));
|
||||
limit_output_verbosity(lp_max_verbosity(module_id));
|
||||
#endif
|
||||
|
||||
if (protocol_version < 23 && (protocol_version == 22 || am_sender))
|
||||
@@ -1095,20 +1112,21 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
#endif
|
||||
|
||||
if (!numeric_ids
|
||||
&& (use_chroot ? lp_numeric_ids(i) != False : lp_numeric_ids(i) == True))
|
||||
&& (use_chroot ? lp_numeric_ids(module_id) != False && !*lp_name_converter(module_id)
|
||||
: lp_numeric_ids(module_id) == True))
|
||||
numeric_ids = -1; /* Set --numeric-ids w/o breaking protocol. */
|
||||
|
||||
if (lp_timeout(i) && (!io_timeout || lp_timeout(i) < io_timeout))
|
||||
set_io_timeout(lp_timeout(i));
|
||||
if (lp_timeout(module_id) && (!io_timeout || lp_timeout(module_id) < io_timeout))
|
||||
set_io_timeout(lp_timeout(module_id));
|
||||
|
||||
/* If we have some incoming/outgoing chmod changes, append them to
|
||||
* any user-specified changes (making our changes have priority).
|
||||
* We also get a pointer to just our changes so that a receiver
|
||||
* process can use them separately if --perms wasn't specified. */
|
||||
if (am_sender)
|
||||
p = lp_outgoing_chmod(i);
|
||||
p = lp_outgoing_chmod(module_id);
|
||||
else
|
||||
p = lp_incoming_chmod(i);
|
||||
p = lp_incoming_chmod(module_id);
|
||||
if (*p && !(daemon_chmod_modes = parse_chmod(p, &chmod_modes))) {
|
||||
rprintf(FLOG, "Invalid \"%sing chmod\" directive: %s\n",
|
||||
am_sender ? "outgo" : "incom", p);
|
||||
@@ -1119,6 +1137,38 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL namecvt_call(const char *cmd, const char **name_p, id_t *id_p)
|
||||
{
|
||||
char buf[1024];
|
||||
int got, len;
|
||||
|
||||
if (*name_p)
|
||||
len = snprintf(buf, sizeof buf, "%s %s\n", cmd, *name_p);
|
||||
else
|
||||
len = snprintf(buf, sizeof buf, "%s %ld\n", cmd, (long)*id_p);
|
||||
if (len >= (int)sizeof buf) {
|
||||
rprintf(FERROR, "namecvt_call() request was too large.\n");
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
while ((got = write(namecvt_fd_req, buf, len)) != len) {
|
||||
if (got < 0 && errno == EINTR)
|
||||
continue;
|
||||
rprintf(FERROR, "Connection to name-converter failed.\n");
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
if (!read_line_old(namecvt_fd_ans, buf, sizeof buf, 0))
|
||||
return False;
|
||||
|
||||
if (*name_p)
|
||||
*id_p = (id_t)atol(buf);
|
||||
else
|
||||
*name_p = strdup(buf);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/* send a list of available modules to the client. Don't list those
|
||||
with "list = False". */
|
||||
static void send_listing(int fd)
|
||||
@@ -1208,7 +1258,7 @@ int start_daemon(int f_in, int f_out)
|
||||
return -1;
|
||||
}
|
||||
our_uid = MY_UID();
|
||||
am_root = (our_uid == 0);
|
||||
am_root = (our_uid == ROOT_UID);
|
||||
}
|
||||
|
||||
addr = client_addr(f_in);
|
||||
@@ -1233,8 +1283,7 @@ int start_daemon(int f_in, int f_out)
|
||||
io_printf(f_out, "@ERROR: invalid early_input length\n");
|
||||
return -1;
|
||||
}
|
||||
if (!(early_input = new_array(char, early_input_len)))
|
||||
out_of_memory("exchange_protocols");
|
||||
early_input = new_array(char, early_input_len);
|
||||
read_buf(f_in, early_input, early_input_len);
|
||||
|
||||
if (!read_line_old(f_in, line, sizeof line, 0))
|
||||
@@ -1402,7 +1451,7 @@ int daemon_main(void)
|
||||
log_init(0);
|
||||
|
||||
rprintf(FLOG, "rsyncd version %s starting, listening on port %d\n",
|
||||
RSYNC_VERSION, rsync_port);
|
||||
rsync_version(), rsync_port);
|
||||
/* TODO: If listening on a particular address, then show that
|
||||
* address too. In fact, why not just do getnameinfo on the
|
||||
* local address??? */
|
||||
|
||||
198
compat.c
198
compat.c
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
|
||||
extern int am_server;
|
||||
extern int am_sender;
|
||||
@@ -42,6 +43,7 @@ extern int protect_args;
|
||||
extern int preserve_uid;
|
||||
extern int preserve_gid;
|
||||
extern int preserve_atimes;
|
||||
extern int preserve_crtimes;
|
||||
extern int preserve_acls;
|
||||
extern int preserve_xattrs;
|
||||
extern int xfer_flags_as_varint;
|
||||
@@ -72,9 +74,10 @@ int want_xattr_optim = 0;
|
||||
int proper_seed_order = 0;
|
||||
int inplace_partial = 0;
|
||||
int do_negotiated_strings = 0;
|
||||
int xmit_id0_names = 0;
|
||||
|
||||
/* These index values are for the file-list's extra-attribute array. */
|
||||
int pathname_ndx, depth_ndx, atimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
|
||||
int pathname_ndx, depth_ndx, atimes_ndx, crtimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
|
||||
|
||||
int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
|
||||
int sender_symlink_iconv = 0; /* sender should convert symlink content */
|
||||
@@ -108,6 +111,7 @@ struct name_num_obj valid_compressions = {
|
||||
#define CF_CHKSUM_SEED_FIX (1<<5)
|
||||
#define CF_INPLACE_PARTIAL_DIR (1<<6)
|
||||
#define CF_VARINT_FLIST_FLAGS (1<<7)
|
||||
#define CF_ID0_NAMES (1<<8)
|
||||
|
||||
static const char *client_info;
|
||||
|
||||
@@ -173,6 +177,8 @@ void parse_compress_choice(int final_call)
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
do_compression = nni->num;
|
||||
if (am_server)
|
||||
validate_choice_vs_env(NSTR_COMPRESS, do_compression, -1);
|
||||
} else if (do_compression)
|
||||
do_compression = CPRES_ZLIB;
|
||||
else
|
||||
@@ -241,8 +247,7 @@ static void init_nno_saw(struct name_num_obj *nno, int val)
|
||||
}
|
||||
|
||||
if (!nno->saw) {
|
||||
if (!(nno->saw = new_array0(uchar, nno->saw_len)))
|
||||
out_of_memory("init_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. */
|
||||
for (cnt = 1, nni = nno->list; nni->name; nni++, cnt++) {
|
||||
@@ -261,10 +266,14 @@ static void init_nno_saw(struct name_num_obj *nno, int val)
|
||||
static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf, int tobuf_len)
|
||||
{
|
||||
char *to = tobuf, *tok = NULL;
|
||||
int cnt = 0;
|
||||
int saw_tok = 0, cnt = 0;
|
||||
|
||||
while (1) {
|
||||
if (*from == ' ' || !*from) {
|
||||
int at_space = isSpace(from);
|
||||
char ch = *from++;
|
||||
if (ch == '&')
|
||||
ch = '\0';
|
||||
if (!ch || at_space) {
|
||||
if (tok) {
|
||||
struct name_num_item *nni = get_nni_by_name(nno, tok, to - tok);
|
||||
if (nni && !nno->saw[nni->num]) {
|
||||
@@ -278,9 +287,10 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
|
||||
}
|
||||
} else
|
||||
to = tok - (tok != tobuf);
|
||||
saw_tok = 1;
|
||||
tok = NULL;
|
||||
}
|
||||
if (!*from++)
|
||||
if (!ch)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
@@ -293,13 +303,19 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
|
||||
to = tok - (tok != tobuf);
|
||||
break;
|
||||
}
|
||||
*to++ = *from++;
|
||||
*to++ = ch;
|
||||
}
|
||||
*to = '\0';
|
||||
|
||||
if (saw_tok && to == tobuf)
|
||||
return strlcpy(tobuf, "INVALID", MAX_NSTR_STRLEN);
|
||||
|
||||
return to - tobuf;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@@ -315,17 +331,26 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *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 *tok;
|
||||
if (am_server)
|
||||
init_nno_saw(nno, 1); /* Since we're parsing client names, anything we parse first is #1. */
|
||||
for (tok = strtok(tmpbuf, " \t"); tok; tok = strtok(NULL, " \t")) {
|
||||
struct name_num_item *nni = get_nni_by_name(nno, tok, -1);
|
||||
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)
|
||||
if (best == 1 || am_server) /* The server side stops at the first acceptable client choice */
|
||||
break;
|
||||
}
|
||||
if (ret) {
|
||||
@@ -337,15 +362,84 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf,
|
||||
}
|
||||
}
|
||||
|
||||
if (!am_server)
|
||||
rprintf(FERROR, "Failed to negotiate a common %s\n", nno->type);
|
||||
if (!am_server || !do_negotiated_strings) {
|
||||
char *cp = tmpbuf;
|
||||
int j;
|
||||
rprintf(FERROR, "Failed to negotiate a %s choice.\n", nno->type);
|
||||
rprintf(FERROR, "%s list: %s\n", am_server ? "Client" : "Server", tmpbuf);
|
||||
/* Recreate our original list from the saw values. This can't overflow our huge
|
||||
* buffer because we don't have enough valid entries to get anywhere close. */
|
||||
for (j = 1, *cp = '\0'; j <= nno->saw_len; j++) {
|
||||
struct name_num_item *nni;
|
||||
for (nni = nno->list; nni->name; nni++) {
|
||||
if (nno->saw[nni->num] == j) {
|
||||
*cp++ = ' ';
|
||||
cp += strlcpy(cp, nni->name, MAX_NSTR_STRLEN - (cp - tmpbuf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!*tmpbuf)
|
||||
strlcpy(cp, " INVALID", MAX_NSTR_STRLEN);
|
||||
rprintf(FERROR, "%s list:%s\n", am_server ? "Server" : "Client", tmpbuf);
|
||||
}
|
||||
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
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)
|
||||
env_str = ntype == NSTR_COMPRESS ? "zlib" : protocol_version >= 30 ? "md5" : "md4";
|
||||
|
||||
if (am_server && env_str) {
|
||||
char *cp = strchr(env_str, '&');
|
||||
if (cp)
|
||||
env_str = cp + 1;
|
||||
}
|
||||
|
||||
return env_str;
|
||||
}
|
||||
|
||||
void validate_choice_vs_env(int ntype, int num1, int num2)
|
||||
{
|
||||
struct name_num_obj *nno = ntype == NSTR_COMPRESS ? &valid_compressions : &valid_checksums;
|
||||
const char *list_str = getenv_nstr(ntype);
|
||||
char tmpbuf[MAX_NSTR_STRLEN];
|
||||
|
||||
if (!list_str)
|
||||
return;
|
||||
|
||||
while (isSpace(list_str)) list_str++;
|
||||
|
||||
if (!*list_str)
|
||||
return;
|
||||
|
||||
init_nno_saw(nno, 0);
|
||||
parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
|
||||
|
||||
if (ntype == NSTR_CHECKSUM) /* If "md4" is in the env list, all the old MD4 choices are OK too. */
|
||||
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",
|
||||
ntype == NSTR_COMPRESS ? "compress" : "checksum",
|
||||
ntype == NSTR_COMPRESS ? compress_choice : checksum_choice);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
free(nno->saw);
|
||||
nno->saw = NULL;
|
||||
}
|
||||
|
||||
/* The saw buffer is initialized and used to store ordinal values from 1 to N
|
||||
* for the order of the args in the array. If dup_markup == '\0', duplicates
|
||||
* are removed otherwise the char is prefixed to the duplicate term and, if it
|
||||
* is an opening paren/bracket/brace, the matching closing char is suffixed. */
|
||||
* is an opening paren/bracket/brace, the matching closing char is suffixed.
|
||||
* "none" is removed on the client side unless dup_markup != '\0'. */
|
||||
int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len, char dup_markup)
|
||||
{
|
||||
struct name_num_item *nni;
|
||||
@@ -367,6 +461,8 @@ int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len,
|
||||
continue;
|
||||
delim = dup_markup;
|
||||
}
|
||||
if (nni->num == 0 && !am_server && !dup_markup)
|
||||
continue;
|
||||
if (len)
|
||||
to_buf[len++]= ' ';
|
||||
if (delim) {
|
||||
@@ -386,25 +482,15 @@ int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len,
|
||||
return len;
|
||||
}
|
||||
|
||||
static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *env_name)
|
||||
static void send_negotiate_str(int f_out, struct name_num_obj *nno, int ntype)
|
||||
{
|
||||
char tmpbuf[MAX_NSTR_STRLEN];
|
||||
const char *list_str = getenv(env_name);
|
||||
int len, fail_if_empty = list_str && strstr(list_str, "FAIL");
|
||||
const char *list_str = getenv_nstr(ntype);
|
||||
int len;
|
||||
|
||||
if (!do_negotiated_strings) {
|
||||
if (!am_server && fail_if_empty) {
|
||||
rprintf(FERROR, "Remote rsync is too old for %s negotiation\n", nno->type);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (list_str && *list_str && (!am_server || local_server)) {
|
||||
if (list_str && *list_str) {
|
||||
init_nno_saw(nno, 0);
|
||||
len = parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
|
||||
if (fail_if_empty && !len)
|
||||
len = strlcpy(tmpbuf, "FAIL", MAX_NSTR_STRLEN);
|
||||
list_str = tmpbuf;
|
||||
} else
|
||||
list_str = NULL;
|
||||
@@ -419,15 +505,10 @@ static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *
|
||||
rprintf(FINFO, "Client %s list (on client): %s\n", nno->type, tmpbuf);
|
||||
}
|
||||
|
||||
if (local_server) {
|
||||
/* A local server doesn't bother to send/recv the strings, it just constructs
|
||||
* and parses the same string on both sides. */
|
||||
recv_negotiate_str(-1, nno, tmpbuf, len);
|
||||
} else {
|
||||
/* Each side sends their list of valid names to the other side and then both sides
|
||||
* pick the first name in the client's list that is also in the server's list. */
|
||||
/* Each side sends their list of valid names to the other side and then both sides
|
||||
* pick the first name in the client's list that is also in the server's list. */
|
||||
if (do_negotiated_strings)
|
||||
write_vstring(f_out, tmpbuf, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void negotiate_the_strings(int f_in, int f_out)
|
||||
@@ -435,20 +516,35 @@ 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. */
|
||||
|
||||
if (!checksum_choice)
|
||||
send_negotiate_str(f_out, &valid_checksums, "RSYNC_CHECKSUM_LIST");
|
||||
send_negotiate_str(f_out, &valid_checksums, NSTR_CHECKSUM);
|
||||
|
||||
if (do_compression && !compress_choice)
|
||||
send_negotiate_str(f_out, &valid_compressions, "RSYNC_COMPRESS_LIST");
|
||||
send_negotiate_str(f_out, &valid_compressions, NSTR_COMPRESS);
|
||||
|
||||
if (valid_checksums.saw) {
|
||||
char tmpbuf[MAX_NSTR_STRLEN];
|
||||
recv_negotiate_str(f_in, &valid_checksums, tmpbuf, -1);
|
||||
int len;
|
||||
if (do_negotiated_strings)
|
||||
len = -1;
|
||||
else
|
||||
len = strlcpy(tmpbuf, protocol_version >= 30 ? "md5" : "md4", MAX_NSTR_STRLEN);
|
||||
recv_negotiate_str(f_in, &valid_checksums, tmpbuf, len);
|
||||
}
|
||||
|
||||
if (valid_compressions.saw) {
|
||||
char tmpbuf[MAX_NSTR_STRLEN];
|
||||
recv_negotiate_str(f_in, &valid_compressions, tmpbuf, -1);
|
||||
int len;
|
||||
if (do_negotiated_strings)
|
||||
len = -1;
|
||||
else
|
||||
len = strlcpy(tmpbuf, "zlib", MAX_NSTR_STRLEN);
|
||||
recv_negotiate_str(f_in, &valid_compressions, tmpbuf, len);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
void setup_protocol(int f_out,int f_in)
|
||||
@@ -460,6 +556,8 @@ void setup_protocol(int f_out,int f_in)
|
||||
* aligned for direct int64-pointer memory access. */
|
||||
if (preserve_atimes)
|
||||
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. */
|
||||
pathname_ndx = (file_extra_cnt += PTR_EXTRA_CNT);
|
||||
else
|
||||
@@ -601,11 +699,11 @@ void setup_protocol(int f_out,int f_in)
|
||||
compat_flags |= CF_CHKSUM_SEED_FIX;
|
||||
if (local_server || strchr(client_info, 'I') != NULL)
|
||||
compat_flags |= CF_INPLACE_PARTIAL_DIR;
|
||||
if (local_server || strchr(client_info, 'u') != NULL)
|
||||
compat_flags |= CF_ID0_NAMES;
|
||||
if (local_server || strchr(client_info, 'v') != NULL) {
|
||||
if (!write_batch || protocol_version >= 30) {
|
||||
do_negotiated_strings = 1;
|
||||
compat_flags |= CF_VARINT_FLIST_FLAGS;
|
||||
}
|
||||
do_negotiated_strings = 1;
|
||||
compat_flags |= CF_VARINT_FLIST_FLAGS;
|
||||
}
|
||||
if (strchr(client_info, 'V') != NULL) { /* Support a pre-release 'V' that got superseded */
|
||||
if (!write_batch)
|
||||
@@ -623,6 +721,11 @@ void setup_protocol(int f_out,int f_in)
|
||||
want_xattr_optim = protocol_version >= 31 && !(compat_flags & CF_AVOID_XATTR_OPTIM);
|
||||
proper_seed_order = compat_flags & CF_CHKSUM_SEED_FIX ? 1 : 0;
|
||||
xfer_flags_as_varint = compat_flags & CF_VARINT_FLIST_FLAGS ? 1 : 0;
|
||||
xmit_id0_names = compat_flags & CF_ID0_NAMES ? 1 : 0;
|
||||
if (!xfer_flags_as_varint && preserve_crtimes) {
|
||||
fprintf(stderr, "Both rsync versions must be at least 3.2.0 for --crtimes.\n");
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if (am_sender) {
|
||||
receiver_symlink_times = am_server
|
||||
? strchr(client_info, 'L') != NULL
|
||||
@@ -654,6 +757,9 @@ void setup_protocol(int f_out,int f_in)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (read_batch)
|
||||
do_negotiated_strings = 0;
|
||||
|
||||
if (need_unsorted_flist && (!am_sender || inc_recurse))
|
||||
unsort_ndx = ++file_extra_cnt;
|
||||
|
||||
|
||||
28
configure
vendored
28
configure
vendored
@@ -4,24 +4,24 @@
|
||||
# then transfer control to the configure.sh script to do the real work.
|
||||
|
||||
dir=`dirname $0`
|
||||
realconfigure="$dir/configure.sh"
|
||||
if test x"$dir" = x; then
|
||||
dir=.
|
||||
fi
|
||||
|
||||
if test ! -f "$realconfigure"; then
|
||||
if test -f "$HOME/build_farm/build_test.fns"; then
|
||||
# Test the included popt
|
||||
set -- --with-included-popt "${@}"
|
||||
# Allow the build farm to grab latest files via rsync.
|
||||
actions='build fetch'
|
||||
else
|
||||
actions='build'
|
||||
if test "$dir" = '.'; then
|
||||
branch=`packaging/prep-auto-dir` || exit 1
|
||||
if test x"$branch" != x; then
|
||||
cd build || exit 1
|
||||
dir=..
|
||||
fi
|
||||
if "$dir/prepare-source" $actions; then
|
||||
:
|
||||
else
|
||||
fi
|
||||
|
||||
if test ! -f configure.sh; then
|
||||
if ! "$dir/prepare-source" build; then
|
||||
echo 'Failed to build configure.sh and/or config.h.in -- giving up.' >&2
|
||||
rm -f "$realconfigure"
|
||||
rm -f configure.sh
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$realconfigure" "${@}"
|
||||
exec ./configure.sh --srcdir="$dir" "${@}"
|
||||
|
||||
109
configure.ac
109
configure.ac
@@ -1,16 +1,15 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([rsync],[3.2.1],[https://rsync.samba.org/bugtracking.html])
|
||||
AC_INIT([rsync],[ ],[https://rsync.samba.org/bug-tracking.html])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_SRCDIR([byteorder.h])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PREREQ([2.69])
|
||||
|
||||
AC_SUBST(RSYNC_VERSION, $PACKAGE_VERSION)
|
||||
AC_MSG_NOTICE([Configuring rsync $PACKAGE_VERSION])
|
||||
PACKAGE_VERSION=`sed 's/.*"\(.*\)".*/\1/' <$srcdir/version.h`
|
||||
|
||||
AC_DEFINE_UNQUOTED(RSYNC_VERSION, ["$PACKAGE_VERSION"], [rsync release version])
|
||||
AC_MSG_NOTICE([Configuring rsync $PACKAGE_VERSION])
|
||||
|
||||
LDFLAGS=${LDFLAGS-""}
|
||||
|
||||
@@ -58,6 +57,11 @@ if test x"$ac_cv_prog_cc_stdc" = x"no"; then
|
||||
AC_MSG_WARN([rsync requires an ANSI C compiler and you do not seem to have one])
|
||||
fi
|
||||
|
||||
no_lib=''
|
||||
err_msg=''
|
||||
nl='
|
||||
'
|
||||
|
||||
AC_ARG_ENABLE(profile,
|
||||
AS_HELP_STRING([--enable-profile],[turn on CPU profiling]))
|
||||
if test x"$enable_profile" = x"yes"; then
|
||||
@@ -89,8 +93,10 @@ if test x"$enable_md2man" != x"no"; then
|
||||
else
|
||||
AC_MSG_RESULT(required)
|
||||
if test x"$md2man_works" = x"no"; then
|
||||
AC_MSG_ERROR(You need python3 and the cmarkgfm OR commonmark python3 lib in order to build man pages.
|
||||
You can specify --disable-md2man if you want to skip building them.)
|
||||
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
|
||||
@@ -347,7 +353,7 @@ 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; do
|
||||
for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta cygwin TANDEM; do
|
||||
case $i in
|
||||
inria)
|
||||
# http://www.kame.net/
|
||||
@@ -439,6 +445,15 @@ 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])])
|
||||
@@ -480,9 +495,9 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.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 \
|
||||
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)
|
||||
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])
|
||||
@@ -495,12 +510,12 @@ if test x"$enable_openssl" != x"no"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_SEARCH_LIBS(MD5_Init, crypto,
|
||||
[AC_DEFINE(USE_OPENSSL)],
|
||||
[AC_MSG_ERROR(Failed to find MD5_Init function in openssl crypto lib.
|
||||
Use --disable-openssl to continue without openssl crypto lib support.)])
|
||||
[err_msg="$err_msg$nl- Failed to find MD5_Init function in openssl crypto lib.";
|
||||
no_lib="$no_lib openssl"])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR(Failed to find openssl/md4.h and openssl/md5.h for openssl crypto lib support.
|
||||
Use --disable-openssl to continue without it.)
|
||||
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
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -516,12 +531,12 @@ if test x"$enable_xxhash" != x"no"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_SEARCH_LIBS(XXH64_createState, xxhash,
|
||||
[AC_DEFINE(SUPPORT_XXHASH)],
|
||||
[AC_MSG_ERROR(Failed to find XXH64_createState function in xxhash lib.
|
||||
Use --disable-xxhash to continue without xxhash checksums.)])
|
||||
[err_msg="$err_msg$nl- Failed to find XXH64_createState function in xxhash lib.";
|
||||
no_lib="$no_lib xxhash"])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR(Failed to find xxhash.h for xxhash checksum support.
|
||||
Use --disable-xxhash to continue without it.)
|
||||
err_msg="$err_msg$nl- Failed to find xxhash.h for xxhash checksum support.";
|
||||
no_lib="$no_lib xxhash"
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -537,12 +552,12 @@ if test x"$enable_zstd" != x"no"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_SEARCH_LIBS(ZSTD_minCLevel, zstd,
|
||||
[AC_DEFINE(SUPPORT_ZSTD)],
|
||||
[AC_MSG_ERROR(Failed to find ZSTD_minCLevel function in zstd lib.
|
||||
Use --disable-zstd to continue without zstd compression.)])
|
||||
[err_msg="$err_msg$nl- Failed to find ZSTD_minCLevel function in zstd lib.";
|
||||
no_lib="$no_lib zstd"])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR(Failed to find zstd.h for zstd compression support.
|
||||
Use --disable-zstd to continue without it.)
|
||||
err_msg="$err_msg$nl- Failed to find zstd.h for zstd compression support.";
|
||||
no_lib="$no_lib zstd"
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -558,17 +573,34 @@ if test x"$enable_lz4" != x"no"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_SEARCH_LIBS(LZ4_compress_default, lz4,
|
||||
[AC_DEFINE(SUPPORT_LZ4)],
|
||||
[AC_MSG_ERROR(Failed to find LZ4_compress_default function in lz4 lib.
|
||||
Use --disable-lz4 to continue without lz4 compression.)])
|
||||
[err_msg="$err_msg$nl- Failed to find LZ4_compress_default function in lz4 lib.";
|
||||
no_lib="$no_lib lz4"])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR(Failed to find lz4.h for lz4 compression support.
|
||||
Use --disable-lz4 to continue without it.)
|
||||
err_msg="$err_msg$nl- Failed to find lz4.h for lz4 compression support."
|
||||
no_lib="$no_lib lz4"
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
if test x"$no_lib" != x; then
|
||||
echo ""
|
||||
echo "Configure found the following issues:"
|
||||
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 " https://github.com/WayneD/rsync/blob/master/INSTALL.md"
|
||||
echo ""
|
||||
echo "To disable one or more features, the relevant configure options are:"
|
||||
for lib in $no_lib; do
|
||||
echo " --disable-$lib"
|
||||
done
|
||||
echo ""
|
||||
AC_MSG_ERROR(Aborting configure run)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([if makedev takes 3 args],rsync_cv_MAKEDEV_TAKES_3_ARGS,[
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <sys/types.h>
|
||||
@@ -812,9 +844,9 @@ dnl AC_FUNC_MEMCMP
|
||||
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_FUNC_ALLOCA
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd chown chmod lchmod mknod mkfifo \
|
||||
fchmod fstat ftruncate strchr readlink link utime utimes lutimes strftime \
|
||||
chflags getattrlist \
|
||||
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 \
|
||||
@@ -938,6 +970,11 @@ fi
|
||||
|
||||
AC_CACHE_CHECK([whether link() can hard-link symlinks],rsync_cv_can_hardlink_symlink,[
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#elif defined HAVE_SYS_FCNTL_H
|
||||
# include <sys/fcntl.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
@@ -948,7 +985,11 @@ int main(void) {
|
||||
unlink(FILENAME);
|
||||
if (symlink("conftest.no-such", FILENAME) < 0) abort();
|
||||
unlink(FILENAME "2");
|
||||
#ifdef HAVE_LINKAT
|
||||
if (linkat(AT_FDCWD, FILENAME, AT_FDCWD, FILENAME "2", 0) < 0) return 1;
|
||||
#else
|
||||
if (link(FILENAME, FILENAME "2") < 0) return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}]])],[rsync_cv_can_hardlink_symlink=yes],[rsync_cv_can_hardlink_symlink=no],[rsync_cv_can_hardlink_symlink=no])])
|
||||
if test $rsync_cv_can_hardlink_symlink = yes; then
|
||||
@@ -1213,11 +1254,6 @@ else
|
||||
AC_DEFINE(HAVE_SOLARIS_ACLS, 1, [true if you have solaris ACLs])
|
||||
AC_DEFINE(SUPPORT_ACLS, 1)
|
||||
;;
|
||||
*hpux*)
|
||||
AC_MSG_RESULT(Using HPUX ACLs)
|
||||
AC_DEFINE(HAVE_HPUX_ACLS, 1, [true if you have HPUX ACLs])
|
||||
AC_DEFINE(SUPPORT_ACLS, 1)
|
||||
;;
|
||||
*irix*)
|
||||
AC_MSG_RESULT(Using IRIX ACLs)
|
||||
AC_DEFINE(HAVE_IRIX_ACLS, 1, [true if you have IRIX ACLs])
|
||||
@@ -1239,6 +1275,11 @@ else
|
||||
AC_DEFINE(HAVE_OSX_ACLS, 1, [true if you have Mac OS X ACLs])
|
||||
AC_DEFINE(SUPPORT_ACLS, 1)
|
||||
;;
|
||||
*hpux*|*nsk*)
|
||||
AC_MSG_RESULT(Using HPUX ACLs)
|
||||
AC_DEFINE(HAVE_HPUX_ACLS, 1, [true if you have HPUX ACLs])
|
||||
AC_DEFINE(SUPPORT_ACLS, 1)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(running tests:)
|
||||
AC_CHECK_LIB(acl,acl_get_file)
|
||||
@@ -1282,7 +1323,7 @@ if test x"$enable_xattr_support" = x"no"; then
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
case "$host_os" in
|
||||
*linux*|*netbsd*)
|
||||
*linux*|*netbsd*|*cygwin*)
|
||||
AC_MSG_RESULT(Using Linux xattrs)
|
||||
AC_DEFINE(HAVE_LINUX_XATTRS, 1, [True if you have Linux xattrs (or equivalent)])
|
||||
AC_DEFINE(SUPPORT_XATTRS, 1)
|
||||
@@ -1338,5 +1379,5 @@ AC_CONFIG_FILES([Makefile lib/dummy zlib/dummy popt/dummy shconfig])
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_RESULT()
|
||||
AC_MSG_RESULT([ rsync ${RSYNC_VERSION} configuration successful])
|
||||
AC_MSG_RESULT([ rsync $PACKAGE_VERSION configuration successful])
|
||||
AC_MSG_RESULT()
|
||||
|
||||
114
daemon-parm.awk
Executable file
114
daemon-parm.awk
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/awk -f
|
||||
|
||||
# The caller must pass arg: daemon-parm.txt
|
||||
# The resulting code is output into daemon-parm.h
|
||||
|
||||
BEGIN {
|
||||
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from a list of values in " ARGV[1] "! */\n\n"
|
||||
sect = psect = defines = accessors = prior_ptype = ""
|
||||
parms = "\nstatic struct parm_struct parm_table[] = {"
|
||||
comment_fmt = "\n/********** %s **********/\n"
|
||||
tdstruct = "typedef struct {"
|
||||
}
|
||||
|
||||
/^\s*$/ { next }
|
||||
/^#/ { next }
|
||||
|
||||
/^Globals:/ {
|
||||
if (defines != "") {
|
||||
print "The Globals section must come first!"
|
||||
defines = ""
|
||||
exit
|
||||
}
|
||||
defines = tdstruct
|
||||
values = "\nstatic const all_vars Defaults = {\n { /* Globals: */\n"
|
||||
exps = exp_values = sprintf(comment_fmt, "EXP")
|
||||
sect = "GLOBAL"
|
||||
psect = ", P_GLOBAL, &Vars.g."
|
||||
next
|
||||
}
|
||||
|
||||
/^Locals:/ {
|
||||
if (sect == "") {
|
||||
print "The Locals section must come after the Globals!"
|
||||
exit
|
||||
}
|
||||
defines = defines exps "} global_vars;\n\n" tdstruct
|
||||
values = values exp_values "\n }, { /* Locals: */\n"
|
||||
exps = exp_values = sprintf(comment_fmt, "EXP")
|
||||
sect = "LOCAL"
|
||||
psect = ", P_LOCAL, &Vars.l."
|
||||
next
|
||||
}
|
||||
|
||||
/^(STRING|CHAR|PATH|INTEGER|ENUM|OCTAL|BOOL|BOOLREV|BOOL3)[ \t]/ {
|
||||
ptype = $1
|
||||
name = $2
|
||||
$1 = $2 = ""
|
||||
sub(/^[ \t]+/, "")
|
||||
|
||||
if (ptype != prior_ptype) {
|
||||
comment = sprintf(comment_fmt, ptype)
|
||||
defines = defines comment
|
||||
values = values comment
|
||||
parms = parms "\n"
|
||||
accessors = accessors "\n"
|
||||
prior_ptype = ptype
|
||||
}
|
||||
|
||||
if (ptype == "STRING" || ptype == "PATH") {
|
||||
atype = "STRING"
|
||||
vtype = "char*"
|
||||
} else if (ptype ~ /BOOL/) {
|
||||
atype = vtype = "BOOL"
|
||||
} else if (ptype == "CHAR") {
|
||||
atype = "CHAR"
|
||||
vtype = "char"
|
||||
} else {
|
||||
atype = "INTEGER"
|
||||
vtype = "int"
|
||||
}
|
||||
|
||||
# The name might be var_name|public_name
|
||||
pubname = name
|
||||
sub(/\|.*/, "", name)
|
||||
sub(/.*\|/, "", pubname)
|
||||
gsub(/_/, " ", pubname)
|
||||
gsub(/-/, "", name)
|
||||
|
||||
if (ptype == "ENUM")
|
||||
enum = "enum_" name
|
||||
else
|
||||
enum = "NULL"
|
||||
|
||||
defines = defines "\t" vtype " " name ";\n"
|
||||
values = values "\t" $0 ", /* " name " */\n"
|
||||
parms = parms " {\"" pubname "\", P_" ptype psect name ", " enum ", 0},\n"
|
||||
accessors = accessors "FN_" sect "_" atype "(lp_" name ", " name ")\n"
|
||||
|
||||
if (vtype == "char*") {
|
||||
exps = exps "\tBOOL " name "_EXP;\n"
|
||||
exp_values = exp_values "\tFalse, /* " name "_EXP */\n"
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
|
||||
/./ {
|
||||
print "Extraneous line:" $0
|
||||
defines = ""
|
||||
exit
|
||||
}
|
||||
|
||||
END {
|
||||
if (sect != "" && defines != "") {
|
||||
defines = defines exps "} local_vars;\n\n"
|
||||
defines = defines tdstruct "\n\tglobal_vars g;\n\tlocal_vars l;\n} all_vars;\n"
|
||||
values = values exp_values "\n }\n};\n\nstatic all_vars Vars;\n"
|
||||
parms = parms "\n {NULL, P_BOOL, P_NONE, NULL, NULL, 0}\n};\n"
|
||||
print heading defines values parms accessors > "daemon-parm.h"
|
||||
} else {
|
||||
print "Failed to parse the data in " ARGV[1]
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
68
daemon-parm.txt
Normal file
68
daemon-parm.txt
Normal file
@@ -0,0 +1,68 @@
|
||||
Globals: ================================================================
|
||||
|
||||
STRING bind_address|address NULL
|
||||
STRING daemon_chroot NULL
|
||||
STRING daemon_gid NULL
|
||||
STRING daemon_uid NULL
|
||||
STRING motd_file NULL
|
||||
STRING pid_file NULL
|
||||
STRING socket_options NULL
|
||||
|
||||
INTEGER listen_backlog 5
|
||||
INTEGER rsync_port|port 0
|
||||
|
||||
BOOL proxy_protocol False
|
||||
|
||||
Locals: =================================================================
|
||||
|
||||
STRING auth_users NULL
|
||||
STRING charset NULL
|
||||
STRING comment NULL
|
||||
STRING dont_compress DEFAULT_DONT_COMPRESS
|
||||
STRING early_exec NULL
|
||||
STRING exclude NULL
|
||||
STRING exclude_from NULL
|
||||
STRING filter NULL
|
||||
STRING gid NULL
|
||||
STRING hosts_allow NULL
|
||||
STRING hosts_deny NULL
|
||||
STRING include NULL
|
||||
STRING include_from NULL
|
||||
STRING incoming_chmod NULL
|
||||
STRING lock_file DEFAULT_LOCK_FILE
|
||||
STRING log_file NULL
|
||||
STRING log_format "%o %h [%a] %m (%u) %f %l"
|
||||
STRING name NULL
|
||||
STRING name_converter NULL
|
||||
STRING outgoing_chmod NULL
|
||||
STRING post-xfer_exec NULL
|
||||
STRING pre-xfer_exec NULL
|
||||
STRING refuse_options NULL
|
||||
STRING secrets_file NULL
|
||||
STRING syslog_tag "rsyncd"
|
||||
STRING uid NULL
|
||||
|
||||
PATH path NULL
|
||||
PATH temp_dir NULL
|
||||
|
||||
INTEGER max_connections 0
|
||||
INTEGER max_verbosity 1
|
||||
INTEGER timeout 0
|
||||
|
||||
ENUM syslog_facility LOG_DAEMON
|
||||
|
||||
BOOL fake_super False
|
||||
BOOL forward_lookup True
|
||||
BOOL ignore_errors False
|
||||
BOOL ignore_nonreadable False
|
||||
BOOL list True
|
||||
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
|
||||
24
exclude.c
24
exclude.c
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "default-cvsignore.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int am_server;
|
||||
extern int am_sender;
|
||||
@@ -200,8 +200,7 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
|
||||
} else
|
||||
suf_len = 0;
|
||||
|
||||
if (!(rule->pattern = new_array(char, pre_len + pat_len + suf_len + 1)))
|
||||
out_of_memory("add_rule");
|
||||
rule->pattern = new_array(char, pre_len + pat_len + suf_len + 1);
|
||||
if (pre_len) {
|
||||
memcpy(rule->pattern, dirbuf + module_dirlen, pre_len);
|
||||
for (cp = rule->pattern; cp < rule->pattern + pre_len; cp++) {
|
||||
@@ -262,19 +261,14 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
|
||||
}
|
||||
}
|
||||
|
||||
if (!(lp = new_array0(filter_rule_list, 1)))
|
||||
out_of_memory("add_rule");
|
||||
lp = new_array0(filter_rule_list, 1);
|
||||
if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0)
|
||||
out_of_memory("add_rule");
|
||||
rule->u.mergelist = lp;
|
||||
|
||||
if (mergelist_cnt == mergelist_size) {
|
||||
mergelist_size += 5;
|
||||
mergelist_parents = realloc_array(mergelist_parents,
|
||||
filter_rule *,
|
||||
mergelist_size);
|
||||
if (!mergelist_parents)
|
||||
out_of_memory("add_rule");
|
||||
mergelist_parents = realloc_array(mergelist_parents, filter_rule *, mergelist_size);
|
||||
}
|
||||
if (DEBUG_GTE(FILTER, 2)) {
|
||||
rprintf(FINFO, "[%s] activating mergelist #%d%s\n",
|
||||
@@ -498,8 +492,6 @@ void *push_local_filters(const char *dir, unsigned int dirlen)
|
||||
push = (struct local_filter_state *)new_array(char,
|
||||
sizeof (struct local_filter_state)
|
||||
+ (mergelist_cnt-1) * sizeof (filter_rule_list));
|
||||
if (!push)
|
||||
out_of_memory("push_local_filters");
|
||||
|
||||
push->mergelist_cnt = mergelist_cnt;
|
||||
for (i = 0; i < mergelist_cnt; i++) {
|
||||
@@ -822,8 +814,7 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
|
||||
if (!*s)
|
||||
return NULL;
|
||||
|
||||
if (!(rule = new0(filter_rule)))
|
||||
out_of_memory("parse_rule_tok");
|
||||
rule = new0(filter_rule);
|
||||
|
||||
/* Inherit from the template. Don't inherit FILTRULES_SIDES; we check
|
||||
* that later. */
|
||||
@@ -1061,7 +1052,7 @@ static void get_cvs_excludes(uint32 rflags)
|
||||
return;
|
||||
initialized = 1;
|
||||
|
||||
parse_filter_str(&cvs_filter_list, DEFAULT_CVSIGNORE,
|
||||
parse_filter_str(&cvs_filter_list, default_cvsignore(),
|
||||
rule_template(rflags | (protocol_version >= 30 ? FILTRULE_PERISHABLE : 0)),
|
||||
0);
|
||||
|
||||
@@ -1125,8 +1116,7 @@ void parse_filter_str(filter_rule_list *listp, const char *rulestr,
|
||||
const char *name;
|
||||
filter_rule *excl_self;
|
||||
|
||||
if (!(excl_self = new0(filter_rule)))
|
||||
out_of_memory("parse_filter_str");
|
||||
excl_self = new0(filter_rule);
|
||||
/* Find the beginning of the basename and add an exclude for it. */
|
||||
for (name = pat + pat_len; name > pat && name[-1] != '/'; name--) {}
|
||||
add_rule(listp, name, (pat + pat_len) - name, excl_self, 0);
|
||||
|
||||
7
fileio.c
7
fileio.c
@@ -157,8 +157,6 @@ int write_file(int f, int use_seek, OFF_T offset, const char *buf, int len)
|
||||
wf_writeBufSize = WRITE_SIZE * 8;
|
||||
wf_writeBufCnt = 0;
|
||||
wf_writeBuf = new_array(char, wf_writeBufSize);
|
||||
if (!wf_writeBuf)
|
||||
out_of_memory("write_file");
|
||||
}
|
||||
r1 = (int)MIN((size_t)len, wf_writeBufSize - wf_writeBufCnt);
|
||||
if (r1) {
|
||||
@@ -217,8 +215,7 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
|
||||
{
|
||||
struct map_struct *map;
|
||||
|
||||
if (!(map = new0(struct map_struct)))
|
||||
out_of_memory("map_file");
|
||||
map = new0(struct map_struct);
|
||||
|
||||
if (blk_size && (read_size % blk_size))
|
||||
read_size += blk_size - (read_size % blk_size);
|
||||
@@ -261,8 +258,6 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
/* make sure we have allocated enough memory for the window */
|
||||
if (window_size > map->p_size) {
|
||||
map->p = realloc_array(map->p, char, window_size);
|
||||
if (!map->p)
|
||||
out_of_memory("map_ptr");
|
||||
map->p_size = window_size;
|
||||
}
|
||||
|
||||
|
||||
138
flist.c
138
flist.c
@@ -56,6 +56,7 @@ extern int delete_during;
|
||||
extern int missing_args;
|
||||
extern int eol_nulls;
|
||||
extern int atimes_ndx;
|
||||
extern int crtimes_ndx;
|
||||
extern int relative_paths;
|
||||
extern int implied_dirs;
|
||||
extern int ignore_perishable;
|
||||
@@ -133,6 +134,7 @@ static char empty_sum[MAX_DIGEST_LEN];
|
||||
static int flist_count_offset; /* for --delete --progress */
|
||||
static int show_filelist_progress;
|
||||
|
||||
static struct file_list *flist_new(int flags, const char *msg);
|
||||
static void flist_sort_and_clean(struct file_list *flist, int strip_root);
|
||||
static void output_flist(struct file_list *flist);
|
||||
|
||||
@@ -301,8 +303,7 @@ static void flist_expand(struct file_list *flist, int extra)
|
||||
if (flist->malloced < flist->used + extra)
|
||||
flist->malloced = flist->used + extra;
|
||||
|
||||
new_ptr = realloc_array(flist->files, struct file_struct *,
|
||||
flist->malloced);
|
||||
new_ptr = realloc_array(flist->files, struct file_struct *, flist->malloced);
|
||||
|
||||
if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
|
||||
rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
|
||||
@@ -312,9 +313,6 @@ static void flist_expand(struct file_list *flist, int extra)
|
||||
}
|
||||
|
||||
flist->files = new_ptr;
|
||||
|
||||
if (!flist->files)
|
||||
out_of_memory("flist_expand");
|
||||
}
|
||||
|
||||
static void flist_done_allocating(struct file_list *flist)
|
||||
@@ -381,6 +379,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
int ndx, int first_ndx)
|
||||
{
|
||||
static time_t modtime, atime;
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
static time_t crtime;
|
||||
#endif
|
||||
static mode_t mode;
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
static int64 dev;
|
||||
@@ -447,7 +448,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
if (protocol_version < 28)
|
||||
xflags |= XMIT_SAME_RDEV_pre28;
|
||||
else {
|
||||
rdev = MAKEDEV(major(rdev), 0);
|
||||
rdev = MAKEDEV(rdev_major, 0);
|
||||
xflags |= XMIT_SAME_RDEV_MAJOR;
|
||||
if (protocol_version < 30)
|
||||
xflags |= XMIT_RDEV_MINOR_8_pre30;
|
||||
@@ -486,6 +487,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
else
|
||||
atime = F_ATIME(file);
|
||||
}
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (crtimes_ndx) {
|
||||
crtime = F_CRTIME(file);
|
||||
if (crtime == modtime)
|
||||
xflags |= XMIT_CRTIME_EQ_MTIME;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
if (tmp_dev != -1) {
|
||||
@@ -573,6 +581,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
}
|
||||
if (xflags & XMIT_MOD_NSEC)
|
||||
write_varint(f, F_MOD_NSEC(file));
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (crtimes_ndx && !(xflags & XMIT_CRTIME_EQ_MTIME))
|
||||
write_varlong(f, crtime, 4);
|
||||
#endif
|
||||
if (!(xflags & XMIT_SAME_MODE))
|
||||
write_int(f, to_wire_mode(mode));
|
||||
if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME))
|
||||
@@ -665,6 +677,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
static struct file_struct *recv_file_entry(int f, struct file_list *flist, int xflags)
|
||||
{
|
||||
static int64 modtime, atime;
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
static time_t crtime;
|
||||
#endif
|
||||
static mode_t mode;
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
static int64 dev;
|
||||
@@ -684,7 +699,9 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
int extra_len = file_extra_cnt * EXTRA_LEN;
|
||||
int first_hlink_ndx = -1;
|
||||
int64 file_length;
|
||||
#ifdef CAN_SET_NSEC
|
||||
uint32 modtime_nsec;
|
||||
#endif
|
||||
const char *basename;
|
||||
struct file_struct *file;
|
||||
alloc_pool_t *pool;
|
||||
@@ -771,17 +788,24 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];
|
||||
file_length = F_LENGTH(first);
|
||||
modtime = first->modtime;
|
||||
#ifdef CAN_SET_NSEC
|
||||
modtime_nsec = F_MOD_NSEC_or_0(first);
|
||||
#endif
|
||||
mode = first->mode;
|
||||
if (atimes_ndx && !S_ISDIR(mode))
|
||||
atime = F_ATIME(first);
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (crtimes_ndx)
|
||||
crtime = F_CRTIME(first);
|
||||
#endif
|
||||
if (preserve_uid)
|
||||
uid = F_OWNER(first);
|
||||
if (preserve_gid)
|
||||
gid = F_GROUP(first);
|
||||
if (preserve_devices && IS_DEVICE(mode)) {
|
||||
uint32 *devp = F_RDEV_P(first);
|
||||
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
|
||||
rdev_major = DEV_MAJOR(devp);
|
||||
rdev = MAKEDEV(rdev_major, DEV_MINOR(devp));
|
||||
extra_len += DEV_EXTRA_CNT * EXTRA_LEN;
|
||||
}
|
||||
if (preserve_links && S_ISLNK(mode))
|
||||
@@ -808,9 +832,28 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
modtime = read_int(f);
|
||||
}
|
||||
if (xflags & XMIT_MOD_NSEC)
|
||||
#ifndef CAN_SET_NSEC
|
||||
(void)read_varint(f);
|
||||
#else
|
||||
modtime_nsec = read_varint(f);
|
||||
else
|
||||
modtime_nsec = 0;
|
||||
#endif
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (crtimes_ndx) {
|
||||
if (xflags & XMIT_CRTIME_EQ_MTIME)
|
||||
crtime = modtime;
|
||||
else
|
||||
crtime = read_varlong(f, 4);
|
||||
#if SIZEOF_TIME_T < SIZEOF_INT64
|
||||
if (!am_generator && (int64)(time_t)crtime != crtime) {
|
||||
rprintf(FERROR_XFER,
|
||||
"Create time value of %s truncated on receiver.\n",
|
||||
lastname);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (!(xflags & XMIT_SAME_MODE))
|
||||
mode = from_wire_mode(read_int(f));
|
||||
if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME)) {
|
||||
@@ -992,6 +1035,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
}
|
||||
if (atimes_ndx && !S_ISDIR(mode))
|
||||
F_ATIME(file) = atime;
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (crtimes_ndx)
|
||||
F_CRTIME(file) = crtime;
|
||||
#endif
|
||||
if (unsort_ndx)
|
||||
F_NDX(file) = flist->used + flist->ndx_start;
|
||||
|
||||
@@ -1335,10 +1382,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
+ linkname_len;
|
||||
if (pool)
|
||||
bp = pool_alloc(pool, alloc_len, "make_file");
|
||||
else {
|
||||
if (!(bp = new_array(char, alloc_len)))
|
||||
out_of_memory("make_file");
|
||||
}
|
||||
else
|
||||
bp = new_array(char, alloc_len);
|
||||
|
||||
memset(bp, 0, extra_len + FILE_STRUCT_LEN);
|
||||
bp += extra_len;
|
||||
@@ -1391,6 +1436,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
file->flags |= FLAG_OWNED_BY_US;
|
||||
if (atimes_ndx && !S_ISDIR(file->mode))
|
||||
F_ATIME(file) = st.st_atime;
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (crtimes_ndx)
|
||||
F_CRTIME(file) = get_create_time(fname);
|
||||
#endif
|
||||
|
||||
if (basename != thisname)
|
||||
file->dirname = lastdir;
|
||||
@@ -1661,8 +1710,7 @@ static void fsort(struct file_struct **fp, size_t num)
|
||||
if (use_qsort)
|
||||
qsort(fp, num, PTR_SIZE, file_compare);
|
||||
else {
|
||||
struct file_struct **tmp = new_array(struct file_struct *,
|
||||
(num+1) / 2);
|
||||
struct file_struct **tmp = new_array(struct file_struct *, (num+1) / 2);
|
||||
fsort_tmp(fp, num, tmp);
|
||||
free(tmp);
|
||||
}
|
||||
@@ -1895,13 +1943,11 @@ static void send_implied_dirs(int f, struct file_list *flist, char *fname,
|
||||
len = strlen(limit+1);
|
||||
memcpy(&relname_list, F_DIR_RELNAMES_P(lastpath_struct), sizeof relname_list);
|
||||
if (!relname_list) {
|
||||
if (!(relname_list = new0(item_list)))
|
||||
out_of_memory("send_implied_dirs");
|
||||
relname_list = new0(item_list);
|
||||
memcpy(F_DIR_RELNAMES_P(lastpath_struct), &relname_list, sizeof relname_list);
|
||||
}
|
||||
rnpp = EXPAND_ITEM_LIST(relname_list, relnamecache *, 32);
|
||||
if (!(*rnpp = (relnamecache*)new_array(char, sizeof (relnamecache) + len)))
|
||||
out_of_memory("send_implied_dirs");
|
||||
*rnpp = (relnamecache*)new_array(char, RELNAMECACHE_LEN + len + 1);
|
||||
(*rnpp)->name_type = name_type;
|
||||
strlcpy((*rnpp)->fname, limit+1, len + 1);
|
||||
|
||||
@@ -2059,10 +2105,8 @@ void send_extra_file_list(int f, int at_least)
|
||||
}
|
||||
|
||||
if (need_unsorted_flist) {
|
||||
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
|
||||
out_of_memory("send_extra_file_list");
|
||||
memcpy(flist->sorted, flist->files,
|
||||
flist->used * sizeof (struct file_struct*));
|
||||
flist->sorted = new_array(struct file_struct *, flist->used);
|
||||
memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
|
||||
} else
|
||||
flist->sorted = flist->files;
|
||||
|
||||
@@ -2414,10 +2458,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
* recursion mode, the sender marks duplicate dirs so that it can
|
||||
* send them together in a single file-list. */
|
||||
if (need_unsorted_flist) {
|
||||
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
|
||||
out_of_memory("send_file_list");
|
||||
memcpy(flist->sorted, flist->files,
|
||||
flist->used * sizeof (struct file_struct*));
|
||||
flist->sorted = new_array(struct file_struct *, flist->used);
|
||||
memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
|
||||
} else
|
||||
flist->sorted = flist->files;
|
||||
flist_sort_and_clean(flist, 0);
|
||||
@@ -2425,7 +2467,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
file_old_total += flist->used;
|
||||
|
||||
if (numeric_ids <= 0 && !inc_recurse)
|
||||
send_id_list(f);
|
||||
send_id_lists(f);
|
||||
|
||||
/* send the io_error flag */
|
||||
if (protocol_version < 30)
|
||||
@@ -2597,10 +2639,8 @@ struct file_list *recv_file_list(int f, int dir_ndx)
|
||||
* order and for calling flist_find()). We keep the "files"
|
||||
* list unsorted for our exchange of index numbers with the
|
||||
* other side (since their names may not sort the same). */
|
||||
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
|
||||
out_of_memory("recv_file_list");
|
||||
memcpy(flist->sorted, flist->files,
|
||||
flist->used * sizeof (struct file_struct*));
|
||||
flist->sorted = new_array(struct file_struct *, flist->used);
|
||||
memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
|
||||
if (inc_recurse && dir_flist->used > dstart) {
|
||||
static int dir_flist_malloced = 0;
|
||||
if (dir_flist_malloced < dir_flist->malloced) {
|
||||
@@ -2610,7 +2650,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
|
||||
dir_flist_malloced = dir_flist->malloced;
|
||||
}
|
||||
memcpy(dir_flist->sorted + dstart, dir_flist->files + dstart,
|
||||
(dir_flist->used - dstart) * sizeof (struct file_struct*));
|
||||
(dir_flist->used - dstart) * PTR_SIZE);
|
||||
fsort(dir_flist->sorted + dstart, dir_flist->used - dstart);
|
||||
}
|
||||
} else {
|
||||
@@ -2742,28 +2782,28 @@ int flist_find(struct file_list *flist, struct file_struct *f)
|
||||
* 1=match directories, 0=match non-directories, or -1=match either. */
|
||||
int flist_find_name(struct file_list *flist, const char *fname, int want_dir_match)
|
||||
{
|
||||
struct { /* We have to create a temporary file_struct for the search. */
|
||||
struct file_struct f;
|
||||
char name_space[MAXPATHLEN];
|
||||
} t;
|
||||
static struct file_struct *f;
|
||||
char fbuf[MAXPATHLEN];
|
||||
const char *slash = strrchr(fname, '/');
|
||||
const char *basename = slash ? slash+1 : fname;
|
||||
|
||||
memset(&t.f, 0, FILE_STRUCT_LEN);
|
||||
memcpy((void *)t.f.basename, basename, strlen(basename)+1);
|
||||
if (!f)
|
||||
f = (struct file_struct*)new_array(char, FILE_STRUCT_LEN + MAXPATHLEN + 1);
|
||||
|
||||
memset(f, 0, FILE_STRUCT_LEN);
|
||||
memcpy((void*)f->basename, basename, strlen(basename)+1);
|
||||
|
||||
if (slash) {
|
||||
strlcpy(fbuf, fname, slash - fname + 1);
|
||||
t.f.dirname = fbuf;
|
||||
f->dirname = fbuf;
|
||||
} else
|
||||
t.f.dirname = NULL;
|
||||
f->dirname = NULL;
|
||||
|
||||
t.f.mode = want_dir_match > 0 ? S_IFDIR : S_IFREG;
|
||||
f->mode = want_dir_match > 0 ? S_IFDIR : S_IFREG;
|
||||
|
||||
if (want_dir_match < 0)
|
||||
return flist_find_ignore_dirness(flist, &t.f);
|
||||
return flist_find(flist, &t.f);
|
||||
return flist_find_ignore_dirness(flist, f);
|
||||
return flist_find(flist, f);
|
||||
}
|
||||
|
||||
/* Search for an identically-named item in the file list. Differs from
|
||||
@@ -2804,26 +2844,20 @@ void clear_file(struct file_struct *file)
|
||||
}
|
||||
|
||||
/* Allocate a new file list. */
|
||||
struct file_list *flist_new(int flags, char *msg)
|
||||
static struct file_list *flist_new(int flags, const char *msg)
|
||||
{
|
||||
struct file_list *flist;
|
||||
|
||||
if (!(flist = new0(struct file_list)))
|
||||
out_of_memory(msg);
|
||||
flist = new0(struct file_list);
|
||||
|
||||
if (flags & FLIST_TEMP) {
|
||||
if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0,
|
||||
out_of_memory,
|
||||
POOL_INTERN)))
|
||||
if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0, _out_of_memory, POOL_INTERN)))
|
||||
out_of_memory(msg);
|
||||
} else {
|
||||
/* This is a doubly linked list with prev looping back to
|
||||
* the end of the list, but the last next pointer is NULL. */
|
||||
if (!first_flist) {
|
||||
flist->file_pool = pool_create(NORMAL_EXTENT, 0,
|
||||
out_of_memory,
|
||||
POOL_INTERN);
|
||||
if (!flist->file_pool)
|
||||
if (!(flist->file_pool = pool_create(NORMAL_EXTENT, 0, _out_of_memory, POOL_INTERN)))
|
||||
out_of_memory(msg);
|
||||
|
||||
flist->ndx_start = flist->flist_num = inc_recurse ? 1 : 0;
|
||||
|
||||
53
generator.c
53
generator.c
@@ -84,7 +84,7 @@ extern int list_only;
|
||||
extern int read_batch;
|
||||
extern int write_batch;
|
||||
extern int safe_symlinks;
|
||||
extern long block_size; /* "long" because popt can't set an int32. */
|
||||
extern int32 block_size;
|
||||
extern int unsort_ndx;
|
||||
extern int max_delete;
|
||||
extern int force_delete;
|
||||
@@ -396,6 +396,19 @@ static inline int mtime_differs(STRUCT_STAT *stp, struct file_struct *file)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int any_time_differs(stat_x *sxp, struct file_struct *file, UNUSED(const char *fname))
|
||||
{
|
||||
int differs = mtime_differs(&sxp->st, file);
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (!differs && crtimes_ndx) {
|
||||
if (sxp->crtime == 0)
|
||||
sxp->crtime = get_create_time(fname);
|
||||
differs = !same_time(sxp->crtime, 0, F_CRTIME(file), 0);
|
||||
}
|
||||
#endif
|
||||
return differs;
|
||||
}
|
||||
|
||||
static inline int perms_differ(struct file_struct *file, stat_x *sxp)
|
||||
{
|
||||
if (preserve_perms)
|
||||
@@ -450,7 +463,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 && mtime_differs(&sxp->st, file))
|
||||
if (preserve_times & PRESERVE_LINK_TIMES && any_time_differs(sxp, file, fname))
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef CAN_CHMOD_SYMLINK
|
||||
@@ -470,7 +483,7 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
if (preserve_times && mtime_differs(&sxp->st, file))
|
||||
if (preserve_times && any_time_differs(sxp, file, fname))
|
||||
return 0;
|
||||
if (perms_differ(file, sxp))
|
||||
return 0;
|
||||
@@ -512,6 +525,14 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
|
||||
if (atimes_ndx && !S_ISDIR(file->mode) && !S_ISLNK(file->mode)
|
||||
&& !same_time(F_ATIME(file), 0, sxp->st.st_atime, 0))
|
||||
iflags |= ITEM_REPORT_ATIME;
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (crtimes_ndx) {
|
||||
if (sxp->crtime == 0)
|
||||
sxp->crtime = get_create_time(fnamecmp);
|
||||
if (!same_time(sxp->crtime, 0, F_CRTIME(file), 0))
|
||||
iflags |= ITEM_REPORT_CRTIME;
|
||||
}
|
||||
#endif
|
||||
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
|
||||
if (S_ISLNK(file->mode)) {
|
||||
;
|
||||
@@ -1131,6 +1152,7 @@ static void list_file_entry(struct file_struct *f)
|
||||
int size_width = human_readable ? 14 : 11;
|
||||
int mtime_width = 1 + strlen(mtime_str);
|
||||
int atime_width = atimes_ndx ? mtime_width : 0;
|
||||
int crtime_width = crtimes_ndx ? mtime_width : 0;
|
||||
|
||||
if (!F_IS_ACTIVE(f)) {
|
||||
/* this can happen if duplicate names were removed */
|
||||
@@ -1141,10 +1163,11 @@ static void list_file_entry(struct file_struct *f)
|
||||
|
||||
if (missing_args == 2 && f->mode == 0) {
|
||||
rprintf(FINFO, "%-*s %s\n",
|
||||
10 + 1 + size_width + mtime_width + atime_width, "*missing",
|
||||
10 + 1 + size_width + mtime_width + atime_width + crtime_width, "*missing",
|
||||
f_name(f, NULL));
|
||||
} else {
|
||||
const char *atime_str = atimes_ndx && !S_ISDIR(f->mode) ? timestring(F_ATIME(f)) : "";
|
||||
const char *crtime_str = crtimes_ndx ? timestring(F_CRTIME(f)) : "";
|
||||
const char *arrow, *lnk;
|
||||
|
||||
permstring(permbuf, f->mode);
|
||||
@@ -1157,9 +1180,9 @@ static void list_file_entry(struct file_struct *f)
|
||||
#endif
|
||||
arrow = lnk = "";
|
||||
|
||||
rprintf(FINFO, "%s %*s %s%*s %s%s%s\n",
|
||||
rprintf(FINFO, "%s %*s %s%*s%*s %s%s%s\n",
|
||||
permbuf, size_width, human_num(F_LENGTH(f)),
|
||||
timestring(f->modtime), atime_width, atime_str,
|
||||
timestring(f->modtime), atime_width, atime_str, crtime_width, crtime_str,
|
||||
f_name(f, NULL), arrow, lnk);
|
||||
}
|
||||
}
|
||||
@@ -1255,6 +1278,7 @@ 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;
|
||||
@@ -1277,20 +1301,25 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
* this function was asked to process in the file list. */
|
||||
if (!inc_recurse
|
||||
&& (*dn != '.' || dn[1]) /* Avoid an issue with --relative and the "." dir. */
|
||||
&& (!prior_dir_file || strcmp(dn, f_name(prior_dir_file, NULL)) != 0)
|
||||
&& flist_find_name(cur_flist, dn, 1) < 0) {
|
||||
&& (!prior_dir_file || strcmp(dn, f_name(prior_dir_file, NULL)) != 0)) {
|
||||
int ok = 0, j = flist_find_name(cur_flist, dn, -1);
|
||||
if (j >= 0) {
|
||||
struct file_struct *f = cur_flist->sorted[j];
|
||||
if (S_ISDIR(f->mode) || (missing_args == 2 && !file->mode && !f->mode))
|
||||
ok = 1;
|
||||
}
|
||||
/* The --delete-missing-args option can actually put invalid entries into
|
||||
* the file list, so if that option was specified, we'll just complain about
|
||||
* it and allow it. */
|
||||
if (missing_args == 2 && file->mode == 0)
|
||||
if (!ok && missing_args == 2 && file->mode == 0 && j < 0)
|
||||
rprintf(FERROR, "WARNING: parent dir is absent in the file list: %s\n", dn);
|
||||
else {
|
||||
else if (!ok) {
|
||||
rprintf(FERROR, "ABORTING due to invalid path from sender: %s/%s\n",
|
||||
dn, file->basename);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
}
|
||||
if (relative_paths && !implied_dirs
|
||||
if (relative_paths && !implied_dirs && file->mode != 0
|
||||
&& do_stat(dn, &sx.st) < 0) {
|
||||
if (dry_run)
|
||||
goto parent_is_dry_missing;
|
||||
@@ -2227,8 +2256,6 @@ void generate_files(int f_out, const char *local_name)
|
||||
if (delete_during == 2) {
|
||||
deldelay_size = BIGPATHBUFLEN * 4;
|
||||
deldelay_buf = new_array(char, deldelay_size);
|
||||
if (!deldelay_buf)
|
||||
out_of_memory("delete-delay");
|
||||
}
|
||||
info_levels[INFO_FLIST] = info_levels[INFO_PROGRESS] = 0;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* `id -G` on Linux, but it's too hard to find a portable equivalent.
|
||||
*
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003-2019 Wayne Davison
|
||||
* Copyright (C) 2003-2020 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 3 as
|
||||
@@ -20,8 +20,7 @@
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
int
|
||||
main(UNUSED(int argc), UNUSED(char *argv[]))
|
||||
int main(UNUSED(int argc), UNUSED(char *argv[]))
|
||||
{
|
||||
int n, i;
|
||||
gid_t *list;
|
||||
|
||||
@@ -35,9 +35,8 @@ struct hashtable *hashtable_create(int size, int key64)
|
||||
size *= 2;
|
||||
}
|
||||
|
||||
if (!(tbl = new(struct hashtable))
|
||||
|| !(tbl->nodes = new_array0(char, size * node_size)))
|
||||
out_of_memory("hashtable_create");
|
||||
tbl = new(struct hashtable);
|
||||
tbl->nodes = new_array0(char, size * node_size);
|
||||
tbl->size = size;
|
||||
tbl->entries = 0;
|
||||
tbl->node_size = node_size;
|
||||
@@ -94,8 +93,7 @@ void *hashtable_find(struct hashtable *tbl, int64 key, void *data_when_new)
|
||||
int size = tbl->size * 2;
|
||||
int i;
|
||||
|
||||
if (!(tbl->nodes = new_array0(char, size * tbl->node_size)))
|
||||
out_of_memory("hashtable_node");
|
||||
tbl->nodes = new_array0(char, size * tbl->node_size);
|
||||
tbl->size = size;
|
||||
tbl->entries = 0;
|
||||
|
||||
|
||||
9
hlink.c
9
hlink.c
@@ -125,8 +125,7 @@ static void match_gnums(int32 *ndx_list, int ndx_count)
|
||||
if (inc_recurse) {
|
||||
node = hashtable_find(prior_hlinks, gnum, data_when_new);
|
||||
if (node->data == data_when_new) {
|
||||
if (!(node->data = new_array0(char, 5)))
|
||||
out_of_memory("match_gnums");
|
||||
node->data = new_array0(char, 5);
|
||||
assert(gnum >= hlink_flist->ndx_start);
|
||||
file->flags |= FLAG_HLINK_FIRST;
|
||||
prev = -1;
|
||||
@@ -190,8 +189,7 @@ void match_hard_links(struct file_list *flist)
|
||||
int i, ndx_count = 0;
|
||||
int32 *ndx_list;
|
||||
|
||||
if (!(ndx_list = new_array(int32, flist->used)))
|
||||
out_of_memory("match_hard_links");
|
||||
ndx_list = new_array(int32, flist->used);
|
||||
|
||||
for (i = 0; i < flist->used; i++) {
|
||||
if (F_IS_HLINKED(flist->sorted[i]))
|
||||
@@ -541,8 +539,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
free(node->data);
|
||||
if (!(node->data = strdup(our_name)))
|
||||
out_of_memory("finish_hard_link");
|
||||
node->data = strdup(our_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
15
ifuncs.h
15
ifuncs.h
@@ -1,6 +1,6 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2007-2019 Wayne Davison
|
||||
* Copyright (C) 2007-2020 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
|
||||
@@ -19,8 +19,7 @@
|
||||
static inline void
|
||||
alloc_xbuf(xbuf *xb, size_t sz)
|
||||
{
|
||||
if (!(xb->buf = new_array(char, sz)))
|
||||
out_of_memory("alloc_xbuf");
|
||||
xb->buf = new_array(char, sz);
|
||||
xb->size = sz;
|
||||
xb->len = xb->pos = 0;
|
||||
}
|
||||
@@ -29,8 +28,6 @@ static inline void
|
||||
realloc_xbuf(xbuf *xb, size_t sz)
|
||||
{
|
||||
char *bf = realloc_array(xb->buf, char, sz);
|
||||
if (!bf)
|
||||
out_of_memory("realloc_xbuf");
|
||||
xb->buf = bf;
|
||||
xb->size = sz;
|
||||
}
|
||||
@@ -104,3 +101,11 @@ free_stat_x(stat_x *sx_p)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline char *my_strdup(const char *str, const char *file, int line)
|
||||
{
|
||||
int len = strlen(str)+1;
|
||||
char *buf = my_alloc(NULL, len, 1, file, line);
|
||||
memcpy(buf, str, len);
|
||||
return buf;
|
||||
}
|
||||
|
||||
66
io.c
66
io.c
@@ -54,12 +54,14 @@ extern int read_batch;
|
||||
extern int compat_flags;
|
||||
extern int protect_args;
|
||||
extern int checksum_seed;
|
||||
extern int daemon_connection;
|
||||
extern int protocol_version;
|
||||
extern int remove_source_files;
|
||||
extern int preserve_hard_links;
|
||||
extern BOOL extra_flist_sending_enabled;
|
||||
extern BOOL flush_ok_after_signal;
|
||||
extern struct stats stats;
|
||||
extern time_t stop_at_utime;
|
||||
extern struct file_list *cur_flist;
|
||||
#ifdef ICONV_OPTION
|
||||
extern int filesfrom_convert;
|
||||
@@ -463,7 +465,7 @@ void reduce_iobuf_size(xbuf *out, size_t new_size)
|
||||
{
|
||||
if (new_size < out->size) {
|
||||
/* Avoid weird buffer interactions by only outputting this to stderr. */
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 4)) {
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 4)) {
|
||||
const char *name = out == &iobuf.out ? "iobuf.out"
|
||||
: out == &iobuf.msg ? "iobuf.msg"
|
||||
: NULL;
|
||||
@@ -481,7 +483,7 @@ void restore_iobuf_size(xbuf *out)
|
||||
if (IOBUF_WAS_REDUCED(out->size)) {
|
||||
size_t new_size = IOBUF_RESTORE_SIZE(out->size);
|
||||
/* Avoid weird buffer interactions by only outputting this to stderr. */
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 4)) {
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 4)) {
|
||||
const char *name = out == &iobuf.out ? "iobuf.out"
|
||||
: out == &iobuf.msg ? "iobuf.msg"
|
||||
: NULL;
|
||||
@@ -565,7 +567,7 @@ static char *perform_io(size_t needed, int flags)
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 3)) {
|
||||
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&" : "");
|
||||
}
|
||||
@@ -579,7 +581,7 @@ static char *perform_io(size_t needed, int flags)
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 3)) {
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
|
||||
rprintf(FINFO, "[%s] perform_io(%ld, outroom) needs to flush %ld\n",
|
||||
who_am_i(), (long)needed,
|
||||
iobuf.out.len + needed > iobuf.out.size
|
||||
@@ -595,7 +597,7 @@ static char *perform_io(size_t needed, int flags)
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 3)) {
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) {
|
||||
rprintf(FINFO, "[%s] perform_io(%ld, msgroom) needs to flush %ld\n",
|
||||
who_am_i(), (long)needed,
|
||||
iobuf.msg.len + needed > iobuf.msg.size
|
||||
@@ -604,7 +606,7 @@ static char *perform_io(size_t needed, int flags)
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 3))
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 3))
|
||||
rprintf(FINFO, "[%s] perform_io(%ld, %d)\n", who_am_i(), (long)needed, flags);
|
||||
break;
|
||||
|
||||
@@ -662,7 +664,7 @@ static char *perform_io(size_t needed, int flags)
|
||||
SIVAL(iobuf.out.buf + iobuf.raw_data_header_pos, 0,
|
||||
((MPLEX_BASE + (int)MSG_DATA)<<24) + iobuf.out.len - 4);
|
||||
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 1)) {
|
||||
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);
|
||||
}
|
||||
@@ -782,12 +784,16 @@ static char *perform_io(size_t needed, int flags)
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
}
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2))
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
|
||||
rprintf(FINFO, "[%s] recv=%ld\n", who_am_i(), (long)n);
|
||||
|
||||
if (io_timeout) {
|
||||
if (io_timeout || stop_at_utime) {
|
||||
last_io_in = time(NULL);
|
||||
if (flags & PIO_NEED_INPUT)
|
||||
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);
|
||||
}
|
||||
stats.total_read += n;
|
||||
@@ -817,7 +823,7 @@ static char *perform_io(size_t needed, int flags)
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
}
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2)) {
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
|
||||
rprintf(FINFO, "[%s] %s sent=%ld\n",
|
||||
who_am_i(), out == &iobuf.out ? "out" : "msg", (long)n);
|
||||
}
|
||||
@@ -912,7 +918,11 @@ void noop_io_until_death(void)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
if (!iobuf.in.buf || !iobuf.out.buf || iobuf.in_fd < 0 || iobuf.out_fd < 0 || kluge_around_eof || msgs2stderr)
|
||||
if (!iobuf.in.buf || !iobuf.out.buf || iobuf.in_fd < 0 || iobuf.out_fd < 0 || kluge_around_eof)
|
||||
return;
|
||||
|
||||
/* If we're talking to a daemon over a socket, don't short-circuit this logic */
|
||||
if (msgs2stderr && daemon_connection >= 0)
|
||||
return;
|
||||
|
||||
kluge_around_eof = 2;
|
||||
@@ -930,7 +940,7 @@ int send_msg(enum msgcode code, const char *buf, size_t len, int convert)
|
||||
{
|
||||
char *hdr;
|
||||
size_t needed, pos;
|
||||
BOOL want_debug = DEBUG_GTE(IO, 1) && convert >= 0 && (msgs2stderr || code != MSG_INFO);
|
||||
BOOL want_debug = DEBUG_GTE(IO, 1) && convert >= 0 && (msgs2stderr == 1 || code != MSG_INFO);
|
||||
|
||||
if (!OUT_MULTIPLEXED)
|
||||
return 0;
|
||||
@@ -1239,8 +1249,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
|
||||
rl_flags |= (protect_args && ic_recv != (iconv_t)-1 ? RL_CONVERT : 0);
|
||||
#endif
|
||||
|
||||
if (!(argv = new_array(char *, maxargs)))
|
||||
out_of_memory("read_args");
|
||||
argv = new_array(char *, maxargs);
|
||||
if (mod_name && !protect_args)
|
||||
argv[argc++] = "rsyncd";
|
||||
|
||||
@@ -1253,8 +1262,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
|
||||
|
||||
if (argc == maxargs-1) {
|
||||
maxargs += MAX_ARGS;
|
||||
if (!(argv = realloc_array(argv, char *, maxargs)))
|
||||
out_of_memory("read_args");
|
||||
argv = realloc_array(argv, char *, maxargs);
|
||||
}
|
||||
|
||||
if (dot_pos) {
|
||||
@@ -1262,8 +1270,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
|
||||
int len = strlen(buf);
|
||||
if (request_len)
|
||||
request_p[0][request_len++] = ' ';
|
||||
if (!(*request_p = realloc_array(*request_p, char, request_len + len + 1)))
|
||||
out_of_memory("read_args");
|
||||
*request_p = realloc_array(*request_p, char, request_len + len + 1);
|
||||
memcpy(*request_p + request_len, buf, len + 1);
|
||||
request_len += len;
|
||||
}
|
||||
@@ -1272,8 +1279,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
|
||||
else
|
||||
glob_expand(buf, &argv, &argc, &maxargs);
|
||||
} else {
|
||||
if (!(p = strdup(buf)))
|
||||
out_of_memory("read_args");
|
||||
p = strdup(buf);
|
||||
argv[argc++] = p;
|
||||
if (*p == '.' && p[1] == '\0')
|
||||
dot_pos = argc;
|
||||
@@ -1289,7 +1295,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
|
||||
|
||||
BOOL io_start_buffering_out(int f_out)
|
||||
{
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2))
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
|
||||
rprintf(FINFO, "[%s] io_start_buffering_out(%d)\n", who_am_i(), f_out);
|
||||
|
||||
if (iobuf.out.buf) {
|
||||
@@ -1308,7 +1314,7 @@ BOOL io_start_buffering_out(int f_out)
|
||||
|
||||
BOOL io_start_buffering_in(int f_in)
|
||||
{
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2))
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
|
||||
rprintf(FINFO, "[%s] io_start_buffering_in(%d)\n", who_am_i(), f_in);
|
||||
|
||||
if (iobuf.in.buf) {
|
||||
@@ -1327,7 +1333,7 @@ BOOL io_start_buffering_in(int f_in)
|
||||
|
||||
void io_end_buffering_in(BOOL free_buffers)
|
||||
{
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2)) {
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
|
||||
rprintf(FINFO, "[%s] io_end_buffering_in(IOBUF_%s_BUFS)\n",
|
||||
who_am_i(), free_buffers ? "FREE" : "KEEP");
|
||||
}
|
||||
@@ -1342,7 +1348,7 @@ void io_end_buffering_in(BOOL free_buffers)
|
||||
|
||||
void io_end_buffering_out(BOOL free_buffers)
|
||||
{
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2)) {
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2)) {
|
||||
rprintf(FINFO, "[%s] io_end_buffering_out(IOBUF_%s_BUFS)\n",
|
||||
who_am_i(), free_buffers ? "FREE" : "KEEP");
|
||||
}
|
||||
@@ -1430,7 +1436,7 @@ static void read_a_msg(void)
|
||||
msg_bytes = tag & 0xFFFFFF;
|
||||
tag = (tag >> 24) - MPLEX_BASE;
|
||||
|
||||
if (DEBUG_GTE(IO, 1) && msgs2stderr)
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 1))
|
||||
rprintf(FINFO, "[%s] got msg=%d, len=%ld\n", who_am_i(), (int)tag, (long)msg_bytes);
|
||||
|
||||
switch (tag) {
|
||||
@@ -2302,7 +2308,7 @@ void io_start_multiplex_out(int fd)
|
||||
{
|
||||
io_flush(FULL_FLUSH);
|
||||
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2))
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
|
||||
rprintf(FINFO, "[%s] io_start_multiplex_out(%d)\n", who_am_i(), fd);
|
||||
|
||||
if (!iobuf.msg.buf)
|
||||
@@ -2319,7 +2325,7 @@ void io_start_multiplex_out(int fd)
|
||||
/* Setup for multiplexing a MSG_* stream with the data stream. */
|
||||
void io_start_multiplex_in(int fd)
|
||||
{
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2))
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
|
||||
rprintf(FINFO, "[%s] io_start_multiplex_in(%d)\n", who_am_i(), fd);
|
||||
|
||||
iobuf.in_multiplexed = 1; /* See also IN_MULTIPLEXED */
|
||||
@@ -2330,7 +2336,7 @@ int io_end_multiplex_in(int mode)
|
||||
{
|
||||
int ret = iobuf.in_multiplexed ? iobuf.in_fd : -1;
|
||||
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2))
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
|
||||
rprintf(FINFO, "[%s] io_end_multiplex_in(mode=%d)\n", who_am_i(), mode);
|
||||
|
||||
iobuf.in_multiplexed = 0;
|
||||
@@ -2348,7 +2354,7 @@ int io_end_multiplex_out(int mode)
|
||||
{
|
||||
int ret = iobuf.out_empty_len ? iobuf.out_fd : -1;
|
||||
|
||||
if (msgs2stderr && DEBUG_GTE(IO, 2))
|
||||
if (msgs2stderr == 1 && DEBUG_GTE(IO, 2))
|
||||
rprintf(FINFO, "[%s] io_end_multiplex_out(mode=%d)\n", who_am_i(), mode);
|
||||
|
||||
if (mode != MPLX_TO_BUFFERED)
|
||||
|
||||
85
lib/compat.c
85
lib/compat.c
@@ -24,16 +24,24 @@
|
||||
|
||||
static char number_separator;
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
char *strdup(char *s)
|
||||
char get_number_separator(void)
|
||||
{
|
||||
int len = strlen(s) + 1;
|
||||
char *ret = (char *)malloc(len);
|
||||
if (ret)
|
||||
memcpy(ret, s, len);
|
||||
return ret;
|
||||
if (!number_separator) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof buf, "%f", 3.14);
|
||||
if (strchr(buf, '.') != NULL)
|
||||
number_separator = ',';
|
||||
else
|
||||
number_separator = '.';
|
||||
}
|
||||
|
||||
return number_separator;
|
||||
}
|
||||
|
||||
char get_decimal_point(void)
|
||||
{
|
||||
return get_number_separator() == ',' ? '.' : ',';
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETCWD
|
||||
char *getcwd(char *buf, int size)
|
||||
@@ -155,30 +163,6 @@ int sys_gettimeofday(struct timeval *tv)
|
||||
#endif
|
||||
}
|
||||
|
||||
#define HUMANIFY(mult) \
|
||||
do { \
|
||||
if (num >= mult || num <= -mult) { \
|
||||
double dnum = (double)num / mult; \
|
||||
char units; \
|
||||
if (num < 0) \
|
||||
dnum = -dnum; \
|
||||
if (dnum < mult) \
|
||||
units = 'K'; \
|
||||
else if ((dnum /= mult) < mult) \
|
||||
units = 'M'; \
|
||||
else if ((dnum /= mult) < mult) \
|
||||
units = 'G'; \
|
||||
else { \
|
||||
dnum /= mult; \
|
||||
units = 'T'; \
|
||||
} \
|
||||
if (num < 0) \
|
||||
dnum = -dnum; \
|
||||
snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units); \
|
||||
return bufs[n]; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Return the int64 number as a string. If the human_flag arg is non-zero,
|
||||
* we may output the number in K, M, G, or T units. If we don't add a unit
|
||||
* suffix, we will append the fract string, if it is non-NULL. We can
|
||||
@@ -190,22 +174,35 @@ char *do_big_num(int64 num, int human_flag, const char *fract)
|
||||
char *s;
|
||||
int len, negated;
|
||||
|
||||
if (human_flag && !number_separator) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof buf, "%f", 3.14);
|
||||
if (strchr(buf, '.') != NULL)
|
||||
number_separator = ',';
|
||||
else
|
||||
number_separator = '.';
|
||||
}
|
||||
if (human_flag && !number_separator)
|
||||
(void)get_number_separator();
|
||||
|
||||
n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
|
||||
|
||||
if (human_flag > 1) {
|
||||
if (human_flag == 2)
|
||||
HUMANIFY(1000);
|
||||
else
|
||||
HUMANIFY(1024);
|
||||
int mult = human_flag == 2 ? 1000 : 1024;
|
||||
if (num >= mult || num <= -mult) {
|
||||
double dnum = (double)num / mult;
|
||||
char units;
|
||||
if (num < 0)
|
||||
dnum = -dnum;
|
||||
if (dnum < mult)
|
||||
units = 'K';
|
||||
else if ((dnum /= mult) < mult)
|
||||
units = 'M';
|
||||
else if ((dnum /= mult) < mult)
|
||||
units = 'G';
|
||||
else if ((dnum /= mult) < mult)
|
||||
units = 'T';
|
||||
else {
|
||||
dnum /= mult;
|
||||
units = 'P';
|
||||
}
|
||||
if (num < 0)
|
||||
dnum = -dnum;
|
||||
snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units);
|
||||
return bufs[n];
|
||||
}
|
||||
}
|
||||
|
||||
s = bufs[n] + sizeof bufs[0] - 1;
|
||||
|
||||
@@ -13,3 +13,5 @@
|
||||
#define CSUM_MD4 4
|
||||
#define CSUM_MD5 5
|
||||
#define CSUM_XXH64 6
|
||||
#define CSUM_XXH3_64 7
|
||||
#define CSUM_XXH3_128 8
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
|
||||
#if !defined USE_OPENSSL && CSUM_CHUNK == 64
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define md5_process_asm _md5_process_asm
|
||||
#endif
|
||||
|
||||
.text
|
||||
.align 16
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ pool_alloc, pool_free, pool_free_old, pool_talloc, pool_tfree, pool_create, pool
|
||||
.SH SYNOPSIS
|
||||
.B #include "pool_alloc.h"
|
||||
|
||||
\fBstruct alloc_pool *pool_create(size_t \fIsize\fB, size_t \fIquantum\fB, void (*\fIbomb\fB)(char *), int \fIflags\fB);
|
||||
\fBstruct alloc_pool *pool_create(size_t \fIsize\fB, size_t \fIquantum\fB, void (*\fIbomb\fB)(char*,char*,int), int \fIflags\fB);
|
||||
|
||||
\fBvoid pool_destroy(struct alloc_pool *\fIpool\fB);
|
||||
|
||||
|
||||
@@ -45,13 +45,13 @@ struct align_test {
|
||||
#define PTR_ADD(b,o) ( (void*) ((char*)(b) + (o)) )
|
||||
|
||||
alloc_pool_t
|
||||
pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags)
|
||||
pool_create(size_t size, size_t quantum, void (*bomb)(const char*, const char*, int), int flags)
|
||||
{
|
||||
struct alloc_pool *pool;
|
||||
|
||||
if ((MINALIGN & (MINALIGN - 1)) != 0) {
|
||||
if (bomb)
|
||||
(*bomb)("Compiler error: MINALIGN is not a power of 2\n");
|
||||
(*bomb)("Compiler error: MINALIGN is not a power of 2", __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg)
|
||||
|
||||
bomb_out:
|
||||
if (pool->bomb)
|
||||
(*pool->bomb)(bomb_msg);
|
||||
(*pool->bomb)(bomb_msg, __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
typedef void *alloc_pool_t;
|
||||
|
||||
alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags);
|
||||
alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(const char*, const char*, int), int flags);
|
||||
void pool_destroy(alloc_pool_t pool);
|
||||
void *pool_alloc(alloc_pool_t pool, size_t size, const char *bomb_msg);
|
||||
void pool_free(alloc_pool_t pool, size_t size, void *addr);
|
||||
|
||||
622
lib/sysacls.c
622
lib/sysacls.c
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
* Version 2.2.x
|
||||
* Portable SMB ACL interface
|
||||
* Copyright (C) Jeremy Allison 2000
|
||||
* Copyright (C) 2007-2019 Wayne Davison
|
||||
* Copyright (C) 2007-2020 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
|
||||
@@ -139,7 +139,9 @@ typedef struct acl *SMB_ACL_ENTRY_T;
|
||||
|
||||
/* Based on the Solaris & UnixWare code. */
|
||||
|
||||
#ifndef __TANDEM
|
||||
#undef GROUP
|
||||
#endif
|
||||
#include <sys/aclv.h>
|
||||
|
||||
/* SVR4.2 ES/MP ACLs */
|
||||
|
||||
453
loadparm.c
453
loadparm.c
@@ -42,12 +42,12 @@
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#include "ifuncs.h"
|
||||
#include "default-dont-compress.h"
|
||||
|
||||
extern item_list dparam_list;
|
||||
|
||||
#define strequal(a, b) (strcasecmp(a, b)==0)
|
||||
#define BOOLSTR(b) ((b) ? "Yes" : "No")
|
||||
|
||||
#ifndef LOG_DAEMON
|
||||
#define LOG_DAEMON 0
|
||||
@@ -55,7 +55,7 @@ extern item_list dparam_list;
|
||||
|
||||
/* the following are used by loadparm for option lists */
|
||||
typedef enum {
|
||||
P_BOOL, P_BOOLREV, P_CHAR, P_INTEGER,
|
||||
P_BOOL, P_BOOLREV, P_BOOL3, P_CHAR, P_INTEGER,
|
||||
P_OCTAL, P_PATH, P_STRING, P_ENUM
|
||||
} parm_type;
|
||||
|
||||
@@ -86,234 +86,6 @@ struct parm_struct {
|
||||
#define LP_SNUM_OK(i) ((i) >= 0 && (i) < (int)section_list.count)
|
||||
#define SECTION_PTR(s, p) (((char*)(s)) + (ptrdiff_t)(((char*)(p))-(char*)&Vars.l))
|
||||
|
||||
/* This structure describes global (ie., server-wide) parameters. */
|
||||
typedef struct {
|
||||
char *bind_address;
|
||||
char *daemon_chroot;
|
||||
char *daemon_gid;
|
||||
char *daemon_uid;
|
||||
char *motd_file;
|
||||
char *pid_file;
|
||||
char *socket_options;
|
||||
|
||||
/* Each _EXP var tracks if the associated char* var has been expanded yet or not. */
|
||||
BOOL bind_address_EXP;
|
||||
BOOL daemon_chroot_EXP;
|
||||
BOOL daemon_gid_EXP;
|
||||
BOOL daemon_uid_EXP;
|
||||
BOOL motd_file_EXP;
|
||||
BOOL pid_file_EXP;
|
||||
BOOL socket_options_EXP;
|
||||
|
||||
int listen_backlog;
|
||||
int rsync_port;
|
||||
|
||||
BOOL proxy_protocol;
|
||||
} global_vars;
|
||||
|
||||
/* This structure describes a single section. Their order must match the
|
||||
* initializers below, which you can accomplish by keeping each sub-section
|
||||
* sorted. (e.g. in vim, just visually select each subsection and use !sort.)
|
||||
* NOTE: the char* variables MUST all remain at the start of the struct! */
|
||||
typedef struct {
|
||||
char *auth_users;
|
||||
char *charset;
|
||||
char *comment;
|
||||
char *dont_compress;
|
||||
char *early_exec;
|
||||
char *exclude;
|
||||
char *exclude_from;
|
||||
char *filter;
|
||||
char *gid;
|
||||
char *hosts_allow;
|
||||
char *hosts_deny;
|
||||
char *include;
|
||||
char *include_from;
|
||||
char *incoming_chmod;
|
||||
char *lock_file;
|
||||
char *log_file;
|
||||
char *log_format;
|
||||
char *name;
|
||||
char *outgoing_chmod;
|
||||
char *path;
|
||||
char *postxfer_exec;
|
||||
char *prexfer_exec;
|
||||
char *refuse_options;
|
||||
char *secrets_file;
|
||||
char *syslog_tag;
|
||||
char *temp_dir;
|
||||
char *uid;
|
||||
|
||||
/* Each _EXP var tracks if the associated char* var has been expanded yet or not. */
|
||||
BOOL auth_users_EXP;
|
||||
BOOL charset_EXP;
|
||||
BOOL comment_EXP;
|
||||
BOOL dont_compress_EXP;
|
||||
BOOL early_exec_EXP;
|
||||
BOOL exclude_EXP;
|
||||
BOOL exclude_from_EXP;
|
||||
BOOL filter_EXP;
|
||||
BOOL gid_EXP;
|
||||
BOOL hosts_allow_EXP;
|
||||
BOOL hosts_deny_EXP;
|
||||
BOOL include_EXP;
|
||||
BOOL include_from_EXP;
|
||||
BOOL incoming_chmod_EXP;
|
||||
BOOL lock_file_EXP;
|
||||
BOOL log_file_EXP;
|
||||
BOOL log_format_EXP;
|
||||
BOOL name_EXP;
|
||||
BOOL outgoing_chmod_EXP;
|
||||
BOOL path_EXP;
|
||||
BOOL postxfer_exec_EXP;
|
||||
BOOL prexfer_exec_EXP;
|
||||
BOOL refuse_options_EXP;
|
||||
BOOL secrets_file_EXP;
|
||||
BOOL syslog_tag_EXP;
|
||||
BOOL temp_dir_EXP;
|
||||
BOOL uid_EXP;
|
||||
|
||||
int max_connections;
|
||||
int max_verbosity;
|
||||
int syslog_facility;
|
||||
int timeout;
|
||||
|
||||
BOOL fake_super;
|
||||
BOOL forward_lookup;
|
||||
BOOL ignore_errors;
|
||||
BOOL ignore_nonreadable;
|
||||
BOOL list;
|
||||
BOOL munge_symlinks;
|
||||
BOOL numeric_ids;
|
||||
BOOL read_only;
|
||||
BOOL reverse_lookup;
|
||||
BOOL strict_modes;
|
||||
BOOL transfer_logging;
|
||||
BOOL use_chroot;
|
||||
BOOL write_only;
|
||||
} local_vars;
|
||||
|
||||
/* This structure describes the global variables (g) as well as the globally
|
||||
* specified values of the local variables (l), which are used when modules
|
||||
* don't specify their own values. */
|
||||
typedef struct {
|
||||
global_vars g;
|
||||
local_vars l;
|
||||
} all_vars;
|
||||
|
||||
/* The application defaults for all the variables. "Defaults" is
|
||||
* used to re-initialize "Vars" before each config-file read.
|
||||
*
|
||||
* In order to keep these sorted in the same way as the structure
|
||||
* above, use the variable name in the leading comment, including a
|
||||
* trailing ';' (to avoid a sorting problem with trailing digits). */
|
||||
static const all_vars Defaults = {
|
||||
/* ==== global_vars ==== */
|
||||
{
|
||||
/* bind_address; */ NULL,
|
||||
/* daemon_chroot; */ NULL,
|
||||
/* daemon_gid; */ NULL,
|
||||
/* daemon_uid; */ NULL,
|
||||
/* motd_file; */ NULL,
|
||||
/* pid_file; */ NULL,
|
||||
/* socket_options; */ NULL,
|
||||
|
||||
/* bind_address_EXP; */ False,
|
||||
/* daemon_chroot_EXP; */ False,
|
||||
/* daemon_gid_EXP; */ False,
|
||||
/* daemon_uid_EXP; */ False,
|
||||
/* motd_file_EXP; */ False,
|
||||
/* pid_file_EXP; */ False,
|
||||
/* socket_options_EXP; */ False,
|
||||
|
||||
/* listen_backlog; */ 5,
|
||||
/* rsync_port; */ 0,
|
||||
|
||||
/* proxy_protocol; */ False,
|
||||
},
|
||||
|
||||
/* ==== local_vars ==== */
|
||||
{
|
||||
/* auth_users; */ NULL,
|
||||
/* charset; */ NULL,
|
||||
/* comment; */ NULL,
|
||||
/* dont_compress; */ DEFAULT_DONT_COMPRESS,
|
||||
/* early_exec; */ NULL,
|
||||
/* exclude; */ NULL,
|
||||
/* exclude_from; */ NULL,
|
||||
/* filter; */ NULL,
|
||||
/* gid; */ NULL,
|
||||
/* hosts_allow; */ NULL,
|
||||
/* hosts_deny; */ NULL,
|
||||
/* include; */ NULL,
|
||||
/* include_from; */ NULL,
|
||||
/* incoming_chmod; */ NULL,
|
||||
/* lock_file; */ DEFAULT_LOCK_FILE,
|
||||
/* log_file; */ NULL,
|
||||
/* log_format; */ "%o %h [%a] %m (%u) %f %l",
|
||||
/* name; */ NULL,
|
||||
/* outgoing_chmod; */ NULL,
|
||||
/* path; */ NULL,
|
||||
/* postxfer_exec; */ NULL,
|
||||
/* prexfer_exec; */ NULL,
|
||||
/* refuse_options; */ NULL,
|
||||
/* secrets_file; */ NULL,
|
||||
/* syslog_tag; */ "rsyncd",
|
||||
/* temp_dir; */ NULL,
|
||||
/* uid; */ NULL,
|
||||
|
||||
/* auth_users_EXP; */ False,
|
||||
/* charset_EXP; */ False,
|
||||
/* comment_EXP; */ False,
|
||||
/* dont_compress_EXP; */ False,
|
||||
/* early_exec_EXP; */ False,
|
||||
/* exclude_EXP; */ False,
|
||||
/* exclude_from_EXP; */ False,
|
||||
/* filter_EXP; */ False,
|
||||
/* gid_EXP; */ False,
|
||||
/* hosts_allow_EXP; */ False,
|
||||
/* hosts_deny_EXP; */ False,
|
||||
/* include_EXP; */ False,
|
||||
/* include_from_EXP; */ False,
|
||||
/* incoming_chmod_EXP; */ False,
|
||||
/* lock_file_EXP; */ False,
|
||||
/* log_file_EXP; */ False,
|
||||
/* log_format_EXP; */ False,
|
||||
/* name_EXP; */ False,
|
||||
/* outgoing_chmod_EXP; */ False,
|
||||
/* path_EXP; */ False,
|
||||
/* postxfer_exec_EXP; */ False,
|
||||
/* prexfer_exec_EXP; */ False,
|
||||
/* refuse_options_EXP; */ False,
|
||||
/* secrets_file_EXP; */ False,
|
||||
/* syslog_tag_EXP; */ False,
|
||||
/* temp_dir_EXP; */ False,
|
||||
/* uid_EXP; */ False,
|
||||
|
||||
/* max_connections; */ 0,
|
||||
/* max_verbosity; */ 1,
|
||||
/* syslog_facility; */ LOG_DAEMON,
|
||||
/* timeout; */ 0,
|
||||
|
||||
/* fake_super; */ False,
|
||||
/* forward_lookup; */ True,
|
||||
/* ignore_errors; */ False,
|
||||
/* ignore_nonreadable; */ False,
|
||||
/* list; */ True,
|
||||
/* munge_symlinks; */ (BOOL)-1,
|
||||
/* numeric_ids; */ (BOOL)-1,
|
||||
/* read_only; */ True,
|
||||
/* reverse_lookup; */ True,
|
||||
/* strict_modes; */ True,
|
||||
/* transfer_logging; */ False,
|
||||
/* use_chroot; */ True,
|
||||
/* write_only; */ False,
|
||||
}
|
||||
};
|
||||
|
||||
/* The currently configured values for all the variables. */
|
||||
static all_vars Vars;
|
||||
|
||||
/* Stack of "Vars" values used by the &include directive. */
|
||||
static item_list Vars_stack = EMPTY_ITEM_LIST;
|
||||
|
||||
@@ -323,9 +95,7 @@ static item_list section_list = EMPTY_ITEM_LIST;
|
||||
static int iSectionIndex = -1;
|
||||
static BOOL bInGlobalSection = True;
|
||||
|
||||
#define NUMPARAMETERS (sizeof (parm_table) / sizeof (struct parm_struct))
|
||||
|
||||
static struct enum_list enum_facilities[] = {
|
||||
static struct enum_list enum_syslog_facility[] = {
|
||||
#ifdef LOG_AUTH
|
||||
{ LOG_AUTH, "auth" },
|
||||
#endif
|
||||
@@ -392,96 +162,27 @@ static struct enum_list enum_facilities[] = {
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static struct parm_struct parm_table[] =
|
||||
{
|
||||
{"address", P_STRING, P_GLOBAL,&Vars.g.bind_address, NULL,0},
|
||||
{"daemon chroot", P_STRING, P_GLOBAL,&Vars.g.daemon_chroot, NULL,0},
|
||||
{"daemon gid", P_STRING, P_GLOBAL,&Vars.g.daemon_gid, NULL,0},
|
||||
{"daemon uid", P_STRING, P_GLOBAL,&Vars.g.daemon_uid, NULL,0},
|
||||
{"listen backlog", P_INTEGER,P_GLOBAL,&Vars.g.listen_backlog, NULL,0},
|
||||
{"motd file", P_STRING, P_GLOBAL,&Vars.g.motd_file, NULL,0},
|
||||
{"pid file", P_STRING, P_GLOBAL,&Vars.g.pid_file, NULL,0},
|
||||
{"port", P_INTEGER,P_GLOBAL,&Vars.g.rsync_port, NULL,0},
|
||||
{"proxy protocol", P_BOOL, P_LOCAL, &Vars.g.proxy_protocol, NULL,0},
|
||||
{"socket options", P_STRING, P_GLOBAL,&Vars.g.socket_options, NULL,0},
|
||||
|
||||
{"auth users", P_STRING, P_LOCAL, &Vars.l.auth_users, NULL,0},
|
||||
{"charset", P_STRING, P_LOCAL, &Vars.l.charset, NULL,0},
|
||||
{"comment", P_STRING, P_LOCAL, &Vars.l.comment, NULL,0},
|
||||
{"dont compress", P_STRING, P_LOCAL, &Vars.l.dont_compress, NULL,0},
|
||||
{"early exec", P_STRING, P_LOCAL, &Vars.l.early_exec, NULL,0},
|
||||
{"exclude from", P_STRING, P_LOCAL, &Vars.l.exclude_from, NULL,0},
|
||||
{"exclude", P_STRING, P_LOCAL, &Vars.l.exclude, NULL,0},
|
||||
{"fake super", P_BOOL, P_LOCAL, &Vars.l.fake_super, NULL,0},
|
||||
{"filter", P_STRING, P_LOCAL, &Vars.l.filter, NULL,0},
|
||||
{"forward lookup", P_BOOL, P_LOCAL, &Vars.l.forward_lookup, NULL,0},
|
||||
{"gid", P_STRING, P_LOCAL, &Vars.l.gid, NULL,0},
|
||||
{"hosts allow", P_STRING, P_LOCAL, &Vars.l.hosts_allow, NULL,0},
|
||||
{"hosts deny", P_STRING, P_LOCAL, &Vars.l.hosts_deny, NULL,0},
|
||||
{"ignore errors", P_BOOL, P_LOCAL, &Vars.l.ignore_errors, NULL,0},
|
||||
{"ignore nonreadable",P_BOOL, P_LOCAL, &Vars.l.ignore_nonreadable, NULL,0},
|
||||
{"include from", P_STRING, P_LOCAL, &Vars.l.include_from, NULL,0},
|
||||
{"include", P_STRING, P_LOCAL, &Vars.l.include, NULL,0},
|
||||
{"incoming chmod", P_STRING, P_LOCAL, &Vars.l.incoming_chmod, NULL,0},
|
||||
{"list", P_BOOL, P_LOCAL, &Vars.l.list, NULL,0},
|
||||
{"lock file", P_STRING, P_LOCAL, &Vars.l.lock_file, NULL,0},
|
||||
{"log file", P_STRING, P_LOCAL, &Vars.l.log_file, NULL,0},
|
||||
{"log format", P_STRING, P_LOCAL, &Vars.l.log_format, NULL,0},
|
||||
{"max connections", P_INTEGER,P_LOCAL, &Vars.l.max_connections, NULL,0},
|
||||
{"max verbosity", P_INTEGER,P_LOCAL, &Vars.l.max_verbosity, NULL,0},
|
||||
{"munge symlinks", P_BOOL, P_LOCAL, &Vars.l.munge_symlinks, NULL,0},
|
||||
{"name", P_STRING, P_LOCAL, &Vars.l.name, NULL,0},
|
||||
{"numeric ids", P_BOOL, P_LOCAL, &Vars.l.numeric_ids, NULL,0},
|
||||
{"outgoing chmod", P_STRING, P_LOCAL, &Vars.l.outgoing_chmod, NULL,0},
|
||||
{"path", P_PATH, P_LOCAL, &Vars.l.path, NULL,0},
|
||||
#ifdef HAVE_PUTENV
|
||||
{"post-xfer exec", P_STRING, P_LOCAL, &Vars.l.postxfer_exec, NULL,0},
|
||||
{"pre-xfer exec", P_STRING, P_LOCAL, &Vars.l.prexfer_exec, NULL,0},
|
||||
#endif
|
||||
{"read only", P_BOOL, P_LOCAL, &Vars.l.read_only, NULL,0},
|
||||
{"refuse options", P_STRING, P_LOCAL, &Vars.l.refuse_options, NULL,0},
|
||||
{"reverse lookup", P_BOOL, P_LOCAL, &Vars.l.reverse_lookup, NULL,0},
|
||||
{"secrets file", P_STRING, P_LOCAL, &Vars.l.secrets_file, NULL,0},
|
||||
{"strict modes", P_BOOL, P_LOCAL, &Vars.l.strict_modes, NULL,0},
|
||||
{"syslog facility", P_ENUM, P_LOCAL, &Vars.l.syslog_facility, enum_facilities,0},
|
||||
{"syslog tag", P_STRING, P_LOCAL, &Vars.l.syslog_tag, NULL,0},
|
||||
{"temp dir", P_PATH, P_LOCAL, &Vars.l.temp_dir, NULL,0},
|
||||
{"timeout", P_INTEGER,P_LOCAL, &Vars.l.timeout, NULL,0},
|
||||
{"transfer logging", P_BOOL, P_LOCAL, &Vars.l.transfer_logging, NULL,0},
|
||||
{"uid", P_STRING, P_LOCAL, &Vars.l.uid, NULL,0},
|
||||
{"use chroot", P_BOOL, P_LOCAL, &Vars.l.use_chroot, NULL,0},
|
||||
{"write only", P_BOOL, P_LOCAL, &Vars.l.write_only, NULL,0},
|
||||
{NULL, P_BOOL, P_NONE, NULL, NULL,0}
|
||||
};
|
||||
|
||||
/* Initialise the Default all_vars structure. */
|
||||
void reset_daemon_vars(void)
|
||||
{
|
||||
memcpy(&Vars, &Defaults, sizeof Vars);
|
||||
}
|
||||
|
||||
/* Expand %VAR% references. Any unknown vars or unrecognized
|
||||
* syntax leaves the raw chars unchanged. */
|
||||
static char *expand_vars(char *str)
|
||||
static char *expand_vars(const char *str)
|
||||
{
|
||||
char *buf, *t, *f;
|
||||
char *buf, *t;
|
||||
const char *f;
|
||||
int bufsize;
|
||||
|
||||
if (!str || !strchr(str, '%'))
|
||||
return str;
|
||||
return (char *)str; /* TODO change return value to const char* at some point. */
|
||||
|
||||
bufsize = strlen(str) + 2048;
|
||||
if ((buf = new_array(char, bufsize+1)) == NULL) /* +1 for trailing '\0' */
|
||||
out_of_memory("expand_vars");
|
||||
buf = new_array(char, bufsize+1); /* +1 for trailing '\0' */
|
||||
|
||||
for (t = buf, f = str; bufsize && *f; ) {
|
||||
if (*f == '%' && *++f != '%') {
|
||||
char *percent = strchr(f, '%');
|
||||
if (percent) {
|
||||
if (*f == '%' && isUpper(f+1)) {
|
||||
char *percent = strchr(f+1, '%');
|
||||
if (percent && percent - f < bufsize) {
|
||||
char *val;
|
||||
*percent = '\0';
|
||||
val = getenv(f);
|
||||
*percent = '%';
|
||||
strlcpy(t, f+1, percent - f);
|
||||
val = getenv(t);
|
||||
if (val) {
|
||||
int len = strlcpy(t, val, bufsize+1);
|
||||
if (len > bufsize)
|
||||
@@ -492,7 +193,6 @@ static char *expand_vars(char *str)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
f--;
|
||||
}
|
||||
*t++ = *f++;
|
||||
bufsize--;
|
||||
@@ -510,6 +210,8 @@ static char *expand_vars(char *str)
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Each "char* foo" has an associated "BOOL foo_EXP" that tracks if the string has been expanded yet or not. */
|
||||
|
||||
/* NOTE: use this function and all the FN_{GLOBAL,LOCAL} ones WITHOUT a trailing semicolon! */
|
||||
#define RETURN_EXPANDED(val) {if (!val ## _EXP) {val = expand_vars(val); val ## _EXP = True;} return val ? val : "";}
|
||||
|
||||
@@ -534,65 +236,24 @@ static char *expand_vars(char *str)
|
||||
#define FN_LOCAL_INTEGER(fn_name, val) \
|
||||
int fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.val;}
|
||||
|
||||
FN_GLOBAL_STRING(lp_bind_address, bind_address)
|
||||
FN_GLOBAL_STRING(lp_daemon_chroot, daemon_chroot)
|
||||
FN_GLOBAL_STRING(lp_daemon_gid, daemon_gid)
|
||||
FN_GLOBAL_STRING(lp_daemon_uid, daemon_uid)
|
||||
FN_GLOBAL_STRING(lp_motd_file, motd_file)
|
||||
FN_GLOBAL_STRING(lp_pid_file, pid_file)
|
||||
FN_GLOBAL_STRING(lp_socket_options, socket_options)
|
||||
/* The following include file contains:
|
||||
*
|
||||
* typedef global_vars - describes global (ie., server-wide) parameters.
|
||||
* typedef local_vars - describes a single section.
|
||||
* typedef all_vars - a combination of global_vars & local_vars.
|
||||
* all_vars Defaults - the default values for all the variables.
|
||||
* all_vars Vars - the currently configured values for all the variables.
|
||||
* struct parm_struct parm_table - the strings & variables for the parser.
|
||||
* FN_{LOCAL,GLOBAL}_{TYPE}() definition for all the lp_var_name() accessors.
|
||||
*/
|
||||
|
||||
FN_GLOBAL_INTEGER(lp_listen_backlog, listen_backlog)
|
||||
FN_GLOBAL_INTEGER(lp_rsync_port, rsync_port)
|
||||
#include "daemon-parm.h"
|
||||
|
||||
FN_GLOBAL_BOOL(lp_proxy_protocol, proxy_protocol)
|
||||
|
||||
FN_LOCAL_STRING(lp_auth_users, auth_users)
|
||||
FN_LOCAL_STRING(lp_charset, charset)
|
||||
FN_LOCAL_STRING(lp_comment, comment)
|
||||
FN_LOCAL_STRING(lp_dont_compress, dont_compress)
|
||||
FN_LOCAL_STRING(lp_early_exec, early_exec)
|
||||
FN_LOCAL_STRING(lp_exclude, exclude)
|
||||
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
|
||||
FN_LOCAL_STRING(lp_filter, filter)
|
||||
FN_LOCAL_STRING(lp_gid, gid)
|
||||
FN_LOCAL_STRING(lp_hosts_allow, hosts_allow)
|
||||
FN_LOCAL_STRING(lp_hosts_deny, hosts_deny)
|
||||
FN_LOCAL_STRING(lp_include, include)
|
||||
FN_LOCAL_STRING(lp_include_from, include_from)
|
||||
FN_LOCAL_STRING(lp_incoming_chmod, incoming_chmod)
|
||||
FN_LOCAL_STRING(lp_lock_file, lock_file)
|
||||
FN_LOCAL_STRING(lp_log_file, log_file)
|
||||
FN_LOCAL_STRING(lp_log_format, log_format)
|
||||
FN_LOCAL_STRING(lp_name, name)
|
||||
FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
|
||||
FN_LOCAL_STRING(lp_path, path)
|
||||
FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
|
||||
FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
|
||||
FN_LOCAL_STRING(lp_refuse_options, refuse_options)
|
||||
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
|
||||
FN_LOCAL_STRING(lp_syslog_tag, syslog_tag)
|
||||
FN_LOCAL_STRING(lp_temp_dir, temp_dir)
|
||||
FN_LOCAL_STRING(lp_uid, uid)
|
||||
|
||||
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
|
||||
FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
|
||||
FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility)
|
||||
FN_LOCAL_INTEGER(lp_timeout, timeout)
|
||||
|
||||
FN_LOCAL_BOOL(lp_fake_super, fake_super)
|
||||
FN_LOCAL_BOOL(lp_forward_lookup, forward_lookup)
|
||||
FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
|
||||
FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
|
||||
FN_LOCAL_BOOL(lp_list, list)
|
||||
FN_LOCAL_BOOL(lp_munge_symlinks, munge_symlinks)
|
||||
FN_LOCAL_BOOL(lp_numeric_ids, numeric_ids)
|
||||
FN_LOCAL_BOOL(lp_read_only, read_only)
|
||||
FN_LOCAL_BOOL(lp_reverse_lookup, reverse_lookup)
|
||||
FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
|
||||
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
|
||||
FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
|
||||
FN_LOCAL_BOOL(lp_write_only, write_only)
|
||||
/* Initialise the Default all_vars structure. */
|
||||
void reset_daemon_vars(void)
|
||||
{
|
||||
memcpy(&Vars, &Defaults, sizeof Vars);
|
||||
}
|
||||
|
||||
/* Assign a copy of v to *s. Handles NULL strings. We don't worry
|
||||
* about overwriting a malloc'd string because the long-running
|
||||
@@ -601,10 +262,7 @@ FN_LOCAL_BOOL(lp_write_only, write_only)
|
||||
* the start, so any lost memory is inconsequential. */
|
||||
static inline void string_set(char **s, const char *v)
|
||||
{
|
||||
if (!v)
|
||||
*s = NULL;
|
||||
else if (!(*s = strdup(v)))
|
||||
out_of_memory("string_set");
|
||||
*s = v ? strdup(v) : NULL;
|
||||
}
|
||||
|
||||
/* Copy local_vars into a new section. No need to strdup since we don't free. */
|
||||
@@ -620,19 +278,14 @@ static void init_section(local_vars *psection)
|
||||
copy_section(psection, &Vars.l);
|
||||
}
|
||||
|
||||
/* Do a case-insensitive, whitespace-ignoring string compare. */
|
||||
static int strwicmp(char *psz1, char *psz2)
|
||||
/* Do a case-insensitive, whitespace-ignoring string equality check. */
|
||||
static int strwiEQ(char *psz1, char *psz2)
|
||||
{
|
||||
/* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
|
||||
/* appropriate value. */
|
||||
/* If one or both strings are NULL, we return equality right away. */
|
||||
if (psz1 == psz2)
|
||||
return 0;
|
||||
|
||||
if (psz1 == NULL)
|
||||
return -1;
|
||||
|
||||
if (psz2 == NULL)
|
||||
return 1;
|
||||
if (psz1 == NULL || psz2 == NULL)
|
||||
return 0;
|
||||
|
||||
/* sync the strings on first non-whitespace */
|
||||
while (1) {
|
||||
@@ -640,12 +293,14 @@ static int strwicmp(char *psz1, char *psz2)
|
||||
psz1++;
|
||||
while (isSpace(psz2))
|
||||
psz2++;
|
||||
if (toUpper(psz1) != toUpper(psz2) || *psz1 == '\0' || *psz2 == '\0')
|
||||
if (*psz1 == '\0' || *psz2 == '\0')
|
||||
break;
|
||||
if (toUpper(psz1) != toUpper(psz2))
|
||||
break;
|
||||
psz1++;
|
||||
psz2++;
|
||||
}
|
||||
return *psz1 - *psz2;
|
||||
return *psz1 == *psz2;
|
||||
}
|
||||
|
||||
/* Find a section by name. Otherwise works like get_section. */
|
||||
@@ -654,7 +309,7 @@ static int getsectionbyname(char *name)
|
||||
int i;
|
||||
|
||||
for (i = section_list.count - 1; i >= 0; i--) {
|
||||
if (strwicmp(iSECTION(i).name, name) == 0)
|
||||
if (strwiEQ(iSECTION(i).name, name))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -694,7 +349,7 @@ static int map_parameter(char *parmname)
|
||||
return -1;
|
||||
|
||||
for (iIndex = 0; parm_table[iIndex].label; iIndex++) {
|
||||
if (strwicmp(parm_table[iIndex].label, parmname) == 0)
|
||||
if (strwiEQ(parm_table[iIndex].label, parmname))
|
||||
return iIndex;
|
||||
}
|
||||
|
||||
@@ -705,16 +360,14 @@ static int map_parameter(char *parmname)
|
||||
/* Set a boolean variable from the text value stored in the passed string.
|
||||
* Returns True in success, False if the passed string does not correctly
|
||||
* represent a boolean. */
|
||||
static BOOL set_boolean(BOOL *pb, char *parmvalue)
|
||||
static BOOL set_boolean(BOOL *pb, char *parmvalue, int allow_unset)
|
||||
{
|
||||
if (strwicmp(parmvalue, "yes") == 0
|
||||
|| strwicmp(parmvalue, "true") == 0
|
||||
|| strwicmp(parmvalue, "1") == 0)
|
||||
if (strwiEQ(parmvalue, "yes") || strwiEQ(parmvalue, "true") || strwiEQ(parmvalue, "1"))
|
||||
*pb = True;
|
||||
else if (strwicmp(parmvalue, "no") == 0
|
||||
|| strwicmp(parmvalue, "False") == 0
|
||||
|| strwicmp(parmvalue, "0") == 0)
|
||||
else if (strwiEQ(parmvalue, "no") || strwiEQ(parmvalue, "false") || strwiEQ(parmvalue, "0"))
|
||||
*pb = False;
|
||||
else if (allow_unset && (strwiEQ(parmvalue, "unset") || strwiEQ(parmvalue, "-1")))
|
||||
*pb = Unset;
|
||||
else {
|
||||
rprintf(FLOG, "Badly formed boolean in configuration file: \"%s\".\n", parmvalue);
|
||||
return False;
|
||||
@@ -763,11 +416,15 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
|
||||
|
||||
switch (parm_table[parmnum].type) {
|
||||
case P_BOOL:
|
||||
set_boolean(parm_ptr, parmvalue);
|
||||
set_boolean(parm_ptr, parmvalue, False);
|
||||
break;
|
||||
|
||||
case P_BOOL3:
|
||||
set_boolean(parm_ptr, parmvalue, True);
|
||||
break;
|
||||
|
||||
case P_BOOLREV:
|
||||
set_boolean(parm_ptr, parmvalue);
|
||||
set_boolean(parm_ptr, parmvalue, False);
|
||||
*(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
|
||||
break;
|
||||
|
||||
@@ -837,7 +494,7 @@ static BOOL do_section(char *sectionname)
|
||||
return True;
|
||||
}
|
||||
|
||||
isglobal = strwicmp(sectionname, GLOBAL_NAME) == 0;
|
||||
isglobal = strwiEQ(sectionname, GLOBAL_NAME);
|
||||
|
||||
/* At the end of the global section, add any --dparam items. */
|
||||
if (bInGlobalSection && !isglobal) {
|
||||
|
||||
25
log.c
25
log.c
@@ -251,7 +251,7 @@ static void filtered_fwrite(FILE *f, const char *in_buf, int in_len, int use_isp
|
||||
void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||
{
|
||||
char trailing_CR_or_NL;
|
||||
FILE *f = msgs2stderr ? stderr : stdout;
|
||||
FILE *f = msgs2stderr == 1 ? stderr : stdout;
|
||||
#ifdef ICONV_OPTION
|
||||
iconv_t ic = is_utf8 && ic_recv != (iconv_t)-1 ? ic_recv : ic_chck;
|
||||
#else
|
||||
@@ -263,7 +263,7 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||
if (len < 0)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
|
||||
if (msgs2stderr) {
|
||||
if (msgs2stderr == 1) {
|
||||
/* A normal daemon can get msgs2stderr set if the socket is busted, so we
|
||||
* change the message destination into an FLOG message in order to try to
|
||||
* get some info about an abnormal-exit into the log file. An rsh daemon
|
||||
@@ -327,7 +327,7 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
|
||||
if (am_server && !msgs2stderr) {
|
||||
if (am_server && msgs2stderr != 1 && (msgs2stderr != 2 || f != stderr)) {
|
||||
enum msgcode msg = (enum msgcode)code;
|
||||
if (protocol_version < 30) {
|
||||
if (msg == MSG_ERROR)
|
||||
@@ -350,8 +350,7 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||
output_needs_newline = 0;
|
||||
}
|
||||
|
||||
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
|
||||
? buf[--len] : 0;
|
||||
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r') ? buf[--len] : '\0';
|
||||
|
||||
if (len && buf[0] == '\r') {
|
||||
fputc('\r', f);
|
||||
@@ -372,7 +371,12 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||
iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT);
|
||||
ierrno = errno;
|
||||
if (outbuf.len) {
|
||||
filtered_fwrite(f, convbuf, outbuf.len, 0, 0);
|
||||
char trailing = inbuf.len ? '\0' : trailing_CR_or_NL;
|
||||
filtered_fwrite(f, convbuf, outbuf.len, 0, trailing);
|
||||
if (trailing) {
|
||||
trailing_CR_or_NL = '\0';
|
||||
fflush(f);
|
||||
}
|
||||
outbuf.len = 0;
|
||||
}
|
||||
/* Log one byte of illegal/incomplete sequence and continue with
|
||||
@@ -716,8 +720,9 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
|
||||
c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
|
||||
c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
|
||||
c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
|
||||
c[8] = !(iflags & ITEM_REPORT_ATIME) ? '.'
|
||||
: S_ISLNK(file->mode) ? 'U' : 'u';
|
||||
c[8] = !(iflags & (ITEM_REPORT_ATIME|ITEM_REPORT_CRTIME)) ? '.'
|
||||
: BITS_SET(iflags, ITEM_REPORT_ATIME|ITEM_REPORT_CRTIME) ? 'b'
|
||||
: iflags & ITEM_REPORT_ATIME ? 'u' : 'n';
|
||||
c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a';
|
||||
c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x';
|
||||
c[11] = '\0';
|
||||
@@ -886,10 +891,10 @@ void log_exit(int code, const char *file, int line)
|
||||
/* VANISHED is not an error, only a warning */
|
||||
if (code == RERR_VANISHED) {
|
||||
rprintf(FWARNING, "rsync warning: %s (code %d) at %s(%d) [%s=%s]\n",
|
||||
name, code, file, line, who_am_i(), RSYNC_VERSION);
|
||||
name, code, src_file(file), line, who_am_i(), rsync_version());
|
||||
} else {
|
||||
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s=%s]\n",
|
||||
name, code, file, line, who_am_i(), RSYNC_VERSION);
|
||||
name, code, src_file(file), line, who_am_i(), rsync_version());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
123
main.c
123
main.c
@@ -22,11 +22,15 @@
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
#include "ifuncs.h"
|
||||
#include "io.h"
|
||||
#if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#include <popt.h>
|
||||
#ifdef __TANDEM
|
||||
#include <floss.h(floss_execlp)>
|
||||
#endif
|
||||
|
||||
extern int dry_run;
|
||||
extern int list_only;
|
||||
@@ -53,6 +57,7 @@ extern int copy_unsafe_links;
|
||||
extern int keep_dirlinks;
|
||||
extern int preserve_hard_links;
|
||||
extern int protocol_version;
|
||||
extern int mkpath_dest_arg;
|
||||
extern int file_total;
|
||||
extern int recurse;
|
||||
extern int xfer_dirs;
|
||||
@@ -92,6 +97,7 @@ extern char *shell_cmd;
|
||||
extern char *password_file;
|
||||
extern char *backup_dir;
|
||||
extern char *copy_as;
|
||||
extern char *tmpdir;
|
||||
extern char curr_dir[MAXPATHLEN];
|
||||
extern char backup_dir_buf[MAXPATHLEN];
|
||||
extern char *basis_dir[MAX_BASIS_DIRS+1];
|
||||
@@ -103,7 +109,7 @@ gid_t our_gid;
|
||||
int am_receiver = 0; /* Only set to 1 after the receiver/generator fork. */
|
||||
int am_generator = 0; /* Only set to 1 after the receiver/generator fork. */
|
||||
int local_server = 0;
|
||||
int daemon_over_rsh = 0;
|
||||
int daemon_connection = 0; /* 0 = no daemon, 1 = daemon via remote shell, -1 = daemon via socket */
|
||||
mode_t orig_umask = 0;
|
||||
int batch_gen_fd = -1;
|
||||
int sender_keeps_checksum = 0;
|
||||
@@ -298,7 +304,7 @@ static void become_copy_as_user()
|
||||
|
||||
our_uid = MY_UID();
|
||||
our_gid = MY_GID();
|
||||
am_root = (our_uid == 0);
|
||||
am_root = (our_uid == ROOT_UID);
|
||||
|
||||
if (gname)
|
||||
gname[-1] = ':';
|
||||
@@ -512,8 +518,6 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
if (!cmd)
|
||||
cmd = RSYNC_RSH;
|
||||
cmd = need_to_free = strdup(cmd);
|
||||
if (!cmd)
|
||||
goto oom;
|
||||
|
||||
for (t = f = cmd; *f; f++) {
|
||||
if (*f == ' ')
|
||||
@@ -563,12 +567,12 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
#ifdef HAVE_REMSH
|
||||
/* remsh (on HPUX) takes the arguments the other way around */
|
||||
args[argc++] = machine;
|
||||
if (user && !(daemon_over_rsh && dash_l_set)) {
|
||||
if (user && !(daemon_connection && dash_l_set)) {
|
||||
args[argc++] = "-l";
|
||||
args[argc++] = user;
|
||||
}
|
||||
#else
|
||||
if (user && !(daemon_over_rsh && dash_l_set)) {
|
||||
if (user && !(daemon_connection && dash_l_set)) {
|
||||
args[argc++] = "-l";
|
||||
args[argc++] = user;
|
||||
}
|
||||
@@ -588,7 +592,11 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
if (blocking_io < 0 && (strcmp(t, "rsh") == 0 || strcmp(t, "remsh") == 0))
|
||||
blocking_io = 1;
|
||||
|
||||
server_options(args, &argc);
|
||||
if (daemon_connection > 0) {
|
||||
args[argc++] = "--server";
|
||||
args[argc++] = "--daemon";
|
||||
} else
|
||||
server_options(args, &argc);
|
||||
|
||||
if (argc >= MAX_ARGS - 2)
|
||||
goto arg_overflow;
|
||||
@@ -596,7 +604,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
|
||||
args[argc++] = ".";
|
||||
|
||||
if (!daemon_over_rsh) {
|
||||
if (!daemon_connection) {
|
||||
while (remote_argc > 0) {
|
||||
if (argc >= MAX_ARGS - 1) {
|
||||
arg_overflow:
|
||||
@@ -649,7 +657,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
#ifdef ICONV_CONST
|
||||
setup_iconv();
|
||||
#endif
|
||||
if (protect_args && !daemon_over_rsh)
|
||||
if (protect_args && !daemon_connection)
|
||||
send_protected_args(*f_out_p, args);
|
||||
}
|
||||
|
||||
@@ -657,10 +665,6 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
free(need_to_free);
|
||||
|
||||
return pid;
|
||||
|
||||
oom:
|
||||
out_of_memory("do_cmd");
|
||||
return 0; /* not reached */
|
||||
}
|
||||
|
||||
/* The receiving side operates in one of two modes:
|
||||
@@ -679,7 +683,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
int statret;
|
||||
int statret, trailing_slash;
|
||||
char *cp;
|
||||
|
||||
if (DEBUG_GTE(RECV, 1)) {
|
||||
@@ -712,7 +716,26 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
}
|
||||
|
||||
/* See what currently exists at the destination. */
|
||||
if ((statret = do_stat(dest_path, &st)) == 0) {
|
||||
statret = do_stat(dest_path, &st);
|
||||
cp = strrchr(dest_path, '/');
|
||||
trailing_slash = cp && !cp[1];
|
||||
|
||||
if (mkpath_dest_arg && statret < 0 && (cp || file_total > 1)) {
|
||||
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 (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)
|
||||
statret = do_stat(dest_path, &st);
|
||||
}
|
||||
|
||||
if (statret == 0) {
|
||||
/* If the destination is a dir, enter it and use mode 1. */
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (!change_dir(dest_path, CD_NORMAL)) {
|
||||
@@ -742,15 +765,12 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
|
||||
cp = strrchr(dest_path, '/');
|
||||
|
||||
/* If we need a destination directory because the transfer is not
|
||||
* of a single non-directory or the user has requested one via a
|
||||
* destination path ending in a slash, create one and use mode 1. */
|
||||
if (file_total > 1 || (cp && !cp[1])) {
|
||||
/* Lop off the final slash (if any). */
|
||||
if (cp && !cp[1])
|
||||
*cp = '\0';
|
||||
if (file_total > 1 || trailing_slash) {
|
||||
if (trailing_slash)
|
||||
*cp = '\0'; /* Lop off the final slash (if any). */
|
||||
|
||||
if (statret == 0) {
|
||||
rprintf(FERROR, "ERROR: destination path is not a directory\n");
|
||||
@@ -758,6 +778,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
}
|
||||
|
||||
if (do_mkdir(dest_path, ACCESSPERMS) != 0) {
|
||||
mkdir_error:
|
||||
rsyserr(FERROR, errno, "mkdir %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
@@ -824,8 +845,6 @@ static void check_alt_basis_dirs(void)
|
||||
if (dry_run > 1 && *bdir != '/') {
|
||||
int len = curr_dir_len + 1 + bd_len + 1;
|
||||
char *new = new_array(char, len);
|
||||
if (!new)
|
||||
out_of_memory("check_alt_basis_dirs");
|
||||
if (slash && strncmp(bdir, "../", 3) == 0) {
|
||||
/* We want to remove only one leading "../" prefix for
|
||||
* the directory we couldn't create in dry-run mode:
|
||||
@@ -984,6 +1003,23 @@ static int do_recv(int f_in, int f_out, char *local_name)
|
||||
backup_dir_buf[backup_dir_len-1] = '/';
|
||||
}
|
||||
|
||||
if (tmpdir) {
|
||||
STRUCT_STAT st;
|
||||
int ret = do_stat(tmpdir, &st);
|
||||
if (ret < 0 || !S_ISDIR(st.st_mode)) {
|
||||
if (ret == 0) {
|
||||
rprintf(FERROR, "The temp-dir is not a directory: %s\n", tmpdir);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if (errno == ENOENT) {
|
||||
rprintf(FERROR, "The temp-dir does not exist: %s\n", tmpdir);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
rprintf(FERROR, "Failed to stat temp-dir %s: %s\n", tmpdir, strerror(errno));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
}
|
||||
|
||||
io_flush(FULL_FLUSH);
|
||||
|
||||
if ((pid = do_fork()) == -1) {
|
||||
@@ -1090,7 +1126,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
|
||||
char *local_name = NULL;
|
||||
int negated_levels;
|
||||
|
||||
if (filesfrom_fd >= 0 && !msgs2stderr && protocol_version < 31) {
|
||||
if (filesfrom_fd >= 0 && msgs2stderr != 1 && protocol_version < 31) {
|
||||
/* We can't mix messages with files-from data on the socket,
|
||||
* so temporarily turn off info/debug messages. */
|
||||
negate_output_levels();
|
||||
@@ -1339,19 +1375,12 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
return MAX(exit_code, exit_code2);
|
||||
}
|
||||
|
||||
static int copy_argv(char *argv[])
|
||||
static void dup_argv(char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; argv[i]; i++) {
|
||||
if (!(argv[i] = strdup(argv[i]))) {
|
||||
rprintf (FERROR, "out of memory at %s(%d)\n",
|
||||
__FILE__, __LINE__);
|
||||
return RERR_MALLOC;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
for (i = 0; argv[i]; i++)
|
||||
argv[i] = strdup(argv[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1372,8 +1401,7 @@ static int start_client(int argc, char *argv[])
|
||||
|
||||
/* Don't clobber argv[] so that ps(1) can still show the right
|
||||
* command line. */
|
||||
if ((ret = copy_argv(argv)) != 0)
|
||||
return ret;
|
||||
dup_argv(argv);
|
||||
|
||||
if (!read_batch) { /* for read_batch, NO source is specified */
|
||||
char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
|
||||
@@ -1401,7 +1429,7 @@ static int start_client(int argc, char *argv[])
|
||||
}
|
||||
am_sender = 0;
|
||||
if (rsync_port)
|
||||
daemon_over_rsh = shell_cmd ? 1 : -1;
|
||||
daemon_connection = shell_cmd ? 1 : -1;
|
||||
} else { /* source is local, check dest arg */
|
||||
am_sender = 1;
|
||||
|
||||
@@ -1433,7 +1461,7 @@ static int start_client(int argc, char *argv[])
|
||||
} else { /* hostspec was found, so dest is remote */
|
||||
argv[argc] = path;
|
||||
if (rsync_port)
|
||||
daemon_over_rsh = shell_cmd ? 1 : -1;
|
||||
daemon_connection = shell_cmd ? 1 : -1;
|
||||
}
|
||||
}
|
||||
} else { /* read_batch */
|
||||
@@ -1454,8 +1482,15 @@ static int start_client(int argc, char *argv[])
|
||||
char *dummy_host;
|
||||
int dummy_port = rsync_port;
|
||||
int i;
|
||||
if (!argv[0][0])
|
||||
goto invalid_empty;
|
||||
/* For local source, extra source args must not have hostspec. */
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!argv[i][0]) {
|
||||
invalid_empty:
|
||||
rprintf(FERROR, "Empty source arg specified.\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if (check_for_hostspec(argv[i], &dummy_host, &dummy_port)) {
|
||||
rprintf(FERROR, "Unexpected remote arg: %s\n", argv[i]);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
@@ -1496,10 +1531,10 @@ static int start_client(int argc, char *argv[])
|
||||
else
|
||||
env_port = rsync_port;
|
||||
|
||||
if (daemon_over_rsh < 0)
|
||||
if (daemon_connection < 0)
|
||||
return start_socket_client(shell_machine, remote_argc, remote_argv, argc, argv);
|
||||
|
||||
if (password_file && !daemon_over_rsh) {
|
||||
if (password_file && !daemon_connection) {
|
||||
rprintf(FERROR, "The --password-file option may only be "
|
||||
"used when accessing an rsync daemon.\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
@@ -1527,7 +1562,7 @@ static int start_client(int argc, char *argv[])
|
||||
}
|
||||
|
||||
#ifdef HAVE_PUTENV
|
||||
if (daemon_over_rsh)
|
||||
if (daemon_connection)
|
||||
set_env_num("RSYNC_PORT", env_port);
|
||||
#endif
|
||||
|
||||
@@ -1535,7 +1570,7 @@ static int start_client(int argc, char *argv[])
|
||||
|
||||
/* if we're running an rsync server on the remote host over a
|
||||
* remote shell command, we need to do the RSYNCD protocol first */
|
||||
if (daemon_over_rsh) {
|
||||
if (daemon_connection) {
|
||||
int tmpret;
|
||||
tmpret = start_inband_exchange(f_in, f_out, shell_user, remote_argc, remote_argv);
|
||||
if (tmpret < 0)
|
||||
@@ -1567,11 +1602,13 @@ static void sigusr2_handler(UNUSED(int val))
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
#if defined SIGINFO || defined SIGVTALRM
|
||||
static void siginfo_handler(UNUSED(int val))
|
||||
{
|
||||
if (!am_server && !INFO_GTE(PROGRESS, 1))
|
||||
want_progress_now = True;
|
||||
}
|
||||
#endif
|
||||
|
||||
void remember_children(UNUSED(int val))
|
||||
{
|
||||
@@ -1682,7 +1719,7 @@ int main(int argc,char *argv[])
|
||||
starttime = time(NULL);
|
||||
our_uid = MY_UID();
|
||||
our_gid = MY_GID();
|
||||
am_root = our_uid == 0;
|
||||
am_root = our_uid == ROOT_UID;
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
|
||||
|
||||
2
match.c
2
match.c
@@ -65,8 +65,6 @@ static void build_hash_table(struct sum_struct *s)
|
||||
if (hash_table)
|
||||
free(hash_table);
|
||||
hash_table = new_array(int32, tablesize);
|
||||
if (!hash_table)
|
||||
out_of_memory("build_hash_table");
|
||||
alloc_size = tablesize;
|
||||
}
|
||||
|
||||
|
||||
15
md2man
15
md2man
@@ -93,7 +93,7 @@ def main():
|
||||
env_subs['VERSION'] = '1.0.0'
|
||||
env_subs['libdir'] = '/usr'
|
||||
else:
|
||||
for fn in (fi.srcdir + 'NEWS.md', 'Makefile'):
|
||||
for fn in (fi.srcdir + 'version.h', 'Makefile'):
|
||||
try:
|
||||
st = os.lstat(fn)
|
||||
except:
|
||||
@@ -101,6 +101,11 @@ def main():
|
||||
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)
|
||||
@@ -112,7 +117,7 @@ def main():
|
||||
while re.search(r'\$\{', val):
|
||||
val = re.sub(r'\$\{(\w+)\}', lambda m: env_subs[m.group(1)], val)
|
||||
env_subs[var] = val
|
||||
if var == 'VERSION':
|
||||
if var == 'srcdir':
|
||||
break
|
||||
|
||||
with open(fi.fn, 'r', encoding='utf-8') as fh:
|
||||
@@ -139,10 +144,6 @@ def main():
|
||||
fh.write(txt)
|
||||
|
||||
|
||||
def html_via_cmarkgfm(txt):
|
||||
return cmarkgfm.markdown_to_html(txt)
|
||||
|
||||
|
||||
def html_via_commonmark(txt):
|
||||
return commonmark.HtmlRenderer().render(commonmark.Parser().parse(txt))
|
||||
|
||||
@@ -371,7 +372,7 @@ if __name__ == '__main__':
|
||||
|
||||
try:
|
||||
import cmarkgfm
|
||||
md_parser = html_via_cmarkgfm
|
||||
md_parser = cmarkgfm.markdown_to_html
|
||||
except:
|
||||
try:
|
||||
import commonmark
|
||||
|
||||
11
mkgitver
Executable file
11
mkgitver
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/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
|
||||
fi
|
||||
echo "#define RSYNC_GITVER $gitver" >git-version.h
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
BEGIN {
|
||||
while ((getline i < "proto.h") > 0) old_protos = old_protos ? old_protos "\n" i : i
|
||||
close("proto.h")
|
||||
protos = "/* This file is automatically generated with \"make proto\". DO NOT EDIT */\n"
|
||||
}
|
||||
|
||||
@@ -35,5 +36,5 @@ inheader {
|
||||
|
||||
END {
|
||||
if (old_protos != protos) print protos > "proto.h"
|
||||
printf "" > "proto.h-tstamp"
|
||||
system("touch proto.h-tstamp")
|
||||
}
|
||||
|
||||
632
options.c
632
options.c
@@ -21,16 +21,13 @@
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#include "latest-year.h"
|
||||
#include "ifuncs.h"
|
||||
#include <popt.h>
|
||||
|
||||
extern int module_id;
|
||||
extern int local_server;
|
||||
extern int sanitize_paths;
|
||||
extern int daemon_over_rsh;
|
||||
extern unsigned int module_dirlen;
|
||||
extern struct name_num_obj valid_checksums;
|
||||
extern struct name_num_obj valid_compressions;
|
||||
extern filter_rule_list filter_list;
|
||||
extern filter_rule_list daemon_filter_list;
|
||||
|
||||
@@ -63,6 +60,7 @@ int preserve_uid = 0;
|
||||
int preserve_gid = 0;
|
||||
int preserve_times = 0;
|
||||
int preserve_atimes = 0;
|
||||
int preserve_crtimes = 0;
|
||||
int update_only = 0;
|
||||
int open_noatime = 0;
|
||||
int cvs_exclude = 0;
|
||||
@@ -89,7 +87,7 @@ int relative_paths = -1;
|
||||
int implied_dirs = 1;
|
||||
int missing_args = 0; /* 0 = FERROR_XFER, 1 = ignore, 2 = delete */
|
||||
int numeric_ids = 0;
|
||||
int msgs2stderr = 0;
|
||||
int msgs2stderr = 2; /* Default: send errors to stderr for local & remote-shell transfers */
|
||||
int allow_8bit_chars = 0;
|
||||
int force_delete = 0;
|
||||
int io_timeout = 0;
|
||||
@@ -102,6 +100,7 @@ int eol_nulls = 0;
|
||||
int protect_args = -1;
|
||||
int human_readable = 1;
|
||||
int recurse = 0;
|
||||
int mkpath_dest_arg = 0;
|
||||
int allow_inc_recurse = 1;
|
||||
int xfer_dirs = -1;
|
||||
int am_daemon = 0;
|
||||
@@ -127,7 +126,8 @@ int blocking_io = -1;
|
||||
int checksum_seed = 0;
|
||||
int inplace = 0;
|
||||
int delay_updates = 0;
|
||||
long block_size = 0; /* "long" because popt can't set an int32. */
|
||||
int32 block_size = 0;
|
||||
time_t stop_at_utime = 0;
|
||||
char *skip_compress = NULL;
|
||||
char *copy_as = NULL;
|
||||
item_list dparam_list = EMPTY_ITEM_LIST;
|
||||
@@ -181,6 +181,10 @@ int rsync_port = 0;
|
||||
int alt_dest_type = 0;
|
||||
int basis_dir_cnt = 0;
|
||||
|
||||
#define DEFAULT_MAX_ALLOC (1024L * 1024 * 1024)
|
||||
size_t max_alloc = DEFAULT_MAX_ALLOC;
|
||||
char *max_alloc_arg;
|
||||
|
||||
static int version_opt_cnt = 0;
|
||||
static int remote_option_alloc = 0;
|
||||
int remote_option_cnt = 0;
|
||||
@@ -188,10 +192,6 @@ const char **remote_options = NULL;
|
||||
const char *checksum_choice = NULL;
|
||||
const char *compress_choice = NULL;
|
||||
|
||||
#ifndef __APPLE__ /* Do we need a configure check for this? */
|
||||
#define SUPPORT_ATIMES 1
|
||||
#endif
|
||||
|
||||
int quiet = 0;
|
||||
int output_motd = 1;
|
||||
int log_before_transfer = 0;
|
||||
@@ -382,8 +382,7 @@ static char *make_output_option(struct output_struct *words, short *levels, ucha
|
||||
return NULL;
|
||||
|
||||
len++;
|
||||
if (!(buf = new_array(char, len)))
|
||||
out_of_memory("make_output_option");
|
||||
buf = new_array(char, len);
|
||||
pos = 0;
|
||||
|
||||
if (skipped || max < 5)
|
||||
@@ -569,218 +568,14 @@ void negate_output_levels(void)
|
||||
debug_levels[j] *= -1;
|
||||
}
|
||||
|
||||
static char *istring(const char *fmt, int val)
|
||||
{
|
||||
char *str;
|
||||
if (asprintf(&str, fmt, val) < 0)
|
||||
out_of_memory("istring");
|
||||
return str;
|
||||
}
|
||||
|
||||
static void print_capabilities(enum logcode f)
|
||||
{
|
||||
STRUCT_STAT *dumstat;
|
||||
char line_buf[75];
|
||||
int line_len, j;
|
||||
char *capabilities[] = {
|
||||
istring("%d-bit files", (int)(sizeof (OFF_T) * 8)),
|
||||
istring("%d-bit inums", (int)(sizeof dumstat->st_ino * 8)), /* Don't check ino_t! */
|
||||
istring("%d-bit timestamps", (int)(sizeof (time_t) * 8)),
|
||||
istring("%d-bit long ints", (int)(sizeof (int64) * 8)),
|
||||
|
||||
#ifndef HAVE_SOCKETPAIR
|
||||
"no "
|
||||
#endif
|
||||
"socketpairs",
|
||||
|
||||
#ifndef SUPPORT_HARD_LINKS
|
||||
"no "
|
||||
#endif
|
||||
"hardlinks",
|
||||
|
||||
#ifndef SUPPORT_LINKS
|
||||
"no "
|
||||
#endif
|
||||
"symlinks",
|
||||
|
||||
#ifndef INET6
|
||||
"no "
|
||||
#endif
|
||||
"IPv6",
|
||||
|
||||
#ifndef SUPPORT_ATIMES
|
||||
"no "
|
||||
#endif
|
||||
"atimes",
|
||||
|
||||
"batchfiles",
|
||||
|
||||
#ifndef HAVE_FTRUNCATE
|
||||
"no "
|
||||
#endif
|
||||
"inplace",
|
||||
|
||||
#ifndef HAVE_FTRUNCATE
|
||||
"no "
|
||||
#endif
|
||||
"append",
|
||||
|
||||
#ifndef SUPPORT_ACLS
|
||||
"no "
|
||||
#endif
|
||||
"ACLs",
|
||||
|
||||
#ifndef SUPPORT_XATTRS
|
||||
"no "
|
||||
#endif
|
||||
"xattrs",
|
||||
|
||||
#ifdef RSYNC_USE_PROTECTED_ARGS
|
||||
"default "
|
||||
#else
|
||||
"optional "
|
||||
#endif
|
||||
"protect-args",
|
||||
|
||||
#ifndef ICONV_OPTION
|
||||
"no "
|
||||
#endif
|
||||
"iconv",
|
||||
|
||||
#ifndef CAN_SET_SYMLINK_TIMES
|
||||
"no "
|
||||
#endif
|
||||
"symtimes",
|
||||
|
||||
#ifndef SUPPORT_PREALLOCATION
|
||||
"no "
|
||||
#endif
|
||||
"prealloc",
|
||||
|
||||
"*" /* All options after this point are hidden w/o -V -V */
|
||||
#ifndef HAVE_SIMD
|
||||
"no "
|
||||
#endif
|
||||
"SIMD",
|
||||
|
||||
#ifndef HAVE_ASM
|
||||
"no "
|
||||
#endif
|
||||
"asm",
|
||||
|
||||
#ifndef USE_OPENSSL
|
||||
"no "
|
||||
#endif
|
||||
"openssl-crypto",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
for (line_len = 0, j = 0; ; j++) {
|
||||
char *cap = capabilities[j];
|
||||
if (!cap)
|
||||
break;
|
||||
if (*cap == '*') {
|
||||
if (version_opt_cnt >= 2)
|
||||
capabilities[j]++;
|
||||
else
|
||||
capabilities[j] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (line_len = 0, j = 0; ; j++) {
|
||||
char *cap = capabilities[j];
|
||||
int cap_len = cap ? strlen(cap) : 1000;
|
||||
int need_comma = cap && capabilities[j+1] != NULL ? 1 : 0;
|
||||
if (line_len + 1 + cap_len + need_comma >= (int)sizeof line_buf) {
|
||||
rprintf(f, " %s\n", line_buf);
|
||||
line_len = 0;
|
||||
}
|
||||
if (!cap)
|
||||
break;
|
||||
line_len += snprintf(line_buf+line_len, sizeof line_buf - line_len, " %s%s", cap, need_comma ? "," : "");
|
||||
}
|
||||
}
|
||||
|
||||
static void print_rsync_version(enum logcode f)
|
||||
{
|
||||
char tmpbuf[256], *subprotocol = "";
|
||||
|
||||
#if SUBPROTOCOL_VERSION != 0
|
||||
subprotocol = istring(".PR%d", SUBPROTOCOL_VERSION);
|
||||
#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, "Capabilities:\n");
|
||||
print_capabilities(f);
|
||||
|
||||
rprintf(f, "Checksum list:\n");
|
||||
get_default_nno_list(&valid_checksums, tmpbuf, sizeof tmpbuf, '(');
|
||||
rprintf(f, " %s\n", tmpbuf);
|
||||
|
||||
rprintf(f, "Compress list:\n");
|
||||
get_default_nno_list(&valid_compressions, tmpbuf, sizeof tmpbuf, '(');
|
||||
rprintf(f, " %s\n", tmpbuf);
|
||||
|
||||
#ifdef MAINTAINER_MODE
|
||||
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
|
||||
#endif
|
||||
|
||||
#if SIZEOF_INT64 < 8
|
||||
rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
|
||||
#endif
|
||||
if (sizeof (int64) != SIZEOF_INT64) {
|
||||
rprintf(f,
|
||||
"WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
|
||||
(int) SIZEOF_INT64, (int) sizeof (int64));
|
||||
}
|
||||
|
||||
rprintf(f,"\n");
|
||||
rprintf(f,"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n");
|
||||
rprintf(f,"are welcome to redistribute it under certain conditions. See the GNU\n");
|
||||
rprintf(f,"General Public Licence for details.\n");
|
||||
}
|
||||
|
||||
|
||||
void usage(enum logcode F)
|
||||
{
|
||||
print_rsync_version(F);
|
||||
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"rsync is a file transfer program capable of efficient remote update\n");
|
||||
rprintf(F,"via a fast differencing algorithm.\n");
|
||||
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC [DEST]\n");
|
||||
rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
|
||||
rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
|
||||
rprintf(F,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n");
|
||||
rprintf(F,"to an rsync daemon, and require SRC or DEST to start with a module name.\n");
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Options\n");
|
||||
#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,"See https://rsync.samba.org/ for updates, bug reports, and answers\n");
|
||||
}
|
||||
|
||||
enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
|
||||
OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST, OPT_HELP,
|
||||
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
|
||||
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_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT,
|
||||
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_STOP_AFTER, OPT_STOP_AT,
|
||||
OPT_REFUSED_BASE = 9000};
|
||||
|
||||
static struct poptOption long_options[] = {
|
||||
@@ -792,7 +587,8 @@ static struct poptOption long_options[] = {
|
||||
{"no-v", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
|
||||
{"info", 0, POPT_ARG_STRING, 0, OPT_INFO, 0, 0 },
|
||||
{"debug", 0, POPT_ARG_STRING, 0, OPT_DEBUG, 0, 0 },
|
||||
{"msgs2stderr", 0, POPT_ARG_NONE, &msgs2stderr, 0, 0, 0 },
|
||||
{"stderr", 0, POPT_ARG_STRING, 0, OPT_STDERR, 0, 0 },
|
||||
{"msgs2stderr", 0, POPT_ARG_VAL, &msgs2stderr, 1, 0, 0 },
|
||||
{"no-msgs2stderr", 0, POPT_ARG_VAL, &msgs2stderr, 0, 0, 0 },
|
||||
{"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
|
||||
{"motd", 0, POPT_ARG_VAL, &output_motd, 1, 0, 0 },
|
||||
@@ -833,6 +629,9 @@ static struct poptOption long_options[] = {
|
||||
{"no-U", 0, POPT_ARG_VAL, &preserve_atimes, 0, 0, 0 },
|
||||
{"open-noatime", 0, POPT_ARG_VAL, &open_noatime, 1, 0, 0 },
|
||||
{"no-open-noatime", 0, POPT_ARG_VAL, &open_noatime, 0, 0, 0 },
|
||||
{"crtimes", 'N', POPT_ARG_VAL, &preserve_crtimes, 1, 0, 0 },
|
||||
{"no-crtimes", 0, POPT_ARG_VAL, &preserve_crtimes, 0, 0, 0 },
|
||||
{"no-N", 0, POPT_ARG_VAL, &preserve_crtimes, 0, 0, 0 },
|
||||
{"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 },
|
||||
{"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
|
||||
{"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
|
||||
@@ -889,6 +688,7 @@ static struct poptOption long_options[] = {
|
||||
{"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 },
|
||||
{"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
|
||||
{"min-size", 0, POPT_ARG_STRING, &min_size_arg, OPT_MIN_SIZE, 0, 0 },
|
||||
{"max-alloc", 0, POPT_ARG_STRING, &max_alloc_arg, 0, 0, 0 },
|
||||
{"sparse", 'S', POPT_ARG_VAL, &sparse_files, 1, 0, 0 },
|
||||
{"no-sparse", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 },
|
||||
{"no-S", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 },
|
||||
@@ -929,7 +729,7 @@ static struct poptOption long_options[] = {
|
||||
{"no-c", 0, POPT_ARG_VAL, &always_checksum, 0, 0, 0 },
|
||||
{"checksum-choice", 0, POPT_ARG_STRING, &checksum_choice, 0, 0, 0 },
|
||||
{"cc", 0, POPT_ARG_STRING, &checksum_choice, 0, 0, 0 },
|
||||
{"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
|
||||
{"block-size", 'B', POPT_ARG_STRING, 0, OPT_BLOCK_SIZE, 0, 0 },
|
||||
{"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
|
||||
{"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
|
||||
{"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
|
||||
@@ -989,6 +789,9 @@ 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 },
|
||||
{"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 },
|
||||
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
|
||||
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
|
||||
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
|
||||
@@ -999,6 +802,8 @@ static struct poptOption long_options[] = {
|
||||
{"8-bit-output", '8', POPT_ARG_VAL, &allow_8bit_chars, 1, 0, 0 },
|
||||
{"no-8-bit-output", 0, POPT_ARG_VAL, &allow_8bit_chars, 0, 0, 0 },
|
||||
{"no-8", 0, POPT_ARG_VAL, &allow_8bit_chars, 0, 0, 0 },
|
||||
{"mkpath", 0, POPT_ARG_VAL, &mkpath_dest_arg, 1, 0, 0 },
|
||||
{"no-mkpath", 0, POPT_ARG_VAL, &mkpath_dest_arg, 0, 0, 0 },
|
||||
{"qsort", 0, POPT_ARG_NONE, &use_qsort, 0, 0, 0 },
|
||||
{"copy-as", 0, POPT_ARG_STRING, ©_as, 0, 0, 0 },
|
||||
{"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
|
||||
@@ -1023,18 +828,6 @@ static struct poptOption long_options[] = {
|
||||
{0,0,0,0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static void daemon_usage(enum logcode F)
|
||||
{
|
||||
print_rsync_version(F);
|
||||
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Usage: rsync --daemon [OPTION]...\n");
|
||||
#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");
|
||||
}
|
||||
|
||||
static struct poptOption long_daemon_options[] = {
|
||||
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
|
||||
{"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
|
||||
@@ -1193,12 +986,18 @@ static void set_refuse_options(void)
|
||||
#ifndef SUPPORT_HARD_LINKS
|
||||
parse_one_refuse_match(0, "link-dest", list_end);
|
||||
#endif
|
||||
#ifndef HAVE_MKTIME
|
||||
parse_one_refuse_match(0, "stop-at", list_end);
|
||||
#endif
|
||||
#ifndef ICONV_OPTION
|
||||
parse_one_refuse_match(0, "iconv", list_end);
|
||||
#endif
|
||||
#ifndef HAVE_SETVBUF
|
||||
parse_one_refuse_match(0, "outbuf", list_end);
|
||||
#endif
|
||||
#ifndef SUPPORT_CRTIMES
|
||||
parse_one_refuse_match(0, "crtimes", list_end);
|
||||
#endif
|
||||
|
||||
/* Now we use the descrip values to actually mark the options for refusal. */
|
||||
for (op = long_options; op != list_end; op++) {
|
||||
@@ -1251,15 +1050,18 @@ static int count_args(const char **argv)
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static OFF_T parse_size_arg(char **size_arg, char def_suf)
|
||||
/* If the size_arg is an invalid string or the value is < min_value, an error
|
||||
* is put into err_buf & the return is -1. Note that this parser does NOT
|
||||
* support negative numbers, so a min_value < 0 doesn't make any sense. */
|
||||
static ssize_t parse_size_arg(const char *size_arg, char def_suf, const char *opt_name,
|
||||
ssize_t min_value, ssize_t max_value, BOOL unlimited_0)
|
||||
{
|
||||
int reps, mult, make_compatible = 0;
|
||||
const char *arg;
|
||||
OFF_T size = 1;
|
||||
int reps, mult, len;
|
||||
const char *arg, *err = "invalid", *min_max = NULL;
|
||||
ssize_t limit = -1, size = 1;
|
||||
|
||||
for (arg = *size_arg; isDigit(arg); arg++) {}
|
||||
if (*arg == '.')
|
||||
for (arg = size_arg; isDigit(arg); arg++) {}
|
||||
if (*arg == '.' || *arg == get_decimal_point()) /* backward compatibility: always allow '.' */
|
||||
for (arg++; isDigit(arg); arg++) {}
|
||||
switch (*arg && *arg != '+' && *arg != '-' ? *arg++ : def_suf) {
|
||||
case 'b': case 'B':
|
||||
@@ -1274,40 +1076,197 @@ static OFF_T parse_size_arg(char **size_arg, char def_suf)
|
||||
case 'g': case 'G':
|
||||
reps = 3;
|
||||
break;
|
||||
case 't': case 'T':
|
||||
reps = 4;
|
||||
break;
|
||||
case 'p': case 'P':
|
||||
reps = 5;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
goto failure;
|
||||
}
|
||||
if (*arg == 'b' || *arg == 'B')
|
||||
mult = 1000, make_compatible = 1, arg++;
|
||||
mult = 1000, arg++;
|
||||
else if (!*arg || *arg == '+' || *arg == '-')
|
||||
mult = 1024;
|
||||
else if (strncasecmp(arg, "ib", 2) == 0)
|
||||
mult = 1024, arg += 2;
|
||||
else
|
||||
return -1;
|
||||
goto failure;
|
||||
while (reps--)
|
||||
size *= mult;
|
||||
size *= atof(*size_arg);
|
||||
if ((*arg == '+' || *arg == '-') && arg[1] == '1')
|
||||
size += atoi(arg), make_compatible = 1, arg += 2;
|
||||
size *= atof(size_arg);
|
||||
if ((*arg == '+' || *arg == '-') && arg[1] == '1' && arg != size_arg)
|
||||
size += atoi(arg), arg += 2;
|
||||
if (*arg)
|
||||
return -1;
|
||||
if (size > 0 && make_compatible && def_suf == 'b') {
|
||||
/* We convert this manually because we may need %lld precision,
|
||||
* and that's not a portable sprintf() escape. */
|
||||
char buf[128], *s = buf + sizeof buf - 1;
|
||||
OFF_T num = size;
|
||||
*s = '\0';
|
||||
while (num) {
|
||||
*--s = (char)(num % 10) + '0';
|
||||
num /= 10;
|
||||
}
|
||||
if (!(*size_arg = strdup(s)))
|
||||
out_of_memory("parse_size_arg");
|
||||
goto failure;
|
||||
if (size < 0 || (max_value >= 0 && size > max_value)) {
|
||||
err = "too large";
|
||||
min_max = "max";
|
||||
limit = max_value;
|
||||
goto failure;
|
||||
}
|
||||
if (size < min_value && (!unlimited_0 || size != 0)) {
|
||||
err = "too small";
|
||||
min_max = "min";
|
||||
limit = min_value;
|
||||
goto failure;
|
||||
}
|
||||
return size;
|
||||
|
||||
failure:
|
||||
len = snprintf(err_buf, sizeof err_buf - 1, "--%s=%s is %s", opt_name, size_arg, err);
|
||||
if (min_max && limit >= 0 && len < (int)sizeof err_buf - 10) {
|
||||
len += snprintf(err_buf + len, sizeof err_buf - len - 1, " (%s: %s%s)",
|
||||
min_max, do_big_num(limit, 3, NULL),
|
||||
unlimited_0 && min_max[1] == 'i' ? " or 0 for unlimited" : "");
|
||||
}
|
||||
err_buf[len] = '\n';
|
||||
err_buf[len+1] = '\0';
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MKTIME
|
||||
/* Allow the user to specify a time in the format yyyy-mm-ddThh:mm while
|
||||
* also allowing abbreviated data. For instance, if the time is omitted,
|
||||
* it defaults to midnight. If the date is omitted, it defaults to the
|
||||
* next possible date in the future with the specified time. Even the
|
||||
* year or year-month can be omitted, again defaulting to the next date
|
||||
* in the future that matches the specified information. A 2-digit year
|
||||
* is also OK, as is using '/' instead of '-'. */
|
||||
static time_t parse_time(const char *arg)
|
||||
{
|
||||
const char *cp;
|
||||
time_t val, now = time(NULL);
|
||||
struct tm t, *today = localtime(&now);
|
||||
int in_date, old_mday, n;
|
||||
|
||||
memset(&t, 0, sizeof t);
|
||||
t.tm_year = t.tm_mon = t.tm_mday = -1;
|
||||
t.tm_hour = t.tm_min = t.tm_isdst = -1;
|
||||
cp = arg;
|
||||
if (*cp == 'T' || *cp == 't' || *cp == ':') {
|
||||
in_date = *cp == ':' ? 0 : -1;
|
||||
cp++;
|
||||
} else
|
||||
in_date = 1;
|
||||
for ( ; ; cp++) {
|
||||
if (!isDigit(cp))
|
||||
return (time_t)-1;
|
||||
n = 0;
|
||||
do {
|
||||
n = n * 10 + *cp++ - '0';
|
||||
} while (isDigit(cp));
|
||||
if (*cp == ':')
|
||||
in_date = 0;
|
||||
if (in_date > 0) {
|
||||
if (t.tm_year != -1)
|
||||
return (time_t)-1;
|
||||
t.tm_year = t.tm_mon;
|
||||
t.tm_mon = t.tm_mday;
|
||||
t.tm_mday = n;
|
||||
if (!*cp)
|
||||
break;
|
||||
if (*cp == 'T' || *cp == 't') {
|
||||
if (!cp[1])
|
||||
break;
|
||||
in_date = -1;
|
||||
} else if (*cp != '-' && *cp != '/')
|
||||
return (time_t)-1;
|
||||
continue;
|
||||
}
|
||||
if (t.tm_hour != -1)
|
||||
return (time_t)-1;
|
||||
t.tm_hour = t.tm_min;
|
||||
t.tm_min = n;
|
||||
if (!*cp) {
|
||||
if (in_date < 0)
|
||||
return (time_t)-1;
|
||||
break;
|
||||
}
|
||||
if (*cp != ':')
|
||||
return (time_t)-1;
|
||||
in_date = 0;
|
||||
}
|
||||
|
||||
in_date = 0;
|
||||
if (t.tm_year < 0) {
|
||||
t.tm_year = today->tm_year;
|
||||
in_date = 1;
|
||||
} else if (t.tm_year < 100) {
|
||||
while (t.tm_year < today->tm_year)
|
||||
t.tm_year += 100;
|
||||
} else
|
||||
t.tm_year -= 1900;
|
||||
if (t.tm_mon < 0) {
|
||||
t.tm_mon = today->tm_mon;
|
||||
in_date = 2;
|
||||
} else
|
||||
t.tm_mon--;
|
||||
if (t.tm_mday < 0) {
|
||||
t.tm_mday = today->tm_mday;
|
||||
in_date = 3;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
if (t.tm_min < 0) {
|
||||
t.tm_hour = t.tm_min = 0;
|
||||
} else if (t.tm_hour < 0) {
|
||||
if (in_date != 3)
|
||||
return (time_t)-1;
|
||||
in_date = 0;
|
||||
t.tm_hour = today->tm_hour;
|
||||
n = 60*60;
|
||||
}
|
||||
|
||||
/* Note that mktime() might change a too-large tm_mday into the start of
|
||||
* the following month which we need to undo in the following code! */
|
||||
old_mday = t.tm_mday;
|
||||
if (t.tm_hour > 23 || t.tm_min > 59
|
||||
|| t.tm_mon < 0 || t.tm_mon >= 12
|
||||
|| t.tm_mday < 1 || t.tm_mday > 31
|
||||
|| (val = mktime(&t)) == (time_t)-1)
|
||||
return (time_t)-1;
|
||||
|
||||
while (in_date && (val <= now || t.tm_mday < old_mday)) {
|
||||
switch (in_date) {
|
||||
case 3:
|
||||
old_mday = ++t.tm_mday;
|
||||
break;
|
||||
case 2:
|
||||
if (t.tm_mday < old_mday)
|
||||
t.tm_mday = old_mday; /* The month already got bumped forward */
|
||||
else if (++t.tm_mon == 12) {
|
||||
t.tm_mon = 0;
|
||||
t.tm_year++;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (t.tm_mday < old_mday) {
|
||||
/* mon==1 mday==29 got bumped to mon==2 */
|
||||
if (t.tm_mon != 2 || old_mday != 29)
|
||||
return (time_t)-1;
|
||||
t.tm_mon = 1;
|
||||
t.tm_mday = 29;
|
||||
}
|
||||
t.tm_year++;
|
||||
break;
|
||||
}
|
||||
if ((val = mktime(&t)) == (time_t)-1) {
|
||||
/* This code shouldn't be needed, as mktime() should auto-round to the next month. */
|
||||
if (in_date != 3 || t.tm_mday <= 28)
|
||||
return (time_t)-1;
|
||||
t.tm_mday = old_mday = 1;
|
||||
in_date = 2;
|
||||
}
|
||||
}
|
||||
if (n) {
|
||||
while (val <= now)
|
||||
val += n;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void create_refuse_error(int which)
|
||||
{
|
||||
@@ -1357,7 +1316,7 @@ char *alt_dest_opt(int type)
|
||||
case LINK_DEST:
|
||||
return "--link-dest";
|
||||
default:
|
||||
assert(0);
|
||||
NOISY_DEATH("Unknown alt_dest_opt type");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1530,8 +1489,6 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
if (daemon_filter_list.head) {
|
||||
int rej;
|
||||
char *cp = strdup(arg);
|
||||
if (!cp)
|
||||
out_of_memory("parse_arguments");
|
||||
if (!*cp)
|
||||
rej = 1;
|
||||
else {
|
||||
@@ -1655,8 +1612,6 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
remote_option_alloc += 16;
|
||||
remote_options = realloc_array(remote_options,
|
||||
const char *, remote_option_alloc);
|
||||
if (!remote_options)
|
||||
out_of_memory("parse_arguments");
|
||||
if (!remote_option_cnt)
|
||||
remote_options[0] = "ARG0";
|
||||
}
|
||||
@@ -1685,40 +1640,39 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OPT_MAX_SIZE:
|
||||
if ((max_size = parse_size_arg(&max_size_arg, 'b')) < 0) {
|
||||
snprintf(err_buf, sizeof err_buf,
|
||||
"--max-size value is invalid: %s\n",
|
||||
max_size_arg);
|
||||
case OPT_BLOCK_SIZE: {
|
||||
/* We may not know the real protocol_version at this point if this is the client
|
||||
* option parsing, but we still want to check it so that the client can specify
|
||||
* a --protocol=29 option with a larger block size. */
|
||||
int max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;
|
||||
ssize_t size;
|
||||
arg = poptGetOptArg(pc);
|
||||
if ((size = parse_size_arg(arg, 'b', "block-size", 0, max_blength, False)) < 0)
|
||||
return 0;
|
||||
}
|
||||
block_size = (int32)size;
|
||||
break;
|
||||
}
|
||||
|
||||
case OPT_MAX_SIZE:
|
||||
if ((max_size = parse_size_arg(max_size_arg, 'b', "max-size", 0, -1, False)) < 0)
|
||||
return 0;
|
||||
max_size_arg = strdup(do_big_num(max_size, 0, NULL));
|
||||
break;
|
||||
|
||||
case OPT_MIN_SIZE:
|
||||
if ((min_size = parse_size_arg(&min_size_arg, 'b')) < 0) {
|
||||
snprintf(err_buf, sizeof err_buf,
|
||||
"--min-size value is invalid: %s\n",
|
||||
min_size_arg);
|
||||
if ((min_size = parse_size_arg(min_size_arg, 'b', "min-size", 0, -1, False)) < 0)
|
||||
return 0;
|
||||
}
|
||||
min_size_arg = strdup(do_big_num(min_size, 0, NULL));
|
||||
break;
|
||||
|
||||
case OPT_BWLIMIT:
|
||||
{
|
||||
OFF_T limit = parse_size_arg(&bwlimit_arg, 'K');
|
||||
if (limit < 0) {
|
||||
snprintf(err_buf, sizeof err_buf,
|
||||
"--bwlimit value is invalid: %s\n", bwlimit_arg);
|
||||
return 0;
|
||||
}
|
||||
bwlimit = (limit + 512) / 1024;
|
||||
if (limit && !bwlimit) {
|
||||
snprintf(err_buf, sizeof err_buf,
|
||||
"--bwlimit value is too small: %s\n", bwlimit_arg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case OPT_BWLIMIT: {
|
||||
ssize_t size = parse_size_arg(bwlimit_arg, 'K', "bwlimit", 512, -1, True);
|
||||
if (size < 0)
|
||||
return 0;
|
||||
bwlimit_arg = strdup(do_big_num(size, 0, NULL));
|
||||
bwlimit = (size + 512) / 1024;
|
||||
break;
|
||||
}
|
||||
|
||||
case OPT_APPEND:
|
||||
if (am_server)
|
||||
@@ -1880,6 +1834,50 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
case OPT_STOP_AFTER: {
|
||||
long val;
|
||||
arg = poptGetOptArg(pc);
|
||||
stop_at_utime = time(NULL);
|
||||
if ((val = atol(arg) * 60) <= 0 || LONG_MAX - val < stop_at_utime || (long)(time_t)val != val) {
|
||||
snprintf(err_buf, sizeof err_buf, "invalid --stop-after value: %s\n", arg);
|
||||
return 0;
|
||||
}
|
||||
stop_at_utime += val;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MKTIME
|
||||
case OPT_STOP_AT:
|
||||
arg = poptGetOptArg(pc);
|
||||
if ((stop_at_utime = parse_time(arg)) == (time_t)-1) {
|
||||
snprintf(err_buf, sizeof err_buf, "invalid --stop-at format: %s\n", arg);
|
||||
return 0;
|
||||
}
|
||||
if (stop_at_utime <= time(NULL)) {
|
||||
snprintf(err_buf, sizeof err_buf, "--stop-at time is not in the future: %s\n", arg);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case OPT_STDERR: {
|
||||
int len;
|
||||
arg = poptGetOptArg(pc);
|
||||
len = strlen(arg);
|
||||
if (len && strncmp("errors", arg, len) == 0)
|
||||
msgs2stderr = 2;
|
||||
else if (len && strncmp("all", arg, len) == 0)
|
||||
msgs2stderr = 1;
|
||||
else if (len && strncmp("client", arg, len) == 0)
|
||||
msgs2stderr = 0;
|
||||
else {
|
||||
snprintf(err_buf, sizeof err_buf,
|
||||
"--stderr mode \"%s\" is not one of errors, all, or client\n", arg);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/* A large opt value means that set_refuse_options()
|
||||
* turned this option off. */
|
||||
@@ -1900,6 +1898,18 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
exit_cleanup(0);
|
||||
}
|
||||
|
||||
if (!max_alloc_arg) {
|
||||
max_alloc_arg = getenv("RSYNC_MAX_ALLOC");
|
||||
if (max_alloc_arg && !*max_alloc_arg)
|
||||
max_alloc_arg = NULL;
|
||||
}
|
||||
if (max_alloc_arg) {
|
||||
ssize_t size = parse_size_arg(max_alloc_arg, 'B', "max-alloc", 1024*1024, -1, True);
|
||||
if (size < 0)
|
||||
return 0;
|
||||
max_alloc = size;
|
||||
}
|
||||
|
||||
if (protect_args < 0) {
|
||||
if (am_server)
|
||||
protect_args = 0;
|
||||
@@ -1970,7 +1980,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
setvbuf(stdout, (char *)NULL, mode, 0);
|
||||
}
|
||||
|
||||
if (msgs2stderr) {
|
||||
if (msgs2stderr == 1) { /* Are all messages going to stderr? */
|
||||
/* Make stderr line buffered for better sharing of the stream. */
|
||||
fflush(stderr); /* Just in case... */
|
||||
setvbuf(stderr, (char *)NULL, _IOLBF, 0);
|
||||
@@ -2042,19 +2052,6 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (block_size) {
|
||||
/* We may not know the real protocol_version at this point if this is the client
|
||||
* option parsing, but we still want to check it so that the client can specify
|
||||
* a --protocol=29 option with a larger block size. */
|
||||
int32 max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;
|
||||
|
||||
if (block_size > max_blength) {
|
||||
snprintf(err_buf, sizeof err_buf,
|
||||
"--block-size=%lu is too large (max: %u)\n", block_size, max_blength);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (write_batch && read_batch) {
|
||||
snprintf(err_buf, sizeof err_buf,
|
||||
"--write-batch and --read-batch can not be used together\n");
|
||||
@@ -2469,13 +2466,6 @@ void server_options(char **args, int *argc_p)
|
||||
/* This should always remain first on the server's command-line. */
|
||||
args[ac++] = "--server";
|
||||
|
||||
if (daemon_over_rsh > 0) {
|
||||
args[ac++] = "--daemon";
|
||||
*argc_p = ac;
|
||||
/* if we're passing --daemon, we're done */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!am_sender)
|
||||
args[ac++] = "--sender";
|
||||
|
||||
@@ -2546,6 +2536,10 @@ void server_options(char **args, int *argc_p)
|
||||
if (preserve_atimes > 1)
|
||||
argstr[x++] = 'U';
|
||||
}
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (preserve_crtimes)
|
||||
argstr[x++] = 'N';
|
||||
#endif
|
||||
if (preserve_perms)
|
||||
argstr[x++] = 'p';
|
||||
else if (preserve_executability && am_sender)
|
||||
@@ -2613,6 +2607,7 @@ void server_options(char **args, int *argc_p)
|
||||
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
|
||||
}
|
||||
@@ -2678,8 +2673,13 @@ void server_options(char **args, int *argc_p)
|
||||
args[ac++] = "--log-format=X";
|
||||
}
|
||||
|
||||
if (msgs2stderr == 1)
|
||||
args[ac++] = "--msgs2stderr";
|
||||
else if (msgs2stderr == 0)
|
||||
args[ac++] = "--no-msgs2stderr";
|
||||
|
||||
if (block_size) {
|
||||
if (asprintf(&arg, "-B%lu", block_size) < 0)
|
||||
if (asprintf(&arg, "-B%u", (int)block_size) < 0)
|
||||
goto oom;
|
||||
args[ac++] = arg;
|
||||
}
|
||||
@@ -2770,6 +2770,11 @@ void server_options(char **args, int *argc_p)
|
||||
}
|
||||
}
|
||||
|
||||
if (max_alloc_arg && max_alloc != DEFAULT_MAX_ALLOC) {
|
||||
args[ac++] = "--max-alloc";
|
||||
args[ac++] = max_alloc_arg;
|
||||
}
|
||||
|
||||
/* --delete-missing-args needs the cooperation of both sides, but
|
||||
* the sender can handle --ignore-missing-args by itself. */
|
||||
if (missing_args == 2)
|
||||
@@ -2896,6 +2901,9 @@ void server_options(char **args, int *argc_p)
|
||||
if (open_noatime && preserve_atimes <= 1)
|
||||
args[ac++] = "--open-noatime";
|
||||
|
||||
if (mkpath_dest_arg && am_sender)
|
||||
args[ac++] = "--mkpath";
|
||||
|
||||
if (ac > MAX_SERVER_ARGS) { /* Not possible... */
|
||||
rprintf(FERROR, "argc overflow in server_options().\n");
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
|
||||
12
packaging/auto-Makefile
Normal file
12
packaging/auto-Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
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
|
||||
|
||||
.PHONY: $(TARGETS) auto-prep
|
||||
|
||||
$(TARGETS): auto-prep
|
||||
make -C build $@
|
||||
|
||||
auto-prep:
|
||||
@if test x`packaging/prep-auto-dir` = x; then echo "auto-build-save is not setup"; exit 1; fi
|
||||
@echo 'Build branch: '`readlink build/.branch | tr % /`
|
||||
@@ -171,4 +171,4 @@ if __name__ == '__main__':
|
||||
args = parser.parse_args()
|
||||
main()
|
||||
|
||||
# vim: sw=4 et
|
||||
# vim: sw=4 et ft=python
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Summary: A fast, versatile, remote (and local) file-copying tool
|
||||
Name: rsync
|
||||
Version: 3.2.1
|
||||
Version: 3.2.3
|
||||
%define fullversion %{version}
|
||||
Release: 1
|
||||
%define srcdir src
|
||||
@@ -79,8 +79,8 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%dir /etc/rsync-ssl/certs
|
||||
|
||||
%changelog
|
||||
* Mon Jun 22 2020 Wayne Davison <wayne@opencoder.net>
|
||||
Released 3.2.1.
|
||||
* Thu Aug 06 2020 Wayne Davison <wayne@opencoder.net>
|
||||
Released 3.2.3.
|
||||
|
||||
* Fri Mar 21 2008 Wayne Davison <wayne@opencoder.net>
|
||||
Added installation of /etc/xinetd.d/rsync file and some commented-out
|
||||
|
||||
@@ -32,6 +32,22 @@ blockquote pre code {
|
||||
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>
|
||||
"""
|
||||
@@ -59,7 +75,7 @@ def main():
|
||||
|
||||
html = md_parser(txt)
|
||||
|
||||
html = re.sub(r'(<code>)([\s\S]*?)(</code>)', lambda m: m[1] + re.sub(r'\s', '\xa0', m[2]) + m[3], html)
|
||||
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('--', '‑‑').replace("\xa0-", ' ‑').replace("\xa0", ' ')
|
||||
html = re.sub(r'(\W)-', r'\1‑', html)
|
||||
|
||||
@@ -72,14 +88,6 @@ def main():
|
||||
fh.write(HTML_END)
|
||||
|
||||
|
||||
def html_via_cmarkgfm(txt):
|
||||
return cmarkgfm.markdown_to_html(txt)
|
||||
|
||||
|
||||
def html_via_commonmark(txt):
|
||||
return commonmark.HtmlRenderer().render(commonmark.Parser().parse(txt))
|
||||
|
||||
|
||||
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.")
|
||||
@@ -88,12 +96,9 @@ if __name__ == '__main__':
|
||||
|
||||
try:
|
||||
import cmarkgfm
|
||||
md_parser = html_via_cmarkgfm
|
||||
# Our NEWS.md file has a gfm table in it.
|
||||
md_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.")
|
||||
die("Failed to find cmarkgfm for python3.")
|
||||
|
||||
main()
|
||||
|
||||
@@ -13,9 +13,9 @@ sys.path = ['packaging'] + sys.path
|
||||
from pkglib import *
|
||||
|
||||
MAKE_GEN_CMDS = [
|
||||
'make -f prepare-source.mak conf'.split(),
|
||||
'./config.status'.split(),
|
||||
'make gen'.split(),
|
||||
'./prepare-source'.split(),
|
||||
'cd build && if test -f config.status ; then ./config.status ; else ../configure ; fi',
|
||||
'make -C build gen'.split(),
|
||||
]
|
||||
TMP_DIR = "patches.gen"
|
||||
|
||||
@@ -33,6 +33,9 @@ def main():
|
||||
|
||||
master_commit = latest_git_hash(args.base_branch)
|
||||
|
||||
if cmd_txt_chk(['packaging/prep-auto-dir']) == '':
|
||||
die('You must setup an auto-build-save dir to use this script.')
|
||||
|
||||
if args.gen:
|
||||
if os.path.lexists(TMP_DIR):
|
||||
die(f'"{TMP_DIR}" must not exist in the current directory.')
|
||||
@@ -42,7 +45,7 @@ def main():
|
||||
cmd_chk(cmd)
|
||||
cmd_chk(['rsync', '-a', *gen_files, f'{TMP_DIR}/master/'])
|
||||
|
||||
last_touch = time.time()
|
||||
last_touch = int(time.time())
|
||||
|
||||
# Start by finding all patches so that we can load all possible parents.
|
||||
patches = sorted(list(get_patch_branches(args.base_branch)))
|
||||
@@ -91,9 +94,10 @@ def main():
|
||||
if args.gen:
|
||||
shutil.rmtree(TMP_DIR)
|
||||
|
||||
while last_touch >= time.time():
|
||||
while last_touch >= int(time.time()):
|
||||
time.sleep(1)
|
||||
cmd_chk(['git', 'checkout', starting_branch])
|
||||
cmd_chk(['packaging/prep-auto-dir'], discard='output')
|
||||
|
||||
|
||||
def update_patch(patch):
|
||||
@@ -113,31 +117,39 @@ def update_patch(patch):
|
||||
|
||||
print(f"======== {patch} ========")
|
||||
|
||||
while args.gen and last_touch >= time.time():
|
||||
while args.gen and last_touch >= int(time.time()):
|
||||
time.sleep(1)
|
||||
s = cmd_run(f"git checkout patch/{args.base_branch}/{patch}".split())
|
||||
|
||||
branch = f"patch/{args.base_branch}/{patch}"
|
||||
s = cmd_run(['git', 'checkout', branch])
|
||||
if s.returncode != 0:
|
||||
return 0
|
||||
|
||||
s = cmd_run(['git', 'merge', based_on])
|
||||
ok = s.returncode == 0
|
||||
if not ok or args.shell:
|
||||
m = re.search(r'([^/]+)$', parent)
|
||||
parent_dir = m[1]
|
||||
if not ok:
|
||||
print(f'"git merge {based_on}" incomplete -- please fix.')
|
||||
os.environ['PS1'] = f"[{parent_dir}] {patch}: "
|
||||
while True:
|
||||
s = cmd_run([os.environ.get('SHELL', '/bin/sh')])
|
||||
if s.returncode != 0:
|
||||
ans = input("Abort? [n/y] ")
|
||||
if re.match(r'^y', ans, flags=re.I):
|
||||
return 0
|
||||
continue
|
||||
cur_branch, is_clean, status_txt = check_git_status(0)
|
||||
if is_clean:
|
||||
break
|
||||
print(status_txt, end='')
|
||||
skip_shell = False
|
||||
if not ok or args.cmd or args.make or args.shell:
|
||||
cmd_chk(['packaging/prep-auto-dir'], discard='output')
|
||||
if not ok:
|
||||
print(f'"git merge {based_on}" incomplete -- please fix.')
|
||||
if not run_a_shell(parent, patch):
|
||||
return 0
|
||||
if not args.make and not args.cmd:
|
||||
skip_shell = True
|
||||
if args.make:
|
||||
if cmd_run(['packaging/smart-make']).returncode != 0:
|
||||
if not run_a_shell(parent, patch):
|
||||
return 0
|
||||
if not args.cmd:
|
||||
skip_shell = True
|
||||
if args.cmd:
|
||||
if cmd_run(args.cmd).returncode != 0:
|
||||
if not run_a_shell(parent, patch):
|
||||
return 0
|
||||
skip_shell = True
|
||||
if args.shell and not skip_shell:
|
||||
if not run_a_shell(parent, patch):
|
||||
return 0
|
||||
|
||||
with open(f"{args.patches_dir}/{patch}.diff", 'w', encoding='utf-8') as fh:
|
||||
fh.write(description[patch])
|
||||
@@ -150,7 +162,7 @@ def update_patch(patch):
|
||||
cmd_chk(['rsync', '-a', *gen_files, f"{TMP_DIR}/{patch}/"])
|
||||
else:
|
||||
gen_files = [ ]
|
||||
last_touch = time.time()
|
||||
last_touch = int(time.time())
|
||||
|
||||
proc = cmd_pipe(['git', 'diff', based_on])
|
||||
skipping = False
|
||||
@@ -185,16 +197,38 @@ def update_patch(patch):
|
||||
line = plus_re.sub(r'+++ b/\1', line)
|
||||
fh.write(line)
|
||||
proc.communicate()
|
||||
for fn in gen_files:
|
||||
os.unlink(fn)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
def run_a_shell(parent, patch):
|
||||
m = re.search(r'([^/]+)$', parent)
|
||||
parent_dir = m[1]
|
||||
os.environ['PS1'] = f"[{parent_dir}] {patch}: "
|
||||
|
||||
while True:
|
||||
s = cmd_run([os.environ.get('SHELL', '/bin/sh')])
|
||||
if s.returncode != 0:
|
||||
ans = input("Abort? [n/y] ")
|
||||
if re.match(r'^y', ans, flags=re.I):
|
||||
return False
|
||||
continue
|
||||
cur_branch, is_clean, status_txt = check_git_status(0)
|
||||
if is_clean:
|
||||
break
|
||||
print(status_txt, end='')
|
||||
|
||||
cmd_run('rm -f build/*.o build/*/*.o')
|
||||
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description="Turn a git branch back into a diff files in the patches dir.", add_help=False)
|
||||
parser.add_argument('--branch', '-b', dest='base_branch', metavar='BASE_BRANCH', default='master', help="The branch the patch is based on. Default: master.")
|
||||
parser.add_argument('--skip-check', action='store_true', help="Skip the check that ensures starting with a clean branch.")
|
||||
parser.add_argument('--make', '-m', action='store_true', help="Run the smart-make script in every patch branch.")
|
||||
parser.add_argument('--cmd', '-c', help="Run a command in every patch branch.")
|
||||
parser.add_argument('--shell', '-s', action='store_true', help="Launch a shell for every patch/BASE/* branch updated, not just when a conflict occurs.")
|
||||
parser.add_argument('--gen', metavar='DIR', nargs='?', const='', help='Include generated files. Optional DIR value overrides the default of using the "patches" dir.')
|
||||
parser.add_argument('--patches-dir', '-p', metavar='DIR', default='patches', help="Override the location of the rsync-patches dir. Default: patches.")
|
||||
@@ -207,4 +241,4 @@ if __name__ == '__main__':
|
||||
args.patches_dir = args.gen
|
||||
main()
|
||||
|
||||
# vim: sw=4 et
|
||||
# vim: sw=4 et ft=python
|
||||
|
||||
@@ -181,38 +181,43 @@ def mandate_gensend_hook():
|
||||
|
||||
|
||||
# Snag the GENFILES values out of the Makefile.in file and return them as a list.
|
||||
def get_gen_files():
|
||||
def get_gen_files(want_dir_plus_list=False):
|
||||
cont_re = re.compile(r'\\\n')
|
||||
|
||||
extras = [ ]
|
||||
gen_files = [ ]
|
||||
|
||||
auto_dir = os.path.join('auto-build-save', cmd_txt('git rev-parse --abbrev-ref HEAD').strip().replace('/', '%'))
|
||||
|
||||
with open('Makefile.in', 'r', encoding='utf-8') as fh:
|
||||
for line in fh:
|
||||
if not extras:
|
||||
if not gen_files:
|
||||
chk = re.sub(r'^GENFILES=', '', line)
|
||||
if line == chk:
|
||||
continue
|
||||
line = chk
|
||||
m = re.search(r'\\$', line)
|
||||
line = re.sub(r'^\s+|\s*\\\n?$|\s+$', '', line)
|
||||
extras += line.split()
|
||||
gen_files += line.split()
|
||||
if not m:
|
||||
break
|
||||
|
||||
return extras
|
||||
if want_dir_plus_list:
|
||||
return (auto_dir, gen_files)
|
||||
|
||||
return [ os.path.join(auto_dir, fn) for fn in gen_files ]
|
||||
|
||||
|
||||
def get_configure_version():
|
||||
with open('configure.ac', 'r', encoding='utf-8') as fh:
|
||||
for line in fh:
|
||||
m = re.match(r'^AC_INIT\(\[rsync\],\s*\[(\d.+?)\]', line)
|
||||
if m:
|
||||
return m[1]
|
||||
die("Unable to find AC_INIT with version in configure.ac")
|
||||
def get_rsync_version():
|
||||
with open('version.h', 'r', encoding='utf-8') as fh:
|
||||
txt = fh.read()
|
||||
m = re.match(r'^#define\s+RSYNC_VERSION\s+"(\d.+?)"', txt)
|
||||
if m:
|
||||
return m[1]
|
||||
die("Unable to find RSYNC_VERSION define in version.h")
|
||||
|
||||
|
||||
def get_NEWS_version_info():
|
||||
rel_re = re.compile(r'^\| \d{2} \w{3} \d{4}\s+\|\s+(?P<ver>\d+\.\d+\.\d+)\s+\|\s+(?P<pdate>\d{2} \w{3} \d{4}\s+)?\|\s+(?P<pver>\d+)\s+\|')
|
||||
rel_re = re.compile(r'^\| \S{2} \w{3} \d{4}\s+\|\s+(?P<ver>\d+\.\d+\.\d+)\s+\|\s+(?P<pdate>\d{2} \w{3} \d{4})?\s+\|\s+(?P<pver>\d+)\s+\|')
|
||||
last_version = last_protocol_version = None
|
||||
pdate = { }
|
||||
|
||||
@@ -228,12 +233,11 @@ def get_NEWS_version_info():
|
||||
pdate[m['ver']] = m['pdate']
|
||||
if m['ver'] == last_version:
|
||||
last_protocol_version = m['pver']
|
||||
break
|
||||
|
||||
if not last_protocol_version:
|
||||
die(f"Unable to determine protocol_version for {last_version}.")
|
||||
|
||||
return last_version, last_protocol_version
|
||||
return last_version, last_protocol_version, pdate
|
||||
|
||||
|
||||
def get_protocol_versions():
|
||||
|
||||
43
packaging/prep-auto-dir
Executable file
43
packaging/prep-auto-dir
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# This script will setup the build dir based on the current git branch and the
|
||||
# directory auto-build-save/$BRANCH. We don't use a symlink for the build dir
|
||||
# because we want to maximize the ccache reuse, so all builds must happen in
|
||||
# the same real dir. When a dir is moved out of auto-build-save/$BRANCH to the
|
||||
# build dir, it is replaced with a symlink so that it can still be found under
|
||||
# that dir. The build dir also gets a .branch -> $BRANCH symlink so that we
|
||||
# can figure out the current build dir's branch.
|
||||
|
||||
# To get started, just clone the rsync git repo and create the auto-build-save
|
||||
# dir. If you have an existing git checkout and it is not in a pristine state,
|
||||
# run "make distclean" before creating the auto-build-save dir.
|
||||
|
||||
auto_top='auto-build-save'
|
||||
if test -d $auto_top -a -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
|
||||
exit 1
|
||||
fi
|
||||
auto_dir="$auto_top/$desired_branch"
|
||||
if test -d build; then
|
||||
cur_branch=`readlink build/.branch`
|
||||
else
|
||||
cur_branch='/'
|
||||
fi
|
||||
if test "$desired_branch" != "$cur_branch"; then
|
||||
if test "$cur_branch" != /; then
|
||||
rm -f "$auto_top/$cur_branch"
|
||||
mv build "$auto_top/$cur_branch"
|
||||
fi
|
||||
test -d "$auto_dir" || mkdir "$auto_dir"
|
||||
test -h "$auto_dir/.branch" || ln -s "$desired_branch" "$auto_dir/.branch"
|
||||
mv "$auto_dir" build
|
||||
ln -s ../build "$auto_dir"
|
||||
fi
|
||||
if test ! -h Makefile; then
|
||||
rm -f Makefile
|
||||
ln -s packaging/auto-Makefile Makefile
|
||||
fi
|
||||
echo $desired_branch
|
||||
fi
|
||||
@@ -13,6 +13,7 @@ sys.path = ['packaging'] + sys.path
|
||||
|
||||
from pkglib import *
|
||||
|
||||
os.environ['LESS'] = 'mqeiXR'; # Make sure that -F is turned off and -R is turned on.
|
||||
dest = os.environ['HOME'] + '/samba-rsync-ftp'
|
||||
ORIGINAL_PATH = os.environ['PATH']
|
||||
|
||||
@@ -29,7 +30,11 @@ def main():
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
gen_files = get_gen_files()
|
||||
if cmd_txt_chk(['packaging/prep-auto-dir']) == '':
|
||||
die('You must setup an auto-build-save dir to use this script.');
|
||||
|
||||
auto_dir, gen_files = get_gen_files(True)
|
||||
gen_pathnames = [ os.path.join(auto_dir, fn) for fn in gen_files ]
|
||||
|
||||
dash_line = '=' * 74
|
||||
|
||||
@@ -52,13 +57,13 @@ def main():
|
||||
|
||||
check_git_state(args.master_branch, True, 'patches')
|
||||
|
||||
confversion = get_configure_version()
|
||||
curversion = get_rsync_version()
|
||||
|
||||
# All version values are strings!
|
||||
lastversion, last_protocol_version = get_NEWS_version_info()
|
||||
lastversion, last_protocol_version, pdate = get_NEWS_version_info()
|
||||
protocol_version, subprotocol_version = get_protocol_versions()
|
||||
|
||||
version = confversion
|
||||
version = curversion
|
||||
m = re.search(r'pre(\d+)', version)
|
||||
if m:
|
||||
version = re.sub(r'pre\d+', 'pre' + str(int(m[1]) + 1), version)
|
||||
@@ -88,8 +93,8 @@ def main():
|
||||
cmd_chk(['git', 'tag', '-d', v_ver])
|
||||
|
||||
version = re.sub(r'[-.]*pre[-.]*', 'pre', version)
|
||||
if 'pre' in version and not confversion.endswith('dev'):
|
||||
lastversion = confversion
|
||||
if 'pre' in version and not curversion.endswith('dev'):
|
||||
lastversion = curversion
|
||||
|
||||
ans = input(f"Enter the previous version to produce a patch against: [{lastversion}] ")
|
||||
if ans != '':
|
||||
@@ -111,11 +116,8 @@ def main():
|
||||
release += '.' + pre
|
||||
|
||||
finalversion = re.sub(r'pre\d+', '', version)
|
||||
if protocol_version == last_protocol_version:
|
||||
proto_changed = 'unchanged'
|
||||
proto_change_date = ' ' * 11
|
||||
else:
|
||||
proto_changed = 'changed'
|
||||
proto_changed = protocol_version != last_protocol_version
|
||||
if proto_changed:
|
||||
if finalversion in pdate:
|
||||
proto_change_date = pdate[finalversion]
|
||||
else:
|
||||
@@ -124,6 +126,8 @@ def main():
|
||||
if re.match(r'^\d\d \w\w\w \d\d\d\d$', ans):
|
||||
break
|
||||
proto_change_date = ans
|
||||
else:
|
||||
proto_change_date = ' ' * 11
|
||||
|
||||
if 'pre' in lastversion:
|
||||
if not pre:
|
||||
@@ -152,7 +156,7 @@ release is "{release}"
|
||||
|
||||
About to:
|
||||
- tweak SUBPROTOCOL_VERSION in rsync.h, if needed
|
||||
- tweak the version in configure.ac and the spec files
|
||||
- tweak the version in version.h and the spec files
|
||||
- tweak NEWS.md to ensure header values are correct
|
||||
- generate configure.sh, config.h.in, and proto.h
|
||||
- page through the differences
|
||||
@@ -167,16 +171,15 @@ About to:
|
||||
'%define srcdir': srcdir,
|
||||
}
|
||||
|
||||
tweak_files = 'configure.ac rsync.h NEWS.md'.split()
|
||||
tweak_files = 'version.h rsync.h NEWS.md'.split()
|
||||
tweak_files += glob.glob('packaging/*.spec')
|
||||
tweak_files += glob.glob('packaging/*/*.spec')
|
||||
|
||||
for fn in tweak_files:
|
||||
with open(fn, 'r', encoding='utf-8') as fh:
|
||||
old_txt = txt = fh.read()
|
||||
if 'configure' in fn:
|
||||
x_re = re.compile(r'^(AC_INIT\(\[rsync\],\s*\[)\d.+?(\])', re.M)
|
||||
txt = replace_or_die(x_re, r'\g<1>%s\2' % version, txt, f"Unable to update AC_INIT with version in {fn}")
|
||||
if fn == 'version.h':
|
||||
txt = f'#define RSYNC_VERSION "{version}"\n'
|
||||
elif '.spec' in fn:
|
||||
for var, val in specvars.items():
|
||||
x_re = re.compile(r'^%s .*' % re.escape(var), re.M)
|
||||
@@ -185,14 +188,17 @@ About to:
|
||||
txt = replace_or_die(x_re, r'%s \1' % cl_today, txt, f"Unable to update ChangeLog header in {fn}")
|
||||
elif fn == 'rsync.h':
|
||||
x_re = re.compile('(#define\s+SUBPROTOCOL_VERSION)\s+(\d+)')
|
||||
repl = lambda m: m[1] + ' ' + '0' if not pre or proto_changed != 'changed' else 1 if m[2] == '0' else m[2]
|
||||
repl = lambda m: m[1] + ' ' + ('0' if not pre or not proto_changed else '1' if m[2] == '0' else m[2])
|
||||
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+Protocol: .+\n' % efv)
|
||||
x_re = re.compile(r'^<.+>\s+# 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'
|
||||
+ f"Protocol: {protocol_version} ({proto_changed})\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'
|
||||
good_top = re.sub(r'\(.*?\)', '(UNRELEASED)', repl, 1)
|
||||
msg = f"The top lines of {fn} are not in the right format. It should be:\n" + good_top
|
||||
txt = replace_or_die(x_re, repl, txt, msg)
|
||||
@@ -215,10 +221,10 @@ About to:
|
||||
srctar_name = f"{rsync_ver}.tar.gz"
|
||||
pattar_name = f"rsync-patches-{version}.tar.gz"
|
||||
diff_name = f"{rsync_lastver}-{version}.diffs.gz"
|
||||
srctar_file = f"{dest}/{srcdir}/{srctar_name}"
|
||||
pattar_file = f"{dest}/{srcdir}/{pattar_name}"
|
||||
diff_file = f"{dest}/{srcdiffdir}/{diff_name}"
|
||||
lasttar_file = f"{dest}/{lastsrcdir}/{rsync_lastver}.tar.gz"
|
||||
srctar_file = os.path.join(dest, srcdir, srctar_name)
|
||||
pattar_file = os.path.join(dest, srcdir, pattar_name)
|
||||
diff_file = os.path.join(dest, srcdiffdir, diff_name)
|
||||
lasttar_file = os.path.join(dest, lastsrcdir, rsync_lastver + '.tar.gz')
|
||||
|
||||
print(f"""\
|
||||
{dash_line}
|
||||
@@ -227,8 +233,8 @@ About to:
|
||||
- git commit all changes
|
||||
- generate the manpages
|
||||
- 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 launch a shell for each patch
|
||||
- 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> ")
|
||||
|
||||
@@ -236,8 +242,7 @@ About to:
|
||||
if s.returncode:
|
||||
die('Aborting')
|
||||
|
||||
cmd_chk('make reconfigure ; make gen')
|
||||
cmd_chk(['rsync', '-a', *gen_files, 'SaVeDiR/'])
|
||||
cmd_chk('make gen')
|
||||
|
||||
print(f'Creating any missing patch branches.')
|
||||
s = cmd_run(f'packaging/branch-from-patch --branch={args.master_branch} --add-missing')
|
||||
@@ -250,11 +255,8 @@ About to:
|
||||
die('Aborting')
|
||||
|
||||
if re.match(r'^y', ans, re.I):
|
||||
print(f'\nVisiting all "patch/{args.master_branch}/*" branches ...')
|
||||
cmd_run(f"packaging/patch-update --branch={args.master_branch} --skip-check --shell")
|
||||
|
||||
cmd_run("rm -f *.[o15] *.html")
|
||||
cmd_chk('rsync -a SaVeDiR/ .'.split())
|
||||
print(f'\nRunning smart-make on all "patch/{args.master_branch}/*" branches ...')
|
||||
cmd_run(f"packaging/patch-update --branch={args.master_branch} --skip-check --make")
|
||||
|
||||
if os.path.isdir('patches/.git'):
|
||||
s = cmd_run(f"cd patches && git commit -a -m 'The patches for {version}.'")
|
||||
@@ -294,12 +296,12 @@ About to:
|
||||
os.environ['PATH'] = ORIGINAL_PATH
|
||||
|
||||
# Extract the generated files from the old tar.
|
||||
tweaked_gen_files = [ f"{rsync_lastver}/{x}" for x in gen_files ]
|
||||
tweaked_gen_files = [ os.path.join(rsync_lastver, fn) for fn in gen_files ]
|
||||
cmd_run(['tar', 'xzf', lasttar_file, *tweaked_gen_files])
|
||||
os.rename(rsync_lastver, 'a')
|
||||
|
||||
print(f"Creating {diff_file} ...")
|
||||
cmd_chk(['rsync', '-a', *gen_files, 'b/'])
|
||||
cmd_chk(['rsync', '-a', *gen_pathnames, 'b/'])
|
||||
|
||||
sed_script = r's:^((---|\+\+\+) [ab]/[^\t]+)\t.*:\1:' # CAUTION: must not contain any single quotes!
|
||||
cmd_chk(f"(git diff v{lastversion} {v_ver} -- ':!.github'; diff -upN a b | sed -r '{sed_script}') | gzip -9 >{diff_file}")
|
||||
@@ -317,18 +319,13 @@ About to:
|
||||
os.mkdir(f"{rsync_ver}/patches", 0o755)
|
||||
cmd_chk(f"packaging/patch-update --skip-check --branch={args.master_branch} --gen={rsync_ver}/patches".split())
|
||||
|
||||
cmd_run("rm -f *.[o15] *.html")
|
||||
cmd_chk('rsync -a SaVeDiR/ .'.split())
|
||||
shutil.rmtree('SaVeDiR')
|
||||
cmd_chk('make gen'.split())
|
||||
|
||||
print(f"Creating {pattar_file} ...")
|
||||
cmd_chk(['fakeroot', 'tar', 'chzf', pattar_file, rsync_ver + '/patches'])
|
||||
shutil.rmtree(rsync_ver)
|
||||
|
||||
print(f"Updating the other files in {dest} ...")
|
||||
md_files = 'README.md NEWS.md'.split()
|
||||
html_files = [ fn for fn in gen_files if fn.endswith('.html') ]
|
||||
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 ])
|
||||
|
||||
@@ -381,4 +378,4 @@ if __name__ == '__main__':
|
||||
args = parser.parse_args()
|
||||
main()
|
||||
|
||||
# vim: sw=4 et
|
||||
# vim: sw=4 et ft=python
|
||||
|
||||
47
packaging/smart-make
Executable file
47
packaging/smart-make
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/bin/sh
|
||||
|
||||
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=.
|
||||
else
|
||||
cd build
|
||||
srcdir=..
|
||||
fi
|
||||
|
||||
if test -f configure.sh; then
|
||||
cp -p configure.sh configure.sh.old
|
||||
else
|
||||
touch configure.sh.old
|
||||
fi
|
||||
|
||||
if test -f .fetch; then
|
||||
$srcdir/prepare-source fetch
|
||||
else
|
||||
$srcdir/prepare-source
|
||||
fi
|
||||
|
||||
if diff configure.sh configure.sh.old >/dev/null 2>&1; then
|
||||
echo "configure.sh is unchanged."
|
||||
rm configure.sh.old
|
||||
else
|
||||
echo "configure.sh has CHANGED."
|
||||
if test -f config.status; then
|
||||
./config.status --recheck
|
||||
else
|
||||
$srcdir/configure
|
||||
fi
|
||||
fi
|
||||
|
||||
./config.status
|
||||
|
||||
$make all
|
||||
|
||||
if test x"$1" = x"check"; then
|
||||
$make check
|
||||
fi
|
||||
@@ -16,14 +16,14 @@ RestartSec=1
|
||||
# This is generally used for public file distribution, [...]
|
||||
#
|
||||
# So let's assume some extra security is more than welcome here. We do full
|
||||
# system protection (which makes it read-only) and hide users' homes and
|
||||
# system protection (which makes /usr, /boot, & /etc read-only) and hide
|
||||
# devices. To override these defaults, it's best to do so in the drop-in
|
||||
# directory, often done via `systemctl edit rsync.service`. The file needs
|
||||
# just the bare minimum of the right [heading] and override values.
|
||||
# See systemd.unit(5) and search for "drop-in" for full details.
|
||||
|
||||
ProtectSystem=full
|
||||
ProtectHome=on
|
||||
#ProtectHome=on|off|read-only
|
||||
PrivateDevices=on
|
||||
NoNewPrivileges=on
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ StandardError=journal
|
||||
# This is generally used for public file distribution, [...]
|
||||
#
|
||||
# So let's assume some extra security is more than welcome here. We do full
|
||||
# system protection (which makes it read-only) and hide users' homes and
|
||||
# system protection (which makes /usr, /boot, & /etc read-only) and hide
|
||||
# devices. To override these defaults, it's best to do so in the drop-in
|
||||
# directory, often done via `systemctl edit rsync@.service`. The file needs
|
||||
# just the bare minimum of the right [heading] and override values.
|
||||
# See systemd.unit(5) and search for "drop-in" for full details.
|
||||
|
||||
ProtectSystem=full
|
||||
ProtectHome=on
|
||||
#ProtectHome=on|off|read-only
|
||||
PrivateDevices=on
|
||||
NoNewPrivileges=on
|
||||
|
||||
@@ -84,4 +84,4 @@ if __name__ == '__main__':
|
||||
args = parser.parse_args()
|
||||
main()
|
||||
|
||||
# vim: sw=4 et
|
||||
# vim: sw=4 et ft=python
|
||||
|
||||
21
params.c
21
params.c
@@ -212,11 +212,6 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
|
||||
{
|
||||
bSize += BUFR_INC;
|
||||
bufr = realloc_array( bufr, char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FLOG, "%s Memory re-allocation failure.", func);
|
||||
return( False );
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle a single character. */
|
||||
@@ -306,11 +301,6 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
{
|
||||
bSize += BUFR_INC;
|
||||
bufr = realloc_array( bufr, char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
|
||||
return( False );
|
||||
}
|
||||
}
|
||||
|
||||
switch( c )
|
||||
@@ -382,11 +372,6 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
{
|
||||
bSize += BUFR_INC;
|
||||
bufr = realloc_array( bufr, char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
|
||||
return( False );
|
||||
}
|
||||
}
|
||||
|
||||
switch( c )
|
||||
@@ -639,12 +624,6 @@ int pm_process( char *FileName,
|
||||
{ /* allocate one, then parse, */
|
||||
bSize = BUFR_INC; /* then free. */
|
||||
bufr = new_array( char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FLOG, "%s memory allocation failure.\n", func);
|
||||
fclose(InFile);
|
||||
return( False );
|
||||
}
|
||||
result = Parse( InFile, sfunc, pfunc );
|
||||
free( bufr );
|
||||
bufr = NULL;
|
||||
|
||||
@@ -11,6 +11,10 @@ extern __const __int32_t *__ctype_toupper;
|
||||
/*@=declundef@*/
|
||||
#endif
|
||||
|
||||
#ifdef __TANDEM
|
||||
# include <floss.h(floss_execvp,floss_read)>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
# Specify one action or more than one to provide a fall-back:
|
||||
#
|
||||
# build build the config files [the default w/no arg]
|
||||
# fetch fetch the latest dev config files
|
||||
# fetchgen fetch all the latest dev generated files
|
||||
# fetch fetch the latest dev autoconfig files
|
||||
# fetchgen fetch all the latest dev generated files (including man pages)
|
||||
# fetchSRC fetch the latest dev source files [NON-GENERATED FILES]
|
||||
#
|
||||
# The script stops after the first successful action.
|
||||
@@ -16,6 +16,26 @@ if test x"$dir" = x; then
|
||||
dir=.
|
||||
fi
|
||||
|
||||
if test "$dir" = '.'; then
|
||||
branch=`packaging/prep-auto-dir` || exit 1
|
||||
if test x"$branch" != x; then
|
||||
cd build || exit 1
|
||||
dir=..
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$dir" != '.'; then
|
||||
for lnk in configure.ac m4; do
|
||||
if test ! -h $lnk; then
|
||||
rm -f $lnk # Just in case
|
||||
ln -s "$dir/$lnk" $lnk
|
||||
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
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# = 0; then
|
||||
set -- build
|
||||
fi
|
||||
@@ -23,13 +43,16 @@ fi
|
||||
for action in "${@}"; do
|
||||
case "$action" in
|
||||
build|make)
|
||||
(cd $dir && make -f prepare-source.mak)
|
||||
make -f "$dir/prepare-source.mak"
|
||||
;;
|
||||
fetch|fetchgen)
|
||||
$dir/rsync-ssl -iip --no-motd rsync://download.samba.org/rsyncftp/generated-files/'[ca]*' $dir
|
||||
if test "$action" = fetchgen; then
|
||||
$dir/rsync-ssl -iip --no-motd rsync://download.samba.org/rsyncftp/generated-files/'[^ca]*' .
|
||||
match='*'
|
||||
else
|
||||
match='[ca]*'
|
||||
fi
|
||||
$dir/rsync-ssl -iipc --no-motd "rsync://download.samba.org/rsyncftp/generated-files/$match" ./
|
||||
test $? != 0 && continue
|
||||
sleep 1 # The following files need to be newer than aclocal.m4
|
||||
touch configure.sh config.h.in
|
||||
;;
|
||||
@@ -39,6 +62,7 @@ for action in "${@}"; do
|
||||
*)
|
||||
echo "Unknown action: $action"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
if test $? = 0; then
|
||||
exit
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
SHELL=/bin/sh
|
||||
|
||||
conf: configure.sh config.h.in
|
||||
.PHONY: conf
|
||||
|
||||
aclocal.m4: m4/*.m4
|
||||
aclocal -I m4
|
||||
|
||||
449
rsync.1.md
449
rsync.1.md
@@ -107,9 +107,9 @@ This would transfer all files matching the pattern `*.c` from the current
|
||||
directory to the directory src on the machine foo. If any of the files already
|
||||
exist on the remote system then the rsync remote-update protocol is used to
|
||||
update the file by sending only the differences in the data. Note that the
|
||||
expansion of wildcards on the commandline (`*.c`) into a list of files is
|
||||
expansion of wildcards on the command-line (`*.c`) into a list of files is
|
||||
handled by the shell before it runs rsync and not by rsync itself (exactly the
|
||||
same as all other posix-style programs).
|
||||
same as all other Posix-style programs).
|
||||
|
||||
> rsync -avz foo:src/bar /data/tmp
|
||||
|
||||
@@ -328,13 +328,13 @@ Here is a short summary of the options available in rsync. Please refer to the
|
||||
detailed description below for a complete description.
|
||||
|
||||
[comment]: # (help-rsync.h)
|
||||
[comment]: # (Keep these short enough that they'll be under 80 chars when indented by 8 chars.)
|
||||
[comment]: # (Keep these short enough that they'll be under 80 chars when indented by 7 chars.)
|
||||
|
||||
```
|
||||
--verbose, -v increase verbosity
|
||||
--info=FLAGS fine-grained informational verbosity
|
||||
--debug=FLAGS fine-grained debug verbosity
|
||||
--msgs2stderr output messages directly to stderr
|
||||
--stderr=e|a|c change stderr output mode (default: errors)
|
||||
--quiet, -q suppress non-error messages
|
||||
--no-motd suppress daemon-mode MOTD
|
||||
--checksum, -c skip based on checksum, not mod-time & size
|
||||
@@ -351,6 +351,7 @@ 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
|
||||
--links, -l copy symlinks as symlinks
|
||||
--copy-links, -L transform symlink into referent file/dir
|
||||
--copy-unsafe-links only "unsafe" symlinks are transformed
|
||||
@@ -372,6 +373,7 @@ detailed description below for a complete description.
|
||||
--times, -t preserve modification times
|
||||
--atimes, -U preserve access (use) times
|
||||
--open-noatime avoid changing the atime on opened files
|
||||
--crtimes, -N preserve create times (newness)
|
||||
--omit-dir-times, -O omit directories from --times
|
||||
--omit-link-times, -J omit symlinks from --times
|
||||
--super receiver attempts super-user activities
|
||||
@@ -403,6 +405,7 @@ detailed description below for a complete description.
|
||||
--max-delete=NUM don't delete more than NUM files
|
||||
--max-size=SIZE don't transfer any file larger than SIZE
|
||||
--min-size=SIZE don't transfer any file smaller than SIZE
|
||||
--max-alloc=SIZE change a limit relating to memory alloc
|
||||
--partial keep partially transferred files
|
||||
--partial-dir=DIR put a partially transferred file into DIR
|
||||
--delay-updates put all updated files into place at end
|
||||
@@ -456,6 +459,8 @@ detailed description below for a complete description.
|
||||
--early-input=FILE use FILE for daemon's early exec input
|
||||
--list-only list the files instead of copying them
|
||||
--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
|
||||
--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
|
||||
@@ -520,9 +525,6 @@ your home directory (remove the '=' for that).
|
||||
list of compression algorithms, a list of compiled-in capabilities, a link
|
||||
to the rsync web site, and some license/copyright info.
|
||||
|
||||
Repeat the option (`-VV`) to include some optimization info at the end of
|
||||
the capabilities list.
|
||||
|
||||
0. `--verbose`, `-v`
|
||||
|
||||
This option increases the amount of information you are given during the
|
||||
@@ -580,10 +582,10 @@ 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 `--msgs2stderr` is
|
||||
Note that some debug messages will only be output when `--stderr=all` is
|
||||
specified, especially those pertaining to I/O and buffer debugging.
|
||||
|
||||
Beginning in 3.2.0, this option is no longer auto-forwared to the server
|
||||
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
|
||||
present in one of the rsync versions. If you want to duplicate the same
|
||||
@@ -592,28 +594,41 @@ your home directory (remove the '=' for that).
|
||||
|
||||
> rsync -aiv {-M,}--debug=del2 src/ dest/
|
||||
|
||||
0. `--msgs2stderr`
|
||||
0. `--stderr=errors|all|client`
|
||||
|
||||
This option changes rsync to send all its output directly to stderr rather
|
||||
than to send messages to the client side via the protocol. The protocol
|
||||
allows rsync to output normal messages via stdout and errors via stderr,
|
||||
but it can delay messages behind a slew of data.
|
||||
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:
|
||||
|
||||
One case where this is helpful is when sending really large files, since
|
||||
errors that happen on a remote receiver tend to get delayed until after the
|
||||
file's data is fully sent. It is also helpful for debugging, since it
|
||||
helps to avoid overpopulating the protocol data with extra message data.
|
||||
- `errors` - (the default) causes all the rsync processes to send an
|
||||
error directly to stderr, even if the process is on the remote side of
|
||||
the transfer. Info messages are sent to the client side via the protocol
|
||||
stream. If stderr is not available (i.e. when directly connecting with a
|
||||
daemon via a socket) errors fall back to being sent via the protocol
|
||||
stream.
|
||||
|
||||
The option does not affect the remote side of a transfer without using
|
||||
`--remote-option` -- e.g. `-M--msgs2stderr` or `{-M,}--msgs2stderr`.
|
||||
- `all` - causes all rsync messages (info and error) to get written
|
||||
directly to stderr from all (possible) processes. This causes stderr to
|
||||
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.
|
||||
|
||||
Also keep in mind that connecting to a normal (non-remote-shell) daemon
|
||||
does not have a stderr channel to send messages back to the client side, so
|
||||
a modern rsync only allows the option on a remote-shell-run daemon.
|
||||
- `client` - causes all rsync messages to be sent to the client side
|
||||
via the protocol stream. One client process outputs all messages, with
|
||||
errors on stderr and info messages on stdout. This **was** the default
|
||||
in older rsync versions, but can cause error delays when a lot of
|
||||
transfer data is ahead of the messages. If you're pushing files to an
|
||||
older rsync, you may want to use `--stderr=all` since that idiom has
|
||||
been around for several releases.
|
||||
|
||||
This option has the side-effect of making stderr output get line-buffered
|
||||
so that the merging of the output of 3 programs happens in a more readable
|
||||
manner.
|
||||
This option was added in rsync 3.2.3. This version also began the
|
||||
forwarding of a non-default setting to the remote side, though rsync uses
|
||||
the backward-compatible options `--msgs2stderr` and `--no-msgs2stderr` to
|
||||
represent the `all` and `client` settings, respectively. A newer rsync
|
||||
will continue to accept these older option names to maintain compatibility.
|
||||
|
||||
0. `--quiet`, `-q`
|
||||
|
||||
@@ -690,7 +705,7 @@ 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` option or an
|
||||
can be overridden using either the `--checksum-choice` (`--cc`) option or an
|
||||
environment variable that is discussed in that option's section.
|
||||
|
||||
0. `--archive`, `-a`
|
||||
@@ -923,30 +938,31 @@ your home directory (remove the '=' for that).
|
||||
|
||||
0. `--append`
|
||||
|
||||
This causes rsync to update a file by appending data onto the end of the
|
||||
file, which presumes that the data that already exists on the receiving
|
||||
side is identical with the start of the file on the sending side. If a
|
||||
file needs to be transferred and its size on the receiver is the same or
|
||||
longer than the size on the sender, the file is skipped. 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 non-regular files.
|
||||
Implies `--inplace`.
|
||||
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
|
||||
`--append` **can be dangerous** if you aren't 100% sure that all the files
|
||||
in the transfer are shared, growing files. You should thus use filter
|
||||
rules to ensure that you weed out any files that do not fit this criteria.
|
||||
|
||||
The use of `--append` can be dangerous if you aren't 100% sure that the
|
||||
files that are longer have only grown by the appending of data onto the
|
||||
end. You should thus use include/exclude/filter rules to ensure that such
|
||||
a transfer is only affecting files that you know to be growing via appended
|
||||
data.
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
0. `--append-verify`
|
||||
|
||||
This works just like the `--append` option, but the existing data on the
|
||||
receiving side is included in the full-file checksum verification step,
|
||||
which will cause a file to be resent if the final verification step fails
|
||||
(rsync uses a normal, non-appending `--inplace` transfer for the resend).
|
||||
It otherwise has the exact same caveats for files that have not grown
|
||||
larger, so don't use this for a general copy.
|
||||
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
|
||||
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.
|
||||
|
||||
Note: prior to rsync 3.0.0, the `--append` option worked like
|
||||
`--append-verify`, so if you are interacting with an older rsync (or the
|
||||
@@ -972,6 +988,26 @@ your home directory (remove the '=' for that).
|
||||
`--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).
|
||||
|
||||
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:
|
||||
|
||||
> rsync -ai --mkpath foo sub/dir/bar
|
||||
|
||||
If you instead ran the following, it would have created file foo in the
|
||||
sub/dir/bar directory:
|
||||
|
||||
> rsync -ai --mkpath foo sub/dir/bar/
|
||||
|
||||
0. `--links`, `-l`
|
||||
|
||||
When symlinks are encountered, recreate the symlink on the destination.
|
||||
@@ -1341,6 +1377,11 @@ your home directory (remove the '=' for that).
|
||||
mounted to avoid updating the atime on read access even without the
|
||||
O_NOATIME flag being set.
|
||||
|
||||
0. `--crtimes`, `-N,`
|
||||
|
||||
This tells rsync to set the create times (newness) of the destination
|
||||
files to the same value as the source files.
|
||||
|
||||
0. `--omit-dir-times`, `-O`
|
||||
|
||||
This tells rsync to omit directories when it is preserving modification
|
||||
@@ -1473,13 +1514,16 @@ your home directory (remove the '=' for that).
|
||||
|
||||
The checksum options that you may be able to use are:
|
||||
|
||||
- `auto` (the default)
|
||||
- `xxh64` (aka xxhash)
|
||||
- `auto` (the default automatic choice)
|
||||
- `xxh128`
|
||||
- `xxh3`
|
||||
- `xxh64` (aka `xxhash`)
|
||||
- `md5`
|
||||
- `md4`
|
||||
- `none`
|
||||
|
||||
Run `rsync -V` to see the default checksum list compiled into your version.
|
||||
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`
|
||||
option is forced on and no checksum verification is performed on the
|
||||
@@ -1489,22 +1533,22 @@ your home directory (remove the '=' for that).
|
||||
The "auto" option is the default, where rsync bases its algorithm choice on
|
||||
a negotiation between the client and the server as follows:
|
||||
|
||||
If both the client and the server are at least version 3.2.0, they will
|
||||
exchange a list of checksum names and choose the first one in the list that
|
||||
they have in common. This typically means that they will choose xxh64 if
|
||||
they both support it and fall back to MD5. If one side of the transfer is
|
||||
not new enough to support this checksum negotiation, then a value is chosen
|
||||
based on the protocol version (which chooses between MD5 and various
|
||||
flavors of MD4 based on protocol age).
|
||||
When both sides of the transfer are at least 3.2.0, rsync chooses the first
|
||||
algorithm in the client's list of choices that is also in the server's list
|
||||
of choices. If no common checksum choice is found, rsync exits with
|
||||
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).
|
||||
|
||||
You can also override the checksum using the RSYNC_CHECKSUM_LIST
|
||||
environment variable by setting it to a space-separated list of checksum
|
||||
names that you consider acceptable. If no common checksum is found, the
|
||||
client exits with an error. This method does not allow you to specify the
|
||||
transfer checksum separately from the pre-transfer checksum, and it ignores
|
||||
"auto" and all unknown checksum names. If the remote rsync is not new
|
||||
enough to handle a checksum negotiation list, the list is silently ignored
|
||||
unless it contains the string "FAIL".
|
||||
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.
|
||||
|
||||
The use of the `--checksum-choice` option overrides this environment list.
|
||||
|
||||
@@ -1724,19 +1768,24 @@ your home directory (remove the '=' for that).
|
||||
0. `--max-size=SIZE`
|
||||
|
||||
This tells rsync to avoid transferring any file that is larger than the
|
||||
specified SIZE. The SIZE value can be suffixed with a string to indicate a
|
||||
size multiplier, and may be a fractional value (e.g. `--max-size=1.5m`).
|
||||
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 `--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.
|
||||
|
||||
The suffixes are as follows: "K" (or "KiB") is a kibibyte (1024), "M" (or
|
||||
"MiB") is a mebibyte (1024\*1024), and "G" (or "GiB") is a gibibyte
|
||||
(1024\*1024\*1024). If you want the multiplier to be 1000 instead of 1024,
|
||||
use "KB", "MB", or "GB". (Note: lower-case is also accepted for all
|
||||
values.) Finally, if the suffix ends in either "+1" or "-1", the value will
|
||||
be offset by one byte in the indicated direction.
|
||||
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
|
||||
char or has "ib" added to it (e.g. "G" or "GiB") then the units are
|
||||
multiples of 1024. If you use a two-letter suffix that ends with a "B"
|
||||
(e.g. "kb") then you get units that are multiples of 1000. The string's
|
||||
letters can be any mix of upper and lower-case that you want to use.
|
||||
|
||||
Finally, if the string ends with either "+1" or "-1", it is offset by one
|
||||
byte in the indicated direction. The largest possible value is usually
|
||||
`8192P-1`.
|
||||
|
||||
Examples: `--max-size=1.5mb-1` is 1499999 bytes, and `--max-size=2g+1` is
|
||||
2147483649 bytes.
|
||||
@@ -1751,12 +1800,39 @@ your home directory (remove the '=' for that).
|
||||
|
||||
Note that rsync versions prior to 3.1.0 did not allow `--min-size=0`.
|
||||
|
||||
0. `--max-alloc=SIZE`
|
||||
|
||||
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
|
||||
many millions of files in a transfer, a large amount of server memory, and
|
||||
you don't want to split up your transfer into multiple parts, you can
|
||||
increase the per-allocation limit to something larger and rsync will
|
||||
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.
|
||||
|
||||
See the `--max-size` 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).
|
||||
|
||||
0. `--block-size=SIZE`, `-B`
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
0. `--rsh=COMMAND`, `-e`
|
||||
|
||||
This option allows you to choose an alternative remote shell program to use
|
||||
@@ -2073,8 +2149,9 @@ your home directory (remove the '=' for that).
|
||||
|
||||
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 -V` to check if this is the case, as it will display "default
|
||||
protect-args" or "optional protect-args" depending on how it was compiled.
|
||||
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.
|
||||
|
||||
This option will eventually become a new default setting at some
|
||||
as-yet-undetermined point in the future.
|
||||
@@ -2114,7 +2191,7 @@ your home directory (remove the '=' for that).
|
||||
has no permissions to change.
|
||||
|
||||
The following command does a local copy into the "dest/" dir as user "joe"
|
||||
(assumimg you've installed support/lsh into a dir on your $PATH):
|
||||
(assuming you've installed support/lsh into a dir on your $PATH):
|
||||
|
||||
> sudo rsync -aive lsh -M--copy-as=joe src/ lh:dest/
|
||||
|
||||
@@ -2260,29 +2337,42 @@ your home directory (remove the '=' for that).
|
||||
destination machine, which reduces the amount of data being transmitted --
|
||||
something that is useful over a slow connection.
|
||||
|
||||
The "zlib" compression method typically achieves better compression ratios
|
||||
than can be achieved by using a compressing remote shell or a compressing
|
||||
transport because it takes advantage of the implicit information in the
|
||||
matching data blocks that are not explicitly sent over the connection.
|
||||
This matching-data compression comes at a cost of CPU, though, and can be
|
||||
disabled by using the "zlibx" compresson method instead. This can be
|
||||
selected by repeating the `-z` option or specifying
|
||||
`--compress-choice=zlibx`, but it only works if both sides of the transfer
|
||||
are at least version 3.1.1.
|
||||
Rsync supports multiple compression methods and will choose one for you
|
||||
unless you force the choice using the `--compress-choice` (`--zc`) option.
|
||||
|
||||
Note that if you see an error about an option named `--old-compress` or
|
||||
`--new-compress`, this is rsync trying to send the `--compress-choice=zlib`
|
||||
or `--compress-choice=zlibx` option in a backward-compatible manner that
|
||||
more rsync versions understand. This error indicates that the older rsync
|
||||
version will not allow you to force the compression type.
|
||||
Run `rsync --version` to see the default compress list compiled into your
|
||||
version.
|
||||
|
||||
See the `--skip-compress` option for the default list of file suffixes that
|
||||
will not be compressed.
|
||||
When both sides of the transfer are at least 3.2.0, rsync chooses the first
|
||||
algorithm in the client's list of choices that is also in the server's list
|
||||
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 "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
|
||||
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.
|
||||
|
||||
There are some older rsync versions that were configured to reject a `-z`
|
||||
option and require the use of `-zz` 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 `-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 selection of the
|
||||
compression algorithm that is the default when `--compress` is used.
|
||||
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`.
|
||||
|
||||
The compression options that you may be able to use are:
|
||||
|
||||
@@ -2292,25 +2382,18 @@ your home directory (remove the '=' for that).
|
||||
- `zlib`
|
||||
- `none`
|
||||
|
||||
Run `rsync -V` to see the compress list compiled into your version.
|
||||
Run `rsync --version` to see the default compress list compiled into your
|
||||
version (which may differ from the list above).
|
||||
|
||||
The "zlibx" algorithm is given preference over "zlib" if both sides of the
|
||||
transfer are at least version 3.2.0, otherwise it will choose "zlib" unless
|
||||
you override it via something like `-zz`. These 2 algorithms are the stame
|
||||
except that "zlibx" does not try to include matched data that was not
|
||||
transferred in the compression computations.
|
||||
Note that if you see an error about an option named `--old-compress` or
|
||||
`--new-compress`, this is rsync trying to send the `--compress-choice=zlib`
|
||||
or `--compress-choice=zlibx` option in a backward-compatible manner that
|
||||
more rsync versions understand. This error indicates that the older rsync
|
||||
version on the server will not allow you to force the compression type.
|
||||
|
||||
If "none" is specified, that is equivalent to using `--no-compress`.
|
||||
|
||||
This option implies `--compress` unless "none" was specified.
|
||||
|
||||
You can also override the compression negotiation using the
|
||||
RSYNC_COMPRESS_LIST environment variable by setting it to a space-separated
|
||||
list of compression names that you consider acceptable. If no common
|
||||
compress choice is found, the client exits with an error. It ignores
|
||||
"auto" and all unknown compression names. If the remote rsync is not new
|
||||
enough to handle a compression negotiation list, the list is silently
|
||||
ignored unless it contains the string "FAIL".
|
||||
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).
|
||||
|
||||
0. `--compress-level=NUM`, `--zl=NUM`
|
||||
|
||||
@@ -2321,8 +2404,8 @@ your home directory (remove the '=' for that).
|
||||
"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`
|
||||
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:
|
||||
|
||||
> rsync -aiv --zc=zstd --zl=22 host:src/ dest/
|
||||
@@ -2352,8 +2435,10 @@ your home directory (remove the '=' for that).
|
||||
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 have the level minimized to reduces the CPU usage as much as
|
||||
possible.
|
||||
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 **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
|
||||
@@ -2375,27 +2460,53 @@ your home directory (remove the '=' for that).
|
||||
|
||||
[comment]: # (This list gets used for the default-dont-compress.h file.)
|
||||
|
||||
> 3g2
|
||||
> 3gp
|
||||
> 7z
|
||||
> aac
|
||||
> ace
|
||||
> apk
|
||||
> avi
|
||||
> bz2
|
||||
> deb
|
||||
> dmg
|
||||
> ear
|
||||
> f4v
|
||||
> flac
|
||||
> flv
|
||||
> gpg
|
||||
> gz
|
||||
> iso
|
||||
> jar
|
||||
> jpeg
|
||||
> jpg
|
||||
> lrz
|
||||
> lz
|
||||
> lz4
|
||||
> lzma
|
||||
> lzo
|
||||
> m1a
|
||||
> m1v
|
||||
> m2a
|
||||
> m2ts
|
||||
> m2v
|
||||
> m4a
|
||||
> m4b
|
||||
> m4p
|
||||
> m4r
|
||||
> m4v
|
||||
> mka
|
||||
> mkv
|
||||
> mov
|
||||
> mp1
|
||||
> mp2
|
||||
> mp3
|
||||
> mp4
|
||||
> mpa
|
||||
> mpeg
|
||||
> mpg
|
||||
> mpv
|
||||
> mts
|
||||
> odb
|
||||
> odf
|
||||
> odg
|
||||
@@ -2404,8 +2515,11 @@ your home directory (remove the '=' for that).
|
||||
> odp
|
||||
> ods
|
||||
> odt
|
||||
> oga
|
||||
> ogg
|
||||
> ogm
|
||||
> ogv
|
||||
> ogx
|
||||
> opus
|
||||
> otg
|
||||
> oth
|
||||
@@ -2414,21 +2528,28 @@ your home directory (remove the '=' for that).
|
||||
> ott
|
||||
> oxt
|
||||
> png
|
||||
> qt
|
||||
> rar
|
||||
> rpm
|
||||
> rz
|
||||
> rzip
|
||||
> spx
|
||||
> squashfs
|
||||
> sxc
|
||||
> sxd
|
||||
> sxg
|
||||
> sxm
|
||||
> sxw
|
||||
> sz
|
||||
> tbz
|
||||
> tbz2
|
||||
> tgz
|
||||
> tlz
|
||||
> ts
|
||||
> txz
|
||||
> tzo
|
||||
> vob
|
||||
> war
|
||||
> webm
|
||||
> webp
|
||||
> xz
|
||||
@@ -2500,6 +2621,8 @@ your home directory (remove the '=' for that).
|
||||
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.
|
||||
|
||||
If your shell complains about the wildcards, use `--protect-args` (`-s`).
|
||||
|
||||
0. `--chown=USER:GROUP`
|
||||
|
||||
This option forces all files to be owned by USER with group GROUP. This is
|
||||
@@ -2510,7 +2633,8 @@ your home directory (remove the '=' for that).
|
||||
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.
|
||||
"`--usermap=*:foo --groupmap=*:bar`", only easier. If your shell complains
|
||||
about the wildcards, use `--protect-args` (`-s`).
|
||||
|
||||
0. `--timeout=SECONDS`
|
||||
|
||||
@@ -2598,12 +2722,14 @@ your home directory (remove the '=' for that).
|
||||
directory, an `L` for a symlink, a `D` for a device, and a `S` for a
|
||||
special file (e.g. named sockets and fifos).
|
||||
|
||||
The other letters in the string above are the actual letters that will be
|
||||
output if the associated attribute for the item is being updated or a "."
|
||||
for no change. Three exceptions to this are: (1) a newly created item
|
||||
replaces each letter with a "+", (2) an identical item replaces the dots
|
||||
with spaces, and (3) an unknown attribute replaces each letter with a "?"
|
||||
(this can happen when talking to an older rsync).
|
||||
The other letters in the string indicate if some attributes of the file
|
||||
have changed, as follows:
|
||||
|
||||
- "`.`" - the attribute is unchanged.
|
||||
- "`+`" - the file is newly created.
|
||||
- "` `" - all the attributes are unchanged (all dots turn to spaces).
|
||||
- "`?`" - the change is unknown (when the remote rsync is old).
|
||||
- A letter indicates an attribute is being updated.
|
||||
|
||||
The attribute that is associated with each letter is as follows:
|
||||
|
||||
@@ -2627,12 +2753,13 @@ your home directory (remove the '=' for that).
|
||||
value (requires `--owner` 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` means the access (use) time is different and is being updated to
|
||||
the sender's value (requires `--atimes`). An alternate value of `U`
|
||||
means that the access time will be set to the transfer time, which
|
||||
happens when a symlink or directory is updated.
|
||||
- The `a` means that the ACL information changed.
|
||||
- The `x` means that the extended attribute information changed.
|
||||
- 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.
|
||||
- The `a` means that the ACL information is being changed.
|
||||
- The `x` means that the extended attribute information is being changed.
|
||||
|
||||
One other output is possible: when deleting files, the "%i" will output the
|
||||
string "`*deleting`" for each item that is being removed (assuming that you
|
||||
@@ -2771,10 +2898,10 @@ your home directory (remove the '=' for that).
|
||||
level by one. You can take the level down to 0 (to output numbers as pure
|
||||
digits) by specifying the `--no-human-readable` (`--no-h`) option.
|
||||
|
||||
The unit letters that are appended in levels 2 and 3 are: K (kilo), M
|
||||
(mega), G (giga), or T (tera). For example, a 1234567-byte file would
|
||||
output as 1.23M in level-2 (assuming that a period is your local decimal
|
||||
point).
|
||||
The unit letters that are appended in levels 2 and 3 are: `K` (kilo), `M`
|
||||
(mega), `G` (giga), `T` (tera), or `P` (peta). For example, a 1234567-byte
|
||||
file would output as 1.23M in level-2 (assuming that a period is your local
|
||||
decimal point).
|
||||
|
||||
Backward compatibility note: versions of rsync prior to 3.1.0 do not
|
||||
support human-readable level 1, and they default to level 0. Thus,
|
||||
@@ -2869,6 +2996,9 @@ your home directory (remove the '=' for that).
|
||||
can do if you want rsync to cleanup old `.~tmp~` dirs that might be lying
|
||||
around. Conflicts with `--inplace` and `--append`.
|
||||
|
||||
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 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
|
||||
@@ -3053,7 +3183,7 @@ your home directory (remove the '=' for that).
|
||||
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 zero specifies no limit.
|
||||
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
|
||||
@@ -3071,12 +3201,57 @@ your home directory (remove the '=' for that).
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
format of year-month-dayThour:minute (e.g. 2000-12-31T23:59) in the local
|
||||
timezone. You may choose to separate the date numbers using slashes
|
||||
instead of dashes.
|
||||
|
||||
The value can also be abbreviated in a variety of ways, such as specifying
|
||||
a 2-digit year and/or leaving off various values. In all cases, the value
|
||||
will be taken to be the next possible point in time where the supplied
|
||||
information matches. If the value specifies the current time or a past
|
||||
time, rsync exits with an error.
|
||||
|
||||
For example, "1-30" specifies the next January 30th (at midnight local
|
||||
time), "14:00" specifies the next 2 P.M., "1" specifies the next 1st of the
|
||||
month at midnight, "31" specifies the next month where we can stop on its
|
||||
31st day, and ":59" specifies the next 59th minute after the hour.
|
||||
|
||||
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. Do keep in
|
||||
mind that the remote host may have a different default timezone than your
|
||||
local host.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
0. `--only-write-batch=FILE`
|
||||
|
||||
Works like `--write-batch`, except that no updates are made on the
|
||||
@@ -3157,8 +3332,8 @@ your home directory (remove the '=' for that).
|
||||
These options also exist in the `--daemon` mode section.
|
||||
|
||||
If rsync was complied without support for IPv6, the `--ipv6` option will
|
||||
have no effect. The `rsync -V` output will contain "`no IPv6`" if is the
|
||||
case.
|
||||
have no effect. The `rsync --version` output will contain "`no IPv6`" if
|
||||
is the case.
|
||||
|
||||
0. `--checksum-seed=NUM`
|
||||
|
||||
@@ -3271,8 +3446,8 @@ The options allowed when starting an rsync daemon are as follows:
|
||||
These options also exist in the regular rsync options section.
|
||||
|
||||
If rsync was complied without support for IPv6, the `--ipv6` option will
|
||||
have no effect. The `rsync -V` output will contain "`no IPv6`" if is the
|
||||
case.
|
||||
have no effect. The `rsync --version` output will contain "`no IPv6`" if
|
||||
is the case.
|
||||
|
||||
0. `--help`, `-h`
|
||||
|
||||
|
||||
17
rsync.c
17
rsync.c
@@ -584,6 +584,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
|
||||
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 (!(flags & ATTRS_SKIP_MTIME) && !same_mtime(file, &sxp->st, flags & ATTRS_ACCURATE_TIME)) {
|
||||
sx2.st.st_mtime = file->modtime;
|
||||
#ifdef ST_MTIME_NSEC
|
||||
@@ -613,6 +616,16 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
|
||||
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
|
||||
@@ -718,7 +731,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
|
||||
|
||||
/* Change permissions before putting the file into place. */
|
||||
set_file_attrs(fnametmp, file, NULL, fnamecmp,
|
||||
ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME);
|
||||
ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME | ATTRS_SKIP_CRTIME);
|
||||
|
||||
/* move tmp file over real file */
|
||||
if (DEBUG_GTE(RECV, 1))
|
||||
@@ -743,7 +756,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
|
||||
|
||||
do_set_file_attrs:
|
||||
set_file_attrs(fnametmp, file, NULL, fnamecmp,
|
||||
ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME);
|
||||
ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME | ATTRS_SKIP_CRTIME);
|
||||
|
||||
if (temp_copy_name) {
|
||||
if (do_rename(fnametmp, fname) < 0) {
|
||||
|
||||
95
rsync.h
95
rsync.h
@@ -20,6 +20,7 @@
|
||||
|
||||
#define False 0
|
||||
#define True 1
|
||||
#define Unset (-1) /* Our BOOL values are always an int. */
|
||||
|
||||
#define BLOCK_SIZE 700
|
||||
#define RSYNC_RSH_ENV "RSYNC_RSH"
|
||||
@@ -69,7 +70,7 @@
|
||||
/* The following XMIT flags require an rsync that uses a varint for the flag values */
|
||||
|
||||
#define XMIT_RESERVED_16 (1<<16) /* reserved for future fileflags use */
|
||||
#define XMIT_RESERVED_17 (1<<17) /* reserved for future crtimes use */
|
||||
#define XMIT_CRTIME_EQ_MTIME (1<<17) /* any protocol - restricted by command-line option */
|
||||
|
||||
/* These flags are used in the live flist data. */
|
||||
|
||||
@@ -181,6 +182,7 @@
|
||||
#define ATTRS_SKIP_MTIME (1<<1)
|
||||
#define ATTRS_ACCURATE_TIME (1<<2)
|
||||
#define ATTRS_SKIP_ATIME (1<<3)
|
||||
#define ATTRS_SKIP_CRTIME (1<<5)
|
||||
|
||||
#define MSG_FLUSH 2
|
||||
#define FULL_FLUSH 1
|
||||
@@ -208,6 +210,7 @@
|
||||
#define ITEM_REPORT_GROUP (1<<6)
|
||||
#define ITEM_REPORT_ACL (1<<7)
|
||||
#define ITEM_REPORT_XATTR (1<<8)
|
||||
#define ITEM_REPORT_CRTIME (1<<10)
|
||||
#define ITEM_BASIS_TYPE_FOLLOWS (1<<11)
|
||||
#define ITEM_XNAME_FOLLOWS (1<<12)
|
||||
#define ITEM_IS_NEW (1<<13)
|
||||
@@ -297,6 +300,7 @@ enum delret {
|
||||
#include "errcode.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "version.h"
|
||||
|
||||
/* The default RSYNC_RSH is always set in config.h. */
|
||||
|
||||
@@ -440,7 +444,9 @@ enum delret {
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#include <syslog.h>
|
||||
#ifdef HAVE_SYS_FILE_H
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DIRENT_H
|
||||
# include <dirent.h>
|
||||
@@ -469,7 +475,23 @@ enum delret {
|
||||
#ifdef MAKEDEV_TAKES_3_ARGS
|
||||
#define MAKEDEV(devmajor,devminor) makedev(0,devmajor,devminor)
|
||||
#else
|
||||
#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
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __TANDEM
|
||||
# include <floss.h(floss_read,floss_write,floss_fork,floss_execvp)>
|
||||
# include <floss.h(floss_getpwuid,floss_select,floss_seteuid)>
|
||||
# define S_IEXEC S_IXUSR
|
||||
# define ROOT_UID 65535
|
||||
#else
|
||||
# define ROOT_UID 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COMPAT_H
|
||||
@@ -548,6 +570,14 @@ typedef unsigned int size_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__ /* Do we need a configure check for this? */
|
||||
#define SUPPORT_ATIMES 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETATTRLIST
|
||||
#define SUPPORT_CRTIMES 1
|
||||
#endif
|
||||
|
||||
/* Find a variable that is either exactly 32-bits or longer.
|
||||
* If some code depends on 32-bit truncation, it will need to
|
||||
* take special action in a "#if SIZEOF_INT32 > 4" section. */
|
||||
@@ -691,6 +721,10 @@ struct ht_int64_node {
|
||||
#define NAME_MAX 255
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX ((size_t)-1)
|
||||
#endif
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
@@ -730,6 +764,10 @@ struct ht_int64_node {
|
||||
# error Character pointers are not 4 or 8 bytes.
|
||||
#endif
|
||||
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
#define USE_FLEXIBLE_ARRAY 1
|
||||
#endif
|
||||
|
||||
union file_extras {
|
||||
int32 num;
|
||||
uint32 unum;
|
||||
@@ -751,12 +789,17 @@ struct file_struct {
|
||||
uint32 len32; /* Lowest 32 bits of the file's length */
|
||||
uint16 mode; /* The item's type and permissions */
|
||||
uint16 flags; /* The FLAG_* bits for this item */
|
||||
const char basename[1]; /* The basename (AKA filename) follows */
|
||||
#ifdef USE_FLEXIBLE_ARRAY
|
||||
const char basename[]; /* The basename (AKA filename) follows */
|
||||
#else
|
||||
const char basename[1]; /* A kluge that should work like a flexible array */
|
||||
#endif
|
||||
};
|
||||
|
||||
extern int file_extra_cnt;
|
||||
extern int inc_recurse;
|
||||
extern int atimes_ndx;
|
||||
extern int crtimes_ndx;
|
||||
extern int pathname_ndx;
|
||||
extern int depth_ndx;
|
||||
extern int uid_ndx;
|
||||
@@ -764,7 +807,11 @@ extern int gid_ndx;
|
||||
extern int acls_ndx;
|
||||
extern int xattrs_ndx;
|
||||
|
||||
#ifdef USE_FLEXIBLE_ARRAY
|
||||
#define FILE_STRUCT_LEN (sizeof (struct file_struct))
|
||||
#else
|
||||
#define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
|
||||
#endif
|
||||
#define EXTRA_LEN (sizeof (union file_extras))
|
||||
#define DEV_EXTRA_CNT 2
|
||||
#define DIRNODE_EXTRA_CNT 3
|
||||
@@ -815,6 +862,7 @@ extern int xattrs_ndx;
|
||||
#define F_XATTR(f) REQ_EXTRA(f, xattrs_ndx)->num
|
||||
#define F_NDX(f) REQ_EXTRA(f, unsort_ndx)->num
|
||||
#define F_ATIME(f) REQ_EXTRA64(f, atimes_ndx)->num
|
||||
#define F_CRTIME(f) REQ_EXTRA64(f, crtimes_ndx)->num
|
||||
|
||||
/* These items are per-entry optional: */
|
||||
#define F_HL_GNUM(f) OPT_EXTRA(f, START_BUMP(f))->num /* non-dirs */
|
||||
@@ -1033,9 +1081,19 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
char name_type;
|
||||
char fname[1]; /* has variable size */
|
||||
#ifdef USE_FLEXIBLE_ARRAY
|
||||
char fname[]; /* has variable size */
|
||||
#else
|
||||
char fname[1]; /* A kluge that should work like a flexible array */
|
||||
#endif
|
||||
} relnamecache;
|
||||
|
||||
#ifdef USE_FLEXIBLE_ARRAY
|
||||
#define RELNAMECACHE_LEN (sizeof (relnamecache))
|
||||
#else
|
||||
#define RELNAMECACHE_LEN (offsetof(relnamecache, fname))
|
||||
#endif
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "lib/mdigest.h"
|
||||
#include "lib/wildmatch.h"
|
||||
@@ -1057,6 +1115,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
STRUCT_STAT st;
|
||||
time_t crtime;
|
||||
#ifdef SUPPORT_ACLS
|
||||
struct rsync_acl *acc_acl; /* access ACL */
|
||||
struct rsync_acl *def_acl; /* default ACL */
|
||||
@@ -1078,6 +1137,9 @@ typedef struct {
|
||||
#define CPRES_LZ4 3
|
||||
#define CPRES_ZSTD 4
|
||||
|
||||
#define NSTR_CHECKSUM 0
|
||||
#define NSTR_COMPRESS 1
|
||||
|
||||
struct name_num_item {
|
||||
int num;
|
||||
const char *name, *main_name;
|
||||
@@ -1089,7 +1151,7 @@ struct name_num_obj {
|
||||
uchar *saw;
|
||||
int saw_len;
|
||||
int negotiated_num;
|
||||
struct name_num_item list[];
|
||||
struct name_num_item list[8]; /* A big-enough len (we'll get a compile error if it is ever too small) */
|
||||
};
|
||||
|
||||
#ifndef __cplusplus
|
||||
@@ -1262,12 +1324,22 @@ extern int errno;
|
||||
/* handler for null strings in printf format */
|
||||
#define NS(s) ((s)?(s):"<NULL>")
|
||||
|
||||
extern char *do_calloc;
|
||||
|
||||
/* Convenient wrappers for malloc and realloc. Use them. */
|
||||
#define new(type) ((type*)malloc(sizeof (type)))
|
||||
#define new0(type) ((type*)calloc(1, sizeof (type)))
|
||||
#define new_array(type, num) ((type*)_new_array((num), sizeof (type), 0))
|
||||
#define new_array0(type, num) ((type*)_new_array((num), sizeof (type), 1))
|
||||
#define realloc_array(ptr, type, num) ((type*)_realloc_array((ptr), sizeof(type), (num)))
|
||||
#define new(type) ((type*)my_alloc(NULL, sizeof (type), 1, __FILE__, __LINE__))
|
||||
#define new0(type) ((type*)my_alloc(do_calloc, sizeof (type), 1, __FILE__, __LINE__))
|
||||
#define realloc_buf(ptr, num) my_alloc((ptr), (num), 1, __FILE__, __LINE__)
|
||||
|
||||
#define new_array(type, num) ((type*)my_alloc(NULL, (num), sizeof (type), __FILE__, __LINE__))
|
||||
#define new_array0(type, num) ((type*)my_alloc(do_calloc, (num), sizeof (type), __FILE__, __LINE__))
|
||||
#define realloc_array(ptr, type, num) ((type*)my_alloc((ptr), (num), sizeof (type), __FILE__, __LINE__))
|
||||
|
||||
#undef strdup
|
||||
#define strdup(s) my_strdup(s, __FILE__, __LINE__)
|
||||
|
||||
#define out_of_memory(msg) _out_of_memory(msg, __FILE__, __LINE__)
|
||||
#define overflow_exit(msg) _overflow_exit(msg, __FILE__, __LINE__)
|
||||
|
||||
/* use magic gcc attributes to catch format errors */
|
||||
void rprintf(enum logcode , const char *, ...)
|
||||
@@ -1383,3 +1455,8 @@ char *getpass(const char *prompt);
|
||||
#ifdef MAINTAINER_MODE
|
||||
const char *get_panic_action(void);
|
||||
#endif
|
||||
|
||||
#define NOISY_DEATH(msg) do { \
|
||||
fprintf(stderr, "%s in %s at line %d\n", msg, __FILE__, __LINE__); \
|
||||
exit_cleanup(RERR_UNSUPPORTED); \
|
||||
} while (0)
|
||||
|
||||
@@ -207,21 +207,18 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
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, the "numeric-ids" option will also default
|
||||
to being enabled (disabling name lookups). See below for what a chroot
|
||||
needs in order for name lookups to succeed.
|
||||
When this parameter is enabled *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
|
||||
lookups.
|
||||
|
||||
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
|
||||
that parameter). At that point it will be safe to enable the mapping of
|
||||
users and groups by name using the "numeric ids" daemon parameter (see
|
||||
below).
|
||||
|
||||
Note also that you are free to setup custom user/group information in the
|
||||
chroot area that is different from your normal system. For example, you
|
||||
could abbreviate the list of users and groups.
|
||||
that parameter). However, it's easier and safer to setup a name converter.
|
||||
|
||||
0. `daemon chroot`
|
||||
|
||||
@@ -258,6 +255,27 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
others, then you will need to setup multiple rsync daemon processes on
|
||||
different ports.
|
||||
|
||||
0. `name converter`
|
||||
|
||||
This parameter lets you specify a program that will be run by the rsync
|
||||
daemon to do user & group conversions between names & ids. This script
|
||||
is started prior to any chroot being setup, and runs as the daemon user
|
||||
(not the transfer user). You can specify a fully qualified pathname or
|
||||
a program name that is on the $PATH.
|
||||
|
||||
The program can be used to do normal user & group lookups without having to
|
||||
put any extra files into the chroot area of the module *or* you can do
|
||||
customized conversions.
|
||||
|
||||
The nameconvert program has access to all of the environment variables that
|
||||
are described in the section on `pre-xfer exec`. This is useful if you
|
||||
want to customize the conversion using information about the module and/or
|
||||
the copy request.
|
||||
|
||||
There is a sample python script in the support dir named "nameconvert" that
|
||||
implements the normal user & group lookups. Feel free to customize it or
|
||||
just use it as documentation to implement your own.
|
||||
|
||||
0. `numeric ids`
|
||||
|
||||
Enabling this parameter disables the mapping of users and groups by name
|
||||
@@ -269,13 +287,10 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
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 enabled unless
|
||||
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. That includes being the code being able to call functions
|
||||
like **getpwuid()**, **getgrgid()**, **getpwname()**, and **getgrnam()**.
|
||||
You should test what libraries and config files are required for your OS
|
||||
and get those setup before starting to test name mapping in rsync.
|
||||
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
|
||||
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.
|
||||
|
||||
0. `munge symlinks`
|
||||
|
||||
@@ -424,6 +439,22 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
Helpful hint: you probably want to specify "refuse options = delete" for a
|
||||
write-only module.
|
||||
|
||||
0. `open noatime`
|
||||
|
||||
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
|
||||
that are being transferred. If your OS does not support the O_NOATIME flag
|
||||
then rsync will silently ignore this option. Note also that some
|
||||
filesystems are mounted to avoid updating the atime on read access even
|
||||
without the O_NOATIME flag being set.
|
||||
|
||||
When set to False, this parameters ensures that files on the server are not
|
||||
opened with O_NOATIME.
|
||||
|
||||
When set to Unset (the default) the user controls the setting via
|
||||
`--open-noatime`.
|
||||
|
||||
0. `list`
|
||||
|
||||
This parameter determines whether this module is listed when the client
|
||||
@@ -669,7 +700,7 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
client's hostname and IP address. If none of the patterns match, then the
|
||||
connection is rejected.
|
||||
|
||||
Each pattern can be in one of five forms:
|
||||
Each pattern can be in one of six forms:
|
||||
|
||||
- a dotted decimal IPv4 address of the form a.b.c.d, or an IPv6 address of
|
||||
the form a:b:c::d:e:f. In this case the incoming machine's IP address
|
||||
@@ -689,6 +720,8 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
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.
|
||||
|
||||
Note IPv6 link-local addresses can have a scope in the address
|
||||
specification:
|
||||
@@ -697,12 +730,12 @@ 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 a separate "hosts deny" parameter.
|
||||
If both parameters are specified then the "hosts allow" parameter is
|
||||
checked first and a match results in the client being able to connect. The
|
||||
"hosts deny" parameter is then checked and a match means that the host is
|
||||
rejected. If the host does not match either the "hosts allow" or the
|
||||
"hosts deny" patterns then it is allowed to connect.
|
||||
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
|
||||
match either list is allowed to connect.
|
||||
|
||||
The default is no "hosts allow" parameter, which means all hosts can
|
||||
connect.
|
||||
@@ -905,15 +938,15 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
|
||||
- `--server`: Required for rsync to even work.
|
||||
- `--rsh`, `-e`: Required to convey compatibility flags to the server.
|
||||
- `--log-format`: This is required to convey things like
|
||||
`--itemize-changes` to a remote receiver. Is an older name for
|
||||
`--out-format` that is still passed to the server for improved backward
|
||||
compatibility and should not be confused with `--log-file-format`.
|
||||
- `--out-format`: This is required to convey output behavior to a remote
|
||||
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.
|
||||
- `--dry-run`, `-n`: Who would want to disable this?
|
||||
- `--protect-args`, `-n`: This actually makes transfers safer.
|
||||
- `--from0`, `-0`: Make it easier to accept/refuse `--files-from` without
|
||||
affecting this modifier.
|
||||
- `--protect-args`, `-s`: This actually makes transfers safer.
|
||||
- `--from0`, `-0`: Makes it easier to accept/refuse `--files-from` without
|
||||
affecting this helpful modifier.
|
||||
- `--iconv`: This is auto-disabled based on "charset" parameter.
|
||||
- `--no-iconv`: Most transfers use this option.
|
||||
- `--checksum-seed`: Is a fairly rare, safe option.
|
||||
@@ -1105,7 +1138,7 @@ An example nginx proxy setup is as follows:
|
||||
> listen [::]:874 ssl;
|
||||
>
|
||||
> ssl_certificate /etc/letsencrypt/example.com/fullchain.pem;
|
||||
> ssl_certificate_key /etc/letsencrypt/example.com/privkey.pem
|
||||
> ssl_certificate_key /etc/letsencrypt/example.com/privkey.pem;
|
||||
>
|
||||
> proxy_pass localhost:873;
|
||||
> proxy_protocol on; # Requires "proxy protocol = true"
|
||||
|
||||
@@ -249,7 +249,7 @@ prep_scratch() {
|
||||
[ -d "$scratchdir" ] && chmod -R u+rwX "$scratchdir" && rm -rf "$scratchdir"
|
||||
mkdir "$scratchdir"
|
||||
# Get rid of default ACLs and dir-setgid to avoid confusing some tests.
|
||||
$setfacl_nodef "$scratchdir" || true
|
||||
$setfacl_nodef "$scratchdir" 2>/dev/null || true
|
||||
chmod g-s "$scratchdir"
|
||||
case "$srcdir" in
|
||||
/*) ln -s "$srcdir" "$scratchdir/src" ;;
|
||||
@@ -339,5 +339,8 @@ echo '------------------------------------------------------------'
|
||||
# because -e is set.
|
||||
|
||||
result=`expr $failed + $missing || true`
|
||||
if [ "$result" = 0 -a "$skipped" -gt "${RSYNC_MAX_SKIPPED:-9999}" ]; then
|
||||
result=1
|
||||
fi
|
||||
echo "overall result is $result"
|
||||
exit $result
|
||||
|
||||
10
sender.c
10
sender.c
@@ -65,13 +65,10 @@ BOOL extra_flist_sending_enabled;
|
||||
**/
|
||||
static struct sum_struct *receive_sums(int f)
|
||||
{
|
||||
struct sum_struct *s;
|
||||
int32 i;
|
||||
struct sum_struct *s = new(struct sum_struct);
|
||||
int lull_mod = protocol_version >= 31 ? 0 : allowed_lull * 5;
|
||||
OFF_T offset = 0;
|
||||
|
||||
if (!(s = new(struct sum_struct)))
|
||||
out_of_memory("receive_sums");
|
||||
int32 i;
|
||||
|
||||
read_sum_head(f, s);
|
||||
|
||||
@@ -92,8 +89,7 @@ static struct sum_struct *receive_sums(int f)
|
||||
if (s->count == 0)
|
||||
return(s);
|
||||
|
||||
if (!(s->sums = new_array(struct sum_buf, s->count)))
|
||||
out_of_memory("receive_sums");
|
||||
s->sums = new_array(struct sum_buf, s->count);
|
||||
|
||||
for (i = 0; i < s->count; i++) {
|
||||
s->sums[i].sum1 = read_int(f);
|
||||
|
||||
11
socket.c
11
socket.c
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#include "ifuncs.h"
|
||||
#ifdef HAVE_NETINET_IN_SYSTM_H
|
||||
#include <netinet/in_systm.h>
|
||||
#endif
|
||||
@@ -248,8 +249,6 @@ int open_socket_out(char *host, int port, const char *bind_addr, int af_hint)
|
||||
|
||||
for (res = res0, addr_cnt = 0; res; res = res->ai_next, addr_cnt++) {}
|
||||
errnos = new_array0(int, addr_cnt);
|
||||
if (!errnos)
|
||||
out_of_memory("open_socket_out");
|
||||
|
||||
s = -1;
|
||||
/* Try to connect to all addresses for this machine until we get
|
||||
@@ -354,8 +353,7 @@ int open_socket_out_wrapped(char *host, int port, const char *bind_addr, int af_
|
||||
len += hlen;
|
||||
}
|
||||
f = prog;
|
||||
if (!(prog = new_array(char, len)))
|
||||
out_of_memory("open_socket_out_wrapped");
|
||||
prog = new_array(char, len);
|
||||
for (t = prog; *f; f++) {
|
||||
if (*f == '%') {
|
||||
switch (*++f) {
|
||||
@@ -423,8 +421,6 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
|
||||
|
||||
socks = new_array(int, maxs + 1);
|
||||
errmsgs = new_array(char *, maxs);
|
||||
if (!socks || !errmsgs)
|
||||
out_of_memory("open_socket_in");
|
||||
|
||||
/* We may not be able to create the socket, if for example the
|
||||
* machine knows about IPv6 in the C library, but not in the
|
||||
@@ -684,9 +680,6 @@ void set_socket_options(int fd, char *options)
|
||||
|
||||
options = strdup(options);
|
||||
|
||||
if (!options)
|
||||
out_of_memory("set_socket_options");
|
||||
|
||||
for (tok = strtok(options, " \t,"); tok; tok = strtok(NULL," \t,")) {
|
||||
int ret=0,i;
|
||||
int value = 1;
|
||||
|
||||
@@ -79,10 +79,10 @@ def print_line(fn, mtime, commit_time):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description="Set the times of the current git checkout to their last-changed time.", add_help=False)
|
||||
parser = argparse.ArgumentParser(description="Set the times of the files in the current git checkout to their last-changed time.", add_help=False)
|
||||
parser.add_argument('--git-dir', metavar='GIT_DIR', help="The git dir to query (defaults to affecting the current git checkout).")
|
||||
parser.add_argument('--tree', metavar='TREE-ISH', help="The tree-ish to query (defaults to the current branch).")
|
||||
parser.add_argument('--prefix', metavar='PREFIX_STR', help="Prepend the PREFIX_STR to each filename we tweak.")
|
||||
parser.add_argument('--prefix', metavar='PREFIX_STR', help="Prepend the PREFIX_STR to each filename we tweak (defaults to the top of current checkout).")
|
||||
parser.add_argument('--quiet', '-q', action='store_true', help="Don't output the changed-file information.")
|
||||
parser.add_argument('--list', '-l', action='count', help="List files & times instead of changing them. Repeat for Unix timestamp instead of human readable.")
|
||||
parser.add_argument('files', metavar='FILE', nargs='*', help="Specify a subset of checked-out files to tweak.")
|
||||
|
||||
20
support/lsh
20
support/lsh
@@ -1,10 +1,6 @@
|
||||
#!/usr/bin/env perl
|
||||
# This script can be used as a "remote shell" command that is only
|
||||
# capable of pretending to connect to "localhost". This is useful
|
||||
# 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 -l USER, we try to become the USER, either directly (must
|
||||
# be root) or by using "sudo -H -u USER" (requires --sudo option).
|
||||
# This is a "local shell" command that works like a remote shell but only for
|
||||
# the local host. See the usage message for more details.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
@@ -78,9 +74,15 @@ die "Failed to exec: $!\n";
|
||||
sub usage
|
||||
{
|
||||
die <<EOT;
|
||||
Usage: lsh [-l user] [--sudo] [--no-cd] localhost COMMAND [...]
|
||||
Usage: lsh [-l USER] [--sudo] [--no-cd] localhost COMMAND [...]
|
||||
|
||||
Note that if you pass hostname "lh" instead of "localhost" that
|
||||
the --no-cd option is implied.
|
||||
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.
|
||||
EOT
|
||||
}
|
||||
|
||||
50
support/nameconvert
Executable file
50
support/nameconvert
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This implements a simple protocol to do user & group conversions between
|
||||
# names & ids. All input and output consists of simple strings with a
|
||||
# terminating newline.
|
||||
#
|
||||
# The requests can be:
|
||||
#
|
||||
# uid ID_NUM\n -> NAME\n
|
||||
# gid ID_NUM\n -> NAME\n
|
||||
# usr NAME\n -> ID_NUM\n
|
||||
# grp NAME\n -> ID_NUM\n
|
||||
#
|
||||
# An unknown ID_NUM or NAME results in an empty return value.
|
||||
#
|
||||
# This is used by an rsync daemon when configured with the "name converter" and
|
||||
# (often) "use chroot = true". While this converter uses real user & group
|
||||
# lookups you could change it to use any mapping idiom you'd like.
|
||||
|
||||
import sys, argparse, pwd, grp
|
||||
|
||||
def main():
|
||||
for line in sys.stdin:
|
||||
try:
|
||||
req, arg = line.rstrip().split(' ', 1)
|
||||
except:
|
||||
req = None
|
||||
try:
|
||||
if req == 'uid':
|
||||
ans = pwd.getpwuid(int(arg)).pw_name
|
||||
elif req == 'gid':
|
||||
ans = grp.getgrgid(int(arg)).gr_name
|
||||
elif req == 'usr':
|
||||
ans = pwd.getpwnam(arg).pw_uid
|
||||
elif req == 'grp':
|
||||
ans = grp.getgrnam(arg).gr_gid
|
||||
else:
|
||||
print("Invalid request", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except KeyError:
|
||||
ans = ''
|
||||
print(ans, flush=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description="Convert users & groups between names & numbers for an rsync daemon.")
|
||||
args = parser.parse_args()
|
||||
main()
|
||||
|
||||
# vim: sw=4 et
|
||||
@@ -111,6 +111,7 @@ our %long_opt = (
|
||||
'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,
|
||||
|
||||
53
syscall.c
53
syscall.c
@@ -54,6 +54,15 @@ extern int open_noatime;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
#pragma pack(push, 4)
|
||||
struct create_time {
|
||||
uint32 length;
|
||||
struct timespec crtime;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#define RETURN_ERROR_IF(x,e) \
|
||||
do { \
|
||||
if (x) { \
|
||||
@@ -120,12 +129,16 @@ ssize_t do_readlink(const char *path, char *buf, size_t bufsiz)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINK
|
||||
#if defined HAVE_LINK || defined HAVE_LINKAT
|
||||
int do_link(const char *old_path, const char *new_path)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
#ifdef HAVE_LINKAT
|
||||
return linkat(AT_FDCWD, old_path, AT_FDCWD, new_path, 0);
|
||||
#else
|
||||
return link(old_path, new_path);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -385,6 +398,40 @@ int do_setattrlist_times(const char *fname, STRUCT_STAT *stp)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
time_t get_create_time(const char *path)
|
||||
{
|
||||
static struct create_time attrBuf;
|
||||
struct attrlist attrList;
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
int set_create_time(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);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
int do_utimensat(const char *fname, STRUCT_STAT *stp)
|
||||
{
|
||||
@@ -523,7 +570,7 @@ OFF_T do_fallocate(int fd, OFF_T offset, OFF_T length)
|
||||
|
||||
/* Punch a hole at pos for len bytes. The current file position must be at pos and will be
|
||||
* changed to be at pos + len. */
|
||||
int do_punch_hole(int fd, UNUSED(OFF_T pos), OFF_T len)
|
||||
int do_punch_hole(int fd, OFF_T pos, OFF_T len)
|
||||
{
|
||||
#ifdef HAVE_FALLOCATE
|
||||
# ifdef HAVE_FALLOC_FL_PUNCH_HOLE
|
||||
@@ -540,6 +587,8 @@ int do_punch_hole(int fd, UNUSED(OFF_T pos), OFF_T len)
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
(void)pos;
|
||||
#endif
|
||||
{
|
||||
char zeros[4096];
|
||||
|
||||
1
t_stub.c
1
t_stub.c
@@ -33,6 +33,7 @@ int preserve_xattrs = 0;
|
||||
int preserve_perms = 0;
|
||||
int preserve_executability = 0;
|
||||
int open_noatime = 0;
|
||||
size_t max_alloc = 0; /* max_alloc is needed when combined with util2.o */
|
||||
char *partial_dir;
|
||||
char *module_dir;
|
||||
filter_rule_list daemon_filter_list;
|
||||
|
||||
@@ -37,6 +37,13 @@ EOF
|
||||
done
|
||||
}
|
||||
;;
|
||||
freebsd*)
|
||||
chown() {
|
||||
own=$1
|
||||
shift
|
||||
setextattr -h user "rsync.%stat" "100644 0,0 $own" "${@}"
|
||||
}
|
||||
;;
|
||||
*)
|
||||
chown() {
|
||||
own=$1
|
||||
@@ -48,15 +55,16 @@ EOF
|
||||
;;
|
||||
*)
|
||||
RSYNC="$RSYNC --super"
|
||||
case `get_testuid` in
|
||||
'') ;; # If "id" failed, try to continue...
|
||||
0) ;;
|
||||
*) if [ -e "$FAKEROOT_PATH" ]; then
|
||||
my_uid=`get_testuid`
|
||||
root_uid=`get_rootuid`
|
||||
if test x"$my_uid" = x; then
|
||||
: # If "id" failed, try to continue...
|
||||
elif test x"$my_uid" != x"$root_uid"; then
|
||||
if [ -e "$FAKEROOT_PATH" ]; then
|
||||
echo "Let's try re-running the script under fakeroot..."
|
||||
exec "$FAKEROOT_PATH" "$SHELL_PATH" "$0"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
26
testsuite/crtimes.test
Normal file
26
testsuite/crtimes.test
Normal file
@@ -0,0 +1,26 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Test rsync copying create times
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
$RSYNC --version | grep "[, ] crtimes" >/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"
|
||||
|
||||
touch -t 200101011111.11 "$fromdir"
|
||||
touch -t 200202022222.22 "$fromdir"
|
||||
|
||||
touch -t 200111111111.11 "$fromdir/foo"
|
||||
touch -t 200212122222.22 "$fromdir/foo"
|
||||
|
||||
TLS_ARGS=--crtimes
|
||||
|
||||
checkit "$RSYNC -rtgvvv --crtimes \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
@@ -41,14 +41,14 @@ cd "$scratchdir"
|
||||
|
||||
ln -s test-rsyncd.conf rsyncd.conf
|
||||
|
||||
my_uid=`get_testuid`
|
||||
root_uid=`get_rootuid`
|
||||
confopt=''
|
||||
case `get_testuid` in
|
||||
0)
|
||||
if test x"$my_uid" = x"$root_uid"; then
|
||||
# Root needs to specify the config file, or it uses /etc/rsyncd.conf.
|
||||
echo "Forcing --config=$conf"
|
||||
confopt=" --config=$conf"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# These have a space-padded 15-char name, then a tab, then a comment.
|
||||
sed 's/NOCOMMENT//' <<EOT >"$chkfile"
|
||||
@@ -91,12 +91,13 @@ drwxr-xr-x DIR ####/##/## ##:##:## foo
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
|
||||
|
||||
$RSYNC -rU localhost::test-from/f* \
|
||||
| sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
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"
|
||||
drwxr-xr-x DIR ####/##/## ##:##:## foo
|
||||
-rw-r--r-- 4 ####/##/## ##:##:## ####/##/## ##:##:## foo/one
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
|
||||
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
|
||||
fi
|
||||
|
||||
@@ -50,6 +50,20 @@ echo "$mode $maj,$min 0:0" > rsync.%stat
|
||||
EOF
|
||||
}
|
||||
;;
|
||||
freebsd*)
|
||||
mknod() {
|
||||
fn="$1"
|
||||
case "$2" in
|
||||
p) mode=10644 ;;
|
||||
c) mode=20644 ;;
|
||||
b) mode=60644 ;;
|
||||
esac
|
||||
maj="${3:-0}"
|
||||
min="${4:-0}"
|
||||
touch "$fn"
|
||||
setextattr -h user "rsync.%stat" "$mode $maj,$min 0:0" "$fn"
|
||||
}
|
||||
;;
|
||||
*)
|
||||
mknod() {
|
||||
fn="$1"
|
||||
@@ -67,21 +81,24 @@ EOF
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
case `get_testuid` in
|
||||
'') ;; # If "id" failed, try to continue...
|
||||
0) ;;
|
||||
*) if [ -e "$FAKEROOT_PATH" ]; then
|
||||
my_uid=`get_testuid`
|
||||
root_uid=`get_rootuid`
|
||||
if test x"$my_uid" = x; then
|
||||
: # If "id" failed, try to continue...
|
||||
elif test x"$my_uid" != x"$root_uid"; then
|
||||
if [ -e "$FAKEROOT_PATH" ]; then
|
||||
echo "Let's try re-running the script under fakeroot..."
|
||||
exec "$FAKEROOT_PATH" "$SHELL_PATH" $RUNSHFLAGS "$0"
|
||||
fi
|
||||
test_skipped "Rsync needs root/fakeroot for device tests"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
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
|
||||
|
||||
mkdir "$fromdir"
|
||||
mkdir "$todir"
|
||||
mknod "$fromdir/char" c 41 67 || test_skipped "Can't create char device node"
|
||||
@@ -90,7 +107,11 @@ mknod "$fromdir/char3" c 42 69 || test_skipped "Can't create char device node"
|
||||
mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node"
|
||||
mknod "$fromdir/block2" b 42 73 || test_skipped "Can't create block device node"
|
||||
mknod "$fromdir/block3" b 105 73 || test_skipped "Can't create block device node"
|
||||
ln "$fromdir/block3" "$fromdir/block3.5" || echo "Skipping hard-linked device test..."
|
||||
if test "$CAN_HLINK_SPECIAL" = yes; then
|
||||
ln "$fromdir/block3" "$fromdir/block3.5"
|
||||
else
|
||||
echo "Skipping hard-linked device test..."
|
||||
fi
|
||||
mkfifo "$fromdir/fifo" || mknod "$fromdir/fifo" p || test_skipped "Can't run mkfifo"
|
||||
# Work around time rounding/truncating issue by touching both files.
|
||||
touch -r "$fromdir/block" "$fromdir/block" "$fromdir/block2"
|
||||
@@ -132,7 +153,7 @@ cD$all_plus char2
|
||||
cD$all_plus char3
|
||||
cS$all_plus fifo
|
||||
EOT
|
||||
if test ! -r "$fromdir/block3.5"; then
|
||||
if test "$CAN_HLINK_SPECIAL" = no; then
|
||||
grep -v block3.5 <"$chkfile" >"$chkfile.new"
|
||||
mv "$chkfile.new" "$chkfile"
|
||||
fi
|
||||
@@ -144,7 +165,7 @@ echo ""
|
||||
( cd "$todir" && rsync_ls_lR . ) > "$tmpdir/ls-to"
|
||||
diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to"
|
||||
|
||||
if test -r "$fromdir/block3.5"; then
|
||||
if test "$CAN_HLINK_SPECIAL" = yes; then
|
||||
set -x
|
||||
$RSYNC -aii --link-dest="$todir" "$fromdir/" "$chkdir/" \
|
||||
| tee "$outfile"
|
||||
|
||||
@@ -23,12 +23,19 @@ testit() {
|
||||
check_perms "$todir/to/program" $4 "Target $1"
|
||||
}
|
||||
|
||||
mkdir "$scratchdir/dir"
|
||||
# Cygwin has a persistent default dir ACL that ruins this test.
|
||||
case `getfacl "$scratchdir/dir" 2>/dev/null || true` in
|
||||
*default:user::*) test_skipped "The default ACL mode interferes with this test" ;;
|
||||
esac
|
||||
|
||||
echo "File!" >"$scratchdir/file"
|
||||
echo "#!/bin/sh" >"$scratchdir/program"
|
||||
mkdir "$scratchdir/dir"
|
||||
|
||||
chmod u=rwx,g=rw,g+s,o=r "$scratchdir/dir" || test_skipped "Can't chmod"
|
||||
chmod 664 "$scratchdir/file"
|
||||
chmod 775 "$scratchdir/program"
|
||||
|
||||
[ -g "$scratchdir/dir" ] || test_skipped "The directory setgid bit vanished!"
|
||||
mkdir "$scratchdir/dir/blah"
|
||||
[ -g "$scratchdir/dir/blah" ] || test_skipped "Your filesystem doesn't use directory setgid; maybe it's BSD."
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
mkdir "$fromdir"
|
||||
mkdir "$todir"
|
||||
|
||||
cp -p "$srcdir"/rsync.c "$fromdir"/rsync.c
|
||||
cp_p "$srcdir"/rsync.c "$fromdir"/rsync.c
|
||||
cp_touch "$fromdir"/rsync.c "$todir"/rsync2.c
|
||||
sleep 1
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ DEBUG_OPTS="--debug=all0,deltasum0"
|
||||
runtest "basic operation" 'checkit "$RSYNC -av \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
|
||||
ln "$fromdir/filelist" "$fromdir/dir"
|
||||
runtest "hard links" 'checkit "$RSYNC -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
runtest "hard links" 'checkit "$RSYNC -avH --bwlimit=0 $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
|
||||
rm "$todir/text"
|
||||
runtest "one file" 'checkit "$RSYNC -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
|
||||
@@ -17,9 +17,9 @@ outfile="$scratchdir/rsync.out"
|
||||
|
||||
makepath "$fromdir/foo"
|
||||
makepath "$fromdir/bar/baz"
|
||||
cp -p "$srcdir/configure.ac" "$fromdir/foo/config1"
|
||||
cp -p "$srcdir/config.h.in" "$fromdir/foo/config2"
|
||||
cp -p "$srcdir/rsync.h" "$fromdir/bar/baz/rsync"
|
||||
cp_p "$srcdir/configure.ac" "$fromdir/foo/config1"
|
||||
cp_p "$srcdir/config.sub" "$fromdir/foo/config2"
|
||||
cp_p "$srcdir/rsync.h" "$fromdir/bar/baz/rsync"
|
||||
chmod 600 "$fromdir"/foo/config? "$fromdir/bar/baz/rsync"
|
||||
umask 0
|
||||
ln -s ../bar/baz/rsync "$fromdir/foo/sym"
|
||||
@@ -66,7 +66,7 @@ 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"
|
||||
cp_p "$srcdir/configure.ac" "$fromdir/foo/config2"
|
||||
chmod 601 "$fromdir/foo/config2"
|
||||
$RSYNC -iplrH "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
@@ -79,12 +79,12 @@ EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
|
||||
|
||||
$RSYNC -a -f '-! */' "$fromdir/" "$todir"
|
||||
cp_p "$srcdir/config.sub" "$fromdir/foo/config2"
|
||||
sleep 1 # For directory mod below to ensure time difference
|
||||
rm "$todir/foo/sym"
|
||||
umask 0
|
||||
ln -s ../bar/baz "$todir/foo/sym"
|
||||
umask 022
|
||||
cp -p "$srcdir/config.h.in" "$fromdir/foo/config2"
|
||||
chmod 600 "$fromdir/foo/config2"
|
||||
chmod 777 "$todir/bar/baz/rsync"
|
||||
|
||||
@@ -99,7 +99,7 @@ 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"
|
||||
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/" \
|
||||
|
||||
43
testsuite/mkpath.test
Executable file
43
testsuite/mkpath.test
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
makepath "$fromdir"
|
||||
makepath "$todir"
|
||||
|
||||
cp_p "$srcdir/rsync.h" "$fromdir/text"
|
||||
cp_p "$srcdir/configure.ac" "$fromdir/extra"
|
||||
|
||||
cd "$tmpdir"
|
||||
|
||||
deep_dir=to/foo/bar/baz/down/deep
|
||||
|
||||
# Check that we can create several levels of dest dir
|
||||
$RSYNC -aiv --mkpath from/text $deep_dir/new
|
||||
test -f $deep_dir/new || test_fail "'new' file not found in $deep_dir dir"
|
||||
rm -rf to/foo
|
||||
|
||||
$RSYNC -aiv --mkpath from/text $deep_dir/
|
||||
test -f $deep_dir/text || test_fail "'text' file not found in $deep_dir dir"
|
||||
rm $deep_dir/text
|
||||
|
||||
# Make sure we can handle an existing path
|
||||
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"
|
||||
rm -rf to/foo
|
||||
|
||||
# Try the tests again with multiple source args
|
||||
$RSYNC -aiv --mkpath from/ $deep_dir
|
||||
test -f $deep_dir/extra || test_fail "'extra' file not found in $deep_dir dir"
|
||||
rm -rf to/foo
|
||||
|
||||
$RSYNC -aiv --mkpath from/ $deep_dir/
|
||||
test -f $deep_dir/text || test_fail "'text' file not found in $deep_dir dir"
|
||||
|
||||
# Make sure that we can handle no path
|
||||
$RSYNC -aiv --mkpath from/text to_text
|
||||
test -f to_text || test_fail "'to_text' file not found in current dir"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/sh
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
@@ -62,7 +62,7 @@ set_cp_destdir() {
|
||||
# Perform a "cp -p", making sure that timestamps are really the same,
|
||||
# even if the copy rounded microsecond times on the destination file.
|
||||
cp_touch() {
|
||||
cp -p "${@}" || test_fail "cp -p failed"
|
||||
cp_p "${@}"
|
||||
if test $# -gt 2 -o -d "$2"; then
|
||||
set_cp_destdir "${@}" # sets destdir var
|
||||
while test $# -gt 1; do
|
||||
@@ -97,11 +97,46 @@ printmsg() {
|
||||
}
|
||||
|
||||
rsync_ls_lR() {
|
||||
find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
|
||||
find "$@" -name .git -prune -o -name auto-build-save -prune -o -print | \
|
||||
sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
|
||||
}
|
||||
|
||||
get_testuid() {
|
||||
id 2>/dev/null | sed 's/^[^0-9]*\([0-9][0-9]*\).*/\1/'
|
||||
uid=`id -u 2>/dev/null || true`
|
||||
case "$uid" in
|
||||
[0-9]*) echo "$uid" ;;
|
||||
*) id 2>/dev/null | sed 's/^[^0-9]*\([0-9][0-9]*\).*/\1/' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_rootuid() {
|
||||
uid=`id -u root 2>/dev/null || true`
|
||||
case "$uid" in
|
||||
[0-9]*) echo "$uid" ;;
|
||||
*) echo 0 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_rootgid() {
|
||||
gid=`id -g root 2>/dev/null || true`
|
||||
case "$gid" in
|
||||
[0-9]*) echo "$gid" ;;
|
||||
*) echo 0 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# When copying via "cp -p", we want to ensure that a non-root user does not
|
||||
# preserve ownership (we want our files to be created as the testing user).
|
||||
# For instance, a Cygwin CI run might have git files owned by a different
|
||||
# user than the (admin) user running the tests.
|
||||
cp_cmd="cp -p"
|
||||
if test x`get_testuid` != x0; then
|
||||
case `cp --help 2>/dev/null` in
|
||||
*--no-preserve=*) cp_cmd="cp -p --no-preserve=ownership" ;;
|
||||
esac
|
||||
fi
|
||||
cp_p() {
|
||||
$cp_cmd "${@}" || test_fail "$cp_cmd failed"
|
||||
}
|
||||
|
||||
check_perms() {
|
||||
@@ -277,16 +312,18 @@ build_rsyncd_conf() {
|
||||
logfile="$scratchdir/rsyncd.log"
|
||||
hostname=`uname -n`
|
||||
|
||||
uid_setting='uid = 0'
|
||||
gid_setting='gid = 0'
|
||||
case `get_testuid` in
|
||||
0) ;;
|
||||
*)
|
||||
my_uid=`get_testuid`
|
||||
root_uid=`get_rootuid`
|
||||
root_gid=`get_rootgid`
|
||||
|
||||
uid_setting="uid = $root_uid"
|
||||
gid_setting="gid = $root_gid"
|
||||
|
||||
if test x"$my_uid" != x"$root_uid"; then
|
||||
# Non-root cannot specify uid & gid settings
|
||||
uid_setting="#$uid_setting"
|
||||
gid_setting="#$gid_setting"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
cat >"$conf" <<EOF
|
||||
# rsyncd configuration file autogenerated by $0
|
||||
@@ -296,8 +333,9 @@ use chroot = no
|
||||
munge symlinks = no
|
||||
hosts allow = localhost 127.0.0.0/24 192.168.0.0/16 10.0.0.0/8 $hostname
|
||||
log file = $logfile
|
||||
log format = %i %h [%a] %m (%u) %l %f%L
|
||||
transfer logging = yes
|
||||
# We don't define log format here so that the test-hidden module will default
|
||||
# to the internal static string (since we had a crash trying to tweak it).
|
||||
exclude = ? foobar.baz
|
||||
max verbosity = 4
|
||||
$uid_setting
|
||||
@@ -305,16 +343,19 @@ $gid_setting
|
||||
|
||||
[test-from]
|
||||
path = $fromdir
|
||||
log format = %i %h [%a] %m (%u) %l %f%L
|
||||
read only = yes
|
||||
comment = r/o
|
||||
|
||||
[test-to]
|
||||
path = $todir
|
||||
log format = %i %h [%a] %m (%u) %l %f%L
|
||||
read only = no
|
||||
comment = r/w
|
||||
|
||||
[test-scratch]
|
||||
path = $scratchdir
|
||||
log format = %i %h [%a] %m (%u) %l %f%L
|
||||
read only = no
|
||||
|
||||
[test-hidden]
|
||||
|
||||
@@ -45,6 +45,19 @@ EOF
|
||||
RSYNC_PREFIX='rsync'
|
||||
RUSR='rsync.nonuser'
|
||||
;;
|
||||
freebsd*)
|
||||
xset() {
|
||||
xnam="$1"
|
||||
xval="$2"
|
||||
shift 2
|
||||
setextattr -h user "$xnam" "$xval" "${@}"
|
||||
}
|
||||
xls() {
|
||||
for f in "${@}"; do lsextattr -q -h user "$f" | tr '[[:space:]]' '\n' | sort | xargs -I % getextattr -h user % "$f"; done
|
||||
}
|
||||
RSYNC_PREFIX='rsync'
|
||||
RUSR='rsync'
|
||||
;;
|
||||
*)
|
||||
xset() {
|
||||
xnam="$1"
|
||||
|
||||
27
tls.c
27
tls.c
@@ -108,6 +108,9 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
|
||||
#endif
|
||||
|
||||
static int display_atimes = 0;
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
static int display_crtimes = 0;
|
||||
#endif
|
||||
|
||||
static void failed(char const *what, char const *where)
|
||||
{
|
||||
@@ -143,14 +146,22 @@ static void storetime(char *dest, size_t destsize, time_t t, int nsecs)
|
||||
static void list_file(const char *fname)
|
||||
{
|
||||
STRUCT_STAT buf;
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
time_t crtime = 0;
|
||||
#endif
|
||||
char permbuf[PERMSTRING_SIZE];
|
||||
char mtimebuf[50];
|
||||
char atimebuf[50];
|
||||
char crtimebuf[50];
|
||||
char linkbuf[4096];
|
||||
int nsecs;
|
||||
|
||||
if (do_lstat(fname, &buf) < 0)
|
||||
failed("stat", fname);
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (display_crtimes && (crtime = get_create_time(fname)) == 0)
|
||||
failed("get_create_time", fname);
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (am_root < 0)
|
||||
stat_xattr(fname, &buf);
|
||||
@@ -195,6 +206,12 @@ static void list_file(const char *fname)
|
||||
storetime(atimebuf, sizeof atimebuf, S_ISDIR(buf.st_mode) ? 0 : buf.st_atime, -1);
|
||||
else
|
||||
atimebuf[0] = '\0';
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
if (display_crtimes)
|
||||
storetime(crtimebuf, sizeof crtimebuf, crtime, -1);
|
||||
else
|
||||
#endif
|
||||
crtimebuf[0] = '\0';
|
||||
|
||||
/* TODO: Perhaps escape special characters in fname? */
|
||||
printf("%s ", permbuf);
|
||||
@@ -204,14 +221,17 @@ static void list_file(const char *fname)
|
||||
} else
|
||||
printf("%15s", do_big_num(buf.st_size, 1, NULL));
|
||||
|
||||
printf(" %6ld.%-6ld %6ld%s%s %s%s\n",
|
||||
printf(" %6ld.%-6ld %6ld%s%s%s %s%s\n",
|
||||
(long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
|
||||
mtimebuf, atimebuf, fname, linkbuf);
|
||||
mtimebuf, atimebuf, crtimebuf, fname, linkbuf);
|
||||
}
|
||||
|
||||
static struct poptOption long_options[] = {
|
||||
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
|
||||
{"atimes", 'U', POPT_ARG_NONE, &display_atimes, 0, 0, 0},
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
{"crtimes", 'N', POPT_ARG_NONE, &display_crtimes, 0, 0, 0},
|
||||
#endif
|
||||
{"link-times", 'l', POPT_ARG_NONE, &link_times, 0, 0, 0 },
|
||||
{"link-owner", 'L', POPT_ARG_NONE, &link_owner, 0, 0, 0 },
|
||||
#ifdef SUPPORT_XATTRS
|
||||
@@ -231,6 +251,9 @@ static void NORETURN tls_usage(int ret)
|
||||
fprintf(F,"Trivial file listing program for portably checking rsync\n");
|
||||
fprintf(F,"\nOptions:\n");
|
||||
fprintf(F," -U, --atimes display access (last-used) times\n");
|
||||
#ifdef SUPPORT_CRTIMES
|
||||
fprintf(F," -N, --crtimes display create times (newness)\n");
|
||||
#endif
|
||||
fprintf(F," -l, --link-times display the time on a symlink\n");
|
||||
fprintf(F," -L, --link-owner display the owner+group on a symlink\n");
|
||||
#ifdef SUPPORT_XATTRS
|
||||
|
||||
248
token.c
248
token.c
@@ -87,7 +87,7 @@ void init_compression_level(void)
|
||||
break;
|
||||
#endif
|
||||
default: /* paranoia to prevent missing case values */
|
||||
assert(0);
|
||||
NOISY_DEATH("Unknown do_compression value");
|
||||
}
|
||||
|
||||
if (do_compression_level == CLVL_NOT_SPECIFIED)
|
||||
@@ -129,8 +129,7 @@ static void add_suffix(struct suffix_tree **prior, char ltr, const char *str)
|
||||
if (node->letter > ltr)
|
||||
break;
|
||||
}
|
||||
if (!(newnode = new(struct suffix_tree)))
|
||||
out_of_memory("add_suffix");
|
||||
newnode = new(struct suffix_tree);
|
||||
newnode->sibling = node;
|
||||
newnode->child = NULL;
|
||||
newnode->letter = ltr;
|
||||
@@ -147,8 +146,7 @@ static void add_nocompress_suffixes(const char *str)
|
||||
char *buf, *t;
|
||||
const char *f = str;
|
||||
|
||||
if (!(buf = new_array(char, strlen(f) + 1)))
|
||||
out_of_memory("add_nocompress_suffixes");
|
||||
buf = new_array(char, strlen(f) + 1);
|
||||
|
||||
while (*f) {
|
||||
if (*f == '/') {
|
||||
@@ -186,8 +184,7 @@ static void init_set_compression(void)
|
||||
else
|
||||
f = lp_dont_compress(module_id);
|
||||
|
||||
if (!(match_list = t = new_array(char, strlen(f) + 2)))
|
||||
out_of_memory("set_compression");
|
||||
match_list = t = new_array(char, strlen(f) + 2);
|
||||
|
||||
per_file_default_level = do_compression_level;
|
||||
|
||||
@@ -282,11 +279,8 @@ static int32 simple_recv_token(int f, char **data)
|
||||
static char *buf;
|
||||
int32 n;
|
||||
|
||||
if (!buf) {
|
||||
if (!buf)
|
||||
buf = new_array(char, CHUNK_SIZE);
|
||||
if (!buf)
|
||||
out_of_memory("simple_recv_token");
|
||||
}
|
||||
|
||||
if (residue == 0) {
|
||||
int32 i = read_int(f);
|
||||
@@ -373,8 +367,7 @@ send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset, in
|
||||
rprintf(FERROR, "compression init failed\n");
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if ((obuf = new_array(char, OBUF_SIZE)) == NULL)
|
||||
out_of_memory("send_deflated_token");
|
||||
obuf = new_array(char, OBUF_SIZE);
|
||||
init_done = 1;
|
||||
} else
|
||||
deflateReset(&tx_strm);
|
||||
@@ -383,8 +376,7 @@ send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset, in
|
||||
flush_pending = 0;
|
||||
} else if (last_token == -2) {
|
||||
run_start = token;
|
||||
} else if (nb != 0 || token != last_token + 1
|
||||
|| token >= run_start + 65536) {
|
||||
} else if (nb != 0 || token != last_token + 1 || token >= run_start + 65536) {
|
||||
/* output previous run */
|
||||
r = run_start - last_run_end;
|
||||
n = last_token - run_start;
|
||||
@@ -518,9 +510,8 @@ static int32 recv_deflated_token(int f, char **data)
|
||||
rprintf(FERROR, "inflate init failed\n");
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if (!(cbuf = new_array(char, MAX_DATA_COUNT))
|
||||
|| !(dbuf = new_array(char, AVAIL_OUT_SIZE(CHUNK_SIZE))))
|
||||
out_of_memory("recv_deflated_token");
|
||||
cbuf = new_array(char, MAX_DATA_COUNT);
|
||||
dbuf = new_array(char, AVAIL_OUT_SIZE(CHUNK_SIZE));
|
||||
init_done = 1;
|
||||
} else {
|
||||
inflateReset(&rx_strm);
|
||||
@@ -687,7 +678,6 @@ static void send_zstd_token(int f, int32 token, struct map_struct *buf, OFF_T of
|
||||
|
||||
/* initialization */
|
||||
if (!comp_init_done) {
|
||||
|
||||
zstd_cctx = ZSTD_createCCtx();
|
||||
if (!zstd_cctx) {
|
||||
rprintf(FERROR, "compression init failed\n");
|
||||
@@ -695,8 +685,6 @@ static void send_zstd_token(int f, int32 token, struct map_struct *buf, OFF_T of
|
||||
}
|
||||
|
||||
obuf = new_array(char, OBUF_SIZE);
|
||||
if (!obuf)
|
||||
out_of_memory("send_deflated_token");
|
||||
|
||||
ZSTD_CCtx_setParameter(zstd_cctx, ZSTD_c_compressionLevel, do_compression_level);
|
||||
zstd_out_buff.dst = obuf + 2;
|
||||
@@ -710,10 +698,7 @@ static void send_zstd_token(int f, int32 token, struct map_struct *buf, OFF_T of
|
||||
flush_pending = 0;
|
||||
} else if (last_token == -2) {
|
||||
run_start = token;
|
||||
|
||||
} else if (nb != 0 || token != last_token + 1
|
||||
|| token >= run_start + 65536) {
|
||||
|
||||
} else if (nb != 0 || token != last_token + 1 || token >= run_start + 65536) {
|
||||
/* output previous run */
|
||||
r = run_start - last_run_end;
|
||||
n = last_token - run_start;
|
||||
@@ -795,7 +780,6 @@ static int32 recv_zstd_token(int f, char **data)
|
||||
int r;
|
||||
|
||||
if (!decomp_init_done) {
|
||||
|
||||
zstd_dctx = ZSTD_createDCtx();
|
||||
if (!zstd_dctx) {
|
||||
rprintf(FERROR, "ZSTD_createDStream failed\n");
|
||||
@@ -806,8 +790,6 @@ static int32 recv_zstd_token(int f, char **data)
|
||||
out_buffer_size = ZSTD_DStreamOutSize() * 2;
|
||||
cbuf = new_array(char, MAX_DATA_COUNT);
|
||||
dbuf = new_array(char, out_buffer_size);
|
||||
if (!cbuf || !dbuf)
|
||||
out_of_memory("recv_zstd_token");
|
||||
|
||||
zstd_in_buff.src = cbuf;
|
||||
zstd_out_buff.dst = dbuf;
|
||||
@@ -815,30 +797,31 @@ static int32 recv_zstd_token(int f, char **data)
|
||||
decomp_init_done = 1;
|
||||
}
|
||||
|
||||
do {
|
||||
switch (recv_state) {
|
||||
case r_init:
|
||||
recv_state = r_idle;
|
||||
rx_token = 0;
|
||||
break;
|
||||
for (;;) {
|
||||
switch (recv_state) {
|
||||
case r_init:
|
||||
recv_state = r_idle;
|
||||
rx_token = 0;
|
||||
break;
|
||||
|
||||
case r_idle:
|
||||
flag = read_byte(f);
|
||||
if ((flag & 0xC0) == DEFLATED_DATA) {
|
||||
n = ((flag & 0x3f) << 8) + read_byte(f);
|
||||
read_buf(f, cbuf, n);
|
||||
case r_idle:
|
||||
flag = read_byte(f);
|
||||
if ((flag & 0xC0) == DEFLATED_DATA) {
|
||||
n = ((flag & 0x3f) << 8) + read_byte(f);
|
||||
read_buf(f, cbuf, n);
|
||||
|
||||
zstd_in_buff.size = n;
|
||||
zstd_in_buff.pos = 0;
|
||||
zstd_in_buff.size = n;
|
||||
zstd_in_buff.pos = 0;
|
||||
|
||||
recv_state = r_inflating;
|
||||
recv_state = r_inflating;
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (flag == END_FLAG) {
|
||||
/* that's all folks */
|
||||
recv_state = r_init;
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
if (flag == END_FLAG) {
|
||||
/* that's all folks */
|
||||
recv_state = r_init;
|
||||
return 0;
|
||||
}
|
||||
/* here we have a token of some kind */
|
||||
if (flag & TOKEN_REL) {
|
||||
rx_token += flag & 0x3f;
|
||||
@@ -851,45 +834,42 @@ static int32 recv_zstd_token(int f, char **data)
|
||||
recv_state = r_running;
|
||||
}
|
||||
return -1 - rx_token;
|
||||
|
||||
case r_inflated: /* zstd doesn't get into this state */
|
||||
break;
|
||||
|
||||
case r_inflating:
|
||||
zstd_out_buff.size = out_buffer_size;
|
||||
zstd_out_buff.pos = 0;
|
||||
|
||||
r = ZSTD_decompressStream(zstd_dctx, &zstd_out_buff, &zstd_in_buff);
|
||||
n = zstd_out_buff.pos;
|
||||
if (ZSTD_isError(r)) {
|
||||
rprintf(FERROR, "ZSTD decomp returned %d (%d bytes)\n", r, n);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the input buffer is fully consumed and the output
|
||||
* buffer is not full then next step is to read more
|
||||
* data.
|
||||
*/
|
||||
if (zstd_in_buff.size == zstd_in_buff.pos && n < out_buffer_size)
|
||||
recv_state = r_idle;
|
||||
|
||||
if (n != 0) {
|
||||
*data = dbuf;
|
||||
return n;
|
||||
}
|
||||
break;
|
||||
|
||||
case r_running:
|
||||
++rx_token;
|
||||
if (--rx_run == 0)
|
||||
recv_state = r_idle;
|
||||
return -1 - rx_token;
|
||||
}
|
||||
break;
|
||||
|
||||
case r_inflating:
|
||||
zstd_out_buff.size = out_buffer_size;
|
||||
zstd_out_buff.pos = 0;
|
||||
|
||||
r = ZSTD_decompressStream(zstd_dctx, &zstd_out_buff, &zstd_in_buff);
|
||||
n = zstd_out_buff.pos;
|
||||
if (ZSTD_isError(r)) {
|
||||
rprintf(FERROR, "ZSTD decomp returned %d (%d bytes)\n", r, n);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the input buffer is fully consumed and the output
|
||||
* buffer is not full then next step is to read more
|
||||
* data.
|
||||
*/
|
||||
if (zstd_in_buff.size == zstd_in_buff.pos && n < out_buffer_size)
|
||||
recv_state = r_idle;
|
||||
|
||||
if (n != 0) {
|
||||
*data = dbuf;
|
||||
return n;
|
||||
}
|
||||
break;
|
||||
|
||||
case r_running:
|
||||
++rx_token;
|
||||
if (--rx_run == 0)
|
||||
recv_state = r_idle;
|
||||
return -1 - rx_token;
|
||||
break;
|
||||
|
||||
case r_inflated:
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
#endif /* SUPPORT_ZSTD */
|
||||
|
||||
@@ -903,8 +883,7 @@ send_compressed_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
|
||||
|
||||
if (last_token == -1) {
|
||||
if (!init_done) {
|
||||
if ((obuf = new_array(char, size)) == NULL)
|
||||
out_of_memory("send_compressed_token");
|
||||
obuf = new_array(char, size);
|
||||
init_done = 1;
|
||||
}
|
||||
last_run_end = 0;
|
||||
@@ -912,8 +891,7 @@ send_compressed_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
|
||||
flush_pending = 0;
|
||||
} else if (last_token == -2) {
|
||||
run_start = token;
|
||||
} else if (nb != 0 || token != last_token + 1
|
||||
|| token >= run_start + 65536) {
|
||||
} else if (nb != 0 || token != last_token + 1 || token >= run_start + 65536) {
|
||||
/* output previous run */
|
||||
r = run_start - last_run_end;
|
||||
n = last_token - run_start;
|
||||
@@ -938,7 +916,6 @@ send_compressed_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
|
||||
const char *next_in;
|
||||
|
||||
do {
|
||||
char *ptr = obuf;
|
||||
char *next_out = obuf + 2;
|
||||
|
||||
if (available_out == 0) {
|
||||
@@ -953,10 +930,10 @@ send_compressed_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
if (available_out <= MAX_DATA_COUNT) {
|
||||
ptr[0] = DEFLATED_DATA + (available_out >> 8);
|
||||
ptr[1] = available_out;
|
||||
obuf[0] = DEFLATED_DATA + (available_out >> 8);
|
||||
obuf[1] = available_out;
|
||||
|
||||
write_buf(f, ptr, available_out + 2);
|
||||
write_buf(f, obuf, available_out + 2);
|
||||
|
||||
available_out = 0;
|
||||
nb -= available_in;
|
||||
@@ -965,14 +942,14 @@ send_compressed_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
|
||||
} while (nb != 0);
|
||||
flush_pending = token == -2;
|
||||
}
|
||||
if (token == -1)
|
||||
if (token == -1) {
|
||||
/* end of file - clean up */
|
||||
write_byte(f, END_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
static int32 recv_compressed_token(int f, char **data)
|
||||
{
|
||||
static int32 saved_flag;
|
||||
static int init_done;
|
||||
int32 n, flag;
|
||||
int size = MAX(LZ4_compressBound(CHUNK_SIZE), MAX_DATA_COUNT+2);
|
||||
@@ -984,21 +961,16 @@ static int32 recv_compressed_token(int f, char **data)
|
||||
switch (recv_state) {
|
||||
case r_init:
|
||||
if (!init_done) {
|
||||
if (!(cbuf = new_array(char, MAX_DATA_COUNT))
|
||||
|| !(dbuf = new_array(char, size)))
|
||||
out_of_memory("recv_compressed_token");
|
||||
cbuf = new_array(char, MAX_DATA_COUNT);
|
||||
dbuf = new_array(char, size);
|
||||
init_done = 1;
|
||||
}
|
||||
recv_state = r_idle;
|
||||
rx_token = 0;
|
||||
break;
|
||||
|
||||
case r_idle:
|
||||
case r_inflated:
|
||||
if (saved_flag) {
|
||||
flag = saved_flag & 0xff;
|
||||
saved_flag = 0;
|
||||
} else
|
||||
flag = read_byte(f);
|
||||
flag = read_byte(f);
|
||||
if ((flag & 0xC0) == DEFLATED_DATA) {
|
||||
n = ((flag & 0x3f) << 8) + read_byte(f);
|
||||
read_buf(f, cbuf, n);
|
||||
@@ -1008,9 +980,6 @@ static int32 recv_compressed_token(int f, char **data)
|
||||
break;
|
||||
}
|
||||
|
||||
if (recv_state == r_inflated)
|
||||
recv_state = r_idle;
|
||||
|
||||
if (flag == END_FLAG) {
|
||||
/* that's all folks */
|
||||
recv_state = r_init;
|
||||
@@ -1036,10 +1005,13 @@ static int32 recv_compressed_token(int f, char **data)
|
||||
rprintf(FERROR, "uncompress failed: %d\n", avail_out);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
recv_state = r_inflated;
|
||||
recv_state = r_idle;
|
||||
*data = dbuf;
|
||||
return avail_out;
|
||||
|
||||
case r_inflated: /* lz4 doesn't get into this state */
|
||||
break;
|
||||
|
||||
case r_running:
|
||||
++rx_token;
|
||||
if (--rx_run == 0)
|
||||
@@ -1047,53 +1019,7 @@ static int32 recv_compressed_token(int f, char **data)
|
||||
return -1 - rx_token;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# if 0
|
||||
static void see_uncompressed_token(char *buf, int32 len)
|
||||
{
|
||||
static const char *next_in;
|
||||
static int avail_in;
|
||||
int avail_out;
|
||||
|
||||
int32 blklen;
|
||||
char hdr[5];
|
||||
|
||||
avail_in = 0;
|
||||
blklen = 0;
|
||||
hdr[0] = 0;
|
||||
do {
|
||||
if (avail_in == 0 && len != 0) {
|
||||
if (blklen == 0) {
|
||||
/* Give it a fake stored-block header. */
|
||||
next_in = hdr;
|
||||
avail_in = 5;
|
||||
blklen = len;
|
||||
if (blklen > 0xffff)
|
||||
blklen = 0xffff;
|
||||
hdr[1] = blklen;
|
||||
hdr[2] = blklen >> 8;
|
||||
hdr[3] = ~hdr[1];
|
||||
hdr[4] = ~hdr[2];
|
||||
} else {
|
||||
next_in = (char *)buf;
|
||||
avail_in = blklen;
|
||||
if (protocol_version >= 31) /* Newer protocols avoid a data-duplicating bug */
|
||||
buf += blklen;
|
||||
len -= blklen;
|
||||
blklen = 0;
|
||||
}
|
||||
}
|
||||
avail_out = LZ4_decompress_safe(next_in, dbuf, avail_in, LZ4_compressBound(CHUNK_SIZE));
|
||||
if (avail_out < 0) {
|
||||
rprintf(FERROR, "uncompress failed: %d\n", avail_out);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
} while (len);
|
||||
}
|
||||
# endif /* 0 */
|
||||
#endif /* SUPPORT_LZ4 */
|
||||
|
||||
/**
|
||||
@@ -1123,7 +1049,7 @@ void send_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
NOISY_DEATH("Unknown do_compression value");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1150,7 +1076,7 @@ int32 recv_token(int f, char **data)
|
||||
return recv_compressed_token(f, data);
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
NOISY_DEATH("Unknown do_compression value");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1167,16 +1093,16 @@ void see_token(char *data, int32 toklen)
|
||||
break;
|
||||
case CPRES_ZLIBX:
|
||||
break;
|
||||
#ifdef SUPPORT_ZSTD
|
||||
case CPRES_ZSTD:
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_LZ4
|
||||
case CPRES_LZ4:
|
||||
/*see_uncompressed_token(data, toklen);*/
|
||||
break;
|
||||
#endif
|
||||
#ifdef SUPPORT_LZ4
|
||||
case CPRES_ZSTD:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
NOISY_DEATH("Unknown do_compression value");
|
||||
}
|
||||
}
|
||||
|
||||
194
uidlist.c
194
uidlist.c
@@ -33,6 +33,8 @@ extern int preserve_uid;
|
||||
extern int preserve_gid;
|
||||
extern int preserve_acls;
|
||||
extern int numeric_ids;
|
||||
extern int xmit_id0_names;
|
||||
extern pid_t namecvt_pid;
|
||||
extern gid_t our_gid;
|
||||
extern char *usermap;
|
||||
extern char *groupmap;
|
||||
@@ -85,8 +87,6 @@ static struct idlist *add_to_list(struct idlist **root, id_t id, union name_or_i
|
||||
id_t id2, uint16 flags)
|
||||
{
|
||||
struct idlist *node = new(struct idlist);
|
||||
if (!node)
|
||||
out_of_memory("add_to_list");
|
||||
node->next = *root;
|
||||
node->u = noiu;
|
||||
node->id = id;
|
||||
@@ -97,52 +97,88 @@ static struct idlist *add_to_list(struct idlist **root, id_t id, union name_or_i
|
||||
}
|
||||
|
||||
/* turn a uid into a user name */
|
||||
char *uid_to_user(uid_t uid)
|
||||
const char *uid_to_user(uid_t uid)
|
||||
{
|
||||
struct passwd *pass = getpwuid(uid);
|
||||
if (pass)
|
||||
return strdup(pass->pw_name);
|
||||
return NULL;
|
||||
const char *name = NULL;
|
||||
|
||||
if (namecvt_pid) {
|
||||
id_t id = uid;
|
||||
namecvt_call("uid", &name, &id);
|
||||
} else {
|
||||
struct passwd *pass = getpwuid(uid);
|
||||
if (pass)
|
||||
name = strdup(pass->pw_name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/* turn a gid into a group name */
|
||||
char *gid_to_group(gid_t gid)
|
||||
const char *gid_to_group(gid_t gid)
|
||||
{
|
||||
struct group *grp = getgrgid(gid);
|
||||
if (grp)
|
||||
return strdup(grp->gr_name);
|
||||
return NULL;
|
||||
const char *name = NULL;
|
||||
|
||||
if (namecvt_pid) {
|
||||
id_t id = gid;
|
||||
namecvt_call("gid", &name, &id);
|
||||
} else {
|
||||
struct group *grp = getgrgid(gid);
|
||||
if (grp)
|
||||
name = strdup(grp->gr_name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/* Parse a user name or (optionally) a number into a uid */
|
||||
int user_to_uid(const char *name, uid_t *uid_p, BOOL num_ok)
|
||||
{
|
||||
struct passwd *pass;
|
||||
if (!name || !*name)
|
||||
return 0;
|
||||
|
||||
if (num_ok && name[strspn(name, "0123456789")] == '\0') {
|
||||
*uid_p = id_parse(name);
|
||||
return 1;
|
||||
}
|
||||
if (!(pass = getpwnam(name)))
|
||||
return 0;
|
||||
*uid_p = pass->pw_uid;
|
||||
|
||||
if (namecvt_pid) {
|
||||
id_t id;
|
||||
if (!namecvt_call("usr", &name, &id))
|
||||
return 0;
|
||||
*uid_p = id;
|
||||
} else {
|
||||
struct passwd *pass = getpwnam(name);
|
||||
if (!pass)
|
||||
return 0;
|
||||
*uid_p = pass->pw_uid;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Parse a group name or (optionally) a number into a gid */
|
||||
int group_to_gid(const char *name, gid_t *gid_p, BOOL num_ok)
|
||||
{
|
||||
struct group *grp;
|
||||
if (!name || !*name)
|
||||
return 0;
|
||||
|
||||
if (num_ok && name[strspn(name, "0123456789")] == '\0') {
|
||||
*gid_p = id_parse(name);
|
||||
return 1;
|
||||
}
|
||||
if (!(grp = getgrnam(name)))
|
||||
return 0;
|
||||
*gid_p = grp->gr_gid;
|
||||
|
||||
if (namecvt_pid) {
|
||||
id_t id;
|
||||
if (!namecvt_call("grp", &name, &id))
|
||||
return 0;
|
||||
*gid_p = id;
|
||||
} else {
|
||||
struct group *grp = getgrnam(name);
|
||||
if (!grp)
|
||||
return 0;
|
||||
*gid_p = grp->gr_gid;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -160,8 +196,6 @@ static int is_in_group(gid_t gid)
|
||||
if ((ngroups = getgroups(0, NULL)) < 0)
|
||||
ngroups = 0;
|
||||
gidset = new_array(GETGROUPS_T, ngroups+1);
|
||||
if (!gidset)
|
||||
out_of_memory("is_in_group");
|
||||
if (ngroups > 0)
|
||||
ngroups = getgroups(ngroups, gidset);
|
||||
/* The default gid might not be in the list on some systems. */
|
||||
@@ -174,8 +208,6 @@ static int is_in_group(gid_t gid)
|
||||
if (DEBUG_GTE(OWN, 2)) {
|
||||
int pos;
|
||||
char *gidbuf = new_array(char, ngroups*21+32);
|
||||
if (!gidbuf)
|
||||
out_of_memory("is_in_group");
|
||||
pos = snprintf(gidbuf, 32, "process has %d gid%s: ", ngroups, ngroups == 1? "" : "s");
|
||||
for (n = 0; n < ngroups; n++) {
|
||||
pos += snprintf(gidbuf+pos, 21, " %d", (int)gidset[n]);
|
||||
@@ -301,9 +333,6 @@ const char *add_uid(uid_t uid)
|
||||
struct idlist *node;
|
||||
union name_or_id noiu;
|
||||
|
||||
if (uid == 0) /* don't map root */
|
||||
return NULL;
|
||||
|
||||
for (list = uidlist; list; list = list->next) {
|
||||
if (list->id == uid)
|
||||
return NULL;
|
||||
@@ -321,9 +350,6 @@ const char *add_gid(gid_t gid)
|
||||
struct idlist *node;
|
||||
union name_or_id noiu;
|
||||
|
||||
if (gid == 0) /* don't map root */
|
||||
return NULL;
|
||||
|
||||
for (list = gidlist; list; list = list->next) {
|
||||
if (list->id == gid)
|
||||
return NULL;
|
||||
@@ -334,54 +360,65 @@ const char *add_gid(gid_t gid)
|
||||
return node->u.name;
|
||||
}
|
||||
|
||||
/* send a complete uid/gid mapping to the peer */
|
||||
void send_id_list(int f)
|
||||
static void send_one_name(int f, id_t id, const char *name)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (!name)
|
||||
name = "";
|
||||
if ((len = strlen(name)) > 255) /* Impossible? */
|
||||
len = 255;
|
||||
|
||||
write_varint30(f, id);
|
||||
write_byte(f, len);
|
||||
if (len)
|
||||
write_buf(f, name, len);
|
||||
}
|
||||
|
||||
static void send_one_list(int f, struct idlist *idlist, int usernames)
|
||||
{
|
||||
struct idlist *list;
|
||||
|
||||
if (preserve_uid || preserve_acls) {
|
||||
int len;
|
||||
/* we send sequences of uid/byte-length/name */
|
||||
for (list = uidlist; list; list = list->next) {
|
||||
if (!list->u.name)
|
||||
continue;
|
||||
len = strlen(list->u.name);
|
||||
write_varint30(f, list->id);
|
||||
write_byte(f, len);
|
||||
write_buf(f, list->u.name, len);
|
||||
}
|
||||
|
||||
/* terminate the uid list with a 0 uid. We explicitly exclude
|
||||
* 0 from the list */
|
||||
write_varint30(f, 0);
|
||||
/* we send sequences of id/byte-len/name */
|
||||
for (list = idlist; list; list = list->next) {
|
||||
if (list->id && list->u.name)
|
||||
send_one_name(f, list->id, list->u.name);
|
||||
}
|
||||
|
||||
if (preserve_gid || preserve_acls) {
|
||||
int len;
|
||||
for (list = gidlist; list; list = list->next) {
|
||||
if (!list->u.name)
|
||||
continue;
|
||||
len = strlen(list->u.name);
|
||||
write_varint30(f, list->id);
|
||||
write_byte(f, len);
|
||||
write_buf(f, list->u.name, len);
|
||||
}
|
||||
/* Terminate the uid list with 0 (which was excluded above).
|
||||
* A modern rsync also sends the name of id 0. */
|
||||
if (xmit_id0_names)
|
||||
send_one_name(f, 0, usernames ? uid_to_user(0) : gid_to_group(0));
|
||||
else
|
||||
write_varint30(f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* send a complete uid/gid mapping to the peer */
|
||||
void send_id_lists(int f)
|
||||
{
|
||||
if (preserve_uid || preserve_acls)
|
||||
send_one_list(f, uidlist, 1);
|
||||
|
||||
if (preserve_gid || preserve_acls)
|
||||
send_one_list(f, gidlist, 0);
|
||||
}
|
||||
|
||||
uid_t recv_user_name(int f, uid_t uid)
|
||||
{
|
||||
struct idlist *node;
|
||||
int len = read_byte(f);
|
||||
char *name = new_array(char, len+1);
|
||||
if (!name)
|
||||
out_of_memory("recv_user_name");
|
||||
read_sbuf(f, name, len);
|
||||
if (numeric_ids < 0) {
|
||||
free(name);
|
||||
char *name;
|
||||
|
||||
if (len) {
|
||||
name = new_array(char, len+1);
|
||||
read_sbuf(f, name, len);
|
||||
if (numeric_ids < 0) {
|
||||
free(name);
|
||||
name = NULL;
|
||||
}
|
||||
} else
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
node = recv_add_id(&uidlist, uidmap, uid, name); /* node keeps name's memory */
|
||||
return node->id2;
|
||||
}
|
||||
@@ -390,14 +427,18 @@ gid_t recv_group_name(int f, gid_t gid, uint16 *flags_ptr)
|
||||
{
|
||||
struct idlist *node;
|
||||
int len = read_byte(f);
|
||||
char *name = new_array(char, len+1);
|
||||
if (!name)
|
||||
out_of_memory("recv_group_name");
|
||||
read_sbuf(f, name, len);
|
||||
if (numeric_ids < 0) {
|
||||
free(name);
|
||||
char *name;
|
||||
|
||||
if (len) {
|
||||
name = new_array(char, len+1);
|
||||
read_sbuf(f, name, len);
|
||||
if (numeric_ids < 0) {
|
||||
free(name);
|
||||
name = NULL;
|
||||
}
|
||||
} else
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
node = recv_add_id(&gidlist, gidmap, gid, name); /* node keeps name's memory */
|
||||
if (flags_ptr && node->flags & FLAG_SKIP_GROUP)
|
||||
*flags_ptr |= FLAG_SKIP_GROUP;
|
||||
@@ -415,12 +456,16 @@ void recv_id_list(int f, struct file_list *flist)
|
||||
/* read the uid list */
|
||||
while ((id = read_varint30(f)) != 0)
|
||||
recv_user_name(f, id);
|
||||
if (xmit_id0_names)
|
||||
recv_user_name(f, 0);
|
||||
}
|
||||
|
||||
if ((preserve_gid || preserve_acls) && numeric_ids <= 0) {
|
||||
/* read the gid list */
|
||||
while ((id = read_varint30(f)) != 0)
|
||||
recv_group_name(f, id, NULL);
|
||||
if (xmit_id0_names)
|
||||
recv_group_name(f, 0, NULL);
|
||||
}
|
||||
|
||||
/* Now convert all the uids/gids from sender values to our values. */
|
||||
@@ -512,8 +557,9 @@ void parse_name_map(char *map, BOOL usernames)
|
||||
*--cp = '\0'; /* replace comma */
|
||||
}
|
||||
|
||||
/* The 0 user/group doesn't get its name sent, so add it explicitly. */
|
||||
recv_add_id(idlist_ptr, *idmap_ptr, 0, numeric_ids ? NULL : usernames ? uid_to_user(0) : gid_to_group(0));
|
||||
/* If the sender isn't going to xmit the id0 name, we assume it's "root". */
|
||||
if (!xmit_id0_names)
|
||||
recv_add_id(idlist_ptr, *idmap_ptr, 0, numeric_ids ? NULL : "root");
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETGROUPLIST
|
||||
|
||||
261
usage.c
Normal file
261
usage.c
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Some usage & version related functions.
|
||||
*
|
||||
* Copyright (C) 2002-2020 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
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "latest-year.h"
|
||||
#include "git-version.h"
|
||||
#include "default-cvsignore.h"
|
||||
|
||||
extern struct name_num_obj valid_checksums;
|
||||
extern struct name_num_obj valid_compressions;
|
||||
|
||||
static char *istring(const char *fmt, int val)
|
||||
{
|
||||
char *str;
|
||||
if (asprintf(&str, fmt, val) < 0)
|
||||
out_of_memory("istring");
|
||||
return str;
|
||||
}
|
||||
|
||||
static void print_info_flags(enum logcode f)
|
||||
{
|
||||
STRUCT_STAT *dumstat;
|
||||
char line_buf[75];
|
||||
int line_len, j;
|
||||
char *info_flags[] = {
|
||||
|
||||
"*Capabilities",
|
||||
|
||||
istring("%d-bit files", (int)(sizeof (OFF_T) * 8)),
|
||||
istring("%d-bit inums", (int)(sizeof dumstat->st_ino * 8)), /* Don't check ino_t! */
|
||||
istring("%d-bit timestamps", (int)(sizeof (time_t) * 8)),
|
||||
istring("%d-bit long ints", (int)(sizeof (int64) * 8)),
|
||||
|
||||
#ifndef HAVE_SOCKETPAIR
|
||||
"no "
|
||||
#endif
|
||||
"socketpairs",
|
||||
|
||||
#ifndef SUPPORT_HARD_LINKS
|
||||
"no "
|
||||
#endif
|
||||
"hardlinks",
|
||||
|
||||
#ifndef CAN_HARDLINK_SPECIAL
|
||||
"no "
|
||||
#endif
|
||||
"hardlink-specials",
|
||||
|
||||
#ifndef SUPPORT_LINKS
|
||||
"no "
|
||||
#endif
|
||||
"symlinks",
|
||||
|
||||
#ifndef INET6
|
||||
"no "
|
||||
#endif
|
||||
"IPv6",
|
||||
|
||||
#ifndef SUPPORT_ATIMES
|
||||
"no "
|
||||
#endif
|
||||
"atimes",
|
||||
|
||||
"batchfiles",
|
||||
|
||||
#ifndef HAVE_FTRUNCATE
|
||||
"no "
|
||||
#endif
|
||||
"inplace",
|
||||
|
||||
#ifndef HAVE_FTRUNCATE
|
||||
"no "
|
||||
#endif
|
||||
"append",
|
||||
|
||||
#ifndef SUPPORT_ACLS
|
||||
"no "
|
||||
#endif
|
||||
"ACLs",
|
||||
|
||||
#ifndef SUPPORT_XATTRS
|
||||
"no "
|
||||
#endif
|
||||
"xattrs",
|
||||
|
||||
#ifdef RSYNC_USE_PROTECTED_ARGS
|
||||
"default "
|
||||
#else
|
||||
"optional "
|
||||
#endif
|
||||
"protect-args",
|
||||
|
||||
#ifndef ICONV_OPTION
|
||||
"no "
|
||||
#endif
|
||||
"iconv",
|
||||
|
||||
#ifndef CAN_SET_SYMLINK_TIMES
|
||||
"no "
|
||||
#endif
|
||||
"symtimes",
|
||||
|
||||
#ifndef SUPPORT_PREALLOCATION
|
||||
"no "
|
||||
#endif
|
||||
"prealloc",
|
||||
|
||||
#ifndef HAVE_MKTIME
|
||||
"no "
|
||||
#endif
|
||||
"stop-at",
|
||||
|
||||
#ifndef SUPPORT_CRTIMES
|
||||
"no "
|
||||
#endif
|
||||
"crtimes",
|
||||
|
||||
"*Optimizations",
|
||||
|
||||
#ifndef HAVE_SIMD
|
||||
"no "
|
||||
#endif
|
||||
"SIMD",
|
||||
|
||||
#ifndef HAVE_ASM
|
||||
"no "
|
||||
#endif
|
||||
"asm",
|
||||
|
||||
#ifndef USE_OPENSSL
|
||||
"no "
|
||||
#endif
|
||||
"openssl-crypto",
|
||||
|
||||
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);
|
||||
line_len = 0;
|
||||
}
|
||||
if (!str)
|
||||
break;
|
||||
if (*str == '*') {
|
||||
rprintf(f, "%s:\n", str+1);
|
||||
continue;
|
||||
}
|
||||
line_len += snprintf(line_buf+line_len, sizeof line_buf - line_len, " %s%s", str, need_comma ? "," : "");
|
||||
}
|
||||
}
|
||||
|
||||
void print_rsync_version(enum logcode f)
|
||||
{
|
||||
char tmpbuf[256], *subprotocol = "";
|
||||
|
||||
#if SUBPROTOCOL_VERSION != 0
|
||||
subprotocol = istring(".PR%d", SUBPROTOCOL_VERSION);
|
||||
#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");
|
||||
|
||||
print_info_flags(f);
|
||||
|
||||
rprintf(f, "Checksum list:\n");
|
||||
get_default_nno_list(&valid_checksums, tmpbuf, sizeof tmpbuf, '(');
|
||||
rprintf(f, " %s\n", tmpbuf);
|
||||
|
||||
rprintf(f, "Compress list:\n");
|
||||
get_default_nno_list(&valid_compressions, tmpbuf, sizeof tmpbuf, '(');
|
||||
rprintf(f, " %s\n", tmpbuf);
|
||||
|
||||
#ifdef MAINTAINER_MODE
|
||||
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
|
||||
#endif
|
||||
|
||||
#if SIZEOF_INT64 < 8
|
||||
rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
|
||||
#endif
|
||||
if (sizeof (int64) != SIZEOF_INT64) {
|
||||
rprintf(f,
|
||||
"WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
|
||||
(int) SIZEOF_INT64, (int) sizeof (int64));
|
||||
}
|
||||
|
||||
rprintf(f,"\n");
|
||||
rprintf(f,"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n");
|
||||
rprintf(f,"are welcome to redistribute it under certain conditions. See the GNU\n");
|
||||
rprintf(f,"General Public Licence for details.\n");
|
||||
}
|
||||
|
||||
void usage(enum logcode F)
|
||||
{
|
||||
print_rsync_version(F);
|
||||
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"rsync is a file transfer program capable of efficient remote update\n");
|
||||
rprintf(F,"via a fast differencing algorithm.\n");
|
||||
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC [DEST]\n");
|
||||
rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
|
||||
rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
|
||||
rprintf(F,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n");
|
||||
rprintf(F,"to an rsync daemon, and require SRC or DEST to start with a module name.\n");
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Options\n");
|
||||
#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,"See https://rsync.samba.org/ for updates, bug reports, and answers\n");
|
||||
}
|
||||
|
||||
void daemon_usage(enum logcode F)
|
||||
{
|
||||
print_rsync_version(F);
|
||||
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Usage: rsync --daemon [OPTION]...\n");
|
||||
#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");
|
||||
}
|
||||
|
||||
const char *rsync_version(void)
|
||||
{
|
||||
return RSYNC_GITVER;
|
||||
}
|
||||
|
||||
const char *default_cvsignore(void)
|
||||
{
|
||||
return DEFAULT_CVSIGNORE;
|
||||
}
|
||||
67
util.c
67
util.c
@@ -592,8 +592,7 @@ int lock_range(int fd, int offset, int len)
|
||||
}
|
||||
|
||||
#define ENSURE_MEMSPACE(buf, type, sz, req) \
|
||||
if ((req) > sz && !(buf = realloc_array(buf, type, sz = MAX(sz * 2, req)))) \
|
||||
out_of_memory("glob_expand")
|
||||
do { if ((req) > sz) buf = realloc_array(buf, type, sz = MAX(sz * 2, req)); } while(0)
|
||||
|
||||
static inline void call_glob_match(const char *name, int len, int from_glob,
|
||||
char *arg, int abpos, int fbpos);
|
||||
@@ -695,8 +694,7 @@ static inline void call_glob_match(const char *name, int len, int from_glob,
|
||||
glob_match(arg, abpos, fbpos);
|
||||
} else {
|
||||
ENSURE_MEMSPACE(glob.argv, char *, glob.maxargs, glob.argc + 1);
|
||||
if (!(glob.argv[glob.argc++] = strdup(glob.arg_buf)))
|
||||
out_of_memory("glob_match");
|
||||
glob.argv[glob.argc++] = strdup(glob.arg_buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,8 +718,6 @@ int glob_expand(const char *arg, char ***argv_p, int *argc_p, int *maxargs_p)
|
||||
s = sanitize_path(NULL, arg, "", 0, SP_KEEP_DOT_DIRS);
|
||||
else {
|
||||
s = strdup(arg);
|
||||
if (!s)
|
||||
out_of_memory("glob_expand");
|
||||
clean_fname(s, CFN_KEEP_DOT_DIRS | CFN_KEEP_TRAILING_SLASH | CFN_COLLAPSE_DOT_DOT_DIRS);
|
||||
}
|
||||
|
||||
@@ -771,8 +767,7 @@ void glob_expand_module(char *base1, char *arg, char ***argv_p, int *argc_p, int
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(arg = strdup(arg)))
|
||||
out_of_memory("glob_expand_module");
|
||||
arg = strdup(arg);
|
||||
|
||||
if (asprintf(&base," %s/", base1) < 0)
|
||||
out_of_memory("glob_expand_module");
|
||||
@@ -1017,11 +1012,10 @@ char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth, i
|
||||
depth = 0;
|
||||
p++;
|
||||
}
|
||||
if (dest) {
|
||||
if (rlen + plen + 1 >= MAXPATHLEN)
|
||||
return NULL;
|
||||
} else if (!(dest = new_array(char, MAX(rlen + plen + 1, 2))))
|
||||
out_of_memory("sanitize_path");
|
||||
if (!dest)
|
||||
dest = new_array(char, MAX(rlen + plen + 1, 2));
|
||||
else if (rlen + plen + 1 >= MAXPATHLEN)
|
||||
return NULL;
|
||||
if (rlen) { /* only true if p previously started with a slash */
|
||||
memcpy(dest, rootdir, rlen);
|
||||
if (rlen > 1) /* a rootdir of len 1 is "/", so this avoids a 2nd slash */
|
||||
@@ -1155,13 +1149,10 @@ char *normalize_path(char *path, BOOL force_newbuf, unsigned int *len_ptr)
|
||||
return NULL;
|
||||
curr_dir[curr_dir_len] = '/';
|
||||
memcpy(curr_dir + curr_dir_len + 1, path, len + 1);
|
||||
if (!(path = strdup(curr_dir)))
|
||||
out_of_memory("normalize_path");
|
||||
path = strdup(curr_dir);
|
||||
curr_dir[curr_dir_len] = '\0';
|
||||
} else if (force_newbuf) {
|
||||
if (!(path = strdup(path)))
|
||||
out_of_memory("normalize_path");
|
||||
}
|
||||
} else if (force_newbuf)
|
||||
path = strdup(path);
|
||||
|
||||
len = clean_fname(path, CFN_COLLAPSE_DOT_DOT_DIRS | CFN_DROP_TRAILING_DOT_DIR);
|
||||
|
||||
@@ -1519,8 +1510,7 @@ struct bitbag *bitbag_create(int max_ndx)
|
||||
struct bitbag *bb = new(struct bitbag);
|
||||
bb->slot_cnt = (max_ndx + BB_PER_SLOT_BITS - 1) / BB_PER_SLOT_BITS;
|
||||
|
||||
if (!(bb->bits = (uint32**)calloc(bb->slot_cnt, sizeof (uint32*))))
|
||||
out_of_memory("bitbag_create");
|
||||
bb->bits = new_array0(uint32*, bb->slot_cnt);
|
||||
|
||||
return bb;
|
||||
}
|
||||
@@ -1530,10 +1520,8 @@ void bitbag_set_bit(struct bitbag *bb, int ndx)
|
||||
int slot = ndx / BB_PER_SLOT_BITS;
|
||||
ndx %= BB_PER_SLOT_BITS;
|
||||
|
||||
if (!bb->bits[slot]) {
|
||||
if (!(bb->bits[slot] = (uint32*)calloc(BB_PER_SLOT_INTS, 4)))
|
||||
out_of_memory("bitbag_set_bit");
|
||||
}
|
||||
if (!bb->bits[slot])
|
||||
bb->bits[slot] = new_array0(uint32, BB_PER_SLOT_INTS);
|
||||
|
||||
bb->bits[slot][ndx/32] |= 1u << (ndx % 32);
|
||||
}
|
||||
@@ -1601,8 +1589,7 @@ void flist_ndx_push(flist_ndx_list *lp, int ndx)
|
||||
{
|
||||
struct flist_ndx_item *item;
|
||||
|
||||
if (!(item = new(struct flist_ndx_item)))
|
||||
out_of_memory("flist_ndx_push");
|
||||
item = new(struct flist_ndx_item);
|
||||
item->next = NULL;
|
||||
item->ndx = ndx;
|
||||
if (lp->tail)
|
||||
@@ -1643,29 +1630,27 @@ void *expand_item_list(item_list *lp, size_t item_size, const char *desc, int in
|
||||
/* First time through, 0 <= 0, so list is expanded. */
|
||||
if (lp->malloced <= lp->count) {
|
||||
void *new_ptr;
|
||||
size_t new_size = lp->malloced;
|
||||
size_t expand_size;
|
||||
if (incr < 0)
|
||||
new_size += -incr; /* increase slowly */
|
||||
else if (new_size < (size_t)incr)
|
||||
new_size = incr;
|
||||
else if (new_size)
|
||||
new_size *= 2;
|
||||
expand_size = -incr; /* increase slowly */
|
||||
else if (lp->malloced < (size_t)incr)
|
||||
expand_size = incr - lp->malloced;
|
||||
else if (lp->malloced)
|
||||
expand_size = lp->malloced; /* double in size */
|
||||
else
|
||||
new_size = 1;
|
||||
if (new_size <= lp->malloced)
|
||||
expand_size = 1;
|
||||
if (SIZE_MAX/item_size - expand_size < lp->malloced)
|
||||
overflow_exit("expand_item_list");
|
||||
/* Using _realloc_array() lets us pass the size, not a type. */
|
||||
new_ptr = _realloc_array(lp->items, item_size, new_size);
|
||||
expand_size += lp->malloced;
|
||||
new_ptr = realloc_buf(lp->items, expand_size * item_size);
|
||||
if (DEBUG_GTE(FLIST, 3)) {
|
||||
rprintf(FINFO, "[%s] expand %s to %s bytes, did%s move\n",
|
||||
who_am_i(), desc, big_num(new_size * item_size),
|
||||
who_am_i(), desc, big_num(expand_size * item_size),
|
||||
new_ptr == lp->items ? " not" : "");
|
||||
}
|
||||
if (!new_ptr)
|
||||
out_of_memory("expand_item_list");
|
||||
|
||||
lp->items = new_ptr;
|
||||
lp->malloced = new_size;
|
||||
lp->malloced = expand_size;
|
||||
}
|
||||
return (char*)lp->items + (lp->count++ * item_size);
|
||||
}
|
||||
|
||||
58
util2.c
58
util2.c
@@ -21,10 +21,13 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "ifuncs.h"
|
||||
#include "itypes.h"
|
||||
#include "inums.h"
|
||||
|
||||
extern size_t max_alloc;
|
||||
|
||||
char *do_calloc = "42";
|
||||
|
||||
/**
|
||||
* Sleep for a specified number of milliseconds.
|
||||
*
|
||||
@@ -67,22 +70,24 @@ int msleep(int t)
|
||||
return True;
|
||||
}
|
||||
|
||||
#define MALLOC_MAX 0x40000000
|
||||
|
||||
void *_new_array(unsigned long num, unsigned int size, int use_calloc)
|
||||
void *my_alloc(void *ptr, size_t num, size_t size, const char *file, int line)
|
||||
{
|
||||
if (num >= MALLOC_MAX/size)
|
||||
return NULL;
|
||||
return use_calloc ? calloc(num, size) : malloc(num * size);
|
||||
}
|
||||
|
||||
void *_realloc_array(void *ptr, unsigned int size, size_t num)
|
||||
{
|
||||
if (num >= MALLOC_MAX/size)
|
||||
return NULL;
|
||||
if (max_alloc && num >= max_alloc/size) {
|
||||
if (!file)
|
||||
return NULL;
|
||||
rprintf(FERROR, "[%s] exceeded --max-alloc=%s setting (file=%s, line=%d)\n",
|
||||
who_am_i(), do_big_num(max_alloc, 0, NULL), src_file(file), line);
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
if (!ptr)
|
||||
return malloc(size * num);
|
||||
return realloc(ptr, size * num);
|
||||
ptr = malloc(num * size);
|
||||
else if (ptr == do_calloc)
|
||||
ptr = calloc(num, size);
|
||||
else
|
||||
ptr = realloc(ptr, num * size);
|
||||
if (!ptr && file)
|
||||
_out_of_memory("my_alloc caller", file, line);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
const char *sum_as_hex(int csum_type, const char *sum, int flist_csum)
|
||||
@@ -112,14 +117,29 @@ const char *sum_as_hex(int csum_type, const char *sum, int flist_csum)
|
||||
return buf;
|
||||
}
|
||||
|
||||
NORETURN void out_of_memory(const char *str)
|
||||
NORETURN void _out_of_memory(const char *msg, const char *file, int line)
|
||||
{
|
||||
rprintf(FERROR, "ERROR: out of memory in %s [%s]\n", str, who_am_i());
|
||||
rprintf(FERROR, "[%s] out of memory: %s (file=%s, line=%d)\n", who_am_i(), msg, src_file(file), line);
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
|
||||
NORETURN void overflow_exit(const char *str)
|
||||
NORETURN void _overflow_exit(const char *msg, const char *file, int line)
|
||||
{
|
||||
rprintf(FERROR, "ERROR: buffer overflow in %s [%s]\n", str, who_am_i());
|
||||
rprintf(FERROR, "[%s] buffer overflow: %s (file=%s, line=%d)\n", who_am_i(), msg, src_file(file), line);
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
|
||||
const char *src_file(const char *file)
|
||||
{
|
||||
static const char *util2 = __FILE__;
|
||||
static int prefix = -1;
|
||||
|
||||
if (prefix < 0) {
|
||||
const char *cp = strrchr(util2, '/');
|
||||
prefix = cp ? cp - util2 + 1 : 0;
|
||||
}
|
||||
|
||||
if (prefix && strncmp(file, util2, prefix) == 0)
|
||||
return file + prefix;
|
||||
return file;
|
||||
}
|
||||
|
||||
42
xattrs.c
42
xattrs.c
@@ -58,7 +58,7 @@ extern int saw_xattr_filter;
|
||||
#define SPRE_LEN ((int)sizeof SYSTEM_PREFIX - 1)
|
||||
|
||||
#ifdef HAVE_LINUX_XATTRS
|
||||
#define MIGHT_NEED_RPRE (am_root < 0)
|
||||
#define MIGHT_NEED_RPRE (am_root <= 0)
|
||||
#define RSYNC_PREFIX USER_PREFIX "rsync."
|
||||
#else
|
||||
#define MIGHT_NEED_RPRE am_root
|
||||
@@ -145,8 +145,6 @@ static ssize_t get_xattr_names(const char *fname)
|
||||
if (!namebuf) {
|
||||
namebuf_len = 1024;
|
||||
namebuf = new_array(char, namebuf_len);
|
||||
if (!namebuf)
|
||||
out_of_memory("get_xattr_names");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
@@ -174,8 +172,6 @@ static ssize_t get_xattr_names(const char *fname)
|
||||
free(namebuf);
|
||||
namebuf_len = list_len + 1024;
|
||||
namebuf = new_array(char, namebuf_len);
|
||||
if (!namebuf)
|
||||
out_of_memory("get_xattr_names");
|
||||
}
|
||||
|
||||
return list_len;
|
||||
@@ -203,10 +199,9 @@ static char *get_xattr_data(const char *fname, const char *name, size_t *len_ptr
|
||||
|
||||
if (!datum_len && !extra_len)
|
||||
extra_len = 1; /* request non-zero amount of memory */
|
||||
if (datum_len + extra_len < datum_len)
|
||||
if (SIZE_MAX - datum_len < extra_len)
|
||||
overflow_exit("get_xattr_data");
|
||||
if (!(ptr = new_array(char, datum_len + extra_len)))
|
||||
out_of_memory("get_xattr_data");
|
||||
ptr = new_array(char, datum_len + extra_len);
|
||||
|
||||
if (datum_len) {
|
||||
size_t len = sys_lgetxattr(fname, name, ptr, datum_len);
|
||||
@@ -279,8 +274,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
|
||||
sum_update(ptr, datum_len);
|
||||
free(ptr);
|
||||
|
||||
if (!(ptr = new_array(char, name_offset + name_len)))
|
||||
out_of_memory("rsync_xal_get");
|
||||
ptr = new_array(char, name_offset + name_len);
|
||||
*ptr = XSTATE_ABBREV;
|
||||
sum_end(ptr + 1);
|
||||
} else
|
||||
@@ -481,8 +475,6 @@ static int rsync_xal_store(item_list *xalp)
|
||||
out_of_memory("rsync_xal_h hashtable_create()");
|
||||
|
||||
new_ref = new0(rsync_xa_list_ref);
|
||||
if (new_ref == NULL)
|
||||
out_of_memory("new0(rsync_xa_list_ref)");
|
||||
new_ref->ndx = ndx;
|
||||
|
||||
node = hashtable_find(rsync_xal_h, new_list->key, new_ref);
|
||||
@@ -756,11 +748,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
|
||||
old_datum = rxa->datum;
|
||||
rxa->datum_len = read_varint(f_in);
|
||||
|
||||
if (rxa->name_len + rxa->datum_len < rxa->name_len)
|
||||
if (SIZE_MAX - rxa->name_len < rxa->datum_len)
|
||||
overflow_exit("recv_xattr_request");
|
||||
rxa->datum = new_array(char, rxa->datum_len + rxa->name_len);
|
||||
if (!rxa->datum)
|
||||
out_of_memory("recv_xattr_request");
|
||||
name = rxa->datum + rxa->datum_len;
|
||||
memcpy(name, rxa->name, rxa->name_len);
|
||||
rxa->name = name;
|
||||
@@ -809,12 +799,9 @@ void receive_xattr(int f, struct file_struct *file)
|
||||
size_t datum_len = read_varint(f);
|
||||
size_t dget_len = datum_len > MAX_FULL_DATUM ? 1 + MAX_DIGEST_LEN : datum_len;
|
||||
size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
|
||||
if ((dget_len + extra_len < dget_len)
|
||||
|| (dget_len + extra_len + name_len < dget_len + extra_len))
|
||||
if (SIZE_MAX - dget_len < extra_len || SIZE_MAX - dget_len - extra_len < name_len)
|
||||
overflow_exit("receive_xattr");
|
||||
ptr = new_array(char, dget_len + extra_len + name_len);
|
||||
if (!ptr)
|
||||
out_of_memory("receive_xattr");
|
||||
name = ptr + dget_len + extra_len;
|
||||
read_buf(f, name, name_len);
|
||||
if (name_len < 1 || name[name_len-1] != '\0') {
|
||||
@@ -934,17 +921,16 @@ void uncache_tmp_xattrs(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
while (ref != NULL) {
|
||||
if (ref->next == NULL) {
|
||||
ref = NULL;
|
||||
while (1) {
|
||||
rsync_xa_list_ref *next = ref->next;
|
||||
if (next == NULL)
|
||||
break;
|
||||
if (xa_list_item->ndx == next->ndx) {
|
||||
ref->next = next->next;
|
||||
free(next);
|
||||
break;
|
||||
}
|
||||
if (xa_list_item->ndx == ref->next->ndx) {
|
||||
ref->next = ref->next->next;
|
||||
free(ref);
|
||||
break;
|
||||
}
|
||||
ref = ref->next;
|
||||
ref = next;
|
||||
}
|
||||
}
|
||||
prior_xattr_count = (size_t)-1;
|
||||
|
||||
Reference in New Issue
Block a user