Compare commits

...

345 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
Wayne Davison
194cee671d Preparing for release of 3.2.2 2020-07-04 23:12:59 -07:00
Wayne Davison
b7c5520add Handle tweaked NEWS headings & protocol change. 2020-07-04 23:11:46 -07:00
Wayne Davison
2bee307592 Get rid of some superfluous lz4 code. 2020-07-04 16:13:00 -07:00
Wayne Davison
85e62c330d Tweak indentation. 2020-07-04 16:10:37 -07:00
Wayne Davison
0add026a5d Initialize values string in a more consistent spot. 2020-07-04 14:21:15 -07:00
Wayne Davison
f4184849c4 Use module_id more consistently after it is set. 2020-07-04 10:28:39 -07:00
Wayne Davison
565cde84a7 Don't turn off the user's open-noatime unless the module is forcing the value. 2020-07-04 10:28:38 -07:00
Paul Slootman
f0e670b4c6 Add "open noatime" module option to rsyncd.conf 2020-07-04 09:30:35 -07:00
Wayne Davison
ef8951779d Fix issue in --compress-level doc. 2020-07-03 11:58:36 -07:00
Wayne Davison
e285f8f9d2 Some NEWS and man page tweaks. 2020-07-02 22:33:40 -07:00
Wayne Davison
cb383673f6 Tweak a var name. 2020-07-02 09:34:08 -07:00
Wayne Davison
0768d620a5 Another table tweak. 2020-07-01 14:20:14 -07:00
Wayne Davison
d640d78f91 Change how protocol changes are mentioned; fix table in html. 2020-07-01 14:14:24 -07:00
Wayne Davison
544b3d8b3b A few more systemd tweaks. 2020-07-01 12:10:14 -07:00
Wayne Davison
ce12142c45 Don't set systemd ProtectHome=on by default. 2020-07-01 10:41:13 -07:00
Wayne Davison
c83a81ca38 Move name exceptions into the txt file. 2020-07-01 09:05:21 -07:00
Wayne Davison
d88db22ae8 Add support for the remaining parser types. 2020-07-01 08:15:12 -07:00
Wayne Davison
a1cc50ba96 Preparing for release of 3.2.2pre3 2020-06-30 23:17:50 -07:00
Wayne Davison
feb2fff894 Put the optimizations into their own list. 2020-06-30 19:31:59 -07:00
Wayne Davison
7d30490ef4 Simplify the daemon parameter definitions
The code now derives all the struct defines, default value assignments,
parser-param defines, and lp_foo() accessor functions from a single list
of daemon parameters.
2020-06-30 19:30:28 -07:00
Wayne Davison
317beebef8 Avoid crash of transfer logging w/default log format. 2020-06-30 12:16:52 -07:00
Wayne Davison
7a413c9722 Avoid strdup redefinition warning. 2020-06-30 08:27:20 -07:00
Wayne Davison
5be7363297 Avoid bloating the src-dir scan. 2020-06-29 21:45:56 -07:00
Wayne Davison
646784f0e5 Move the new target after "all". 2020-06-29 20:04:54 -07:00
Wayne Davison
18ed3f0279 More patch-update improvements; configure.ac tweak; Makefile tweaks. 2020-06-29 19:53:05 -07:00
Wayne Davison
00dd50a00c Preparing for release of 3.2.2pre2 2020-06-28 19:54:38 -07:00
Wayne Davison
7039d14616 Improve the per-branch build dir support
The release script & the patch management script now require the use of
an auto-build-save dir that makes it much easier to keep the generated
files from melding together, and remembers the configure setup for each
patch branch.
2020-06-28 19:42:25 -07:00
Wayne Davison
ec3c9f2f5a Improve alternate build-dir support
We now put the configure.sh, config.h.in, and aclocal.m4 files in the
alternate build dir along with the other generated files.  This requires
that we create symlinks for configure.ac & m4 in the build dir, which is
handled on the first run of configure or prepare-source.  I also changed
the patch-branch handling away from the .gen-stash dir to an automatic
build/$PATCH subdir idiom that will keep each branch's configuration
separated.  These automatic build dirs are only used when there is a
.git dir, a build/master dir, and no top-dir Makefile.  You'll also
want to have package/make early on your path for optimal ease of use.
2020-06-28 15:12:10 -07:00
Wayne Davison
3b4f5fb891 Move the version string out of configure.ac. 2020-06-28 15:02:19 -07:00
Wayne Davison
76064b1bf2 Fix rebuilding configure.sh in an alternate build dir 2020-06-28 12:55:43 -07:00
Wayne Davison
8df766917e A bit more man page & NEWS tweaking. 2020-06-28 09:21:29 -07:00
Wayne Davison
299430a6c1 Lack of "saw" values now reported as "INVALID"; tweak a comment. 2020-06-27 23:14:35 -07:00
Wayne Davison
dcbe005a6a Preparing for release of 3.2.2pre1 2020-06-27 21:22:49 -07:00
Wayne Davison
af57b55bdb Some misc cleanup
Remove some extraneous vars, update some years, add an  rrsync opt, &
ensure some less options are set right when running release-rsync.
2020-06-27 21:19:52 -07:00
Wayne Davison
967e6426b9 Improve the NSTR differentiation idiom. 2020-06-27 20:43:38 -07:00
Wayne Davison
61971acbe1 Some more doc & NEWS improvements. 2020-06-27 20:43:34 -07:00
Wayne Davison
5bd0b6cf71 Change the CI name 2020-06-27 18:40:21 -07:00
Wayne Davison
0eec25f75b Some patch-update & vim ft improvements
- Stash off some gen files when switching patch branches.
- Set the filetype in "env -S" files that vim can't handle.
2020-06-27 17:59:04 -07:00
Wayne Davison
3a6f06003c Improve the output when a negotiation fails. 2020-06-27 10:51:29 -07:00
Wayne Davison
f805d1a7f7 More NEWS and man page changes. 2020-06-27 10:39:12 -07:00
Wayne Davison
ab29ee9c44 Negotation env lists can specify "client & server" 2020-06-26 17:56:57 -07:00
Wayne Davison
d07c2992d1 A few more simple changes & fixes. 2020-06-26 13:19:07 -07:00
Wayne Davison
b1a8b09c21 Some man page changes. 2020-06-26 11:27:27 -07:00
Wayne Davison
fe2ef556d9 A few more tweaks. 2020-06-25 22:30:02 -07:00
Wayne Davison
11eb67eec9 Some memory allocation improvements
- All the memory-allocation macros now auto-check for failure and exit
   with a failure message that incudes the caller's file and lineno
   info.  This includes strdup().

 - Added the `--max-alloc=SIZE` option to be able to override the memory
   allocator's sanity-check limit.  It defaults to 1G (as before).
   Fixes bugzilla bug 12769.
2020-06-25 20:54:21 -07:00
Christian Hesse
39a083b16b Add missing semicolon in man page
All nginx configuration directives end in semicolon.
2020-06-24 17:54:47 -07:00
Wayne Davison
202b7b18af Tweak alloc args to size_t w/proper realloc order. 2020-06-24 17:52:36 -07:00
Wayne Davison
20934382e3 Use normal C comment style. 2020-06-23 21:45:32 -07:00
Wayne Davison
1bdf68b905 Prepare for future release of XXH3 & XXH128. 2020-06-23 21:01:25 -07:00
Wayne Davison
89827e49bc Another NEWS update. 2020-06-23 19:32:44 -07:00
Wayne Davison
f157ff3b3a Avoid negotiating a "none" choice by default
The client does not pass "none" as a negotiation choice unless it's from
the user's environment list.  The server still passes the "none" value
to the client unless its environment var excludes it.
2020-06-23 19:20:01 -07:00
Wayne Davison
d15cfef935 Setup for 3.2.2dev. 2020-06-23 19:02:59 -07:00
Wayne Davison
28f9c960d5 The server side can enforce its negotiation limits 2020-06-23 18:53:23 -07:00
Wayne Davison
323c42d51e Improve how the env restricts negotiated strings
- The env on the server side now affects the negotiated strings
  that are sent to the client.
- A too-old remote rsync gets a default negotiated string value
  so that an env restriction now handles old clients the same way
  as new ones.
2020-06-23 17:33:16 -07:00
Wayne Davison
d1fdf9ff8d Avoid -U if --atimes is disabled. 2020-06-23 15:53:47 -07:00
Wayne Davison
e93f40d8b4 Apple needs a leading underscore. 2020-06-23 15:47:27 -07:00
Hiroshi Takekawa
4df1b1d4fe Makefile.in: Use srcdir for installing rsync-ssl
When building out of source tree, we can't find rsync-ssl in the current
directory and installation fails.  Fix it by using the srcdir variable for the
path to rsync-ssl.

