Compare commits

..

157 Commits

Author SHA1 Message Date
Wayne Davison
e94bad1c15 Preparing for release of 3.2.3 2020-08-06 20:57:26 -07:00
Wayne Davison
617d726a3d Tweak a comment. 2020-08-05 21:32:44 -07:00
Wayne Davison
020eda887f Change fetch depth. 2020-08-03 14:47:38 -07:00
Wayne Davison
b5f8021a12 Don't use --always to ensure a tag is in gitver. 2020-08-03 14:27:49 -07:00
Wayne Davison
7b6947576a Avoid a build fail when git isn't installed. 2020-08-03 14:20:08 -07:00
Wayne Davison
9375a8c4c2 Make my_alloc(NULL) use malloc instead of calloc. 2020-08-03 14:01:18 -07:00
Wayne Davison
7f5c4084c7 Use touch for proto.h-tstamp since one awk wasn't updating mtime. 2020-08-03 13:33:46 -07:00
Wayne Davison
6c89f00d1b Move SUPPORT_ATIMES to rsync.h. 2020-08-03 13:27:00 -07:00
Wayne Davison
dee0993286 Create usage.c for smaller awk-dep rebuilds. 2020-08-03 12:23:18 -07:00
Wayne Davison
47351c2b16 Use RSYNC_GITVER in more output 2020-08-03 10:46:31 -07:00
Wayne Davison
16b7670614 A couple more mkgitver tweaks
- Support git worktree checkouts (has non-dir .git)
- Use --always for someone who may be missing a tag.
2020-08-03 10:23:43 -07:00
Wayne Davison
72b2a81f90 Use --abbrev=8 instead of --tags. 2020-08-01 00:43:37 -07:00
Wayne Davison
d73c26d2b7 Put git version in a file for between-release versioning. 2020-08-01 00:15:06 -07:00
Wayne Davison
e83bbeb673 Don't make .PHONY the first target in a Makefile. 2020-07-30 18:58:34 -07:00
Wayne Davison
b6aa9c5cfe Make configure less annoying
- Improve configure's notifications around the new features.
- Improve the info about man page generation and fetching.
2020-07-30 18:33:58 -07:00
Wayne Davison
dfe3b77cb5 Some Makefile improvements.
- Improve distclean.
- Remove proto.h from GENFILES (we don't need to distribute it).
- Improve finddead target.
2020-07-29 11:51:55 -07:00
Wayne Davison
cbe3b2bfe5 Tweak a comment. 2020-07-29 11:51:52 -07:00
Wayne Davison
b1ae7fc941 INSTALL changes, including some Fedora packages. 2020-07-29 11:22:23 -07:00
Wayne Davison
8695bcc2b1 Preparing for release of 3.2.3pre1 2020-07-27 17:56:25 -07:00
Wayne Davison
4ae6f708b1 Need 3.2.3 line in table & tweak to release script. 2020-07-27 17:54:48 -07:00
Wayne Davison
14c4656fb8 A couple more NEWS updates. 2020-07-27 17:31:51 -07:00
Wayne Davison
13cec31f7f Set LANG to C to help with some remote build hosts. 2020-07-27 16:48:48 -07:00
Wayne Davison
5db7e4b1ee Use linkat() if available
Some OSes have a more capable linkat() function that can hard-link
syslinks, so use linkat() when it is available.
2020-07-27 16:36:55 -07:00
Wayne Davison
54693fa992 Add a few more skip-compress suffixes. 2020-07-27 15:56:48 -07:00
Wayne Davison
3f83bcb4af Make the --append* options have more warnings. 2020-07-27 15:21:50 -07:00
Wayne Davison
e1e546d67e Don't allow a completely empty source arg. 2020-07-27 14:49:51 -07:00
Wayne Davison
3714084f48 Mention an implied option. 2020-07-27 13:49:51 -07:00
Wayne Davison
eb2c3a5e18 Replace a couple calloc() calls with new_array0(). 2020-07-26 23:30:50 -07:00
Wayne Davison
f6967eca58 Complain about a missing/non-dir --temp-dir. 2020-07-26 02:01:30 -07:00
Wayne Davison
8455bf66c2 Don't include config.h in proto.h rule. 2020-07-26 01:40:55 -07:00
Wayne Davison
00e59e01e3 Mention awk/gawk/nawk dependency. 2020-07-26 01:40:43 -07:00
Wayne Davison
91eaffe13f Mention --protect-args in --chown info. 2020-07-26 01:02:07 -07:00
Wayne Davison
2066024981 Fix issue where rdev major could get out of sync
If the receiving side read a hard-linked device, it needs to set the
value of rdev_major to the value it snags from the hard-linked data
because the sender set their rdev_major value for that file entry.
2020-07-26 00:11:28 -07:00
Wayne Davison
d274b2096f Have release script use patch-update --make (not --shell) 2020-07-25 10:52:49 -07:00
Wayne Davison
0327a2526b Fix a grammar error. 2020-07-25 10:40:46 -07:00
Wayne Davison
f43412f1d5 More spelling fixes. 2020-07-25 10:34:26 -07:00
Wayne Davison
b9010ec617 Fix some spelling errors. 2020-07-25 10:21:50 -07:00
Wayne Davison
21ecc833ea Change new stderr options to --stderr=MODE. 2020-07-25 10:03:32 -07:00
Wayne Davison
f9bb8f76ee Change daemon variable & simplify some option code
- Rename daemon_over_rsh -> daemon_connection since it is also used to
  indicate if a non-rsh daemon connection is active.
- Move the daemon-over-rsh exception out of server_options() to the one
  caller that needs that behavior.
- Don't allow noop_io_until_death() to be short-circuited when talking
  to a daemon over a socket, because it can't send errors via stderr.
2020-07-25 09:36:42 -07:00
Wayne Davison
a5a9f268fe Tweak NEWS & src_file(). 2020-07-24 23:30:32 -07:00
Wayne Davison
0a255771f4 Add --errors2stderr & --msgs2protocol options. 2020-07-24 22:48:37 -07:00
Wayne Davison
e07d79ad50 Handle the first run of configure; prefer gmake. 2020-07-24 17:37:01 -07:00
Wayne Davison
2f74eb7584 Change smart-rebuild to smart-make. 2020-07-24 17:25:09 -07:00
Wayne Davison
39741c7d50 Fix the setting of $make. 2020-07-24 16:49:55 -07:00
Wayne Davison
3f016888fd Add helper script for a smart rebuild. 2020-07-24 14:19:19 -07:00
Wayne Davison
e5a012c959 Link to the git blob for source files. 2020-07-24 13:20:11 -07:00
Wayne Davison
c3cf174e5e More changes to NEWS, README, INSTALL, & configure.ac 2020-07-24 12:38:25 -07:00
Wayne Davison
a0a7c9f2e3 Enable xattrs on Cygwin.
- Tweak configure.ac to have Cygwin use linux xattrs.
- Change CI setup to install attr packages on Cygwin.

[buildall]
2020-07-24 11:38:14 -07:00
Wayne Davison
a8f61ba937 Add Cygwin package info into INSTALL.md. 2020-07-24 11:37:50 -07:00
Wayne Davison
842d6edfdc Fix devices-fake test if rsync can't link specials
- Add info about hardlinked specials to --version output.
- Use "no hardlink-special" info to ensure that the devices-fake
  test will not fail.
2020-07-24 11:33:21 -07:00
Wayne Davison
92a8855ff3 Install python3 for cygwin [buildall] 2020-07-24 10:10:26 -07:00
Wayne Davison
def96fd7c4 Install python36 for cygwin [buildall] 2020-07-24 09:57:41 -07:00
Wayne Davison
f624a73bbc Change the --mkpath message. 2020-07-24 09:46:53 -07:00
Wayne Davison
93a373f6ba Some INSTALL improvements. 2020-07-24 09:42:49 -07:00
Wayne Davison
01742c07e6 Add --mkpath option. Fixes bugzilla bug 4621. 2020-07-23 20:54:38 -07:00
Wayne Davison
e00662f263 Add packages to INSTALL.md; put INSTALL.md on ftp site 2020-07-23 17:29:13 -07:00
Wayne Davison
491ddb08a4 Simplify md_parser assignment. 2020-07-23 17:28:34 -07:00
Wayne Davison
918cb39fed Fix multi-line code blocks. 2020-07-23 16:22:12 -07:00
Wayne Davison
1369fe43e1 Tweak ubuntu configure args. 2020-07-23 12:32:41 -07:00
Wayne Davison
150f3416ac Setup commonmark on Cygwin. 2020-07-23 12:20:40 -07:00
Wayne Davison
d8941be8cb Simplify the msgs2stderr default logic. 2020-07-23 12:15:50 -07:00
Wayne Davison
592059c8fd Improve error output for local & remote-shell xfers 2020-07-23 11:23:47 -07:00
Wayne Davison
37f4a23f60 Drop a superfluous "+". 2020-07-22 21:42:24 -07:00
Wayne Davison
27be94c889 A few more build improvements
Includes Ben's RSYNC_MAX_SKIPPED=3 suggestion for FreeBSD and a fix for
the artifact file list for Cygwin.
2020-07-22 21:01:01 -07:00
Wayne Davison
974f49e22a Add --crtimes option. 2020-07-22 12:12:18 -07:00
Wayne Davison
9f7506ac1b Improve --itemize-changes doc. 2020-07-22 11:30:00 -07:00
Wayne Davison
8779d6c8bb Switch to RSYNC_MAX_SKIPPED test setting. 2020-07-22 11:00:26 -07:00
Wayne Davison
96be713fd2 Update NEWS. 2020-07-21 12:37:56 -07:00
Wayne Davison
13d8fc9542 Avoid some extraneous parent-dir warnings
Don't complain about an absent parent dir if the current file is marked
as missing and there is a marked-as-missing entry for the parent dir.
2020-07-21 11:54:54 -07:00
Wayne Davison
f74473b151 Don't create a path for a file marked as missing. 2020-07-21 11:54:48 -07:00
Wayne Davison
5eda68f11b Tweak include syntax. 2020-07-20 18:45:36 -07:00
Wayne Davison
f635207347 Save the build into an artifact. 2020-07-20 14:44:35 -07:00
Wayne Davison
64f7e893f3 Ignore *.exe files (for Cygwin builds). 2020-07-20 14:43:06 -07:00
Wayne Davison
31556ec7a8 Use just $(...) instead of a mix of that and ${...}. 2020-07-20 14:42:13 -07:00
Wayne Davison
9ad3f4385f Make the daily build happen a few hours later. 2020-07-18 23:17:25 -07:00
Wayne Davison
e9899dbdb4 Add strict (no-skipping) checks and use them. 2020-07-17 11:20:04 -07:00
Wayne Davison
18cffa8aa9 A couple minor changes. 2020-07-17 10:56:22 -07:00
Wayne Davison
7e07a32504 Add the name converter daemon parameter.
This is based on the long-standing patch but with the protocol changed
to just use newlines as delimiters instead of null chars (since names
should not contain a newline AND it makes it easier to write a helper
script).  Lots of other small improvements and a better default value
for "numeric ids" when using "use chroot" with "name converter".
2020-07-17 10:30:59 -07:00
Wayne Davison
be11a496bb Run a daily build. 2020-07-16 22:04:40 -07:00
Wayne Davison
c6f5f0b505 Let's try cygwin again. (#69)
Setup an optional cygwin build that is currently triggered when a [buildall] is in the commit message (the build is currently quite slow).
2020-07-15 14:30:22 -07:00
Wayne Davison
f553da1730 GitHub artifact test didn't work. 2020-07-15 13:53:40 -07:00
Wayne Davison
40753bcbf7 Tweak the save path. 2020-07-15 13:42:36 -07:00
Wayne Davison
33df361d52 Avoid normal build on cygwin-save change. 2020-07-15 13:20:40 -07:00
Wayne Davison
f4db970718 Try to get cygwin-save to run. 2020-07-15 13:16:36 -07:00
Wayne Davison
ab3928898f Try to save cygwin install in an artifact. 2020-07-15 12:31:38 -07:00
Ben RUBSON
13f274fd02 Force git line endings (#68) 2020-07-15 10:20:52 -07:00
Wayne Davison
b51fe50e7f Tweak the workflows filename. 2020-07-14 21:47:50 -07:00
Wayne Davison
1829a2ee0d Disable cygwin for now. 2020-07-14 21:47:11 -07:00
Wayne Davison
65370a0f56 Try a couple different way to fix the build. 2020-07-14 21:32:41 -07:00
Wayne Davison
23213099e9 Try Cygwin build in actions. 2020-07-14 21:18:52 -07:00
Wayne Davison
25e08110d5 Let's try a Cygwin build on Cirrus. 2020-07-14 20:41:44 -07:00
Wayne Davison
95f683039d Mention the auto-build-save setup. 2020-07-14 20:25:02 -07:00
Ben RUBSON
129d7195ff Enable FreeBSD CI ssl (#66) 2020-07-14 13:22:55 -07:00
Wayne Davison
044339d6b4 Reduce the installed pkg items since they are so slow. 2020-07-13 16:26:58 -07:00
Wayne Davison
4c4fc7462a A few more NEWS & man tweaks. 2020-07-13 16:14:27 -07:00
Wayne Davison
22cb57ee20 Try using cmarkgfm. 2020-07-13 15:44:43 -07:00
Wayne Davison
4c0be4da13 Avoid a failed test on Cygwin. 2020-07-13 15:33:07 -07:00
Wayne Davison
4549855126 Search for cmark. 2020-07-13 14:09:24 -07:00
Wayne Davison
284c28c773 Add new code to recv_group_name() too. 2020-07-13 13:43:17 -07:00
Wayne Davison
d2406ae372 Give up on commonmark. 2020-07-13 13:42:28 -07:00
Wayne Davison
1e9c34972a Avoid a crash if id-0 doesn't exist. 2020-07-13 13:18:38 -07:00
Wayne Davison
116bd19324 One more commonmark try. 2020-07-13 13:12:39 -07:00
Wayne Davison
883de22c29 Avoid a test failure if id didn't work. 2020-07-13 12:59:22 -07:00
Wayne Davison
18f500a7a4 Try another way to get commonmark working. 2020-07-13 12:59:07 -07:00
Wayne Davison
d14b0ca4db Install commonmark on FreeBSD. 2020-07-13 12:18:13 -07:00
Wayne Davison
4156e7d464 Tweak lsh's Usage message & opening comment. 2020-07-13 12:01:00 -07:00
Wayne Davison
9e48da65c1 Search for commonmark pkg. 2020-07-13 12:00:56 -07:00
Wayne Davison
2cdf9416ee Tweak brew run. 2020-07-13 10:41:26 -07:00
Wayne Davison
cd0c83e485 Setup a macOS CI. 2020-07-13 10:38:17 -07:00
Wayne Davison
0e814e956c A couple more NEWS items. 2020-07-12 23:45:55 -07:00
Wayne Davison
f47e5a7732 Mention file & line on OOM and overflow errors.
Also simplify output of src file paths in errors & warnings when
built in a alternate build dir.
2020-07-12 23:25:21 -07:00
Wayne Davison
91fff802b9 Check for overflow the right way. 2020-07-12 22:45:01 -07:00
Wayne Davison
3c8ac20d63 Fix a typo. 2020-07-12 20:51:21 -07:00
Wayne Davison
38a521defd More NEWS tweaks. 2020-07-12 20:49:01 -07:00
Wayne Davison
2f13049600 Add "@netgroup" names to host matching. 2020-07-12 19:16:57 -07:00
Wayne Davison
af531cf787 Add the --stop-after & --stop-at options. 2020-07-12 18:32:41 -07:00
Wayne Davison
d495e343c0 A few word tweaks. 2020-07-12 12:38:12 -07:00
Ben RUBSON
de7e4d00ab Improve FreeBSD tests (#61)
Improve FreeBSD tests & use a ZFS mount for the CI's testtmp.
2020-07-12 12:36:02 -07:00
Wayne Davison
374cc1be74 Get my yaml continuation line right. 2020-07-11 16:22:48 -07:00
Wayne Davison
8b25488fe9 More CI tweaks
- Add to ubuntu build: make install & rsync-ssl test run
- Don't fail a build if samba.org daemon list has an issue.
2020-07-11 16:08:22 -07:00
Wayne Davison
4f5742baa0 Make sure FreeBSD has bash installed. 2020-07-11 15:51:05 -07:00
Wayne Davison
2b416de4ca More FreeBSD script separation. 2020-07-11 15:37:51 -07:00
Wayne Davison
1f41b7dca1 Add a little more FreeBSD testing. 2020-07-11 15:32:51 -07:00
Wayne Davison
486e7852db Add FreeBSD test & re-enable linux build. 2020-07-11 15:03:31 -07:00
Wayne Davison
a68a92793c Just disable md2man on FreeBSD for now. 2020-07-11 12:28:05 -07:00
Wayne Davison
a84e8aced7 Add 2 more FreeBSD pkg installs. 2020-07-11 12:22:05 -07:00
Wayne Davison
3bc2d9aeaa Add some FreeBSD pkg installs and pause on linux. 2020-07-11 12:11:13 -07:00
benrubson
6214c26bd3 Add FreeBSD CI 2020-07-11 11:54:33 -07:00
Wayne Davison
da7a350667 Some number & string improvements
- Use strdup(do_big_num(...)) to replace num_to_byte_string(...).
- Allow a ',' for a decimal point in a SIZE option in some locales.
- Get rid of old (now unused) strdup() compatibility function.
- Try harder to include the newline in a single error message write.
2020-07-11 11:39:36 -07:00
Wayne Davison
66ca4fc97b Allow --block-size's size to have a suffix.
Change the block_size global to be an int32.
2020-07-10 13:00:42 -07:00
Wayne Davison
7d63f8b249 Add missing "M" in SIZE suffixes; mention bytes are the default. 2020-07-10 09:59:17 -07:00
Wayne Davison
bb1365dd77 Fix see_token zstd case. 2020-07-10 09:47:16 -07:00
Wayne Davison
bcc273d460 Clean more built .h files. 2020-07-09 15:18:11 -07:00
Wayne Davison
a6da3c67f8 Must read the nsec val even w/o CAN_SET_NSEC. 2020-07-08 14:17:01 -07:00
Wayne Davison
ab110fc8fb Warning fixes & impossible-failure improvements
- Silence a couple warnings for less-common builds.
- Use a better impossible-failure idiom than assert(0).
2020-07-08 12:26:19 -07:00
Wayne Davison
7265d96116 Avoid non-updating proto.h on Alpine. 2020-07-07 23:50:55 -07:00
Wayne Davison
560b63b051 Avoid a test failure on Alpine. 2020-07-07 23:05:41 -07:00
Wayne Davison
0eb82a7c90 Fix xattr issue with MIGHT_NEED_PRE.
Fixes bugzilla 13113.
2020-07-07 20:07:31 -07:00
Wayne Davison
f92a5182fc Tweak the NEWS. 2020-07-07 19:50:13 -07:00
Wayne Davison
fb6fabc116 Fix an xattr free of the wrong object.
In uncache_tmp_xattrs() the code used to find the value to unlink,
update the single-linked list, and then free the wrong pointer.
This fixes bug #50.
2020-07-07 14:25:58 -07:00
Wayne Davison
c3269275a8 Don't use UNUSED() when an arg is used sometimes. 2020-07-07 13:12:51 -07:00
Wayne Davison
7e47855d47 Update the NEWS. 2020-07-07 12:38:20 -07:00
Wayne Davison
d2d6ad481a Allow --max-alloc=0 for unlimited. 2020-07-07 11:56:23 -07:00
Wayne Davison
5dcb49c7dd Allow --bwlimit=0 again. 2020-07-07 11:43:33 -07:00
Wayne Davison
19d8550cf4 One more TANDEM include. 2020-07-06 09:41:31 -07:00
Wayne Davison
7610f76aea Remove another file_struct kluge. 2020-07-06 09:31:22 -07:00
Wayne Davison
59cb358fda More TANDEM changes
- Handle a non-0 root uid.
- Handle alternate major/minor/MAKEDEV funcs.
- Other misc compatibility tweaks.
2020-07-06 00:05:46 -07:00
Wayne Davison
bb16db1747 Send the uid/gid 0 name since not all systems use 0 for root. 2020-07-05 22:51:12 -07:00
Wayne Davison
d6f0342a34 Change name map funcs to return a const char*. 2020-07-05 22:17:09 -07:00
Wayne Davison
6f6e5b51cc Some TANDEM ACL support. 2020-07-05 20:09:16 -07:00
Wayne Davison
28de25a664 Some whitespace & paren cleanup. 2020-07-05 20:09:13 -07:00
Wayne Davison
052b34dceb A bit more configure tweaking. 2020-07-05 19:16:32 -07:00
Wayne Davison
748b5c5d53 Some configure tweaks for TANDEM. 2020-07-05 19:08:44 -07:00
Wayne Davison
e1e4ffe057 Some C99 flexible array changes
- Use C99 flexible arrays when possible, and fall back on the existing
  fname[1] kluges on older compilers.
- Avoid static initialization of a flexible array, which is not really
  in the C standard.
2020-07-05 17:25:53 -07:00
Wayne Davison
1b53b2ff4b Tweak a comment. 2020-07-05 14:42:36 -07:00
Wayne Davison
da45cecfc8 Tweak a couple var names. 2020-07-05 14:22:09 -07:00
Wayne Davison
87b5d233e9 Setup for 3.2.3dev. 2020-07-05 09:26:40 -07:00
75 changed files with 2767 additions and 1247 deletions

22
.cirrus.yml Normal file
View 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
View File

@@ -0,0 +1 @@
* text=auto eol=lf

117
.github/workflows/build.yml vendored Normal file
View 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

View File

@@ -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
View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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 |

View File

@@ -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

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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??? */

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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
View File

@@ -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;

View File

@@ -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;

View File

@@ -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
View File

@@ -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)

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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
View 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

View File

@@ -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
View File

@@ -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, &copy_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);

View File

@@ -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

View File

@@ -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

View File

@@ -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('--', '&#8209;&#8209;').replace("\xa0-", '&nbsp;&#8209;').replace("\xa0", '&nbsp;')
html = re.sub(r'(\W)-', r'\1&#8209;', 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.")

View File

@@ -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.")

View File

@@ -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`

View File

@@ -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
View 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

View File

@@ -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>

View File

@@ -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.

View File

@@ -1,7 +1,7 @@
SHELL=/bin/sh
.PHONY: conf
conf: configure.sh config.h.in
.PHONY: conf
aclocal.m4: m4/*.m4
aclocal -I m4

View File

@@ -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
View File

@@ -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
View File

@@ -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)

View File

@@ -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.

View File

@@ -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

View File

@@ -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.")

View File

@@ -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
View 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

View File

@@ -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];

View File

@@ -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;

View File

@@ -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
View 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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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."

View File

@@ -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

View File

@@ -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"'

View File

@@ -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
View 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

View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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
View 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
View File

@@ -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
View File

@@ -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;
}

View File

@@ -1 +1 @@
#define RSYNC_VERSION "3.2.2"
#define RSYNC_VERSION "3.2.3"

View File

@@ -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;