mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-25 23:35:27 -04:00
Compare commits
157 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 |
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: build
|
||||
|
||||
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
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -32,6 +32,7 @@ aclocal.m4
|
||||
/rsync
|
||||
/stunnel-rsyncd.conf
|
||||
/shconfig
|
||||
/git-version.h
|
||||
/testdir
|
||||
/tests-dont-exist
|
||||
/testtmp
|
||||
@@ -53,3 +54,4 @@ aclocal.m4
|
||||
/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
|
||||
|
||||
58
Makefile.in
58
Makefile.in
@@ -32,7 +32,7 @@ SHELL=/bin/sh
|
||||
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 version.h
|
||||
@@ -43,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 \
|
||||
@@ -67,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 $(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
|
||||
-$(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
|
||||
@@ -99,8 +99,7 @@ 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
|
||||
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
|
||||
@@ -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
|
||||
|
||||
@@ -231,7 +236,7 @@ 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 daemon-parm.h
|
||||
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
|
||||
@@ -249,7 +254,8 @@ rsyncd.conf.5: rsyncd.conf.5.md md2man version.h Makefile
|
||||
.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:
|
||||
@@ -260,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
|
||||
@@ -279,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
|
||||
|
||||
150
NEWS.md
150
NEWS.md
@@ -1,3 +1,104 @@
|
||||
<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)
|
||||
@@ -15,7 +116,7 @@
|
||||
|
||||
- Apple requires the asm function name to begin with an underscore.
|
||||
|
||||
- Avoid a test failure in the daemon test when --atimes is disabled.
|
||||
- Avoid a test failure in the daemon test when `--atimes` is disabled.
|
||||
|
||||
### ENHANCEMENTS:
|
||||
|
||||
@@ -296,7 +397,7 @@
|
||||
|
||||
### 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
|
||||
|
||||
@@ -336,7 +437,7 @@
|
||||
|
||||
- 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.
|
||||
|
||||
@@ -385,7 +486,7 @@
|
||||
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:
|
||||
|
||||
@@ -467,7 +568,7 @@
|
||||
- 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.
|
||||
@@ -829,7 +930,7 @@
|
||||
- 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
|
||||
@@ -853,7 +954,7 @@
|
||||
|
||||
- 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>
|
||||
@@ -905,7 +1006,7 @@
|
||||
- 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.
|
||||
|
||||
@@ -1104,7 +1205,7 @@
|
||||
- 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.
|
||||
|
||||
@@ -1120,7 +1221,7 @@
|
||||
|
||||
- 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>
|
||||
@@ -1336,7 +1437,7 @@
|
||||
|
||||
- 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
|
||||
@@ -1496,7 +1597,7 @@
|
||||
- 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.).
|
||||
|
||||
@@ -1620,7 +1721,7 @@
|
||||
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
|
||||
@@ -1830,7 +1931,7 @@
|
||||
|
||||
### 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
|
||||
@@ -2267,7 +2368,7 @@
|
||||
- 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:
|
||||
@@ -2426,7 +2527,7 @@
|
||||
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.
|
||||
@@ -2500,7 +2601,7 @@
|
||||
- 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
|
||||
@@ -2545,7 +2646,7 @@
|
||||
|
||||
### 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
|
||||
@@ -2767,9 +2868,9 @@
|
||||
- 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.
|
||||
@@ -3227,7 +3328,7 @@
|
||||
### 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)
|
||||
@@ -3416,7 +3517,7 @@
|
||||
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:
|
||||
@@ -3459,9 +3560,9 @@
|
||||
|
||||
- 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.
|
||||
|
||||
@@ -4143,6 +4244,7 @@
|
||||
|
||||
| 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 |
|
||||
|
||||
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
|
||||
|
||||
5
access.c
5
access.c
@@ -34,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;
|
||||
|
||||
@@ -119,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;
|
||||
}
|
||||
@@ -196,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);
|
||||
}
|
||||
@@ -227,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;
|
||||
@@ -287,7 +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;
|
||||
auth_uid_groups = new_array(char *, auth_uid_groups_cnt);
|
||||
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]);
|
||||
}
|
||||
@@ -313,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);
|
||||
}
|
||||
|
||||
@@ -324,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);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "rsync.h"
|
||||
|
||||
#ifdef SUPPORT_XXHASH
|
||||
#include "xxhash.h"
|
||||
#include <xxhash.h>
|
||||
# if XXH_VERSION_NUMBER >= 800
|
||||
# define SUPPORT_XXH3 1
|
||||
# endif
|
||||
|
||||
@@ -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"
|
||||
@@ -222,10 +222,6 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
* we don't want to output a duplicate error. */
|
||||
if ((exit_code && line > 0)
|
||||
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1)))) {
|
||||
#ifdef HAVE_USLEEP /* A tiny delay just in case both sender & receiver are sending a msg at the same time. */
|
||||
if (am_server && exit_code)
|
||||
usleep(50);
|
||||
#endif
|
||||
log_exit(exit_code, exit_file, exit_line);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int quiet;
|
||||
extern int dry_run;
|
||||
@@ -36,7 +37,6 @@ 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;
|
||||
@@ -71,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="
|
||||
@@ -85,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;
|
||||
@@ -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)
|
||||
@@ -704,7 +703,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
logfile_format_has_o_or_i = 1;
|
||||
|
||||
uid = MY_UID();
|
||||
am_root = (uid == 0);
|
||||
am_root = (uid == ROOT_UID);
|
||||
|
||||
p = *lp_uid(module_id) ? lp_uid(module_id) : am_root ? NOBODY_USER : NULL;
|
||||
if (p) {
|
||||
@@ -811,7 +810,8 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
log_init(1);
|
||||
|
||||
#ifdef HAVE_PUTENV
|
||||
if ((*lp_early_exec(module_id) || *lp_prexfer_exec(module_id) || *lp_postxfer_exec(module_id))
|
||||
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());
|
||||
|
||||
@@ -873,6 +873,15 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
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
|
||||
|
||||
@@ -959,7 +968,7 @@ 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(module_id) && *lp_temp_dir(module_id)) {
|
||||
@@ -1004,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);
|
||||
|
||||
@@ -1100,7 +1112,8 @@ 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(module_id) != False : lp_numeric_ids(module_id) == 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(module_id) && (!io_timeout || lp_timeout(module_id) < io_timeout))
|
||||
@@ -1124,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)
|
||||
@@ -1213,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);
|
||||
@@ -1406,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??? */
|
||||
|
||||
14
compat.c
14
compat.c
@@ -43,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;
|
||||
@@ -73,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 */
|
||||
@@ -109,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;
|
||||
|
||||
@@ -553,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
|
||||
@@ -694,6 +699,8 @@ 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) {
|
||||
do_negotiated_strings = 1;
|
||||
compat_flags |= CF_VARINT_FLIST_FLAGS;
|
||||
@@ -714,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
|
||||
|
||||
102
configure.ac
102
configure.ac
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([rsync],[ ],[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])
|
||||
@@ -57,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
|
||||
@@ -88,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
|
||||
@@ -346,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/
|
||||
@@ -438,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])])
|
||||
@@ -479,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])
|
||||
@@ -494,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)
|
||||
@@ -515,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)
|
||||
@@ -536,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)
|
||||
@@ -557,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>
|
||||
@@ -811,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 \
|
||||
@@ -937,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
|
||||
@@ -947,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
|
||||
@@ -1212,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])
|
||||
@@ -1238,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)
|
||||
@@ -1281,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)
|
||||
|
||||
@@ -33,6 +33,7 @@ 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
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "default-cvsignore.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int am_server;
|
||||
@@ -1053,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);
|
||||
|
||||
|
||||
107
flist.c
107
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);
|
||||
|
||||
@@ -377,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;
|
||||
@@ -443,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;
|
||||
@@ -482,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) {
|
||||
@@ -569,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))
|
||||
@@ -661,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;
|
||||
@@ -680,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;
|
||||
@@ -767,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))
|
||||
@@ -804,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)) {
|
||||
@@ -988,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;
|
||||
|
||||
@@ -1385,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;
|
||||
@@ -1892,7 +1947,7 @@ static void send_implied_dirs(int f, struct file_list *flist, char *fname,
|
||||
memcpy(F_DIR_RELNAMES_P(lastpath_struct), &relname_list, sizeof relname_list);
|
||||
}
|
||||
rnpp = EXPAND_ITEM_LIST(relname_list, relnamecache *, 32);
|
||||
*rnpp = (relnamecache*)new_array(char, sizeof (relnamecache) + len);
|
||||
*rnpp = (relnamecache*)new_array(char, RELNAMECACHE_LEN + len + 1);
|
||||
(*rnpp)->name_type = name_type;
|
||||
strlcpy((*rnpp)->fname, limit+1, len + 1);
|
||||
|
||||
@@ -2051,8 +2106,7 @@ void send_extra_file_list(int f, int at_least)
|
||||
|
||||
if (need_unsorted_flist) {
|
||||
flist->sorted = new_array(struct file_struct *, flist->used);
|
||||
memcpy(flist->sorted, flist->files,
|
||||
flist->used * sizeof (struct file_struct*));
|
||||
memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
|
||||
} else
|
||||
flist->sorted = flist->files;
|
||||
|
||||
@@ -2405,8 +2459,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
* send them together in a single file-list. */
|
||||
if (need_unsorted_flist) {
|
||||
flist->sorted = new_array(struct file_struct *, flist->used);
|
||||
memcpy(flist->sorted, flist->files,
|
||||
flist->used * sizeof (struct file_struct*));
|
||||
memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
|
||||
} else
|
||||
flist->sorted = flist->files;
|
||||
flist_sort_and_clean(flist, 0);
|
||||
@@ -2414,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)
|
||||
@@ -2587,8 +2640,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
|
||||
* list unsorted for our exchange of index numbers with the
|
||||
* other side (since their names may not sort the same). */
|
||||
flist->sorted = new_array(struct file_struct *, flist->used);
|
||||
memcpy(flist->sorted, flist->files,
|
||||
flist->used * sizeof (struct file_struct*));
|
||||
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) {
|
||||
@@ -2598,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 {
|
||||
@@ -2730,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
|
||||
@@ -2792,25 +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;
|
||||
|
||||
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;
|
||||
|
||||
51
generator.c
51
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;
|
||||
|
||||
2
ifuncs.h
2
ifuncs.h
@@ -105,7 +105,7 @@ free_stat_x(stat_x *sx_p)
|
||||
static inline char *my_strdup(const char *str, const char *file, int line)
|
||||
{
|
||||
int len = strlen(str)+1;
|
||||
char *buf = my_alloc(do_malloc, len, 1, file, line);
|
||||
char *buf = my_alloc(NULL, len, 1, file, line);
|
||||
memcpy(buf, str, len);
|
||||
return buf;
|
||||
}
|
||||
|
||||
54
io.c
54
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;
|
||||
@@ -1285,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) {
|
||||
@@ -1304,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) {
|
||||
@@ -1323,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");
|
||||
}
|
||||
@@ -1338,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");
|
||||
}
|
||||
@@ -1426,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) {
|
||||
@@ -2298,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)
|
||||
@@ -2315,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 */
|
||||
@@ -2326,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;
|
||||
@@ -2344,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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -242,7 +242,7 @@ static char *expand_vars(const char *str)
|
||||
* 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 - tThe currently configured 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.
|
||||
*/
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
98
main.c
98
main.c
@@ -28,6 +28,9 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#include <popt.h>
|
||||
#ifdef __TANDEM
|
||||
#include <floss.h(floss_execlp)>
|
||||
#endif
|
||||
|
||||
extern int dry_run;
|
||||
extern int list_only;
|
||||
@@ -54,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;
|
||||
@@ -93,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];
|
||||
@@ -104,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;
|
||||
@@ -299,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] = ':';
|
||||
@@ -562,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;
|
||||
}
|
||||
@@ -587,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;
|
||||
@@ -595,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:
|
||||
@@ -648,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);
|
||||
}
|
||||
|
||||
@@ -674,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)) {
|
||||
@@ -707,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)) {
|
||||
@@ -737,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");
|
||||
@@ -753,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);
|
||||
@@ -977,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) {
|
||||
@@ -1083,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();
|
||||
@@ -1386,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;
|
||||
|
||||
@@ -1418,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 */
|
||||
@@ -1439,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);
|
||||
@@ -1481,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);
|
||||
@@ -1512,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
|
||||
|
||||
@@ -1520,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)
|
||||
@@ -1552,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))
|
||||
{
|
||||
@@ -1667,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));
|
||||
|
||||
|
||||
6
md2man
6
md2man
@@ -144,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))
|
||||
|
||||
@@ -376,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")
|
||||
}
|
||||
|
||||
536
options.c
536
options.c
@@ -22,16 +22,12 @@
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#include "ifuncs.h"
|
||||
#include "latest-year.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;
|
||||
|
||||
@@ -64,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;
|
||||
@@ -90,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;
|
||||
@@ -103,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;
|
||||
@@ -128,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;
|
||||
@@ -193,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;
|
||||
@@ -573,212 +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_info_flags(enum logcode f)
|
||||
{
|
||||
STRUCT_STAT *dumstat;
|
||||
char line_buf[75];
|
||||
int line_len, j;
|
||||
char *capabilities[] = {
|
||||
|
||||
"*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",
|
||||
|
||||
"*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 *cap = capabilities[j], *next_cap = cap ? capabilities[j+1] : NULL;
|
||||
int cap_len = cap && *cap != '*' ? strlen(cap) : 1000;
|
||||
int need_comma = next_cap && *next_cap != '*' ? 1 : 0;
|
||||
if (line_len && line_len + 1 + cap_len + need_comma >= (int)sizeof line_buf) {
|
||||
rprintf(f, " %s\n", line_buf);
|
||||
line_len = 0;
|
||||
}
|
||||
if (!cap)
|
||||
break;
|
||||
if (*cap == '*') {
|
||||
rprintf(f, "%s:\n", cap+1);
|
||||
continue;
|
||||
}
|
||||
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");
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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[] = {
|
||||
@@ -790,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 },
|
||||
@@ -831,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 },
|
||||
@@ -928,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 },
|
||||
@@ -988,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 },
|
||||
@@ -998,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 },
|
||||
@@ -1022,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 },
|
||||
@@ -1192,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++) {
|
||||
@@ -1253,14 +1053,15 @@ static int count_args(const char **argv)
|
||||
/* 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(char *size_arg, char def_suf, const char *opt_name, ssize_t min_value)
|
||||
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;
|
||||
const char *arg, *err = "invalid";
|
||||
ssize_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 == '.')
|
||||
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':
|
||||
@@ -1299,17 +1100,174 @@ static ssize_t parse_size_arg(char *size_arg, char def_suf, const char *opt_name
|
||||
size += atoi(arg), arg += 2;
|
||||
if (*arg)
|
||||
goto failure;
|
||||
if (size < min_value) {
|
||||
err = size < 0 ? "too big" : "too small";
|
||||
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:
|
||||
snprintf(err_buf, sizeof err_buf, "--%s value is %s: %s\n", opt_name, err, size_arg);
|
||||
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)
|
||||
{
|
||||
const char *msg;
|
||||
@@ -1358,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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1682,23 +1640,36 @@ 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', "max-size", 0)) < 0)
|
||||
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;
|
||||
max_size_arg = num_to_byte_string(max_size);
|
||||
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', "min-size", 0)) < 0)
|
||||
if ((min_size = parse_size_arg(min_size_arg, 'b', "min-size", 0, -1, False)) < 0)
|
||||
return 0;
|
||||
min_size_arg = num_to_byte_string(min_size);
|
||||
min_size_arg = strdup(do_big_num(min_size, 0, NULL));
|
||||
break;
|
||||
|
||||
case OPT_BWLIMIT: {
|
||||
ssize_t size = parse_size_arg(bwlimit_arg, 'K', "bwlimit", 512);
|
||||
ssize_t size = parse_size_arg(bwlimit_arg, 'K', "bwlimit", 512, -1, True);
|
||||
if (size < 0)
|
||||
return 0;
|
||||
bwlimit_arg = num_to_byte_string(size);
|
||||
bwlimit_arg = strdup(do_big_num(size, 0, NULL));
|
||||
bwlimit = (size + 512) / 1024;
|
||||
break;
|
||||
}
|
||||
@@ -1863,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. */
|
||||
@@ -1889,7 +1904,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
||||
max_alloc_arg = NULL;
|
||||
}
|
||||
if (max_alloc_arg) {
|
||||
ssize_t size = parse_size_arg(max_alloc_arg, 'B', "max-alloc", 1024*1024);
|
||||
ssize_t size = parse_size_arg(max_alloc_arg, 'B', "max-alloc", 1024*1024, -1, True);
|
||||
if (size < 0)
|
||||
return 0;
|
||||
max_alloc = size;
|
||||
@@ -1965,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);
|
||||
@@ -2037,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");
|
||||
@@ -2464,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";
|
||||
|
||||
@@ -2541,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)
|
||||
@@ -2608,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
|
||||
}
|
||||
@@ -2673,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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
TARGETS := all install install-ssl-daemon install-all install-strip conf gen gensend reconfigure restatus \
|
||||
proto man clean cleantests distclean test check check29 check30 installcheck splint doxygen doxygen-upload
|
||||
proto man clean cleantests distclean test check check29 check30 installcheck splint \
|
||||
doxygen doxygen-upload finddead
|
||||
|
||||
.PHONY: $(TARGETS) auto-prep
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Summary: A fast, versatile, remote (and local) file-copying tool
|
||||
Name: rsync
|
||||
Version: 3.2.2
|
||||
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
|
||||
* Sat Jul 04 2020 Wayne Davison <wayne@opencoder.net>
|
||||
Released 3.2.2.
|
||||
* 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
|
||||
|
||||
@@ -75,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)
|
||||
|
||||
@@ -88,11 +88,6 @@ def main():
|
||||
fh.write(HTML_END)
|
||||
|
||||
|
||||
def html_via_cmarkgfm(txt):
|
||||
# Our NEWS.md file has a gfm table in it.
|
||||
return cmarkgfm.github_flavored_markdown_to_html(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.")
|
||||
@@ -101,7 +96,8 @@ 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:
|
||||
die("Failed to find cmarkgfm for python3.")
|
||||
|
||||
|
||||
@@ -127,18 +127,27 @@ def update_patch(patch):
|
||||
|
||||
s = cmd_run(['git', 'merge', based_on])
|
||||
ok = s.returncode == 0
|
||||
if not ok or args.cmd or args.shell:
|
||||
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
|
||||
ok = False
|
||||
if ok and args.shell:
|
||||
skip_shell = True
|
||||
if args.shell and not skip_shell:
|
||||
if not run_a_shell(parent, patch):
|
||||
return 0
|
||||
|
||||
@@ -218,8 +227,9 @@ 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('--shell', '-s', action='store_true', help="Launch a shell for every patch/BASE/* branch updated, not just when a conflict occurs.")
|
||||
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.")
|
||||
parser.add_argument('patch_files', metavar='patches/DIFF_FILE', nargs='*', help="Specify what patch diff files to process. Default: all of them.")
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
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`
|
||||
|
||||
@@ -188,7 +188,7 @@ 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 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)
|
||||
@@ -233,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> ")
|
||||
|
||||
@@ -255,8 +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")
|
||||
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}.'")
|
||||
@@ -324,7 +324,7 @@ About to:
|
||||
shutil.rmtree(rsync_ver)
|
||||
|
||||
print(f"Updating the other files in {dest} ...")
|
||||
md_files = 'README.md NEWS.md'.split()
|
||||
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 ])
|
||||
|
||||
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
|
||||
@@ -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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SHELL=/bin/sh
|
||||
|
||||
.PHONY: conf
|
||||
conf: configure.sh config.h.in
|
||||
.PHONY: conf
|
||||
|
||||
aclocal.m4: m4/*.m4
|
||||
aclocal -I m4
|
||||
|
||||
276
rsync.1.md
276
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
|
||||
@@ -457,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
|
||||
@@ -578,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
|
||||
@@ -590,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`
|
||||
|
||||
@@ -921,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
|
||||
@@ -970,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.
|
||||
@@ -1339,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
|
||||
@@ -1725,23 +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 accepted suffix letters are: `B`, `K`, `G`, `T`, and `P` for bytes,
|
||||
kilobytes/kibibytes, megabytes/mebibytes, gigabytes/gibibytes,
|
||||
terabytes/tebibytes, and petabytes/pebibytes. If you use a single-char
|
||||
suffix or add-on "ib" to it (e.g. "G" or "GiB") then you get units that are
|
||||
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 suffix
|
||||
(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 `8192P-1`.
|
||||
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.
|
||||
@@ -1772,6 +1816,8 @@ your home directory (remove the '=' for that).
|
||||
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
|
||||
@@ -1784,6 +1830,9 @@ your home directory (remove the '=' for that).
|
||||
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
|
||||
@@ -2142,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/
|
||||
|
||||
@@ -2316,7 +2365,7 @@ your home directory (remove the '=' for that).
|
||||
specify `-zz`.
|
||||
|
||||
See also the `--skip-compress` option for the default list of file suffixes
|
||||
that will trasnferred with no (or minimal) compression.
|
||||
that will be transferred with no (or minimal) compression.
|
||||
|
||||
0. `--compress-choice=STR`, `--zc=STR`
|
||||
|
||||
@@ -2411,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
|
||||
@@ -2440,8 +2515,11 @@ your home directory (remove the '=' for that).
|
||||
> odp
|
||||
> ods
|
||||
> odt
|
||||
> oga
|
||||
> ogg
|
||||
> ogm
|
||||
> ogv
|
||||
> ogx
|
||||
> opus
|
||||
> otg
|
||||
> oth
|
||||
@@ -2450,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
|
||||
@@ -2536,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
|
||||
@@ -2546,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`
|
||||
|
||||
@@ -2634,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:
|
||||
|
||||
@@ -2663,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
|
||||
@@ -2807,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,
|
||||
@@ -2905,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
|
||||
@@ -3089,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
|
||||
@@ -3107,6 +3201,46 @@ 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
|
||||
|
||||
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) {
|
||||
|
||||
83
rsync.h
83
rsync.h
@@ -70,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. */
|
||||
|
||||
@@ -182,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
|
||||
@@ -209,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)
|
||||
@@ -442,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>
|
||||
@@ -471,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
|
||||
@@ -550,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. */
|
||||
@@ -693,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
|
||||
@@ -732,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;
|
||||
@@ -753,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;
|
||||
@@ -766,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
|
||||
@@ -817,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 */
|
||||
@@ -1035,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"
|
||||
@@ -1059,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 */
|
||||
@@ -1094,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
|
||||
@@ -1267,20 +1324,23 @@ extern int errno;
|
||||
/* handler for null strings in printf format */
|
||||
#define NS(s) ((s)?(s):"<NULL>")
|
||||
|
||||
extern char *do_malloc;
|
||||
extern char *do_calloc;
|
||||
|
||||
/* Convenient wrappers for malloc and realloc. Use them. */
|
||||
#define new(type) ((type*)my_alloc(do_malloc, sizeof (type), 1, __FILE__, __LINE__))
|
||||
#define new0(type) ((type*)my_alloc(NULL, sizeof (type), 1, __FILE__, __LINE__))
|
||||
#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(do_malloc, (num), sizeof (type), __FILE__, __LINE__))
|
||||
#define new_array0(type, num) ((type*)my_alloc(NULL, (num), sizeof (type), __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 *, ...)
|
||||
__attribute__((format (printf, 2, 3)))
|
||||
@@ -1395,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`
|
||||
|
||||
@@ -685,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
|
||||
@@ -705,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:
|
||||
@@ -713,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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
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];
|
||||
|
||||
2
t_stub.c
2
t_stub.c
@@ -33,7 +33,7 @@ int preserve_xattrs = 0;
|
||||
int preserve_perms = 0;
|
||||
int preserve_executability = 0;
|
||||
int open_noatime = 0;
|
||||
size_t max_alloc = 1024*1024*1024; /* max_alloc is needed when combined with util2.o */
|
||||
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"
|
||||
|
||||
@@ -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.sub" "$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.sub" "$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
|
||||
@@ -102,7 +102,41 @@ rsync_ls_lR() {
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -278,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
|
||||
|
||||
@@ -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
|
||||
|
||||
16
token.c
16
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)
|
||||
@@ -1049,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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1076,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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1093,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");
|
||||
}
|
||||
}
|
||||
|
||||
184
uidlist.c
184
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;
|
||||
@@ -95,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;
|
||||
}
|
||||
|
||||
@@ -295,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;
|
||||
@@ -315,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;
|
||||
@@ -328,52 +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);
|
||||
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;
|
||||
}
|
||||
@@ -382,12 +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);
|
||||
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;
|
||||
@@ -405,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. */
|
||||
@@ -502,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;
|
||||
}
|
||||
33
util.c
33
util.c
@@ -1510,7 +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;
|
||||
|
||||
bb->bits = (uint32**)calloc(bb->slot_cnt, sizeof (uint32*));
|
||||
bb->bits = new_array0(uint32*, bb->slot_cnt);
|
||||
|
||||
return bb;
|
||||
}
|
||||
@@ -1520,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);
|
||||
}
|
||||
@@ -1632,28 +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");
|
||||
new_ptr = realloc_buf(lp->items, new_size * item_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);
|
||||
}
|
||||
|
||||
53
util2.c
53
util2.c
@@ -21,13 +21,12 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "ifuncs.h"
|
||||
#include "itypes.h"
|
||||
#include "inums.h"
|
||||
|
||||
extern size_t max_alloc;
|
||||
|
||||
char *do_malloc = "42";
|
||||
char *do_calloc = "42";
|
||||
|
||||
/**
|
||||
* Sleep for a specified number of milliseconds.
|
||||
@@ -71,38 +70,23 @@ int msleep(int t)
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Convert a num manually because the needed %lld precision is not a portable sprintf() escape. */
|
||||
char *num_to_byte_string(ssize_t num)
|
||||
{
|
||||
char buf[128], *s = buf + sizeof buf - 1;
|
||||
|
||||
*s = '\0';
|
||||
while (num) {
|
||||
*--s = (char)(num % 10) + '0';
|
||||
num /= 10;
|
||||
}
|
||||
return strdup(s);
|
||||
}
|
||||
|
||||
void *my_alloc(void *ptr, size_t num, size_t size, const char *file, int line)
|
||||
{
|
||||
if (num >= max_alloc/size) {
|
||||
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(), num_to_byte_string(max_alloc), file, line);
|
||||
who_am_i(), do_big_num(max_alloc, 0, NULL), src_file(file), line);
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
if (!ptr)
|
||||
ptr = calloc(num, size);
|
||||
else if (ptr == do_malloc)
|
||||
ptr = malloc(num * size);
|
||||
else if (ptr == do_calloc)
|
||||
ptr = calloc(num, size);
|
||||
else
|
||||
ptr = realloc(ptr, num * size);
|
||||
if (!ptr && file) {
|
||||
rprintf(FERROR, "[%s] out of memory (file=%s, line=%d)\n", who_am_i(), file, line);
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
if (!ptr && file)
|
||||
_out_of_memory("my_alloc caller", file, line);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -133,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;
|
||||
}
|
||||
|
||||
26
xattrs.c
26
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
|
||||
@@ -199,7 +199,7 @@ 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");
|
||||
ptr = new_array(char, datum_len + extra_len);
|
||||
|
||||
@@ -748,7 +748,7 @@ 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);
|
||||
name = rxa->datum + rxa->datum_len;
|
||||
@@ -799,8 +799,7 @@ 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);
|
||||
name = ptr + dget_len + extra_len;
|
||||
@@ -922,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