Signed-off-by: Hiroshi Takekawa <sian.ht@gmail.com>
2020-06-23 09:02:33 -07:00
Wayne Davison
1af58f6b77 Improve the info about compression. 2020-06-22 20:37:52 -07:00
Wayne Davison
a8fc8fc2d2 Preparing for release of 3.2.1 2020-06-22 19:31:16 -07:00
Wayne Davison
b8b7f1f3d0 Fix a typo. 2020-06-22 19:30:07 -07:00
Wayne Davison
622a116917 A few more man page tweaks. 2020-06-22 19:21:32 -07:00
Wayne Davison
b51b0b3236 Get the NEWS heading idiom right. 2020-06-22 14:46:14 -07:00
Wayne Davison
8cb1c99563 A few more https changes. 2020-06-22 14:21:15 -07:00
Wayne Davison
597a751466 Update links to https. 2020-06-22 14:16:21 -07:00
Wayne Davison
5a9e4ae5e7 Improve the options info a bit more. 2020-06-22 14:12:27 -07:00
Wayne Davison
3094552311 Add --zl=N opt & improve its docs. 2020-06-22 13:41:42 -07:00
Samuel Henrique
e4c9ff5873 Make --backup be set when --backup-dir is used 2020-06-22 13:05:17 -07:00
Samuel Henrique
9b13bcf185 Add Documentation field to systemd unit 2020-06-22 13:01:02 -07:00
Wayne Davison
8f6d6bcb08 Tweak valid_ipaddr() check. 2020-06-22 11:17:56 -07:00
Wayne Davison
300fd3055a Even more NEWS changes. 2020-06-22 09:57:29 -07:00
Wayne Davison
f6df3708c2 A few more NEWS changes; change release script. 2020-06-22 09:09:51 -07:00
Wayne Davison
785cb938ec Even more NEWS improvements. 2020-06-21 23:30:00 -07:00
Wayne Davison
246d117df0 A bit more NEWS tweaking. 2020-06-21 23:07:16 -07:00
Wayne Davison
3f776f582b More talk of buggy clang++. 2020-06-21 22:53:33 -07:00
Wayne Davison
d8d2d71663 Get the g++ version to see if it is really clang. 2020-06-21 22:34:32 -07:00
Wayne Davison
6a9adabfbb Mention the early-input on stdin. 2020-06-21 20:25:51 -07:00
Wayne Davison
2564f25114 Put the date in the heading of a pre release too. 2020-06-21 19:46:28 -07:00
Wayne Davison
7fb08531e0 Preparing for release of 3.2.1pre1 2020-06-21 19:24:26 -07:00
Wayne Davison
9dba0bb7fb Improve the simd note. 2020-06-21 18:52:28 -07:00
Wayne Davison
87bca719c3 Merge OLDNEWS.md into NEWS.md 2020-06-21 18:42:53 -07:00
Wayne Davison
f3439944ea The proto files don't need perl, so change fetch rule. 2020-06-21 16:46:50 -07:00
Wayne Davison
a7c1690d62 One more >= tweak. 2020-06-21 15:30:34 -07:00
Wayne Davison
662fedd74b Get the early-input reading code right. 2020-06-21 15:23:13 -07:00
Wayne Davison
128139c66a Leave 3.2.0 news in the NEWS file for 3.2.1. 2020-06-21 15:20:43 -07:00
Wayne Davison
2b439c1fc8 Disable atimes on macOS. 2020-06-21 15:16:56 -07:00
Wayne Davison
e16b22751a Add --early-input=FILE option. 2020-06-21 14:32:00 -07:00
Wayne Davison
7587e20cf4 Output a helpful msg about configure only if the command fails. 2020-06-21 12:55:24 -07:00
Wayne Davison
2e1b46db39 Close STDIN for early exec script. 2020-06-21 11:17:09 -07:00
Wayne Davison
f4e6fe54c9 More NEWS changes. 2020-06-21 09:18:52 -07:00
Wayne Davison
f86ceb5539 Give more_testing() a default target. 2020-06-21 09:06:59 -07:00
Wayne Davison
dfa34b4792 Some more docs/news changes.
- Mention the -VV behavior.
- Mention how the protect-args default is presented in -V list.
2020-06-21 08:58:45 -07:00
Wayne Davison
e9e9fd0cca Use an ssse3 target instead of an inline declaration. 2020-06-21 08:28:49 -07:00
Wayne Davison
7e95ba8787 Add -fno-slp-vectorize to clang++. 2020-06-21 08:05:19 -07:00
Wayne Davison
66fd34ed84 Mention atimes & protected-args in capabilities. 2020-06-20 23:28:19 -07:00
Wayne Davison
f8c6f9f4f3 Tweak the NEWS. 2020-06-20 23:15:22 -07:00
Wayne Davison
e6cfebb578 We only need one capability marked with a "*". 2020-06-20 22:09:08 -07:00
Wayne Davison
5d2379d93f Mention "asm" instead of "ASM". 2020-06-20 21:59:51 -07:00
Wayne Davison
6884ccbd2f Mention openssl-crypto in -VV list. 2020-06-20 21:44:46 -07:00
Wayne Davison
bad97961dc Elide -g from CXXFLAGS before the c++ test. 2020-06-20 21:26:21 -07:00
Wayne Davison
b0ab07cdac Some README and man page tweaks. 2020-06-20 20:31:52 -07:00
Wayne Davison
68c4583693 Change repo to be 3.2.1dev. 2020-06-20 20:17:13 -07:00
Wayne Davison
6b237b0fe9 Require -VV to see SIMD & ASM in version output 2020-06-20 19:57:11 -07:00
Wayne Davison
b37a136314 Get rid of -g option in CXXFLAGS (at least for now). 2020-06-20 19:23:54 -07:00
Wayne Davison
c9c8c64506 Remove leftover case match. 2020-06-20 19:00:57 -07:00
Wayne Davison
c5d502dc5f When fetching gen files, make sure aclocal.m4 is older than configure files. 2020-06-20 18:46:16 -07:00
Wayne Davison
1629b803cb More asm improvements
- Only use the asm code if we're on x86_64.
- More changes to decouple asm from simd.
- Check if the -Wa,--noexecstack option works.
- Support --disable-asm configure option.
2020-06-20 18:40:47 -07:00
Wayne Davison
29c7a4558a Include more SIMD test code to weed out older compilers. 2020-06-20 17:48:56 -07:00
Wayne Davison
b7dc2ca25c Decouple the MD5 asm code from the simd enabling. 2020-06-20 17:01:25 -07:00
Wayne Davison
f525f2c818 Remove asm type & size. 2020-06-20 16:54:24 -07:00
Wayne Davison
1b5819efbd Use AC_RUN_IFELSE() to make sure we can run the cpp test program. 2020-06-20 14:47:55 -07:00
Wayne Davison
a56a0bc7d6 Mention how to turn off simd near the cpp compile. 2020-06-20 11:53:22 -07:00
Wayne Davison
bd7bd5ff0c Simplify some escaping. 2020-06-20 11:35:56 -07:00
Wayne Davison
f9aece899f Change SIMD test to use a compile check. 2020-06-20 11:13:06 -07:00
Wayne Davison
63508f1518 Handle hard-linking the top-level $VER-NEWS.html file on a final release. 2020-06-20 09:57:35 -07:00
Wayne Davison
9ac22062af The nightly dir is gone now. 2020-06-20 09:43:25 -07:00
Wayne Davison
73faaab26d Pass --noexecstack to assembler. 2020-06-20 09:23:56 -07:00
Wayne Davison
9467c1f9b9 Fix conditional directives in the asm file
- Switch .s -> .S to enable the preprocessor.
- Move some defines from mdigest.h to md-defines.h.
- Tweak the asm file to use md-defines.h.
- Add a couple missing .h dependencies in the Makefile.
2020-06-20 09:06:18 -07:00
Wayne Davison
04653dabc8 Exclude the asm code when it's not being used. 2020-06-20 08:05:53 -07:00
Wayne Davison
19617f7b4a Fix compiling in a separate dir. 2020-06-20 08:05:53 -07:00
Caleb Xu
b218de2702 lib/md5-asm-x86_64.s: fix build with Apple Clang
The Mach-O x86-64 model doesn't seem to support ".type" and
".size" directives in assembly. Add ifdefs that should allow for
the file to build without issues in Apple Clang.
2020-06-19 23:38:15 -07:00
Wayne Davison
d4764934c3 A slightly modified g++/clang++ check. 2020-06-19 23:29:31 -07:00
Wayne Davison
c225330aaf Preparing for release of 3.2.0 2020-06-19 14:11:01 -07:00
Wayne Davison
3c56896d21 Simplify a variable. 2020-06-19 11:07:02 -07:00
Wayne Davison
deb8353d2c Yes, we know we're discarding a return value. 2020-06-19 10:56:32 -07:00
Wayne Davison
73053f26bc Simple change to recv_token(). 2020-06-19 09:55:48 -07:00
Holger Hoffstätte
0c13e1b3f8 Prevent unnecessary xattr warning by reordering header inclusion. (#22)
xattr headers have been provided by glibc (at least on Linux/glibc)
for many years now. Reorder the inclusion of xattr headers to
attempt compatibility/legacy after the common case.
This prevents the warning without changing compatibility to
non-glibc systems.

* Add dependency on lib/sysxattrs.h header in Makefile

Co-authored-by: Wayne Davison <wayne@opencoder.net>
2020-06-19 08:22:54 -07:00
Wayne Davison
9da38f2f99 A few minor man page tweaks. 2020-06-19 00:26:43 -07:00
Wayne Davison
a93ffb1ae9 More non-breaking space/dash improvements
- In html, use css more for non-breakability.
- In nroff, mark more dashes as non-breaking in code->bold sections,
  and get rid of backslashed dashes in preformatted blocks.
2020-06-18 23:55:51 -07:00
Wayne Davison
e08f600378 Use -&#8288; instead of &#8209;
Using a non-breaking zero-width char after a dash makes the browser
avoiding breaking on that dash and also makes it match a dash in a
search.  This is better than a non-breaking dash char, which does not
match a dash in a search.
2020-06-18 22:58:11 -07:00
Wayne Davison
e406845542 Comment must be indented to avoid ending the list item. 2020-06-18 21:57:34 -07:00
Wayne Davison
a93eb4cf38 Handle a missing c++ too. 2020-06-18 17:02:46 -07:00
Wayne Davison
7fd24bef0f Make SIMD enabled by default again (for x86_64) 2020-06-18 16:28:28 -07:00
Wayne Davison
1a9a184145 Check extra rounding using an int64. 2020-06-18 15:45:39 -07:00
Wayne Davison
4965ccf283 We need to use nawk or gawk on Solaris, not their weird awk. 2020-06-18 14:53:55 -07:00
Wayne Davison
c6f89cbf9c Complain if we can't enable simd on non-x86_64. 2020-06-18 14:27:00 -07:00
Wayne Davison
2921779c1f Fix clang check. 2020-06-18 13:46:01 -07:00
Wayne Davison
cbed522ef4 Get rid of useless -e with sed. 2020-06-18 13:31:50 -07:00
Chainfire
4f539ccf21 x86-64 SIMD build fixes (#20)
* x86-64 SIMD build fixes

configure.ac was modified to detect g++ >=5 and clang++ >=7. Additionally
some script malfunctions on FreeBSD were corrected.

The get_checksum1() code has been modified to fix clang and g++ 10
compilation.

This version of the code and configure.ac has been tested on:

Ubuntu 16 - gcc 7.3.0, clang 6.0.0
Debian 10 - gcc 5.4.0, 6.4.0, 7.2.0, 8.4.0, 9.2.1, 10.0.1, clang 5.0.2,
6.0.1, 7.0.1, 8.0.0, 9.0.0, 10.0.0
ArchLinux 20200605 - gcc 10.1.0, clang 10.0.0
FreeBSD 12.1 - gcc 9.3.0, clang 8.0.1

It is unknown if it will work on gcc 5.0-5.3, but the script currently
allows it.
2020-06-18 13:20:44 -07:00
Wayne Davison
b5e539fc5a Use documentation to extract 2 more .h lists
- Change default_cvsignore char[] into a define.
- Make the DEFAULT_DONT_COMPRESS and DEFAULT_CVSIGNORE defines get set
  based on their info in rsync.1.md.
- Add a few more don't-compress suffixes from Simon Matter.
2020-06-18 11:20:57 -07:00
Wayne Davison
88c18ef648 Make the g++ check more lenient. 2020-06-18 09:31:47 -07:00
Wayne Davison
7dc9431f60 A few minor man page improvements. 2020-06-17 11:25:38 -07:00
Wayne Davison
07a3e1f939 Enhance compatibility with older python3 versions. 2020-06-17 10:52:02 -07:00
Wayne Davison
93223719c9 A couple more NEWS tweaks. 2020-06-17 10:30:32 -07:00
Wayne Davison
0b2d5fe494 Preparing for release of 3.2.0pre3 2020-06-17 10:12:09 -07:00
Wayne Davison
d3c7cfad22 Be a little more explicit with override info. 2020-06-17 09:31:48 -07:00
Christian Hesse
9ec777faf8 add a systemd socket unit for rsync 2020-06-17 09:19:12 -07:00
Christian Hesse
69f445fd09 update rsync systemd unit, add more security features 2020-06-17 09:19:12 -07:00
Wayne Davison
643b9d0183 Change SIMD back to disabled unless requested. 2020-06-16 23:00:01 -07:00
Wayne Davison
2c681b874e Some fixes after compiling on cygwin. 2020-06-16 22:58:24 -07:00
Wayne Davison
e44e79cedb Update config.guess & config.sub. 2020-06-16 21:24:23 -07:00
Wayne Davison
beaf19c3e7 Have --disable-md2man affect the Makefile. 2020-06-16 19:05:05 -07:00
Wayne Davison
0b2a394cbc Fix /usr/bin/env with script args. 2020-06-16 18:32:16 -07:00
Wayne Davison
27e88dec04 Use /usr/bin/env for increased portability. 2020-06-16 18:27:48 -07:00
Wayne Davison
929f136b3b A few more NEWS tweaks. 2020-06-16 15:48:23 -07:00
benrubson
6a22f4fee1 enh(configure) Promote OpenSSL crypto lib support 2020-06-16 15:05:36 -07:00
Wayne Davison
d90990d6ac A few more trivial tweaks. 2020-06-16 14:42:41 -07:00
Wayne Davison
111225a996 Fix md2man --test on a fresh checkout. 2020-06-16 14:03:16 -07:00
Wayne Davison
7dfcbf7df6 Add g++ failure info; add mention of SSL rsyncd examples. 2020-06-16 12:10:56 -07:00
Wayne Davison
38ecf188d9 Only complain about lack of g++ on linux for now. 2020-06-16 11:35:54 -07:00
Wayne Davison
29be5eddde Add configure check for md2man functioning; split long error lines. 2020-06-16 11:13:45 -07:00
Wayne Davison
54b1ddc45d Change configure to make new features more likely to get included in a build. 2020-06-16 09:59:00 -07:00
Wayne Davison
8cd9aa326c Fix bug in CXXFLAGS tweak. 2020-06-16 09:14:28 -07:00
Wayne Davison
cd50745e1c Remove the new $< use from the Makefile. 2020-06-16 08:46:44 -07:00
Wayne Davison
ae94e3db4b Tweak my email. 2020-06-16 07:55:42 -07:00
Wayne Davison
6efaa74dd3 More spelling fixes from Fossies
https://fossies.org/linux/test/rsync-master.tar.gz/codespell.html
2020-06-16 07:46:28 -07:00
Wayne Davison
5496eda5d1 Turn help-from-md into an awk script. 2020-06-15 18:32:00 -07:00
Wayne Davison
353dec1102 Avoid -e option to sed for BSD. 2020-06-15 15:08:42 -07:00
Wayne Davison
d80da9e674 A few small tweaks. 2020-06-15 15:04:08 -07:00
Wayne Davison
6f0c56304f Preparing for release of 3.2.0pre2 2020-06-15 11:53:19 -07:00
Wayne Davison
2452ad3663 Fixed setting of rsync_lastver var. 2020-06-15 11:52:54 -07:00
Wayne Davison
1fa38546a0 Document how to setup rsyncd behind a TLS proxy. 2020-06-15 11:36:24 -07:00
Wayne Davison
249e28c75a Rename "haproxy header" to "proxy protocol". 2020-06-15 11:33:23 -07:00
Wayne Davison
6273153c5f Add preliminary gnutls support. 2020-06-15 11:19:36 -07:00
Wayne Davison
628dcceb8d Choose openssl before stunnel. 2020-06-15 10:41:08 -07:00
Wayne Davison
00ec415a69 Tweak the stunnel4 Verify config; tweak the rsync-ssl docs/usage. 2020-06-15 09:36:13 -07:00
Wayne Davison
ec8035cef9 A minor NEWS tweak. 2020-06-15 09:21:26 -07:00
Wayne Davison
775f64f4b8 Add a warning header to the generated help-*.h files. 2020-06-14 18:49:38 -07:00
Wayne Davison
660274bfb7 A few more md -> html improvements 2020-06-14 18:28:30 -07:00
Wayne Davison
59cf9ff797 More NEWS improvements. 2020-06-14 18:00:18 -07:00
Wayne Davison
ff272503b0 Output who_am_i() info in all rsyserr() messages. 2020-06-14 15:54:42 -07:00
Wayne Davison
43a939e3f2 Improve some md files. 2020-06-14 15:29:45 -07:00
Wayne Davison
b65b6db304 Add handling of non-breaking space & double-dash. 2020-06-14 15:29:45 -07:00
Wayne Davison
7b1f8f57c3 Update rrsync & its opt-culling script. 2020-06-13 22:11:37 -07:00
Wayne Davison
c32012d199 Need to indent a code block in the README. 2020-06-13 21:31:26 -07:00
Wayne Davison
9ba6ce1b67 More release improvements. 2020-06-13 21:21:26 -07:00
Wayne Davison
ca9e247762 Mention renamed .md files. 2020-06-13 20:42:33 -07:00
Wayne Davison
f27a630e46 Don't use c++ comments. 2020-06-13 20:12:15 -07:00
Wayne Davison
243a9d9be0 A few more release script fixes. 2020-06-13 20:11:06 -07:00
130 changed files with 11140 additions and 8593 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: C CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: prepare-packages
run: sudo apt-get install fakeroot acl libacl1-dev attr libattr1-dev liblz4-dev libzstd-dev libxxhash-dev python3-cmarkgfm
- name: prepare-source
run: ./prepare-source
- name: configure
run: ./configure --with-included-popt --with-protected-args --with-included-zlib --enable-simd
- 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

9
.gitignore vendored
View File

@@ -19,6 +19,9 @@ aclocal.m4
/rsync*.5
/rsync*.html
/help-rsync*.h
/default-cvsignore.h
/default-dont-compress.h
/daemon-parm.h
/.md2man-works
/autom4te*.cache
/confdefs.h
@@ -29,6 +32,7 @@ aclocal.m4
/rsync
/stunnel-rsyncd.conf
/shconfig
/git-version.h
/testdir
/tests-dont-exist
/testtmp
@@ -46,5 +50,8 @@ aclocal.m4
/testsuite/devices-fake.test
/testsuite/xattrs-hlink.test
/patches
/SaVeDiR
/patches.gen
/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

@@ -1,5 +1,4 @@
# Makefile for rsync. This is processed by configure to produce the final
# Makefile
# The Makefile for rsync (configure creates it from Makefile.in).
prefix=@prefix@
datarootdir=@datarootdir@
@@ -10,6 +9,7 @@ mandir=@mandir@
LIBS=@LIBS@
CC=@CC@
AWK=@AWK@
CFLAGS=@CFLAGS@
CPPFLAGS=@CPPFLAGS@
CXX=@CXX@
@@ -26,17 +26,16 @@ MKDIR_P=@MKDIR_P@
VPATH=$(srcdir)
SHELL=/bin/sh
VERSION=@RSYNC_VERSION@
.SUFFIXES:
.SUFFIXES: .c .o
SIMD_x86_64=simd-checksum-x86_64.o lib/md5-asm-x86_64.o
SIMD_x86_64=simd-checksum-x86_64.o
ASM_x86_64=lib/md5-asm-x86_64.o
GENFILES=configure.sh aclocal.m4 config.h.in proto.h proto.h-tstamp rsync.1 rsync.1.html \
GENFILES=configure.sh aclocal.m4 config.h.in rsync.1 rsync.1.html \
rsync-ssl.1 rsync-ssl.1.html rsyncd.conf.5 rsyncd.conf.5.html
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h itypes.h inums.h \
lib/pool_alloc.h
lib/pool_alloc.h lib/mdigest.h lib/md-defines.h version.h
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o lib/md5.o \
lib/permstring.o lib/pool_alloc.o lib/sysacls.o lib/sysxattrs.o @LIBOBJS@
zlib_OBJS=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
@@ -44,8 +43,8 @@ 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
OBJS3=progress.o pipe.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 \
popt/popthelp.o popt/poptparse.o
@@ -68,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@
all: Makefile rsync$(EXEEXT) stunnel-rsyncd.conf @MAKE_MAN@
.PHONY: all
all: Makefile rsync$(EXEEXT) stunnel-rsyncd.conf man
.PHONY: install
install: all
-${MKDIR_P} ${DESTDIR}${bindir}
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
${INSTALLCMD} -m 755 rsync-ssl ${DESTDIR}${bindir}
-${MKDIR_P} ${DESTDIR}${mandir}/man1
-${MKDIR_P} ${DESTDIR}${mandir}/man5
if test -f rsync.1; then ${INSTALLMAN} -m 644 rsync.1 ${DESTDIR}${mandir}/man1; fi
if test -f rsync-ssl.1; then ${INSTALLMAN} -m 644 rsync-ssl.1 ${DESTDIR}${mandir}/man1; fi
if test -f rsyncd.conf.5; then ${INSTALLMAN} -m 644 rsyncd.conf.5 ${DESTDIR}${mandir}/man5; fi
-$(MKDIR_P) $(DESTDIR)$(bindir)
$(INSTALLCMD) $(INSTALL_STRIP) -m 755 rsync$(EXEEXT) $(DESTDIR)$(bindir)
$(INSTALLCMD) -m 755 $(srcdir)/rsync-ssl $(DESTDIR)$(bindir)
-$(MKDIR_P) $(DESTDIR)$(mandir)/man1
-$(MKDIR_P) $(DESTDIR)$(mandir)/man5
if test -f rsync.1; then $(INSTALLMAN) -m 644 rsync.1 $(DESTDIR)$(mandir)/man1; fi
if test -f rsync-ssl.1; then $(INSTALLMAN) -m 644 rsync-ssl.1 $(DESTDIR)$(mandir)/man1; fi
if test -f rsyncd.conf.5; then $(INSTALLMAN) -m 644 rsyncd.conf.5 $(DESTDIR)$(mandir)/man5; fi
install-ssl-daemon: stunnel-rsyncd.conf
-${MKDIR_P} ${DESTDIR}/etc/stunnel
${INSTALLCMD} -m 644 stunnel-rsyncd.conf ${DESTDIR}/etc/stunnel/rsyncd.conf
-$(MKDIR_P) $(DESTDIR)/etc/stunnel
$(INSTALLCMD) -m 644 stunnel-rsyncd.conf $(DESTDIR)/etc/stunnel/rsyncd.conf
@if ! ls /etc/rsync-ssl/certs/server.* >/dev/null 2>/dev/null; then \
echo "Note that you'll need to install the certificate used by /etc/stunnel/rsyncd.conf"; \
fi
install-all: install install-ssl-client install-ssl-daemon
install-all: install install-ssl-daemon
install-strip:
$(MAKE) INSTALL_STRIP='-s' install
@@ -99,19 +98,20 @@ rsync$(EXEEXT): $(OBJS)
$(OBJS): $(HEADERS)
$(CHECK_OBJS): $(HEADERS)
options.o: latest-year.h help-rsync.h help-rsyncd.h
tls.o xattrs.o: lib/sysxattrs.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
help-rsync.h help-rsyncd.h: rsync.1.md
@sed -e '1,/^\[comment\].*$@/d' \
-e '1,/^```/d' \
-e '/^```/,$$d' \
-e 's/"/\\"/g' \
-e 's/^/ rprintf(F,"/' \
-e 's/$$/\\n");/' \
<"$(srcdir)/$<" >$@
@if ! test -s $@; then rm -f $@ ; echo "The Makefile generated an empty file: $@" ; exit 1 ; fi
default-cvsignore.h default-dont-compress.h: rsync.1.md define-from-md.awk
$(AWK) -f $(srcdir)/define-from-md.awk -v hfile=$@ $(srcdir)/rsync.1.md
help-rsync.h help-rsyncd.h: rsync.1.md help-from-md.awk
$(AWK) -f $(srcdir)/help-from-md.awk -v hfile=$@ $(srcdir)/rsync.1.md
daemon-parm.h: daemon-parm.txt daemon-parm.awk
$(AWK) -f $(srcdir)/daemon-parm.awk $(srcdir)/daemon-parm.txt
rounding.h: rounding.c rsync.h proto.h
@for r in 0 1 3; do \
@@ -131,11 +131,17 @@ rounding.h: rounding.c rsync.h proto.h
fi
@rm -f rounding.out
simd-checksum-x86_64.o: simd-checksum-x86_64.cpp
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
# 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
lib/md5-asm-x86_64.o: lib/md5-asm-x86_64.s
$(CC) -c -o $@ $<
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
lib/md5-asm-x86_64.o: lib/md5-asm-x86_64.S config.h lib/md-defines.h
@$(srcdir)/cmdormsg disable-asm $(CC) -I. @NOEXECSTACK@ -c -o $@ $(srcdir)/lib/md5-asm-x86_64.S
tls$(EXEEXT): $(TLS_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
@@ -202,6 +208,10 @@ reconfigure: configure.sh
./config.status --recheck
./config.status
.PHONY: restatus
restatus:
./config.status
Makefile: Makefile.in config.status configure.sh config.h.in
@if test -f Makefile; then cp -p Makefile Makefile.old; else touch Makefile.old; fi
@./config.status
@@ -226,25 +236,26 @@ proto: proto.h-tstamp
proto.h: proto.h-tstamp
@if test -f proto.h; then :; else cp -p $(srcdir)/proto.h .; fi
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c config.h
awk -f $(srcdir)/mkproto.awk $(srcdir)/*.c $(srcdir)/lib/compat.c
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c daemon-parm.h
$(AWK) -f $(srcdir)/mkproto.awk $(srcdir)/*.c $(srcdir)/lib/compat.c daemon-parm.h
.PHONY: man
man: rsync.1 rsync-ssl.1 rsyncd.conf.5
rsync.1: rsync.1.md md2man NEWS.md Makefile
rsync.1: rsync.1.md md2man version.h Makefile
@$(srcdir)/maybe-make-man $(srcdir) rsync.1.md
rsync-ssl.1: rsync-ssl.1.md md2man NEWS.md Makefile
rsync-ssl.1: rsync-ssl.1.md md2man version.h Makefile
@$(srcdir)/maybe-make-man $(srcdir) rsync-ssl.1.md
rsyncd.conf.5: rsyncd.conf.5.md md2man NEWS.md Makefile
rsyncd.conf.5: rsyncd.conf.5.md md2man version.h Makefile
@$(srcdir)/maybe-make-man $(srcdir) rsyncd.conf.5.md
.PHONY: clean
clean: cleantests
rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) \
rounding rounding.h *.old rsync*.1 rsync*.5 rsync*.html
rounding rounding.h *.old rsync*.1 rsync*.5 rsync*.html \
daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
.PHONY: cleantests
cleantests:
@@ -255,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
@@ -274,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

4242
NEWS.md
View File

File diff suppressed because it is too large Load Diff

3863
OLDNEWS.md
View File

File diff suppressed because it is too large Load Diff

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].
> http://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.
> http://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.
> http://rsync.samba.org/bugzilla.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].
> http://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,42 +117,27 @@ 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
or clone it from its samba repo:
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:
> http://rsync.samba.org/download.html
[8]: https://rsync.samba.org/download.html
COPYRIGHT
---------
Rsync was originally written by Andrew Tridgell and is currently
maintained by Wayne Davison. It has been improved by many developers
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].
> http://www.fsf.org/licenses/gpl.html
AVAILABILITY
------------
The main web site for rsync is http://rsync.samba.org/
The main ftp site is ftp://rsync.samba.org/pub/rsync/
This is also available as rsync://download.samba.org/rsyncftp/ if you
connect via ssl. Use the `rsync-ssl` script if you have it, otherwise
connect to the rsync server via a normal rsync command and it will
output some instructions for how to connect.
[9]: https://github.com/WayneD/rsync/blob/master/COPYING
[10]: https://www.fsf.org/licenses/gpl.html

12
TODO
View File

@@ -49,7 +49,7 @@ Create test makefile target for some tests
RELATED PROJECTS -----------------------------------------------------
rsyncsh
http://rsync.samba.org/rsync-and-debian/
https://rsync.samba.org/rsync-and-debian/
rsyncable gzip patch
rsyncsplit as alternative to real integration with gzip?
reverse rsync over HTTP Range
@@ -66,8 +66,8 @@ Use chroot only if supported
If running as non-root, then don't fail, just give a warning.
(There was a thread about this a while ago?)
http://lists.samba.org/pipermail/rsync/2001-August/thread.html
http://lists.samba.org/pipermail/rsync/2001-September/thread.html
https://lists.samba.org/pipermail/rsync/2001-August/thread.html
https://lists.samba.org/pipermail/rsync/2001-September/thread.html
-- --
@@ -204,7 +204,7 @@ Create more granular verbosity 2003/05/15
fine grained selection of statistical reporting and what
actions are logged.
http://lists.samba.org/archive/rsync/2003-May/006059.html
https://lists.samba.org/archive/rsync/2003-May/006059.html
-- --
@@ -287,7 +287,7 @@ Perhaps flush stdout like syslog
Perhaps flush stdout after each filename, so that people trying to
monitor progress in a log file can do so more easily. See
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
-- --
@@ -495,7 +495,7 @@ rsyncsh
-- --
http://rsync.samba.org/rsync-and-debian/
https://rsync.samba.org/rsync-and-debian/
-- --

View File

@@ -19,6 +19,7 @@
*/
#include "rsync.h"
#include "ifuncs.h"
static int allow_forward_dns;
@@ -33,6 +34,11 @@ static int match_hostname(const char **host_ptr, const char *addr, const char *t
if (!host || !*host)
return 0;
#ifdef HAVE_INNETGR
if (*tok == '@' && tok[1])
return innetgr(tok + 1, host, NULL, NULL);
#endif
/* First check if the reverse-DNS-determined hostname matches. */
if (iwildmatch(tok, host))
return 1;
@@ -52,10 +58,8 @@ static int match_hostname(const char **host_ptr, const char *addr, const char *t
if (strcmp(addr, inet_ntoa(*(struct in_addr*)(hp->h_addr_list[i]))) == 0) {
/* If reverse lookups are off, we'll use the conf-specified
* hostname in preference to UNDETERMINED. */
if (host == undetermined_hostname) {
if (!(*host_ptr = strdup(tok)))
*host_ptr = undetermined_hostname;
}
if (host == undetermined_hostname)
*host_ptr = strdup(tok);
return 1;
}
}
@@ -241,9 +245,6 @@ static int access_match(const char *list, const char *addr, const char **host_pt
char *tok;
char *list2 = strdup(list);
if (!list2)
out_of_memory("access_match");
strlower(list2);
for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {

16
acls.c
View File

@@ -168,8 +168,6 @@ static rsync_acl *create_racl(void)
{
rsync_acl *racl = new(rsync_acl);
if (!racl)
out_of_memory("create_racl");
*racl = empty_rsync_acl;
return racl;
@@ -335,8 +333,7 @@ static BOOL unpack_smb_acl(SMB_ACL_T sacl, rsync_acl *racl)
qsort(temp_ida_list.items, temp_ida_list.count, sizeof (id_access), id_access_sorter);
}
#endif
if (!(racl->names.idas = new_array(id_access, temp_ida_list.count)))
out_of_memory("unpack_smb_acl");
racl->names.idas = new_array(id_access, temp_ida_list.count);
memcpy(racl->names.idas, temp_ida_list.items, temp_ida_list.count * sizeof (id_access));
} else
racl->names.idas = NULL;
@@ -505,9 +502,7 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl,
if (cnt) {
char *bp = buf + 4*4;
id_access *ida;
if (!(ida = racl->names.idas = new_array(id_access, cnt)))
out_of_memory("get_rsync_acl");
id_access *ida = racl->names.idas = new_array(id_access, cnt);
racl->names.count = cnt;
for ( ; cnt--; ida++, bp += 4+4) {
ida->id = IVAL(bp, 0);
@@ -703,12 +698,7 @@ static uchar recv_ida_entries(int f, ida_entries *ent)
uchar computed_mask_bits = 0;
int i, count = read_varint(f);
if (count) {
if (!(ent->idas = new_array(id_access, count)))
out_of_memory("recv_ida_entries");
} else
ent->idas = NULL;
ent->idas = count ? new_array(id_access, count) : NULL;
ent->count = count;
for (i = 0; i < count; i++) {

View File

@@ -20,6 +20,7 @@
#include "rsync.h"
#include "itypes.h"
#include "ifuncs.h"
extern int read_only;
extern char *password_file;
@@ -118,7 +119,7 @@ static const char *check_secret(int module, const char *user, const char *group,
if ((st.st_mode & 06) != 0) {
rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
ok = 0;
} else if (MY_UID() == 0 && st.st_uid != 0) {
} else if (MY_UID() == ROOT_UID && st.st_uid != ROOT_UID) {
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
ok = 0;
}
@@ -195,7 +196,7 @@ static const char *getpassf(const char *filename)
rprintf(FERROR, "ERROR: password file must not be other-accessible\n");
exit_cleanup(RERR_SYNTAX);
}
if (MY_UID() == 0 && st.st_uid != 0) {
if (MY_UID() == ROOT_UID && st.st_uid != ROOT_UID) {
rprintf(FERROR, "ERROR: password file must be owned by root when running as root\n");
exit_cleanup(RERR_SYNTAX);
}
@@ -226,7 +227,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
char *users = lp_auth_users(module);
char challenge[MAX_DIGEST_LEN*2];
char line[BIGPATHBUFLEN];
char **auth_uid_groups = NULL;
const char **auth_uid_groups = NULL;
int auth_uid_groups_cnt = -1;
const char *err = NULL;
int group_match = -1;
@@ -250,8 +251,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
}
*pass++ = '\0';
if (!(users = strdup(users)))
out_of_memory("auth_server");
users = strdup(users);
for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
char *opts;
@@ -287,8 +287,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
else {
gid_t *gid_array = gid_list.items;
auth_uid_groups_cnt = gid_list.count;
if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
out_of_memory("auth_server");
auth_uid_groups = new_array(const char *, auth_uid_groups_cnt);
for (j = 0; j < auth_uid_groups_cnt; j++)
auth_uid_groups[j] = gid_to_group(gid_array[j]);
}
@@ -314,7 +313,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
else if (opt_ch == 'd')
err = "denied by rule";
else {
char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
const char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
err = check_secret(module, line, group, challenge, pass);
}
@@ -325,7 +324,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
int j;
for (j = 0; j < auth_uid_groups_cnt; j++) {
if (auth_uid_groups[j])
free(auth_uid_groups[j]);
free((char*)auth_uid_groups[j]);
}
free(auth_uid_groups);
}

11
batch.c
View File

@@ -38,13 +38,10 @@ extern int do_compression;
extern int inplace;
extern int append_mode;
extern int write_batch;
extern int xfersum_type;
extern int protocol_version;
extern int raw_argc, cooked_argc;
extern char **raw_argv, **cooked_argv;
extern char *batch_name;
extern const char *checksum_choice;
extern const char *compress_choice;
#ifdef ICONV_OPTION
extern char *iconv_opt;
#endif
@@ -269,14 +266,6 @@ void write_batch_shell_file(void)
err |= write_opt("--exclude-from", "-");
}
/* We need to make sure that any protocol-based or negotiated choices get accurately
* reflected in the options we save AND that we avoid any need for --read-batch to
* do a string-based negotation (since we don't write them into the file). */
if (do_compression)
err |= write_opt("--compress-choice", compress_choice);
if (strchr(checksum_choice, ',') || xfersum_type != parse_csum_name(NULL, -1))
err |= write_opt("--checksum-choice", checksum_choice);
/* Elide the filename args from the option list, but scan for them in reverse. */
for (i = raw_argc-1, j = cooked_argc-1; i > 0 && j >= 0; i--) {
if (strcmp(raw_argv[i], cooked_argv[j]) == 0) {

View File

@@ -27,8 +27,12 @@
*/
#include "rsync.h"
#ifdef SUPPORT_XXHASH
#include "xxhash.h"
#include <xxhash.h>
# if XXH_VERSION_NUMBER >= 800
# define SUPPORT_XXH3 1
# endif
#endif
extern int am_server;
@@ -40,6 +44,10 @@ extern const char *checksum_choice;
struct name_num_obj valid_checksums = {
"checksum", NULL, NULL, 0, 0, {
#ifdef SUPPORT_XXH3
{ CSUM_XXH3_128, "xxh128", NULL },
{ CSUM_XXH3_64, "xxh3", NULL },
#endif
#ifdef SUPPORT_XXHASH
{ CSUM_XXH64, "xxh64", NULL },
{ CSUM_XXH64, "xxhash", NULL },
@@ -85,7 +93,7 @@ static const char *checksum_name(int num)
{
struct name_num_item *nni = get_nni_by_num(&valid_checksums, num);
return nni ? nni->name : num < CSUM_MD4 ? "MD4" : "UNKNOWN";
return nni ? nni->name : num < CSUM_MD4 ? "md4" : "UNKNOWN";
}
void parse_checksum_choice(int final_call)
@@ -99,6 +107,8 @@ void parse_checksum_choice(int final_call)
checksum_type = parse_csum_name(cp+1, -1);
} else
xfersum_type = checksum_type = parse_csum_name(checksum_choice, -1);
if (am_server && checksum_choice)
validate_choice_vs_env(NSTR_CHECKSUM, xfersum_type, checksum_type);
}
if (xfersum_type == CSUM_NONE)
@@ -133,10 +143,11 @@ int csum_len_for_type(int cst, BOOL flist_csum)
return MD4_DIGEST_LEN;
case CSUM_MD5:
return MD5_DIGEST_LEN;
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
case CSUM_XXH3_64:
return 64/8;
#endif
case CSUM_XXH3_128:
return 128/8;
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
@@ -158,10 +169,10 @@ int canonical_checksum(int csum_type)
case CSUM_MD4:
case CSUM_MD5:
return -1;
#ifdef SUPPORT_XXHASH
case CSUM_XXH64:
case CSUM_XXH3_64:
case CSUM_XXH3_128:
return 1;
#endif
default: /* paranoia to prevent missing case values */
exit_cleanup(RERR_UNSUPPORTED);
}
@@ -198,6 +209,17 @@ void get_checksum2(char *buf, int32 len, char *sum)
case CSUM_XXH64:
SIVAL64(sum, 0, XXH64(buf, len, checksum_seed));
break;
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64:
SIVAL64(sum, 0, XXH3_64bits_withSeed(buf, len, checksum_seed));
break;
case CSUM_XXH3_128: {
XXH128_hash_t digest = XXH3_128bits_withSeed(buf, len, checksum_seed);
SIVAL64(sum, 0, digest.low64);
SIVAL64(sum, 8, digest.high64);
break;
}
#endif
case CSUM_MD5: {
MD5_CTX m5;
@@ -249,8 +271,6 @@ void get_checksum2(char *buf, int32 len, char *sum)
free(buf1);
buf1 = new_array(char, len+4);
len1 = len;
if (!buf1)
out_of_memory("get_checksum2");
}
memcpy(buf1, buf, len);
@@ -313,6 +333,45 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
SIVAL64(sum, 0, XXH64_digest(state));
break;
}
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64: {
static XXH3_state_t* state = NULL;
if (!state && !(state = XXH3_createState()))
out_of_memory("file_checksum");
XXH3_64bits_reset(state);
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
XXH3_64bits_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
remainder = (int32)(len - i);
if (remainder > 0)
XXH3_64bits_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
SIVAL64(sum, 0, XXH3_64bits_digest(state));
break;
}
case CSUM_XXH3_128: {
XXH128_hash_t digest;
static XXH3_state_t* state = NULL;
if (!state && !(state = XXH3_createState()))
out_of_memory("file_checksum");
XXH3_128bits_reset(state);
for (i = 0; i + CHUNK_SIZE <= len; i += CHUNK_SIZE)
XXH3_128bits_update(state, (uchar *)map_ptr(buf, i, CHUNK_SIZE), CHUNK_SIZE);
remainder = (int32)(len - i);
if (remainder > 0)
XXH3_128bits_update(state, (uchar *)map_ptr(buf, i, remainder), remainder);
digest = XXH3_128bits_digest(state);
SIVAL64(sum, 0, digest.low64);
SIVAL64(sum, 8, digest.high64);
break;
}
#endif
case CSUM_MD5: {
MD5_CTX m5;
@@ -389,6 +448,9 @@ static union {
#ifdef SUPPORT_XXHASH
static XXH64_state_t* xxh64_state;
#endif
#ifdef SUPPORT_XXH3
static XXH3_state_t* xxh3_state;
#endif
static int cursum_type;
void sum_init(int csum_type, int seed)
@@ -406,6 +468,18 @@ void sum_init(int csum_type, int seed)
out_of_memory("sum_init");
XXH64_reset(xxh64_state, 0);
break;
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64:
if (!xxh3_state && !(xxh3_state = XXH3_createState()))
out_of_memory("sum_init");
XXH3_64bits_reset(xxh3_state);
break;
case CSUM_XXH3_128:
if (!xxh3_state && !(xxh3_state = XXH3_createState()))
out_of_memory("sum_init");
XXH3_128bits_reset(xxh3_state);
break;
#endif
case CSUM_MD5:
MD5_Init(&ctx.m5);
@@ -448,6 +522,14 @@ void sum_update(const char *p, int32 len)
case CSUM_XXH64:
XXH64_update(xxh64_state, p, len);
break;
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64:
XXH3_64bits_update(xxh3_state, p, len);
break;
case CSUM_XXH3_128:
XXH3_128bits_update(xxh3_state, p, len);
break;
#endif
case CSUM_MD5:
MD5_Update(&ctx.m5, (uchar *)p, len);
@@ -502,6 +584,17 @@ int sum_end(char *sum)
case CSUM_XXH64:
SIVAL64(sum, 0, XXH64_digest(xxh64_state));
break;
#endif
#ifdef SUPPORT_XXH3
case CSUM_XXH3_64:
SIVAL64(sum, 0, XXH3_64bits_digest(xxh3_state));
break;
case CSUM_XXH3_128: {
XXH128_hash_t digest = XXH3_128bits_digest(xxh3_state);
SIVAL64(sum, 0, digest.low64);
SIVAL64(sum, 8, digest.high64);
break;
}
#endif
case CSUM_MD5:
MD5_Final((uchar *)sum, &ctx.m5);

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"
@@ -221,8 +221,9 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
/* If line < 0, this exit is after a MSG_ERROR_EXIT event, so
* we don't want to output a duplicate error. */
if ((exit_code && line > 0)
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1))))
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1)))) {
log_exit(exit_code, exit_file, exit_line);
}
#include "case_N.h"
switch_step++;

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,8 +156,8 @@ char *client_name(const char *ipaddr)
}
/* Try to read an haproxy header (V1 or V2). Returns 1 on success or 0 on failure. */
int read_haproxy_header(int fd)
/* 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 {
struct {
@@ -388,7 +388,7 @@ static int compare_addrinfo_sockaddr(const struct addrinfo *ai, const struct soc
sin1 = (const struct sockaddr_in6 *) ss;
sin2 = (const struct sockaddr_in6 *) ai->ai_addr;
if (ai->ai_addrlen < sizeof (struct sockaddr_in6)) {
if (ai->ai_addrlen < (int)sizeof (struct sockaddr_in6)) {
rprintf(FLOG, "%s: too short sockaddr_in6; length=%d\n",
fn, (int)ai->ai_addrlen);
return 1;
@@ -481,7 +481,7 @@ static int valid_ipaddr(const char *s)
for (count = 0; count < 8; count++) {
if (!*s)
return saw_double_colon && count < 7;
return saw_double_colon;
if (strchr(s, ':') == NULL && strchr(s, '.') != NULL) {
if ((!saw_double_colon && count != 6) || (saw_double_colon && count > 6))

View File

@@ -21,6 +21,7 @@
#include "rsync.h"
#include "itypes.h"
#include "ifuncs.h"
extern int quiet;
extern int dry_run;
@@ -36,8 +37,8 @@ extern int protect_args;
extern int ignore_errors;
extern int preserve_xattrs;
extern int kluge_around_eof;
extern int daemon_over_rsh;
extern int munge_symlinks;
extern int open_noatime;
extern int sanitize_paths;
extern int numeric_ids;
extern int filesfrom_fd;
@@ -54,6 +55,7 @@ extern char *config_file;
extern char *logfile_format;
extern char *files_from;
extern char *tmpdir;
extern char *early_input_file;
extern struct chmod_mode_struct *chmod_modes;
extern filter_rule_list daemon_filter_list;
#ifdef ICONV_OPTION
@@ -67,8 +69,14 @@ char *auth_user;
int read_only = 0;
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="
#define EARLY_INPUT_CMDLEN (sizeof EARLY_INPUT_CMD - 1)
/* module_dirlen is the length of the module_dir string when in daemon
* mode and module_dir is not "/"; otherwise 0. (Note that a chroot-
* enabled module can have a non-"/" module_dir these days.) */
@@ -78,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;
@@ -144,14 +153,12 @@ static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int
#else
int our_sub = 0;
#endif
char *motd;
io_printf(f_out, "@RSYNCD: %d.%d\n", protocol_version, our_sub);
if (!am_client) {
motd = lp_motd_file();
char *motd = lp_motd_file();
if (motd && *motd) {
FILE *f = fopen(motd,"r");
FILE *f = fopen(motd, "r");
while (f && !feof(f)) {
int len = fread(buf, 1, bufsiz - 1, f);
if (len > 0)
@@ -231,8 +238,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
else
modlen = p - *argv;
if (!(modname = new_array(char, modlen+1+1))) /* room for '/' & '\0' */
out_of_memory("start_inband_exchange");
modname = new_array(char, modlen+1+1); /* room for '/' & '\0' */
strlcpy(modname, *argv, modlen + 1);
modname[modlen] = '/';
modname[modlen+1] = '\0';
@@ -245,10 +251,36 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
if (exchange_protocols(f_in, f_out, line, sizeof line, 1) < 0)
return -1;
/* 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;
if (early_input_file) {
STRUCT_STAT st;
FILE *f = fopen(early_input_file, "rb");
if (!f || do_fstat(fileno(f), &st) < 0) {
rsyserr(FERROR, errno, "failed to open %s", early_input_file);
return -1;
}
early_input_len = st.st_size;
if (early_input_len > (int)sizeof line) {
rprintf(FERROR, "%s is > %d bytes.\n", early_input_file, (int)sizeof line);
return -1;
}
if (early_input_len > 0) {
io_printf(f_out, EARLY_INPUT_CMD "%d\n", early_input_len);
while (early_input_len > 0) {
int len;
if (feof(f)) {
rprintf(FERROR, "Early EOF in %s\n", early_input_file);
return -1;
}
len = fread(line, 1, early_input_len, f);
if (len > 0) {
write_buf(f_out, line, len);
early_input_len -= len;
}
}
}
fclose(f);
}
server_options(sargs, &sargc);
if (sargc >= MAX_ARGS - 2)
@@ -391,13 +423,13 @@ 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, error_fd;
int arg_fds[2], error_fds[2], arg_fd;
pid_t pid;
if ((error_fd_ptr && pipe(error_fds) < 0) || (arg_fd_ptr && pipe(arg_fds) < 0) || (pid = fork()) < 0)
if ((error_fd_ptr && pipe(error_fds) < 0) || pipe(arg_fds) < 0 || (pid = fork()) < 0)
return (pid_t)-1;
if (pid == 0) {
@@ -406,38 +438,36 @@ static pid_t start_pre_exec(const char *cmd, int *arg_fd_ptr, int *error_fd_ptr)
if (error_fd_ptr) {
close(error_fds[0]);
error_fd = error_fds[1];
set_blocking(error_fd);
set_blocking(error_fds[1]);
}
if (arg_fd_ptr) {
close(arg_fds[1]);
arg_fd = arg_fds[0];
set_blocking(arg_fd);
close(arg_fds[1]);
arg_fd = arg_fds[0];
set_blocking(arg_fd);
len = read_arg_from_pipe(arg_fd, buf, BIGPATHBUFLEN);
if (len <= 0)
_exit(1);
set_env_str("RSYNC_REQUEST", buf);
for (j = 0; ; j++) {
char *p;
len = read_arg_from_pipe(arg_fd, buf, BIGPATHBUFLEN);
if (len <= 0)
if (len <= 0) {
if (!len)
break;
_exit(1);
set_env_str("RSYNC_REQUEST", buf);
for (j = 0; ; j++) {
char *p;
len = read_arg_from_pipe(arg_fd, buf, BIGPATHBUFLEN);
if (len <= 0) {
if (!len)
break;
_exit(1);
}
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) >= 0)
putenv(p);
}
close(arg_fd);
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) >= 0)
putenv(p);
}
dup2(arg_fd, STDIN_FILENO);
close(arg_fd);
if (error_fd_ptr) {
close(STDIN_FILENO);
dup2(error_fd, STDOUT_FILENO);
close(error_fd);
dup2(error_fds[1], STDOUT_FILENO);
close(error_fds[1]);
}
status = shell_exec(cmd);
@@ -449,20 +479,18 @@ static pid_t start_pre_exec(const char *cmd, int *arg_fd_ptr, int *error_fd_ptr)
if (error_fd_ptr) {
close(error_fds[1]);
error_fd = *error_fd_ptr = error_fds[0];
set_blocking(error_fd);
*error_fd_ptr = error_fds[0];
set_blocking(error_fds[0]);
}
if (arg_fd_ptr) {
close(arg_fds[0]);
arg_fd = *arg_fd_ptr = arg_fds[1];
set_blocking(arg_fd);
}
close(arg_fds[0]);
arg_fd = *arg_fd_ptr = arg_fds[1];
set_blocking(arg_fd);
return pid;
}
static void write_pre_exec_args(int write_fd, char *request, char **early_argv, char **argv)
static void write_pre_exec_args(int write_fd, char *request, char **early_argv, char **argv, int exec_type)
{
int j = 0;
@@ -475,11 +503,17 @@ static void write_pre_exec_args(int write_fd, char *request, char **early_argv,
write_buf(write_fd, *early_argv, strlen(*early_argv)+1);
j = 1; /* Skip arg0 name in argv. */
}
for ( ; argv[j]; j++)
write_buf(write_fd, argv[j], strlen(argv[j])+1);
if (argv) {
for ( ; argv[j]; j++)
write_buf(write_fd, argv[j], strlen(argv[j])+1);
}
write_byte(write_fd, 0);
close(write_fd);
if (exec_type == 1 && early_input_len)
write_buf(write_fd, early_input, early_input_len);
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)
@@ -661,17 +695,17 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
module_id = i;
if (lp_transfer_logging(i) && !logfile_format)
logfile_format = lp_log_format(i);
if (lp_transfer_logging(module_id) && !logfile_format)
logfile_format = lp_log_format(module_id);
if (log_format_has(logfile_format, 'i'))
logfile_format_has_i = 1;
if (logfile_format_has_i || log_format_has(logfile_format, 'o'))
logfile_format_has_o_or_i = 1;
uid = MY_UID();
am_root = (uid == 0);
am_root = (uid == ROOT_UID);
p = *lp_uid(i) ? lp_uid(i) : am_root ? NOBODY_USER : NULL;
p = *lp_uid(module_id) ? lp_uid(module_id) : am_root ? NOBODY_USER : NULL;
if (p) {
if (!user_to_uid(p, &uid, True)) {
rprintf(FLOG, "Invalid uid %s\n", p);
@@ -682,7 +716,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
} else
set_uid = 0;
p = *lp_gid(i) ? conf_strtok(lp_gid(i)) : NULL;
p = *lp_gid(module_id) ? conf_strtok(lp_gid(module_id)) : NULL;
if (p) {
/* The "*" gid must be the first item in the list. */
if (strcmp(p, "*") == 0) {
@@ -715,7 +749,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
return -1;
}
module_dir = lp_path(i);
module_dir = lp_path(module_id);
if (*module_dir == '\0') {
rprintf(FLOG, "No path specified for module %s\n", name);
io_printf(f_out, "@ERROR: no path setting.\n");
@@ -752,38 +786,39 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
} else
set_filter_dir(module_dir, module_dirlen);
p = lp_filter(i);
p = lp_filter(module_id);
parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3);
p = lp_include_from(i);
p = lp_include_from(module_id);
parse_filter_file(&daemon_filter_list, p, rule_template(FILTRULE_INCLUDE),
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
p = lp_include(i);
p = lp_include(module_id);
parse_filter_str(&daemon_filter_list, p,
rule_template(FILTRULE_INCLUDE | FILTRULE_WORD_SPLIT),
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES);
p = lp_exclude_from(i);
p = lp_exclude_from(module_id);
parse_filter_file(&daemon_filter_list, p, rule_template(0),
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
p = lp_exclude(i);
p = lp_exclude(module_id);
parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES);
log_init(1);
#ifdef HAVE_PUTENV
if ((*lp_early_exec(i) || *lp_prexfer_exec(i) || *lp_postxfer_exec(i))
if ((*lp_early_exec(module_id) || *lp_prexfer_exec(module_id)
|| *lp_postxfer_exec(module_id) || *lp_name_converter(module_id))
&& !getenv("RSYNC_NO_XFER_EXEC")) {
set_env_num("RSYNC_PID", (long)getpid());
/* For post-xfer exec, fork a new process to run the rsync
* daemon while this process waits for the exit status and
* runs the indicated command at that point. */
if (*lp_postxfer_exec(i)) {
if (*lp_postxfer_exec(module_id)) {
pid_t pid = fork();
if (pid < 0) {
rsyserr(FLOG, errno, "fork failed");
@@ -803,7 +838,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
else
status = -1;
set_env_num("RSYNC_EXIT_STATUS", status);
if (shell_exec(lp_postxfer_exec(i)) < 0)
if (shell_exec(lp_postxfer_exec(module_id)) < 0)
status = -1;
_exit(status);
}
@@ -811,13 +846,15 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
/* For early exec, fork a child process to run the indicated
* command and wait for it to exit. */
if (*lp_early_exec(i)) {
pid_t pid = start_pre_exec(lp_early_exec(i), NULL, NULL);
if (*lp_early_exec(module_id)) {
int arg_fd;
pid_t pid = start_pre_exec(lp_early_exec(module_id), &arg_fd, NULL);
if (pid == (pid_t)-1) {
rsyserr(FLOG, errno, "early exec preparation failed");
io_printf(f_out, "@ERROR: early exec preparation failed\n");
return -1;
}
write_pre_exec_args(arg_fd, NULL, NULL, NULL, 1);
if (finish_pre_exec("early exec", pid, -1) != NULL) {
rsyserr(FLOG, errno, "early exec failed");
io_printf(f_out, "@ERROR: early exec failed\n");
@@ -828,17 +865,31 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
/* For pre-xfer exec, fork a child process to run the indicated
* command, though it first waits for the parent process to
* send us the user's request via a pipe. */
if (*lp_prexfer_exec(i)) {
pre_exec_pid = start_pre_exec(lp_prexfer_exec(i), &pre_exec_arg_fd, &pre_exec_error_fd);
if (*lp_prexfer_exec(module_id)) {
pre_exec_pid = start_pre_exec(lp_prexfer_exec(module_id), &pre_exec_arg_fd, &pre_exec_error_fd);
if (pre_exec_pid == (pid_t)-1) {
rsyserr(FLOG, errno, "pre-xfer exec preparation failed");
io_printf(f_out, "@ERROR: pre-xfer exec preparation failed\n");
return -1;
}
}
if (*lp_name_converter(module_id)) {
namecvt_pid = start_pre_exec(lp_name_converter(module_id), &namecvt_fd_req, &namecvt_fd_ans);
if (namecvt_pid == (pid_t)-1) {
rsyserr(FLOG, errno, "name-converter exec preparation failed");
io_printf(f_out, "@ERROR: name-converter exec preparation failed\n");
return -1;
}
}
}
#endif
if (early_input) {
free(early_input);
early_input = NULL;
}
if (use_chroot) {
/*
* XXX: The 'use chroot' flag is a fairly reliable
@@ -865,7 +916,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
if (module_dirlen || (!use_chroot && !*lp_daemon_chroot()))
sanitize_paths = 1;
if ((munge_symlinks = lp_munge_symlinks(i)) < 0)
if ((munge_symlinks = lp_munge_symlinks(module_id)) < 0)
munge_symlinks = !use_chroot || module_dirlen;
if (munge_symlinks) {
STRUCT_STAT st;
@@ -917,11 +968,11 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
}
our_uid = MY_UID();
am_root = (our_uid == 0);
am_root = (our_uid == ROOT_UID);
}
if (lp_temp_dir(i) && *lp_temp_dir(i)) {
tmpdir = lp_temp_dir(i);
if (lp_temp_dir(module_id) && *lp_temp_dir(module_id)) {
tmpdir = lp_temp_dir(module_id);
if (strlen(tmpdir) >= MAXPATHLEN - 10) {
rprintf(FLOG,
"the 'temp dir' value for %s is WAY too long -- ignoring.\n",
@@ -948,15 +999,23 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
} else
orig_early_argv = NULL;
/* The default is to use the user's setting unless the module sets True or False. */
if (lp_open_noatime(module_id) >= 0)
open_noatime = lp_open_noatime(module_id);
munge_symlinks = save_munge_symlinks; /* The client mustn't control this. */
if (am_daemon > 0)
msgs2stderr = 0; /* A non-rsh-run daemon doesn't have stderr for msgs. */
if (pre_exec_pid) {
write_pre_exec_args(pre_exec_arg_fd, request, orig_early_argv, orig_argv);
write_pre_exec_args(pre_exec_arg_fd, request, orig_early_argv, orig_argv, 0);
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);
@@ -967,7 +1026,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
if (write_batch < 0)
dry_run = 1;
if (lp_fake_super(i)) {
if (lp_fake_super(module_id)) {
if (preserve_xattrs > 1)
preserve_xattrs = 1;
am_root = -1;
@@ -992,7 +1051,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
#ifndef DEBUG
/* don't allow the logs to be flooded too fast */
limit_output_verbosity(lp_max_verbosity(i));
limit_output_verbosity(lp_max_verbosity(module_id));
#endif
if (protocol_version < 23 && (protocol_version == 22 || am_sender))
@@ -1053,20 +1112,21 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
#endif
if (!numeric_ids
&& (use_chroot ? lp_numeric_ids(i) != False : lp_numeric_ids(i) == True))
&& (use_chroot ? lp_numeric_ids(module_id) != False && !*lp_name_converter(module_id)
: lp_numeric_ids(module_id) == True))
numeric_ids = -1; /* Set --numeric-ids w/o breaking protocol. */
if (lp_timeout(i) && (!io_timeout || lp_timeout(i) < io_timeout))
set_io_timeout(lp_timeout(i));
if (lp_timeout(module_id) && (!io_timeout || lp_timeout(module_id) < io_timeout))
set_io_timeout(lp_timeout(module_id));
/* If we have some incoming/outgoing chmod changes, append them to
* any user-specified changes (making our changes have priority).
* We also get a pointer to just our changes so that a receiver
* process can use them separately if --perms wasn't specified. */
if (am_sender)
p = lp_outgoing_chmod(i);
p = lp_outgoing_chmod(module_id);
else
p = lp_incoming_chmod(i);
p = lp_incoming_chmod(module_id);
if (*p && !(daemon_chmod_modes = parse_chmod(p, &chmod_modes))) {
rprintf(FLOG, "Invalid \"%sing chmod\" directive: %s\n",
am_sender ? "outgo" : "incom", p);
@@ -1077,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)
@@ -1130,7 +1222,7 @@ int start_daemon(int f_in, int f_out)
if (!load_config(0))
exit_cleanup(RERR_SYNTAX);
if (lp_haproxy_header() && !read_haproxy_header(f_in))
if (lp_proxy_protocol() && !read_proxy_protocol_header(f_in))
return -1;
p = lp_daemon_chroot();
@@ -1166,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);
@@ -1185,6 +1277,19 @@ int start_daemon(int f_in, int f_out)
if (!read_line_old(f_in, line, sizeof line, 0))
return -1;
if (strncmp(line, EARLY_INPUT_CMD, EARLY_INPUT_CMDLEN) == 0) {
early_input_len = strtol(line + EARLY_INPUT_CMDLEN, NULL, 10);
if (early_input_len <= 0 || early_input_len > BIGPATHBUFLEN) {
io_printf(f_out, "@ERROR: invalid early_input length\n");
return -1;
}
early_input = new_array(char, early_input_len);
read_buf(f_in, early_input, early_input_len);
if (!read_line_old(f_in, line, sizeof line, 0))
return -1;
}
if (!*line || strcmp(line, "#list") == 0) {
rprintf(FLOG, "module-list request from %s (%s)\n",
host, addr);
@@ -1346,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??? */

11
cmdormsg Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
srcdir=`dirname $0`
opt="$1"
shift
echo "$*"
if ! "${@}"; then
echo "If you can't fix the issue, re-run $srcdir/configure with --$opt."
exit 1
fi

198
compat.c
View File

@@ -20,6 +20,7 @@
*/
#include "rsync.h"
#include "itypes.h"
extern int am_server;
extern int am_sender;
@@ -42,6 +43,7 @@ extern int protect_args;
extern int preserve_uid;
extern int preserve_gid;
extern int preserve_atimes;
extern int preserve_crtimes;
extern int preserve_acls;
extern int preserve_xattrs;
extern int xfer_flags_as_varint;
@@ -72,9 +74,10 @@ int want_xattr_optim = 0;
int proper_seed_order = 0;
int inplace_partial = 0;
int do_negotiated_strings = 0;
int xmit_id0_names = 0;
/* These index values are for the file-list's extra-attribute array. */
int pathname_ndx, depth_ndx, atimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
int pathname_ndx, depth_ndx, atimes_ndx, crtimes_ndx, uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
int sender_symlink_iconv = 0; /* sender should convert symlink content */
@@ -108,6 +111,7 @@ struct name_num_obj valid_compressions = {
#define CF_CHKSUM_SEED_FIX (1<<5)
#define CF_INPLACE_PARTIAL_DIR (1<<6)
#define CF_VARINT_FLIST_FLAGS (1<<7)
#define CF_ID0_NAMES (1<<8)
static const char *client_info;
@@ -173,6 +177,8 @@ void parse_compress_choice(int final_call)
exit_cleanup(RERR_UNSUPPORTED);
}
do_compression = nni->num;
if (am_server)
validate_choice_vs_env(NSTR_COMPRESS, do_compression, -1);
} else if (do_compression)
do_compression = CPRES_ZLIB;
else
@@ -241,8 +247,7 @@ static void init_nno_saw(struct name_num_obj *nno, int val)
}
if (!nno->saw) {
if (!(nno->saw = new_array0(uchar, nno->saw_len)))
out_of_memory("init_nno_saw");
nno->saw = new_array0(uchar, nno->saw_len);
/* We'll take this opportunity to make sure that the main_name values are set right. */
for (cnt = 1, nni = nno->list; nni->name; nni++, cnt++) {
@@ -261,10 +266,14 @@ static void init_nno_saw(struct name_num_obj *nno, int val)
static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf, int tobuf_len)
{
char *to = tobuf, *tok = NULL;
int cnt = 0;
int saw_tok = 0, cnt = 0;
while (1) {
if (*from == ' ' || !*from) {
int at_space = isSpace(from);
char ch = *from++;
if (ch == '&')
ch = '\0';
if (!ch || at_space) {
if (tok) {
struct name_num_item *nni = get_nni_by_name(nno, tok, to - tok);
if (nni && !nno->saw[nni->num]) {
@@ -278,9 +287,10 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
}
} else
to = tok - (tok != tobuf);
saw_tok = 1;
tok = NULL;
}
if (!*from++)
if (!ch)
break;
continue;
}
@@ -293,13 +303,19 @@ static int parse_nni_str(struct name_num_obj *nno, const char *from, char *tobuf
to = tok - (tok != tobuf);
break;
}
*to++ = *from++;
*to++ = ch;
}
*to = '\0';
if (saw_tok && to == tobuf)
return strlcpy(tobuf, "INVALID", MAX_NSTR_STRLEN);
return to - tobuf;
}
/* This routine is always called with a tmpbuf of MAX_NSTR_STRLEN length, but the
* buffer may be pre-populated with a "len" length string to use OR a len of -1
* to tell us to read a string from the fd. */
static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf, int len)
{
struct name_num_item *ret = NULL;
@@ -315,17 +331,26 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf,
}
if (len > 0) {
struct name_num_item *nni;
int best = nno->saw_len; /* We want best == 1 from the client list, so start with a big number. */
char *tok;
if (am_server)
init_nno_saw(nno, 1); /* Since we're parsing client names, anything we parse first is #1. */
for (tok = strtok(tmpbuf, " \t"); tok; tok = strtok(NULL, " \t")) {
struct name_num_item *nni = get_nni_by_name(nno, tok, -1);
char *space, *tok = tmpbuf;
while (tok) {
while (*tok == ' ') tok++; /* Should be unneeded... */
if (!*tok)
break;
if ((space = strchr(tok, ' ')) != NULL)
*space = '\0';
nni = get_nni_by_name(nno, tok, -1);
if (space) {
*space = ' ';
tok = space + 1;
} else
tok = NULL;
if (!nni || !nno->saw[nni->num] || best <= nno->saw[nni->num])
continue;
ret = nni;
best = nno->saw[nni->num];
if (best == 1)
if (best == 1 || am_server) /* The server side stops at the first acceptable client choice */
break;
}
if (ret) {
@@ -337,15 +362,84 @@ static void recv_negotiate_str(int f_in, struct name_num_obj *nno, char *tmpbuf,
}
}
if (!am_server)
rprintf(FERROR, "Failed to negotiate a common %s\n", nno->type);
if (!am_server || !do_negotiated_strings) {
char *cp = tmpbuf;
int j;
rprintf(FERROR, "Failed to negotiate a %s choice.\n", nno->type);
rprintf(FERROR, "%s list: %s\n", am_server ? "Client" : "Server", tmpbuf);
/* Recreate our original list from the saw values. This can't overflow our huge
* buffer because we don't have enough valid entries to get anywhere close. */
for (j = 1, *cp = '\0'; j <= nno->saw_len; j++) {
struct name_num_item *nni;
for (nni = nno->list; nni->name; nni++) {
if (nno->saw[nni->num] == j) {
*cp++ = ' ';
cp += strlcpy(cp, nni->name, MAX_NSTR_STRLEN - (cp - tmpbuf));
break;
}
}
}
if (!*tmpbuf)
strlcpy(cp, " INVALID", MAX_NSTR_STRLEN);
rprintf(FERROR, "%s list:%s\n", am_server ? "Server" : "Client", tmpbuf);
}
exit_cleanup(RERR_UNSUPPORTED);
}
static const char *getenv_nstr(int ntype)
{
const char *env_str = getenv(ntype == NSTR_COMPRESS ? "RSYNC_COMPRESS_LIST" : "RSYNC_CHECKSUM_LIST");
/* When writing a batch file, we always negotiate an old-style choice. */
if (write_batch)
env_str = ntype == NSTR_COMPRESS ? "zlib" : protocol_version >= 30 ? "md5" : "md4";
if (am_server && env_str) {
char *cp = strchr(env_str, '&');
if (cp)
env_str = cp + 1;
}
return env_str;
}
void validate_choice_vs_env(int ntype, int num1, int num2)
{
struct name_num_obj *nno = ntype == NSTR_COMPRESS ? &valid_compressions : &valid_checksums;
const char *list_str = getenv_nstr(ntype);
char tmpbuf[MAX_NSTR_STRLEN];
if (!list_str)
return;
while (isSpace(list_str)) list_str++;
if (!*list_str)
return;
init_nno_saw(nno, 0);
parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
if (ntype == NSTR_CHECKSUM) /* If "md4" is in the env list, all the old MD4 choices are OK too. */
nno->saw[CSUM_MD4_ARCHAIC] = nno->saw[CSUM_MD4_BUSTED] = nno->saw[CSUM_MD4_OLD] = nno->saw[CSUM_MD4];
if (!nno->saw[num1] || (num2 >= 0 && !nno->saw[num2])) {
rprintf(FERROR, "Your --%s-choice value (%s) was refused by the server.\n",
ntype == NSTR_COMPRESS ? "compress" : "checksum",
ntype == NSTR_COMPRESS ? compress_choice : checksum_choice);
exit_cleanup(RERR_UNSUPPORTED);
}
free(nno->saw);
nno->saw = NULL;
}
/* The saw buffer is initialized and used to store ordinal values from 1 to N
* for the order of the args in the array. If dup_markup == '\0', duplicates
* are removed otherwise the char is prefixed to the duplicate term and, if it
* is an opening paren/bracket/brace, the matching closing char is suffixed. */
* is an opening paren/bracket/brace, the matching closing char is suffixed.
* "none" is removed on the client side unless dup_markup != '\0'. */
int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len, char dup_markup)
{
struct name_num_item *nni;
@@ -367,6 +461,8 @@ int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len,
continue;
delim = dup_markup;
}
if (nni->num == 0 && !am_server && !dup_markup)
continue;
if (len)
to_buf[len++]= ' ';
if (delim) {
@@ -386,25 +482,15 @@ int get_default_nno_list(struct name_num_obj *nno, char *to_buf, int to_buf_len,
return len;
}
static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *env_name)
static void send_negotiate_str(int f_out, struct name_num_obj *nno, int ntype)
{
char tmpbuf[MAX_NSTR_STRLEN];
const char *list_str = getenv(env_name);
int len, fail_if_empty = list_str && strstr(list_str, "FAIL");
const char *list_str = getenv_nstr(ntype);
int len;
if (!do_negotiated_strings) {
if (!am_server && fail_if_empty) {
rprintf(FERROR, "Remote rsync is too old for %s negotation\n", nno->type);
exit_cleanup(RERR_UNSUPPORTED);
}
return;
}
if (list_str && *list_str && (!am_server || local_server)) {
if (list_str && *list_str) {
init_nno_saw(nno, 0);
len = parse_nni_str(nno, list_str, tmpbuf, MAX_NSTR_STRLEN);
if (fail_if_empty && !len)
len = strlcpy(tmpbuf, "FAIL", MAX_NSTR_STRLEN);
list_str = tmpbuf;
} else
list_str = NULL;
@@ -419,15 +505,10 @@ static void send_negotiate_str(int f_out, struct name_num_obj *nno, const char *
rprintf(FINFO, "Client %s list (on client): %s\n", nno->type, tmpbuf);
}
if (local_server) {
/* A local server doesn't bother to send/recv the strings, it just constructs
* and parses the same string on both sides. */
recv_negotiate_str(-1, nno, tmpbuf, len);
} else {
/* Each side sends their list of valid names to the other side and then both sides
* pick the first name in the client's list that is also in the server's list. */
/* Each side sends their list of valid names to the other side and then both sides
* pick the first name in the client's list that is also in the server's list. */
if (do_negotiated_strings)
write_vstring(f_out, tmpbuf, len);
}
}
static void negotiate_the_strings(int f_in, int f_out)
@@ -435,20 +516,35 @@ static void negotiate_the_strings(int f_in, int f_out)
/* We send all the negotiation strings before we start to read them to help avoid a slow startup. */
if (!checksum_choice)
send_negotiate_str(f_out, &valid_checksums, "RSYNC_CHECKSUM_LIST");
send_negotiate_str(f_out, &valid_checksums, NSTR_CHECKSUM);
if (do_compression && !compress_choice)
send_negotiate_str(f_out, &valid_compressions, "RSYNC_COMPRESS_LIST");
send_negotiate_str(f_out, &valid_compressions, NSTR_COMPRESS);
if (valid_checksums.saw) {
char tmpbuf[MAX_NSTR_STRLEN];
recv_negotiate_str(f_in, &valid_checksums, tmpbuf, -1);
int len;
if (do_negotiated_strings)
len = -1;
else
len = strlcpy(tmpbuf, protocol_version >= 30 ? "md5" : "md4", MAX_NSTR_STRLEN);
recv_negotiate_str(f_in, &valid_checksums, tmpbuf, len);
}
if (valid_compressions.saw) {
char tmpbuf[MAX_NSTR_STRLEN];
recv_negotiate_str(f_in, &valid_compressions, tmpbuf, -1);
int len;
if (do_negotiated_strings)
len = -1;
else
len = strlcpy(tmpbuf, "zlib", MAX_NSTR_STRLEN);
recv_negotiate_str(f_in, &valid_compressions, tmpbuf, len);
}
/* If the other side is too old to negotiate, the above steps just made sure that
* the env didn't disallow the old algorithm. Mark things as non-negotiated. */
if (!do_negotiated_strings)
valid_checksums.negotiated_name = valid_compressions.negotiated_name = NULL;
}
void setup_protocol(int f_out,int f_in)
@@ -460,6 +556,8 @@ void setup_protocol(int f_out,int f_in)
* aligned for direct int64-pointer memory access. */
if (preserve_atimes)
atimes_ndx = (file_extra_cnt += EXTRA64_CNT);
if (preserve_crtimes)
crtimes_ndx = (file_extra_cnt += EXTRA64_CNT);
if (am_sender) /* This is most likely in the in64 union as well. */
pathname_ndx = (file_extra_cnt += PTR_EXTRA_CNT);
else
@@ -601,11 +699,11 @@ void setup_protocol(int f_out,int f_in)
compat_flags |= CF_CHKSUM_SEED_FIX;
if (local_server || strchr(client_info, 'I') != NULL)
compat_flags |= CF_INPLACE_PARTIAL_DIR;
if (local_server || strchr(client_info, 'u') != NULL)
compat_flags |= CF_ID0_NAMES;
if (local_server || strchr(client_info, 'v') != NULL) {
if (!write_batch || protocol_version >= 30) {
do_negotiated_strings = 1;
compat_flags |= CF_VARINT_FLIST_FLAGS;
}
do_negotiated_strings = 1;
compat_flags |= CF_VARINT_FLIST_FLAGS;
}
if (strchr(client_info, 'V') != NULL) { /* Support a pre-release 'V' that got superseded */
if (!write_batch)
@@ -623,6 +721,11 @@ void setup_protocol(int f_out,int f_in)
want_xattr_optim = protocol_version >= 31 && !(compat_flags & CF_AVOID_XATTR_OPTIM);
proper_seed_order = compat_flags & CF_CHKSUM_SEED_FIX ? 1 : 0;
xfer_flags_as_varint = compat_flags & CF_VARINT_FLIST_FLAGS ? 1 : 0;
xmit_id0_names = compat_flags & CF_ID0_NAMES ? 1 : 0;
if (!xfer_flags_as_varint && preserve_crtimes) {
fprintf(stderr, "Both rsync versions must be at least 3.2.0 for --crtimes.\n");
exit_cleanup(RERR_PROTOCOL);
}
if (am_sender) {
receiver_symlink_times = am_server
? strchr(client_info, 'L') != NULL
@@ -654,6 +757,9 @@ void setup_protocol(int f_out,int f_in)
#endif
}
if (read_batch)
do_negotiated_strings = 0;
if (need_unsorted_flist && (!am_sender || inc_recurse))
unsort_ndx = ++file_extra_cnt;

976
config.guess vendored
View File

File diff suppressed because it is too large Load Diff

2749
config.sub vendored
View File

File diff suppressed because it is too large Load Diff

28
configure vendored
View File

@@ -4,24 +4,24 @@
# then transfer control to the configure.sh script to do the real work.
dir=`dirname $0`
realconfigure="$dir/configure.sh"
if test x"$dir" = x; then
dir=.
fi
if test ! -f "$realconfigure"; then
if test -f "$HOME/build_farm/build_test.fns"; then
# Test the included popt
set -- --with-included-popt "${@}"
# Allow the build farm to grab latest files via rsync.
actions='build fetch'
else
actions='build'
if test "$dir" = '.'; then
branch=`packaging/prep-auto-dir` || exit 1
if test x"$branch" != x; then
cd build || exit 1
dir=..
fi
if "$dir/prepare-source" $actions; then
:
else
fi
if test ! -f configure.sh; then
if ! "$dir/prepare-source" build; then
echo 'Failed to build configure.sh and/or config.h.in -- giving up.' >&2
rm -f "$realconfigure"
rm -f configure.sh
exit 1
fi
fi
exec "$realconfigure" "${@}"
exec ./configure.sh --srcdir="$dir" "${@}"

View File

@@ -1,16 +1,15 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT([rsync],[3.2.0pre1],[http://rsync.samba.org/bugzilla.html])
AC_INIT([rsync],[ ],[https://rsync.samba.org/bug-tracking.html])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ([2.69])
AC_SUBST(RSYNC_VERSION, $PACKAGE_VERSION)
AC_MSG_NOTICE([Configuring rsync $PACKAGE_VERSION])
PACKAGE_VERSION=`sed 's/.*"\(.*\)".*/\1/' <$srcdir/version.h`
AC_DEFINE_UNQUOTED(RSYNC_VERSION, ["$PACKAGE_VERSION"], [rsync release version])
AC_MSG_NOTICE([Configuring rsync $PACKAGE_VERSION])
LDFLAGS=${LDFLAGS-""}
@@ -42,12 +41,14 @@ dnl Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_AWK
AC_PROG_EGREP
AC_PROG_INSTALL
AC_PROG_MKDIR_P
AC_PROG_CC_STDC
AC_SUBST(SHELL)
AC_PATH_PROG([PERL], [perl])
AC_PATH_PROG([PYTHON3], [python3])
AC_DEFINE([_GNU_SOURCE], 1,
[Define _GNU_SOURCE so that we get all necessary prototypes])
@@ -56,12 +57,53 @@ 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
CFLAGS="$CFLAGS -pg"
fi
AC_MSG_CHECKING([if md2man can create man pages])
if test x"$ac_cv_path_PYTHON3" = x; then
AC_MSG_RESULT(no - python3 not found)
md2man_works=no
else
md2man_out=`"$srcdir/md2man" --test "$srcdir/rsync-ssl.1.md" 2>&1`
if test $? = 0; then
AC_MSG_RESULT(yes)
md2man_works=yes
else
AC_MSG_RESULT(no)
md2man_works=no
echo "$md2man_out"
fi
fi
AC_MSG_CHECKING([if we require man-page building])
AC_ARG_ENABLE([md2man],
AS_HELP_STRING([--disable-md2man],[disable md2man for man page creation]))
if test x"$enable_md2man" != x"no"; then
if test -f "$srcdir/rsync.1"; then
AC_MSG_RESULT(optional)
else
AC_MSG_RESULT(required)
if test x"$md2man_works" = x"no"; then
err_msg="$err_msg$nl- You need python3 and either the cmarkgfm OR commonmark python3 lib in order"
err_msg="$err_msg$nl to build man pages based on the git source (man pages are included in the"
err_msg="$err_msg$nl official release tar files)."
no_lib="$no_lib md2man"
fi
fi
MAKE_MAN=man
else
AC_MSG_RESULT(no)
MAKE_MAN=''
fi
# Specifically, this turns on panic_action handling.
AC_ARG_ENABLE(maintainer-mode,
@@ -70,7 +112,6 @@ if test x"$enable_maintainer_mode" = x"yes"; then
CFLAGS="$CFLAGS -DMAINTAINER_MODE"
fi
# This is needed for our included version of popt. Kind of silly, but
# I don't want our version too far out of sync.
CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
@@ -163,31 +204,104 @@ SIMD=
AC_MSG_CHECKING([whether to enable SIMD optimizations])
AC_ARG_ENABLE(simd,
AS_HELP_STRING([--disable-simd],[disable SIMD optimizations (requires g++)]))
AS_HELP_STRING([--disable-simd],[disable SIMD optimizations (requires c++)]))
# Clag is crashing with -g -O2, so we'll get rid of -g for now.
CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-g //'`
if test x"$enable_simd" != x"no"; then
# For x86-64 SIMD, g++ is also required
if test x"$build_cpu" = x"x86_64" && test x"$CXX" = x"g++"; then
SIMD="$SIMD x86_64"
# For x86-64 SIMD, g++ >=5 or clang++ >=7 is required
if test x"$build_cpu" = x"x86_64"; then
AC_LANG(C++)
AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
#include <immintrin.h>
__attribute__ ((target("default"))) int test_ssse3(int x) { return x; }
__attribute__ ((target("default"))) int test_sse2(int x) { return x; }
__attribute__ ((target("default"))) int test_avx2(int x) { return x; }
__attribute__ ((target("ssse3"))) int test_ssse3(int x) { return x; }
__attribute__ ((target("sse2"))) int test_sse2(int x) { return x; }
__attribute__ ((target("avx2"))) int test_avx2(int x) { return x; }
typedef long long __m128i_u __attribute__((__vector_size__(16), __may_alias__, __aligned__(1)));
typedef long long __m256i_u __attribute__((__vector_size__(32), __may_alias__, __aligned__(1)));
__attribute__ ((target("default"))) void more_testing(char* buf, int len) { }
__attribute__ ((target("ssse3"))) void more_testing(char* buf, int len)
{
int i;
for (i = 0; i < (len-32); i+=32) {
__m128i in8_1, in8_2;
in8_1 = _mm_lddqu_si128((__m128i_u*)&buf[i]);
in8_2 = _mm_lddqu_si128((__m128i_u*)&buf[i + 16]);
}
}
]], [[if (test_ssse3(42) != 42 || test_sse2(42) != 42 || test_avx2(42) != 42) exit(1);]])],[CXX_OK=yes],[CXX_OK=no])
AC_LANG(C)
if test x"$CXX_OK" = x"yes"; then
# AC_MSG_RESULT() is called below.
SIMD="x86_64"
elif test x"$enable_simd" = x"yes"; then
AC_MSG_RESULT(error)
AC_MSG_ERROR(The SIMD compilation test failed.
Omit --enable-simd to continue without it.)
fi
elif test x"$enable_simd" = x"yes"; then
AC_MSG_RESULT(unavailable)
AC_MSG_ERROR(The SIMD optimizations are currently x86_64 only.
Omit --enable-simd to continue without it.)
fi
fi
if test x"$SIMD" != x""; then
SIMD=`echo "$SIMD" | sed -e 's/^ *//'`
AC_MSG_RESULT([yes ($SIMD)])
AC_DEFINE(HAVE_SIMD, 1, [Define to 1 to enable SIMD optimizations])
SIMD=`echo "$SIMD" | sed -e 's/[[^ ]]\+/$(SIMD_&)/g'`
AC_DEFINE(HAVE_SIMD, 1, [Define to 1 to enable SIMD optimizations])
SIMD='$(SIMD_'"$SIMD)"
# We only use c++ for its target attribute dispatching, disable unneeded bulky features
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-rtti"
# Apple often has "g++" as a symlink for clang. Try to find out the truth.
CXX_VERSION=`$CXX --version 2>/dev/null | head -n 2`
case "$CXX_VERSION" in
*clang*) CXXFLAGS="$CXXFLAGS -fno-slp-vectorize" ;; # avoid a performance hit
esac
else
AC_MSG_RESULT(no)
fi
AC_SUBST(SIMD)
# We only use g++ for its target attribute dispatching, disable unneeded bulky features
if test x"$CXXOBJ" != x""; then
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-rtti"
AC_MSG_CHECKING([if assembler accepts noexecstack])
OLD_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wa,--noexecstack"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[return 0;]])],
[ NOEXECSTACK='-Wa,--noexecstack' ; AC_MSG_RESULT(yes) ],
[ NOEXECSTACK='' ; AC_MSG_RESULT(no) ])
CFLAGS="$OLD_CFLAGS"
AC_SUBST(NOEXECSTACK)
ASM=
AC_MSG_CHECKING([whether to enable ASM optimizations])
AC_ARG_ENABLE(asm,
AS_HELP_STRING([--disable-asm],[disable ASM optimizations]))
if test x"$enable_asm" != x"no"; then
if test x"$build_cpu" = x"x86_64"; then
ASM="$build_cpu"
elif test x"$enable_asm" = x"yes"; then
AC_MSG_RESULT(unavailable)
AC_MSG_ERROR(The ASM optimizations are currently x86_64 only.
Omit --enable-asm to continue without it.)
fi
fi
if test x"$ASM" != x""; then
AC_MSG_RESULT([yes ($ASM)])
AC_DEFINE(HAVE_ASM, 1, [Define to 1 to enable ASM optimizations])
ASM='$(ASM_'"$ASM)"
else
AC_MSG_RESULT(no)
fi
AC_SUBST(ASM)
# arrgh. libc in some old debian version screwed up the largefile
# stuff, getting byte range locking wrong
AC_CACHE_CHECK([for broken largefile support],rsync_cv_HAVE_BROKEN_LARGEFILE,[
@@ -239,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/
@@ -331,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])])
@@ -372,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])
@@ -382,9 +505,18 @@ AC_ARG_ENABLE([openssl],
AS_HELP_STRING([--disable-openssl],[disable openssl crypto library]))
AH_TEMPLATE([USE_OPENSSL],
[Undefine if you do not want to use openssl crypto library. By default this is defined.])
if test x"$enable_openssl" != x"no" && test x"$ac_cv_header_openssl_md4_h" = x"yes" && test x"$ac_cv_header_openssl_md5_h" = x"yes"; then
AC_MSG_RESULT(yes)
AC_SEARCH_LIBS(MD5_Init, crypto, [AC_DEFINE(USE_OPENSSL)])
if test x"$enable_openssl" != x"no"; then
if test x"$ac_cv_header_openssl_md4_h" = x"yes" && test x"$ac_cv_header_openssl_md5_h" = x"yes"; then
AC_MSG_RESULT(yes)
AC_SEARCH_LIBS(MD5_Init, crypto,
[AC_DEFINE(USE_OPENSSL)],
[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)
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)
fi
@@ -394,9 +526,18 @@ AC_ARG_ENABLE([xxhash],
AS_HELP_STRING([--disable-xxhash],[disable xxhash checksums]))
AH_TEMPLATE([SUPPORT_XXHASH],
[Undefine if you do not want xxhash checksums. By default this is defined.])
if test x"$enable_xxhash" != x"no" && test x"$ac_cv_header_xxhash_h" = x"yes"; then
AC_MSG_RESULT(yes)
AC_SEARCH_LIBS(XXH64_createState, xxhash, [AC_DEFINE(SUPPORT_XXHASH)])
if test x"$enable_xxhash" != x"no"; then
if test x"$ac_cv_header_xxhash_h" = x"yes"; then
AC_MSG_RESULT(yes)
AC_SEARCH_LIBS(XXH64_createState, xxhash,
[AC_DEFINE(SUPPORT_XXHASH)],
[err_msg="$err_msg$nl- Failed to find XXH64_createState function in xxhash lib.";
no_lib="$no_lib xxhash"])
else
AC_MSG_RESULT(no)
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)
fi
@@ -406,9 +547,18 @@ AC_ARG_ENABLE([zstd],
AC_HELP_STRING([--disable-zstd], [disable zstd compression]))
AH_TEMPLATE([SUPPORT_ZSTD],
[Undefine if you do not want zstd compression. By default this is defined.])
if test x"$enable_zstd" != x"no" && test x"$ac_cv_header_zstd_h" = x"yes"; then
AC_MSG_RESULT(yes)
AC_SEARCH_LIBS(ZSTD_minCLevel, zstd, [AC_DEFINE(SUPPORT_ZSTD)])
if test x"$enable_zstd" != x"no"; then
if test x"$ac_cv_header_zstd_h" = x"yes"; then
AC_MSG_RESULT(yes)
AC_SEARCH_LIBS(ZSTD_minCLevel, zstd,
[AC_DEFINE(SUPPORT_ZSTD)],
[err_msg="$err_msg$nl- Failed to find ZSTD_minCLevel function in zstd lib.";
no_lib="$no_lib zstd"])
else
AC_MSG_RESULT(no)
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)
fi
@@ -418,13 +568,39 @@ AC_ARG_ENABLE([lz4],
AC_HELP_STRING([--disable-lz4], [disable LZ4 compression]))
AH_TEMPLATE([SUPPORT_LZ4],
[Undefine if you do not want LZ4 compression. By default this is defined.])
if test x"$enable_lz4" != x"no" && test x"$ac_cv_header_lz4_h" = x"yes"; then
AC_MSG_RESULT(yes)
AC_SEARCH_LIBS(LZ4_compress_default, lz4, [AC_DEFINE(SUPPORT_LZ4)])
if test x"$enable_lz4" != x"no"; then
if test x"$ac_cv_header_lz4_h" = x"yes"; then
AC_MSG_RESULT(yes)
AC_SEARCH_LIBS(LZ4_compress_default, lz4,
[AC_DEFINE(SUPPORT_LZ4)],
[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)
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>
@@ -556,7 +732,7 @@ size_t iconv();
#endif
]], [[]])],[am_cv_proto_iconv_arg1=""],[am_cv_proto_iconv_arg1="const"])
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed 's/( /(/'`
AC_MSG_RESULT([$]{ac_t:-
}[$]am_cv_proto_iconv)
AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
@@ -668,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 \
@@ -763,7 +939,7 @@ AC_ARG_ENABLE(iconv,
AS_HELP_STRING([--disable-iconv],[disable rsync's --iconv option]),
[], [enable_iconv=$enable_iconv_open])
AH_TEMPLATE([ICONV_OPTION],
[Define if you want the --iconv option. Specifing a value will set the
[Define if you want the --iconv option. Specifying a value will set the
default iconv setting (a NULL means no --iconv processing by default).])
if test x"$enable_iconv" != x"no"; then
if test x"$enable_iconv" = x"yes"; then
@@ -794,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
@@ -804,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
@@ -1069,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])
@@ -1095,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)
@@ -1138,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)
@@ -1194,5 +1379,5 @@ AC_CONFIG_FILES([Makefile lib/dummy zlib/dummy popt/dummy shconfig])
AC_OUTPUT
AC_MSG_RESULT()
AC_MSG_RESULT([ rsync ${RSYNC_VERSION} configuration successful])
AC_MSG_RESULT([ rsync $PACKAGE_VERSION configuration successful])
AC_MSG_RESULT()

114
daemon-parm.awk Executable file
View File

@@ -0,0 +1,114 @@
#!/usr/bin/awk -f
# The caller must pass arg: daemon-parm.txt
# The resulting code is output into daemon-parm.h
BEGIN {
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from a list of values in " ARGV[1] "! */\n\n"
sect = psect = defines = accessors = prior_ptype = ""
parms = "\nstatic struct parm_struct parm_table[] = {"
comment_fmt = "\n/********** %s **********/\n"
tdstruct = "typedef struct {"
}
/^\s*$/ { next }
/^#/ { next }
/^Globals:/ {
if (defines != "") {
print "The Globals section must come first!"
defines = ""
exit
}
defines = tdstruct
values = "\nstatic const all_vars Defaults = {\n { /* Globals: */\n"
exps = exp_values = sprintf(comment_fmt, "EXP")
sect = "GLOBAL"
psect = ", P_GLOBAL, &Vars.g."
next
}
/^Locals:/ {
if (sect == "") {
print "The Locals section must come after the Globals!"
exit
}
defines = defines exps "} global_vars;\n\n" tdstruct
values = values exp_values "\n }, { /* Locals: */\n"
exps = exp_values = sprintf(comment_fmt, "EXP")
sect = "LOCAL"
psect = ", P_LOCAL, &Vars.l."
next
}
/^(STRING|CHAR|PATH|INTEGER|ENUM|OCTAL|BOOL|BOOLREV|BOOL3)[ \t]/ {
ptype = $1
name = $2
$1 = $2 = ""
sub(/^[ \t]+/, "")
if (ptype != prior_ptype) {
comment = sprintf(comment_fmt, ptype)
defines = defines comment
values = values comment
parms = parms "\n"
accessors = accessors "\n"
prior_ptype = ptype
}
if (ptype == "STRING" || ptype == "PATH") {
atype = "STRING"
vtype = "char*"
} else if (ptype ~ /BOOL/) {
atype = vtype = "BOOL"
} else if (ptype == "CHAR") {
atype = "CHAR"
vtype = "char"
} else {
atype = "INTEGER"
vtype = "int"
}
# The name might be var_name|public_name
pubname = name
sub(/\|.*/, "", name)
sub(/.*\|/, "", pubname)
gsub(/_/, " ", pubname)
gsub(/-/, "", name)
if (ptype == "ENUM")
enum = "enum_" name
else
enum = "NULL"
defines = defines "\t" vtype " " name ";\n"
values = values "\t" $0 ", /* " name " */\n"
parms = parms " {\"" pubname "\", P_" ptype psect name ", " enum ", 0},\n"
accessors = accessors "FN_" sect "_" atype "(lp_" name ", " name ")\n"
if (vtype == "char*") {
exps = exps "\tBOOL " name "_EXP;\n"
exp_values = exp_values "\tFalse, /* " name "_EXP */\n"
}
next
}
/./ {
print "Extraneous line:" $0
defines = ""
exit
}
END {
if (sect != "" && defines != "") {
defines = defines exps "} local_vars;\n\n"
defines = defines tdstruct "\n\tglobal_vars g;\n\tlocal_vars l;\n} all_vars;\n"
values = values exp_values "\n }\n};\n\nstatic all_vars Vars;\n"
parms = parms "\n {NULL, P_BOOL, P_NONE, NULL, NULL, 0}\n};\n"
print heading defines values parms accessors > "daemon-parm.h"
} else {
print "Failed to parse the data in " ARGV[1]
exit 1
}
}

68
daemon-parm.txt Normal file
View File

@@ -0,0 +1,68 @@
Globals: ================================================================
STRING bind_address|address NULL
STRING daemon_chroot NULL
STRING daemon_gid NULL
STRING daemon_uid NULL
STRING motd_file NULL
STRING pid_file NULL
STRING socket_options NULL
INTEGER listen_backlog 5
INTEGER rsync_port|port 0
BOOL proxy_protocol False
Locals: =================================================================
STRING auth_users NULL
STRING charset NULL
STRING comment NULL
STRING dont_compress DEFAULT_DONT_COMPRESS
STRING early_exec NULL
STRING exclude NULL
STRING exclude_from NULL
STRING filter NULL
STRING gid NULL
STRING hosts_allow NULL
STRING hosts_deny NULL
STRING include NULL
STRING include_from NULL
STRING incoming_chmod NULL
STRING lock_file DEFAULT_LOCK_FILE
STRING log_file NULL
STRING log_format "%o %h [%a] %m (%u) %f %l"
STRING name NULL
STRING name_converter NULL
STRING outgoing_chmod NULL
STRING post-xfer_exec NULL
STRING pre-xfer_exec NULL
STRING refuse_options NULL
STRING secrets_file NULL
STRING syslog_tag "rsyncd"
STRING uid NULL
PATH path NULL
PATH temp_dir NULL
INTEGER max_connections 0
INTEGER max_verbosity 1
INTEGER timeout 0
ENUM syslog_facility LOG_DAEMON
BOOL fake_super False
BOOL forward_lookup True
BOOL ignore_errors False
BOOL ignore_nonreadable False
BOOL list True
BOOL read_only True
BOOL reverse_lookup True
BOOL strict_modes True
BOOL transfer_logging False
BOOL use_chroot True
BOOL write_only False
BOOL3 munge_symlinks Unset
BOOL3 numeric_ids Unset
BOOL3 open_noatime Unset

41
define-from-md.awk Executable file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/awk -f
# The caller must pass args: -v hfile=NAME rsync.1.md
BEGIN {
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from a list of values in " ARGV[1] "! */"
if (hfile ~ /compress/) {
define = "#define DEFAULT_DONT_COMPRESS"
prefix = "*."
} else {
define = "#define DEFAULT_CVSIGNORE"
prefix = ""
}
value_list = ""
}
/^ > [^ ]+$/ {
gsub(/`/, "")
if (value_list != "") value_list = value_list " "
value_list = value_list prefix $2
next
}
value_list ~ /\.gz / && hfile ~ /compress/ {
exit
}
value_list ~ /SCCS / && hfile ~ /cvsignore/ {
exit
}
value_list = ""
END {
if (value_list != "")
print heading "\n\n" define " \"" value_list "\"" > hfile
else {
print "Failed to find a value list in " ARGV[1] " for " hfile
exit 1
}
}

View File

@@ -21,6 +21,7 @@
*/
#include "rsync.h"
#include "ifuncs.h"
extern int am_server;
extern int am_sender;
@@ -199,8 +200,7 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
} else
suf_len = 0;
if (!(rule->pattern = new_array(char, pre_len + pat_len + suf_len + 1)))
out_of_memory("add_rule");
rule->pattern = new_array(char, pre_len + pat_len + suf_len + 1);
if (pre_len) {
memcpy(rule->pattern, dirbuf + module_dirlen, pre_len);
for (cp = rule->pattern; cp < rule->pattern + pre_len; cp++) {
@@ -261,19 +261,14 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
}
}
if (!(lp = new_array0(filter_rule_list, 1)))
out_of_memory("add_rule");
lp = new_array0(filter_rule_list, 1);
if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0)
out_of_memory("add_rule");
rule->u.mergelist = lp;
if (mergelist_cnt == mergelist_size) {
mergelist_size += 5;
mergelist_parents = realloc_array(mergelist_parents,
filter_rule *,
mergelist_size);
if (!mergelist_parents)
out_of_memory("add_rule");
mergelist_parents = realloc_array(mergelist_parents, filter_rule *, mergelist_size);
}
if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] activating mergelist #%d%s\n",
@@ -497,8 +492,6 @@ void *push_local_filters(const char *dir, unsigned int dirlen)
push = (struct local_filter_state *)new_array(char,
sizeof (struct local_filter_state)
+ (mergelist_cnt-1) * sizeof (filter_rule_list));
if (!push)
out_of_memory("push_local_filters");
push->mergelist_cnt = mergelist_cnt;
for (i = 0; i < mergelist_cnt; i++) {
@@ -821,8 +814,7 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
if (!*s)
return NULL;
if (!(rule = new0(filter_rule)))
out_of_memory("parse_rule_tok");
rule = new0(filter_rule);
/* Inherit from the template. Don't inherit FILTRULES_SIDES; we check
* that later. */
@@ -1051,16 +1043,6 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
return rule;
}
static char default_cvsignore[] =
/* These default ignored items come from the CVS manual. */
"RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS"
" .make.state .nse_depinfo *~ #* .#* ,* _$* *$"
" *.old *.bak *.BAK *.orig *.rej .del-*"
" *.a *.olb *.o *.obj *.so *.exe"
" *.Z *.elc *.ln core"
/* The rest we added to suit ourself. */
" .svn/ .git/ .hg/ .bzr/";
static void get_cvs_excludes(uint32 rflags)
{
static int initialized = 0;
@@ -1070,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);
@@ -1134,8 +1116,7 @@ void parse_filter_str(filter_rule_list *listp, const char *rulestr,
const char *name;
filter_rule *excl_self;
if (!(excl_self = new0(filter_rule)))
out_of_memory("parse_filter_str");
excl_self = new0(filter_rule);
/* Find the beginning of the basename and add an exclude for it. */
for (name = pat + pat_len; name > pat && name[-1] != '/'; name--) {}
add_rule(listp, name, (pat + pat_len) - name, excl_self, 0);

View File

@@ -157,8 +157,6 @@ int write_file(int f, int use_seek, OFF_T offset, const char *buf, int len)
wf_writeBufSize = WRITE_SIZE * 8;
wf_writeBufCnt = 0;
wf_writeBuf = new_array(char, wf_writeBufSize);
if (!wf_writeBuf)
out_of_memory("write_file");
}
r1 = (int)MIN((size_t)len, wf_writeBufSize - wf_writeBufCnt);
if (r1) {
@@ -217,8 +215,7 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
{
struct map_struct *map;
if (!(map = new0(struct map_struct)))
out_of_memory("map_file");
map = new0(struct map_struct);
if (blk_size && (read_size % blk_size))
read_size += blk_size - (read_size % blk_size);
@@ -261,8 +258,6 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
/* make sure we have allocated enough memory for the window */
if (window_size > map->p_size) {
map->p = realloc_array(map->p, char, window_size);
if (!map->p)
out_of_memory("map_ptr");
map->p_size = window_size;
}

138
flist.c
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);
@@ -301,8 +303,7 @@ static void flist_expand(struct file_list *flist, int extra)
if (flist->malloced < flist->used + extra)
flist->malloced = flist->used + extra;
new_ptr = realloc_array(flist->files, struct file_struct *,
flist->malloced);
new_ptr = realloc_array(flist->files, struct file_struct *, flist->malloced);
if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
@@ -312,9 +313,6 @@ static void flist_expand(struct file_list *flist, int extra)
}
flist->files = new_ptr;
if (!flist->files)
out_of_memory("flist_expand");
}
static void flist_done_allocating(struct file_list *flist)
@@ -381,6 +379,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
int ndx, int first_ndx)
{
static time_t modtime, atime;
#ifdef SUPPORT_CRTIMES
static time_t crtime;
#endif
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
@@ -447,7 +448,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
if (protocol_version < 28)
xflags |= XMIT_SAME_RDEV_pre28;
else {
rdev = MAKEDEV(major(rdev), 0);
rdev = MAKEDEV(rdev_major, 0);
xflags |= XMIT_SAME_RDEV_MAJOR;
if (protocol_version < 30)
xflags |= XMIT_RDEV_MINOR_8_pre30;
@@ -486,6 +487,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
else
atime = F_ATIME(file);
}
#ifdef SUPPORT_CRTIMES
if (crtimes_ndx) {
crtime = F_CRTIME(file);
if (crtime == modtime)
xflags |= XMIT_CRTIME_EQ_MTIME;
}
#endif
#ifdef SUPPORT_HARD_LINKS
if (tmp_dev != -1) {
@@ -573,6 +581,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
}
if (xflags & XMIT_MOD_NSEC)
write_varint(f, F_MOD_NSEC(file));
#ifdef SUPPORT_CRTIMES
if (crtimes_ndx && !(xflags & XMIT_CRTIME_EQ_MTIME))
write_varlong(f, crtime, 4);
#endif
if (!(xflags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME))
@@ -665,6 +677,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
static struct file_struct *recv_file_entry(int f, struct file_list *flist, int xflags)
{
static int64 modtime, atime;
#ifdef SUPPORT_CRTIMES
static time_t crtime;
#endif
static mode_t mode;
#ifdef SUPPORT_HARD_LINKS
static int64 dev;
@@ -684,7 +699,9 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
int extra_len = file_extra_cnt * EXTRA_LEN;
int first_hlink_ndx = -1;
int64 file_length;
#ifdef CAN_SET_NSEC
uint32 modtime_nsec;
#endif
const char *basename;
struct file_struct *file;
alloc_pool_t *pool;
@@ -771,17 +788,24 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];
file_length = F_LENGTH(first);
modtime = first->modtime;
#ifdef CAN_SET_NSEC
modtime_nsec = F_MOD_NSEC_or_0(first);
#endif
mode = first->mode;
if (atimes_ndx && !S_ISDIR(mode))
atime = F_ATIME(first);
#ifdef SUPPORT_CRTIMES
if (crtimes_ndx)
crtime = F_CRTIME(first);
#endif
if (preserve_uid)
uid = F_OWNER(first);
if (preserve_gid)
gid = F_GROUP(first);
if (preserve_devices && IS_DEVICE(mode)) {
uint32 *devp = F_RDEV_P(first);
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
rdev_major = DEV_MAJOR(devp);
rdev = MAKEDEV(rdev_major, DEV_MINOR(devp));
extra_len += DEV_EXTRA_CNT * EXTRA_LEN;
}
if (preserve_links && S_ISLNK(mode))
@@ -808,9 +832,28 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
modtime = read_int(f);
}
if (xflags & XMIT_MOD_NSEC)
#ifndef CAN_SET_NSEC
(void)read_varint(f);
#else
modtime_nsec = read_varint(f);
else
modtime_nsec = 0;
#endif
#ifdef SUPPORT_CRTIMES
if (crtimes_ndx) {
if (xflags & XMIT_CRTIME_EQ_MTIME)
crtime = modtime;
else
crtime = read_varlong(f, 4);
#if SIZEOF_TIME_T < SIZEOF_INT64
if (!am_generator && (int64)(time_t)crtime != crtime) {
rprintf(FERROR_XFER,
"Create time value of %s truncated on receiver.\n",
lastname);
}
#endif
}
#endif
if (!(xflags & XMIT_SAME_MODE))
mode = from_wire_mode(read_int(f));
if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME)) {
@@ -992,6 +1035,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
}
if (atimes_ndx && !S_ISDIR(mode))
F_ATIME(file) = atime;
#ifdef SUPPORT_CRTIMES
if (crtimes_ndx)
F_CRTIME(file) = crtime;
#endif
if (unsort_ndx)
F_NDX(file) = flist->used + flist->ndx_start;
@@ -1335,10 +1382,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+ linkname_len;
if (pool)
bp = pool_alloc(pool, alloc_len, "make_file");
else {
if (!(bp = new_array(char, alloc_len)))
out_of_memory("make_file");
}
else
bp = new_array(char, alloc_len);
memset(bp, 0, extra_len + FILE_STRUCT_LEN);
bp += extra_len;
@@ -1391,6 +1436,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
file->flags |= FLAG_OWNED_BY_US;
if (atimes_ndx && !S_ISDIR(file->mode))
F_ATIME(file) = st.st_atime;
#ifdef SUPPORT_CRTIMES
if (crtimes_ndx)
F_CRTIME(file) = get_create_time(fname);
#endif
if (basename != thisname)
file->dirname = lastdir;
@@ -1661,8 +1710,7 @@ static void fsort(struct file_struct **fp, size_t num)
if (use_qsort)
qsort(fp, num, PTR_SIZE, file_compare);
else {
struct file_struct **tmp = new_array(struct file_struct *,
(num+1) / 2);
struct file_struct **tmp = new_array(struct file_struct *, (num+1) / 2);
fsort_tmp(fp, num, tmp);
free(tmp);
}
@@ -1895,13 +1943,11 @@ static void send_implied_dirs(int f, struct file_list *flist, char *fname,
len = strlen(limit+1);
memcpy(&relname_list, F_DIR_RELNAMES_P(lastpath_struct), sizeof relname_list);
if (!relname_list) {
if (!(relname_list = new0(item_list)))
out_of_memory("send_implied_dirs");
relname_list = new0(item_list);
memcpy(F_DIR_RELNAMES_P(lastpath_struct), &relname_list, sizeof relname_list);
}
rnpp = EXPAND_ITEM_LIST(relname_list, relnamecache *, 32);
if (!(*rnpp = (relnamecache*)new_array(char, sizeof (relnamecache) + len)))
out_of_memory("send_implied_dirs");
*rnpp = (relnamecache*)new_array(char, RELNAMECACHE_LEN + len + 1);
(*rnpp)->name_type = name_type;
strlcpy((*rnpp)->fname, limit+1, len + 1);
@@ -2059,10 +2105,8 @@ void send_extra_file_list(int f, int at_least)
}
if (need_unsorted_flist) {
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
out_of_memory("send_extra_file_list");
memcpy(flist->sorted, flist->files,
flist->used * sizeof (struct file_struct*));
flist->sorted = new_array(struct file_struct *, flist->used);
memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
} else
flist->sorted = flist->files;
@@ -2414,10 +2458,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
* recursion mode, the sender marks duplicate dirs so that it can
* send them together in a single file-list. */
if (need_unsorted_flist) {
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
out_of_memory("send_file_list");
memcpy(flist->sorted, flist->files,
flist->used * sizeof (struct file_struct*));
flist->sorted = new_array(struct file_struct *, flist->used);
memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
} else
flist->sorted = flist->files;
flist_sort_and_clean(flist, 0);
@@ -2425,7 +2467,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
file_old_total += flist->used;
if (numeric_ids <= 0 && !inc_recurse)
send_id_list(f);
send_id_lists(f);
/* send the io_error flag */
if (protocol_version < 30)
@@ -2597,10 +2639,8 @@ struct file_list *recv_file_list(int f, int dir_ndx)
* order and for calling flist_find()). We keep the "files"
* list unsorted for our exchange of index numbers with the
* other side (since their names may not sort the same). */
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
out_of_memory("recv_file_list");
memcpy(flist->sorted, flist->files,
flist->used * sizeof (struct file_struct*));
flist->sorted = new_array(struct file_struct *, flist->used);
memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
if (inc_recurse && dir_flist->used > dstart) {
static int dir_flist_malloced = 0;
if (dir_flist_malloced < dir_flist->malloced) {
@@ -2610,7 +2650,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
dir_flist_malloced = dir_flist->malloced;
}
memcpy(dir_flist->sorted + dstart, dir_flist->files + dstart,
(dir_flist->used - dstart) * sizeof (struct file_struct*));
(dir_flist->used - dstart) * PTR_SIZE);
fsort(dir_flist->sorted + dstart, dir_flist->used - dstart);
}
} else {
@@ -2742,28 +2782,28 @@ int flist_find(struct file_list *flist, struct file_struct *f)
* 1=match directories, 0=match non-directories, or -1=match either. */
int flist_find_name(struct file_list *flist, const char *fname, int want_dir_match)
{
struct { /* We have to create a temporary file_struct for the search. */
struct file_struct f;
char name_space[MAXPATHLEN];
} t;
static struct file_struct *f;
char fbuf[MAXPATHLEN];
const char *slash = strrchr(fname, '/');
const char *basename = slash ? slash+1 : fname;
memset(&t.f, 0, FILE_STRUCT_LEN);
memcpy((void *)t.f.basename, basename, strlen(basename)+1);
if (!f)
f = (struct file_struct*)new_array(char, FILE_STRUCT_LEN + MAXPATHLEN + 1);
memset(f, 0, FILE_STRUCT_LEN);
memcpy((void*)f->basename, basename, strlen(basename)+1);
if (slash) {
strlcpy(fbuf, fname, slash - fname + 1);
t.f.dirname = fbuf;
f->dirname = fbuf;
} else
t.f.dirname = NULL;
f->dirname = NULL;
t.f.mode = want_dir_match > 0 ? S_IFDIR : S_IFREG;
f->mode = want_dir_match > 0 ? S_IFDIR : S_IFREG;
if (want_dir_match < 0)
return flist_find_ignore_dirness(flist, &t.f);
return flist_find(flist, &t.f);
return flist_find_ignore_dirness(flist, f);
return flist_find(flist, f);
}
/* Search for an identically-named item in the file list. Differs from
@@ -2804,26 +2844,20 @@ void clear_file(struct file_struct *file)
}
/* Allocate a new file list. */
struct file_list *flist_new(int flags, char *msg)
static struct file_list *flist_new(int flags, const char *msg)
{
struct file_list *flist;
if (!(flist = new0(struct file_list)))
out_of_memory(msg);
flist = new0(struct file_list);
if (flags & FLIST_TEMP) {
if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0,
out_of_memory,
POOL_INTERN)))
if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0, _out_of_memory, POOL_INTERN)))
out_of_memory(msg);
} else {
/* This is a doubly linked list with prev looping back to
* the end of the list, but the last next pointer is NULL. */
if (!first_flist) {
flist->file_pool = pool_create(NORMAL_EXTENT, 0,
out_of_memory,
POOL_INTERN);
if (!flist->file_pool)
if (!(flist->file_pool = pool_create(NORMAL_EXTENT, 0, _out_of_memory, POOL_INTERN)))
out_of_memory(msg);
flist->ndx_start = flist->flist_num = inc_recurse ? 1 : 0;

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;
@@ -2227,8 +2256,6 @@ void generate_files(int f_out, const char *local_name)
if (delete_during == 2) {
deldelay_size = BIGPATHBUFLEN * 4;
deldelay_buf = new_array(char, deldelay_size);
if (!deldelay_buf)
out_of_memory("delete-delay");
}
info_levels[INFO_FLIST] = info_levels[INFO_PROGRESS] = 0;

View File

@@ -3,7 +3,7 @@
* `id -G` on Linux, but it's too hard to find a portable equivalent.
*
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2019 Wayne Davison
* Copyright (C) 2003-2020 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
@@ -20,8 +20,7 @@
#include "rsync.h"
int
main(UNUSED(int argc), UNUSED(char *argv[]))
int main(UNUSED(int argc), UNUSED(char *argv[]))
{
int n, i;
gid_t *list;

View File

@@ -35,9 +35,8 @@ struct hashtable *hashtable_create(int size, int key64)
size *= 2;
}
if (!(tbl = new(struct hashtable))
|| !(tbl->nodes = new_array0(char, size * node_size)))
out_of_memory("hashtable_create");
tbl = new(struct hashtable);
tbl->nodes = new_array0(char, size * node_size);
tbl->size = size;
tbl->entries = 0;
tbl->node_size = node_size;
@@ -94,8 +93,7 @@ void *hashtable_find(struct hashtable *tbl, int64 key, void *data_when_new)
int size = tbl->size * 2;
int i;
if (!(tbl->nodes = new_array0(char, size * tbl->node_size)))
out_of_memory("hashtable_node");
tbl->nodes = new_array0(char, size * tbl->node_size);
tbl->size = size;
tbl->entries = 0;

40
help-from-md.awk Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/awk -f
# The caller must pass args: -v hfile=help-NAME.h NAME.NUM.md
BEGIN {
heading = "/* DO NOT EDIT THIS FILE! It is auto-generated from the option list in " ARGV[1] "! */"
findcomment = hfile
sub("\\.", "\\.", findcomment)
findcomment = "\\[comment\\].*" findcomment
backtick_cnt = 0
prints = ""
}
/^```/ {
backtick_cnt++
next
}
foundcomment {
if (backtick_cnt > 1) exit
if (backtick_cnt == 1) {
gsub(/"/, "\\\"")
prints = prints "\n rprintf(F,\"" $0 "\\n\");"
}
next
}
$0 ~ findcomment {
foundcomment = 1
backtick_cnt = 0
}
END {
if (foundcomment && backtick_cnt > 1)
print heading "\n" prints > hfile
else {
print "Failed to find " hfile " section in " ARGV[1]
exit 1
}
}

View File

@@ -125,8 +125,7 @@ static void match_gnums(int32 *ndx_list, int ndx_count)
if (inc_recurse) {
node = hashtable_find(prior_hlinks, gnum, data_when_new);
if (node->data == data_when_new) {
if (!(node->data = new_array0(char, 5)))
out_of_memory("match_gnums");
node->data = new_array0(char, 5);
assert(gnum >= hlink_flist->ndx_start);
file->flags |= FLAG_HLINK_FIRST;
prev = -1;
@@ -190,8 +189,7 @@ void match_hard_links(struct file_list *flist)
int i, ndx_count = 0;
int32 *ndx_list;
if (!(ndx_list = new_array(int32, flist->used)))
out_of_memory("match_hard_links");
ndx_list = new_array(int32, flist->used);
for (i = 0; i < flist->used; i++) {
if (F_IS_HLINKED(flist->sorted[i]))
@@ -541,8 +539,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
exit_cleanup(RERR_MESSAGEIO);
}
free(node->data);
if (!(node->data = strdup(our_name)))
out_of_memory("finish_hard_link");
node->data = strdup(our_name);
}
}

View File

@@ -1,6 +1,6 @@
/* Inline functions for rsync.
*
* Copyright (C) 2007-2019 Wayne Davison
* Copyright (C) 2007-2020 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,8 +19,7 @@
static inline void
alloc_xbuf(xbuf *xb, size_t sz)
{
if (!(xb->buf = new_array(char, sz)))
out_of_memory("alloc_xbuf");
xb->buf = new_array(char, sz);
xb->size = sz;
xb->len = xb->pos = 0;
}
@@ -29,8 +28,6 @@ static inline void
realloc_xbuf(xbuf *xb, size_t sz)
{
char *bf = realloc_array(xb->buf, char, sz);
if (!bf)
out_of_memory("realloc_xbuf");
xb->buf = bf;
xb->size = sz;
}
@@ -104,3 +101,11 @@ free_stat_x(stat_x *sx_p)
}
#endif
}
static inline char *my_strdup(const char *str, const char *file, int line)
{
int len = strlen(str)+1;
char *buf = my_alloc(NULL, len, 1, file, line);
memcpy(buf, str, len);
return buf;
}

81
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;
@@ -251,8 +253,7 @@ static size_t safe_read(int fd, char *buf, size_t len)
cnt = select(fd+1, &r_fds, NULL, &e_fds, &tv);
if (cnt <= 0) {
if (cnt < 0 && errno == EBADF) {
rsyserr(FERROR, errno, "safe_read select failed [%s]",
who_am_i());
rsyserr(FERROR, errno, "safe_read select failed");
exit_cleanup(RERR_FILEIO);
}
check_timeout(1, MSK_ALLOW_FLUSH);
@@ -271,8 +272,7 @@ static size_t safe_read(int fd, char *buf, size_t len)
if (n < 0) {
if (errno == EINTR)
continue;
rsyserr(FERROR, errno, "safe_read failed to read %ld bytes [%s]",
(long)len, who_am_i());
rsyserr(FERROR, errno, "safe_read failed to read %ld bytes", (long)len);
exit_cleanup(RERR_STREAMIO);
}
if ((got += (size_t)n) == len)
@@ -315,8 +315,8 @@ static void safe_write(int fd, const char *buf, size_t len)
if (errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) {
write_failed:
rsyserr(FERROR, errno,
"safe_write failed to write %ld bytes to %s [%s]",
(long)len, what_fd_is(fd), who_am_i());
"safe_write failed to write %ld bytes to %s",
(long)len, what_fd_is(fd));
exit_cleanup(RERR_STREAMIO);
}
} else {
@@ -337,8 +337,7 @@ static void safe_write(int fd, const char *buf, size_t len)
cnt = select(fd + 1, NULL, &w_fds, NULL, &tv);
if (cnt <= 0) {
if (cnt < 0 && errno == EBADF) {
rsyserr(FERROR, errno, "safe_write select failed on %s [%s]",
what_fd_is(fd), who_am_i());
rsyserr(FERROR, errno, "safe_write select failed on %s", what_fd_is(fd));
exit_cleanup(RERR_FILEIO);
}
if (io_timeout)
@@ -466,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;
@@ -484,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;
@@ -568,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&" : "");
}
@@ -582,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
@@ -598,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
@@ -607,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;
@@ -665,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);
}
@@ -785,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;
@@ -815,12 +818,12 @@ static char *perform_io(size_t needed, int flags)
msgs2stderr = 1;
iobuf.out_fd = -2;
iobuf.out.len = iobuf.msg.len = iobuf.raw_flushing_ends_before = 0;
rsyserr(FERROR_SOCKET, errno, "[%s] write error", who_am_i());
rsyserr(FERROR_SOCKET, errno, "write error");
drain_multiplex_messages();
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);
}
@@ -915,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;
@@ -933,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;
@@ -1242,8 +1249,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
rl_flags |= (protect_args && ic_recv != (iconv_t)-1 ? RL_CONVERT : 0);
#endif
if (!(argv = new_array(char *, maxargs)))
out_of_memory("read_args");
argv = new_array(char *, maxargs);
if (mod_name && !protect_args)
argv[argc++] = "rsyncd";
@@ -1256,8 +1262,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
if (argc == maxargs-1) {
maxargs += MAX_ARGS;
if (!(argv = realloc_array(argv, char *, maxargs)))
out_of_memory("read_args");
argv = realloc_array(argv, char *, maxargs);
}
if (dot_pos) {
@@ -1265,8 +1270,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
int len = strlen(buf);
if (request_len)
request_p[0][request_len++] = ' ';
if (!(*request_p = realloc_array(*request_p, char, request_len + len + 1)))
out_of_memory("read_args");
*request_p = realloc_array(*request_p, char, request_len + len + 1);
memcpy(*request_p + request_len, buf, len + 1);
request_len += len;
}
@@ -1275,8 +1279,7 @@ void read_args(int f_in, char *mod_name, char *buf, size_t bufsiz, int rl_nulls,
else
glob_expand(buf, &argv, &argc, &maxargs);
} else {
if (!(p = strdup(buf)))
out_of_memory("read_args");
p = strdup(buf);
argv[argc++] = p;
if (*p == '.' && p[1] == '\0')
dot_pos = argc;
@@ -1292,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) {
@@ -1311,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) {
@@ -1330,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");
}
@@ -1345,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");
}
@@ -1433,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) {
@@ -2305,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)
@@ -2322,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 */
@@ -2333,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;
@@ -2351,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;

17
lib/md-defines.h Normal file
View File

@@ -0,0 +1,17 @@
/* Keep this simple so both C and ASM can use it */
#define MD4_DIGEST_LEN 16
#define MD5_DIGEST_LEN 16
#define MAX_DIGEST_LEN MD5_DIGEST_LEN
#define CSUM_CHUNK 64
#define CSUM_NONE 0
#define CSUM_MD4_ARCHAIC 1
#define CSUM_MD4_BUSTED 2
#define CSUM_MD4_OLD 3
#define CSUM_MD4 4
#define CSUM_MD5 5
#define CSUM_XXH64 6
#define CSUM_XXH3_64 7
#define CSUM_XXH3_128 8

View File

@@ -24,11 +24,19 @@
* show any significant difference in performance, though.
*/
#include "config.h"
#include "md-defines.h"
#if !defined USE_OPENSSL && CSUM_CHUNK == 64
#ifdef __APPLE__
#define md5_process_asm _md5_process_asm
#endif
.text
.align 16
.globl md5_process_asm
.type md5_process_asm,@function
md5_process_asm:
push %rbp
push %rbx
@@ -689,5 +697,5 @@ md5_process_asm:
pop %rbx
pop %rbp
ret
.L_md5_process_asm_end:
.size md5_process_asm,.L_md5_process_asm_end-md5_process_asm
#endif /* !USE_OPENSSL ... */

View File

@@ -148,7 +148,7 @@ static void md5_process(md_context *ctx, const uchar data[CSUM_CHUNK])
ctx->D += D;
}
#if defined(HAVE_SIMD) && (CSUM_CHUNK == 64)
#if defined HAVE_ASM && CSUM_CHUNK == 64
extern void md5_process_asm(md_context *ctx, const void *data, size_t num);
#endif
@@ -176,7 +176,7 @@ void md5_update(md_context *ctx, const uchar *input, uint32 length)
left = 0;
}
#if defined(HAVE_SIMD) && (CSUM_CHUNK == 64)
#if defined HAVE_ASM && CSUM_CHUNK == 64
if (length >= CSUM_CHUNK) {
uint32 chunks = length / CSUM_CHUNK;
md5_process_asm(ctx, input, chunks);

View File

@@ -4,20 +4,7 @@
#include "openssl/md4.h"
#include "openssl/md5.h"
#endif
#define MD4_DIGEST_LEN 16
#define MD5_DIGEST_LEN 16
#define MAX_DIGEST_LEN MD5_DIGEST_LEN
#define CSUM_CHUNK 64
#define CSUM_NONE 0
#define CSUM_MD4_ARCHAIC 1
#define CSUM_MD4_BUSTED 2
#define CSUM_MD4_OLD 3
#define CSUM_MD4 4
#define CSUM_MD5 5
#define CSUM_XXH64 6
#include "md-defines.h"
typedef struct {
uint32 A, B, C, D;

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

@@ -1,9 +1,9 @@
#ifdef SUPPORT_XATTRS
#if defined HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#elif defined HAVE_SYS_XATTR_H
#if defined HAVE_SYS_XATTR_H
#include <sys/xattr.h>
#elif defined HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#elif defined HAVE_SYS_EXTATTR_H
#include <sys/extattr.h>
#endif

View File

@@ -42,24 +42,20 @@
#include "rsync.h"
#include "itypes.h"
#include "ifuncs.h"
#include "default-dont-compress.h"
extern item_list dparam_list;
#define strequal(a, b) (strcasecmp(a, b)==0)
#define BOOLSTR(b) ((b) ? "Yes" : "No")
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
#endif
#define DEFAULT_DONT_COMPRESS "*.gz *.zip *.z *.rpm *.deb *.iso *.bz2" \
" *.t[gb]z *.7z *.mp[34] *.mov *.avi *.ogg *.jpg *.jpeg *.png" \
" *.lzo *.rzip *.lzma *.rar *.ace *.gpg *.xz *.txz *.lz *.tlz" \
" *.ogv *.web[mp] *.squashfs"
/* the following are used by loadparm for option lists */
typedef enum {
P_BOOL, P_BOOLREV, P_CHAR, P_INTEGER,
P_BOOL, P_BOOLREV, P_BOOL3, P_CHAR, P_INTEGER,
P_OCTAL, P_PATH, P_STRING, P_ENUM
} parm_type;
@@ -90,234 +86,6 @@ struct parm_struct {
#define LP_SNUM_OK(i) ((i) >= 0 && (i) < (int)section_list.count)
#define SECTION_PTR(s, p) (((char*)(s)) + (ptrdiff_t)(((char*)(p))-(char*)&Vars.l))
/* This structure describes global (ie., server-wide) parameters. */
typedef struct {
char *bind_address;
char *daemon_chroot;
char *daemon_gid;
char *daemon_uid;
char *motd_file;
char *pid_file;
char *socket_options;
/* Each _EXP var tracks if the associated char* var has been expanded yet or not. */
BOOL bind_address_EXP;
BOOL daemon_chroot_EXP;
BOOL daemon_gid_EXP;
BOOL daemon_uid_EXP;
BOOL motd_file_EXP;
BOOL pid_file_EXP;
BOOL socket_options_EXP;
int listen_backlog;
int rsync_port;
BOOL haproxy_header;
} global_vars;
/* This structure describes a single section. Their order must match the
* initializers below, which you can accomplish by keeping each sub-section
* sorted. (e.g. in vim, just visually select each subsection and use !sort.)
* NOTE: the char* variables MUST all remain at the start of the struct! */
typedef struct {
char *auth_users;
char *charset;
char *comment;
char *dont_compress;
char *early_exec;
char *exclude;
char *exclude_from;
char *filter;
char *gid;
char *hosts_allow;
char *hosts_deny;
char *include;
char *include_from;
char *incoming_chmod;
char *lock_file;
char *log_file;
char *log_format;
char *name;
char *outgoing_chmod;
char *path;
char *postxfer_exec;
char *prexfer_exec;
char *refuse_options;
char *secrets_file;
char *syslog_tag;
char *temp_dir;
char *uid;
/* Each _EXP var tracks if the associated char* var has been expanded yet or not. */
BOOL auth_users_EXP;
BOOL charset_EXP;
BOOL comment_EXP;
BOOL dont_compress_EXP;
BOOL early_exec_EXP;
BOOL exclude_EXP;
BOOL exclude_from_EXP;
BOOL filter_EXP;
BOOL gid_EXP;
BOOL hosts_allow_EXP;
BOOL hosts_deny_EXP;
BOOL include_EXP;
BOOL include_from_EXP;
BOOL incoming_chmod_EXP;
BOOL lock_file_EXP;
BOOL log_file_EXP;
BOOL log_format_EXP;
BOOL name_EXP;
BOOL outgoing_chmod_EXP;
BOOL path_EXP;
BOOL postxfer_exec_EXP;
BOOL prexfer_exec_EXP;
BOOL refuse_options_EXP;
BOOL secrets_file_EXP;
BOOL syslog_tag_EXP;
BOOL temp_dir_EXP;
BOOL uid_EXP;
int max_connections;
int max_verbosity;
int syslog_facility;
int timeout;
BOOL fake_super;
BOOL forward_lookup;
BOOL ignore_errors;
BOOL ignore_nonreadable;
BOOL list;
BOOL munge_symlinks;
BOOL numeric_ids;
BOOL read_only;
BOOL reverse_lookup;
BOOL strict_modes;
BOOL transfer_logging;
BOOL use_chroot;
BOOL write_only;
} local_vars;
/* This structure describes the global variables (g) as well as the globally
* specified values of the local variables (l), which are used when modules
* don't specify their own values. */
typedef struct {
global_vars g;
local_vars l;
} all_vars;
/* The application defaults for all the variables. "Defaults" is
* used to re-initialize "Vars" before each config-file read.
*
* In order to keep these sorted in the same way as the structure
* above, use the variable name in the leading comment, including a
* trailing ';' (to avoid a sorting problem with trailing digits). */
static const all_vars Defaults = {
/* ==== global_vars ==== */
{
/* bind_address; */ NULL,
/* daemon_chroot; */ NULL,
/* daemon_gid; */ NULL,
/* daemon_uid; */ NULL,
/* motd_file; */ NULL,
/* pid_file; */ NULL,
/* socket_options; */ NULL,
/* bind_address_EXP; */ False,
/* daemon_chroot_EXP; */ False,
/* daemon_gid_EXP; */ False,
/* daemon_uid_EXP; */ False,
/* motd_file_EXP; */ False,
/* pid_file_EXP; */ False,
/* socket_options_EXP; */ False,
/* listen_backlog; */ 5,
/* rsync_port; */ 0,
/* haproxy_header; */ False,
},
/* ==== local_vars ==== */
{
/* auth_users; */ NULL,
/* charset; */ NULL,
/* comment; */ NULL,
/* dont_compress; */ DEFAULT_DONT_COMPRESS,
/* early_exec; */ NULL,
/* exclude; */ NULL,
/* exclude_from; */ NULL,
/* filter; */ NULL,
/* gid; */ NULL,
/* hosts_allow; */ NULL,
/* hosts_deny; */ NULL,
/* include; */ NULL,
/* include_from; */ NULL,
/* incoming_chmod; */ NULL,
/* lock_file; */ DEFAULT_LOCK_FILE,
/* log_file; */ NULL,
/* log_format; */ "%o %h [%a] %m (%u) %f %l",
/* name; */ NULL,
/* outgoing_chmod; */ NULL,
/* path; */ NULL,
/* postxfer_exec; */ NULL,
/* prexfer_exec; */ NULL,
/* refuse_options; */ NULL,
/* secrets_file; */ NULL,
/* syslog_tag; */ "rsyncd",
/* temp_dir; */ NULL,
/* uid; */ NULL,
/* auth_users_EXP; */ False,
/* charset_EXP; */ False,
/* comment_EXP; */ False,
/* dont_compress_EXP; */ False,
/* early_exec_EXP; */ False,
/* exclude_EXP; */ False,
/* exclude_from_EXP; */ False,
/* filter_EXP; */ False,
/* gid_EXP; */ False,
/* hosts_allow_EXP; */ False,
/* hosts_deny_EXP; */ False,
/* include_EXP; */ False,
/* include_from_EXP; */ False,
/* incoming_chmod_EXP; */ False,
/* lock_file_EXP; */ False,
/* log_file_EXP; */ False,
/* log_format_EXP; */ False,
/* name_EXP; */ False,
/* outgoing_chmod_EXP; */ False,
/* path_EXP; */ False,
/* postxfer_exec_EXP; */ False,
/* prexfer_exec_EXP; */ False,
/* refuse_options_EXP; */ False,
/* secrets_file_EXP; */ False,
/* syslog_tag_EXP; */ False,
/* temp_dir_EXP; */ False,
/* uid_EXP; */ False,
/* max_connections; */ 0,
/* max_verbosity; */ 1,
/* syslog_facility; */ LOG_DAEMON,
/* timeout; */ 0,
/* fake_super; */ False,
/* forward_lookup; */ True,
/* ignore_errors; */ False,
/* ignore_nonreadable; */ False,
/* list; */ True,
/* munge_symlinks; */ (BOOL)-1,
/* numeric_ids; */ (BOOL)-1,
/* read_only; */ True,
/* reverse_lookup; */ True,
/* strict_modes; */ True,
/* transfer_logging; */ False,
/* use_chroot; */ True,
/* write_only; */ False,
}
};
/* The currently configured values for all the variables. */
static all_vars Vars;
/* Stack of "Vars" values used by the &include directive. */
static item_list Vars_stack = EMPTY_ITEM_LIST;
@@ -327,9 +95,7 @@ static item_list section_list = EMPTY_ITEM_LIST;
static int iSectionIndex = -1;
static BOOL bInGlobalSection = True;
#define NUMPARAMETERS (sizeof (parm_table) / sizeof (struct parm_struct))
static struct enum_list enum_facilities[] = {
static struct enum_list enum_syslog_facility[] = {
#ifdef LOG_AUTH
{ LOG_AUTH, "auth" },
#endif
@@ -396,96 +162,27 @@ static struct enum_list enum_facilities[] = {
{ -1, NULL }
};
static struct parm_struct parm_table[] =
{
{"address", P_STRING, P_GLOBAL,&Vars.g.bind_address, NULL,0},
{"daemon chroot", P_STRING, P_GLOBAL,&Vars.g.daemon_chroot, NULL,0},
{"daemon gid", P_STRING, P_GLOBAL,&Vars.g.daemon_gid, NULL,0},
{"daemon uid", P_STRING, P_GLOBAL,&Vars.g.daemon_uid, NULL,0},
{"listen backlog", P_INTEGER,P_GLOBAL,&Vars.g.listen_backlog, NULL,0},
{"motd file", P_STRING, P_GLOBAL,&Vars.g.motd_file, NULL,0},
{"pid file", P_STRING, P_GLOBAL,&Vars.g.pid_file, NULL,0},
{"port", P_INTEGER,P_GLOBAL,&Vars.g.rsync_port, NULL,0},
{"socket options", P_STRING, P_GLOBAL,&Vars.g.socket_options, NULL,0},
{"haproxy header", P_BOOL, P_LOCAL, &Vars.g.haproxy_header, NULL,0},
{"auth users", P_STRING, P_LOCAL, &Vars.l.auth_users, NULL,0},
{"charset", P_STRING, P_LOCAL, &Vars.l.charset, NULL,0},
{"comment", P_STRING, P_LOCAL, &Vars.l.comment, NULL,0},
{"dont compress", P_STRING, P_LOCAL, &Vars.l.dont_compress, NULL,0},
{"early exec", P_STRING, P_LOCAL, &Vars.l.early_exec, NULL,0},
{"exclude from", P_STRING, P_LOCAL, &Vars.l.exclude_from, NULL,0},
{"exclude", P_STRING, P_LOCAL, &Vars.l.exclude, NULL,0},
{"fake super", P_BOOL, P_LOCAL, &Vars.l.fake_super, NULL,0},
{"filter", P_STRING, P_LOCAL, &Vars.l.filter, NULL,0},
{"forward lookup", P_BOOL, P_LOCAL, &Vars.l.forward_lookup, NULL,0},
{"gid", P_STRING, P_LOCAL, &Vars.l.gid, NULL,0},
{"hosts allow", P_STRING, P_LOCAL, &Vars.l.hosts_allow, NULL,0},
{"hosts deny", P_STRING, P_LOCAL, &Vars.l.hosts_deny, NULL,0},
{"ignore errors", P_BOOL, P_LOCAL, &Vars.l.ignore_errors, NULL,0},
{"ignore nonreadable",P_BOOL, P_LOCAL, &Vars.l.ignore_nonreadable, NULL,0},
{"include from", P_STRING, P_LOCAL, &Vars.l.include_from, NULL,0},
{"include", P_STRING, P_LOCAL, &Vars.l.include, NULL,0},
{"incoming chmod", P_STRING, P_LOCAL, &Vars.l.incoming_chmod, NULL,0},
{"list", P_BOOL, P_LOCAL, &Vars.l.list, NULL,0},
{"lock file", P_STRING, P_LOCAL, &Vars.l.lock_file, NULL,0},
{"log file", P_STRING, P_LOCAL, &Vars.l.log_file, NULL,0},
{"log format", P_STRING, P_LOCAL, &Vars.l.log_format, NULL,0},
{"max connections", P_INTEGER,P_LOCAL, &Vars.l.max_connections, NULL,0},
{"max verbosity", P_INTEGER,P_LOCAL, &Vars.l.max_verbosity, NULL,0},
{"munge symlinks", P_BOOL, P_LOCAL, &Vars.l.munge_symlinks, NULL,0},
{"name", P_STRING, P_LOCAL, &Vars.l.name, NULL,0},
{"numeric ids", P_BOOL, P_LOCAL, &Vars.l.numeric_ids, NULL,0},
{"outgoing chmod", P_STRING, P_LOCAL, &Vars.l.outgoing_chmod, NULL,0},
{"path", P_PATH, P_LOCAL, &Vars.l.path, NULL,0},
#ifdef HAVE_PUTENV
{"post-xfer exec", P_STRING, P_LOCAL, &Vars.l.postxfer_exec, NULL,0},
{"pre-xfer exec", P_STRING, P_LOCAL, &Vars.l.prexfer_exec, NULL,0},
#endif
{"read only", P_BOOL, P_LOCAL, &Vars.l.read_only, NULL,0},
{"refuse options", P_STRING, P_LOCAL, &Vars.l.refuse_options, NULL,0},
{"reverse lookup", P_BOOL, P_LOCAL, &Vars.l.reverse_lookup, NULL,0},
{"secrets file", P_STRING, P_LOCAL, &Vars.l.secrets_file, NULL,0},
{"strict modes", P_BOOL, P_LOCAL, &Vars.l.strict_modes, NULL,0},
{"syslog facility", P_ENUM, P_LOCAL, &Vars.l.syslog_facility, enum_facilities,0},
{"syslog tag", P_STRING, P_LOCAL, &Vars.l.syslog_tag, NULL,0},
{"temp dir", P_PATH, P_LOCAL, &Vars.l.temp_dir, NULL,0},
{"timeout", P_INTEGER,P_LOCAL, &Vars.l.timeout, NULL,0},
{"transfer logging", P_BOOL, P_LOCAL, &Vars.l.transfer_logging, NULL,0},
{"uid", P_STRING, P_LOCAL, &Vars.l.uid, NULL,0},
{"use chroot", P_BOOL, P_LOCAL, &Vars.l.use_chroot, NULL,0},
{"write only", P_BOOL, P_LOCAL, &Vars.l.write_only, NULL,0},
{NULL, P_BOOL, P_NONE, NULL, NULL,0}
};
/* Initialise the Default all_vars structure. */
void reset_daemon_vars(void)
{
memcpy(&Vars, &Defaults, sizeof Vars);
}
/* Expand %VAR% references. Any unknown vars or unrecognized
* syntax leaves the raw chars unchanged. */
static char *expand_vars(char *str)
static char *expand_vars(const char *str)
{
char *buf, *t, *f;
char *buf, *t;
const char *f;
int bufsize;
if (!str || !strchr(str, '%'))
return str;
return (char *)str; /* TODO change return value to const char* at some point. */
bufsize = strlen(str) + 2048;
if ((buf = new_array(char, bufsize+1)) == NULL) /* +1 for trailing '\0' */
out_of_memory("expand_vars");
buf = new_array(char, bufsize+1); /* +1 for trailing '\0' */
for (t = buf, f = str; bufsize && *f; ) {
if (*f == '%' && *++f != '%') {
char *percent = strchr(f, '%');
if (percent) {
if (*f == '%' && isUpper(f+1)) {
char *percent = strchr(f+1, '%');
if (percent && percent - f < bufsize) {
char *val;
*percent = '\0';
val = getenv(f);
*percent = '%';
strlcpy(t, f+1, percent - f);
val = getenv(t);
if (val) {
int len = strlcpy(t, val, bufsize+1);
if (len > bufsize)
@@ -496,7 +193,6 @@ static char *expand_vars(char *str)
continue;
}
}
f--;
}
*t++ = *f++;
bufsize--;
@@ -514,6 +210,8 @@ static char *expand_vars(char *str)
return buf;
}
/* Each "char* foo" has an associated "BOOL foo_EXP" that tracks if the string has been expanded yet or not. */
/* NOTE: use this function and all the FN_{GLOBAL,LOCAL} ones WITHOUT a trailing semicolon! */
#define RETURN_EXPANDED(val) {if (!val ## _EXP) {val = expand_vars(val); val ## _EXP = True;} return val ? val : "";}
@@ -538,65 +236,24 @@ static char *expand_vars(char *str)
#define FN_LOCAL_INTEGER(fn_name, val) \
int fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.val;}
FN_GLOBAL_STRING(lp_bind_address, bind_address)
FN_GLOBAL_STRING(lp_daemon_chroot, daemon_chroot)
FN_GLOBAL_STRING(lp_daemon_gid, daemon_gid)
FN_GLOBAL_STRING(lp_daemon_uid, daemon_uid)
FN_GLOBAL_STRING(lp_motd_file, motd_file)
FN_GLOBAL_STRING(lp_pid_file, pid_file)
FN_GLOBAL_STRING(lp_socket_options, socket_options)
/* The following include file contains:
*
* typedef global_vars - describes global (ie., server-wide) parameters.
* typedef local_vars - describes a single section.
* typedef all_vars - a combination of global_vars & local_vars.
* all_vars Defaults - the default values for all the variables.
* all_vars Vars - the currently configured values for all the variables.
* struct parm_struct parm_table - the strings & variables for the parser.
* FN_{LOCAL,GLOBAL}_{TYPE}() definition for all the lp_var_name() accessors.
*/
FN_GLOBAL_INTEGER(lp_listen_backlog, listen_backlog)
FN_GLOBAL_INTEGER(lp_rsync_port, rsync_port)
#include "daemon-parm.h"
FN_GLOBAL_BOOL(lp_haproxy_header, haproxy_header)
FN_LOCAL_STRING(lp_auth_users, auth_users)
FN_LOCAL_STRING(lp_charset, charset)
FN_LOCAL_STRING(lp_comment, comment)
FN_LOCAL_STRING(lp_dont_compress, dont_compress)
FN_LOCAL_STRING(lp_early_exec, early_exec)
FN_LOCAL_STRING(lp_exclude, exclude)
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
FN_LOCAL_STRING(lp_filter, filter)
FN_LOCAL_STRING(lp_gid, gid)
FN_LOCAL_STRING(lp_hosts_allow, hosts_allow)
FN_LOCAL_STRING(lp_hosts_deny, hosts_deny)
FN_LOCAL_STRING(lp_include, include)
FN_LOCAL_STRING(lp_include_from, include_from)
FN_LOCAL_STRING(lp_incoming_chmod, incoming_chmod)
FN_LOCAL_STRING(lp_lock_file, lock_file)
FN_LOCAL_STRING(lp_log_file, log_file)
FN_LOCAL_STRING(lp_log_format, log_format)
FN_LOCAL_STRING(lp_name, name)
FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
FN_LOCAL_STRING(lp_path, path)
FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
FN_LOCAL_STRING(lp_refuse_options, refuse_options)
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
FN_LOCAL_STRING(lp_syslog_tag, syslog_tag)
FN_LOCAL_STRING(lp_temp_dir, temp_dir)
FN_LOCAL_STRING(lp_uid, uid)
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility)
FN_LOCAL_INTEGER(lp_timeout, timeout)
FN_LOCAL_BOOL(lp_fake_super, fake_super)
FN_LOCAL_BOOL(lp_forward_lookup, forward_lookup)
FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
FN_LOCAL_BOOL(lp_list, list)
FN_LOCAL_BOOL(lp_munge_symlinks, munge_symlinks)
FN_LOCAL_BOOL(lp_numeric_ids, numeric_ids)
FN_LOCAL_BOOL(lp_read_only, read_only)
FN_LOCAL_BOOL(lp_reverse_lookup, reverse_lookup)
FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
FN_LOCAL_BOOL(lp_write_only, write_only)
/* Initialise the Default all_vars structure. */
void reset_daemon_vars(void)
{
memcpy(&Vars, &Defaults, sizeof Vars);
}
/* Assign a copy of v to *s. Handles NULL strings. We don't worry
* about overwriting a malloc'd string because the long-running
@@ -605,10 +262,7 @@ FN_LOCAL_BOOL(lp_write_only, write_only)
* the start, so any lost memory is inconsequential. */
static inline void string_set(char **s, const char *v)
{
if (!v)
*s = NULL;
else if (!(*s = strdup(v)))
out_of_memory("string_set");
*s = v ? strdup(v) : NULL;
}
/* Copy local_vars into a new section. No need to strdup since we don't free. */
@@ -624,19 +278,14 @@ static void init_section(local_vars *psection)
copy_section(psection, &Vars.l);
}
/* Do a case-insensitive, whitespace-ignoring string compare. */
static int strwicmp(char *psz1, char *psz2)
/* Do a case-insensitive, whitespace-ignoring string equality check. */
static int strwiEQ(char *psz1, char *psz2)
{
/* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
/* appropriate value. */
/* If one or both strings are NULL, we return equality right away. */
if (psz1 == psz2)
return 0;
if (psz1 == NULL)
return -1;
if (psz2 == NULL)
return 1;
if (psz1 == NULL || psz2 == NULL)
return 0;
/* sync the strings on first non-whitespace */
while (1) {
@@ -644,12 +293,14 @@ static int strwicmp(char *psz1, char *psz2)
psz1++;
while (isSpace(psz2))
psz2++;
if (toUpper(psz1) != toUpper(psz2) || *psz1 == '\0' || *psz2 == '\0')
if (*psz1 == '\0' || *psz2 == '\0')
break;
if (toUpper(psz1) != toUpper(psz2))
break;
psz1++;
psz2++;
}
return *psz1 - *psz2;
return *psz1 == *psz2;
}
/* Find a section by name. Otherwise works like get_section. */
@@ -658,7 +309,7 @@ static int getsectionbyname(char *name)
int i;
for (i = section_list.count - 1; i >= 0; i--) {
if (strwicmp(iSECTION(i).name, name) == 0)
if (strwiEQ(iSECTION(i).name, name))
break;
}
@@ -698,7 +349,7 @@ static int map_parameter(char *parmname)
return -1;
for (iIndex = 0; parm_table[iIndex].label; iIndex++) {
if (strwicmp(parm_table[iIndex].label, parmname) == 0)
if (strwiEQ(parm_table[iIndex].label, parmname))
return iIndex;
}
@@ -709,16 +360,14 @@ static int map_parameter(char *parmname)
/* Set a boolean variable from the text value stored in the passed string.
* Returns True in success, False if the passed string does not correctly
* represent a boolean. */
static BOOL set_boolean(BOOL *pb, char *parmvalue)
static BOOL set_boolean(BOOL *pb, char *parmvalue, int allow_unset)
{
if (strwicmp(parmvalue, "yes") == 0
|| strwicmp(parmvalue, "true") == 0
|| strwicmp(parmvalue, "1") == 0)
if (strwiEQ(parmvalue, "yes") || strwiEQ(parmvalue, "true") || strwiEQ(parmvalue, "1"))
*pb = True;
else if (strwicmp(parmvalue, "no") == 0
|| strwicmp(parmvalue, "False") == 0
|| strwicmp(parmvalue, "0") == 0)
else if (strwiEQ(parmvalue, "no") || strwiEQ(parmvalue, "false") || strwiEQ(parmvalue, "0"))
*pb = False;
else if (allow_unset && (strwiEQ(parmvalue, "unset") || strwiEQ(parmvalue, "-1")))
*pb = Unset;
else {
rprintf(FLOG, "Badly formed boolean in configuration file: \"%s\".\n", parmvalue);
return False;
@@ -767,11 +416,15 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
switch (parm_table[parmnum].type) {
case P_BOOL:
set_boolean(parm_ptr, parmvalue);
set_boolean(parm_ptr, parmvalue, False);
break;
case P_BOOL3:
set_boolean(parm_ptr, parmvalue, True);
break;
case P_BOOLREV:
set_boolean(parm_ptr, parmvalue);
set_boolean(parm_ptr, parmvalue, False);
*(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
break;
@@ -841,7 +494,7 @@ static BOOL do_section(char *sectionname)
return True;
}
isglobal = strwicmp(sectionname, GLOBAL_NAME) == 0;
isglobal = strwiEQ(sectionname, GLOBAL_NAME);
/* At the end of the global section, add any --dparam items. */
if (bInGlobalSection && !isglobal) {

36
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
@@ -318,16 +318,16 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
if (quiet)
return;
break;
//case FLOG:
//case FCLIENT:
//case FERROR_UTF8:
//case FERROR_SOCKET:
/*case FLOG:*/
/*case FCLIENT:*/
/*case FERROR_UTF8:*/
/*case FERROR_SOCKET:*/
default:
fprintf(stderr, "Bad logcode in rwrite(): %d [%s]\n", (int)code, who_am_i());
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
@@ -452,8 +456,7 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
char buf[BIGPATHBUFLEN];
size_t len;
strlcpy(buf, RSYNC_NAME ": ", sizeof buf);
len = (sizeof RSYNC_NAME ": ") - 1;
len = snprintf(buf, sizeof buf, RSYNC_NAME ": [%s] ", who_am_i());
va_start(ap, format);
len += vsnprintf(buf + len, sizeof buf - len, format, ap);
@@ -717,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';
@@ -887,10 +891,10 @@ void log_exit(int code, const char *file, int line)
/* VANISHED is not an error, only a warning */
if (code == RERR_VANISHED) {
rprintf(FWARNING, "rsync warning: %s (code %d) at %s(%d) [%s=%s]\n",
name, code, file, line, who_am_i(), RSYNC_VERSION);
name, code, src_file(file), line, who_am_i(), rsync_version());
} else {
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s=%s]\n",
name, code, file, line, who_am_i(), RSYNC_VERSION);
name, code, src_file(file), line, who_am_i(), rsync_version());
}
}
}

123
main.c
View File

@@ -22,11 +22,15 @@
#include "rsync.h"
#include "inums.h"
#include "ifuncs.h"
#include "io.h"
#if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
#include <locale.h>
#endif
#include <popt.h>
#ifdef __TANDEM
#include <floss.h(floss_execlp)>
#endif
extern int dry_run;
extern int list_only;
@@ -53,6 +57,7 @@ extern int copy_unsafe_links;
extern int keep_dirlinks;
extern int preserve_hard_links;
extern int protocol_version;
extern int mkpath_dest_arg;
extern int file_total;
extern int recurse;
extern int xfer_dirs;
@@ -92,6 +97,7 @@ extern char *shell_cmd;
extern char *password_file;
extern char *backup_dir;
extern char *copy_as;
extern char *tmpdir;
extern char curr_dir[MAXPATHLEN];
extern char backup_dir_buf[MAXPATHLEN];
extern char *basis_dir[MAX_BASIS_DIRS+1];
@@ -103,7 +109,7 @@ gid_t our_gid;
int am_receiver = 0; /* Only set to 1 after the receiver/generator fork. */
int am_generator = 0; /* Only set to 1 after the receiver/generator fork. */
int local_server = 0;
int daemon_over_rsh = 0;
int daemon_connection = 0; /* 0 = no daemon, 1 = daemon via remote shell, -1 = daemon via socket */
mode_t orig_umask = 0;
int batch_gen_fd = -1;
int sender_keeps_checksum = 0;
@@ -298,7 +304,7 @@ static void become_copy_as_user()
our_uid = MY_UID();
our_gid = MY_GID();
am_root = (our_uid == 0);
am_root = (our_uid == ROOT_UID);
if (gname)
gname[-1] = ':';
@@ -512,8 +518,6 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
if (!cmd)
cmd = RSYNC_RSH;
cmd = need_to_free = strdup(cmd);
if (!cmd)
goto oom;
for (t = f = cmd; *f; f++) {
if (*f == ' ')
@@ -563,12 +567,12 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
#ifdef HAVE_REMSH
/* remsh (on HPUX) takes the arguments the other way around */
args[argc++] = machine;
if (user && !(daemon_over_rsh && dash_l_set)) {
if (user && !(daemon_connection && dash_l_set)) {
args[argc++] = "-l";
args[argc++] = user;
}
#else
if (user && !(daemon_over_rsh && dash_l_set)) {
if (user && !(daemon_connection && dash_l_set)) {
args[argc++] = "-l";
args[argc++] = user;
}
@@ -588,7 +592,11 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
if (blocking_io < 0 && (strcmp(t, "rsh") == 0 || strcmp(t, "remsh") == 0))
blocking_io = 1;
server_options(args, &argc);
if (daemon_connection > 0) {
args[argc++] = "--server";
args[argc++] = "--daemon";
} else
server_options(args, &argc);
if (argc >= MAX_ARGS - 2)
goto arg_overflow;
@@ -596,7 +604,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
args[argc++] = ".";
if (!daemon_over_rsh) {
if (!daemon_connection) {
while (remote_argc > 0) {
if (argc >= MAX_ARGS - 1) {
arg_overflow:
@@ -649,7 +657,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
#ifdef ICONV_CONST
setup_iconv();
#endif
if (protect_args && !daemon_over_rsh)
if (protect_args && !daemon_connection)
send_protected_args(*f_out_p, args);
}
@@ -657,10 +665,6 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
free(need_to_free);
return pid;
oom:
out_of_memory("do_cmd");
return 0; /* not reached */
}
/* The receiving side operates in one of two modes:
@@ -679,7 +683,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
static char *get_local_name(struct file_list *flist, char *dest_path)
{
STRUCT_STAT st;
int statret;
int statret, trailing_slash;
char *cp;
if (DEBUG_GTE(RECV, 1)) {
@@ -712,7 +716,26 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
}
/* See what currently exists at the destination. */
if ((statret = do_stat(dest_path, &st)) == 0) {
statret = do_stat(dest_path, &st);
cp = strrchr(dest_path, '/');
trailing_slash = cp && !cp[1];
if (mkpath_dest_arg && statret < 0 && (cp || file_total > 1)) {
int ret = make_path(dest_path, file_total > 1 && !trailing_slash ? 0 : MKP_DROP_NAME);
if (ret < 0)
goto mkdir_error;
if (INFO_GTE(NAME, 1)) {
if (file_total == 1 || trailing_slash)
*cp = '\0';
rprintf(FINFO, "created %d director%s for %s\n", ret, ret == 1 ? "y" : "ies", dest_path);
if (file_total == 1 || trailing_slash)
*cp = '/';
}
if (file_total > 1 || trailing_slash)
statret = do_stat(dest_path, &st);
}
if (statret == 0) {
/* If the destination is a dir, enter it and use mode 1. */
if (S_ISDIR(st.st_mode)) {
if (!change_dir(dest_path, CD_NORMAL)) {
@@ -742,15 +765,12 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
exit_cleanup(RERR_FILESELECT);
}
cp = strrchr(dest_path, '/');
/* If we need a destination directory because the transfer is not
* of a single non-directory or the user has requested one via a
* destination path ending in a slash, create one and use mode 1. */
if (file_total > 1 || (cp && !cp[1])) {
/* Lop off the final slash (if any). */
if (cp && !cp[1])
*cp = '\0';
if (file_total > 1 || trailing_slash) {
if (trailing_slash)
*cp = '\0'; /* Lop off the final slash (if any). */
if (statret == 0) {
rprintf(FERROR, "ERROR: destination path is not a directory\n");
@@ -758,6 +778,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
}
if (do_mkdir(dest_path, ACCESSPERMS) != 0) {
mkdir_error:
rsyserr(FERROR, errno, "mkdir %s failed",
full_fname(dest_path));
exit_cleanup(RERR_FILEIO);
@@ -824,8 +845,6 @@ static void check_alt_basis_dirs(void)
if (dry_run > 1 && *bdir != '/') {
int len = curr_dir_len + 1 + bd_len + 1;
char *new = new_array(char, len);
if (!new)
out_of_memory("check_alt_basis_dirs");
if (slash && strncmp(bdir, "../", 3) == 0) {
/* We want to remove only one leading "../" prefix for
* the directory we couldn't create in dry-run mode:
@@ -984,6 +1003,23 @@ static int do_recv(int f_in, int f_out, char *local_name)
backup_dir_buf[backup_dir_len-1] = '/';
}
if (tmpdir) {
STRUCT_STAT st;
int ret = do_stat(tmpdir, &st);
if (ret < 0 || !S_ISDIR(st.st_mode)) {
if (ret == 0) {
rprintf(FERROR, "The temp-dir is not a directory: %s\n", tmpdir);
exit_cleanup(RERR_SYNTAX);
}
if (errno == ENOENT) {
rprintf(FERROR, "The temp-dir does not exist: %s\n", tmpdir);
exit_cleanup(RERR_SYNTAX);
}
rprintf(FERROR, "Failed to stat temp-dir %s: %s\n", tmpdir, strerror(errno));
exit_cleanup(RERR_FILEIO);
}
}
io_flush(FULL_FLUSH);
if ((pid = do_fork()) == -1) {
@@ -1090,7 +1126,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
char *local_name = NULL;
int negated_levels;
if (filesfrom_fd >= 0 && !msgs2stderr && protocol_version < 31) {
if (filesfrom_fd >= 0 && msgs2stderr != 1 && protocol_version < 31) {
/* We can't mix messages with files-from data on the socket,
* so temporarily turn off info/debug messages. */
negate_output_levels();
@@ -1339,19 +1375,12 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
return MAX(exit_code, exit_code2);
}
static int copy_argv(char *argv[])
static void dup_argv(char *argv[])
{
int i;
for (i = 0; argv[i]; i++) {
if (!(argv[i] = strdup(argv[i]))) {
rprintf (FERROR, "out of memory at %s(%d)\n",
__FILE__, __LINE__);
return RERR_MALLOC;
}
}
return 0;
for (i = 0; argv[i]; i++)
argv[i] = strdup(argv[i]);
}
@@ -1372,8 +1401,7 @@ static int start_client(int argc, char *argv[])
/* Don't clobber argv[] so that ps(1) can still show the right
* command line. */
if ((ret = copy_argv(argv)) != 0)
return ret;
dup_argv(argv);
if (!read_batch) { /* for read_batch, NO source is specified */
char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
@@ -1401,7 +1429,7 @@ static int start_client(int argc, char *argv[])
}
am_sender = 0;
if (rsync_port)
daemon_over_rsh = shell_cmd ? 1 : -1;
daemon_connection = shell_cmd ? 1 : -1;
} else { /* source is local, check dest arg */
am_sender = 1;
@@ -1433,7 +1461,7 @@ static int start_client(int argc, char *argv[])
} else { /* hostspec was found, so dest is remote */
argv[argc] = path;
if (rsync_port)
daemon_over_rsh = shell_cmd ? 1 : -1;
daemon_connection = shell_cmd ? 1 : -1;
}
}
} else { /* read_batch */
@@ -1454,8 +1482,15 @@ static int start_client(int argc, char *argv[])
char *dummy_host;
int dummy_port = rsync_port;
int i;
if (!argv[0][0])
goto invalid_empty;
/* For local source, extra source args must not have hostspec. */
for (i = 1; i < argc; i++) {
if (!argv[i][0]) {
invalid_empty:
rprintf(FERROR, "Empty source arg specified.\n");
exit_cleanup(RERR_SYNTAX);
}
if (check_for_hostspec(argv[i], &dummy_host, &dummy_port)) {
rprintf(FERROR, "Unexpected remote arg: %s\n", argv[i]);
exit_cleanup(RERR_SYNTAX);
@@ -1496,10 +1531,10 @@ static int start_client(int argc, char *argv[])
else
env_port = rsync_port;
if (daemon_over_rsh < 0)
if (daemon_connection < 0)
return start_socket_client(shell_machine, remote_argc, remote_argv, argc, argv);
if (password_file && !daemon_over_rsh) {
if (password_file && !daemon_connection) {
rprintf(FERROR, "The --password-file option may only be "
"used when accessing an rsync daemon.\n");
exit_cleanup(RERR_SYNTAX);
@@ -1527,7 +1562,7 @@ static int start_client(int argc, char *argv[])
}
#ifdef HAVE_PUTENV
if (daemon_over_rsh)
if (daemon_connection)
set_env_num("RSYNC_PORT", env_port);
#endif
@@ -1535,7 +1570,7 @@ static int start_client(int argc, char *argv[])
/* if we're running an rsync server on the remote host over a
* remote shell command, we need to do the RSYNCD protocol first */
if (daemon_over_rsh) {
if (daemon_connection) {
int tmpret;
tmpret = start_inband_exchange(f_in, f_out, shell_user, remote_argc, remote_argv);
if (tmpret < 0)
@@ -1567,11 +1602,13 @@ static void sigusr2_handler(UNUSED(int val))
_exit(0);
}
#if defined SIGINFO || defined SIGVTALRM
static void siginfo_handler(UNUSED(int val))
{
if (!am_server && !INFO_GTE(PROGRESS, 1))
want_progress_now = True;
}
#endif
void remember_children(UNUSED(int val))
{
@@ -1682,7 +1719,7 @@ int main(int argc,char *argv[])
starttime = time(NULL);
our_uid = MY_UID();
our_gid = MY_GID();
am_root = our_uid == 0;
am_root = our_uid == ROOT_UID;
memset(&stats, 0, sizeof(stats));

View File

@@ -65,8 +65,6 @@ static void build_hash_table(struct sum_struct *s)
if (hash_table)
free(hash_table);
hash_table = new_array(int32, tablesize);
if (!hash_table)
out_of_memory("build_hash_table");
alloc_size = tablesize;
}

108
md2man
View File

@@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python3
# This script takes a manpage written in markdown and turns it into an html web
# page and a nroff man page. The input file must have the name of the program
@@ -35,6 +35,7 @@ body, b, strong, u {
code {
font-family: 'Roboto Mono', monospace;
font-weight: bold;
white-space: pre;
}
pre code {
display: block;
@@ -64,7 +65,9 @@ MAN_END = """\
NORM_FONT = ('\1', r"\fP")
BOLD_FONT = ('\2', r"\fB")
ULIN_FONT = ('\3', r"\fI")
UNDR_FONT = ('\3', r"\fI")
NBR_DASH = ('\4', r"\-")
NBR_SPACE = ('\xa0', r"\ ")
md_parser = None
@@ -78,46 +81,55 @@ def main():
fi.srcdir = './'
fi.title = fi.prog + '(' + fi.sect + ') man page'
fi.mtime = None
fi.mtime = 0
if os.path.lexists(fi.srcdir + '.git'):
fi.mtime = int(subprocess.check_output('git log -1 --format=%at'.split()))
chk_files = 'NEWS.md Makefile'.split()
for fn in chk_files:
try:
st = os.lstat(fi.srcdir + fn)
except:
die('Failed to find', fi.srcdir + fn)
if not fi.mtime:
fi.mtime = st.st_mtime
fi.date = time.strftime('%d %b %Y', time.localtime(fi.mtime))
git_dir = fi.srcdir + '.git'
if os.path.lexists(git_dir):
fi.mtime = int(subprocess.check_output(['git', '--git-dir', git_dir, 'log', '-1', '--format=%at']))
env_subs = { 'prefix': os.environ.get('RSYNC_OVERRIDE_PREFIX', None) }
with open(fi.srcdir + 'Makefile', 'r', encoding='utf-8') as fh:
for line in fh:
m = re.match(r'^(\w+)=(.+)', line)
if not m:
continue
var, val = (m[1], m[2])
if var == 'prefix' and env_subs[var] is not None:
continue
while re.search(r'\$\{', val):
val = re.sub(r'\$\{(\w+)\}', lambda m: env_subs[m[1]], val)
env_subs[var] = val
if var == 'VERSION':
break
if args.test:
env_subs['VERSION'] = '1.0.0'
env_subs['libdir'] = '/usr'
else:
for fn in (fi.srcdir + 'version.h', 'Makefile'):
try:
st = os.lstat(fn)
except:
die('Failed to find', fi.srcdir + fn)
if not fi.mtime:
fi.mtime = st.st_mtime
with open(fi.srcdir + 'version.h', 'r', encoding='utf-8') as fh:
txt = fh.read()
m = re.search(r'"(.+?)"', txt)
env_subs['VERSION'] = m.group(1)
with open('Makefile', 'r', encoding='utf-8') as fh:
for line in fh:
m = re.match(r'^(\w+)=(.+)', line)
if not m:
continue
var, val = (m.group(1), m.group(2))
if var == 'prefix' and env_subs[var] is not None:
continue
while re.search(r'\$\{', val):
val = re.sub(r'\$\{(\w+)\}', lambda m: env_subs[m.group(1)], val)
env_subs[var] = val
if var == 'srcdir':
break
with open(fi.fn, 'r', encoding='utf-8') as fh:
txt = fh.read()
txt = re.sub(r'@VERSION@', env_subs['VERSION'], txt)
txt = re.sub(r'@LIBDIR@', env_subs['libdir'], txt)
fi.html_in = md_parser(txt)
txt = None
fi.date = time.strftime('%d %b %Y', time.localtime(fi.mtime))
fi.man_headings = (fi.prog, fi.sect, fi.date, fi.prog + ' ' + env_subs['VERSION'])
HtmlToManPage(fi)
@@ -132,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))
@@ -151,6 +159,7 @@ class HtmlToManPage(HTMLParser):
at_first_tag_in_dd = False,
dt_from = None,
in_pre = False,
in_code = False,
html_out = [ HTML_START % fi.title ],
man_out = [ MAN_START % fi.man_headings ],
txt = '',
@@ -180,6 +189,8 @@ class HtmlToManPage(HTMLParser):
tag = 'dt'
else:
st.html_out.append('<dt>')
elif tag == 'p':
st.at_first_tag_in_dd = True # Kluge to suppress a .P at the start of an li.
st.at_first_tag_in_li = False
if tag == 'p':
if not st.at_first_tag_in_dd:
@@ -200,12 +211,13 @@ class HtmlToManPage(HTMLParser):
st.in_pre = True
st.man_out.append(st.p_macro + ".nf\n")
elif tag == 'code' and not st.in_pre:
st.in_code = True
st.txt += BOLD_FONT[0]
elif tag == 'strong' or tag == 'b':
st.txt += BOLD_FONT[0]
elif tag == 'em' or tag == 'i':
tag = 'u' # Change it into underline to be more like the man page
st.txt += ULIN_FONT[0]
st.txt += UNDR_FONT[0]
elif tag == 'ol':
start = 1
for var, val in attrs_list:
@@ -266,7 +278,10 @@ class HtmlToManPage(HTMLParser):
elif tag == 'pre':
st.in_pre = False
st.man_out.append(manify(txt) + "\n.fi\n")
elif (tag == 'code' and not st.in_pre) or tag == 'strong' or tag == 'b':
elif (tag == 'code' and not st.in_pre):
st.in_code = False
add_to_txt = NORM_FONT[0]
elif tag == 'strong' or tag == 'b':
add_to_txt = NORM_FONT[0]
elif tag == 'em' or tag == 'i':
tag = 'u' # Change it into underline to be more like the man page
@@ -295,12 +310,21 @@ class HtmlToManPage(HTMLParser):
st.at_first_tag_in_dd = True
def handle_data(self, data):
def handle_data(self, txt):
st = self.state
if args.debug:
self.output_debug('DATA', (data,))
st.html_out.append(htmlify(data))
st.txt += data
self.output_debug('DATA', (txt,))
if st.in_pre:
html = htmlify(txt)
else:
txt = re.sub(r'\s--(\s)', NBR_SPACE[0] + r'--\1', txt).replace('--', NBR_DASH[0]*2)
txt = re.sub(r'(^|\W)-', r'\1' + NBR_DASH[0], txt)
html = htmlify(txt)
if st.in_code:
txt = re.sub(r'\s', NBR_SPACE[0], txt)
html = html.replace(NBR_DASH[0], '-').replace(NBR_SPACE[0], ' ') # <code> is non-breaking in CSS
st.html_out.append(html.replace(NBR_SPACE[0], '&nbsp;').replace(NBR_DASH[0], '-&#8288;'))
st.txt += txt
def output_debug(self, event, extra):
@@ -318,9 +342,11 @@ class HtmlToManPage(HTMLParser):
def manify(txt):
return re.sub(r"^(['.])", r'\&\1', txt.replace('\\', '\\\\')
.replace(NBR_SPACE[0], NBR_SPACE[1])
.replace(NBR_DASH[0], NBR_DASH[1])
.replace(NORM_FONT[0], NORM_FONT[1])
.replace(BOLD_FONT[0], BOLD_FONT[1])
.replace(ULIN_FONT[0], ULIN_FONT[1]), flags=re.M)
.replace(UNDR_FONT[0], UNDR_FONT[1]), flags=re.M)
def htmlify(txt):
@@ -346,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")
}

616
options.c
View File

@@ -21,16 +21,13 @@
#include "rsync.h"
#include "itypes.h"
#include "latest-year.h"
#include "ifuncs.h"
#include <popt.h>
extern int module_id;
extern int local_server;
extern int sanitize_paths;
extern int daemon_over_rsh;
extern unsigned int module_dirlen;
extern struct name_num_obj valid_checksums;
extern struct name_num_obj valid_compressions;
extern filter_rule_list filter_list;
extern filter_rule_list daemon_filter_list;
@@ -63,6 +60,7 @@ int preserve_uid = 0;
int preserve_gid = 0;
int preserve_times = 0;
int preserve_atimes = 0;
int preserve_crtimes = 0;
int update_only = 0;
int open_noatime = 0;
int cvs_exclude = 0;
@@ -89,7 +87,7 @@ int relative_paths = -1;
int implied_dirs = 1;
int missing_args = 0; /* 0 = FERROR_XFER, 1 = ignore, 2 = delete */
int numeric_ids = 0;
int msgs2stderr = 0;
int msgs2stderr = 2; /* Default: send errors to stderr for local & remote-shell transfers */
int allow_8bit_chars = 0;
int force_delete = 0;
int io_timeout = 0;
@@ -102,6 +100,7 @@ int eol_nulls = 0;
int protect_args = -1;
int human_readable = 1;
int recurse = 0;
int mkpath_dest_arg = 0;
int allow_inc_recurse = 1;
int xfer_dirs = -1;
int am_daemon = 0;
@@ -127,7 +126,8 @@ int blocking_io = -1;
int checksum_seed = 0;
int inplace = 0;
int delay_updates = 0;
long block_size = 0; /* "long" because popt can't set an int32. */
int32 block_size = 0;
time_t stop_at_utime = 0;
char *skip_compress = NULL;
char *copy_as = NULL;
item_list dparam_list = EMPTY_ITEM_LIST;
@@ -170,6 +170,7 @@ char *logfile_name = NULL;
char *logfile_format = NULL;
char *stdout_format = NULL;
char *password_file = NULL;
char *early_input_file = NULL;
char *rsync_path = RSYNC_PATH;
char *backup_dir = NULL;
char backup_dir_buf[MAXPATHLEN];
@@ -180,6 +181,11 @@ int rsync_port = 0;
int alt_dest_type = 0;
int basis_dir_cnt = 0;
#define DEFAULT_MAX_ALLOC (1024L * 1024 * 1024)
size_t max_alloc = DEFAULT_MAX_ALLOC;
char *max_alloc_arg;
static int version_opt_cnt = 0;
static int remote_option_alloc = 0;
int remote_option_cnt = 0;
const char **remote_options = NULL;
@@ -200,8 +206,11 @@ int list_only = 0;
char *batch_name = NULL;
int need_unsorted_flist = 0;
char *iconv_opt =
#ifdef ICONV_OPTION
char *iconv_opt = ICONV_OPTION;
ICONV_OPTION;
#else
NULL;
#endif
struct chmod_mode_struct *chmod_modes = NULL;
@@ -308,9 +317,7 @@ static int refused_partial, refused_progress, refused_delete_before;
static int refused_delete_during;
static int refused_inplace, refused_no_iconv;
static BOOL usermap_via_chown, groupmap_via_chown;
#ifdef HAVE_SETVBUF
static char *outbuf_mode;
#endif
static char *bwlimit_arg, *max_size_arg, *min_size_arg;
static char tmp_partialdir[] = ".~tmp~";
@@ -375,8 +382,7 @@ static char *make_output_option(struct output_struct *words, short *levels, ucha
return NULL;
len++;
if (!(buf = new_array(char, len)))
out_of_memory("make_output_option");
buf = new_array(char, len);
pos = 0;
if (skipped || max < 5)
@@ -562,182 +568,14 @@ void negate_output_levels(void)
debug_levels[j] *= -1;
}
static char *istring(const char *fmt, int val)
{
char *str;
if (asprintf(&str, fmt, val) < 0)
out_of_memory("istring");
return str;
}
static void print_capabilities(enum logcode f)
{
STRUCT_STAT *dumstat;
char line_buf[75];
int line_len, j;
char *capabilities[] = {
istring("%d-bit files", (int)(sizeof (OFF_T) * 8)),
istring("%d-bit inums", (int)(sizeof dumstat->st_ino * 8)), /* Don't check ino_t! */
istring("%d-bit timestamps", (int)(sizeof (time_t) * 8)),
istring("%d-bit long ints", (int)(sizeof (int64) * 8)),
#ifndef HAVE_SOCKETPAIR
"no "
#endif
"socketpairs",
#ifndef SUPPORT_HARD_LINKS
"no "
#endif
"hardlinks",
#ifndef SUPPORT_LINKS
"no "
#endif
"symlinks",
#ifndef INET6
"no "
#endif
"IPv6",
"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",
#ifndef ICONV_OPTION
"no "
#endif
"iconv",
#ifndef CAN_SET_SYMLINK_TIMES
"no "
#endif
"symtimes",
#ifndef SUPPORT_PREALLOCATION
"no "
#endif
"prealloc",
#ifndef HAVE_SIMD
"no "
#endif
"SIMD",
NULL
};
for (line_len = 0, j = 0; ; j++) {
char *cap = capabilities[j];
int cap_len = cap ? strlen(cap) : 1000;
int need_comma = cap && capabilities[j+1] != NULL ? 1 : 0;
if (line_len + 1 + cap_len + need_comma >= (int)sizeof line_buf) {
rprintf(f, " %s\n", line_buf);
line_len = 0;
}
if (!cap)
break;
line_len += snprintf(line_buf+line_len, sizeof line_buf - line_len, " %s%s", cap, need_comma ? "," : "");
}
}
static void print_rsync_version(enum logcode f)
{
char tmpbuf[256], *subprotocol = "";
#if SUBPROTOCOL_VERSION != 0
subprotocol = istring(".PR%d", SUBPROTOCOL_VERSION);
#endif
rprintf(f, "%s version %s protocol version %d%s\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
rprintf(f, "Copyright (C) 1996-" LATEST_YEAR " by Andrew Tridgell, Wayne Davison, and others.\n");
rprintf(f, "Web site: http://rsync.samba.org/\n");
rprintf(f, "Capabilities:\n");
print_capabilities(f);
rprintf(f, "Checksum list:\n");
get_default_nno_list(&valid_checksums, tmpbuf, sizeof tmpbuf, '(');
rprintf(f, " %s\n", tmpbuf);
rprintf(f, "Compress list:\n");
get_default_nno_list(&valid_compressions, tmpbuf, sizeof tmpbuf, '(');
rprintf(f, " %s\n", tmpbuf);
#ifdef MAINTAINER_MODE
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
#endif
#if SIZEOF_INT64 < 8
rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
#endif
if (sizeof (int64) != SIZEOF_INT64) {
rprintf(f,
"WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
(int) SIZEOF_INT64, (int) sizeof (int64));
}
rprintf(f,"\n");
rprintf(f,"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n");
rprintf(f,"are welcome to redistribute it under certain conditions. See the GNU\n");
rprintf(f,"General Public Licence for details.\n");
}
void usage(enum logcode F)
{
print_rsync_version(F);
rprintf(F,"\n");
rprintf(F,"rsync is a file transfer program capable of efficient remote update\n");
rprintf(F,"via a fast differencing algorithm.\n");
rprintf(F,"\n");
rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n");
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC [DEST]\n");
rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
rprintf(F,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n");
rprintf(F,"to an rsync daemon, and require SRC or DEST to start with a module name.\n");
rprintf(F,"\n");
rprintf(F,"Options\n");
#include "help-rsync.h"
rprintf(F,"\n");
rprintf(F,"Use \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
rprintf(F,"See http://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[] = {
@@ -749,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 },
@@ -790,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 },
@@ -846,6 +688,7 @@ static struct poptOption long_options[] = {
{"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 },
{"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
{"min-size", 0, POPT_ARG_STRING, &min_size_arg, OPT_MIN_SIZE, 0, 0 },
{"max-alloc", 0, POPT_ARG_STRING, &max_alloc_arg, 0, 0, 0 },
{"sparse", 'S', POPT_ARG_VAL, &sparse_files, 1, 0, 0 },
{"no-sparse", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 },
{"no-S", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 },
@@ -886,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 },
@@ -902,6 +745,7 @@ static struct poptOption long_options[] = {
{"zc", 0, POPT_ARG_STRING, &compress_choice, 0, 0, 0 },
{"skip-compress", 0, POPT_ARG_STRING, &skip_compress, 0, 0, 0 },
{"compress-level", 0, POPT_ARG_INT, &do_compression_level, 0, 0, 0 },
{"zl", 0, POPT_ARG_INT, &do_compression_level, 0, 0, 0 },
{0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
{"progress", 0, POPT_ARG_VAL, &do_progress, 1, 0, 0 },
{"no-progress", 0, POPT_ARG_VAL, &do_progress, 0, 0, 0 },
@@ -945,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 },
@@ -955,12 +802,15 @@ 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 },
{"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
{"sockopts", 0, POPT_ARG_STRING, &sockopts, 0, 0, 0 },
{"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
{"early-input", 0, POPT_ARG_STRING, &early_input_file, 0, 0, 0 },
{"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
{"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
{"outbuf", 0, POPT_ARG_STRING, &outbuf_mode, 0, 0, 0 },
@@ -978,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 },
@@ -1142,15 +980,24 @@ static void set_refuse_options(void)
parse_one_refuse_match(0, "log-file*", list_end);
}
#ifndef SUPPORT_ATIMES
parse_one_refuse_match(0, "atimes", list_end);
#endif
#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++) {
@@ -1203,15 +1050,18 @@ static int count_args(const char **argv)
return i;
}
static OFF_T parse_size_arg(char **size_arg, char def_suf)
/* If the size_arg is an invalid string or the value is < min_value, an error
* is put into err_buf & the return is -1. Note that this parser does NOT
* support negative numbers, so a min_value < 0 doesn't make any sense. */
static ssize_t parse_size_arg(const char *size_arg, char def_suf, const char *opt_name,
ssize_t min_value, ssize_t max_value, BOOL unlimited_0)
{
int reps, mult, make_compatible = 0;
const char *arg;
OFF_T size = 1;
int reps, mult, len;
const char *arg, *err = "invalid", *min_max = NULL;
ssize_t limit = -1, size = 1;
for (arg = *size_arg; isDigit(arg); arg++) {}
if (*arg == '.')
for (arg = size_arg; isDigit(arg); arg++) {}
if (*arg == '.' || *arg == get_decimal_point()) /* backward compatibility: always allow '.' */
for (arg++; isDigit(arg); arg++) {}
switch (*arg && *arg != '+' && *arg != '-' ? *arg++ : def_suf) {
case 'b': case 'B':
@@ -1226,40 +1076,197 @@ static OFF_T parse_size_arg(char **size_arg, char def_suf)
case 'g': case 'G':
reps = 3;
break;
case 't': case 'T':
reps = 4;
break;
case 'p': case 'P':
reps = 5;
break;
default:
return -1;
goto failure;
}
if (*arg == 'b' || *arg == 'B')
mult = 1000, make_compatible = 1, arg++;
mult = 1000, arg++;
else if (!*arg || *arg == '+' || *arg == '-')
mult = 1024;
else if (strncasecmp(arg, "ib", 2) == 0)
mult = 1024, arg += 2;
else
return -1;
goto failure;
while (reps--)
size *= mult;
size *= atof(*size_arg);
if ((*arg == '+' || *arg == '-') && arg[1] == '1')
size += atoi(arg), make_compatible = 1, arg += 2;
size *= atof(size_arg);
if ((*arg == '+' || *arg == '-') && arg[1] == '1' && arg != size_arg)
size += atoi(arg), arg += 2;
if (*arg)
return -1;
if (size > 0 && make_compatible && def_suf == 'b') {
/* We convert this manually because we may need %lld precision,
* and that's not a portable sprintf() escape. */
char buf[128], *s = buf + sizeof buf - 1;
OFF_T num = size;
*s = '\0';
while (num) {
*--s = (char)(num % 10) + '0';
num /= 10;
}
if (!(*size_arg = strdup(s)))
out_of_memory("parse_size_arg");
goto failure;
if (size < 0 || (max_value >= 0 && size > max_value)) {
err = "too large";
min_max = "max";
limit = max_value;
goto failure;
}
if (size < min_value && (!unlimited_0 || size != 0)) {
err = "too small";
min_max = "min";
limit = min_value;
goto failure;
}
return size;
failure:
len = snprintf(err_buf, sizeof err_buf - 1, "--%s=%s is %s", opt_name, size_arg, err);
if (min_max && limit >= 0 && len < (int)sizeof err_buf - 10) {
len += snprintf(err_buf + len, sizeof err_buf - len - 1, " (%s: %s%s)",
min_max, do_big_num(limit, 3, NULL),
unlimited_0 && min_max[1] == 'i' ? " or 0 for unlimited" : "");
}
err_buf[len] = '\n';
err_buf[len+1] = '\0';
return -1;
}
#ifdef HAVE_MKTIME
/* Allow the user to specify a time in the format yyyy-mm-ddThh:mm while
* also allowing abbreviated data. For instance, if the time is omitted,
* it defaults to midnight. If the date is omitted, it defaults to the
* next possible date in the future with the specified time. Even the
* year or year-month can be omitted, again defaulting to the next date
* in the future that matches the specified information. A 2-digit year
* is also OK, as is using '/' instead of '-'. */
static time_t parse_time(const char *arg)
{
const char *cp;
time_t val, now = time(NULL);
struct tm t, *today = localtime(&now);
int in_date, old_mday, n;
memset(&t, 0, sizeof t);
t.tm_year = t.tm_mon = t.tm_mday = -1;
t.tm_hour = t.tm_min = t.tm_isdst = -1;
cp = arg;
if (*cp == 'T' || *cp == 't' || *cp == ':') {
in_date = *cp == ':' ? 0 : -1;
cp++;
} else
in_date = 1;
for ( ; ; cp++) {
if (!isDigit(cp))
return (time_t)-1;
n = 0;
do {
n = n * 10 + *cp++ - '0';
} while (isDigit(cp));
if (*cp == ':')
in_date = 0;
if (in_date > 0) {
if (t.tm_year != -1)
return (time_t)-1;
t.tm_year = t.tm_mon;
t.tm_mon = t.tm_mday;
t.tm_mday = n;
if (!*cp)
break;
if (*cp == 'T' || *cp == 't') {
if (!cp[1])
break;
in_date = -1;
} else if (*cp != '-' && *cp != '/')
return (time_t)-1;
continue;
}
if (t.tm_hour != -1)
return (time_t)-1;
t.tm_hour = t.tm_min;
t.tm_min = n;
if (!*cp) {
if (in_date < 0)
return (time_t)-1;
break;
}
if (*cp != ':')
return (time_t)-1;
in_date = 0;
}
in_date = 0;
if (t.tm_year < 0) {
t.tm_year = today->tm_year;
in_date = 1;
} else if (t.tm_year < 100) {
while (t.tm_year < today->tm_year)
t.tm_year += 100;
} else
t.tm_year -= 1900;
if (t.tm_mon < 0) {
t.tm_mon = today->tm_mon;
in_date = 2;
} else
t.tm_mon--;
if (t.tm_mday < 0) {
t.tm_mday = today->tm_mday;
in_date = 3;
}
n = 0;
if (t.tm_min < 0) {
t.tm_hour = t.tm_min = 0;
} else if (t.tm_hour < 0) {
if (in_date != 3)
return (time_t)-1;
in_date = 0;
t.tm_hour = today->tm_hour;
n = 60*60;
}
/* Note that mktime() might change a too-large tm_mday into the start of
* the following month which we need to undo in the following code! */
old_mday = t.tm_mday;
if (t.tm_hour > 23 || t.tm_min > 59
|| t.tm_mon < 0 || t.tm_mon >= 12
|| t.tm_mday < 1 || t.tm_mday > 31
|| (val = mktime(&t)) == (time_t)-1)
return (time_t)-1;
while (in_date && (val <= now || t.tm_mday < old_mday)) {
switch (in_date) {
case 3:
old_mday = ++t.tm_mday;
break;
case 2:
if (t.tm_mday < old_mday)
t.tm_mday = old_mday; /* The month already got bumped forward */
else if (++t.tm_mon == 12) {
t.tm_mon = 0;
t.tm_year++;
}
break;
case 1:
if (t.tm_mday < old_mday) {
/* mon==1 mday==29 got bumped to mon==2 */
if (t.tm_mon != 2 || old_mday != 29)
return (time_t)-1;
t.tm_mon = 1;
t.tm_mday = 29;
}
t.tm_year++;
break;
}
if ((val = mktime(&t)) == (time_t)-1) {
/* This code shouldn't be needed, as mktime() should auto-round to the next month. */
if (in_date != 3 || t.tm_mday <= 28)
return (time_t)-1;
t.tm_mday = old_mday = 1;
in_date = 2;
}
}
if (n) {
while (val <= now)
val += n;
}
return val;
}
#endif
static void create_refuse_error(int which)
{
@@ -1309,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");
}
}
@@ -1360,8 +1367,8 @@ int parse_arguments(int *argc_p, const char ***argv_p)
switch (opt) {
case 'V':
print_rsync_version(FINFO);
exit_cleanup(0);
version_opt_cnt++;
break;
case OPT_SERVER:
if (!am_server) {
@@ -1482,8 +1489,6 @@ int parse_arguments(int *argc_p, const char ***argv_p)
if (daemon_filter_list.head) {
int rej;
char *cp = strdup(arg);
if (!cp)
out_of_memory("parse_arguments");
if (!*cp)
rej = 1;
else {
@@ -1607,8 +1612,6 @@ int parse_arguments(int *argc_p, const char ***argv_p)
remote_option_alloc += 16;
remote_options = realloc_array(remote_options,
const char *, remote_option_alloc);
if (!remote_options)
out_of_memory("parse_arguments");
if (!remote_option_cnt)
remote_options[0] = "ARG0";
}
@@ -1637,40 +1640,39 @@ int parse_arguments(int *argc_p, const char ***argv_p)
#endif
break;
case OPT_MAX_SIZE:
if ((max_size = parse_size_arg(&max_size_arg, 'b')) < 0) {
snprintf(err_buf, sizeof err_buf,
"--max-size value is invalid: %s\n",
max_size_arg);
case OPT_BLOCK_SIZE: {
/* We may not know the real protocol_version at this point if this is the client
* option parsing, but we still want to check it so that the client can specify
* a --protocol=29 option with a larger block size. */
int max_blength = protocol_version < 30 ? OLD_MAX_BLOCK_SIZE : MAX_BLOCK_SIZE;
ssize_t size;
arg = poptGetOptArg(pc);
if ((size = parse_size_arg(arg, 'b', "block-size", 0, max_blength, False)) < 0)
return 0;
}
block_size = (int32)size;
break;
}
case OPT_MAX_SIZE:
if ((max_size = parse_size_arg(max_size_arg, 'b', "max-size", 0, -1, False)) < 0)
return 0;
max_size_arg = strdup(do_big_num(max_size, 0, NULL));
break;
case OPT_MIN_SIZE:
if ((min_size = parse_size_arg(&min_size_arg, 'b')) < 0) {
snprintf(err_buf, sizeof err_buf,
"--min-size value is invalid: %s\n",
min_size_arg);
if ((min_size = parse_size_arg(min_size_arg, 'b', "min-size", 0, -1, False)) < 0)
return 0;
}
min_size_arg = strdup(do_big_num(min_size, 0, NULL));
break;
case OPT_BWLIMIT:
{
OFF_T limit = parse_size_arg(&bwlimit_arg, 'K');
if (limit < 0) {
snprintf(err_buf, sizeof err_buf,
"--bwlimit value is invalid: %s\n", bwlimit_arg);
return 0;
}
bwlimit = (limit + 512) / 1024;
if (limit && !bwlimit) {
snprintf(err_buf, sizeof err_buf,
"--bwlimit value is too small: %s\n", bwlimit_arg);
return 0;
}
}
case OPT_BWLIMIT: {
ssize_t size = parse_size_arg(bwlimit_arg, 'K', "bwlimit", 512, -1, True);
if (size < 0)
return 0;
bwlimit_arg = strdup(do_big_num(size, 0, NULL));
bwlimit = (size + 512) / 1024;
break;
}
case OPT_APPEND:
if (am_server)
@@ -1832,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. */
@@ -1847,6 +1893,23 @@ int parse_arguments(int *argc_p, const char ***argv_p)
}
}
if (version_opt_cnt) {
print_rsync_version(FINFO);
exit_cleanup(0);
}
if (!max_alloc_arg) {
max_alloc_arg = getenv("RSYNC_MAX_ALLOC");
if (max_alloc_arg && !*max_alloc_arg)
max_alloc_arg = NULL;
}
if (max_alloc_arg) {
ssize_t size = parse_size_arg(max_alloc_arg, 'B', "max-alloc", 1024*1024, -1, True);
if (size < 0)
return 0;
max_alloc = size;
}
if (protect_args < 0) {
if (am_server)
protect_args = 0;
@@ -1917,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);
@@ -1989,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");
@@ -2170,6 +2220,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
}
if (backup_dir) {
size_t len;
make_backups = 1; /* --backup-dir implies --backup */
while (*backup_dir == '.' && backup_dir[1] == '/')
backup_dir += 2;
if (*backup_dir == '.' && backup_dir[1] == '\0')
@@ -2415,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";
@@ -2492,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)
@@ -2559,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
}
@@ -2624,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;
}
@@ -2716,6 +2770,11 @@ void server_options(char **args, int *argc_p)
}
}
if (max_alloc_arg && max_alloc != DEFAULT_MAX_ALLOC) {
args[ac++] = "--max-alloc";
args[ac++] = max_alloc_arg;
}
/* --delete-missing-args needs the cooperation of both sides, but
* the sender can handle --ignore-missing-args by itself. */
if (missing_args == 2)
@@ -2842,6 +2901,9 @@ void server_options(char **args, int *argc_p)
if (open_noatime && preserve_atimes <= 1)
args[ac++] = "--open-noatime";
if (mkpath_dest_arg && am_sender)
args[ac++] = "--mkpath";
if (ac > MAX_SERVER_ARGS) { /* Not possible... */
rprintf(FERROR, "argc overflow in server_options().\n");
exit_cleanup(RERR_MALLOC);

12
packaging/auto-Makefile Normal file
View File

@@ -0,0 +1,12 @@
TARGETS := all install install-ssl-daemon install-all install-strip conf gen gensend reconfigure restatus \
proto man clean cleantests distclean test check check29 check30 installcheck splint \
doxygen doxygen-upload finddead
.PHONY: $(TARGETS) auto-prep
$(TARGETS): auto-prep
make -C build $@
auto-prep:
@if test x`packaging/prep-auto-dir` = x; then echo "auto-build-save is not setup"; exit 1; fi
@echo 'Build branch: '`readlink build/.branch | tr % /`

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python3 -B
#!/usr/bin/env -S python3 -B
# This script turns one or more diff files in the patches dir (which is
# expected to be a checkout of the rsync-patches git repo) into a branch
@@ -171,4 +171,4 @@ if __name__ == '__main__':
args = parser.parse_args()
main()
# vim: sw=4 et
# vim: sw=4 et ft=python

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
# This script outputs some perl code that parses all possible options
# that the code in options.c might send to the server. This perl code
# is included in the rrsync script.
@@ -23,6 +23,7 @@ our %long_opt = ( # These include some extra long-args that BackupPC uses:
'perms' => 0,
'recursive' => 0,
'times' => 0,
'write-devices' => -1,
);
our $last_long_opt;
@@ -39,10 +40,10 @@ while (<IN>) {
$last_long_opt = $1;
$long_opt{$1} = 0 unless exists $long_opt{$1};
} elsif (defined($last_long_opt)
&& /\Qargs[ac++]\E = ([^["\s]+);/ && $1 ne 'dest_option') {
&& /\Qargs[ac++]\E = ([^["\s]+);/) {
$long_opt{$last_long_opt} = 2;
undef $last_long_opt;
} elsif (/dest_option = "--([^"]+)"/) {
} elsif (/return "--([^"]+-dest)";/) {
$long_opt{$1} = 2;
undef $last_long_opt;
} elsif (/\Qasprintf(\E[^,]+, "--([^"=]+)=/ || /\Qargs[ac++]\E = "--([^"=]+)=/ || /fmt = .*: "--([^"=]+)=/) {

View File

@@ -1,14 +1,14 @@
Summary: A fast, versatile, remote (and local) file-copying tool
Name: rsync
Version: 3.2.0
%define fullversion %{version}pre1
Release: 0.1.pre1
%define srcdir src-previews
Version: 3.2.3
%define fullversion %{version}
Release: 1
%define srcdir src
Group: Applications/Internet
License: GPL
Source0: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-%{fullversion}.tar.gz
#Source1: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-patches-%{fullversion}.tar.gz
URL: http://rsync.samba.org/
Source0: https://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-%{fullversion}.tar.gz
#Source1: https://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-patches-%{fullversion}.tar.gz
URL: https://rsync.samba.org/
Prefix: %{_prefix}
BuildRoot: /var/tmp/%{name}-root
@@ -66,7 +66,7 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc COPYING NEWS.md OLDNEWS.md README.md support/ tech_report.tex
%doc COPYING NEWS.md README.md support/ tech_report.tex
%config(noreplace) /etc/xinetd.d/rsync
%{_prefix}/bin/rsync
%{_prefix}/bin/rsync-ssl
@@ -79,9 +79,9 @@ rm -rf $RPM_BUILD_ROOT
%dir /etc/rsync-ssl/certs
%changelog
* Sat Jun 13 2020 Wayne Davison <wayned@samba.org>
Released 3.2.0pre1.
* Thu Aug 06 2020 Wayne Davison <wayne@opencoder.net>
Released 3.2.3.
* Fri Mar 21 2008 Wayne Davison <wayned@samba.org>
* Fri Mar 21 2008 Wayne Davison <wayne@opencoder.net>
Added installation of /etc/xinetd.d/rsync file and some commented-out
lines that demonstrate how to use the rsync-patches tar file.

104
packaging/md2html Executable file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env python3
# Copyright (C) 2020 Wayne Davison
#
# This program is freely redistributable.
import os, re, argparse
HTML_START = """\
<html><head>
<title>%s</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&display=swap" rel="stylesheet">
<style>
body {
max-width: 50em;
margin: auto;
}
body, b, strong, u {
font-family: 'Roboto', sans-serif;
}
code {
font-family: 'Roboto Mono', monospace;
font-weight: bold;
}
pre code {
display: block;
font-weight: normal;
}
blockquote pre code {
background: #f1f1f1;
}
dd p:first-of-type {
margin-block-start: 0em;
}
table {
border-color: grey;
border-spacing: 0;
}
tr {
border-top: 1px solid grey;
}
tr:nth-child(2n) {
background-color: #f6f8fa;
}
th, td {
border: 1px solid #dfe2e5;
text-align: center;
padding-left: 1em;
padding-right: 1em;
}
</style>
</head><body>
"""
HTML_END = """\
</body></html>
"""
md_parser = None
def main():
for mdfn in args.mdfiles:
if not mdfn.endswith('.md'):
print('Ignoring non-md input file:', mdfn)
continue
title = re.sub(r'.*/', '', mdfn).replace('.md', '')
htfn = mdfn.replace('.md', '.html')
print("Parsing", mdfn, '->', htfn)
with open(mdfn, 'r', encoding='utf-8') as fh:
txt = fh.read()
txt = re.sub(r'\s--\s', '\xa0-- ', txt)
html = md_parser(txt)
html = re.sub(r'(?<!<pre>)(<code>)([\s\S]*?)(</code>)', lambda m: m[1] + re.sub(r'\s', '\xa0', m[2]) + m[3], html)
html = html.replace('--', '&#8209;&#8209;').replace("\xa0-", '&nbsp;&#8209;').replace("\xa0", '&nbsp;')
html = re.sub(r'(\W)-', r'\1&#8209;', html)
if os.path.lexists(htfn):
os.unlink(htfn)
with open(htfn, 'w', encoding='utf-8') as fh:
fh.write(HTML_START % title)
fh.write(html)
fh.write(HTML_END)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Output html for md pages.', add_help=False)
parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
parser.add_argument("mdfiles", nargs='+', help="The .md files to turn into .html files.")
args = parser.parse_args()
try:
import cmarkgfm
# Our NEWS.md file has a gfm table in it.
md_parser = cmarkgfm.github_flavored_markdown_to_html
except:
die("Failed to find cmarkgfm for python3.")
main()

View File

@@ -1,106 +0,0 @@
#!/usr/bin/python3 -B
# This script expects the directory ~/samba-rsync-ftp to exist and to be a
# copy of the /home/ftp/pub/rsync dir on samba.org. It also requires a
# git checkout of rsync (feel free to use your normal rsync build dir as
# long as it doesn't have any uncommitted changes).
#
# If this is run with -tu, it will make an updated "nightly" tar file in
# the nightly dir. It will also remove any old tar files, regenerate the
# HTML man pages in the nightly dir, and then rsync the changes to the
# samba.org server.
import os, sys, re, argparse, glob
from datetime import datetime, timezone
from getpass import getpass
sys.path = ['packaging'] + sys.path
from pkglib import *
# Where the local copy of /home/ftp/pub/rsync/dev/nightly should be updated.
dest = os.environ['HOME'] + '/samba-rsync-ftp/dev/nightly'
samba_host = os.environ['SAMBA_HOST']
nightly_symlink = f"{dest}/rsync-HEAD.tar.gz"
def main():
now = datetime.now(timezone.utc)
name = now.strftime('rsync-HEAD-%Y%m%d-%H%MGMT')
ztoday = now.strftime('%d %b %Y')
today = ztoday.lstrip('0')
gen_target = 'gensend' if args.upload else 'gen'
if not os.path.isdir(dest):
die("$dest does not exist")
if not os.path.isdir('.git'):
die("There is no .git dir in the current directory.")
if not os.path.exists('rsyncd.conf.5.md'):
die("There is no rsync checkout in the current directory.")
mandate_gensend_hook()
if args.make_tar:
check_git_state('master')
cmd_chk(['touch', 'NEWS.md'])
cmd_chk(['make', gen_target])
cmd_chk(['rsync', '-a', *glob.glob('*.[1-9].html'), dest])
gen_files = get_gen_files()
confversion = get_configure_version()
# All version values are strings!
last_version, last_protocol_version = get_OLDNEWS_version_info()
protocol_version, subprotocol_version = get_protocol_versions()
if 'dev' in confversion or 'pre' in confversion:
if last_protocol_version != protocol_version:
if subprotocol_version == '0':
die("SUBPROTOCOL_VERSION must not be 0 for a non-final release with a changed PROTOCOL_VERSION.")
elif subprotocol_version != '0':
die("SUBPROTOCOL_VERSION must be 0 when the PROTOCOL_VERSION hasn't changed from the last release.")
elif subprotocol_version != '0':
die("SUBPROTOCOL_VERSION must be 0 for a final release.")
name_slash = name + '/'
tar_name = f"{name}.tar.gz"
print('Creating', tar_name)
cmd_chk(['rsync', '-a', *gen_files, name_slash])
cmd_chk(f"git archive --format=tar --prefix={name}/ HEAD | tar xf -")
cmd_chk(['support/git-set-file-times', '--quiet', '--prefix', name_slash])
cmd_chk(['fakeroot', 'tar', 'czf', os.path.join(dest, tar_name), name])
cmd_chk(['rm', '-rf', name])
if os.path.lexists(nightly_symlink):
os.unlink(nightly_symlink)
os.symlink(tar_name, nightly_symlink)
os.chdir(dest)
tar_files = list(reversed(sorted(glob.glob('rsync-HEAD-*'))))
if len(tar_files) > 10:
for fn in tar_files[10:]:
print('Removing', fn)
os.unlink(fn)
cmd_run('ls -ltr'.split())
if args.upload:
cmd = 'rsync -aivHP --delete-after'.split()
partial_dir = os.environ.get('RSYNC_PARTIAL_DIR', None)
if partial_dir:
cmd.append('-fR ' + partial_dir)
cmd_chk([*cmd, '.', f"{samba_host}:/home/ftp/pub/rsync/dev/nightly"])
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='A helper script for "nightly" tar files.', add_help=False)
parser.add_argument('--make-tar', '-t', action='store_true', help=f"Create a new tar file in {dest}.")
parser.add_argument('--upload', '-u', action='store_true', help="Upload the revised nightly dir to {samba_host}.")
parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
args = parser.parse_args()
main()
# vim: sw=4 et

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python3 -B
#!/usr/bin/env -S python3 -B
# This script is used to turn one or more of the "patch/BASE/*" branches
# into one or more diffs in the "patches" directory. Pass the option
@@ -13,9 +13,9 @@ sys.path = ['packaging'] + sys.path
from pkglib import *
MAKE_GEN_CMDS = [
'make -f prepare-source.mak conf'.split(),
'./config.status'.split(),
'make gen'.split(),
'./prepare-source'.split(),
'cd build && if test -f config.status ; then ./config.status ; else ../configure ; fi',
'make -C build gen'.split(),
]
TMP_DIR = "patches.gen"
@@ -33,6 +33,9 @@ def main():
master_commit = latest_git_hash(args.base_branch)
if cmd_txt_chk(['packaging/prep-auto-dir']) == '':
die('You must setup an auto-build-save dir to use this script.')
if args.gen:
if os.path.lexists(TMP_DIR):
die(f'"{TMP_DIR}" must not exist in the current directory.')
@@ -42,7 +45,7 @@ def main():
cmd_chk(cmd)
cmd_chk(['rsync', '-a', *gen_files, f'{TMP_DIR}/master/'])
last_touch = time.time()
last_touch = int(time.time())
# Start by finding all patches so that we can load all possible parents.
patches = sorted(list(get_patch_branches(args.base_branch)))
@@ -91,9 +94,10 @@ def main():
if args.gen:
shutil.rmtree(TMP_DIR)
while last_touch >= time.time():
while last_touch >= int(time.time()):
time.sleep(1)
cmd_chk(['git', 'checkout', starting_branch])
cmd_chk(['packaging/prep-auto-dir'], discard='output')
def update_patch(patch):
@@ -113,31 +117,39 @@ def update_patch(patch):
print(f"======== {patch} ========")
while args.gen and last_touch >= time.time():
while args.gen and last_touch >= int(time.time()):
time.sleep(1)
s = cmd_run(f"git checkout patch/{args.base_branch}/{patch}".split())
branch = f"patch/{args.base_branch}/{patch}"
s = cmd_run(['git', 'checkout', branch])
if s.returncode != 0:
return 0
s = cmd_run(['git', 'merge', based_on])
ok = s.returncode == 0
if not ok or args.shell:
m = re.search(r'([^/]+)$', parent)
parent_dir = m[1]
if not ok:
print(f'"git merge {based_on}" incomplete -- please fix.')
os.environ['PS1'] = f"[{parent_dir}] {patch}: "
while True:
s = cmd_run([os.environ.get('SHELL', '/bin/sh')])
if s.returncode != 0:
ans = input("Abort? [n/y] ")
if re.match(r'^y', ans, flags=re.I):
return 0
continue
cur_branch, is_clean, status_txt = check_git_status(0)
if is_clean:
break
print(status_txt, end='')
skip_shell = False
if not ok or args.cmd or args.make or args.shell:
cmd_chk(['packaging/prep-auto-dir'], discard='output')
if not ok:
print(f'"git merge {based_on}" incomplete -- please fix.')
if not run_a_shell(parent, patch):
return 0
if not args.make and not args.cmd:
skip_shell = True
if args.make:
if cmd_run(['packaging/smart-make']).returncode != 0:
if not run_a_shell(parent, patch):
return 0
if not args.cmd:
skip_shell = True
if args.cmd:
if cmd_run(args.cmd).returncode != 0:
if not run_a_shell(parent, patch):
return 0
skip_shell = True
if args.shell and not skip_shell:
if not run_a_shell(parent, patch):
return 0
with open(f"{args.patches_dir}/{patch}.diff", 'w', encoding='utf-8') as fh:
fh.write(description[patch])
@@ -150,7 +162,7 @@ def update_patch(patch):
cmd_chk(['rsync', '-a', *gen_files, f"{TMP_DIR}/{patch}/"])
else:
gen_files = [ ]
last_touch = time.time()
last_touch = int(time.time())
proc = cmd_pipe(['git', 'diff', based_on])
skipping = False
@@ -185,16 +197,38 @@ def update_patch(patch):
line = plus_re.sub(r'+++ b/\1', line)
fh.write(line)
proc.communicate()
for fn in gen_files:
os.unlink(fn)
return 1
def run_a_shell(parent, patch):
m = re.search(r'([^/]+)$', parent)
parent_dir = m[1]
os.environ['PS1'] = f"[{parent_dir}] {patch}: "
while True:
s = cmd_run([os.environ.get('SHELL', '/bin/sh')])
if s.returncode != 0:
ans = input("Abort? [n/y] ")
if re.match(r'^y', ans, flags=re.I):
return False
continue
cur_branch, is_clean, status_txt = check_git_status(0)
if is_clean:
break
print(status_txt, end='')
cmd_run('rm -f build/*.o build/*/*.o')
return True
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Turn a git branch back into a diff files in the patches dir.", add_help=False)
parser.add_argument('--branch', '-b', dest='base_branch', metavar='BASE_BRANCH', default='master', help="The branch the patch is based on. Default: master.")
parser.add_argument('--skip-check', action='store_true', help="Skip the check that ensures starting with a clean branch.")
parser.add_argument('--make', '-m', action='store_true', help="Run the smart-make script in every patch branch.")
parser.add_argument('--cmd', '-c', help="Run a command in every patch branch.")
parser.add_argument('--shell', '-s', action='store_true', help="Launch a shell for every patch/BASE/* branch updated, not just when a conflict occurs.")
parser.add_argument('--gen', metavar='DIR', nargs='?', const='', help='Include generated files. Optional DIR value overrides the default of using the "patches" dir.')
parser.add_argument('--patches-dir', '-p', metavar='DIR', default='patches', help="Override the location of the rsync-patches dir. Default: patches.")
@@ -207,4 +241,4 @@ if __name__ == '__main__':
args.patches_dir = args.gen
main()
# vim: sw=4 et
# vim: sw=4 et ft=python

View File

@@ -181,45 +181,50 @@ def mandate_gensend_hook():
# Snag the GENFILES values out of the Makefile.in file and return them as a list.
def get_gen_files():
def get_gen_files(want_dir_plus_list=False):
cont_re = re.compile(r'\\\n')
extras = [ ]
gen_files = [ ]
auto_dir = os.path.join('auto-build-save', cmd_txt('git rev-parse --abbrev-ref HEAD').strip().replace('/', '%'))
with open('Makefile.in', 'r', encoding='utf-8') as fh:
for line in fh:
if not extras:
if not gen_files:
chk = re.sub(r'^GENFILES=', '', line)
if line == chk:
continue
line = chk
m = re.search(r'\\$', line)
line = re.sub(r'^\s+|\s*\\\n?$|\s+$', '', line)
extras += line.split()
gen_files += line.split()
if not m:
break
return extras
if want_dir_plus_list:
return (auto_dir, gen_files)
return [ os.path.join(auto_dir, fn) for fn in gen_files ]
def get_configure_version():
with open('configure.ac', 'r', encoding='utf-8') as fh:
for line in fh:
m = re.match(r'^AC_INIT\(\[rsync\],\s*\[(\d.+?)\]', line)
if m:
return m[1]
die("Unable to find AC_INIT with version in configure.ac")
def get_rsync_version():
with open('version.h', 'r', encoding='utf-8') as fh:
txt = fh.read()
m = re.match(r'^#define\s+RSYNC_VERSION\s+"(\d.+?)"', txt)
if m:
return m[1]
die("Unable to find RSYNC_VERSION define in version.h")
def get_OLDNEWS_version_info():
rel_re = re.compile(r'^\| \d{2} \w{3} \d{4}\s+\|\s+(?P<ver>\d+\.\d+\.\d+)\s+\|\s+(?P<pdate>\d{2} \w{3} \d{4}\s+)?\|\s+(?P<pver>\d+)\s+\|')
def get_NEWS_version_info():
rel_re = re.compile(r'^\| \S{2} \w{3} \d{4}\s+\|\s+(?P<ver>\d+\.\d+\.\d+)\s+\|\s+(?P<pdate>\d{2} \w{3} \d{4})?\s+\|\s+(?P<pver>\d+)\s+\|')
last_version = last_protocol_version = None
pdate = { }
with open('OLDNEWS.md', 'r', encoding='utf-8') as fh:
with open('NEWS.md', 'r', encoding='utf-8') as fh:
for line in fh:
if not last_version:
m = re.search(r'(\d+\.\d+\.\d+)', line)
if not last_version: # Find the first non-dev|pre version with a release date.
m = re.search(r'rsync (\d+\.\d+\.\d+) .*\d\d\d\d', line)
if m:
last_version = m[1]
m = rel_re.match(line)
@@ -228,12 +233,11 @@ def get_OLDNEWS_version_info():
pdate[m['ver']] = m['pdate']
if m['ver'] == last_version:
last_protocol_version = m['pver']
break
if not last_protocol_version:
die(f"Unable to determine protocol_version for {last_version}.")
return last_version, last_protocol_version
return last_version, last_protocol_version, pdate
def get_protocol_versions():

43
packaging/prep-auto-dir Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/sh -e
# This script will setup the build dir based on the current git branch and the
# directory auto-build-save/$BRANCH. We don't use a symlink for the build dir
# because we want to maximize the ccache reuse, so all builds must happen in
# the same real dir. When a dir is moved out of auto-build-save/$BRANCH to the
# build dir, it is replaced with a symlink so that it can still be found under
# that dir. The build dir also gets a .branch -> $BRANCH symlink so that we
# can figure out the current build dir's branch.
# To get started, just clone the rsync git repo and create the auto-build-save
# dir. If you have an existing git checkout and it is not in a pristine state,
# run "make distclean" before creating the auto-build-save dir.
auto_top='auto-build-save'
if test -d $auto_top -a -d .git; then
desired_branch=`git rev-parse --abbrev-ref HEAD | tr / %`
if test "$desired_branch" = HEAD; then
echo "ERROR: switch to the right build dir manually when in detached HEAD mode." 1>&2
exit 1
fi
auto_dir="$auto_top/$desired_branch"
if test -d build; then
cur_branch=`readlink build/.branch`
else
cur_branch='/'
fi
if test "$desired_branch" != "$cur_branch"; then
if test "$cur_branch" != /; then
rm -f "$auto_top/$cur_branch"
mv build "$auto_top/$cur_branch"
fi
test -d "$auto_dir" || mkdir "$auto_dir"
test -h "$auto_dir/.branch" || ln -s "$desired_branch" "$auto_dir/.branch"
mv "$auto_dir" build
ln -s ../build "$auto_dir"
fi
if test ! -h Makefile; then
rm -f Makefile
ln -s packaging/auto-Makefile Makefile
fi
echo $desired_branch
fi

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python3 -B
#!/usr/bin/env -S python3 -B
# This script expects the directory ~/samba-rsync-ftp to exist and to be a
# copy of the /home/ftp/pub/rsync dir on samba.org. When the script is done,
@@ -13,6 +13,7 @@ sys.path = ['packaging'] + sys.path
from pkglib import *
os.environ['LESS'] = 'mqeiXR'; # Make sure that -F is turned off and -R is turned on.
dest = os.environ['HOME'] + '/samba-rsync-ftp'
ORIGINAL_PATH = os.environ['PATH']
@@ -29,7 +30,11 @@ def main():
signal.signal(signal.SIGINT, signal_handler)
gen_files = get_gen_files()
if cmd_txt_chk(['packaging/prep-auto-dir']) == '':
die('You must setup an auto-build-save dir to use this script.');
auto_dir, gen_files = get_gen_files(True)
gen_pathnames = [ os.path.join(auto_dir, fn) for fn in gen_files ]
dash_line = '=' * 74
@@ -52,13 +57,13 @@ def main():
check_git_state(args.master_branch, True, 'patches')
confversion = get_configure_version()
curversion = get_rsync_version()
# All version values are strings!
lastversion, last_protocol_version = get_OLDNEWS_version_info()
lastversion, last_protocol_version, pdate = get_NEWS_version_info()
protocol_version, subprotocol_version = get_protocol_versions()
version = confversion
version = curversion
m = re.search(r'pre(\d+)', version)
if m:
version = re.sub(r'pre\d+', 'pre' + str(int(m[1]) + 1), version)
@@ -75,12 +80,9 @@ def main():
v_ver = 'v' + version
rsync_ver = 'rsync-' + version
rsync_lastver = 'rsync-' + lastversion
if os.path.lexists(rsync_ver):
die(f'"{rsync_ver}" must not exist in the current directory.')
if os.path.lexists(rsync_lastver):
die(f'"{rsync_lastver}" must not exist in the current directory.')
out = cmd_txt_chk(['git', 'tag', '-l', v_ver])
if out != '':
@@ -91,14 +93,18 @@ def main():
cmd_chk(['git', 'tag', '-d', v_ver])
version = re.sub(r'[-.]*pre[-.]*', 'pre', version)
if 'pre' in version and not confversion.endswith('dev'):
lastversion = confversion
if 'pre' in version and not curversion.endswith('dev'):
lastversion = curversion
ans = input(f"Enter the previous version to produce a patch against: [{lastversion}] ")
if ans != '':
lastversion = ans
lastversion = re.sub(r'[-.]*pre[-.]*', 'pre', lastversion)
rsync_lastver = 'rsync-' + lastversion
if os.path.lexists(rsync_lastver):
die(f'"{rsync_lastver}" must not exist in the current directory.')
m = re.search(r'(pre\d+)', version)
pre = m[1] if m else ''
@@ -110,11 +116,8 @@ def main():
release += '.' + pre
finalversion = re.sub(r'pre\d+', '', version)
if protocol_version == last_protocol_version:
proto_changed = 'unchanged'
proto_change_date = ' ' * 11
else:
proto_changed = 'changed'
proto_changed = protocol_version != last_protocol_version
if proto_changed:
if finalversion in pdate:
proto_change_date = pdate[finalversion]
else:
@@ -123,6 +126,8 @@ def main():
if re.match(r'^\d\d \w\w\w \d\d\d\d$', ans):
break
proto_change_date = ans
else:
proto_change_date = ' ' * 11
if 'pre' in lastversion:
if not pre:
@@ -151,8 +156,8 @@ release is "{release}"
About to:
- tweak SUBPROTOCOL_VERSION in rsync.h, if needed
- tweak the version in configure.ac and the spec files
- tweak NEWS.md and OLDNEWS.md to ensure header values are correct
- tweak the version in version.h and the spec files
- tweak NEWS.md to ensure header values are correct
- generate configure.sh, config.h.in, and proto.h
- page through the differences
""")
@@ -166,16 +171,15 @@ About to:
'%define srcdir': srcdir,
}
tweak_files = 'configure.ac rsync.h NEWS.md OLDNEWS.md'.split()
tweak_files = 'version.h rsync.h NEWS.md'.split()
tweak_files += glob.glob('packaging/*.spec')
tweak_files += glob.glob('packaging/*/*.spec')
for fn in tweak_files:
with open(fn, 'r', encoding='utf-8') as fh:
old_txt = txt = fh.read()
if 'configure' in fn:
x_re = re.compile(r'^(AC_INIT\(\[rsync\],\s*\[)\d.+?(\])', re.M)
txt = replace_or_die(x_re, r'\g<1>%s\2' % version, txt, f"Unable to update AC_INIT with version in {fn}")
if fn == 'version.h':
txt = f'#define RSYNC_VERSION "{version}"\n'
elif '.spec' in fn:
for var, val in specvars.items():
x_re = re.compile(r'^%s .*' % re.escape(var), re.M)
@@ -184,19 +188,20 @@ About to:
txt = replace_or_die(x_re, r'%s \1' % cl_today, txt, f"Unable to update ChangeLog header in {fn}")
elif fn == 'rsync.h':
x_re = re.compile('(#define\s+SUBPROTOCOL_VERSION)\s+(\d+)')
repl = lambda m: m[1] + ' ' + '0' if not pre or proto_changed != 'changed' else 1 if m[2] == '0' else m[2]
repl = lambda m: m[1] + ' ' + ('0' if not pre or not proto_changed else '1' if m[2] == '0' else m[2])
txt = replace_or_die(x_re, repl, txt, f"Unable to find SUBPROTOCOL_VERSION define in {fn}")
elif fn == 'NEWS.md':
x_re = re.compile(
r'^(# NEWS for rsync %s )(\(UNRELEASED\))\s*(\n\nProtocol: )(\d+) (\([^)]+\))\n' % re.escape(finalversion),
re.I)
repl = lambda m: m[1] + (m[2] if pre else f"({today})") + m[3] + f"{protocol_version} ({proto_changed})\n"
msg = (f"The first 3 lines of {fn} are not in the right format. They must be:\n"
+ f"# NEWS for rsync {finalversion} (UNRELEASED)\n\n"
+ f"Protocol: {protocol_version} ({proto_changed})")
txt = replace_or_die(x_re, repl, txt, msg)
elif fn == 'OLDNEWS.md':
efv = re.escape(finalversion)
x_re = re.compile(r'^<.+>\s+# NEWS for rsync %s \(UNRELEASED\)\s+## Changes in this version:\n' % efv
+ r'(\n### PROTOCOL NUMBER:\s+- The protocol number was changed to \d+\.\n)?')
rel_day = 'UNRELEASED' if pre else today
repl = (f'<a name="{finalversion}"></a>\n\n# NEWS for rsync {finalversion} ({rel_day})\n\n'
+ '## Changes in this version:\n')
if proto_changed:
repl += f'\n### PROTOCOL NUMBER:\n\n - The protocol number was changed to {protocol_version}.\n'
good_top = re.sub(r'\(.*?\)', '(UNRELEASED)', repl, 1)
msg = f"The top lines of {fn} are not in the right format. It should be:\n" + good_top
txt = replace_or_die(x_re, repl, txt, msg)
x_re = re.compile(r'^(\| )(\S{2} \S{3} \d{4})(\s+\|\s+%s\s+\| ).{11}(\s+\| )\S{2}(\s+\|+)$' % efv, re.M)
repl = lambda m: m[1] + (m[2] if pre else ztoday) + m[3] + proto_change_date + m[4] + protocol_version + m[5]
txt = replace_or_die(x_re, repl, txt, f'Unable to find "| ?? ??? {year} | {finalversion} | ... |" line in {fn}')
@@ -216,11 +221,10 @@ About to:
srctar_name = f"{rsync_ver}.tar.gz"
pattar_name = f"rsync-patches-{version}.tar.gz"
diff_name = f"{rsync_lastver}-{version}.diffs.gz"
srctar_file = f"{dest}/{srcdir}/{srctar_name}"
pattar_file = f"{dest}/{srcdir}/{pattar_name}"
diff_file = f"{dest}/{srcdiffdir}/{diff_name}"
news_file = f"{dest}/{srcdir}/{rsync_ver}-NEWS.md"
lasttar_file = f"{dest}/{lastsrcdir}/{rsync_lastver}.tar.gz"
srctar_file = os.path.join(dest, srcdir, srctar_name)
pattar_file = os.path.join(dest, srcdir, pattar_name)
diff_file = os.path.join(dest, srcdiffdir, diff_name)
lasttar_file = os.path.join(dest, lastsrcdir, rsync_lastver + '.tar.gz')
print(f"""\
{dash_line}
@@ -229,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> ")
@@ -238,8 +242,7 @@ About to:
if s.returncode:
die('Aborting')
cmd_chk('make reconfigure ; make gen')
cmd_chk(['rsync', '-a', *gen_files, 'SaVeDiR/'])
cmd_chk('make gen')
print(f'Creating any missing patch branches.')
s = cmd_run(f'packaging/branch-from-patch --branch={args.master_branch} --add-missing')
@@ -252,12 +255,8 @@ About to:
die('Aborting')
if re.match(r'^y', ans, re.I):
print(f'\nVisiting all "patch/{args.master_branch}/*" branches ...')
cmd_run(f"packaging/patch-update --branch={args.master_branch} --skip-check --shell")
cmd_run("rm -f *.[o15] *.html")
cmd_chk('rsync -a SaVeDiR/ .'.split())
shutil.rmtree('SaVeDiR')
cmd_chk('make gen'.split())
print(f'\nRunning smart-make on all "patch/{args.master_branch}/*" branches ...')
cmd_run(f"packaging/patch-update --branch={args.master_branch} --skip-check --make")
if os.path.isdir('patches/.git'):
s = cmd_run(f"cd patches && git commit -a -m 'The patches for {version}.'")
@@ -273,7 +272,7 @@ About to:
- create release tar, "{srctar_name}"
- generate {rsync_ver}/patches/* files
- create patches tar, "{pattar_name}"
- update top-level README.md, *NEWS.md, TODO, and ChangeLog
- update top-level README.md, NEWS.md, TODO, and ChangeLog
- update top-level rsync*.html manpages
- gpg-sign the release files
- update hard-linked top-level release files{skipping}
@@ -297,12 +296,12 @@ About to:
os.environ['PATH'] = ORIGINAL_PATH
# Extract the generated files from the old tar.
tweaked_gen_files = [ f"{rsync_lastver}/{x}" for x in gen_files ]
tweaked_gen_files = [ os.path.join(rsync_lastver, fn) for fn in gen_files ]
cmd_run(['tar', 'xzf', lasttar_file, *tweaked_gen_files])
os.rename(rsync_lastver, 'a')
print(f"Creating {diff_file} ...")
cmd_chk(['rsync', '-a', *gen_files, 'b/'])
cmd_chk(['rsync', '-a', *gen_pathnames, 'b/'])
sed_script = r's:^((---|\+\+\+) [ab]/[^\t]+)\t.*:\1:' # CAUTION: must not contain any single quotes!
cmd_chk(f"(git diff v{lastversion} {v_ver} -- ':!.github'; diff -upN a b | sed -r '{sed_script}') | gzip -9 >{diff_file}")
@@ -325,15 +324,12 @@ About to:
shutil.rmtree(rsync_ver)
print(f"Updating the other files in {dest} ...")
cmd_chk('rsync -a README.md NEWS.md OLDNEWS.md TODO'.split() + [dest])
if os.path.lexists(news_file):
os.unlink(news_file)
os.link(f"{dest}/NEWS.md", news_file)
cmd_chk(f"git log --name-status | gzip -9 >{dest}/ChangeLog.gz")
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 ])
for md_fn in glob.glob('*.[1-9].md'):
html_fn = md_fn.replace('.md', '.html')
cmd_chk(['rsync', '-a', html_fn, os.path.join(dest, html_fn)])
cmd_chk(f"git log --name-status | gzip -9 >{dest}/ChangeLog.gz")
for fn in (srctar_file, pattar_file, diff_file):
asc_fn = fn + '.asc'
@@ -344,14 +340,13 @@ About to:
die("gpg signing failed")
if not pre:
for find in f'{dest}/rsync-*.gz {dest}/rsync-*.asc {dest}/rsync-*-NEWS.md {dest}/src-previews/rsync-*diffs.gz*'.split():
for find in f'{dest}/rsync-*.gz {dest}/rsync-*.asc {dest}/src-previews/rsync-*diffs.gz*'.split():
for fn in glob.glob(find):
os.unlink(fn)
top_link = [
srctar_file, f"{srctar_file}.asc",
pattar_file, f"{pattar_file}.asc",
diff_file, f"{diff_file}.asc",
news_file,
]
for fn in top_link:
os.link(fn, re.sub(r'/src(-\w+)?/', '/', fn))
@@ -383,4 +378,4 @@ if __name__ == '__main__':
args = parser.parse_args()
main()
# vim: sw=4 et
# vim: sw=4 et ft=python

47
packaging/smart-make Executable file
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

@@ -1,9 +1,31 @@
[Unit]
Description=fast remote file copy program daemon
ConditionPathExists=/etc/rsyncd.conf
After=network.target
Documentation=man:rsync(1) man:rsyncd.conf(5)
[Service]
ExecStart=/usr/bin/rsync --daemon --no-detach
RestartSec=1
# Citing README.md:
#
# [...] Using ssh is recommended for its security features.
#
# Alternatively, rsync can run in `daemon' mode, listening on a socket.
# This is generally used for public file distribution, [...]
#
# So let's assume some extra security is more than welcome here. We do full
# system protection (which makes /usr, /boot, & /etc read-only) and hide
# devices. To override these defaults, it's best to do so in the drop-in
# directory, often done via `systemctl edit rsync.service`. The file needs
# just the bare minimum of the right [heading] and override values.
# See systemd.unit(5) and search for "drop-in" for full details.
ProtectSystem=full
#ProtectHome=on|off|read-only
PrivateDevices=on
NoNewPrivileges=on
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,10 @@
[Unit]
Description=socket for fast remote file copy program daemon
Conflicts=rsync.service
[Socket]
ListenStream=873
Accept=true
[Install]
WantedBy=sockets.target

View File

@@ -0,0 +1,28 @@
[Unit]
Description=fast remote file copy program daemon
After=network.target
[Service]
ExecStart=-/usr/bin/rsync --daemon
StandardInput=socket
StandardOutput=inherit
StandardError=journal
# Citing README.md:
#
# [...] Using ssh is recommended for its security features.
#
# Alternatively, rsync can run in `daemon' mode, listening on a socket.
# This is generally used for public file distribution, [...]
#
# So let's assume some extra security is more than welcome here. We do full
# system protection (which makes /usr, /boot, & /etc read-only) and hide
# devices. To override these defaults, it's best to do so in the drop-in
# directory, often done via `systemctl edit rsync@.service`. The file needs
# just the bare minimum of the right [heading] and override values.
# See systemd.unit(5) and search for "drop-in" for full details.
ProtectSystem=full
#ProtectHome=on|off|read-only
PrivateDevices=on
NoNewPrivileges=on

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python3 -B
#!/usr/bin/env -S python3 -B
# This script checks the *.c files for extraneous "extern" variables,
# for vars that are defined but not used, and for inconsistent array
@@ -84,4 +84,4 @@ if __name__ == '__main__':
args = parser.parse_args()
main()
# vim: sw=4 et
# vim: sw=4 et ft=python

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python3
# This uses the output from "support/git-set-file-times --list" to discern
# the last-modified year of each *.c & *.h file and updates the copyright

View File

@@ -212,11 +212,6 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
{
bSize += BUFR_INC;
bufr = realloc_array( bufr, char, bSize );
if( NULL == bufr )
{
rprintf(FLOG, "%s Memory re-allocation failure.", func);
return( False );
}
}
/* Handle a single character. */
@@ -306,11 +301,6 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
{
bSize += BUFR_INC;
bufr = realloc_array( bufr, char, bSize );
if( NULL == bufr )
{
rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
return( False );
}
}
switch( c )
@@ -382,11 +372,6 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
{
bSize += BUFR_INC;
bufr = realloc_array( bufr, char, bSize );
if( NULL == bufr )
{
rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
return( False );
}
}
switch( c )
@@ -639,12 +624,6 @@ int pm_process( char *FileName,
{ /* allocate one, then parse, */
bSize = BUFR_INC; /* then free. */
bufr = new_array( char, bSize );
if( NULL == bufr )
{
rprintf(FLOG, "%s memory allocation failure.\n", func);
fclose(InFile);
return( False );
}
result = Parse( InFile, sfunc, pfunc );
free( bufr );
bufr = NULL;

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.
@@ -16,6 +16,26 @@ if test x"$dir" = x; then
dir=.
fi
if test "$dir" = '.'; then
branch=`packaging/prep-auto-dir` || exit 1
if test x"$branch" != x; then
cd build || exit 1
dir=..
fi
fi
if test "$dir" != '.'; then
for lnk in configure.ac m4; do
if test ! -h $lnk; then
rm -f $lnk # Just in case
ln -s "$dir/$lnk" $lnk
fi
done
for fn in configure.sh config.h.in aclocal.m4; do
test ! -f $fn -a -f "$dir/$fn" && cp -p "$dir/$fn" $fn
done
fi
if test $# = 0; then
set -- build
fi
@@ -23,17 +43,18 @@ fi
for action in "${@}"; do
case "$action" in
build|make)
(cd $dir && make -f prepare-source.mak)
make -f "$dir/prepare-source.mak"
;;
fetch)
$dir/rsync-ssl -iip --no-motd rsync://download.samba.org/rsyncftp/generated-files/'[ca]*' $dir
if ! perl --version >/dev/null 2>/dev/null; then
$dir/rsync-ssl -iip --no-motd rsync://download.samba.org/rsyncftp/generated-files/'p*' .
fetch|fetchgen)
if test "$action" = fetchgen; then
match='*'
else
match='[ca]*'
fi
;;
fetchgen)
$dir/rsync-ssl -iip --no-motd rsync://download.samba.org/rsyncftp/generated-files/'[ca]*' $dir
$dir/rsync-ssl -iip --no-motd rsync://download.samba.org/rsyncftp/generated-files/'[^ca]*' .
$dir/rsync-ssl -iipc --no-motd "rsync://download.samba.org/rsyncftp/generated-files/$match" ./
test $? != 0 && continue
sleep 1 # The following files need to be newer than aclocal.m4
touch configure.sh config.h.in
;;
fetchSRC)
./rsync-ssl -iipr --no-motd --exclude=/.git/ rsync://download.samba.org/ftp/pub/unpacked/rsync/ .
@@ -41,6 +62,7 @@ for action in "${@}"; do
*)
echo "Unknown action: $action"
exit 1
;;
esac
if test $? = 0; then
exit

View File

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

View File

@@ -24,11 +24,11 @@
struct test {
union file_extras extras[ARRAY_LEN];
struct file_struct file;
int64 test;
};
#define ACTUAL_SIZE SIZEOF(struct test)
#define EXPECTED_SIZE (SIZEOF(union file_extras) * ARRAY_LEN + SIZEOF(struct file_struct))
#define EXPECTED_SIZE (SIZEOF(union file_extras) * ARRAY_LEN + SIZEOF(int64))
int main(UNUSED(int argc), UNUSED(char *argv[]))
{

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#!/usr/bin/env bash
# This script supports using stunnel or openssl to secure an rsync daemon connection.
# This script uses openssl, gnutls, or stunnel to secure an rsync daemon connection.
# By default this script takes rsync args and hands them off to the actual
# rsync command with an --rsh option that makes it open an SSL connection to an
@@ -31,10 +31,13 @@ function rsync_ssl_run {
function rsync_ssl_helper {
if [[ -z "$RSYNC_SSL_TYPE" ]]; then
found=`path_search stunnel4 stunnel openssl` || exit 1
found=`path_search openssl stunnel4 stunnel` || exit 1
if [[ "$found" == */openssl ]]; then
RSYNC_SSL_TYPE=openssl
RSYNC_SSL_OPENSSL="$found"
elif [[ "$found" == */gnutls-cli ]]; then
RSYNC_SSL_TYPE=gnutls
RSYNC_SSL_GNUTLS="$found"
else
RSYNC_SSL_TYPE=stunnel
RSYNC_SSL_STUNNEL="$found"
@@ -48,6 +51,12 @@ function rsync_ssl_helper {
fi
optsep=' '
;;
gnutls)
if [[ -z "$RSYNC_SSL_GNUTLS" ]]; then
RSYNC_SSL_GNUTLS=`path_search gnutls-cli` || exit 1
fi
optsep=' '
;;
stunnel)
if [[ -z "$RSYNC_SSL_STUNNEL" ]]; then
RSYNC_SSL_STUNNEL=`path_search stunnel4 stunnel` || exit 1
@@ -62,31 +71,42 @@ function rsync_ssl_helper {
if [[ -z "$RSYNC_SSL_CERT" ]]; then
certopt=""
gnutls_cert_opt=""
else
certopt="cert$optsep$RSYNC_SSL_CERT"
gnutls_cert_opt="--x509keyfile=$RSYNC_SSL_CERT"
fi
if [[ -z ${RSYNC_SSL_CA_CERT+x} ]]; then
# RSYNC_SSL_CA_CERT unset - default CA set AND verify:
# openssl:
caopt="-verify_return_error -verify 4"
# gnutls:
gnutls_opts=""
# stunnel:
# Since there is no way of using the default CA certificate collection,
# we cannot do any verification. Thus, stunnel should really only be
# used if nothing else is available.
cafile=""
verify=0
verify=""
elif [[ "$RSYNC_SSL_CA_CERT" == "" ]]; then
# RSYNC_SSL_CA_CERT set but empty -do NO verifications:
# openssl:
caopt="-verify 1"
# gnutls:
gnutls_opts="--insecure"
# stunnel:
cafile=""
verify=0
verify="verifyChain = no"
else
# RSYNC_SSL_CA_CERT set - use CA AND verify:
# openssl:
caopt="-CAfile $RSYNC_SSL_CA_CERT -verify_return_error -verify 4"
# gnutls:
gnutls_opts="--x509cafile=$RSYNC_SSL_CA_CERT"
# stunnel:
cafile="CAfile = $RSYNC_SSL_CA_CERT"
verify=3
verify="verifyChain = yes"
fi
port="${RSYNC_PORT:-0}"
@@ -110,6 +130,8 @@ function rsync_ssl_helper {
if [[ $RSYNC_SSL_TYPE == openssl ]]; then
exec $RSYNC_SSL_OPENSSL s_client $caopt $certopt -quiet -verify_quiet -servername $hostname -connect $hostname:$port
elif [[ $RSYNC_SSL_TYPE == gnutls ]]; then
exec $RSYNC_SSL_GNUTLS --logfile=/dev/null $gnutls_cert_opt $gnutls_opts $hostname:$port
else
# devzero@web.de came up with this no-tmpfile calling syntax:
exec $RSYNC_SSL_STUNNEL -fd 10 11<&0 <<EOF 10<&0 0<&11 11<&-
@@ -118,7 +140,7 @@ debug = crit
connect = $hostname:$port
client = yes
TIMEOUTclose = 0
verify = $verify
$verify
$certopt
$cafile
EOF
@@ -146,7 +168,8 @@ function path_search {
}
if [[ "$#" == 0 ]]; then
echo "Usage: rsync-ssl [--type=openssl|stunnel] RSYNC_ARG [...]" 1>&2
echo "Usage: rsync-ssl [--type=SSL_TYPE] RSYNC_ARG [...]" 1>&2
echo "The SSL_TYPE can be openssl or stunnel"
exit 1
fi

View File

@@ -5,7 +5,7 @@ rsync-ssl - a helper script for connecting to an ssl rsync daemon
# SYNOPSIS
```
rsync-ssl [--type=openssl|stunnel] RSYNC_ARGS
rsync-ssl [--type=SSL_TYPE] RSYNC_ARGS
```
# DESCRIPTION
@@ -13,26 +13,32 @@ rsync-ssl [--type=openssl|stunnel] RSYNC_ARGS
The rsync-ssl script helps you to run an rsync copy to/from an rsync daemon
that requires ssl connections.
If the **first** arg is a `--type=NAME` option, the script will only use that
particular program to open an ssl connection instead of trying to find an
stunnel or openssl executable via a simple heuristic (assuming that the
The script requires that you specify an rsync-daemon arg in the style of either
`hostname::` (with 2 colons) or `rsync://hostname/`. The default port used for
connecting is 874 (one higher than the normal 873) unless overridden in the
environment. You can specify an overriding port via `--port` or by including
it in the normal spot in the URL format, though both of those require your
rsync version to be at least 3.2.0.
# OPTIONS
If the **first** arg is a `--type=SSL_TYPE` option, the script will only use
that particular program to open an ssl connection instead of trying to find an
openssl or stunnel executable via a simple heuristic (assuming that the
`RSYNC_SSL_TYPE` environment variable is not set as well -- see below). This
option must be one of `--type=openssl` or `--type=stunnel`. The equal sign is
option must specify one of `openssl` or `stunnel`. The equal sign is
required for this particular option.
All the other options are passed through to the rsync command, so consult the
**rsync** manpage for more information on how it works.
Note that the stunnel connection type requires at least version 4 of stunnel,
which should be the case on modern systems.
**rsync**(1) manpage for more information on how it works.
# ENVIRONMENT VARIABLES
The ssl helper scripts are affected by the following environment variables:
0. `RSYNC_SSL_TYPE` Specifies the program type that should be used to open the
ssl connection. It must be one of "openssl" or "stunnel". The
`--type=NAME` option overrides this, if specified.
ssl connection. It must be one of `openssl` or `stunnel`. The
`--type=SSL_TYPE` option overrides this, when specified.
0. `RSYNC_SSL_PORT` If specified, the value is the port number that is used as
the default when the user does not specify a port in their rsync command.
When not specified, the default port number is 874. (Note that older rsync
@@ -42,26 +48,46 @@ The ssl helper scripts are affected by the following environment variables:
certificate to use for the connection.
0. `RSYNC_SSL_CA_CERT` If specified, the value is a filename that contains a
certificate authority certificate that is used to validate the connection.
0. `RSYNC_SSL_STUNNEL` Specifies the stunnel executable to run when the
connection type is set to stunnel. If unspecified, the $PATH is searched
first for "stunnel4" and then for "stunnel".
0. `RSYNC_SSL_OPENSSL` Specifies the openssl executable to run when the
connection type is set to openssl. If unspecified, the $PATH is searched
for "openssl".
0. `RSYNC_SSL_GNUTLS` Specifies the gnutls-cli executable to run when the
connection type is set to gnutls. If unspecified, the $PATH is searched
for "gnutls-cli".
0. `RSYNC_SSL_STUNNEL` Specifies the stunnel executable to run when the
connection type is set to stunnel. If unspecified, the $PATH is searched
first for "stunnel4" and then for "stunnel".
# EXAMPLES
> rsync-ssl -aiv example.com::src/ dest
> rsync-ssl -aiv example.com::mod/ dest
> rsync-ssl --type=openssl -aiv example.com::src/ dest
> rsync-ssl --type=openssl -aiv example.com::mod/ dest
> rsync-ssl -aiv --port 9874 example.com::mod/ dest
> rsync-ssl -aiv rsync://example.com:9874/mod/ dest
# SEE ALSO
**rsync**(1), **rsyncd.conf**(5)
# CAVEATS
Note that using an stunnel connection requires at least version 4 of stunnel,
which should be the case on modern systems. Also, it does not verify a
connection against the CA certificate collection, so it only encrypts the
connection without any cert validation unless you have specified the
certificate environment options.
This script also supports a `--type=gnutls` option, but at the time of this
release the gnutls-cli command was dropping output, making it unusable. If
that bug has been fixed in your version, feel free to put gnutls into an
exported RSYNC_SSL_TYPE environment variable to make its use the default.
# BUGS
Please report bugs! See the web site at <http://rsync.samba.org/>.
Please report bugs! See the web site at <https://rsync.samba.org/>.
# VERSION
@@ -72,7 +98,7 @@ This man page is current for version @VERSION@ of rsync.
rsync is distributed under the GNU General Public License. See the file
COPYING for details.
A web site is available at <http://rsync.samba.org/>. The site includes an
A web site is available at <https://rsync.samba.org/>. The site includes an
FAQ-O-Matic which may cover questions unanswered by this manual page.
# AUTHOR
@@ -80,4 +106,4 @@ FAQ-O-Matic which may cover questions unanswered by this manual page.
This manpage was written by Wayne Davison.
Mailing lists for support and development are available at
<http://lists.samba.org/>.
<https://lists.samba.org/>.

View File

File diff suppressed because it is too large Load Diff

29
rsync.c
View File

@@ -57,12 +57,6 @@ extern struct chmod_mode_struct *daemon_chmod_modes;
extern char *iconv_opt;
#endif
#ifdef ICONV_CONST
iconv_t ic_chck = (iconv_t)-1;
# ifdef ICONV_OPTION
iconv_t ic_send = (iconv_t)-1, ic_recv = (iconv_t)-1;
# endif
#define UPDATED_OWNER (1<<0)
#define UPDATED_GROUP (1<<1)
#define UPDATED_MTIME (1<<2)
@@ -72,6 +66,12 @@ iconv_t ic_send = (iconv_t)-1, ic_recv = (iconv_t)-1;
#define UPDATED_TIMES (UPDATED_MTIME|UPDATED_ATIME)
#ifdef ICONV_CONST
iconv_t ic_chck = (iconv_t)-1;
# ifdef ICONV_OPTION
iconv_t ic_send = (iconv_t)-1, ic_recv = (iconv_t)-1;
# endif
static const char *default_charset(void)
{
# if defined HAVE_LIBCHARSET_H && defined HAVE_LOCALE_CHARSET
@@ -584,6 +584,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
memcpy(&sx2.st, &sxp->st, sizeof (sx2.st));
if (!atimes_ndx || S_ISDIR(sxp->st.st_mode))
flags |= ATTRS_SKIP_ATIME;
/* Don't set the creation date on the root folder of an HFS+ volume. */
if (sxp->st.st_ino == 2 && S_ISDIR(sxp->st.st_mode))
flags |= ATTRS_SKIP_CRTIME;
if (!(flags & ATTRS_SKIP_MTIME) && !same_mtime(file, &sxp->st, flags & ATTRS_ACCURATE_TIME)) {
sx2.st.st_mtime = file->modtime;
#ifdef ST_MTIME_NSEC
@@ -613,6 +616,16 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
file->flags |= FLAG_TIME_FAILED;
}
}
#ifdef SUPPORT_CRTIMES
if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) {
time_t file_crtime = F_CRTIME(file);
if (sxp->crtime == 0)
sxp->crtime = get_create_time(fname);
if (!same_time(sxp->crtime, 0L, file_crtime, 0L)
&& set_create_time(fname, file_crtime) == 0)
updated = 1;
}
#endif
#ifdef SUPPORT_ACLS
/* It's OK to call set_acl() now, even for a dir, as the generator
@@ -718,7 +731,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
/* Change permissions before putting the file into place. */
set_file_attrs(fnametmp, file, NULL, fnamecmp,
ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME);
ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME | ATTRS_SKIP_CRTIME);
/* move tmp file over real file */
if (DEBUG_GTE(RECV, 1))
@@ -743,7 +756,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
do_set_file_attrs:
set_file_attrs(fnametmp, file, NULL, fnamecmp,
ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME);
ok_to_set_time ? ATTRS_ACCURATE_TIME : ATTRS_SKIP_MTIME | ATTRS_SKIP_ATIME | ATTRS_SKIP_CRTIME);
if (temp_copy_name) {
if (do_rename(fnametmp, fname) < 0) {

95
rsync.h
View File

@@ -20,6 +20,7 @@
#define False 0
#define True 1
#define Unset (-1) /* Our BOOL values are always an int. */
#define BLOCK_SIZE 700
#define RSYNC_RSH_ENV "RSYNC_RSH"
@@ -69,7 +70,7 @@
/* The following XMIT flags require an rsync that uses a varint for the flag values */
#define XMIT_RESERVED_16 (1<<16) /* reserved for future fileflags use */
#define XMIT_RESERVED_17 (1<<17) /* reserved for future crtimes use */
#define XMIT_CRTIME_EQ_MTIME (1<<17) /* any protocol - restricted by command-line option */
/* These flags are used in the live flist data. */
@@ -181,6 +182,7 @@
#define ATTRS_SKIP_MTIME (1<<1)
#define ATTRS_ACCURATE_TIME (1<<2)
#define ATTRS_SKIP_ATIME (1<<3)
#define ATTRS_SKIP_CRTIME (1<<5)
#define MSG_FLUSH 2
#define FULL_FLUSH 1
@@ -208,6 +210,7 @@
#define ITEM_REPORT_GROUP (1<<6)
#define ITEM_REPORT_ACL (1<<7)
#define ITEM_REPORT_XATTR (1<<8)
#define ITEM_REPORT_CRTIME (1<<10)
#define ITEM_BASIS_TYPE_FOLLOWS (1<<11)
#define ITEM_XNAME_FOLLOWS (1<<12)
#define ITEM_IS_NEW (1<<13)
@@ -297,6 +300,7 @@ enum delret {
#include "errcode.h"
#include "config.h"
#include "version.h"
/* The default RSYNC_RSH is always set in config.h. */
@@ -440,7 +444,9 @@ enum delret {
#include <netdb.h>
#endif
#include <syslog.h>
#ifdef HAVE_SYS_FILE_H
#include <sys/file.h>
#endif
#ifdef HAVE_DIRENT_H
# include <dirent.h>
@@ -469,7 +475,23 @@ enum delret {
#ifdef MAKEDEV_TAKES_3_ARGS
#define MAKEDEV(devmajor,devminor) makedev(0,devmajor,devminor)
#else
#ifndef __TANDEM
#define MAKEDEV(devmajor,devminor) makedev(devmajor,devminor)
#else
# include <sys/stat.h>
# define major DEV_TO_MAJOR
# define minor DEV_TO_MINOR
# define MAKEDEV MAJORMINOR_TO_DEV
#endif
#endif
#ifdef __TANDEM
# include <floss.h(floss_read,floss_write,floss_fork,floss_execvp)>
# include <floss.h(floss_getpwuid,floss_select,floss_seteuid)>
# define S_IEXEC S_IXUSR
# define ROOT_UID 65535
#else
# define ROOT_UID 0
#endif
#ifdef HAVE_COMPAT_H
@@ -548,6 +570,14 @@ typedef unsigned int size_t;
#endif
#endif
#ifndef __APPLE__ /* Do we need a configure check for this? */
#define SUPPORT_ATIMES 1
#endif
#ifdef HAVE_GETATTRLIST
#define SUPPORT_CRTIMES 1
#endif
/* Find a variable that is either exactly 32-bits or longer.
* If some code depends on 32-bit truncation, it will need to
* take special action in a "#if SIZEOF_INT32 > 4" section. */
@@ -691,6 +721,10 @@ struct ht_int64_node {
#define NAME_MAX 255
#endif
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
@@ -730,6 +764,10 @@ struct ht_int64_node {
# error Character pointers are not 4 or 8 bytes.
#endif
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#define USE_FLEXIBLE_ARRAY 1
#endif
union file_extras {
int32 num;
uint32 unum;
@@ -751,12 +789,17 @@ struct file_struct {
uint32 len32; /* Lowest 32 bits of the file's length */
uint16 mode; /* The item's type and permissions */
uint16 flags; /* The FLAG_* bits for this item */
const char basename[1]; /* The basename (AKA filename) follows */
#ifdef USE_FLEXIBLE_ARRAY
const char basename[]; /* The basename (AKA filename) follows */
#else
const char basename[1]; /* A kluge that should work like a flexible array */
#endif
};
extern int file_extra_cnt;
extern int inc_recurse;
extern int atimes_ndx;
extern int crtimes_ndx;
extern int pathname_ndx;
extern int depth_ndx;
extern int uid_ndx;
@@ -764,7 +807,11 @@ extern int gid_ndx;
extern int acls_ndx;
extern int xattrs_ndx;
#ifdef USE_FLEXIBLE_ARRAY
#define FILE_STRUCT_LEN (sizeof (struct file_struct))
#else
#define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
#endif
#define EXTRA_LEN (sizeof (union file_extras))
#define DEV_EXTRA_CNT 2
#define DIRNODE_EXTRA_CNT 3
@@ -815,6 +862,7 @@ extern int xattrs_ndx;
#define F_XATTR(f) REQ_EXTRA(f, xattrs_ndx)->num
#define F_NDX(f) REQ_EXTRA(f, unsort_ndx)->num
#define F_ATIME(f) REQ_EXTRA64(f, atimes_ndx)->num
#define F_CRTIME(f) REQ_EXTRA64(f, crtimes_ndx)->num
/* These items are per-entry optional: */
#define F_HL_GNUM(f) OPT_EXTRA(f, START_BUMP(f))->num /* non-dirs */
@@ -1033,9 +1081,19 @@ typedef struct {
typedef struct {
char name_type;
char fname[1]; /* has variable size */
#ifdef USE_FLEXIBLE_ARRAY
char fname[]; /* has variable size */
#else
char fname[1]; /* A kluge that should work like a flexible array */
#endif
} relnamecache;
#ifdef USE_FLEXIBLE_ARRAY
#define RELNAMECACHE_LEN (sizeof (relnamecache))
#else
#define RELNAMECACHE_LEN (offsetof(relnamecache, fname))
#endif
#include "byteorder.h"
#include "lib/mdigest.h"
#include "lib/wildmatch.h"
@@ -1057,6 +1115,7 @@ typedef struct {
typedef struct {
STRUCT_STAT st;
time_t crtime;
#ifdef SUPPORT_ACLS
struct rsync_acl *acc_acl; /* access ACL */
struct rsync_acl *def_acl; /* default ACL */
@@ -1078,6 +1137,9 @@ typedef struct {
#define CPRES_LZ4 3
#define CPRES_ZSTD 4
#define NSTR_CHECKSUM 0
#define NSTR_COMPRESS 1
struct name_num_item {
int num;
const char *name, *main_name;
@@ -1089,7 +1151,7 @@ struct name_num_obj {
uchar *saw;
int saw_len;
int negotiated_num;
struct name_num_item list[];
struct name_num_item list[8]; /* A big-enough len (we'll get a compile error if it is ever too small) */
};
#ifndef __cplusplus
@@ -1262,12 +1324,22 @@ extern int errno;
/* handler for null strings in printf format */
#define NS(s) ((s)?(s):"<NULL>")
extern char *do_calloc;
/* Convenient wrappers for malloc and realloc. Use them. */
#define new(type) ((type*)malloc(sizeof (type)))
#define new0(type) ((type*)calloc(1, sizeof (type)))
#define new_array(type, num) ((type*)_new_array((num), sizeof (type), 0))
#define new_array0(type, num) ((type*)_new_array((num), sizeof (type), 1))
#define realloc_array(ptr, type, num) ((type*)_realloc_array((ptr), sizeof(type), (num)))
#define new(type) ((type*)my_alloc(NULL, sizeof (type), 1, __FILE__, __LINE__))
#define new0(type) ((type*)my_alloc(do_calloc, sizeof (type), 1, __FILE__, __LINE__))
#define realloc_buf(ptr, num) my_alloc((ptr), (num), 1, __FILE__, __LINE__)
#define new_array(type, num) ((type*)my_alloc(NULL, (num), sizeof (type), __FILE__, __LINE__))
#define new_array0(type, num) ((type*)my_alloc(do_calloc, (num), sizeof (type), __FILE__, __LINE__))
#define realloc_array(ptr, type, num) ((type*)my_alloc((ptr), (num), sizeof (type), __FILE__, __LINE__))
#undef strdup
#define strdup(s) my_strdup(s, __FILE__, __LINE__)
#define out_of_memory(msg) _out_of_memory(msg, __FILE__, __LINE__)
#define overflow_exit(msg) _overflow_exit(msg, __FILE__, __LINE__)
/* use magic gcc attributes to catch format errors */
void rprintf(enum logcode , const char *, ...)
@@ -1383,3 +1455,8 @@ char *getpass(const char *prompt);
#ifdef MAINTAINER_MODE
const char *get_panic_action(void);
#endif
#define NOISY_DEATH(msg) do { \
fprintf(stderr, "%s in %s at line %d\n", msg, __FILE__, __LINE__); \
exit_cleanup(RERR_UNSUPPORTED); \
} while (0)

View File

@@ -396,7 +396,7 @@ Conflict resolution:
would be useful.
Moved files: <http://rsync.samba.org/cgi-bin/rsync.fom?file=44>
Moved files:
- There's no trivial way to detect renamed files, especially if they
move between directories.
@@ -457,13 +457,11 @@ Streaming:
Related work:
- mirror.pl http://freshmeat.net/project/mirror/
- mirror.pl
- ProFTPd
- Apache
- http://freshmeat.net/search/?site=Freshmeat&q=mirror&section=projects
- BitTorrent -- p2p mirroring
http://bitconjurer.org/BitTorrent/

View File

@@ -18,7 +18,7 @@ modules.
The file consists of modules and parameters. A module begins with the name of
the module in square brackets and continues until the next module begins.
Modules contain parameters of the form "name = value".
Modules contain parameters of the form `name = value`.
The file is line-based -- that is, each newline-terminated line represents
either a comment, a module name or a parameter.
@@ -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`
@@ -234,11 +231,11 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
allow the daemon to function. By default the daemon runs without any
chrooting.
0. `haproxy header`
0. `proxy protocol`
When this parameter is enabled, all incoming connections must start with a
V1 or V2 haproxy header. If the header is not found, the connection is
closed.
V1 or V2 proxy protocol header. If the header is not found, the connection
is closed.
Setting this to `true` requires a proxy server to forward source IP
information to rsync, allowing you to log proper IP/host info and make use
@@ -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,22 +287,19 @@ 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`
This parameter tells rsync to modify all symlinks in the same way as the
(non-daemon-affecting) `--munge-links` command-line option (using a method
described below). This should help protect your files from user trickery
when your daemon module is writable. The default is disabled when "use
chroot" is on with an inside-chroot path of "/", OR if "daemon chroot" is
on, otherwise it is enabled.
when your daemon module is writable. The default is disabled when
"use chroot" is on with an inside-chroot path of "/", OR if "daemon chroot"
is on, otherwise it is enabled.
If you disable this parameter on a daemon that is not read-only, there are
tricks that a user can play with uploaded symlinks to access
@@ -393,8 +408,8 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
and `--debug` logging. If the max value is 2, then no info and/or debug
value that is higher than what would be set by `-vv` will be honored by the
daemon in its logging. To see how high of a verbosity level you need to
accept for a particular info/debug level, refer to "rsync --info=help" and
"rsync --debug=help". For instance, it takes max-verbosity 4 to be able to
accept for a particular info/debug level, refer to `rsync --info=help` and
`rsync --debug=help`. For instance, it takes max-verbosity 4 to be able to
output debug TIME2 and FLIST3.
0. `lock file`
@@ -407,12 +422,11 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
0. `read only`
This parameter determines whether clients will be able to upload files or
not. If "read only" is true then any attempted uploads will fail. If "read
only" is false then uploads will be possible if file permissions on the
daemon side allow them. The default is for all modules to be read only.
not. If "read only" is true then any attempted uploads will fail. If
"read only" is false then uploads will be possible if file permissions on
the daemon side allow them. The default is for all modules to be read only.
Note that "auth users" can override this setting on a
per-user basis.
Note that "auth users" can override this setting on a per-user basis.
0. `write only`
@@ -425,6 +439,22 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
Helpful hint: you probably want to specify "refuse options = delete" for a
write-only module.
0. `open noatime`
When set to True, this parameter tells the rsync daemon to open files with
the O_NOATIME flag
(on systems that support it) to avoid changing the access time of the files
that are being transferred. If your OS does not support the O_NOATIME flag
then rsync will silently ignore this option. Note also that some
filesystems are mounted to avoid updating the atime on read access even
without the O_NOATIME flag being set.
When set to False, this parameters ensures that files on the server are not
opened with O_NOATIME.
When set to Unset (the default) the user controls the setting via
`--open-noatime`.
0. `list`
This parameter determines whether this module is listed when the client
@@ -511,7 +541,7 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
The "filter" parameter takes a space-separated list of daemon filter rules,
though it is smart enough to know not to split a token at an internal space
in a rule (e.g. "- /foo - /bar" is parsed as two rules). You may specify
in a rule (e.g. "`- /foo - /bar`" is parsed as two rules). You may specify
one or more merge-file rules using the normal syntax. Only one "filter"
parameter can apply to a given module in the config file, so put all the
rules you want in a single parameter. Note that per-directory merge-file
@@ -523,8 +553,8 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
0. `exclude`
This parameter takes a space-separated list of daemon exclude patterns. As
with the client `--exclude` option, patterns can be qualified with "- " or
"+ " to explicitly indicate exclude/include. Only one "exclude" parameter
with the client `--exclude` option, patterns can be qualified with "`- `" or
"`+ `" to explicitly indicate exclude/include. Only one "exclude" parameter
can apply to a given module. See the "filter" parameter for a description
of how excluded files affect the daemon.
@@ -580,9 +610,9 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
authentication. If "auth users" is set then the client will be challenged
to supply a username and password to connect to the module. A challenge
response authentication protocol is used for this exchange. The plain text
usernames and passwords are stored in the file specified by the "secrets
file" parameter. The default is for all users to be able to connect without
a password (this is called "anonymous rsync").
usernames and passwords are stored in the file specified by the
"secrets file" parameter. The default is for all users to be able to
connect without a password (this is called "anonymous rsync").
In addition to username matching, you can specify groupname matching via a
'@' prefix. When using groupname matching, the authenticating username
@@ -670,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
@@ -690,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:
@@ -698,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.
@@ -721,11 +753,11 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
0. `reverse lookup`
Controls whether the daemon performs a reverse lookup on the client's IP
address to determine its hostname, which is used for "hosts allow"/"hosts
deny" checks and the "%h" log escape. This is enabled by default, but you
may wish to disable it to save time if you know the lookup will not return
a useful result, in which case the daemon will use the name "UNDETERMINED"
instead.
address to determine its hostname, which is used for "hosts allow" &
"hosts deny" checks and the "%h" log escape. This is enabled by default,
but you may wish to disable it to save time if you know the lookup will not
return a useful result, in which case the daemon will use the name
"UNDETERMINED" instead.
If this parameter is enabled globally (even by default), rsync performs the
lookup as soon as a client connects, so disabling it for a module will not
@@ -770,18 +802,18 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
transfers when transfer logging is enabled. The format is a text string
containing embedded single-character escape sequences prefixed with a
percent (%) character. An optional numeric field width may also be
specified between the percent and the escape letter (e.g. "`%-50n %8l
%07p`"). In addition, one or more apostrophes may be specified prior to a
numerical escape to indicate that the numerical value should be made more
human-readable. The 3 supported levels are the same as for the
specified between the percent and the escape letter (e.g.
"`%-50n %8l %07p`"). In addition, one or more apostrophes may be specified
prior to a numerical escape to indicate that the numerical value should be
made more human-readable. The 3 supported levels are the same as for the
`--human-readable` command-line option, though the default is for
human-readability to be off. Each added apostrophe increases the level
(e.g. "`%''l %'b %f`").
The default log format is "%o %h [%a] %m (%u) %f %l", and a "%t [%p] " is
always prefixed when using the "log file" parameter. (A perl script that
will summarize this default log format is included in the rsync source code
distribution in the "support" subdirectory: rsyncstats.)
The default log format is "`%o %h [%a] %m (%u) %f %l`", and a "`%t [%p] `"
is always prefixed when using the "log file" parameter. (A perl script
that will summarize this default log format is included in the rsync source
code distribution in the "support" subdirectory: rsyncstats.)
The single-character escapes that are understood are as follows:
@@ -801,8 +833,8 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
- %h the remote host name (only available for a daemon)
- %i an itemized list of what is being updated
- %l the length of the file in bytes
- %L the string " -> SYMLINK", " => HARDLINK", or "" (where `SYMLINK` or
`HARDLINK` is a filename)
- %L the string "` -> SYMLINK`", "` => HARDLINK`", or "" (where `SYMLINK`
or `HARDLINK` is a filename)
- %m the module name
- %M the last-modified time of the file
- %n the filename (short form; trailing "/" on dir)
@@ -867,7 +899,7 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
> refuse options = * no-iconv !a !v
As an additional aid (beginning in 3.2.0), refusing (or "!refusing") the
As an additional aid (beginning in 3.2.0), refusing (or "`!refusing`") the
"a" or "archive" option also affects all the options that the `--archive`
option implies (`-rdlptgoD`), but only if the option is matched explicitly
(not using a wildcard). If you want to do something tricky, you can use
@@ -899,22 +931,22 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
"`!compress*`" so that you also accept the `--compress-level` option.
Note that the "write-devices" option is refused by default, but can be
explicitly accepted with "!write-devices". The options "log-file" and
explicitly accepted with "`!write-devices`". The options "log-file" and
"log-file-format" are forcibly refused and cannot be accepted.
Here are all the options that are not matched by wild-cards:
- `--server`: Required for rsync to even work.
- `-e`: Required to convey compatibility flags to the server.
- `--log-format`: This is required to convey things like
`--itemize-changes` to a remote receiver. Is an older name for
`--out-format` that is still passed to the server for improved backward
compatibility and should not be confused with `--log-file-format`.
- `--rsh`, `-e`: Required to convey compatibility flags to the server.
- `--out-format`: This is required to convey output behavior to a remote
receiver. While rsync passes the older alias `--log-format` for
compatibility reasons, this options should not be confused with
`--log-file-format`.
- `--sender`: Use "write only" parameter instead of refusing this.
- `-n, --dry-run`: Who would want to disable this?
- `-s, --protect-args`: This actually makes transfers safer.
- `-0, --from0`: Make it easier to accept/refuse `--files-from` without
affecting this modifier.
- `--dry-run`, `-n`: Who would want to disable this?
- `--protect-args`, `-s`: This actually makes transfers safer.
- `--from0`, `-0`: Makes it easier to accept/refuse `--files-from` without
affecting this helpful modifier.
- `--iconv`: This is auto-disabled based on "charset" parameter.
- `--no-iconv`: Most transfers use this option.
- `--checksum-seed`: Is a fairly rare, safe option.
@@ -936,10 +968,10 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
compression occurs for those files. Other algorithms have the level
minimized to reduces the CPU usage as much as possible.
See the `--skip-compress` parameter in the `rsync`(1) manpage for the list
of file suffixes that are not compressed by default. Specifying a value
for the "dont compress" parameter changes the default when the daemon is
the sender.
See the `--skip-compress` parameter in the **rsync**(1) manpage for the
list of file suffixes that are not compressed by default. Specifying a
value for the "dont compress" parameter changes the default when the daemon
is the sender.
0. `early exec`, `pre-xfer exec`, `post-xfer exec`
@@ -958,7 +990,9 @@ the values of parameters. See the GLOBAL PARAMETERS section for more details.
request is known except for the module name. This helper script can be
used to setup a disk mount or decrypt some data into a module dir, but you
may need to use `lock file` and `max connections` to avoid concurrency
issues.
issues. If the client rsync specified the `--early-input=FILE` option, it
can send up to about 5K of data to the stdin of the early script. The
stdin will otherwise be empty.
Note that the `post-xfer exec` command is still run even if one of the
other scripts returns an error code. The `pre-xfer exec` command will _not_
@@ -1066,8 +1100,53 @@ Also note that the rsync daemon protocol does not currently provide any
encryption of the data that is transferred over the connection. Only
authentication is provided. Use ssh as the transport if you want encryption.
Future versions of rsync may support SSL for better authentication and
encryption, but that is still being investigated.
You can also make use of SSL/TLS encryption if you put rsync behind an
SSL proxy.
# SSL/TLS Daemon Setup
When setting up an rsync daemon for access via SSL/TLS, you will need to
configure a proxy (such as haproxy or nginx) as the front-end that handles the
encryption.
- You should limit the access to the backend-rsyncd port to only allow the
proxy to connect. If it is on the same host as the proxy, then configuring
it to only listen on localhost is a good idea.
- You should consider turning on the `proxy protocol` parameter if your proxy
supports sending that information. The examples below assume that this is
enabled.
An example haproxy setup is as follows:
> ```
> frontend fe_rsync-ssl
> bind :::874 ssl crt /etc/letsencrypt/example.com/combined.pem
> mode tcp
> use_backend be_rsync
>
> backend be_rsync
> mode tcp
> server local-rsync 127.0.0.1:873 check send-proxy
> ```
An example nginx proxy setup is as follows:
> ```
> stream {
> server {
> listen 874 ssl;
> listen [::]:874 ssl;
>
> ssl_certificate /etc/letsencrypt/example.com/fullchain.pem;
> ssl_certificate_key /etc/letsencrypt/example.com/privkey.pem;
>
> proxy_pass localhost:873;
> proxy_protocol on; # Requires "proxy protocol = true"
> proxy_timeout 1m;
> proxy_connect_timeout 5s;
> }
> }
> ```
# EXAMPLES
@@ -1089,23 +1168,23 @@ A more sophisticated example would be:
> max connections = 4
> syslog facility = local5
> pid file = /var/run/rsyncd.pid
>
>
> [ftp]
> path = /var/ftp/./pub
> comment = whole ftp area (approx 6.1 GB)
>
>
> [sambaftp]
> path = /var/ftp/./pub/samba
> comment = Samba ftp area (approx 300 MB)
>
>
> [rsyncftp]
> path = /var/ftp/./pub/rsync
> comment = rsync ftp area (approx 6 MB)
>
>
> [sambawww]
> path = /public_html/samba
> comment = Samba WWW pages (approx 240 MB)
>
>
> [cvs]
> path = /data/cvs
> comment = CVS repository (requires authentication)
@@ -1129,7 +1208,7 @@ The /etc/rsyncd.secrets file would look something like this:
# BUGS
Please report bugs! The rsync bug tracking system is online at
<http://rsync.samba.org/>.
<https://rsync.samba.org/>.
# VERSION
@@ -1142,7 +1221,7 @@ COPYING for details.
The primary ftp site for rsync is <ftp://rsync.samba.org/pub/rsync>
A web site is available at <http://rsync.samba.org/>.
A web site is available at <https://rsync.samba.org/>.
We would be delighted to hear from you if you like this program.
@@ -1160,4 +1239,4 @@ rsync was written by Andrew Tridgell and Paul Mackerras. Many people have
later contributed to it.
Mailing lists for support and development are available at
<http://lists.samba.org/>.
<https://lists.samba.org/>.

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

@@ -65,13 +65,10 @@ BOOL extra_flist_sending_enabled;
**/
static struct sum_struct *receive_sums(int f)
{
struct sum_struct *s;
int32 i;
struct sum_struct *s = new(struct sum_struct);
int lull_mod = protocol_version >= 31 ? 0 : allowed_lull * 5;
OFF_T offset = 0;
if (!(s = new(struct sum_struct)))
out_of_memory("receive_sums");
int32 i;
read_sum_head(f, s);
@@ -92,8 +89,7 @@ static struct sum_struct *receive_sums(int f)
if (s->count == 0)
return(s);
if (!(s->sums = new_array(struct sum_buf, s->count)))
out_of_memory("receive_sums");
s->sums = new_array(struct sum_buf, s->count);
for (i = 0; i < s->count; i++) {
s->sums[i].sum1 = read_int(f);

View File

@@ -45,9 +45,10 @@
* the available xmm registers, this optimized version may not be faster than
* the pure C version anyway. Note that all x86-64 CPUs support at least SSE2.
*
* This file is compiled using GCC 4.8+'s C++ front end to allow the use of
* the target attribute, selecting the fastest code path based on runtime
* detection of CPU capabilities.
* This file is compiled using GCC 4.8+/clang 6+'s C++ front end to allow the
* use of the target attribute, selecting the fastest code path based on
* dispatch priority (GCC 5) or runtime detection of CPU capabilities (GCC 6+).
* GCC 4.x are not supported to ease configure.ac logic.
*/
#ifdef __x86_64__
@@ -59,73 +60,34 @@
#include <immintrin.h>
/* Compatibility functions to let our SSSE3 algorithm run on SSE2 */
/* Some clang versions don't like it when you use static with multi-versioned functions: linker errors */
#ifdef __clang__
#define MVSTATIC
#else
#define MVSTATIC static
#endif
__attribute__ ((target("sse2"))) static inline __m128i sse_interleave_odd_epi16(__m128i a, __m128i b)
{
return _mm_packs_epi32(
_mm_srai_epi32(a, 16),
_mm_srai_epi32(b, 16)
);
}
// Missing from the headers on gcc 6 and older, clang 8 and older
typedef long long __m128i_u __attribute__((__vector_size__(16), __may_alias__, __aligned__(1)));
typedef long long __m256i_u __attribute__((__vector_size__(32), __may_alias__, __aligned__(1)));
__attribute__ ((target("sse2"))) static inline __m128i sse_interleave_even_epi16(__m128i a, __m128i b)
{
return sse_interleave_odd_epi16(
_mm_slli_si128(a, 2),
_mm_slli_si128(b, 2)
);
}
/* Compatibility macros to let our SSSE3 algorithm run with only SSE2.
These used to be neat individual functions with target attributes switching between SSE2 and SSSE3 implementations
as needed, but though this works perfectly with GCC, clang fails to inline those properly leading to a near 50%
performance drop - combined with static and inline modifiers gets you linker errors and even compiler crashes...
*/
__attribute__ ((target("sse2"))) static inline __m128i sse_mulu_odd_epi8(__m128i a, __m128i b)
{
return _mm_mullo_epi16(
_mm_srli_epi16(a, 8),
_mm_srai_epi16(b, 8)
);
}
#define SSE2_INTERLEAVE_ODD_EPI16(a, b) _mm_packs_epi32(_mm_srai_epi32(a, 16), _mm_srai_epi32(b, 16))
#define SSE2_INTERLEAVE_EVEN_EPI16(a, b) SSE2_INTERLEAVE_ODD_EPI16(_mm_slli_si128(a, 2), _mm_slli_si128(b, 2))
#define SSE2_MULU_ODD_EPI8(a, b) _mm_mullo_epi16(_mm_srli_epi16(a, 8), _mm_srai_epi16(b, 8))
#define SSE2_MULU_EVEN_EPI8(a, b) _mm_mullo_epi16(_mm_and_si128(a, _mm_set1_epi16(0xFF)), _mm_srai_epi16(_mm_slli_si128(b, 1), 8))
__attribute__ ((target("sse2"))) static inline __m128i sse_mulu_even_epi8(__m128i a, __m128i b)
{
return _mm_mullo_epi16(
_mm_and_si128(a, _mm_set1_epi16(0xFF)),
_mm_srai_epi16(_mm_slli_si128(b, 1), 8)
);
}
#define SSE2_HADDS_EPI16(a, b) _mm_adds_epi16(SSE2_INTERLEAVE_EVEN_EPI16(a, b), SSE2_INTERLEAVE_ODD_EPI16(a, b))
#define SSE2_MADDUBS_EPI16(a, b) _mm_adds_epi16(SSE2_MULU_EVEN_EPI8(a, b), SSE2_MULU_ODD_EPI8(a, b))
__attribute__ ((target("sse2"))) static inline __m128i sse_hadds_epi16(__m128i a, __m128i b)
{
return _mm_adds_epi16(
sse_interleave_even_epi16(a, b),
sse_interleave_odd_epi16(a, b)
);
}
__attribute__ ((target("ssse3"))) static inline __m128i sse_hadds_epi16(__m128i a, __m128i b)
{
return _mm_hadds_epi16(a, b);
}
__attribute__ ((target("sse2"))) static inline __m128i sse_maddubs_epi16(__m128i a, __m128i b)
{
return _mm_adds_epi16(
sse_mulu_even_epi8(a, b),
sse_mulu_odd_epi8(a, b)
);
}
__attribute__ ((target("ssse3"))) static inline __m128i sse_maddubs_epi16(__m128i a, __m128i b)
{
return _mm_maddubs_epi16(a, b);
}
/* These don't actually get called, but we need to define them. */
__attribute__ ((target("default"))) static inline __m128i sse_interleave_odd_epi16(__m128i a, __m128i b) { return a; }
__attribute__ ((target("default"))) static inline __m128i sse_interleave_even_epi16(__m128i a, __m128i b) { return a; }
__attribute__ ((target("default"))) static inline __m128i sse_mulu_odd_epi8(__m128i a, __m128i b) { return a; }
__attribute__ ((target("default"))) static inline __m128i sse_mulu_even_epi8(__m128i a, __m128i b) { return a; }
__attribute__ ((target("default"))) static inline __m128i sse_hadds_epi16(__m128i a, __m128i b) { return a; }
__attribute__ ((target("default"))) static inline __m128i sse_maddubs_epi16(__m128i a, __m128i b) { return a; }
__attribute__ ((target("default"))) MVSTATIC int32 get_checksum1_avx2_64(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2) { return i; }
__attribute__ ((target("default"))) MVSTATIC int32 get_checksum1_ssse3_32(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2) { return i; }
__attribute__ ((target("default"))) MVSTATIC int32 get_checksum1_sse2_32(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2) { return i; }
/*
Original loop per 4 bytes:
@@ -146,12 +108,7 @@ __attribute__ ((target("default"))) static inline __m128i sse_maddubs_epi16(__m1
s1 += (uint32)(t1[0] + t1[1] + t1[2] + t1[3] + t1[4] + t1[5] + t1[6] + t1[7]) +
32*CHAR_OFFSET;
*/
/*
Both sse2 and ssse3 targets must be specified here or we lose (a lot) of
performance, possibly due to not unrolling+inlining the called targeted
functions.
*/
__attribute__ ((target("sse2", "ssse3"))) static int32 get_checksum1_sse2_32(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
__attribute__ ((target("ssse3"))) MVSTATIC int32 get_checksum1_ssse3_32(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
{
if (len > 32) {
int aligned = ((uintptr_t)buf & 15) == 0;
@@ -167,16 +124,11 @@ __attribute__ ((target("sse2", "ssse3"))) static int32 get_checksum1_sse2_32(sch
for (; i < (len-32); i+=32) {
// Load ... 2*[int8*16]
// SSSE3 has _mm_lqqdu_si128, but this requires another
// target function for each SSE2 and SSSE3 loads. For reasons
// unknown (to me) we lose about 10% performance on some CPUs if
// we do that right here. We just use _mm_loadu_si128 as for all
// but a handful of specific old CPUs they are synonymous, and
// take the 1-5% hit on those specific CPUs where it isn't.
__m128i in8_1, in8_2;
if (!aligned) {
in8_1 = _mm_loadu_si128((__m128i_u*)&buf[i]);
in8_2 = _mm_loadu_si128((__m128i_u*)&buf[i + 16]);
// Synonymous with _mm_loadu_si128 on all but a handful of old CPUs
in8_1 = _mm_lddqu_si128((__m128i_u*)&buf[i]);
in8_2 = _mm_lddqu_si128((__m128i_u*)&buf[i + 16]);
} else {
in8_1 = _mm_load_si128((__m128i_u*)&buf[i]);
in8_2 = _mm_load_si128((__m128i_u*)&buf[i + 16]);
@@ -185,13 +137,13 @@ __attribute__ ((target("sse2", "ssse3"))) static int32 get_checksum1_sse2_32(sch
// (1*buf[i] + 1*buf[i+1]), (1*buf[i+2], 1*buf[i+3]), ... 2*[int16*8]
// Fastest, even though multiply by 1
__m128i mul_one = _mm_set1_epi8(1);
__m128i add16_1 = sse_maddubs_epi16(mul_one, in8_1);
__m128i add16_2 = sse_maddubs_epi16(mul_one, in8_2);
__m128i add16_1 = _mm_maddubs_epi16(mul_one, in8_1);
__m128i add16_2 = _mm_maddubs_epi16(mul_one, in8_2);
// (4*buf[i] + 3*buf[i+1]), (2*buf[i+2], buf[i+3]), ... 2*[int16*8]
__m128i mul_const = _mm_set1_epi32(4 + (3 << 8) + (2 << 16) + (1 << 24));
__m128i mul_add16_1 = sse_maddubs_epi16(mul_const, in8_1);
__m128i mul_add16_2 = sse_maddubs_epi16(mul_const, in8_2);
__m128i mul_add16_1 = _mm_maddubs_epi16(mul_const, in8_1);
__m128i mul_add16_2 = _mm_maddubs_epi16(mul_const, in8_2);
// s2 += 32*s1
ss2 = _mm_add_epi32(ss2, _mm_slli_epi32(ss1, 5));
@@ -224,7 +176,111 @@ __attribute__ ((target("sse2", "ssse3"))) static int32 get_checksum1_sse2_32(sch
// [t1[0] + t1[1], t1[2] + t1[3] ...] [int16*8]
// We could've combined this with generating sum_add32 above and
// save an instruction but benchmarking shows that as being slower
__m128i add16 = sse_hadds_epi16(add16_1, add16_2);
__m128i add16 = _mm_hadds_epi16(add16_1, add16_2);
// [t1[0], t1[1], ...] -> [t1[0]*28 + t1[1]*24, ...] [int32*4]
__m128i mul32 = _mm_madd_epi16(add16, mul_t1);
// [sum(mul32), X, X, X] [int32*4]; faster than multiple _mm_hadd_epi32
mul32 = _mm_add_epi32(mul32, _mm_srli_si128(mul32, 4));
mul32 = _mm_add_epi32(mul32, _mm_srli_si128(mul32, 8));
// s2 += 28*t1[0] + 24*t1[1] + 20*t1[2] + 16*t1[3] + 12*t1[4] + 8*t1[5] + 4*t1[6]
ss2 = _mm_add_epi32(ss2, mul32);
#if CHAR_OFFSET != 0
// s1 += 32*CHAR_OFFSET
__m128i char_offset_multiplier = _mm_set1_epi32(32 * CHAR_OFFSET);
ss1 = _mm_add_epi32(ss1, char_offset_multiplier);
// s2 += 528*CHAR_OFFSET
char_offset_multiplier = _mm_set1_epi32(528 * CHAR_OFFSET);
ss2 = _mm_add_epi32(ss2, char_offset_multiplier);
#endif
}
_mm_store_si128((__m128i_u*)x, ss1);
*ps1 = x[0];
_mm_store_si128((__m128i_u*)x, ss2);
*ps2 = x[0];
}
return i;
}
/*
Same as SSSE3 version, but using macros defined above to emulate SSSE3 calls that are not available with SSE2.
For GCC-only the SSE2 and SSSE3 versions could be a single function calling other functions with the right
target attributes to emulate SSSE3 calls on SSE2 if needed, but clang doesn't inline those properly leading
to a near 50% performance drop.
*/
__attribute__ ((target("sse2"))) MVSTATIC int32 get_checksum1_sse2_32(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
{
if (len > 32) {
int aligned = ((uintptr_t)buf & 15) == 0;
uint32 x[4] = {0};
x[0] = *ps1;
__m128i ss1 = _mm_loadu_si128((__m128i_u*)x);
x[0] = *ps2;
__m128i ss2 = _mm_loadu_si128((__m128i_u*)x);
const int16 mul_t1_buf[8] = {28, 24, 20, 16, 12, 8, 4, 0};
__m128i mul_t1 = _mm_loadu_si128((__m128i_u*)mul_t1_buf);
for (; i < (len-32); i+=32) {
// Load ... 2*[int8*16]
__m128i in8_1, in8_2;
if (!aligned) {
in8_1 = _mm_loadu_si128((__m128i_u*)&buf[i]);
in8_2 = _mm_loadu_si128((__m128i_u*)&buf[i + 16]);
} else {
in8_1 = _mm_load_si128((__m128i_u*)&buf[i]);
in8_2 = _mm_load_si128((__m128i_u*)&buf[i + 16]);
}
// (1*buf[i] + 1*buf[i+1]), (1*buf[i+2], 1*buf[i+3]), ... 2*[int16*8]
// Fastest, even though multiply by 1
__m128i mul_one = _mm_set1_epi8(1);
__m128i add16_1 = SSE2_MADDUBS_EPI16(mul_one, in8_1);
__m128i add16_2 = SSE2_MADDUBS_EPI16(mul_one, in8_2);
// (4*buf[i] + 3*buf[i+1]), (2*buf[i+2], buf[i+3]), ... 2*[int16*8]
__m128i mul_const = _mm_set1_epi32(4 + (3 << 8) + (2 << 16) + (1 << 24));
__m128i mul_add16_1 = SSE2_MADDUBS_EPI16(mul_const, in8_1);
__m128i mul_add16_2 = SSE2_MADDUBS_EPI16(mul_const, in8_2);
// s2 += 32*s1
ss2 = _mm_add_epi32(ss2, _mm_slli_epi32(ss1, 5));
// [sum(t1[0]..t1[7]), X, X, X] [int32*4]; faster than multiple _mm_hadds_epi16
// Shifting left, then shifting right again and shuffling (rather than just
// shifting right as with mul32 below) to cheaply end up with the correct sign
// extension as we go from int16 to int32.
__m128i sum_add32 = _mm_add_epi16(add16_1, add16_2);
sum_add32 = _mm_add_epi16(sum_add32, _mm_slli_si128(sum_add32, 2));
sum_add32 = _mm_add_epi16(sum_add32, _mm_slli_si128(sum_add32, 4));
sum_add32 = _mm_add_epi16(sum_add32, _mm_slli_si128(sum_add32, 8));
sum_add32 = _mm_srai_epi32(sum_add32, 16);
sum_add32 = _mm_shuffle_epi32(sum_add32, 3);
// [sum(t2[0]..t2[7]), X, X, X] [int32*4]; faster than multiple _mm_hadds_epi16
__m128i sum_mul_add32 = _mm_add_epi16(mul_add16_1, mul_add16_2);
sum_mul_add32 = _mm_add_epi16(sum_mul_add32, _mm_slli_si128(sum_mul_add32, 2));
sum_mul_add32 = _mm_add_epi16(sum_mul_add32, _mm_slli_si128(sum_mul_add32, 4));
sum_mul_add32 = _mm_add_epi16(sum_mul_add32, _mm_slli_si128(sum_mul_add32, 8));
sum_mul_add32 = _mm_srai_epi32(sum_mul_add32, 16);
sum_mul_add32 = _mm_shuffle_epi32(sum_mul_add32, 3);
// s1 += t1[0] + t1[1] + t1[2] + t1[3] + t1[4] + t1[5] + t1[6] + t1[7]
ss1 = _mm_add_epi32(ss1, sum_add32);
// s2 += t2[0] + t2[1] + t2[2] + t2[3] + t2[4] + t2[5] + t2[6] + t2[7]
ss2 = _mm_add_epi32(ss2, sum_mul_add32);
// [t1[0] + t1[1], t1[2] + t1[3] ...] [int16*8]
// We could've combined this with generating sum_add32 above and
// save an instruction but benchmarking shows that as being slower
__m128i add16 = SSE2_HADDS_EPI16(add16_1, add16_2);
// [t1[0], t1[1], ...] -> [t1[0]*28 + t1[1]*24, ...] [int32*4]
__m128i mul32 = _mm_madd_epi16(add16, mul_t1);
@@ -270,7 +326,7 @@ __attribute__ ((target("sse2", "ssse3"))) static int32 get_checksum1_sse2_32(sch
s1 += (uint32)(t1[0] + t1[1] + t1[2] + t1[3] + t1[4] + t1[5] + t1[6] + t1[7] + t1[8] + t1[9] + t1[10] + t1[11] + t1[12] + t1[13] + t1[14] + t1[15]) +
64*CHAR_OFFSET;
*/
__attribute__ ((target("avx2"))) static int32 get_checksum1_avx2_64(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
__attribute__ ((target("avx2"))) MVSTATIC int32 get_checksum1_avx2_64(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
{
if (len > 64) {
// Instructions reshuffled compared to SSE2 for slightly better performance
@@ -377,17 +433,7 @@ __attribute__ ((target("avx2"))) static int32 get_checksum1_avx2_64(schar* buf,
return i;
}
__attribute__ ((target("default"))) static int32 get_checksum1_avx2_64(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
{
return i;
}
__attribute__ ((target("default"))) static int32 get_checksum1_sse2_32(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
{
return i;
}
static inline int32 get_checksum1_default_1(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
static int32 get_checksum1_default_1(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2)
{
uint32 s1 = *ps1;
uint32 s2 = *ps2;
@@ -403,9 +449,10 @@ static inline int32 get_checksum1_default_1(schar* buf, int32 len, int32 i, uint
return i;
}
extern "C" {
uint32 get_checksum1(char *buf1, int32 len)
/* With GCC 10 putting this implementation inside 'extern "C"' causes an
assembler error. That worked fine on GCC 5-9 and clang 6-10...
*/
static inline uint32 get_checksum1_cpp(char *buf1, int32 len)
{
int32 i = 0;
uint32 s1 = 0;
@@ -414,7 +461,10 @@ uint32 get_checksum1(char *buf1, int32 len)
// multiples of 64 bytes using AVX2 (if available)
i = get_checksum1_avx2_64((schar*)buf1, len, i, &s1, &s2);
// multiples of 32 bytes using SSE2/SSSE3 (if available)
// multiples of 32 bytes using SSSE3 (if available)
i = get_checksum1_ssse3_32((schar*)buf1, len, i, &s1, &s2);
// multiples of 32 bytes using SSE2 (if available)
i = get_checksum1_sse2_32((schar*)buf1, len, i, &s1, &s2);
// whatever is left
@@ -423,7 +473,70 @@ uint32 get_checksum1(char *buf1, int32 len)
return (s1 & 0xffff) + (s2 << 16);
}
} // "C"
extern "C" {
uint32 get_checksum1(char *buf1, int32 len)
{
return get_checksum1_cpp(buf1, len);
}
} // extern "C"
#ifdef BENCHMARK_SIMD_CHECKSUM1
#pragma clang optimize off
#pragma GCC push_options
#pragma GCC optimize ("O0")
#define ROUNDS 1024
#define BLOCK_LEN 1024*1024
#ifndef CLOCK_MONOTONIC_RAW
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
#endif
static void benchmark(const char* desc, int32 (*func)(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2), schar* buf, int32 len) {
struct timespec start, end;
uint64_t us;
uint32_t cs, s1, s2;
int i, next;
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
for (i = 0; i < ROUNDS; i++) {
s1 = s2 = 0;
next = func((schar*)buf, len, 0, &s1, &s2);
get_checksum1_default_1((schar*)buf, len, next, &s1, &s2);
}
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
us = next == 0 ? 0 : (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
cs = next == 0 ? 0 : (s1 & 0xffff) + (s2 << 16);
printf("%-5s :: %5.0f MB/s :: %08x\n", desc, us ? (float)(len / (1024 * 1024) * ROUNDS) / ((float)us / 1000000.0f) : 0, cs);
}
static int32 get_checksum1_auto(schar* buf, int32 len, int32 i, uint32* ps1, uint32* ps2) {
uint32 cs = get_checksum1((char*)buf, len);
*ps1 = cs & 0xffff;
*ps2 = cs >> 16;
return len;
}
int main() {
int i;
unsigned char* buf = (unsigned char*)malloc(BLOCK_LEN);
for (i = 0; i < BLOCK_LEN; i++) buf[i] = (i + (i % 3) + (i % 11)) % 256;
benchmark("Auto", get_checksum1_auto, (schar*)buf, BLOCK_LEN);
benchmark("Raw-C", get_checksum1_default_1, (schar*)buf, BLOCK_LEN);
benchmark("SSE2", get_checksum1_sse2_32, (schar*)buf, BLOCK_LEN);
benchmark("SSSE3", get_checksum1_ssse3_32, (schar*)buf, BLOCK_LEN);
benchmark("AVX2", get_checksum1_avx2_64, (schar*)buf, BLOCK_LEN);
free(buf);
return 0;
}
#pragma GCC pop_options
#pragma clang optimize on
#endif /* BENCHMARK_SIMD_CHECKSUM1 */
#endif /* HAVE_SIMD */
#endif /* __cplusplus */

View File

@@ -26,6 +26,7 @@
#include "rsync.h"
#include "itypes.h"
#include "ifuncs.h"
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
@@ -248,8 +249,6 @@ int open_socket_out(char *host, int port, const char *bind_addr, int af_hint)
for (res = res0, addr_cnt = 0; res; res = res->ai_next, addr_cnt++) {}
errnos = new_array0(int, addr_cnt);
if (!errnos)
out_of_memory("open_socket_out");
s = -1;
/* Try to connect to all addresses for this machine until we get
@@ -354,8 +353,7 @@ int open_socket_out_wrapped(char *host, int port, const char *bind_addr, int af_
len += hlen;
}
f = prog;
if (!(prog = new_array(char, len)))
out_of_memory("open_socket_out_wrapped");
prog = new_array(char, len);
for (t = prog; *f; f++) {
if (*f == '%') {
switch (*++f) {
@@ -423,8 +421,6 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
socks = new_array(int, maxs + 1);
errmsgs = new_array(char *, maxs);
if (!socks || !errmsgs)
out_of_memory("open_socket_in");
/* We may not be able to create the socket, if for example the
* machine knows about IPv6 in the C library, but not in the
@@ -684,9 +680,6 @@ void set_socket_options(int fd, char *options)
options = strdup(options);
if (!options)
out_of_memory("set_socket_options");
for (tok = strtok(options, " \t,"); tok; tok = strtok(NULL," \t,")) {
int ret=0,i;
int value = 1;

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
#
# This script lets you update a hierarchy of files in an atomic way by
# first creating a new hierarchy using rsync's --link-dest option, and

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
#
# This script finds all CVS/Entries files in the current directory and below
# and creates a local .cvsinclude file with non-inherited rules including each

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Send an error message via the rsync-protocol to a non-daemon client rsync.
#
# Usage: deny-rsync "message"

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
# This script will parse the output of "find ARG [ARG...] -ls" and
# apply (at your discretion) the permissions, owner, and group info
# it reads onto any existing files and dirs (it doesn't try to affect

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
# This script takes an input of filenames and outputs a set of
# include/exclude directives that can be used by rsync to copy
# just the indicated files using an --exclude-from=FILE option.

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python3
import os, re, argparse, subprocess
from datetime import datetime
@@ -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,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# instant-rsyncd lets you quickly set up and start a simple, unprivileged rsync
# daemon with a single module in the current directory. I've found it

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
# Filter the rsync daemon log messages by module name. The log file can be
# in either syslog format or rsync's own log-file format. Note that the
# MODULE_NAME parameter is used in a regular-expression match in order to

View File

@@ -1,10 +1,6 @@
#!/usr/bin/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).
#!/usr/bin/env perl
# 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
}

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
# This helper script makes it easy to use a passwd or group file to map
# values in a LOCAL transfer. For instance, if you mount a backup that
# does not have the same passwd setup as the local machine, you can do

View File

@@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
# This helper script makes it easy to use a passwd or group file to map
# values in a LOCAL transfer. For instance, if you mount a backup that
# does not have the same passwd setup as the local machine, you can do

Some files were not shown because too many files have changed in this diff Show More