Compare commits

..

571 Commits

Author SHA1 Message Date
Wayne Davison
bc58313bf7 Preparing for release of 3.1.0 2013-09-28 13:55:54 -07:00
Wayne Davison
de78297b61 Remove unused var. 2013-09-28 13:53:23 -07:00
Wayne Davison
9c7d755dfe Flush write buffer on an aborted in-place transfer. 2013-09-28 10:40:27 -07:00
Wayne Davison
60cc5d4b78 Mention latest news. 2013-09-16 09:23:35 -07:00
Wayne Davison
1220c93a99 Fix the visit-all-patches path. 2013-09-16 09:16:30 -07:00
Wayne Davison
7d7538d43c Fix error in write_sparse() on incomplete write.
Fix a problem where sparse_seek could get left non-zero when we
did not finish writing all the data that would take us to that
sparse gap.  Issue pointed out by David Taylor.
2013-09-16 09:02:46 -07:00
Wayne Davison
de94193353 Remove bypassed checksums in --inplace to improve speed.
When checking a checksum that refers to a part of an --inplace file that
has been overwritten w/o getting SUMFLG_SAME_OFFSET set, we remove the
checksum from the list.  This will speed up files that have a lot of
identical checksum blocks (e.g. sequences of zeros) that we can't use
due to them not getting marked as being the same.  Patch provided by
Michael Chapman.
2013-08-03 09:59:38 -07:00
Wayne Davison
05fce6582a Preparing for release of 3.1.0pre1 2013-07-28 10:36:43 -07:00
Wayne Davison
62327b1281 We need a trailing dot when using --server --daemon. 2013-07-12 15:28:54 -07:00
Wayne Davison
99c9520ea7 Look for REMOTE_HOST before SSH_* environment options. 2013-07-12 15:24:58 -07:00
Wayne Davison
01959d6387 Set DESTDIR for make install. 2013-06-23 15:47:09 -07:00
Wayne Davison
807f3a44ba Mention latest changes. 2013-06-16 16:59:24 -07:00
Wayne Davison
2791e0b542 Be a little clearer about full-line comments. 2013-06-16 16:43:14 -07:00
Wayne Davison
d6a7ed99c1 Get GPL name right. 2013-06-16 16:36:27 -07:00
Wayne Davison
4066d61a9d Mention right option when using --delete-delay. 2013-06-16 16:33:32 -07:00
Wayne Davison
70d4a945f7 Support rsync daemon over SSL via stunnel.
Added the client rsync-ssl script and various client/daemon support
files needed for talking to an rsync daemon over SSL on port 874 (no
tls support).  This uses an elegant stunnel setup that was detailed
by dozzie (see the resources page) now that stunnel4 has improved
command-spawning support.  Also incorporates some tweaks by devzero
(e.g. the nice no-tmpfile-config client-side code) and a few by me
(including logging of the actual remote IP that came in to the
stunnel process).  This probably still needs a little work.
2013-06-15 16:40:10 -07:00
Wayne Davison
0488a14b99 Fix "make check". 2013-06-11 18:06:53 -07:00
Wayne Davison
a213d1cd6e Move some code from util.c to util2.c and add sum_as_hex(). 2013-06-11 13:36:44 -07:00
Wayne Davison
fc2d6fabe7 Set number_separator the first time it gets used. 2013-06-11 13:28:45 -07:00
Wayne Davison
a508e88fcf More NEWS changes. 2013-06-09 22:28:24 -07:00
Wayne Davison
f0da824237 Upgrading zlib to 1.2.8. 2013-06-09 22:27:33 -07:00
Wayne Davison
b74250037c Rename lsh.pl -> lsh. 2013-06-09 19:40:56 -07:00
Wayne Davison
f93094fa9f Rename lsh -> lsh.sh. 2013-06-09 19:40:56 -07:00
Wayne Davison
baf382d62e Updating NEWS with the latest changes. 2013-06-09 16:02:19 -07:00
Wayne Davison
12505e02b1 Allow --password-file=- for a stdin-supplied password. 2013-06-09 12:11:53 -07:00
Wayne Davison
d6df07392e Fix module-name splitting with --protect-args.
Fixes bug 8838.
2013-06-02 15:54:48 -07:00
Wayne Davison
d9ca1e4990 Tweak --checksum-seed docs. 2013-06-02 13:14:27 -07:00
Wayne Davison
0ab8e166f4 Avoid preallocation on inplace file that is already long enough. 2013-06-02 12:37:48 -07:00
Wayne Davison
1e9ee19a71 Look for got_kill_signal in a couple more spots. 2013-05-28 12:59:47 -07:00
Wayne Davison
9bf065860f Improve logic of code vs exit_code (etc.) in cleanup. 2013-05-26 16:23:37 -07:00
Wayne Davison
5b46454364 Forward a MSG_ERROR_EXIT value to generator too.
Fixes bug 9882.
2013-05-26 16:23:37 -07:00
Wayne Davison
d4070db631 Avoid I/O via signal-handler thread.
The cleanup code will try to flush the output buffer in some
circumstances, which is not valid if we're handling an async signal
(since it might have interrupted some partial I/O in the main thread).
These signals now set a flag and try to let the main I/O handler take
care of the exit strategy.  Fixes a protocol error that could happen
when trying to exit after a kill signal.
2013-05-26 16:22:56 -07:00
Wayne Davison
cb784f18ec Improve iconvbufs() to do more buffer size checks.
- If iconv() returns EINVAL or EILSEQ and the error is being ignored, make
  sure that there is room in the output buffer to store the erroneous char.
- When accepting an erroneous char, be sure to break if there are no more
  input characters (without calling iconv() with a zero input length).
2013-05-19 23:56:34 +00:00
Wayne Davison
2dc2070992 Fix msleep() if time goes backwards. Fixes bug 9789. 2013-05-19 22:55:08 +00:00
Wayne Davison
4442f8037b Fixed unused variable warnings in free_stat_x. 2013-05-19 22:01:29 +00:00
Wayne Davison
333e3a9ff0 Add an implementation of getpass for systems that lack one. 2013-05-19 22:01:29 +00:00
Wayne Davison
94073d20e4 Use S_IXUSR instead of the now-obsolete S_IEXEC. 2013-05-19 22:01:29 +00:00
Wayne Davison
750ec9bcdc Updated to the version dated 2013-04-24. 2013-05-19 22:01:07 +00:00
Wayne Davison
7fdba7aaf8 Updated to the version dated 2013-05-16. 2013-05-19 22:00:44 +00:00
Wayne Davison
eec26089b1 Improve description of --max-delete. 2013-01-20 11:30:08 -08:00
Wayne Davison
76340ea44c Fix weird error in test programs on SunOS. 2013-01-19 12:07:38 -08:00
Wayne Davison
7e1a9c4d79 Update copyright year. 2013-01-19 11:05:53 -08:00
Wayne Davison
16a9883649 Update OLDNEWS with 3.0.9 info. 2013-01-19 11:05:15 -08:00
Wayne Davison
bd7d36cc6c Free ACL/xattr info in try_dests_reg() loop. 2013-01-19 10:25:18 -08:00
Wayne Davison
d42e7181d5 Add free_stat_x() inline function. 2013-01-19 10:25:18 -08:00
Wayne Davison
c03bb3d181 Further improve non-empty-destination --link-dest behavior:
- Avoid relinking a file that is already linked correctly.
- Avoid trashing the stat buffer of an existing file in try_dests_reg().
2013-01-19 10:24:46 -08:00
Wayne Davison
cee326436c Remove -3 return from try_dests_reg() again -- let it do a local copy
when the dest file is unlinked and the hard link fails.
2013-01-19 09:08:39 -08:00
Wayne Davison
0ae92567ed Align fileio's map_ptr() reads. Fixes bug 8177. 2013-01-18 15:30:08 -08:00
Wayne Davison
42f759ad9a Reformat a few things for wider lines. 2013-01-18 15:20:43 -08:00
Wayne Davison
e1ded58983 Improve handling of existing files for alt-dest opts.
Fixes bug #5644.
2013-01-18 11:57:49 -08:00
Wayne Davison
0bacaccee6 Perl version of lsh that can change user w/o sudo. 2012-10-07 16:33:30 -07:00
Wayne Davison
d46f8314b6 Fix bogus "vanished file" with "./" prefixes.
Fixes bug 9212.
2012-10-07 10:47:58 -07:00
Wayne Davison
7cefbf106f Fix indentation that used expanded tabs. 2012-10-03 15:20:43 -07:00
Wayne Davison
f143b55ef1 Avoid an unused variable warning if no setvbuf. 2012-09-23 12:03:19 -07:00
Wayne Davison
ee51a745c1 Make read_args() return the full request.
When a daemon is sent multiple request args, they are now joined into a
single return value (separated by spaces) so that the RSYNC_REQUEST
environment variable is accurate for any "pre-xfer exec".  The values
in RSYNC_ARG# vars are no longer truncated at the "." arg, so that all
the request values are also listed (separately) in RSYNC_ARG#.
2012-09-23 11:15:36 -07:00
Wayne Davison
0d34fbdf5a Make daemon listener exit w/code 0 on SIGTERM. 2012-06-16 10:31:14 -07:00
Wayne Davison
d51a3adb4f Set the modtime to 0 on a partial file.
Fixes debian bug 624826.
2012-05-05 08:01:09 -07:00
Wayne Davison
b55115ec6f Fix --only-write-batch hang with --hard-links.
Fixes bug 8565.
2012-01-28 12:04:26 -08:00
Wayne Davison
f5e2b8f803 Add a slash-stripping version of rsync in support dir. 2012-01-28 10:42:01 -08:00
Wayne Davison
41c5ba641f flist->in_progress is only needed w/inc_recurese. 2012-01-28 10:42:01 -08:00
Wayne Davison
0dfd2a64ec Make stderr line-buffered w/--msgs2stderr. 2012-01-28 10:42:01 -08:00
Wayne Davison
6686b93a7a Add new --outbuf=N|L|B option. 2012-01-28 10:41:58 -08:00
Wayne Davison
9510fa9ab8 Allow --max-size=0 and --min-size=0.
Fixes bug 7965.
2011-12-24 12:35:37 -08:00
Wayne Davison
d74512eb05 Complain if the --block-size=N value is too large.
Fixes bug 8036.
2011-12-24 12:35:37 -08:00
Wayne Davison
1a2704512a Improve the handling of verbose/debug messages
The sender no longer allows a filelist to be sent in the middle of
parsing an incoming message, so that the directory sending doesn't block
all further input reading.  The generator no longer allows recursive
reading of info/error messages when it is waiting for the message buffer
to flush.  This avoids a stack overflow when lots of messages are coming
from the receiver and the sender is not reading things quickly enough.
The I/O code now avoids sending debug messages that could mess up the
I/O buffer it was in the middle of tweaking.  This fixes an infinite
loop in reduce_iobuf_size() with high levels of debug enabled.  Several
I/O-related messages were changed to output only when --msgs2stderr is
enabled.
2011-12-21 12:14:49 -08:00
Wayne Davison
a3b62ff4cf Avoid double-free of xattr/acl data in real_sx.
Fixes bug 8665.
2011-12-16 09:07:19 -08:00
Wayne Davison
60ef397057 Mention that %a and %h are daemon-only escapes. 2011-11-24 07:55:11 -08:00
Wayne Davison
89e049ad7f Another asprintf() return-value-check tweak. 2011-11-23 13:14:35 -08:00
Wayne Davison
036094d30e Committing missed manpage tweak. 2011-11-23 12:36:50 -08:00
Wayne Davison
48b51d0004 make repeated --fuzzy option look into alt-dest dirs. 2011-11-23 12:29:25 -08:00
Wayne Davison
7da17144fd Add compatibility with an unmodified zlib. 2011-11-21 09:22:14 -08:00
Wayne Davison
cbdff74b44 Fix --compress data-duplication bug. 2011-11-21 09:17:17 -08:00
Wayne Davison
37a729768b Fix version expansion. 2011-11-21 09:10:49 -08:00
Wayne Davison
8dd6ea1f1e Fix --delete-missing-args when --relative is active. 2011-10-22 10:24:54 -07:00
Wayne Davison
7c8f180900 Test asprintf() failure with < 0, not <= 0. 2011-10-08 09:16:43 -07:00
Wayne Davison
3527677043 Let's cast getpid() to an int instead of a long for snprintf(). 2011-10-08 09:15:36 -07:00
Wayne Davison
fd91c3b666 Fix two unused-variable compiler warnings. 2011-09-22 23:37:07 -07:00
Wayne Davison
15df927ae2 Fix xattr memory leak. Fixes bug 8475. 2011-09-22 09:13:31 -07:00
Ben Walton
8adceeb2b3 Testsuite/dir-sgid: use symbolic mode to set sgid bit
The chmod on Solaris (9 and 10) cannot set the sgid bit on a directory
using absolute mode, so use symbolic mode.  Avoids a skipped test.
2011-09-22 08:28:07 -07:00
Wayne Davison
0c7fdf705e Add solaris xattr support to the tests.
Change the xattr case statements to use $HOST_OS.
(Slightly tweaked version of a Ben Walton patch.)
2011-09-20 13:24:42 -07:00
Wayne Davison
439d5d8929 Better fakeroot support helps Solaris. 2011-09-20 13:17:42 -07:00
Wayne Davison
de219101ed Change stat order for better ELOOP determination. 2011-09-20 13:02:12 -07:00
Wayne Davison
79853c30c0 Be sure to use STRUCT_STAT. 2011-09-20 12:54:06 -07:00
Wayne Davison
953feeadd2 Make do_readlink() support fake-super w/o O_NOFOLLOW. 2011-09-19 09:29:00 -07:00
Wayne Davison
3417881d5c Make --delete-excluded work better with --filter=merge. 2011-09-15 07:52:38 -07:00
Wayne Davison
397fb1acd2 When modifying PATH, export it (for Solaris). 2011-09-15 07:32:07 -07:00
Wayne Davison
db0443cf90 Added "SORTED TRANSFER ORDER" manpage section. 2011-09-13 16:04:21 -07:00
Wayne Davison
d5bff8ffe2 Cleanup some manpage & --help info. 2011-09-13 15:30:40 -07:00
Wayne Davison
a7d7f52ae0 Use "|| true" in our xattr test runs. 2011-09-13 08:07:31 -07:00
Wayne Davison
847ddaf071 Make sure other early exit calls can't hang in noop_io_until_death(). 2011-09-12 17:56:23 -07:00
Wayne Davison
c4c5dc68b9 Improve the usage for --help. 2011-09-11 22:46:57 -07:00
Ben Walton
c4170cbaac Better configure support for Solaris xattrs
If we have the attropen() function, allow OS conditional enabling of
extended attribute support.  This removes the need to pass
--enable-extended-attributes to force the feature activation on Solaris.
2011-09-11 18:48:52 -07:00
Wayne Davison
de407c03d2 Fix a potential hang on an empty file list.
Fixes bug 8423.
2011-09-11 11:08:14 -07:00
Wayne Davison
c1005fb256 Document --msgs2stderr. 2011-09-11 11:01:04 -07:00
Wayne Davison
70c4bfb770 Error out if --password-file specifed and it fails.
Fixes bug 8440.
2011-09-06 21:22:22 -07:00
Wayne Davison
a470b675af Dirs need +rx as well as +w for non-super xfers.
Fixes bug 8242.
2011-09-03 12:41:22 -07:00
Wayne Davison
5561c14978 Move implied_dot_dir=1, just to be safe. 2011-08-27 14:58:20 -07:00
Wayne Davison
865efe9456 Fix sending of "." attributes for implied-dot-dir. 2011-08-27 12:05:07 -07:00
Wayne Davison
18749579b5 Fix bwlimit multiplication overflow. Fixes bug 8375. 2011-08-27 12:05:07 -07:00
Wayne Davison
a05758fde6 Some option-parsing clarifiation in the intro. 2011-08-27 12:04:45 -07:00
Wayne Davison
fb0d4403f0 Fix misplaced parens on getnameinfo() call. 2011-08-06 11:21:40 -07:00
Wayne Davison
3fd0357f9f Ignore socketpair() on cygwin. Fixes bug 8356. 2011-08-06 11:19:00 -07:00
Wayne Davison
64fa23add9 Tweak includes to fix non-defined NULL on some systems. 2011-07-31 23:31:24 -07:00
Wayne Davison
0a77adee0b Fix Minix build errors. Fixes bug 8313. 2011-07-22 11:17:57 -07:00
Wayne Davison
0a04a80d9f Replace another inet_ntop() call with getnameinfo(). 2011-07-16 16:16:04 -07:00
Wayne Davison
7ae666d2a7 Add more connect debug info, as Carlos suggested. 2011-07-12 16:02:31 -07:00
Wayne Davison
fbf4c261f4 Move freeaddrinfo() call after failure-reporting loop. 2011-07-11 18:15:51 -07:00
Wayne Davison
425747c2f3 Fix a comment. 2011-07-04 16:32:06 -07:00
Wayne Davison
03cd1ae4fa Handle FES_NO_SEND properly on a hard-linked file.
Fixes bug 8246.
2011-07-04 16:13:45 -07:00
Wayne Davison
01580c794a Fix #ifdef in unchanged_attrs(). Fixes bug 8268. 2011-06-26 09:52:47 -07:00
Wayne Davison
a59a7b2423 Fix reading side of fake-symlink bug 7109. 2011-06-18 13:42:30 -07:00
Wayne Davison
5bfe006882 Make daemon-exclude errors more error-like.
Fixes bug 7765.
2011-06-18 12:44:26 -07:00
Wayne Davison
852585b1fc Check if sender file changed before allowing a remove.
Fixes bug 7691.
2011-06-18 12:29:21 -07:00
Wayne Davison
e2c1e482e0 Set NO_SYMLINK_USER_XATTRS on linux. Fixes bug 7109. 2011-06-18 10:12:47 -07:00
Wayne Davison
4591bb2f66 Only skip deletions on IOERR_GENERAL. Fixes bug 7809. 2011-06-04 13:04:46 -07:00
Wayne Davison
810dc9fc2a Don't force \(em in the manpages. Fixes bug 7941. 2011-06-04 12:53:10 -07:00
Wayne Davison
d80f7d6cc3 Add a colon if a non-empty pre-xfer exec message follows. 2011-06-04 12:12:49 -07:00
Wayne Davison
e3bc529de9 Handle EINTR when reading the pre-xfer exec message. 2011-06-04 12:08:18 -07:00
Wayne Davison
820f7a7b57 Send error messages from pre-xfer exec script to the user. 2011-06-04 10:46:22 -07:00
Wayne Davison
a131954b7b Linux needs symlink xattrs. Fixes bug 8201. 2011-06-04 09:47:24 -07:00
Wayne Davison
f187ce36cc We need VA_COPY() defined more. Fix dangling #endif. 2011-05-30 12:48:04 -07:00
Wayne Davison
2fff0a4f28 Merge latest samba version to get va_end() fixes, etc. 2011-05-30 10:24:57 -07:00
Wayne Davison
cb0db58fb3 Fix unwritable directory issue due to misordered chmod call. 2011-05-30 08:24:27 -07:00
Wayne Davison
582aead623 Expand NO_ENTRY items from fake-super ACLs in get_rsync_acl(). 2011-05-25 08:59:47 -07:00
Wayne Davison
d518e02243 Use a union for idlist's name/max_id value. Fixes bug 8137. 2011-05-16 18:24:34 -07:00
Wayne Davison
b9cc2d4c86 Explicitly mention spaces in the "path" setting. 2011-05-16 11:34:15 -07:00
Wayne Davison
ac30d22ae5 Check for linux/falloc.h header file. 2011-05-16 08:26:40 -07:00
Wayne Davison
8bcd6a4aff Abort if the cd fails. 2011-05-07 13:01:21 -07:00
Wayne Davison
58663df432 Turn empty remote args into dot dirs. 2011-05-07 12:42:16 -07:00
Wayne Davison
da7acc5e42 Make --files-from allow a missing trailing arg w/--server. 2011-05-07 12:16:50 -07:00
Wayne Davison
54d13604fa Mention the number of child args. 2011-05-07 12:11:56 -07:00
Wayne Davison
3ed84dbc98 Don't die if man-copy fails. 2011-04-28 18:50:21 -07:00
Wayne Davison
0308092914 Handle non-srcdir man copying when yodl isn't installed. 2011-04-28 16:41:03 -07:00
Wayne Davison
a13d3b3d77 Avoid adding a slash to path '/'. 2011-04-22 16:06:15 -07:00
Wayne Davison
813d5a25e3 Fix a potential crash when trying to find a better block match. 2011-04-22 16:06:06 -07:00
Wayne Davison
591c224584 Improve lsh's handling of -l user option w/cd. 2011-04-09 08:51:26 -07:00
Wayne Davison
b223d96bf0 Add some temp-name dot heuristics for OS X's sake.
- Drop one leading '.' from the filename (before adding our own).
 - Drop one trailing '.' from a (possibly truncated) name prior to
   the .XXXXXX suffix being added.
 - Allow the temp-name to collapse to just the .XXXXXX suffix
   if the path is long enough to require that.

Note that we don't try to remove multiple dots from a filename
that actually has multiple consecutive dots, since we might as
well learn early if the final name is going to fail or not.
2011-04-05 13:35:13 -07:00
Wayne Davison
28b519c93b Applying the preallocate patch. 2011-04-04 21:57:57 -07:00
Wayne Davison
8686d3abba Move var declaration for older C compilers. 2011-04-03 18:02:45 -07:00
Wayne Davison
73b9b90a0b Adding release info for 3.0.8 to the trunk. 2011-03-26 14:50:52 -07:00
Wayne Davison
98ec67d786 Verify the module list output of the daemon-via-ssh check. 2011-03-26 11:07:27 -07:00
Wayne Davison
0de5157564 Tweak dir xattrs after the writability fudging. 2011-03-26 10:19:04 -07:00
Wayne Davison
78286a03d1 Avoid re-setting (and sending) xattrs on a hard-linked file w/the same xattrs.
Improved the xattrs testing to include hard-linking.
2011-03-26 10:09:20 -07:00
Wayne Davison
d699d815d6 Enhance the -liconv check for OS X. Fixes bug 8018. 2011-03-20 19:33:28 -07:00
Wayne Davison
e5e6d3c410 Get the branch set right before listing names and handling --delete. 2011-03-19 16:34:37 -07:00
Wayne Davison
016ce71568 Make it possible to create a new patch file while on a patch branch. 2011-03-19 16:29:47 -07:00
Wayne Davison
2792a83d58 Don't send user/group names for ACLs with --numeric-ids.
Fixes bug 8020.
2011-03-18 14:59:03 -07:00
Wayne Davison
0b67d5e396 Fix xattrs test on OS X. 2011-03-13 20:48:18 -07:00
Wayne Davison
d52aeae4e9 Improve the &merge/&include example explanation. 2011-03-11 17:39:33 -08:00
Wayne Davison
f7c3a25052 Change rsyncd.conf &merge directive to match *.inc.
This allows the same rsyncd.d directory to be used for a set
of merge files (*.inc) and a set of include files (*.conf).
2011-03-11 16:13:33 -08:00
Wayne Davison
6da6b02bb7 Suggest a better solution for a make without wildcard support. 2011-02-26 08:12:28 -08:00
Wayne Davison
da9b72b36c Clarify what extraneous hard link are. 2011-02-23 07:19:52 -08:00
Wayne Davison
75a1a04847 Get rid of obsolete tempfs warning. 2011-02-22 15:37:26 -08:00
Wayne Davison
eee2c77a93 Some uid/gid fixes for (id_t)-1 and other large ID values.
The code now avoids any special internal meaning for uid/gid -1, which
allows it to be mapped to a better value (use 4294967295 instead of -1
as the ID to map).  Replaced atol() with something than can return a
value > 0x7FFFFFFF and that will error-out if the value overflows.  If
chown() is called with a uid or gid of -1, complain that the ID is not
settable and signal a transfer error.  Fixes bug 6936.
2011-02-22 10:27:35 -08:00
Wayne Davison
7766e67321 Allow a failure of EINVAL to mean no ACLs are available.
(If our POSIX types aren't valid, we can't handle the ACLs.)
2011-02-22 08:52:48 -08:00
Wayne Davison
4403b1332f Fix --force with --one-file-system w/o --delete. 2011-02-22 08:26:13 -08:00
Wayne Davison
c82711b34e Fix issue with devices-fake test. 2011-02-22 08:25:11 -08:00
Wayne Davison
b2e446d0cb Fix devices test on OS w/o hard-linked devices. 2011-02-22 07:39:10 -08:00
Wayne Davison
3bd9f51917 Improve some hard-link caveats in the manpage. 2011-02-20 23:30:53 -08:00
Wayne Davison
86e90c58f4 Add .hg dir exclude to default_cvsignore list.
Fixes bug 7957.
2011-02-17 22:09:08 -08:00
Wayne Davison
e1fe1d55c4 Updated a comment to match a 3.0.x change. 2011-01-29 22:24:49 -08:00
Matt McCutchen
57edc4808f Avoid changing file_extra_cnt during deletion.
The I/O code can receive incremental file-list chunks during deletion,
and their OPT_EXTRA fields would get corrupted when file_extra_cnt is
incremented.

Instead of temporarily enabling uid_ndx to find out whether the user
owns a file, have make_file() set a flag for that purpose.

Applied with a few minor tweaks by Wayne.  Fixes bug 7936.
2011-01-29 22:05:16 -08:00
Wayne Davison
69be312b5e Some minor variable and flag cleanup. 2011-01-29 22:01:37 -08:00
Wayne Davison
4b4bcbe674 Optimize finding the sum that matches our --inplace position. 2011-01-16 17:35:50 -08:00
Wayne Davison
3f26945cb1 Include backup in map_ptr() to avoid backing up when reading. 2011-01-15 11:16:49 -08:00
Wayne Davison
580cffdec9 Sender realigns chunks with generator during an --inplace copy
when sending a sequence of zeros.
2011-01-14 21:32:15 -08:00
Wayne Davison
58a1c1a218 Make sure an alternate --inplace sum has the right length
and add missing break in --inplace same-offset loop.
2011-01-14 15:37:48 -08:00
Wayne Davison
53e6507e14 Fix a bug in the trailing-slash handling. 2011-01-13 23:00:30 -08:00
Wayne Davison
3feece5938 Improve the discussion of the absolute-filter alternative. 2011-01-13 17:16:32 -08:00
Wayne Davison
4ab6125214 Have build farm always use included popt. 2011-01-04 08:00:31 -08:00
Wayne Davison
49eb0c4a35 Mention that sorting the --files-from input is helpful. 2011-01-03 19:49:05 -08:00
Wayne Davison
050e5334d8 Added "listen backlog" daemon config paramater. 2011-01-03 19:42:27 -08:00
Wayne Davison
bf4170ade8 Daemon supports forward-DNS lookups for simple hostnames
in hosts deny/allow config settings.
2011-01-03 19:04:06 -08:00
Wayne Davison
6500e0769a Avoid reading ACL/xattr info on filetypes not being copied.
Make OS X avoid xattr access on device/special files.
Fixes bug 5458.
2011-01-03 11:20:04 -08:00
Wayne Davison
aa3faf5f8c Separate the dirs from the files in xattrs.text. 2011-01-01 21:23:19 -08:00
Wayne Davison
8030518dd0 Clarify incremental recursion's effect on --hard-link. 2011-01-01 18:21:40 -08:00
Wayne Davison
e630fd1186 Some --inplace manpage enhancements. 2011-01-01 18:16:49 -08:00
Wayne Davison
d3f5c628d7 Avoid directory permission issues with --fake-super.
Fixes bug 7070.
2011-01-01 18:09:57 -08:00
Wayne Davison
8b6ebde1f3 Be clear on which part(s) of testsuite's checkit() failed. 2011-01-01 18:09:16 -08:00
Wayne Davison
1c99b1d956 Report all socket connection errors if we fail.
Fixes bug 6588.
2011-01-01 14:00:40 -08:00
Wayne Davison
575933e9d0 Itemize xattrs of a missing dir from an alt-dest dir.
Fixes bug 6576.
2011-01-01 13:10:28 -08:00
Wayne Davison
14013906ca Use full_fname() for system error messages. 2011-01-01 13:09:58 -08:00
Wayne Davison
d1b3118c16 Tweak the year. 2011-01-01 11:52:03 -08:00
Wayne Davison
8f30d21584 Protect a remote filename that starts with a dash. 2010-12-23 22:09:45 -08:00
Wayne Davison
3f770ab0a5 Set NO_SYMLINK_XATTRS on linux the easy way.
Fixes bug 7109.
2010-12-19 08:54:11 -08:00
Wayne Davison
743348e848 Fix issues with unchanged_attrs() for symlinks. 2010-12-18 08:48:07 -08:00
Wayne Davison
14ebc5b618 Fix crash when --backup-dir is excessively long. 2010-12-16 22:15:04 -08:00
Wayne Davison
aef2b8ce41 Enhance --chmod to allow octal values. 2010-12-16 21:53:07 -08:00
Wayne Davison
9f5c16e51d Avoid splitting a multi-byte character when trimming a name.
Fixes bug 7816.
2010-11-26 09:35:43 -08:00
Wayne Davison
8484ddd3d1 A couple comment tweaks. 2010-11-20 09:30:35 -08:00
Wayne Davison
51b2ff03b3 Optimize --inplace chunck search to avoid a non-aligned search. 2010-11-12 09:07:58 -08:00
Wayne Davison
96e051c86a Use ftruncate() at the end of a --sparse file.
Fixes bug 7337.
2010-11-06 10:13:16 -07:00
Wayne Davison
55f767c5ca Mention seek effect of an unmoved --inplace chunk. 2010-11-06 08:14:21 -07:00
Wayne Davison
5ebe9a46d7 Add @group auth and overrides to "auth user" daemon config. 2010-10-12 10:34:38 -07:00
Wayne Davison
d64bda1c1e Some quoting fixes/improvements. 2010-09-06 08:41:46 -07:00
Wayne Davison
c6679e04f8 If we create an off_t type, define SIZEOF_OFF_T. 2010-09-06 08:26:41 -07:00
Wayne Davison
9cb20c605f Fix rsync_xal_set reference in an error. 2010-09-06 08:09:46 -07:00
Wayne Davison
ba342e22e7 Undo unintended mode-reference tweak. 2010-08-28 18:02:22 -07:00
Wayne Davison
29358819ca Fix description of how to force new prototype generation. 2010-08-27 07:44:17 -07:00
Wayne Davison
2a189350f2 Move time setting to syscall.c and add syscall fallback.
See bug 5506 and bug 7621.
2010-08-26 15:31:07 -07:00
Wayne Davison
020df16def Make case_N.h more generic. 2010-08-26 11:13:02 -07:00
Wayne Davison
2624e005e2 Add --omit-link-times and use CAN_SET_SYMLINK_TIMES less. 2010-08-26 11:12:58 -07:00
Wayne Davison
c9bf436e5b Mention need of wildcard support in make.
See bug 7625.
2010-08-26 08:50:34 -07:00
Wayne Davison
8b48c68285 Remove duplication for -x option. 2010-08-26 07:58:22 -07:00
Wayne Davison
aff4850053 Add some new dont-compress suffixes.
As suggested in bug 6839.
2010-08-21 14:41:53 -07:00
Wayne Davison
b32fd63459 Avoid a crash with --append-verify when discarding the received data.
Fixes bug 6293.
2010-08-21 14:25:48 -07:00
Wayne Davison
3b22184d4c Avoid a non-writable-by-the-user file when copying xattrs.
Fixes part of the problem in bug 5147.
2010-08-21 14:14:31 -07:00
Wayne Davison
929002a2d5 Avoid infinite loop if the file's length is negative.
Fixes bug 4664.
2010-08-21 13:48:01 -07:00
Wayne Davison
a64840a29d Don't mention bug fixes that are queued up for 3.0.8. 2010-07-03 08:57:28 -07:00
Wayne Davison
0f6b683c8e Refer to the right lsetxattr() caller in a error message. 2010-07-03 08:14:02 -07:00
Wayne Davison
18070203c2 Replace another assert with a descriptive error. 2010-06-26 16:06:09 -07:00
Wayne Davison
b3e41255a6 I like braces when multiple lines are indented. 2010-06-26 11:43:09 -07:00
Wayne Davison
9dbb94a7e6 Older protocols should send 1-incremented dev numbers. 2010-06-26 11:42:55 -07:00
Wayne Davison
1c9eafdda0 Mention more changes. 2010-06-26 10:59:30 -07:00
Wayne Davison
cf0f454b8a More manpage improvements. 2010-06-26 10:52:04 -07:00
Wayne Davison
d8c55a6e04 Mention more output changes. 2010-06-26 10:01:24 -07:00
Wayne Davison
b320b7d6e5 Manpage improvements for --stats, --human-readable, and --list-only. 2010-06-26 10:01:13 -07:00
Wayne Davison
54504b8e4f Output list-only sizes using any human-readable setting. 2010-06-26 10:00:29 -07:00
Wayne Davison
de32838ea2 Fix accessors F_LENGTH() and F_MOD_NSEC(). 2010-06-26 08:54:57 -07:00
Wayne Davison
ce571e64b6 Close the socket fds in the "post-xfer exec" process. 2010-06-19 10:50:28 -07:00
Wayne Davison
9541770faf Get rid of some trailing whitespace. 2010-06-19 10:49:09 -07:00
Wayne Davison
3be1d9beb2 Fix compression-ignoring of upper-case suffixes.
Fixes bug 7512.
2010-06-19 09:47:00 -07:00
Wayne Davison
292a5c2b72 Fix a couple socketpair_tcp() issues (see bug 7514). 2010-06-19 09:39:55 -07:00
Wayne Davison
e60c8b59fe Fix daemon-filter crash issue (bug 7489). 2010-06-04 23:09:20 -07:00
Wayne Davison
130cdd0d90 Avoid a double-increment of a file's st_dev value
while supporting older rsyncs that send dev == 0.
2010-05-29 10:57:09 -07:00
Wayne Davison
db22e586da Make sure our idev_find() hashtable use is right. 2010-05-29 09:21:30 -07:00
Wayne Davison
60c25caa64 Make sure we never try to store a 0 key and tweak key64 init. 2010-05-29 09:20:26 -07:00
Wayne Davison
c3541d30b6 Turn an assert into two more descriptive errors. 2010-05-29 08:52:59 -07:00
Wayne Davison
86be7a0e64 Mention --debug=hlink's level limits. 2010-05-29 08:52:26 -07:00
Wayne Davison
47573508f4 Update rrsync with the latest options. 2010-05-26 11:24:00 -07:00
Wayne Davison
d1fe65fc5e Make an empty-string dest-dir the same as "." again. 2010-05-02 17:05:07 -07:00
Wayne Davison
9fbec6e44c May as well use do_mkdir() directly these days. 2010-04-30 12:58:17 -07:00
Wayne Davison
25082d1ef6 Reject passing an arg to an option that doesn't take one (bug 6915).
Based on a patch by Matt, but further tweaked to deal with -q=foo.

Ultimately this should be upstreamed, but for now lets get this
functionality into rsync.
2010-04-24 10:00:38 -07:00
Matt McCutchen
5deb19e4ea Man page description of --xattrs should not assume a push. 2010-04-24 09:58:09 -07:00
Matt McCutchen
0b8a9bd69d Minor restructuring/clarification to get_backup_name.
(Tweaked by Wayne to follow his preferred style.)
2010-04-24 09:56:34 -07:00
Matt McCutchen
7a3ce973c3 In "ignoring unsafe symlink" messages, show only the file-list path.
Rsync was showing the full destination path, which was confusing because
nothing is created at that path and was especially bogus in combination
with the source name of a solo file.

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506830
2010-04-24 09:51:54 -07:00
Matt McCutchen
be8234cd59 Point out that the file_struct in log_delete is zero-initialized
because it is static.

It took me long enough to realize this that I think it is worth
documenting.
2010-04-24 09:51:05 -07:00
Matt McCutchen
d0f2bbb83e Rename configure.in to configure.ac, the current autoconf standard. 2010-04-24 09:34:43 -07:00
Matt McCutchen
ef7441669b Fix erroneous "--fake-user" in the rsyncd.conf(5) man page. 2010-04-24 09:30:04 -07:00
Matt McCutchen
9a54a640f7 Don't set the umask to 0 any more: it's ugly and pointless. 2010-04-24 09:28:58 -07:00
Matt McCutchen
58a79f4b44 Amplify the man page description of --hard-links (see bug 3693), and
improve that of --inplace while I'm at it.
2010-04-24 08:11:54 -07:00
Matt McCutchen
ae03e0e008 Document the "copy-some-dirlinks" trick in the man page.
Originally explained at:

http://lists.samba.org/archive/rsync/2006-February/014838.html
2010-04-24 08:07:56 -07:00
Wayne Davison
554dc122f2 Removing now-redundant path-size check from send_if_directory(). 2010-03-31 14:57:01 -07:00
Wayne Davison
8c934eba05 Fix a typo that Andrea Gelmini pointed out. 2010-03-27 12:06:45 -07:00
Wayne Davison
41ae04e09c Get rid of trailing whitespace. 2010-03-27 12:05:01 -07:00
Wayne Davison
9a7532e516 Fix directory-length overflow bug (7057). 2010-03-26 16:58:39 -07:00
Wayne Davison
9b594a530f Handle files that spring up while doing backup path checking. 2010-03-09 11:58:07 -08:00
Wayne Davison
5d8dcd1edb Write out the right compat_flags value into the batch file. 2010-02-17 14:55:34 -08:00
Wayne Davison
afccb3d326 If a module has no path setting, return an error. 2010-02-06 13:40:12 -08:00
Wayne Davison
0d78a27893 Mention what -XX (repeated --xattrs) does. 2010-02-06 13:32:47 -08:00
Wayne Davison
05c36015f7 More --timeout improvements, especially for the receiving side:
- The receiver now sends keep-alive messages to the generator
  when it is actively doing work and hasn't sent anything
  recently.  This ensures that the generator won't timeout
  if the receiver is working hard.
- The perform_io() code has improved keep-alive participation.
- Allow the sender to send some keep-alive messages, which
  ensures that if it is in a lull, it can probe the socket.
2010-01-02 10:58:39 -08:00
Wayne Davison
e34f43495c Don't try to send MSG_ERROR_EXIT after a timeout. 2010-01-02 09:14:19 -08:00
Wayne Davison
4256264991 Always use lchmod() if it is available. 2009-12-31 14:10:38 -08:00
Wayne Davison
fa5a06ad0c Mention 2010 in the main copyright. 2009-12-31 13:43:10 -08:00
Wayne Davison
794f2cbab3 Adding release info for 3.0.7 to the trunk. 2009-12-31 13:41:23 -08:00
Wayne Davison
12e59929e2 Allow any gcc to make use of __builtin_alloca for alloca. 2009-12-30 20:04:20 -08:00
Wayne Davison
fc4bb1230e Configure check for -Wno-unused-parameter now tries to link too. 2009-12-30 19:59:49 -08:00
Wayne Davison
a01e3b490e Change naming of local patch-related branches and unify
the git-status checking into a library.
2009-12-30 13:57:39 -08:00
Wayne Davison
2b2a473831 Add understanding of RSYNC_PROTECT_ARGS environment var. 2009-12-30 12:29:47 -08:00
Wayne Davison
4c4a296209 Allow "./configure --with-protect-args" to make -s the default. 2009-12-29 12:08:41 -08:00
Wayne Davison
e89a0fc094 Handle check-in and tagging of patches dir. 2009-12-26 14:29:51 -08:00
Wayne Davison
164faae84f Improve handling of MSG_IO_ERROR message. 2009-12-23 14:14:54 -08:00
Wayne Davison
de6ab501b6 Pass the 'f' compatibility flag to the server (via -e)
so that 3.0.7 knows we support the safer flist-xfer method.
2009-12-21 14:37:47 -08:00
Wayne Davison
4286ea6036 Don't die if inflate() returns Z_BUF_ERROR in see_deflate_token(). 2009-12-21 10:15:13 -08:00
Wayne Davison
626b5ae839 Don't set last_io_out in check_timeout. 2009-12-19 13:42:35 -08:00
Wayne Davison
92d021488e Improve --timeout method to take into account all I/O that is going on.
The receiving side also switches timeout handling from the receiver to
the generator, which obviates the need for the sender to send any
keep-alive messages at all (for protocol 31 and beyond).  Given this
setup, all keep-alive messages are now sent as empty MSG_DATA messages,
with MSG_NOOP messages only being understood and (when necessary) acted
upon to forward a keep-alive event to an older receiver.  This is both
safer and more compatible with older versions.
2009-12-19 11:00:36 -08:00
Wayne Davison
82b2a31a46 Added an am_receiver variable. 2009-12-19 10:14:49 -08:00
Wayne Davison
eeea1bbd72 Improved some I/O comments. 2009-12-17 09:00:52 -08:00
Wayne Davison
aa3999d66c Fix the val reading for MSG_ERROR_EXIT. Use 0-length MSG_DATA when
MSG_NOOP is not available (is both safer and supports older rsyncs).
2009-12-16 12:38:54 -08:00
Wayne Davison
6e9ad2bb03 Allow per-test timeout overrides. Give hardlinks more time. 2009-12-15 08:44:46 -08:00
Wayne Davison
c5130bc123 Improve the timeout messages. 2009-12-15 08:32:18 -08:00
Wayne Davison
f8e1fa6272 Free a strdup() in do_cmd() that checker was complaining about. 2009-12-13 19:28:01 -08:00
Wayne Davison
8e7f3107a4 Avoid -u option to id since solaris doesn't support it. 2009-12-13 18:15:09 -08:00
Wayne Davison
c2dd3ec32c Avoid a compiler warnings about a signed/unsigned mismatch. 2009-12-13 17:52:05 -08:00
Wayne Davison
e9ad7bb1f8 Increase the testrun timeout for slow compilefarm systems. 2009-12-13 17:49:09 -08:00
Wayne Davison
b9107ee61e Fix a compiler warning about a %d mismatch. 2009-12-13 17:47:35 -08:00
Wayne Davison
45426a7604 Run each testsuite test with a timeout. 2009-12-13 14:14:38 -08:00
Wayne Davison
dc2a0923a2 Avoid another checker warning. 2009-12-13 13:21:30 -08:00
Wayne Davison
ac32cdd7d4 Prevent the reading of another message before the end of the current one. 2009-12-12 21:54:52 -08:00
Wayne Davison
6d952fdbe7 Change a variable name in read_a_msg(). 2009-12-12 21:40:02 -08:00
Wayne Davison
870cf55287 This should fix another checker warning. 2009-12-12 15:58:53 -08:00
Wayne Davison
7d0fe4da70 Fix checker compile warning. 2009-12-12 15:51:03 -08:00
Wayne Davison
763880ba81 Turn iobuf.in into a circular input buffer. 2009-12-12 15:16:46 -08:00
Wayne Davison
2885270b52 Fix a hang that can happen when the sender is sending an extra file-list
and no one is reading (i.e. do advantageous reading in perform_io()).
2009-12-12 09:46:02 -08:00
Wayne Davison
0c2e8f9364 Don't send MSG_ERROR_EXIT messages at the end of the transfer.
Added some debug output for MSG_ERROR_EXIT messages.
2009-12-12 08:54:36 -08:00
Wayne Davison
24079e988f Don't (wrongly) retouch dir permissions with --fake-super.
(Patch from Matt.)
2009-11-28 21:46:42 -08:00
Wayne Davison
8a68cad1f7 Add IPv6 detection on cygwin. 2009-11-26 15:17:49 -08:00
Wayne Davison
d03c0b1ed3 Fix a comment. 2009-11-23 22:45:29 -08:00
Wayne Davison
907e6a32a0 Change the handling of circular buffers to not waste 4 bytes
all the time (we only waste from 1-3 bytes some of the time).
2009-11-23 08:16:18 -08:00
Wayne Davison
e4c598c830 Make some RERR_* choices better, and another noop_io_until_death() tweak. 2009-11-16 12:35:17 -08:00
Wayne Davison
ae598f3847 Don't complain about a socket EOF unless it affects a read.
Make sure a write error drains any messages in the input buffer.
2009-11-15 12:54:55 -08:00
Wayne Davison
d85d029b92 Tweak the noop_io_until_death() timeout and comment it. 2009-11-14 23:05:52 -08:00
Wayne Davison
d620b907e4 Improved a couple comments and added some "else" optimizations. 2009-11-14 10:01:13 -08:00
Wayne Davison
5692657757 No need to check MIN_FILECNT_LOOKAHEAD w/extra_flist_sending_enabled. 2009-11-14 09:58:25 -08:00
Wayne Davison
c493b6b81d Make the two "wrap-bytes" sections simpler and more similar. 2009-11-14 09:56:42 -08:00
Wayne Davison
4e2a7e59e5 Prefer send_msg_int() over send_msg() for better debug output. 2009-11-14 09:52:40 -08:00
Wayne Davison
b82d8c9d1a Tweaked sizing checks in perform_io(). 2009-11-14 09:51:26 -08:00
Wayne Davison
75ea845904 Fixed the buffer-has-space check in write_buf(). 2009-11-14 09:43:02 -08:00
Wayne Davison
ce795fcd75 Make --bwlimit take the same size suffixes as the --max-size option
(while keeping it backward compatible). Improve --bwlimit docs.
2009-11-12 23:55:21 -08:00
Wayne Davison
aa381148a3 Fix the daemon test when running it as root. 2009-11-12 22:05:45 -08:00
Wayne Davison
cece2e3f5e Make use of seteuid() determined by configure. 2009-11-08 20:17:02 -08:00
Wayne Davison
f397616e00 Change an RERR_* to RERR_FILEIO. 2009-11-08 11:51:02 -08:00
Wayne Davison
4351c039ad Mention who got the unknown logcode. 2009-11-08 11:50:43 -08:00
Wayne Davison
304d7b5817 More improvements for abnormal exits. 2009-11-08 11:45:55 -08:00
Wayne Davison
9270e88d76 Save first filename and linenum in case exit_cleanup() recurses. 2009-11-08 00:12:33 -08:00
Wayne Davison
2907af472d Try to silence some warnings from "checker". 2009-11-07 09:46:20 -08:00
Wayne Davison
8346c62a95 Mention the error improvements. 2009-11-07 09:46:01 -08:00
Wayne Davison
4655dcf218 Give noop_io_until_death() a time limit. 2009-11-07 09:45:43 -08:00
Wayne Davison
f9185203ee Added notifications about error-exit values:
- The receiver notifies the generator if it is exiting with an error,
  and then, if it is a server, waits around for the generator to die.
  This ensures that the client side has time to read the error.
- The generator or sender will notifiy the other side of the transfer of
  an error-exit value if protocol 31 is in effect.  This will get rid of
  some "connection unexpectedly closed" errors that are really expected
  events due to a fatal exit on the other side.
2009-11-07 01:22:11 -08:00
Wayne Davison
84c11e85a4 Fix MSG_IO_TIMEOUT when the daemon is the receiver. 2009-11-01 13:57:17 -08:00
Wayne Davison
6be8a8b14d A daemon treats --msgs2stderr as "output only to the log, not the user". 2009-11-01 13:43:29 -08:00
Wayne Davison
ef9d3a152b Make sure rwrite() can handle any logcode value in --msgs2stderr mode. 2009-11-01 13:26:15 -08:00
Wayne Davison
fe16d9a67d Fix a hang when dealing with really large numbers of files
in an incremental recursion scan.
2009-10-29 17:35:54 -07:00
Wayne Davison
23a0d1e200 Get rid of some unneeded externs. 2009-10-27 12:38:30 -07:00
Wayne Davison
a0f1ed55cd Change the daemon-timeout conveyance into a protocol-31 message. 2009-10-27 12:38:04 -07:00
Wayne Davison
4dde3347fb Fix %b and %c so that they count per-transfer bytes again. 2009-10-25 22:27:01 -07:00
Wayne Davison
44a97a34b1 Enhance log_format_has() to understand the "'" modifier. 2009-10-25 21:24:48 -07:00
Wayne Davison
281a141ea7 Updated NEWS with some of the recent changes. 2009-10-25 13:51:09 -07:00
Wayne Davison
8e6b4ddbe8 A few more --files-from fixes, and an enhanced testsuite for it. 2009-10-24 12:39:58 -07:00
Wayne Davison
9ccc8f8bbb Add a check30 target. 2009-10-24 12:37:26 -07:00
Wayne Davison
2170667802 Make use of $suitedir. 2009-10-24 11:42:29 -07:00
Wayne Davison
705132bcee Fixed some backward-compatibility issues with --files-from. 2009-10-24 11:12:37 -07:00
Wayne Davison
0dd2310cac Moved some --iconv text that was supposed to be in --files-from. 2009-10-24 00:23:21 -07:00
Wayne Davison
cbc63a09e8 Fixed a couple iconv loops to properly handle incomplete chars
that span two reads.
2009-10-24 00:19:40 -07:00
Wayne Davison
a0a88e0ef3 Move free_xbuf() into ifuncs.h. 2009-10-23 22:55:06 -07:00
Wayne Davison
d8a7290f86 Give iconvbufs() an ICB_INIT flag. 2009-10-23 22:51:29 -07:00
Wayne Davison
3b8f819222 A protocol 31 daemon will inform the client about its timeout setting
so that the client will be able to cooperate with keep-alive.
2009-10-20 15:07:51 -07:00
Wayne Davison
8b3e6fb985 Make sure daemon's io_timeout is used as a maximum value. 2009-10-20 15:05:15 -07:00
Wayne Davison
d720569422 Moved a few group-related functions with some minor tweaks; 2009-10-20 07:54:21 -07:00
Wayne Davison
0a56ef128c Silence some rprintf() size_t warnings. 2009-10-19 08:06:21 -07:00
Wayne Davison
0a9fbe17de Allow %VAR% environment references in daemon-config parameter values. 2009-10-17 16:30:23 -07:00
Wayne Davison
d23cc156aa Call seteuid() when calling setuid(). 2009-10-17 15:03:11 -07:00
Wayne Davison
6f098b0f8c Fix some man page problems Scott Kostyshak pointed out. 2009-10-17 11:06:49 -07:00
Wayne Davison
1ec57e4ddc Fix check for an empty output buffer and limit to flist_eof. 2009-10-17 11:06:20 -07:00
Wayne Davison
20caffd2b3 A major overhaul of I/O routines, creating perform_io().
Files-from data is now sent as multiplexed I/O so that it can mingle
with any messages (such as debug output).  Requires protocol 31.

Protocol 31 no longer disables output verbosity in a couple instances
that used to cause protocol issues.

Got rid of MSG_* messages that have implied raw data that follows after
them.  We instead send a negative index value as a part of the raw data
stream, which is guaranteed to be output together with the following
data.  This only affects the (in-progress) protocol 31 and the (self-
contained) communication stream from the receiver to the generator.

Added --debug=IO and improved --debug=FLIST.  Some --debug=IO output
requires --msgs2stderr to be used to see it (i.e. sending a message
about sending a message would send another message, ad infinitum).
2009-10-17 00:03:32 -07:00
Wayne Davison
df6350a8b8 Avoid type-punned compiler warnings for the byteorder.h macros
by using inline functions for the 4-char <-> uint32 conversions.
2009-10-13 21:10:57 -07:00
Wayne Davison
7a7810aa2f Avoid calling send_extra_file_list() when we shouldn't. 2009-10-13 10:45:23 -07:00
Wayne Davison
41000dffc1 Avoid stopping multiplexed out over the message fd.
Use simpler multiplexed-out stopping method.
Make sure we can't false-match a socket fd.
2009-10-12 09:10:50 -07:00
Wayne Davison
d8587b4690 Change the msg pipe to use a real multiplexed IO mode
for the data that goes from the receiver to the generator.
2009-10-02 14:18:51 -07:00
Wayne Davison
e8bb37f567 Better mask handling, including some changes to help solaris. 2009-09-12 09:40:31 -07:00
Wayne Davison
ee1c00fea8 Pass "new_mode" to set_acl() and change its return values. 2009-09-12 09:27:07 -07:00
Wayne Davison
1b502f3ec2 Put file descriptor arg at the start of the arg list for consistency. 2009-09-12 09:13:38 -07:00
Wayne Davison
44d7d045c7 Improve the "--delete does not work without -r or -d" message. 2009-09-07 14:22:59 -07:00
Wayne Davison
1a2e41af94 Add support for transferring & setting nsec time values. 2009-09-07 14:11:58 -07:00
Wayne Davison
accc091fe9 Always use lutimes() if it is available. 2009-09-07 13:45:33 -07:00
Wayne Davison
4b660bae92 Add a few new "dont compress" suffixes and improve the docs. 2009-09-05 10:29:29 -07:00
Wayne Davison
2f1fb732d4 Improve error handling and get rid of a lingering fprintf(). 2009-09-05 10:25:42 -07:00
Wayne Davison
59924aa8cf Fix daemon's conveyance of io_error value from sender. 2009-09-05 09:40:53 -07:00
Wayne Davison
b15fa9bd7b Avoid an dry-run error trying to stat a prior hard-link
file that hasn't really been created.
2009-09-05 08:18:35 -07:00
Wayne Davison
2c1aa2efac Need to use O_RDONLY in solaris sys_lremovexattr(). 2009-09-03 15:25:55 -07:00
Wayne Davison
6e310d38fc Have --fake-super turn a symlink into a file when
NO_SYMLINK_XATTRS is defined.
2009-09-02 09:06:29 -07:00
Wayne Davison
3b83a22057 Define and use "our_gid" variable. 2009-09-02 08:56:34 -07:00
Wayne Davison
8e15bd87dd Better compiling if SUPPORT_LINKS is not defined. 2009-09-02 08:53:40 -07:00
Wayne Davison
4a440e4be8 Rebuild proto.h if config.h changes. 2009-09-02 08:52:41 -07:00
Wayne Davison
486ecd3d9c Fix attropen() flags for writing an xattr on solaris. 2009-09-02 07:37:55 -07:00
Wayne Davison
17cc4c383b Fix read_xattr() for solaris. 2009-09-01 12:11:32 -07:00
Wayne Davison
c55fb5e1d6 Create non-transferred files in a more atomic manner:
If a symlink, device, special-file, or hard-linked file is replacing
an existing non-directory, the new file is created using a temporary
filename and then renamed into place.  Also changed the handling of
a cluster of hard-linked symlinks/devices/special-files to always
ensure the first item in the cluster is correct, since it doesn't
really save any significant work to try to find an existing correct
item later in the cluster to link with.
2009-08-29 16:18:57 -07:00
Wayne Davison
8a21be11f0 Fix the chmod-temp-dir test if /var/tmp doesn't exist.
Fixes bug 6569.
2009-08-22 09:34:01 -07:00
Wayne Davison
ce827c3e50 Have the sender use dead time to pad out the file list. 2009-08-22 08:15:26 -07:00
Wayne Davison
2523d0cc14 Allow Solaris sys_llistxattr() to return the list length when size == 0. 2009-08-15 06:43:06 -07:00
Wayne Davison
18bd04018d Fix some variable references. 2009-08-15 06:27:19 -07:00
Wayne Davison
4c3e9c09eb Fix a bogus free in uncache_tmp_xattrs(). 2009-08-14 07:05:48 -07:00
Wayne Davison
05a652d0b7 Some improvements to the solaris xattr routines.
Inspired by the patch to bug 6633.
2009-08-13 08:02:53 -07:00
Wayne Davison
845ed84d70 Fix a warning about a %d not getting an int (on some platforms). 2009-08-10 09:24:53 -07:00
Wayne Davison
049f8cbc8a Initial version of xattr routines for Solaris. 2009-08-08 13:27:58 -07:00
Wayne Davison
0d5ebab1d6 Add conditional support for excluding types of files from xattr ops. 2009-08-08 13:21:26 -07:00
Wayne Davison
dab0fb7cf0 Get section reference right. Fixes bug #6573. 2009-08-01 11:29:55 -07:00
Wayne Davison
62342430bf Added solaris IPv6 checking to configure. Fixes #6438.
Patch from Tim Spriggs.
2009-06-05 13:02:55 -07:00
Wayne Davison
63070274f2 Mention that --whole-file is not the default for a local transfer when
writing a batch file.
2009-06-01 09:09:09 -07:00
Wayne Davison
06886d36cf Adding a new script that creates a local patch/* branch
for each file given on the command-line.
2009-05-23 13:40:34 -07:00
Wayne Davison
9ba4d44fa8 Improved the usage output. 2009-05-23 13:40:23 -07:00
Wayne Davison
350242c5c1 Determine the master's commit hash and note it in each patch
that is based on the master in the new "based-on:" line.
2009-05-23 13:12:01 -07:00
Wayne Davison
181c9faf92 Mention some recent changes. 2009-05-23 11:45:17 -07:00
Matt McCutchen
c8fa85b23b Refactorings to the filter code, most notably:
- Improve function name: parse_rule -> parse_filter_str (to make the
  similarity with parse_filter_file clearer, and better indicate that
  it can parse multiple rules when FILTRULE_WORD_SPLIT is specified).

- In preparation for rule prefixes containing information beyond the
  rflags, change the code to pass around a full "template" filter_rule
  instead of just rflags.  Callers of parse_filter_{str,file} that want
  to specify only rflags can use rule_template(rflags) .

- Remove the MODIFIERS_* strings and instead hand-code the condition
  under which each modifier is valid.  This should make it easier to
  see that the conditions are correct.

- Tighten up default modifiers on merge rules:
  - Disallow "!" because it isn't useful.
  - If the merge rule specifies a side via "s" or "r", the rules in the
    file cannot also specify a side via "s", "r", "hide", etc.

[Patch was changed by Wayne a bit prior to application.]
2009-05-23 11:20:40 -07:00
Wayne Davison
a61ec6b168 Improved a couple variable names. 2009-05-23 10:41:16 -07:00
Wayne Davison
7b6c5c7794 Use typedefs for the filter structures. 2009-05-23 09:07:43 -07:00
Wayne Davison
b32d425451 Change filter MATCHFLGs to FILTRULEs. 2009-05-23 09:07:35 -07:00
Wayne Davison
134f97c9cc Support an older AIX system that doesn't have ENOTSUP. 2009-05-14 11:23:38 -07:00
Wayne Davison
87755c6cea Switch from inet_aton() to inet_pton() (since we supply a compatibility
function for the latter, it will always exist).
2009-05-14 11:22:37 -07:00
Wayne Davison
8f73c8a498 Adding release info for 3.0.6 to the trunk. 2009-05-08 11:13:37 -07:00
Wayne Davison
0cdb547f5c Fix typo pointed out by Chris Pepper. 2009-05-07 08:02:17 -07:00
Wayne Davison
56017d3150 Enhance name_to_{u,g}id() to optionally parse numbers and rename
to {user,group}_to_*().  Based on a patch by Matt McCutchen.
2009-05-07 07:34:42 -07:00
Matt McCutchen
d960af72b2 Move the description of include/exclude modifiers to a better place
in the man page.
2009-05-05 07:46:54 -07:00
Wayne Davison
fd2b6046cb Clarify which options are transfer rules, and what that means. 2009-04-27 07:26:23 -07:00
Wayne Davison
a8e6e14869 Change sending/receiving/storing of the rdev value for special files.
Since the value is not needed, protocol 31 no longer sends it, while
older protocols are optimized so the sender just sends a valid rdev
value as efficiently as possible.  The receiver no longer caches an
rdev value for special files, and the generator will always pass a 0
rdev value to do_mknod() for special files. Fixes bug #6280.
2009-04-26 07:43:32 -07:00
Wayne Davison
307555eba3 Use upper-case HLINK in a --debug setting to avoid a really weird bug
in the strncasecmp() of OpenSUSE 10.2 (x86_64).
2009-04-13 21:07:12 -07:00
Wayne Davison
261808dac1 Switch to upper-case in the {debug,info}_verbosity arrays. 2009-04-13 07:37:49 -07:00
Wayne Davison
5250c3bc20 Changed the commands used to "make gen" without any stoppage. 2009-04-12 15:44:52 -07:00
Wayne Davison
9eaba7266c Don't allow --remove-s*-files with --read-batch. 2009-04-12 12:57:31 -07:00
Wayne Davison
d510e82fc6 Fixed the use of --xattrs with --only-write-batch. 2009-04-12 12:51:20 -07:00
Wayne Davison
4e9c7fae8f The suffix must be non-empty if the backup-dir is the same as the dest
dir.
2009-04-11 17:31:13 -07:00
Wayne Davison
3696674bc6 More backup improvements:
- Changed get_backup_name() to verify the backup path, and make any
  missing directories.  This avoids accidental use of a symlink as a dir
  in a backup path, and gets rid of any other non-dirs that are in the
  way.  It also avoids the need for various operations to retry after
  calling make_bak_dir(), simplifying several pices of code.
- Changed create_directory_path() to make_path(), giving it flags that
  lets the caller decide if it should skip a leading slash or drop the
  trailing filename.
- Mention when we create the backup directory, so the user is not caught
  unaware when rsync uses a directory they didn't expect.
- Got rid of some dir-moving backup code that is not used.
- Added a little more backup-debug output.
2009-04-11 11:51:07 -07:00
Wayne Davison
5e2d51ee06 Fix "just in case" unlink. Prefer renaming of normal files
if hard-linking fails.
2009-04-11 06:37:49 -07:00
Wayne Davison
d735fe2014 Improved link_or_rename() to handle prefer_rename better. 2009-04-10 23:33:08 -07:00
Wayne Davison
7e6c8ad653 Don't try to backup a file being removed from the backup area. 2009-04-10 23:14:06 -07:00
Wayne Davison
407ea78a62 Allow a "make reconfigure" to continue, even if the Makefile changes. 2009-04-10 16:24:12 -07:00
Wayne Davison
cb197514d9 Fixed an ACL/xattr corruption issue where the --backup option could cause
rsync to associate the wrong ACL/xattr information with received files.
2009-04-10 16:22:44 -07:00
Wayne Davison
a055dbdd88 Allow $RSYNC_TEST_TMP to indicate a good tmp dir for our tests. 2009-04-10 08:19:16 -07:00
Wayne Davison
5eb8bd4962 Don't try to simplify an ACL that has a mask w/o any named values. 2009-04-09 22:49:24 -07:00
Wayne Davison
e129500c85 Some improvements to the rsync.yo manpage:
- Mention the switch from MD4 to MD5.
- Mention the default for the --log-file-format option.
2009-04-07 07:39:34 -07:00
Wayne Davison
7fc2ca2551 Make sure that config.h.in is up-to-date before allowing the
Makefile-updating rule to run ./config.status.
2009-04-04 07:52:26 -07:00
Wayne Davison
83c32ca572 Fixed --dry-run with --read-batch:
- Avoid sending MSG_NO_SEND to the generator.
- Check if the file is wanted before discarding the batched data.
2009-04-04 07:25:25 -07:00
Wayne Davison
1a85a969a7 Fixed improper deletion of mount-point hierarchies.
Fixes bug #6240.
2009-03-31 20:15:44 -07:00
Wayne Davison
7f2591eaea Fixed a word ending that Jesse Weinstein and revamp some of the text
to make it clearer.
2009-03-31 14:34:31 -07:00
Wayne Davison
eecc969e9b Make symlink iconv work for a local copy.
Fixes issue mention in bug #5615.
2009-03-29 13:24:15 -07:00
Matt McCutchen
f8605c5b89 Give a meaningful error message when we fail to write to a batch file. 2009-03-13 09:45:35 -07:00
Wayne Davison
42d8ec616d My version of Matt's improvements related to missing source args:
- Implement --ignore-missing-args.
- In the absence of --*-missing-args, a missing source arg is an
  FERROR_XFER, but doesn't need to be an IOERR_GENERAL.
- Revise the man page.
2009-03-13 09:37:31 -07:00
Wayne Davison
7781241889 Make missing args governed by protect filters, not hide. 2009-03-13 08:49:53 -07:00
Wayne Davison
b5473dd4a9 Made --list-only output missing args as a "*missing" line. 2009-03-06 22:42:13 -08:00
Wayne Davison
4e0fa131fe Don't let --chmod tweak a 0 mode value (which marks a missing arg). 2009-03-06 22:41:23 -08:00
Wayne Davison
17a1676976 Simplify an "if" in ssh-basic.test. Fixes bug #6169; 2009-03-06 07:07:43 -08:00
Wayne Davison
b4d30300b9 Improved the unsafe_symlink() code to not get fooled by extra '/' chars
in the symlink's path.  Added test cases.  This fixes bug #6151.
2009-03-03 08:46:57 -08:00
Wayne Davison
e6f3a33c5e Make the backup code call unsafe_symlink() correctly. 2009-03-03 08:42:56 -08:00
Wayne Davison
ce66f41791 Added the --delete-missing-args option to delete specified
files on the receiver that don't exist on the sender.
2009-02-28 09:25:26 -08:00
Wayne Davison
8d10cbfcb1 Made --progress use ir-chk instead of to-chk when the incremental
recursion scan is still active.  Mention the output change more
prominently in the NEWS file.  Updated the --progress output in
the manpage, with mention of the new "ir-chk" string's meaning.
2009-02-28 08:07:01 -08:00
Wayne Davison
e8d6fe6261 Properly indent some lines. 2009-02-19 23:09:20 -08:00
Wayne Davison
7f367bb1b4 Added a way for supplementary groups to be specified in the rsyncd.conf
file.  Also made explicitly-set uid/gid values no longer ignored by a
daemon that was not run by a super-user.
2009-02-19 23:08:48 -08:00
Wayne Davison
df7ec1cf42 Adding a way for log-format numbers to become more human readable. 2009-02-18 07:26:48 -08:00
Wayne Davison
6437b817c0 Mention that only the first line of a password-file is used. 2009-02-16 10:31:58 -08:00
Wayne Davison
d39d60a129 Handle a link_stat() failure with errno ENOENT as a vanished file. 2009-02-14 08:35:57 -08:00
Wayne Davison
49c2407141 Added --disable-iconv-open option for configure to turn off all use
of the iconv_open() function.  Implies --disable-iconv (which turns
off the --iconv option).  Fixes bug #6107.
2009-02-14 07:50:09 -08:00
Wayne Davison
44ae54114a Moved the --disable-debug check sooner in configure.in so that it
happens prior to checking for the compiler.  Switched no-debug code
to setting ac_cv_prog_cc_g=no.  Fixes bug #6106.
2009-02-14 07:48:40 -08:00
Wayne Davison
43eb865f9a Made copy_section() and string_set() simpler, getting rid of a
"FIXME" comment that we don't need to fix.
2009-02-06 07:27:18 -08:00
Wayne Davison
789213909d Combine Globals and Locals into a Vars struct that parallels Defaults,
shortening some code.  Improve comments and make other minor cleanups.
Based on a patch that Matt McCutchen posted to the mailing list.
2009-02-05 07:35:33 -08:00
Wayne Davison
46cd1ef6bc Ensure that the sender turns off any msg_fd_in use earlier.
This avoids a problem where an extra message from the sender
could give the generator time to start sending data that will
not be understood by the sender's use of read_msg_fd().
2009-02-04 18:23:59 -08:00
Wayne Davison
6e80613717 Do not try to send a symlink with a 0-length value.
This avoids a transfer error in the receiver.
2009-02-04 18:13:09 -08:00
Wayne Davison
dc6fb11b41 We only need to send --stats to a remote receiver now. 2009-01-30 08:45:54 -08:00
Wayne Davison
4d13a2fe55 A few more improvements to the hostspec-parsing code. 2009-01-28 23:17:46 -08:00
Wayne Davison
58cf354711 Fixed the parsing of IPv6 literal addresses with a username
prefixed.  Fixes bug #6067.
2009-01-28 15:59:06 -08:00
Wayne Davison
7a498f5b6c Check the right flist_num in gen_wants_ndx(). 2009-01-18 23:02:36 -08:00
Wayne Davison
243e9a366d Added a "Defaults" structure with both globals and locals in it.
Initialize both the Globals and Locals back to their default values
when reading the config.  This fixes a bug where locals set in the
global section were not getting reset to their default value if the
config item was removed from the file.
2009-01-18 22:42:41 -08:00
Wayne Davison
b53c202e45 A couple minor function-call tweaks. 2009-01-18 22:40:17 -08:00
Wayne Davison
aef68d7892 Renamed some typedefs:
- global -> global_vars
- section -> local_vars
- global_and_section -> all_vars
2009-01-18 22:39:57 -08:00
Wayne Davison
077e543b7d Renamed sDefault to Locals. 2009-01-18 22:39:20 -08:00
Wayne Davison
9784f01cbc Use a varint when sending the error_code. 2009-01-17 14:52:13 -08:00
Wayne Davison
bc40a30503 Fixed the delete statistics with --delete-delay and --delete-after. 2009-01-17 14:46:42 -08:00
Wayne Davison
4079d6a684 Fixed a hang in the inc_recurse batch-reading code. 2009-01-17 13:59:08 -08:00
Wayne Davison
df694f72ed Change some args from "char *" to "const char *" in order to get rid of
a compiler warning that was just introduced.  Also avoids changing the
host string to lower-case in access.c (by using iwildmatch()).
2009-01-15 00:23:07 -08:00
Matt McCutchen
11ef77b76a Added the "reverse lookup" daemon-config parameter. 2009-01-15 00:22:36 -08:00
Wayne Davison
abd32c9585 Send the --stats option for proper del-stats operation. 2009-01-14 07:38:37 -08:00
Wayne Davison
01e293f1b5 Use "use warnings" rather than -w on the #! line. 2009-01-13 14:52:03 -08:00
Wayne Davison
8051aa5a34 Adding recent release info from the 3.0.x branch. 2009-01-13 13:53:01 -08:00
Matt McCutchen
46d68be3da Fixed recv_add_uid() to properly differentiate users and groups. 2009-01-13 11:21:06 -08:00
Matt McCutchen
bb499bd7a0 Handle simultaneous arrival of multiple connections. 2009-01-13 09:42:54 -08:00
Wayne Davison
416cef36e9 Tweaked the --delete-* option summaries. 2009-01-08 17:01:38 -08:00
Wayne Davison
1fb6a4018d Avoid a server-side problem with -e is at the start of the short options.
(Bug #6020)
2009-01-07 16:39:22 -08:00
Wayne Davison
fc4a695cdd Tweaked s### and m## to avoid vim highlighting issues. 2009-01-07 16:38:06 -08:00
Wayne Davison
83238ed0bb Fixed bug #6011: use of target in configure. 2009-01-03 20:50:54 -08:00
Wayne Davison
21cddef2b4 Improved the backup code:
- Backups do not interfere with an atomic update (when possible).
- Backing up a file will remove a directory that is in the way
  and visa versa.
- Unify the backup-dir and non-backup-dir code in backup.c.
- Improved the backup tests a little bit.
2009-01-03 12:02:47 -08:00
Wayne Davison
b3bf9b9df9 Update the copyright year. 2009-01-03 10:57:14 -08:00
Wayne Davison
974e18191c Make delete_item() public, moving it into delete.c. 2009-01-03 10:52:50 -08:00
Wayne Davison
09ca0d15d3 Added init_stat_x() to avoid duplication of acl/xattr init code. 2009-01-03 08:53:59 -08:00
Wayne Davison
c43c66125e Allow opendir() in send_directory() to fail with ENOENT. 2008-12-27 11:09:53 -08:00
Wayne Davison
8b7a752024 Mention the mapfrom/mapto scripts and how they work. 2008-11-15 18:32:21 -08:00
Wayne Davison
2df20057e3 Adding the --usermap/--groupmap/--chown options. 2008-11-15 18:13:00 -08:00
Wayne Davison
9556f156a9 Make it clearer which configure files changed. 2008-11-15 15:31:38 -08:00
Wayne Davison
aade88bfc2 An ftruncate() failure should result in FERROR_XFER. 2008-11-15 14:50:40 -08:00
Wayne Davison
3795dafd97 Change clean_fname() to keep "//" at the start for cygwin. 2008-11-15 14:18:36 -08:00
Wayne Davison
e4ed195bb7 Change some size_t vars to ints. 2008-11-11 18:06:11 -08:00
Wayne Davison
faf980ffb5 Make sparse_seek an OFF_T (pointed out by Pedro Valasco). 2008-11-11 18:05:27 -08:00
Wayne Davison
b3ad9649bc A "make reconfigure" doesn't stop if configure changes. 2008-11-11 15:55:14 -08:00
Matt McCutchen
d4d56eed8a Add flist_find_ignore_dirness() and change delete_in_dir() to use it.
This fixes an issue with -K noticed by eric casteleijn, avoids some
inconsistent itemizing when a file/dir is replaced by a dir/file,
and removes a now-obsolete chunk of code from make_file().
2008-11-10 07:05:21 -08:00
Wayne Davison
3ce3cabe34 Fixed the use of a dot-dir path (foo/./bar) inside of a files-from file. 2008-11-09 21:37:04 -08:00
Wayne Davison
9411292489 Fixed a bunch of "warn_unused_result" compiler warnings. 2008-11-09 18:56:21 -08:00
Wayne Davison
b4de848d75 Avoid a potential hang when --remove-*-files is active. 2008-11-09 17:59:11 -08:00
Matt McCutchen
89cb47212e The protect filter automatically added with --backup is not perishable
(see f41152d393), so remove the inaccurate
"p" from the man page.  Noticed by Jacob Balazer:

http://lists.samba.org/archive/rsync/2008-November/022022.html
2008-11-02 20:52:27 -08:00
Wayne Davison
1049378d9c Mention rsync's definition of client and server. 2008-10-25 09:43:50 -07:00
Wayne Davison
9ddc2b64da Fixed our supplied getnameinfo()'s ability to do a reverse lookup,
as reported in bug 5851.
2008-10-25 09:21:13 -07:00
Wayne Davison
b3347e2a03 Adding hashtable debugging output (--debug=hash). 2008-10-15 07:51:45 -07:00
Wayne Davison
d8e8ef323a Fixed a glitch when using -s with a remote-shell daemon. 2008-10-11 11:11:10 -07:00
Wayne Davison
ea0f037930 Don't lookup address "0.0.0.0" when we're a remote-shell daemon.
Gets rid of a DNS delay waiting for a lookup failure.
2008-10-11 11:00:51 -07:00
Wayne Davison
08b7c3ed83 Fixed send_protected_args() to send "." in place of an empty arg. 2008-10-11 10:27:16 -07:00
Wayne Davison
76181461f5 Added a fully atomic update if the user has setup a symlink
to a *-1 or *-2 directory.  A few other minor improvements.
2008-10-11 09:30:26 -07:00
Wayne Davison
2c11e80e2e Fix the error message on one of the rename operations. 2008-09-29 21:54:49 -07:00
Wayne Davison
e366e5303f Enhanced the --stats output:
- Mention how many files were created (protocol >= 29).
- Mention how many files were deleted (new in protocol 31).
- Follow the file-count, created-count, and deleted-count
  with a break-out list of each count by type.
2008-09-26 22:14:01 -07:00
Wayne Davison
0a23e33630 Properly ignore source args on a --read-batch command. 2008-09-26 20:45:49 -07:00
Wayne Davison
8ab02ccd52 More batch-mode fixes to handle redos properly (and without hanging). 2008-09-26 20:32:04 -07:00
Wayne Davison
e0c572c5c6 Moved the flist_ndx_{push,pop}() routines from io.c into util.c. 2008-09-26 19:45:08 -07:00
Wayne Davison
315c2152d0 Initialize xattr data in a couple spots in the hlink code, which avoids
a crash when the xattr pointer's memory happens to start out non-zero.
Also fixed the itemizing of an alt-dest file's xattrs when hard-linking.
2008-09-24 08:00:50 -07:00
Wayne Davison
6d301fa3de Don't send a bogus "-" option to an older server if there were
no short options specified.
2008-09-23 19:35:36 -07:00
Wayne Davison
af2dea6033 Fixed skipping of unneeded updates in a batch file when
incremental recursion is active.  Added test.
2008-09-23 19:31:14 -07:00
Wayne Davison
7fdb3bdab9 Remove bogus "non-empty" qualifier in '*' discussion. 2008-09-14 19:58:15 -07:00
Wayne Davison
794d033981 A couple instant-rsyncd improvements:
- Prompt the user for the parameters when missing.
- Allow the creation of a module without a user+password.
2008-09-11 08:50:14 -07:00
Matt McCutchen
45574a73c1 Add instant-rsyncd to support/ . 2008-09-11 08:05:06 -07:00
Wayne Davison
26e21efc5a Convey the cleaned-up module-path to the user in all cases.
Fixed a just-introduced problem with a relative module-path.
2008-09-11 07:35:40 -07:00
Wayne Davison
433c6753a8 Fix the %P logfile escape inside a chroot. 2008-09-10 16:45:06 -07:00
Wayne Davison
46b1361b41 Adding 3.0.4 release line to OLDNEWS. 2008-09-06 09:50:49 -07:00
Wayne Davison
9e7acc86c3 Adding human_readable var. 2008-09-03 16:10:45 -07:00
Wayne Davison
56c7ed9983 Changed some "rsync" commands into proper "$RSYNC" commands. 2008-09-03 12:15:36 -07:00
Wayne Davison
5dd14f0c33 Split up the ifuncs.h file into 3 .h files. 2008-09-01 19:11:36 -07:00
Wayne Davison
2a147e9fcb Don't define an array with no size. 2008-09-01 19:01:48 -07:00
Wayne Davison
7634fc8eb6 A little tidying up to follow my preferred style. 2008-09-01 17:08:26 -07:00
Matt McCutchen
daa8d92094 Several fixes for merge file handling:
- Free a mergelist's parent_dirscanned filters the last time it is
  popped or as soon as the filters are discarded due to the "n"
  modifier.  Aside from not leaking memory, this is needed to clean up
  any mergelists defined during the parent_dirscan to avoid crashing by
  trying to restore nonexistent state for them in pop_local_filters.
- Make push_local_filters save the current mergelist_cnt, and make
  pop_local_filters assert that it has the correct number of mergelists
  before restoring their state.
- Assert that mergelists get deactivated in strict LIFO order to catch
  any glitches as soon as they happen.  Free linked lists of filters in
  reverse order to make that the case.
- Add a bunch of mergelist-related debug output (--debug=filter2).
2008-09-01 17:01:19 -07:00
Wayne Davison
adc2476fa2 Output numbers in 3-digit groups by default (e.g. 1,234,567).
Also improved the human-readable output functions, including
adding the ability to output negative numbers.
2008-09-01 13:27:11 -07:00
Wayne Davison
34c3ca8f35 Verify that SUBPROTOCOL_VERSION is set correctly when making a
nightly tar file release.  Fixed the opening comments.
2008-08-31 11:55:09 -07:00
Wayne Davison
4f282b0b92 Added extra file-changing logic to ensure that the various files that
mention the protocol number have the right value, that the check-in date
for a protocol-change release is specified, and that a pre-release with
a protocol change doesn't have SUBPROTOCOL_VERSION set to 0.  Prompt for
releasing a branch if -b option was not used and we're on a branch.
2008-08-31 10:13:38 -07:00
Wayne Davison
8b3e60523a Improved the fix that ensures that the generator gets notified about an
I/O error for the incremental directory that generated the error.  The
PROTOCOL_VERSION was bumped to 31 to implement this.
2008-08-31 09:43:39 -07:00
Wayne Davison
1d891835e7 Improved rwrite() to handle a stderr exception without playing games
with the msgs2stderr value.
2008-08-24 14:07:10 -07:00
Wayne Davison
0b78944600 Some minor improvements to the flushing code to try to make it
even more solid.
2008-08-24 13:40:36 -07:00
Wayne Davison
79daa59618 Make the !flist_eof assumption explicit before the check_for_io_err
code calls wait_for_receiver().
2008-08-24 12:54:49 -07:00
Wayne Davison
72de4140d5 Added /support/savetransfer to .gitignore. 2008-08-17 09:28:50 -07:00
Wayne Davison
94a4a125bc An improved RERR_PARTIAL message. 2008-08-17 09:23:28 -07:00
Wayne Davison
e982d59146 Changed flist_for_ndx() to optionally die with an error
if the index isn't found.
2008-08-14 07:40:56 -07:00
Wayne Davison
c78e4ea905 Made an error of readlink_stat() use the right function name. 2008-08-10 07:32:54 -07:00
Wayne Davison
0b7bce2c7b Make sure that the hlink node->data allocation doesn't fail. 2008-08-08 07:48:41 -07:00
Wayne Davison
87678cefd1 Tweaked the symlink iconv buffer size and fixed a comment. 2008-08-02 13:45:50 -07:00
Wayne Davison
7c7462cd30 When using --iconv, if a server-side receiver can't convert a filename,
it now outputs the name back to the client without mangling the charset.
2008-08-02 10:26:17 -07:00
Wayne Davison
e34ad4e925 Refer to the symlink's contents as "symlink data", not "symlink name". 2008-08-02 10:20:51 -07:00
Wayne Davison
f303b749f2 Added logic to the receiving side to ensure that the --delete-during
code will not delete in a directory prior to receiving an I/O error
for that directory (or not receiving it, as the case may be).
2008-08-02 09:14:36 -07:00
Wayne Davison
91fd15b8b6 Skip new symlink conversion step if the remote rsync is not
new enough to do symlink content conversions.
2008-08-02 07:06:15 -07:00
Wayne Davison
6e5b682273 The --iconv option now converts the content of a symlink too. 2008-08-01 19:21:02 -07:00
Wayne Davison
902ee53ea4 Fixed a problem with checking for the '.' dir in the first file
list that is transferred.  This fixes a glitch where a failed
--iconv conversion on the receiving side could prevent deletions
from happening in the root-dir of the transfer.
2008-08-01 19:03:59 -07:00
Wayne Davison
c9f540f37d Changed the iconv-related message that was being output as the
lone --info=misc2 message into a --debug=iconv message so that
all iconv info will be output when requesting iconv debugging.
2008-08-01 18:15:28 -07:00
Wayne Davison
0479eb7601 Fixed a couple minor problems in util.c:
- Make sure that handle_partial_dir() never returns a truncated fname.
- Make robust_rename() return that it failed to do a cross-device
  copy if the partial-dir could not be created.
2008-08-01 18:04:24 -07:00
Wayne Davison
459abd75f5 Properly handle a failure to create a partial directory, which is
especially important for --delay-updates, particularly when
--remove-source-files was also specified.
2008-08-01 18:03:57 -07:00
Wayne Davison
342bfb5e23 Output an FERROR* for a general io_error, and an FWARNING for other
io_error flags.
2008-07-31 07:59:45 -07:00
Wayne Davison
1fe0d14263 Mention a missing sender-side hash improvment that went out in 3.0.0. 2008-07-30 08:33:05 -07:00
Wayne Davison
c8b823f9d8 Make hard-linking work when a device has an st_dev of 0. 2008-07-29 18:06:26 -07:00
Wayne Davison
45c37e737f Mention some mount options that can interfere with --link-dest. 2008-07-28 18:25:18 -07:00
Wayne Davison
41adbcec9f Added a client --munge-links option that works like the daemon
"munge symlinks" parameter.
2008-07-28 16:35:03 -07:00
Wayne Davison
582831a447 - Don't require a daemon config &directive to use an equal sign.
- Improved some daemon-config error messages.
2008-07-27 16:25:11 -07:00
Wayne Davison
312b68417f Made include_config() more efficient, and fixed a memory leak. 2008-07-27 15:14:20 -07:00
Wayne Davison
2206abf884 Added a command-line override for daemon config parameters:
--dparam=PARAMETER=VALUE (-M PARAMETER=VALUE).
2008-07-27 12:13:35 -07:00
Wayne Davison
fcd613d6c7 - Got rid of unused pstring/P_GSTRING/P_SEP/P_SEPARATOR code.
- Made pointer-adding code a little better.
2008-07-27 12:06:26 -07:00
Wayne Davison
8a3ddcfc81 Added &include and &merge config-file directives that allow the
daemon's config file incorporate the contents of other files.
2008-07-26 20:03:45 -07:00
Wayne Davison
c9604e2115 Changed the module array to use an item_list structure. 2008-07-26 19:57:02 -07:00
Wayne Davison
b583594ac7 Change the references to "service" to be either "section" or "module". 2008-07-26 19:11:32 -07:00
Wayne Davison
36828daef1 Reorder the static functions to avoid the need for forward declarations. 2008-07-26 17:47:02 -07:00
Wayne Davison
8880d8ec5e Since the loadparm.c file is changing, I'm reformatting it to use the
rsync style.
2008-07-26 17:42:09 -07:00
Wayne Davison
56fc9f70d3 Enhanced the release scripts to be able to handle a branch release. 2008-07-23 23:40:06 -07:00
Wayne Davison
aacd188034 Fixed a potential alignment issue in the IRIX ACL code when allocating
the initial struct acl object.  Also, cast mallocs to avoid warnings.
2008-07-22 08:31:17 -07:00
Wayne Davison
bb640d3221 Explicitly cast a -1 that is being assigned to a size_t. 2008-07-21 23:22:40 -07:00
Wayne Davison
0566dc54b1 Use PTR_ADD for the new instances of void-pointer arithmetic. 2008-07-21 23:12:02 -07:00
Wayne Davison
aad635f766 Explicitly cast an int64 to an int32. 2008-07-21 23:11:23 -07:00
Wayne Davison
a72f37bb67 Got rid of a variable that was set but not used. 2008-07-21 23:11:04 -07:00
Wayne Davison
93465f51bc Improved var-checker and tweaked all the issues it found. 2008-07-21 00:10:22 -07:00
Wayne Davison
26a7af26aa Renamed extern-squish -> var-checker. 2008-07-21 00:09:16 -07:00
Wayne Davison
b791d6802b Include the array-size in array externs so that IBM's code-checker
can do more checking for us.
2008-07-20 22:41:29 -07:00
Wayne Davison
741597c2df Turn off extra debugging now that the problem is fixed. 2008-07-20 22:28:19 -07:00
Wayne Davison
37077bd339 Improved the handling of --msgs2stderr a little more. 2008-07-20 22:27:23 -07:00
Wayne Davison
ced4fd8993 Fixed a bug in match_hard_links() where an empty directory would try
to allocate 0 bytes of memory (which can fail on some OSes).
2008-07-20 20:34:06 -07:00
Wayne Davison
eabc85ef5e Added a debug-helping option, --msgs2stderr, than should help all
messages to be seen in a situation where rsync is dying (as long
as stderr is a viable output method for the remote rsync).
2008-07-20 20:08:08 -07:00
Wayne Davison
5a18b34de3 Changed the chksum debug flag to deltasum. 2008-07-20 20:02:09 -07:00
Wayne Davison
56ac812359 A few more HLINK debug messages. 2008-07-20 13:54:53 -07:00
Wayne Davison
e42fc158c9 Output even more debug messages. 2008-07-20 13:06:54 -07:00
Wayne Davison
886df221c1 Added a '%C' (MD5 checksum) flag for the output/logfile formatting. 2008-07-19 22:50:28 -07:00
Wayne Davison
fb01d1fb07 Changed the POOL_QALIGN flag to POOL_NO_QALIGN, reversing the setting
(making pools aligned by default).  Added the missing code to make the
documented behavior of pool_free() with a NULL addr work.  Updated the
pool_alloc.3 manpage.
2008-07-19 09:20:56 -07:00
Wayne Davison
51ce67d599 Improved the alignment code and changed POOL_APPEND to POOL_PREPEND. 2008-07-18 20:57:52 -07:00
Wayne Davison
a02348b5df We now pass the POOL_QALIGN flag to pool_create(). Also optimized
the verbose-message check at the start of recv_file_list().
2008-07-18 20:46:58 -07:00
Wayne Davison
28a5b78c6f Improved the hard-link logging. 2008-07-18 17:35:22 -07:00
Wayne Davison
7bbd60101e Turn on flist5 debugging. 2008-07-18 17:34:59 -07:00
Wayne Davison
d239efa3ff Some minor tweaking for the info+debug option parsing. 2008-07-18 08:17:05 -07:00
Wayne Davison
269a8fb604 Make the hands.test use a higher hlink debug level. 2008-07-18 08:12:06 -07:00
Wayne Davison
b1617a0825 Add --debug=hlink to hands.test. 2008-07-18 07:19:21 -07:00
Wayne Davison
806f530bcb Don't interrupt the make for a generated file didn't really change. 2008-07-17 20:02:56 -07:00
Wayne Davison
7f0db4fd8e Use big_num() in a few more places. 2008-07-17 17:01:10 -07:00
Wayne Davison
3a8fad7805 Moving big_num() into lib/compat.c so tls.c can use it. 2008-07-17 16:59:59 -07:00
Wayne Davison
0c096e29aa Added some HLINK debugging output and enabled it for hardlink tests. 2008-07-17 07:43:11 -07:00
Wayne Davison
6d56efa6ea Changed human_num() to big_num() with an extra arg so that it can
be used in place of all %.0f output idioms.
2008-07-17 07:37:31 -07:00
Wayne Davison
97dde6b620 A couple xattr fixes for --fake-super. 2008-07-14 23:48:33 -07:00
Wayne Davison
75d9697869 A few more minor improvements in the --info/--debug code. 2008-07-14 23:36:21 -07:00
Wayne Davison
f35798a57e Added a "test_fail" function to 00-hello.test. 2008-07-14 22:47:03 -07:00
Wayne Davison
b8993a1ee9 Made the info_verbosity array 1 element larger. 2008-07-14 07:40:10 -07:00
Wayne Davison
951e826b75 Added the --info=FLAGS an --debug=FLAGS options, which allows
fine-grained output control (in addition to the coarse -v).
2008-07-13 20:51:08 -07:00
Wayne Davison
d8d1389348 Fixed the timeout/flush loop-check logic to work properly with
incremental recursion.
2008-07-13 17:29:47 -07:00
Wayne Davison
2970362338 If the user specifies --protocol=29, rsync will avoid sending an -e
option to the server (which is only useful for protocols 30 and above
anyway).  This gives the user an easy way to talk to a restricted
server that has overly restrictive option-checking.
2008-07-11 09:48:33 -07:00
Wayne Davison
7a2eca415b Added the --remote-option=OPT (-M OPT) option. 2008-07-05 08:31:16 -07:00
Wayne Davison
854411909b Got rid of some trailing whitespace. 2008-07-05 01:41:19 -07:00
Wayne Davison
bb4e4d889f The --progress output now leaves the cursor at the end of the line
(instead of the start) in order to be extra sure that an error won't
overwrite it.  We also ensure that the progress option can't be enabled
on the server side.
2008-07-05 00:31:46 -07:00
Wayne Davison
93f3fbf73e Prepare repository for more development. 2008-07-04 23:45:57 -07:00
Wayne Davison
d252e47d09 Improved the docs for various delete options. 2008-07-04 13:14:16 -07:00
128 changed files with 13922 additions and 6369 deletions

4
.gitignore vendored
View File

@@ -23,11 +23,15 @@ config.status
/getgroups
/gmon.out
/rsync
/rsync-ssl
/stunnel-rsync
/stunnel-rsyncd.conf
/shconfig
/testdir
/tests-dont-exist
/testtmp
/tls
/testrun
/trimslash
/t_unsafe
/wildtest

View File

@@ -4,6 +4,7 @@
prefix=@prefix@
datarootdir=@datarootdir@
exec_prefix=@exec_prefix@
stunnel4=@STUNNEL4@
bindir=@bindir@
mandir=@mandir@
@@ -18,40 +19,42 @@ INSTALLCMD=@INSTALL@
INSTALLMAN=@INSTALL@
srcdir=@srcdir@
MKDIR_P=@MKDIR_P@
VPATH=$(srcdir)
SHELL=/bin/sh
VERSION=@VERSION@
VERSION=@RSYNC_VERSION@
.SUFFIXES:
.SUFFIXES: .c .o
GENFILES=configure.sh config.h.in proto.h proto.h-tstamp rsync.1 rsyncd.conf.5
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h lib/pool_alloc.h
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h itypes.h inums.h \
lib/pool_alloc.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@
ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
zlib_OBJS=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \
util.o main.o checksum.o match.o syscall.o log.o backup.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
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
TLS_OBJ = tls.o syscall.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
# Programs we must have to run the test cases
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
CHECK_SYMLINKS = testsuite/chown-fake.test testsuite/devices-fake.test testsuite/xattrs-hlink.test
# Objects for CHECK_PROGS to clean
CHECK_OBJS=tls.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o
CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o
# note that the -I. is needed to handle config.h when using VPATH
.c.o:
@@ -59,16 +62,30 @@ CHECK_OBJS=tls.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
@OBJ_RESTORE@
all: Makefile rsync$(EXEEXT) @MAKE_MAN@
all: Makefile rsync$(EXEEXT) rsync-ssl stunnel-rsync stunnel-rsyncd.conf @MAKE_MAN@
install: all
-mkdir -p ${DESTDIR}${bindir}
-${MKDIR_P} ${DESTDIR}${bindir}
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
-mkdir -p ${DESTDIR}${mandir}/man1
-mkdir -p ${DESTDIR}${mandir}/man5
-${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 rsyncd.conf.5; then ${INSTALLMAN} -m 644 rsyncd.conf.5 ${DESTDIR}${mandir}/man5; fi
install-ssl-client: rsync-ssl stunnel-rsync
-${MKDIR_P} ${DESTDIR}${bindir}
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync-ssl ${DESTDIR}${bindir}
${INSTALLCMD} ${INSTALL_STRIP} -m 755 stunnel-rsync ${DESTDIR}${bindir}
install-ssl-daemon: stunnel-rsyncd.conf
-${MKDIR_P} ${DESTDIR}/etc/stunnel
${INSTALLCMD} ${INSTALL_STRIP} -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-strip:
$(MAKE) INSTALL_STRIP='-s' install
@@ -101,6 +118,9 @@ rounding.h: rounding.c rsync.h
tls$(EXEEXT): $(TLS_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
testrun$(EXEEXT): testrun.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ testrun.o
getgroups$(EXEEXT): getgroups.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getgroups.o $(LIBS)
@@ -111,7 +131,7 @@ TRIMSLASH_OBJ = trimslash.o syscall.o lib/compat.o lib/snprintf.o
trimslash$(EXEEXT): $(TRIMSLASH_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
@@ -169,6 +189,17 @@ Makefile: Makefile.in config.status configure.sh config.h.in
fi \
fi
rsync-ssl: $(srcdir)/rsync-ssl.in Makefile
sed 's;\@bindir\@;$(bindir);g' <$(srcdir)/rsync-ssl.in >rsync-ssl
@chmod +x rsync-ssl
stunnel-rsync: $(srcdir)/stunnel-rsync.in Makefile
sed 's;\@stunnel4\@;$(stunnel4);g' <$(srcdir)/stunnel-rsync.in >stunnel-rsync
@chmod +x stunnel-rsync
stunnel-rsyncd.conf: $(srcdir)/stunnel-rsyncd.conf.in Makefile
sed 's;\@bindir\@;$(bindir);g' <$(srcdir)/stunnel-rsyncd.conf.in >stunnel-rsyncd.conf
proto: proto.h-tstamp
proto.h: proto.h-tstamp
@@ -177,9 +208,11 @@ proto.h: proto.h-tstamp
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c config.h
perl $(srcdir)/mkproto.pl $(srcdir)/*.c $(srcdir)/lib/compat.c
man: rsync.1 rsyncd.conf.5
@if test -f rsync.1; then :; else cp -p $(srcdir)/rsync.1 .; fi
@if test -f rsyncd.conf.5; then :; else cp -p $(srcdir)/rsyncd.conf.5 .; fi
man: rsync.1 rsyncd.conf.5 man-copy
man-copy:
@-if test -f rsync.1; then :; else echo 'Copying srcdir rsync.1'; cp -p $(srcdir)/rsync.1 .; fi
@-if test -f rsyncd.conf.5; then :; else echo 'Copying srcdir rsyncd.conf.5'; cp -p $(srcdir)/rsyncd.conf.5 .; fi
rsync.1: rsync.yo
yodl2man -o rsync.1 $(srcdir)/rsync.yo
@@ -201,6 +234,7 @@ cleantests:
# the source directory.
distclean: clean
rm -f Makefile config.h config.status
rm -f rsync-ssl stunnel-rsync 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
@@ -239,6 +273,9 @@ check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=29
check30: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=30
wildtest.o: wildtest.c lib/wildmatch.c rsync.h config.h
wildtest$(EXEEXT): wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@ $(LIBS)

251
NEWS
View File

@@ -1,56 +1,243 @@
NEWS for rsync 3.0.9 (23 Sep 2011)
Protocol: 30 (unchanged)
Changes since 3.0.8:
NEWS for rsync 3.1.0 (28 Sep 2013)
Protocol: 31 (changed)
Changes since 3.0.9:
OUTPUT CHANGES:
- Output numbers in 3-digit groups by default (e.g. 1,234,567). See the
--human-readable option for a way to turn it off. See also the daemon's
"log format" parameter and related command-line options (including
--out-format) for a modifier that can be used to request digit-grouping
or human-readable output in log escapes. (Note that log output is
unchanged by default.)
- The --list-only option is now affected by the --human-readable setting.
It will display digit groupings by default, and unit suffixes if higher
levels of readability are requested. Also, the column width for the size
output has increased from 11 to 14 characters when human readability is
enabled. Use --no-h to get the old-style output and column size.
- The output of the --progress option has changed: the string "xfer" was
shortened to "xfr", and the string "to-check" was shortened to "to-chk",
both designed to make room for the (by default) wider display of file
size numbers without making the total line-length longer. Also, when
incremental recursion is enabled, the string "ir-chk" will be used
instead of "to-chk" up until the incremental-recursion scan is done,
letting you know that the value to check and the total value will still
be increasing as new files are found.
- Enhanced the --stats output: 1) to mention how many files were created
(protocol >= 28), 2) to mention how many files were deleted (a new line
for protocol 31, but only output when --delete is in effect), and 3) to
follow the file-count, created-count, and deleted-count with a subcount
list that shows the counts by type. The wording of the transferred count
has also changed so that it is clearer that it is only a count of regular
files.
BUG FIXES:
- Fix a crash bug in checksum scanning when --inplace is used.
- Fixed a bug in the iconv code when EINVAL or EILSEQ is returned with a
full output buffer.
- Fix a hang if a hard-linked file cannot be opened by the sender (e.g.
if it has no read permission).
- Fixed some rare bugs in --iconv processing that might cause a multibyte
character to get translated incorrectly.
- Fix preservation of a symlink's system xattrs (e.g. selinux) on Linux.
- Fixed a bogus "vanished file" error if some files were specified with
"./" prefixes and others were not.
- Fix a memory leak in the xattr code.
- Fixed a bug in --sparse where an extra gap could get inserted after a
partial write.
- Fixed a bug with --delete-excluded when a filter merge file has a rule
that specifies a receiver-only side restriction.
- Changed the way --progress overwrites its prior output in order to make
it nearly impossible for the progress to get overwritten by an error.
- Fix a bug with the modifying of unwritable directories.
- Improved the propagation of abnormal-exit error messages. This should
help the client side to receive errors from the server when it is exiting
abnormally, and should also avoid dying with an "connection unexpectedly
closed" exit when the closed connection is really expected.
- Fix --fake-super's interaction with --link-dest same-file comparisons.
- The sender now checks each file it plans to remove to ensure that it
hasn't changed from the first stat's info. This helps to avoid losing
file data when the user is not using the option in a safe manner.
- Fix the updating of the curr_dir buffer to avoid a duplicate slash.
- Fixed a data-duplication bug in the compress option that made compression
less efficient. This improves protocol 31 onward, while behaving in a
compatible (buggy) manner with older rsync protocols.
- Fix the directory permissions on an implied dot-dir when using --relative
(e.g. /outside/path/././send/path).
- When creating a temp-file, rsync is now a bit smarter about it dot-char
choices, which can fix a problem on OS X with names that start with "..".
- Fixed some too-long sleeping instances when using --bwlimit.
- Rsync now sets a cleanup flag for --inplace and --append transfers that
will flush the write buffer if the transfer aborts. This ensures that
more received data gets written out to the disk on an aborted transfer
(which is quite helpful on a slow, flaky connection).
- Fixed when symlink ownership difference-checking gets compiled into
unchanged_attrs().
- The reads that map_ptr() now does are aligned on 1K boundaries. This
helps some filesystems and/or files that don't like unaligned reads.
- Improved the socket-error reporting when multiple protocols fail.
- Fix an issue in the msleep() function if time jumps backwards.
- Fixed a case where a socket error could reference just-freed memory.
- Fix daemon-server module-name splitting bug where an arg would get split
even if --protect-args was used.
- Failing to use a password file that was specified on the command-line is
now a fatal error.
ENHANCEMENTS:
- Fix the non-root updating of directories that don't have the read and/or
execute permission.
- Added the --remote-option=OPT (-M OPT) command-line option that is useful
for things like sending a remote --log-file=FILE or --fake-super option.
- Make daemon-excluded file errors more error-like.
- Added the --info=FLAGS and --debug=FLAGS options to allow finer-grained
control over what is output. Added an extra type of --progress output
using --info=progress2.
- Fix a compilation issue on older C compilers (due to a misplaced var
declaration).
- The --msgs2stderr option can help with debugging rsync by allowing the
debug messages to get output to stderr rather than travel via the socket
protocol.
- Make configure avoid finding socketpair on cygwin.
- Added the --delete-missing-args and --ignore-missing-args options to
either delete or ignore user-specified files on the receiver that are
missing on the sender (normally the absence of user-specified files
generates an error).
- Avoid trying to reference SO_BROADCAST if the OS doesn't support it.
- Added a "T" (terabyte) category to the --human-readable size suffixes.
- Fix some issues with the post-processing of the man pages.
- Added the --usermap/--groupmap/--chown options for manipulating file
ownership during the copy.
- Fixed the user home-dir handling in the support/lsh script.
- Added the "%C" escape to the log-output handling, which will output the
MD5 checksum of any transferred file, or all files if --checksum was
specified (when protocol 30 or above is in effect).
- Some minor manpage improvements.
- Added the "reverse lookup" parameter to the rsync daemon config file to
allow reverse-DNS lookups to be disabled.
- Added a forward-DNS lookup for the daemon's hosts allow/deny config. Can
be disabled via "forward lookup" parameter (defaults to enabled).
- Added a way for more than one group to be specified in the daemon's
config file, including a way to specify that you want all of the
specified user's groups without having to name them. Also changed the
daemon to complain about an inability to set explicitly-specified uid/gid
values, even when not run by a super-user.
- The daemon now tries to send the user the error messages from the
pre-xfer exec script when it fails.
- Improved the use of alt-dest options into an existing hierarchy of files:
If a match is found in an alt-dir, it takes precedence over an existing
file. (We'll need to wait for a future version before attribute-changes
on otherwise unchanged files are safe when using an existing hierarchy.)
- Added per-user authorization options and group-authorization support to
the daemon's "auth users" parameter.
- Added a way to reference environment variables in a daemon's config file
(using %VAR% references).
- When replacing a non-dir with a symlink/hard-link/device/special-file,
the update should now be done in an atomic manner.
- Avoid re-sending xattr info for hard-linked files w/the same xattrs
(protocol 31).
- The backup code was improved to use better logic maintaining the backup
directory hierarchy. Also, when a file is being backed up, rsync tries
to hard-link it into place so that the upcoming replacement of the
destination file will be atomic (for the normal, non-inplace logic).
- Added the ability to synchronize nano-second modified times.
- Added a few more default suffixes for the "dont compress" settings.
- Added the checking of the RSYNC_PROTECT_ARGS environment variable to allow
the default for the --protect-args command-line option to be overridden.
- Added the --preallocate command-line option.
- Allow --password-file=- to read the password from stdin (filename "-").
- Rsync now comes packaged with an rsync-ssl helper script that can be
used to contact a remote rsync daemon using a piped-stunnel command.
It also includes an stunnel config file to run the server side to
support ssl daemon connections. See the packaging/lsb/rsync.spec
file for one way to package the resulting files. (Suggestions for
how to make this even easier to install & use are welcomed.)
- Improved the speed of some --inplace updates when there are lots of
identical checksum blocks that end up being unusable.
- Added the --outbuf=N|L|B option for choosing the output buffering.
- Repeating the --fuzzy option now causes the code to look for fuzzy
matches inside alt-dest directories too.
- The --chmod option now supports numeric modes, e.g. --chmod=644,D755
- Added some Solaris xattr code.
- Made an rsync daemon (the listening process) exit with a 0 status when
it was signaled to die. This helps launchd.
- Improved the RSYNC_* environment variables for the pre-xfer exec script:
when a daemon is sent multiple request args, they are now joined into a
single return value (separated by spaces) so that the RSYNC_REQUEST
environment variable is accurate for any "pre-xfer exec". The values in
RSYNC_ARG# vars are no longer truncated at the "." arg (prior to the
request dirs/files), so that all the requested values are also listed
(separately) in RSYNC_ARG# variables.
EXTRAS:
- Added an "instant-rsyncd" script to the support directory, which makes
it easy to configure a simple rsync daemon in the current directory.
- Added the "mapfrom" and "mapto" scripts to the support directory, which
makes it easier to do user/group mapping in a local transfer based on
passwd/group files from another machine.
- There's a new, improved version of the lsh script in the support dir:
it's written in perl and supports -u without resorting to using sudo
(when run as root). The old shell version is now named lsh.sh.
- There is a helper script named rsync-slash-strip in the support directory
for anyone that wants to change the way rsync handles args with trailing
slashes. (e.g. arg/ would get stripped to arg while arg/. would turn into
arg/).
INTERNAL:
- The I/O code was rewritten to be simpler and do bigger buffered reads
over the socket. The I/O between the receiver and the generator was
changed to be standard multiplexed-I/O (like that over the socket).
- The sender tries to use any dead time while the generator is looking for
files to transfer in order to do sender-side directory scanning in a more
parallel manner.
- A daemon can now inform a client about a daemon-configured timeout value
so that the client can assist in the keep-alive activity (protocol 31).
- The filter code received some refactoring to make it more extendible, to
read better, and do better sanity checking.
- Really big numbers are now output using our own big-num routine rather
than casting them to a double and using a %.0f conversion.
- The pool_alloc library has received some minor improvements in alignment
handling.
- Added init_stat_x() function to avoid duplication of acl/xattr init code.
- The included zlib was upgraded from 1.2.3 to 1.2.8.
- Rsync can now be compiled to use an unmodified zlib library instead of
the tweaked one that is included with rsync. This will eventually
become the default, at which point we'll start the countdown to removing
the included zlib. Until then, feel free to configure using:
./configure --with-included-zlib=no
DEVELOPER RELATED:
- Added more conditional debug output.
- Fixed some build issues for android and minix.

60
OLDNEWS
View File

@@ -1,3 +1,60 @@
NEWS for rsync 3.0.9 (23 Sep 2011)
Protocol: 30 (unchanged)
Changes since 3.0.8:
BUG FIXES:
- Fix a crash bug in checksum scanning when --inplace is used.
- Fix a hang if a hard-linked file cannot be opened by the sender (e.g.
if it has no read permission).
- Fix preservation of a symlink's system xattrs (e.g. selinux) on Linux.
- Fix a memory leak in the xattr code.
- Fixed a bug with --delete-excluded when a filter merge file has a rule
that specifies a receiver-only side restriction.
- Fix a bug with the modifying of unwritable directories.
- Fix --fake-super's interaction with --link-dest same-file comparisons.
- Fix the updating of the curr_dir buffer to avoid a duplicate slash.
- Fix the directory permissions on an implied dot-dir when using --relative
(e.g. /outside/path/././send/path).
- Fixed some too-long sleeping instances when using --bwlimit.
- Fixed when symlink ownership difference-checking gets compiled into
unchanged_attrs().
- Improved the socket-error reporting when multiple protocols fail.
- Fixed a case where a socket error could reference just-freed memory.
- Failing to use a password file that was specified on the command-line is
now a fatal error.
- Fix the non-root updating of directories that don't have the read and/or
execute permission.
- Make daemon-excluded file errors more error-like.
- Fix a compilation issue on older C compilers (due to a misplaced var
declaration).
- Make configure avoid finding socketpair on cygwin.
- Avoid trying to reference SO_BROADCAST if the OS doesn't support it.
- Fix some issues with the post-processing of the man pages.
- Fixed the user home-dir handling in the support/lsh script.
- Some minor manpage improvements.
NEWS for rsync 3.0.8 (26 Mar 2011)
Protocol: 30 (unchanged)
Changes since 3.0.7:
@@ -136,7 +193,6 @@ Changes since 3.0.7:
- Fixed configure's checking for iconv routines for newer OS X versions.
- Fixed the testsuite/xattrs.test script on OS X.
NEWS for rsync 3.0.7 (31 Dec 2009)
Protocol: 30 (unchanged)
@@ -3231,10 +3287,10 @@ Changes since 2.4.6:
* The existing test.sh script by Phil Hands has been merged into a
test framework that works from both "make check" and the Samba
build farm.
Partial Protocol History
RELEASE DATE VER. DATE OF COMMIT* PROTOCOL
28 Sep 2013 3.1.0 31 Aug 2008 31
23 Sep 2011 3.0.9 30
26 Mar 2011 3.0.8 30
31 Dec 2009 3.0.7 30

View File

@@ -2,7 +2,7 @@
* Routines to authenticate access to a daemon (hosts allow/deny).
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2004-2009 Wayne Davison
* Copyright (C) 2004-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,14 +20,50 @@
#include "rsync.h"
static int match_hostname(char *host, char *tok)
static int allow_forward_dns;
extern const char undetermined_hostname[];
static int match_hostname(const char **host_ptr, const char *addr, const char *tok)
{
struct hostent *hp;
unsigned int i;
const char *host = *host_ptr;
if (!host || !*host)
return 0;
return wildmatch(tok, host);
/* First check if the reverse-DNS-determined hostname matches. */
if (iwildmatch(tok, host))
return 1;
if (!allow_forward_dns)
return 0;
/* Fail quietly if tok is an address or wildcarded entry, not a simple hostname. */
if (!tok[strspn(tok, ".0123456789")] || tok[strcspn(tok, ":/*?[")])
return 0;
/* Now try forward-DNS on the token (config-specified hostname) and see if the IP matches. */
if (!(hp = gethostbyname(tok)))
return 0;
for (i = 0; hp->h_addr_list[i] != NULL; i++) {
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;
}
return 1;
}
}
return 0;
}
static int match_binary(char *b1, char *b2, char *mask, int addrlen)
static int match_binary(const char *b1, const char *b2, const char *mask, int addrlen)
{
int i;
@@ -56,7 +92,7 @@ static void make_mask(char *mask, int plen, int addrlen)
return;
}
static int match_address(char *addr, char *tok)
static int match_address(const char *addr, const char *tok)
{
char *p;
struct addrinfo hints, *resa, *rest;
@@ -70,24 +106,16 @@ static int match_address(char *addr, char *tok)
#endif
char mask[16];
char *a = NULL, *t = NULL;
unsigned int len;
if (!addr || !*addr)
return 0;
p = strchr(tok,'/');
if (p) {
if (p)
*p = '\0';
len = p - tok;
} else
len = strlen(tok);
/* Fail quietly if tok is a hostname (not an address) */
if (strspn(tok, ".0123456789") != len
#ifdef INET6
&& strchr(tok, ':') == NULL
#endif
) {
/* Fail quietly if tok is a hostname, not an address. */
if (tok[strspn(tok, ".0123456789")] && strchr(tok, ':') == NULL) {
if (p)
*p = '/';
return 0;
@@ -210,7 +238,7 @@ static int match_address(char *addr, char *tok)
return ret;
}
static int access_match(char *list, char *addr, char *host)
static int access_match(const char *list, const char *addr, const char **host_ptr)
{
char *tok;
char *list2 = strdup(list);
@@ -219,11 +247,9 @@ static int access_match(char *list, char *addr, char *host)
out_of_memory("access_match");
strlower(list2);
if (host)
strlower(host);
for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
if (match_hostname(host, tok) || match_address(addr, tok)) {
if (match_hostname(host_ptr, addr, tok) || match_address(addr, tok)) {
free(list2);
return 1;
}
@@ -233,16 +259,21 @@ static int access_match(char *list, char *addr, char *host)
return 0;
}
int allow_access(char *addr, char *host, char *allow_list, char *deny_list)
int allow_access(const char *addr, const char **host_ptr, int i)
{
const char *allow_list = lp_hosts_allow(i);
const char *deny_list = lp_hosts_deny(i);
if (allow_list && !*allow_list)
allow_list = NULL;
if (deny_list && !*deny_list)
deny_list = NULL;
allow_forward_dns = lp_forward_lookup(i);
/* If we match an allow-list item, we always allow access. */
if (allow_list) {
if (access_match(allow_list, addr, host))
if (access_match(allow_list, addr, host_ptr))
return 1;
/* For an allow-list w/o a deny-list, disallow non-matches. */
if (!deny_list)
@@ -251,7 +282,7 @@ int allow_access(char *addr, char *host, char *allow_list, char *deny_list)
/* If we match a deny-list item (and got past any allow-list
* items), we always disallow access. */
if (deny_list && access_match(deny_list, addr, host))
if (deny_list && access_match(deny_list, addr, host_ptr))
return 0;
/* Allow all other access. */

4
acls.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2006-2009 Wayne Davison
* Copyright (C) 2006-2013 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
@@ -1143,7 +1143,7 @@ int default_perms_for_dir(const char *dir)
/* Apply the permission-bit entries of the default ACL, if any. */
if (racl.user_obj != NO_ENTRY) {
perms = rsync_acl_get_perms(&racl);
if (verbose > 2)
if (DEBUG_GTE(ACL, 1))
rprintf(FINFO, "got ACL-based default perms %o for directory %s\n", perms, dir);
}

View File

@@ -2,7 +2,7 @@
* Support rsync daemon authentication.
*
* Copyright (C) 1998-2000 Andrew Tridgell
* Copyright (C) 2002-2009 Wayne Davison
* Copyright (C) 2002-2013 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,7 +19,9 @@
*/
#include "rsync.h"
#include "itypes.h"
extern int read_only;
extern char *password_file;
/***************************************************************************
@@ -76,121 +78,6 @@ static void gen_challenge(const char *addr, char *challenge)
base64_encode(digest, len, challenge, 0);
}
/* Return the secret for a user from the secret file, null terminated.
* Maximum length is len (not counting the null). */
static int get_secret(int module, const char *user, char *secret, int len)
{
const char *fname = lp_secrets_file(module);
STRUCT_STAT st;
int fd, ok = 1;
const char *p;
char ch, *s;
if (!fname || !*fname)
return 0;
if ((fd = open(fname, O_RDONLY)) < 0)
return 0;
if (do_stat(fname, &st) == -1) {
rsyserr(FLOG, errno, "stat(%s)", fname);
ok = 0;
} else if (lp_strict_modes(module)) {
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) {
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
ok = 0;
}
}
if (!ok) {
rprintf(FLOG, "continuing without secrets file\n");
close(fd);
return 0;
}
if (*user == '#') {
/* Reject attempt to match a comment. */
close(fd);
return 0;
}
/* Try to find a line that starts with the user name and a ':'. */
p = user;
while (1) {
if (read(fd, &ch, 1) != 1) {
close(fd);
return 0;
}
if (ch == '\n')
p = user;
else if (p) {
if (*p == ch)
p++;
else if (!*p && ch == ':')
break;
else
p = NULL;
}
}
/* Slurp the secret into the "secret" buffer. */
s = secret;
while (len > 0) {
if (read(fd, s, 1) != 1 || *s == '\n')
break;
if (*s == '\r')
continue;
s++;
len--;
}
*s = '\0';
close(fd);
return 1;
}
static const char *getpassf(const char *filename)
{
STRUCT_STAT st;
char buffer[512], *p;
int fd, n;
if (!filename)
return NULL;
if ((fd = open(filename,O_RDONLY)) < 0) {
rsyserr(FERROR, errno, "could not open password file %s", filename);
exit_cleanup(RERR_SYNTAX);
}
if (do_stat(filename, &st) == -1) {
rsyserr(FERROR, errno, "stat(%s)", filename);
exit_cleanup(RERR_SYNTAX);
}
if ((st.st_mode & 06) != 0) {
rprintf(FERROR, "ERROR: password file must not be other-accessible\n");
exit_cleanup(RERR_SYNTAX);
}
if (MY_UID() == 0 && st.st_uid != 0) {
rprintf(FERROR, "ERROR: password file must be owned by root when running as root\n");
exit_cleanup(RERR_SYNTAX);
}
n = read(fd, buffer, sizeof buffer - 1);
close(fd);
if (n > 0) {
buffer[n] = '\0';
if ((p = strtok(buffer, "\n\r")) != NULL)
return strdup(p);
}
rprintf(FERROR, "ERROR: failed to read a password from %s\n", filename);
exit_cleanup(RERR_SYNTAX);
}
/* Generate an MD4 hash created from the combination of the password
* and the challenge string and return it base64-encoded. */
static void generate_hash(const char *in, const char *challenge, char *out)
@@ -206,6 +93,125 @@ static void generate_hash(const char *in, const char *challenge, char *out)
base64_encode(buf, len, out, 0);
}
/* Return the secret for a user from the secret file, null terminated.
* Maximum length is len (not counting the null). */
static const char *check_secret(int module, const char *user, const char *group,
const char *challenge, const char *pass)
{
char line[1024];
char pass2[MAX_DIGEST_LEN*2];
const char *fname = lp_secrets_file(module);
STRUCT_STAT st;
int fd, ok = 1;
int user_len = strlen(user);
int group_len = group ? strlen(group) : 0;
char *err;
if (!fname || !*fname || (fd = open(fname, O_RDONLY)) < 0)
return "no secrets file";
if (do_fstat(fd, &st) == -1) {
rsyserr(FLOG, errno, "fstat(%s)", fname);
ok = 0;
} else if (lp_strict_modes(module)) {
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) {
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
ok = 0;
}
}
if (!ok) {
close(fd);
return "ignoring secrets file";
}
if (*user == '#') {
/* Reject attempt to match a comment. */
close(fd);
return "invalid username";
}
/* Try to find a line that starts with the user (or @group) name and a ':'. */
err = "secret not found";
while ((user || group) && read_line_old(fd, line, sizeof line, 1)) {
const char **ptr, *s;
int len;
if (*line == '@') {
ptr = &group;
len = group_len;
s = line+1;
} else {
ptr = &user;
len = user_len;
s = line;
}
if (!*ptr || strncmp(s, *ptr, len) != 0 || s[len] != ':')
continue;
generate_hash(s+len+1, challenge, pass2);
if (strcmp(pass, pass2) == 0) {
err = NULL;
break;
}
err = "password mismatch";
*ptr = NULL; /* Don't look for name again. */
}
close(fd);
memset(line, 0, sizeof line);
memset(pass2, 0, sizeof pass2);
return err;
}
static const char *getpassf(const char *filename)
{
STRUCT_STAT st;
char buffer[512], *p;
int n;
if (!filename)
return NULL;
if (strcmp(filename, "-") == 0) {
n = fgets(buffer, sizeof buffer, stdin) == NULL ? -1 : (int)strlen(buffer);
} else {
int fd;
if ((fd = open(filename,O_RDONLY)) < 0) {
rsyserr(FERROR, errno, "could not open password file %s", filename);
exit_cleanup(RERR_SYNTAX);
}
if (do_stat(filename, &st) == -1) {
rsyserr(FERROR, errno, "stat(%s)", filename);
exit_cleanup(RERR_SYNTAX);
}
if ((st.st_mode & 06) != 0) {
rprintf(FERROR, "ERROR: password file must not be other-accessible\n");
exit_cleanup(RERR_SYNTAX);
}
if (MY_UID() == 0 && st.st_uid != 0) {
rprintf(FERROR, "ERROR: password file must be owned by root when running as root\n");
exit_cleanup(RERR_SYNTAX);
}
n = read(fd, buffer, sizeof buffer - 1);
close(fd);
}
if (n > 0) {
buffer[n] = '\0';
if ((p = strtok(buffer, "\n\r")) != NULL)
return strdup(p);
}
rprintf(FERROR, "ERROR: failed to read a password from %s\n", filename);
exit_cleanup(RERR_SYNTAX);
}
/* Possibly negotiate authentication with the client. Use "leader" to
* start off the auth if necessary.
*
@@ -218,9 +224,12 @@ 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 secret[512];
char pass2[MAX_DIGEST_LEN*2];
char **auth_uid_groups = NULL;
int auth_uid_groups_cnt = -1;
const char *err = NULL;
int group_match = -1;
char *tok, *pass;
char opt_ch = '\0';
/* if no auth list then allow anyone in! */
if (!users || !*users)
@@ -230,7 +239,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
io_printf(f_out, "%s%s\n", leader, challenge);
if (!read_line_old(f_in, line, sizeof line)
if (!read_line_old(f_in, line, sizeof line, 0)
|| (pass = strchr(line, ' ')) == NULL) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"invalid challenge response\n",
@@ -243,36 +252,91 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
out_of_memory("auth_server");
for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
if (wildmatch(tok, line))
break;
char *opts;
/* See if the user appended :deny, :ro, or :rw. */
if ((opts = strchr(tok, ':')) != NULL) {
*opts++ = '\0';
opt_ch = isUpper(opts) ? toLower(opts) : *opts;
if (opt_ch == 'r') { /* handle ro and rw */
opt_ch = isUpper(opts+1) ? toLower(opts+1) : opts[1];
if (opt_ch == 'o')
opt_ch = 'r';
else if (opt_ch != 'w')
opt_ch = '\0';
} else if (opt_ch != 'd') /* if it's not deny, ignore it */
opt_ch = '\0';
} else
opt_ch = '\0';
if (*tok != '@') {
/* Match the username */
if (wildmatch(tok, line))
break;
} else {
#ifdef HAVE_GETGROUPLIST
int j;
/* See if authorizing user is a real user, and if so, see
* if it is in a group that matches tok+1 wildmat. */
if (auth_uid_groups_cnt < 0) {
gid_t gid_list[64];
uid_t auth_uid;
auth_uid_groups_cnt = sizeof gid_list / sizeof (gid_t);
if (!user_to_uid(line, &auth_uid, False)
|| getallgroups(auth_uid, gid_list, &auth_uid_groups_cnt) != NULL)
auth_uid_groups_cnt = 0;
else {
if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
out_of_memory("auth_server");
for (j = 0; j < auth_uid_groups_cnt; j++)
auth_uid_groups[j] = gid_to_group(gid_list[j]);
}
}
for (j = 0; j < auth_uid_groups_cnt; j++) {
if (auth_uid_groups[j] && wildmatch(tok+1, auth_uid_groups[j])) {
group_match = j;
break;
}
}
if (group_match >= 0)
break;
#else
rprintf(FLOG, "your computer doesn't support getgrouplist(), so no @group authorization is possible.\n");
#endif
}
}
free(users);
if (!tok) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"unauthorized user\n",
lp_name(module), host, addr);
if (!tok)
err = "no matching rule";
else if (opt_ch == 'd')
err = "denied by rule";
else {
char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
err = check_secret(module, line, group, challenge, pass);
}
memset(challenge, 0, sizeof challenge);
memset(pass, 0, strlen(pass));
if (auth_uid_groups) {
int j;
for (j = 0; j < auth_uid_groups_cnt; j++) {
if (auth_uid_groups[j])
free(auth_uid_groups[j]);
}
free(auth_uid_groups);
}
if (err) {
rprintf(FLOG, "auth failed on module %s from %s (%s) for %s: %s\n",
lp_name(module), host, addr, line, err);
return NULL;
}
memset(secret, 0, sizeof secret);
if (!get_secret(module, line, secret, sizeof secret - 1)) {
memset(secret, 0, sizeof secret);
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"missing secret for user \"%s\"\n",
lp_name(module), host, addr, line);
return NULL;
}
generate_hash(secret, challenge, pass2);
memset(secret, 0, sizeof secret);
if (strcmp(pass, pass2) != 0) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"password mismatch\n",
lp_name(module), host, addr);
return NULL;
}
if (opt_ch == 'r')
read_only = 1;
else if (opt_ch == 'w')
read_only = 0;
return strdup(line);
}

493
backup.c
View File

@@ -2,7 +2,7 @@
* Backup handling code.
*
* Copyright (C) 1999 Andrew Tridgell
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 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,8 @@
*/
#include "rsync.h"
#include "ifuncs.h"
extern int verbose;
extern int am_root;
extern int preserve_acls;
extern int preserve_xattrs;
@@ -34,210 +34,218 @@ extern char backup_dir_buf[MAXPATHLEN];
extern char *backup_suffix;
extern char *backup_dir;
/* make a complete pathname for backup file */
/* Returns -1 on error, 0 on missing dir, and 1 on present dir. */
static int validate_backup_dir(void)
{
STRUCT_STAT st;
if (do_lstat(backup_dir_buf, &st) < 0) {
if (errno == ENOENT)
return 0;
rsyserr(FERROR, errno, "backup lstat %s failed", backup_dir_buf);
return -1;
}
if (!S_ISDIR(st.st_mode)) {
int flags = get_del_for_flag(st.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
if (delete_item(backup_dir_buf, st.st_mode, flags) == 0)
return 0;
return -1;
}
return 1;
}
/* Create a backup path from the given fname, putting the result into
* backup_dir_buf. Any new directories (compared to the prior backup
* path) are ensured to exist as directories, replacing anything else
* that may be in the way (e.g. a symlink). */
static BOOL copy_valid_path(const char *fname)
{
const char *f;
int val;
BOOL ret = True;
stat_x sx;
char *b, *rel = backup_dir_buf + backup_dir_len, *name = rel;
for (f = fname, b = rel; *f && *f == *b; f++, b++) {
if (*b == '/')
name = b + 1;
}
if (stringjoin(rel, backup_dir_remainder, fname, backup_suffix, NULL) >= backup_dir_remainder) {
rprintf(FERROR, "backup filename too long\n");
*name = '\0';
return False;
}
for ( ; ; name = b + 1) {
if ((b = strchr(name, '/')) == NULL)
return True;
*b = '\0';
val = validate_backup_dir();
if (val == 0)
break;
if (val < 0) {
*name = '\0';
return False;
}
*b = '/';
}
init_stat_x(&sx);
for ( ; b; name = b + 1, b = strchr(name, '/')) {
*b = '\0';
while (do_mkdir(backup_dir_buf, ACCESSPERMS) < 0) {
if (errno == EEXIST) {
val = validate_backup_dir();
if (val > 0)
break;
if (val == 0)
continue;
} else
rsyserr(FERROR, errno, "backup mkdir %s failed", backup_dir_buf);
*name = '\0';
ret = False;
goto cleanup;
}
/* Try to transfer the directory settings of the actual dir
* that the files are coming from. */
if (x_stat(rel, &sx.st, NULL) < 0)
rsyserr(FERROR, errno, "backup stat %s failed", full_fname(rel));
else {
struct file_struct *file;
if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS)))
continue;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(rel, &sx);
cache_tmp_acl(file, &sx);
free_acl(&sx);
}
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
get_xattr(rel, &sx);
cache_tmp_xattr(file, &sx);
free_xattr(&sx);
}
#endif
set_file_attrs(backup_dir_buf, file, NULL, NULL, 0);
unmake_file(file);
}
*b = '/';
}
cleanup:
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
#endif
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
return ret;
}
/* Make a complete pathname for backup file and verify any new path elements. */
char *get_backup_name(const char *fname)
{
if (backup_dir) {
if (stringjoin(backup_dir_buf + backup_dir_len, backup_dir_remainder,
fname, backup_suffix, NULL) < backup_dir_remainder)
return backup_dir_buf;
} else {
if (stringjoin(backup_dir_buf, MAXPATHLEN,
fname, backup_suffix, NULL) < MAXPATHLEN)
/* copy fname into backup_dir_buf while validating the dirs. */
if (copy_valid_path(fname))
return backup_dir_buf;
/* copy_valid_path() has printed an error message. */
return NULL;
}
if (stringjoin(backup_dir_buf, MAXPATHLEN, fname, backup_suffix, NULL) < MAXPATHLEN)
return backup_dir_buf;
rprintf(FERROR, "backup filename too long\n");
return NULL;
}
/* simple backup creates a backup with a suffix in the same directory */
static int make_simple_backup(const char *fname)
/* Has same return codes as make_backup(). */
static inline int link_or_rename(const char *from, const char *to,
BOOL prefer_rename, STRUCT_STAT *stp)
{
int rename_errno;
const char *fnamebak = get_backup_name(fname);
if (!fnamebak)
return 0;
while (1) {
if (do_rename(fname, fnamebak) == 0) {
if (verbose > 1) {
rprintf(FINFO, "backed up %s to %s\n",
fname, fnamebak);
}
break;
#ifdef SUPPORT_HARD_LINKS
if (!prefer_rename) {
#ifndef CAN_HARDLINK_SYMLINK
if (S_ISLNK(stp->st_mode))
return 0; /* Use copy code. */
#endif
#ifndef CAN_HARDLINK_SPECIAL
if (IS_SPECIAL(stp->st_mode) || IS_DEVICE(stp->st_mode))
return 0; /* Use copy code. */
#endif
if (do_link(from, to) == 0) {
if (DEBUG_GTE(BACKUP, 1))
rprintf(FINFO, "make_backup: HLINK %s successful.\n", from);
return 2;
}
/* cygwin (at least version b19) reports EINVAL */
if (errno == ENOENT || errno == EINVAL)
break;
rename_errno = errno;
if (errno == EISDIR && do_rmdir(fnamebak) == 0)
continue;
if (errno == ENOTDIR && do_unlink(fnamebak) == 0)
continue;
rsyserr(FERROR, rename_errno, "rename %s to backup %s",
fname, fnamebak);
errno = rename_errno;
return 0;
/* We prefer to rename a regular file rather than copy it. */
if (!S_ISREG(stp->st_mode) || errno == EEXIST || errno == EISDIR)
return 0;
}
return 1;
}
/****************************************************************************
Create a directory given an absolute path, perms based upon another directory
path
****************************************************************************/
int make_bak_dir(const char *fullpath)
{
char fbuf[MAXPATHLEN], *rel, *end, *p;
struct file_struct *file;
int len = backup_dir_len;
stat_x sx;
while (*fullpath == '.' && fullpath[1] == '/') {
fullpath += 2;
len -= 2;
}
if (strlcpy(fbuf, fullpath, sizeof fbuf) >= sizeof fbuf)
return -1;
rel = fbuf + len;
end = p = rel + strlen(rel);
/* Try to find an existing dir, starting from the deepest dir. */
while (1) {
if (--p == fbuf)
return -1;
if (*p == '/') {
*p = '\0';
if (mkdir_defmode(fbuf) == 0)
break;
if (errno != ENOENT) {
rsyserr(FERROR, errno,
"make_bak_dir mkdir %s failed",
full_fname(fbuf));
return -1;
}
}
}
/* Make all the dirs that we didn't find on the way here. */
while (1) {
if (p >= rel) {
/* Try to transfer the directory settings of the
* actual dir that the files are coming from. */
if (x_stat(rel, &sx.st, NULL) < 0) {
rsyserr(FERROR, errno,
"make_bak_dir stat %s failed",
full_fname(rel));
} else {
#ifdef SUPPORT_ACLS
sx.acc_acl = sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
sx.xattr = NULL;
#endif
if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS)))
continue;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(rel, &sx);
cache_tmp_acl(file, &sx);
free_acl(&sx);
}
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
get_xattr(rel, &sx);
cache_tmp_xattr(file, &sx);
free_xattr(&sx);
}
#endif
set_file_attrs(fbuf, file, NULL, NULL, 0);
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
#endif
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
}
}
*p = '/';
p += strlen(p);
if (p == end)
break;
if (mkdir_defmode(fbuf) < 0) {
rsyserr(FERROR, errno, "make_bak_dir mkdir %s failed",
full_fname(fbuf));
return -1;
}
}
return 0;
}
/* robustly move a file, creating new directory structures if necessary */
static int robust_move(const char *src, char *dst)
{
if (robust_rename(src, dst, NULL, 0755) < 0) {
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
if (errno == ENOENT && make_bak_dir(dst) == 0) {
if (robust_rename(src, dst, NULL, 0755) < 0)
save_errno = errno ? errno : save_errno;
else
save_errno = 0;
}
if (save_errno) {
errno = save_errno;
return -1;
#endif
if (do_rename(from, to) == 0) {
if (stp->st_nlink > 1 && !S_ISDIR(stp->st_mode)) {
/* If someone has hard-linked the file into the backup
* dir, rename() might return success but do nothing! */
robust_unlink(from); /* Just in case... */
}
if (DEBUG_GTE(BACKUP, 1))
rprintf(FINFO, "make_backup: RENAME %s successful.\n", from);
return 1;
}
return 0;
}
/* If we have a --backup-dir, then we get here from make_backup().
* We will move the file to be deleted into a parallel directory tree. */
static int keep_backup(const char *fname)
/* Hard-link, rename, or copy an item to the backup name. Returns 2 if item
* was duplicated into backup area, 1 if item was moved, or 0 for failure.*/
int make_backup(const char *fname, BOOL prefer_rename)
{
stat_x sx;
struct file_struct *file;
char *buf;
int save_preserve_xattrs = preserve_xattrs;
int kept = 0;
int ret_code;
int save_preserve_xattrs;
char *buf = get_backup_name(fname);
int ret = 0;
/* return if no file to keep */
if (!buf)
return 0;
init_stat_x(&sx);
/* Return success if no file to keep. */
if (x_lstat(fname, &sx.st, NULL) < 0)
return 1;
#ifdef SUPPORT_ACLS
sx.acc_acl = sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
sx.xattr = NULL;
#endif
if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
return 1; /* the file could have disappeared */
if (!(buf = get_backup_name(fname))) {
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
#endif
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
return 0;
/* Try a hard-link or a rename first. Using rename is not atomic, but
* is more efficient than forcing a copy for larger files when no hard-
* linking is possible. */
if ((ret = link_or_rename(fname, buf, prefer_rename, &sx.st)) != 0)
goto success;
if (errno == EEXIST || errno == EISDIR) {
STRUCT_STAT bakst;
if (do_lstat(buf, &bakst) == 0) {
int flags = get_del_for_flag(bakst.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
if (delete_item(buf, bakst.st_mode, flags) != 0)
return 0;
}
if ((ret = link_or_rename(fname, buf, prefer_rename, &sx.st)) != 0)
goto success;
}
/* Fall back to making a copy. */
if (!(file = make_file(fname, NULL, &sx.st, 0, NO_FILTERS)))
return 1; /* the file could have disappeared */
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(fname, &sx);
@@ -256,87 +264,34 @@ static int keep_backup(const char *fname)
/* Check to see if this is a device file, or link */
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|| (preserve_specials && IS_SPECIAL(file->mode))) {
int save_errno;
do_unlink(buf);
if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0) {
save_errno = errno ? errno : EINVAL; /* 0 paranoia */
if (errno == ENOENT && make_bak_dir(buf) == 0) {
if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0)
save_errno = errno ? errno : save_errno;
else
save_errno = 0;
}
if (save_errno) {
rsyserr(FERROR, save_errno, "mknod %s failed",
full_fname(buf));
}
} else
save_errno = 0;
if (verbose > 2 && save_errno == 0) {
rprintf(FINFO, "make_backup: DEVICE %s successful.\n",
fname);
}
kept = 1;
do_unlink(fname);
}
if (!kept && S_ISDIR(file->mode)) {
/* make an empty directory */
if (do_mkdir(buf, file->mode) < 0) {
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
if (errno == ENOENT && make_bak_dir(buf) == 0) {
if (do_mkdir(buf, file->mode) < 0)
save_errno = errno ? errno : save_errno;
else
save_errno = 0;
}
if (save_errno) {
rsyserr(FINFO, save_errno, "mkdir %s failed",
full_fname(buf));
}
}
ret_code = do_rmdir(fname);
if (verbose > 2) {
rprintf(FINFO, "make_backup: RMDIR %s returns %i\n",
full_fname(fname), ret_code);
}
kept = 1;
if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0)
rsyserr(FERROR, errno, "mknod %s failed", full_fname(buf));
else if (DEBUG_GTE(BACKUP, 1))
rprintf(FINFO, "make_backup: DEVICE %s successful.\n", fname);
ret = 2;
}
#ifdef SUPPORT_LINKS
if (!kept && preserve_links && S_ISLNK(file->mode)) {
if (!ret && preserve_links && S_ISLNK(file->mode)) {
const char *sl = F_SYMLINK(file);
if (safe_symlinks && unsafe_symlink(sl, fname)) {
if (verbose) {
if (INFO_GTE(SYMSAFE, 1)) {
rprintf(FINFO, "not backing up unsafe symlink \"%s\" -> \"%s\"\n",
fname, sl);
}
kept = 1;
ret = 2;
} else {
do_unlink(buf);
if (do_symlink(sl, buf) < 0) {
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
if (errno == ENOENT && make_bak_dir(buf) == 0) {
if (do_symlink(sl, buf) < 0)
save_errno = errno ? errno : save_errno;
else
save_errno = 0;
}
if (save_errno) {
rsyserr(FERROR, save_errno, "link %s -> \"%s\"",
full_fname(buf), sl);
}
}
do_unlink(fname);
kept = 1;
if (do_symlink(sl, buf) < 0)
rsyserr(FERROR, errno, "link %s -> \"%s\"", full_fname(buf), sl);
else if (DEBUG_GTE(BACKUP, 1))
rprintf(FINFO, "make_backup: SYMLINK %s successful.\n", fname);
ret = 2;
}
}
#endif
if (!kept && !S_ISREG(file->mode)) {
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
fname);
if (!ret && !S_ISREG(file->mode)) {
rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname);
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
@@ -344,23 +299,33 @@ static int keep_backup(const char *fname)
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
return 1;
return 2;
}
/* move to keep tree if a file */
if (!kept) {
if (robust_move(fname, buf) != 0) {
/* Copy to backup tree if a file. */
if (!ret) {
if (copy_file(fname, buf, -1, file->mode) < 0) {
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
full_fname(fname), buf);
} else if (sx.st.st_nlink > 1) {
/* If someone has hard-linked the file into the backup
* dir, rename() might return success but do nothing! */
robust_unlink(fname); /* Just in case... */
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
#endif
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
return 0;
}
if (DEBUG_GTE(BACKUP, 1))
rprintf(FINFO, "make_backup: COPY %s successful.\n", fname);
ret = 2;
}
save_preserve_xattrs = preserve_xattrs;
preserve_xattrs = 0;
set_file_attrs(buf, file, NULL, fname, 0);
preserve_xattrs = save_preserve_xattrs;
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
@@ -369,18 +334,8 @@ static int keep_backup(const char *fname)
uncache_tmp_xattrs();
#endif
if (verbose > 1) {
rprintf(FINFO, "backed up %s to %s\n",
fname, buf);
}
return 1;
}
/* main backup switch routine */
int make_backup(const char *fname)
{
if (backup_dir)
return keep_backup(fname);
return make_simple_backup(fname);
success:
if (INFO_GTE(BACKUP, 1))
rprintf(FINFO, "backed up %s to %s\n", fname, buf);
return ret;
}

16
batch.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1999 Weiss
* Copyright (C) 2004 Chris Shoemaker
* Copyright (C) 2004-2009 Wayne Davison
* Copyright (C) 2004-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
*/
#include "rsync.h"
#include "zlib/zlib.h"
#include <zlib.h>
#include <time.h>
extern int eol_nulls;
@@ -43,7 +43,7 @@ extern char *batch_name;
extern char *iconv_opt;
#endif
extern struct filter_list_struct filter_list;
extern filter_rule_list filter_list;
int batch_stream_flags;
@@ -135,7 +135,7 @@ void check_batch_flags(void)
set ? "Please" : "Do not");
exit_cleanup(RERR_SYNTAX);
}
if (verbose) {
if (INFO_GTE(MISC, 1)) {
rprintf(FINFO,
"%sing the %s option to match the batchfile.\n",
set ? "Sett" : "Clear", flag_name[i]);
@@ -191,15 +191,15 @@ static int write_arg(int fd, char *arg)
static void write_filter_rules(int fd)
{
struct filter_struct *ent;
filter_rule *ent;
write_sbuf(fd, " <<'#E#'\n");
for (ent = filter_list.head; ent; ent = ent->next) {
unsigned int plen;
char *p = get_rule_prefix(ent->match_flags, "- ", 0, &plen);
char *p = get_rule_prefix(ent, "- ", 0, &plen);
write_buf(fd, p, plen);
write_sbuf(fd, ent->pattern);
if (ent->match_flags & MATCHFLG_DIRECTORY)
if (ent->rflags & FILTRULE_DIRECTORY)
write_byte(fd, '/');
write_byte(fd, eol_nulls ? 0 : '\n');
}
@@ -221,7 +221,7 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
stringjoin(filename, sizeof filename,
batch_name, ".sh", NULL);
fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IEXEC);
S_IRUSR | S_IWUSR | S_IXUSR);
if (fd < 0) {
rsyserr(FERROR, errno, "Batch file %s open error",
filename);

View File

@@ -2,7 +2,7 @@
* Simple byteorder handling.
*
* Copyright (C) 1992-1995 Andrew Tridgell
* Copyright (C) 2007-2008 Wayne Davison
* Copyright (C) 2007-2013 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

View File

@@ -1,7 +1,7 @@
/*
* Allow an arbitrary sequence of case labels.
*
* Copyright (C) 2006-2010 Wayne Davison
* Copyright (C) 2006-2013 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

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2004-2009 Wayne Davison
* Copyright (C) 2004-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

32
chmod.c
View File

@@ -2,7 +2,7 @@
* Implement the core of the --chmod option.
*
* Copyright (C) 2002 Scott Howard
* Copyright (C) 2005-2009 Wayne Davison
* Copyright (C) 2005-2013 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,6 +19,7 @@
*/
#include "rsync.h"
#include "itypes.h"
extern mode_t orig_umask;
@@ -35,10 +36,12 @@ struct chmod_mode_struct {
#define CHMOD_ADD 1
#define CHMOD_SUB 2
#define CHMOD_EQ 3
#define CHMOD_SET 4
#define STATE_ERROR 0
#define STATE_1ST_HALF 1
#define STATE_2ND_HALF 2
#define STATE_OCTAL_NUM 3
/* Parse a chmod-style argument, and break it down into one or more AND/OR
* pairs in a linked list. We return a pointer to new items on succcess
@@ -87,6 +90,10 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
curr_mode->ModeAND = CHMOD_BITS - (where * 7) - (topoct ? topbits : 0);
curr_mode->ModeOR = bits + topoct;
break;
case CHMOD_SET:
curr_mode->ModeAND = 0;
curr_mode->ModeOR = bits;
break;
}
curr_mode->flags = flags;
@@ -99,7 +106,8 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
where = what = op = topoct = topbits = flags = 0;
}
if (state != STATE_2ND_HALF) {
switch (state) {
case STATE_1ST_HALF:
switch (*modestr) {
case 'D':
if (flags & FLAG_FILES_ONLY)
@@ -138,10 +146,17 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
state = STATE_2ND_HALF;
break;
default:
state = STATE_ERROR;
if (isDigit(modestr) && *modestr < '8' && !where) {
op = CHMOD_SET;
state = STATE_OCTAL_NUM;
where = 1;
what = *modestr - '0';
} else
state = STATE_ERROR;
break;
}
} else {
break;
case STATE_2ND_HALF:
switch (*modestr) {
case 'r':
what |= 4;
@@ -168,6 +183,15 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
state = STATE_ERROR;
break;
}
break;
case STATE_OCTAL_NUM:
if (isDigit(modestr) && *modestr < '8') {
what = what*8 + *modestr - '0';
if (what > CHMOD_BITS)
state = STATE_ERROR;
} else
state = STATE_ERROR;
break;
}
modestr++;
}

108
cleanup.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 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
@@ -28,9 +28,14 @@ extern int am_receiver;
extern int io_error;
extern int keep_partial;
extern int got_xfer_error;
extern int protocol_version;
extern int output_needs_newline;
extern char *partial_dir;
extern char *logfile_name;
BOOL shutting_down = False;
BOOL flush_ok_after_signal = False;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
#endif
@@ -82,7 +87,7 @@ int cleanup_got_literal = 0;
static const char *cleanup_fname;
static const char *cleanup_new_fname;
static struct file_struct *cleanup_file;
static int cleanup_fd_r, cleanup_fd_w;
static int cleanup_fd_r = -1, cleanup_fd_w = -1;
static pid_t cleanup_pid = 0;
pid_t cleanup_child_pid = -1;
@@ -97,15 +102,15 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
static int switch_step = 0;
static int exit_code = 0, exit_line = 0;
static const char *exit_file = NULL;
static int unmodified_code = 0;
static int first_code = 0;
SIGACTION(SIGUSR1, SIG_IGN);
SIGACTION(SIGUSR2, SIG_IGN);
if (exit_code) { /* Preserve first exit info when recursing. */
code = exit_code;
file = exit_file;
line = exit_line;
if (!exit_code) { /* Preserve first error exit info when recursing. */
exit_code = code;
exit_file = file;
exit_line = line < 0 ? -line : line;
}
/* If this is the exit at the end of the run, the server side
@@ -119,11 +124,14 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
#include "case_N.h" /* case 0: */
switch_step++;
exit_code = unmodified_code = code;
exit_file = file;
exit_line = line;
first_code = code;
if (verbose > 3) {
if (output_needs_newline) {
fputc('\n', stdout);
output_needs_newline = 0;
}
if (DEBUG_GTE(EXIT, 2)) {
rprintf(FINFO,
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
who_am_i(), code, file, line);
@@ -138,8 +146,8 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
int pid = wait_process(cleanup_child_pid, &status, WNOHANG);
if (pid == cleanup_child_pid) {
status = WEXITSTATUS(status);
if (status > code)
code = exit_code = status;
if (status > exit_code)
exit_code = status;
}
}
@@ -147,25 +155,43 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
#include "case_N.h"
switch_step++;
if (cleanup_got_literal && cleanup_fname && cleanup_new_fname
&& keep_partial && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
if (cleanup_got_literal && (cleanup_fname || cleanup_fd_w != -1)) {
const char *fname = cleanup_fname;
cleanup_fname = NULL;
if (cleanup_fd_r != -1)
if (cleanup_fd_r != -1) {
close(cleanup_fd_r);
cleanup_fd_r = -1;
}
if (cleanup_fd_w != -1) {
flush_write_file(cleanup_fd_w);
close(cleanup_fd_w);
cleanup_fd_w = -1;
}
if (fname && cleanup_new_fname && keep_partial
&& handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
int tweak_modtime = 0;
if (!partial_dir) {
/* We don't want to leave a partial file with a modern time or it
* could be skipped via --update. Setting the time to something
* really old also helps it to stand out as unfinished in an ls. */
tweak_modtime = 1;
cleanup_file->modtime = 0;
}
finish_transfer(cleanup_new_fname, fname, NULL, NULL,
cleanup_file, tweak_modtime, !partial_dir);
}
finish_transfer(cleanup_new_fname, fname, NULL, NULL,
cleanup_file, 0, !partial_dir);
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
if (!code || am_server || am_receiver)
if (flush_ok_after_signal) {
flush_ok_after_signal = False;
if (code == RERR_SIGNAL)
io_flush(FULL_FLUSH);
}
if (!exit_code && !code)
io_flush(FULL_FLUSH);
/* FALLTHROUGH */
@@ -174,7 +200,7 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
if (cleanup_fname)
do_unlink(cleanup_fname);
if (code)
if (exit_code)
kill_all(SIGUSR1);
if (cleanup_pid && cleanup_pid == getpid()) {
char *pidf = lp_pid_file();
@@ -182,34 +208,55 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
unlink(lp_pid_file());
}
if (code == 0) {
if (exit_code == 0) {
if (code)
exit_code = code;
if (io_error & IOERR_DEL_LIMIT)
code = exit_code = RERR_DEL_LIMIT;
exit_code = RERR_DEL_LIMIT;
if (io_error & IOERR_VANISHED)
code = exit_code = RERR_VANISHED;
exit_code = RERR_VANISHED;
if (io_error & IOERR_GENERAL || got_xfer_error)
code = exit_code = RERR_PARTIAL;
exit_code = RERR_PARTIAL;
}
if (code || am_daemon || (logfile_name && (am_server || !verbose)))
log_exit(code, file, 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))))
log_exit(exit_code, exit_file, exit_line);
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
if (verbose > 2) {
if (DEBUG_GTE(EXIT, 1)) {
rprintf(FINFO,
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): "
"about to call exit(%d)\n",
who_am_i(), unmodified_code, file, line, code);
who_am_i(), first_code, exit_file, exit_line, exit_code);
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
if (am_server && code)
if (exit_code && exit_code != RERR_SOCKETIO && exit_code != RERR_STREAMIO && exit_code != RERR_SIGNAL1
&& exit_code != RERR_TIMEOUT && !shutting_down && (protocol_version >= 31 || am_receiver)) {
if (line > 0) {
if (DEBUG_GTE(EXIT, 3)) {
rprintf(FINFO, "[%s] sending MSG_ERROR_EXIT with exit_code %d\n",
who_am_i(), exit_code);
}
send_msg_int(MSG_ERROR_EXIT, exit_code);
}
noop_io_until_death();
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
if (am_server && exit_code)
msleep(100);
close_all();
@@ -218,12 +265,13 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
break;
}
exit(code);
exit(exit_code);
}
void cleanup_disable(void)
{
cleanup_fname = cleanup_new_fname = NULL;
cleanup_fd_r = cleanup_fd_w = -1;
cleanup_got_literal = 0;
}

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2002-2009 Wayne Davison
* Copyright (C) 2002-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,7 +41,6 @@ char *client_addr(int fd)
static int initialised;
struct sockaddr_storage ss;
socklen_t length = sizeof ss;
char *ssh_info, *p;
if (initialised)
return addr_buf;
@@ -49,11 +48,14 @@ char *client_addr(int fd)
initialised = 1;
if (am_server) { /* daemon over --rsh mode */
char *env_str;
strlcpy(addr_buf, "0.0.0.0", sizeof addr_buf);
if ((ssh_info = getenv("SSH_CONNECTION")) != NULL
|| (ssh_info = getenv("SSH_CLIENT")) != NULL
|| (ssh_info = getenv("SSH2_CLIENT")) != NULL) {
strlcpy(addr_buf, ssh_info, sizeof addr_buf);
if ((env_str = getenv("REMOTE_HOST")) != NULL
|| (env_str = getenv("SSH_CONNECTION")) != NULL
|| (env_str = getenv("SSH_CLIENT")) != NULL
|| (env_str = getenv("SSH2_CLIENT")) != NULL) {
char *p;
strlcpy(addr_buf, env_str, sizeof addr_buf);
/* Truncate the value to just the IP address. */
if ((p = strchr(addr_buf, ' ')) != NULL)
*p = '\0';

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2001-2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2002-2009 Wayne Davison
* Copyright (C) 2002-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +20,9 @@
*/
#include "rsync.h"
#include "ifuncs.h"
#include "itypes.h"
extern int quiet;
extern int verbose;
extern int dry_run;
extern int output_motd;
extern int list_only;
@@ -37,6 +36,7 @@ extern int ignore_errors;
extern int preserve_xattrs;
extern int kluge_around_eof;
extern int daemon_over_rsh;
extern int munge_symlinks;
extern int sanitize_paths;
extern int numeric_ids;
extern int filesfrom_fd;
@@ -48,23 +48,23 @@ extern int write_batch;
extern int default_af_hint;
extern int logfile_format_has_i;
extern int logfile_format_has_o_or_i;
extern mode_t orig_umask;
extern char *bind_address;
extern char *config_file;
extern char *logfile_format;
extern char *files_from;
extern char *tmpdir;
extern struct chmod_mode_struct *chmod_modes;
extern struct filter_list_struct daemon_filter_list;
extern filter_rule_list daemon_filter_list;
#ifdef ICONV_OPTION
extern char *iconv_opt;
extern iconv_t ic_send, ic_recv;
#endif
#define MAX_GID_LIST 32
char *auth_user;
int read_only = 0;
int module_id = -1;
int munge_symlinks = 0;
struct chmod_mode_struct *daemon_chmod_modes;
/* module_dirlen is the length of the module_dir string when in daemon
@@ -81,6 +81,12 @@ static int rl_nulls = 0;
static struct sigaction sigact;
#endif
static gid_t gid_list[MAX_GID_LIST];
static int gid_count = 0;
/* Used when "reverse lookup" is off. */
const char undetermined_hostname[] = "UNDETERMINED";
/**
* Run a client connected to an rsyncd. The alternative to this
* function for remote-shell connections is do_cmd().
@@ -158,7 +164,7 @@ static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int
}
/* This strips the \n. */
if (!read_line_old(f_in, buf, bufsiz)) {
if (!read_line_old(f_in, buf, bufsiz, 0)) {
if (am_client)
rprintf(FERROR, "rsync: did not see server greeting\n");
return -1;
@@ -270,7 +276,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
sargs[sargc] = NULL;
if (verbose > 1)
if (DEBUG_GTE(CMD, 1))
print_child_argv("sending daemon args:", sargs);
io_printf(f_out, "%.*s\n", modlen, modname);
@@ -280,7 +286,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
kluge_around_eof = list_only && protocol_version < 25 ? 1 : 0;
while (1) {
if (!read_line_old(f_in, line, sizeof line)) {
if (!read_line_old(f_in, line, sizeof line, 0)) {
rprintf(FERROR, "rsync: didn't get server startup line\n");
return -1;
}
@@ -334,7 +340,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
if (protocol_version < 23) {
if (protocol_version == 22 || !am_sender)
io_start_multiplex_in();
io_start_multiplex_in(f_in);
}
free(modname);
@@ -342,61 +348,83 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
return 0;
}
static char *finish_pre_exec(pid_t pid, int fd, char *request,
static char *finish_pre_exec(pid_t pid, int write_fd, int read_fd, char *request,
char **early_argv, char **argv)
{
int j = 0, status = -1;
char buf[BIGPATHBUFLEN], *bp;
int j = 0, status = -1, msglen = sizeof buf - 1;
if (!request)
request = "(NONE)";
write_buf(fd, request, strlen(request)+1);
write_buf(write_fd, request, strlen(request)+1);
if (early_argv) {
for ( ; *early_argv; early_argv++)
write_buf(fd, *early_argv, strlen(*early_argv)+1);
write_buf(write_fd, *early_argv, strlen(*early_argv)+1);
j = 1; /* Skip arg0 name in argv. */
}
for ( ; argv[j]; j++) {
write_buf(fd, argv[j], strlen(argv[j])+1);
if (argv[j][0] == '.' && argv[j][1] == '\0')
break;
}
write_byte(fd, 0);
for ( ; argv[j]; j++)
write_buf(write_fd, argv[j], strlen(argv[j])+1);
write_byte(write_fd, 0);
close(fd);
close(write_fd);
/* Read the stdout from the pre-xfer exec program. This it is only
* displayed to the user if the script also returns an error status. */
for (bp = buf; msglen > 0; msglen -= j) {
if ((j = read(read_fd, bp, msglen)) <= 0) {
if (j == 0)
break;
if (errno == EINTR)
continue;
break; /* Just ignore the read error for now... */
}
bp += j;
if (j > 1 && bp[-1] == '\n' && bp[-2] == '\r') {
bp--;
j--;
bp[-1] = '\n';
}
}
*bp = '\0';
close(read_fd);
if (wait_process(pid, &status, 0) < 0
|| !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
char *e;
if (asprintf(&e, "pre-xfer exec returned failure (%d)%s%s\n",
if (asprintf(&e, "pre-xfer exec returned failure (%d)%s%s%s\n%s",
status, status < 0 ? ": " : "",
status < 0 ? strerror(errno) : "") < 0)
out_of_memory("finish_pre_exec");
status < 0 ? strerror(errno) : "",
*buf ? ":" : "", buf) < 0)
return "out_of_memory in finish_pre_exec\n";
return e;
}
return NULL;
}
#ifdef HAVE_PUTENV
static int read_arg_from_pipe(int fd, char *buf, int limit)
{
char *bp = buf, *eob = buf + limit - 1;
while (1) {
int got = read(fd, bp, 1);
if (got != 1) {
if (got < 0 && errno == EINTR)
continue;
return -1;
}
if (*bp == '\0')
break;
if (bp < eob)
bp++;
int got = read(fd, bp, 1);
if (got != 1) {
if (got < 0 && errno == EINTR)
continue;
return -1;
}
if (*bp == '\0')
break;
if (bp < eob)
bp++;
}
*bp = '\0';
return bp - buf;
}
#endif
static int path_failure(int f_out, const char *dir, BOOL was_chdir)
{
@@ -408,20 +436,91 @@ static int path_failure(int f_out, const char *dir, BOOL was_chdir)
return -1;
}
static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
static int add_a_group(int f_out, const char *gname)
{
gid_t gid;
if (!group_to_gid(gname, &gid, True)) {
rprintf(FLOG, "Invalid gid %s\n", gname);
io_printf(f_out, "@ERROR: invalid gid %s\n", gname);
return -1;
}
if (gid_count == MAX_GID_LIST) {
rprintf(FLOG, "Too many groups specified via gid parameter.\n");
io_printf(f_out, "@ERROR: too many groups\n");
return -1;
}
gid_list[gid_count++] = gid;
return 0;
}
#ifdef HAVE_GETGROUPLIST
static int want_all_groups(int f_out, uid_t uid)
{
const char *err;
gid_count = MAX_GID_LIST;
if ((err = getallgroups(uid, gid_list, &gid_count)) != NULL) {
rsyserr(FLOG, errno, "%s", err);
io_printf(f_out, "@ERROR: %s\n", err);
return -1;
}
return 0;
}
#elif defined HAVE_INITGROUPS
static struct passwd *want_all_groups(int f_out, uid_t uid)
{
struct passwd *pw;
if ((pw = getpwuid(uid)) == NULL) {
rsyserr(FLOG, errno, "getpwuid failed");
io_printf(f_out, "@ERROR: getpwuid failed\n");
return NULL;
}
/* Start with the default group and initgroups() will add the reset. */
gid_count = 1;
gid_list[0] = pw->pw_gid;
return pw;
}
#endif
static void set_env_str(const char *var, const char *str)
{
#ifdef HAVE_PUTENV
char *mem;
if (asprintf(&mem, "%s=%s", var, str) < 0)
out_of_memory("set_env_str");
putenv(mem);
#endif
}
#ifdef HAVE_PUTENV
static void set_env_num(const char *var, long num)
{
char *mem;
if (asprintf(&mem, "%s=%ld", var, num) < 0)
out_of_memory("set_env_num");
putenv(mem);
}
#endif
static int rsync_module(int f_in, int f_out, int i, const char *addr, const char *host)
{
int argc;
char **argv, **orig_argv, **orig_early_argv, *module_chdir;
char line[BIGPATHBUFLEN];
uid_t uid = (uid_t)-2; /* canonically "nobody" */
gid_t gid = (gid_t)-2;
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
struct passwd *pw = NULL;
#endif
uid_t uid;
int set_uid;
char *p, *err_msg = NULL;
char *name = lp_name(i);
int use_chroot = lp_use_chroot(i);
int ret, pre_exec_fd = -1;
int ret, pre_exec_arg_fd = -1, pre_exec_error_fd = -1;
int save_munge_symlinks;
pid_t pre_exec_pid = 0;
char *request = NULL;
set_env_str("RSYNC_MODULE_NAME", name);
#ifdef ICONV_OPTION
iconv_opt = lp_charset(i);
if (*iconv_opt)
@@ -429,7 +528,14 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
iconv_opt = NULL;
#endif
if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
/* If reverse lookup is disabled globally but enabled for this module,
* we need to do it now before the access check. */
if (host == undetermined_hostname && lp_reverse_lookup(i))
host = client_name(f_in);
set_env_str("RSYNC_HOST_NAME", host);
set_env_str("RSYNC_HOST_ADDR", addr);
if (!allow_access(addr, &host, i)) {
rprintf(FLOG, "rsync denied on module %s from %s (%s)\n",
name, host, addr);
if (!lp_list(i))
@@ -461,18 +567,17 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
return -1;
}
read_only = lp_read_only(i); /* may also be overridden by auth_server() */
auth_user = auth_server(f_in, f_out, i, host, addr, "@RSYNCD: AUTHREQD ");
if (!auth_user) {
io_printf(f_out, "@ERROR: auth failed on module %s\n", name);
return -1;
}
set_env_str("RSYNC_USER_NAME", auth_user);
module_id = i;
if (lp_read_only(i))
read_only = 1;
if (lp_transfer_logging(i) && !logfile_format)
logfile_format = lp_log_format(i);
if (log_format_has(logfile_format, 'i'))
@@ -480,37 +585,53 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
if (logfile_format_has_i || log_format_has(logfile_format, 'o'))
logfile_format_has_o_or_i = 1;
am_root = (MY_UID() == 0);
uid = MY_UID();
am_root = (uid == 0);
if (am_root) {
p = lp_uid(i);
if (!name_to_uid(p, &uid)) {
if (!isDigit(p)) {
rprintf(FLOG, "Invalid uid %s\n", p);
io_printf(f_out, "@ERROR: invalid uid %s\n", p);
p = *lp_uid(i) ? lp_uid(i) : am_root ? NOBODY_USER : NULL;
if (p) {
if (!user_to_uid(p, &uid, True)) {
rprintf(FLOG, "Invalid uid %s\n", p);
io_printf(f_out, "@ERROR: invalid uid %s\n", p);
return -1;
}
set_uid = 1;
} else
set_uid = 0;
p = *lp_gid(i) ? strtok(lp_gid(i), ", ") : NULL;
if (p) {
/* The "*" gid must be the first item in the list. */
if (strcmp(p, "*") == 0) {
#ifdef HAVE_GETGROUPLIST
if (want_all_groups(f_out, uid) < 0)
return -1;
#elif defined HAVE_INITGROUPS
if ((pw = want_all_groups(f_out, uid)) == NULL)
return -1;
#else
rprintf(FLOG, "This rsync does not support a gid of \"*\"\n");
io_printf(f_out, "@ERROR: invalid gid setting.\n");
return -1;
#endif
} else if (add_a_group(f_out, p) < 0)
return -1;
while ((p = strtok(NULL, ", ")) != NULL) {
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
if (pw) {
rprintf(FLOG, "This rsync cannot add groups after \"*\".\n");
io_printf(f_out, "@ERROR: invalid gid setting.\n");
return -1;
}
uid = atoi(p);
}
p = lp_gid(i);
if (!name_to_gid(p, &gid)) {
if (!isDigit(p)) {
rprintf(FLOG, "Invalid gid %s\n", p);
io_printf(f_out, "@ERROR: invalid gid %s\n", p);
#endif
if (add_a_group(f_out, p) < 0)
return -1;
}
gid = atoi(p);
}
} else if (am_root) {
if (add_a_group(f_out, NOBODY_GROUP) < 0)
return -1;
}
/* TODO: If we're not root, but the configuration requests
* that we change to some uid other than the current one, then
* log a warning. */
/* TODO: Perhaps take a list of gids, and make them into the
* supplementary groups. */
module_dir = lp_path(i);
if (*module_dir == '\0') {
rprintf(FLOG, "No path specified for module %s\n", name);
@@ -540,6 +661,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
return path_failure(f_out, module_dir, False);
full_module_path = module_dir = module_chdir;
}
set_env_str("RSYNC_MODULE_PATH", full_module_path);
if (module_dirlen == 1) {
module_dirlen = 0;
@@ -548,45 +670,32 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
set_filter_dir(module_dir, module_dirlen);
p = lp_filter(i);
parse_rule(&daemon_filter_list, p, MATCHFLG_WORD_SPLIT,
parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3);
p = lp_include_from(i);
parse_filter_file(&daemon_filter_list, p, MATCHFLG_INCLUDE,
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);
parse_rule(&daemon_filter_list, p,
MATCHFLG_INCLUDE | MATCHFLG_WORD_SPLIT,
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);
parse_filter_file(&daemon_filter_list, p, 0,
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);
parse_rule(&daemon_filter_list, p, MATCHFLG_WORD_SPLIT,
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_prexfer_exec(i) || *lp_postxfer_exec(i)) {
char *modname, *modpath, *hostaddr, *hostname, *username;
int status;
if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
|| asprintf(&modpath, "RSYNC_MODULE_PATH=%s", full_module_path) < 0
|| asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0
|| asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0
|| asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0)
out_of_memory("rsync_module");
putenv(modname);
putenv(modpath);
putenv(hostaddr);
putenv(hostname);
putenv(username);
umask(orig_umask);
/* 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. */
@@ -598,18 +707,18 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
return -1;
}
if (pid) {
if (asprintf(&p, "RSYNC_PID=%ld", (long)pid) > 0)
putenv(p);
close(f_in);
if (f_out != f_in)
close(f_out);
set_env_num("RSYNC_PID", (long)pid);
if (wait_process(pid, &status, 0) < 0)
status = -1;
if (asprintf(&p, "RSYNC_RAW_STATUS=%d", status) > 0)
putenv(p);
set_env_num("RSYNC_RAW_STATUS", status);
if (WIFEXITED(status))
status = WEXITSTATUS(status);
else
status = -1;
if (asprintf(&p, "RSYNC_EXIT_STATUS=%d", status) > 0)
putenv(p);
set_env_num("RSYNC_EXIT_STATUS", status);
if (system(lp_postxfer_exec(i)) < 0)
status = -1;
_exit(status);
@@ -619,10 +728,9 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
* command, though it first waits for the parent process to
* send us the user's request via a pipe. */
if (*lp_prexfer_exec(i)) {
int fds[2];
if (asprintf(&p, "RSYNC_PID=%ld", (long)getpid()) > 0)
putenv(p);
if (pipe(fds) < 0 || (pre_exec_pid = fork()) < 0) {
int arg_fds[2], error_fds[2];
set_env_num("RSYNC_PID", (long)getpid());
if (pipe(arg_fds) < 0 || pipe(error_fds) < 0 || (pre_exec_pid = fork()) < 0) {
rsyserr(FLOG, errno, "pre-xfer exec preparation failed");
io_printf(f_out, "@ERROR: pre-xfer exec preparation failed\n");
return -1;
@@ -630,37 +738,43 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
if (pre_exec_pid == 0) {
char buf[BIGPATHBUFLEN];
int j, len;
close(fds[1]);
set_blocking(fds[0]);
len = read_arg_from_pipe(fds[0], buf, BIGPATHBUFLEN);
close(arg_fds[1]);
close(error_fds[0]);
pre_exec_arg_fd = arg_fds[0];
pre_exec_error_fd = error_fds[1];
set_blocking(pre_exec_arg_fd);
set_blocking(pre_exec_error_fd);
len = read_arg_from_pipe(pre_exec_arg_fd, buf, BIGPATHBUFLEN);
if (len <= 0)
_exit(1);
if (asprintf(&p, "RSYNC_REQUEST=%s", buf) > 0)
putenv(p);
set_env_str("RSYNC_REQUEST", buf);
for (j = 0; ; j++) {
len = read_arg_from_pipe(fds[0], buf,
len = read_arg_from_pipe(pre_exec_arg_fd, buf,
BIGPATHBUFLEN);
if (len <= 0) {
if (!len)
break;
_exit(1);
}
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) > 0)
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) >= 0)
putenv(p);
}
close(fds[0]);
close(pre_exec_arg_fd);
close(STDIN_FILENO);
close(STDOUT_FILENO);
dup2(pre_exec_error_fd, STDOUT_FILENO);
close(pre_exec_error_fd);
status = system(lp_prexfer_exec(i));
if (!WIFEXITED(status))
_exit(1);
_exit(WEXITSTATUS(status));
}
close(fds[0]);
set_blocking(fds[1]);
pre_exec_fd = fds[1];
close(arg_fds[0]);
close(error_fds[1]);
pre_exec_arg_fd = arg_fds[1];
pre_exec_error_fd = error_fds[0];
set_blocking(pre_exec_arg_fd);
set_blocking(pre_exec_error_fd);
}
umask(0);
}
#endif
@@ -694,46 +808,47 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
munge_symlinks = !use_chroot || module_dirlen;
if (munge_symlinks) {
STRUCT_STAT st;
if (do_stat(SYMLINK_PREFIX, &st) == 0 && S_ISDIR(st.st_mode)) {
rprintf(FLOG, "Symlink munging is unsupported when a %s directory exists.\n",
SYMLINK_PREFIX);
char prefix[SYMLINK_PREFIX_LEN]; /* NOT +1 ! */
strlcpy(prefix, SYMLINK_PREFIX, sizeof prefix); /* trim the trailing slash */
if (do_stat(prefix, &st) == 0 && S_ISDIR(st.st_mode)) {
rprintf(FLOG, "Symlink munging is unsafe when a %s directory exists.\n",
prefix);
io_printf(f_out, "@ERROR: daemon security issue -- contact admin\n", name);
exit_cleanup(RERR_UNSUPPORTED);
}
}
if (am_root) {
/* XXXX: You could argue that if the daemon is started
* by a non-root user and they explicitly specify a
* gid, then we should try to change to that gid --
* this could be possible if it's already in their
* supplementary groups. */
/* TODO: Perhaps we need to document that if rsyncd is
* started by somebody other than root it will inherit
* all their supplementary groups. */
if (setgid(gid)) {
rsyserr(FLOG, errno, "setgid %d failed", (int)gid);
if (gid_count) {
if (setgid(gid_list[0])) {
rsyserr(FLOG, errno, "setgid %ld failed", (long)gid_list[0]);
io_printf(f_out, "@ERROR: setgid failed\n");
return -1;
}
#ifdef HAVE_SETGROUPS
/* Get rid of any supplementary groups this process
* might have inheristed. */
if (setgroups(1, &gid)) {
/* Set the group(s) we want to be active. */
if (setgroups(gid_count, gid_list)) {
rsyserr(FLOG, errno, "setgroups failed");
io_printf(f_out, "@ERROR: setgroups failed\n");
return -1;
}
#endif
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
/* pw is set if the user wants all the user's groups. */
if (pw && initgroups(pw->pw_name, pw->pw_gid) < 0) {
rsyserr(FLOG, errno, "initgroups failed");
io_printf(f_out, "@ERROR: initgroups failed\n");
return -1;
}
#endif
}
if (set_uid) {
if (setuid(uid) < 0
#ifdef HAVE_SETEUID
|| seteuid(uid) < 0
#endif
) {
rsyserr(FLOG, errno, "setuid %d failed", (int)uid);
rsyserr(FLOG, errno, "setuid %ld failed", (long)uid);
io_printf(f_out, "@ERROR: setuid failed\n");
return -1;
}
@@ -756,7 +871,9 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
read_args(f_in, name, line, sizeof line, rl_nulls, &argv, &argc, &request);
orig_argv = argv;
verbose = 0; /* future verbosity is controlled by client options */
save_munge_symlinks = munge_symlinks;
reset_output_levels(); /* future verbosity is controlled by client options */
ret = parse_arguments(&argc, (const char ***) &argv);
if (protect_args && ret) {
orig_early_argv = orig_argv;
@@ -767,9 +884,11 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
} else
orig_early_argv = NULL;
munge_symlinks = save_munge_symlinks; /* The client mustn't control this. */
if (pre_exec_pid) {
err_msg = finish_pre_exec(pre_exec_pid, pre_exec_fd, request,
orig_early_argv, orig_argv);
err_msg = finish_pre_exec(pre_exec_pid, pre_exec_arg_fd, pre_exec_error_fd,
request, orig_early_argv, orig_argv);
}
if (orig_early_argv)
@@ -807,13 +926,12 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
#ifndef DEBUG
/* don't allow the logs to be flooded too fast */
if (verbose > lp_max_verbosity(i))
verbose = lp_max_verbosity(i);
limit_output_verbosity(lp_max_verbosity(i));
#endif
if (protocol_version < 23
&& (protocol_version == 22 || am_sender))
io_start_multiplex_out();
io_start_multiplex_out(f_out);
else if (!ret || err_msg) {
/* We have to get I/O multiplexing started so that we can
* get the error back to the client. This means getting
@@ -837,13 +955,19 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
if (files_from)
write_byte(f_out, 0);
}
io_start_multiplex_out();
io_start_multiplex_out(f_out);
}
if (!ret || err_msg) {
if (err_msg)
rwrite(FERROR, err_msg, strlen(err_msg), 0);
else
if (err_msg) {
while ((p = strchr(err_msg, '\n')) != NULL) {
int len = p - err_msg + 1;
rwrite(FERROR, err_msg, len, 0);
err_msg += len;
}
if (*err_msg)
rprintf(FERROR, "%s\n", err_msg);
} else
option_error();
msleep(400);
exit_cleanup(RERR_UNSUPPORTED);
@@ -891,7 +1015,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
with "list = False". */
static void send_listing(int fd)
{
int n = lp_numservices();
int n = lp_num_modules();
int i;
for (i = 0; i < n; i++) {
@@ -920,7 +1044,7 @@ static int load_config(int globals_only)
int start_daemon(int f_in, int f_out)
{
char line[1024];
char *addr, *host;
const char *addr, *host;
int i;
io_set_sock_fds(f_in, f_out);
@@ -933,7 +1057,7 @@ int start_daemon(int f_in, int f_out)
exit_cleanup(RERR_SYNTAX);
addr = client_addr(f_in);
host = client_name(f_in);
host = lp_reverse_lookup(-1) ? client_name(f_in) : undetermined_hostname;
rprintf(FLOG, "connect from %s (%s)\n", host, addr);
if (!am_server) {
@@ -945,7 +1069,7 @@ int start_daemon(int f_in, int f_out)
return -1;
line[0] = 0;
if (!read_line_old(f_in, line, sizeof line))
if (!read_line_old(f_in, line, sizeof line, 0))
return -1;
if (!*line || strcmp(line, "#list") == 0) {
@@ -987,14 +1111,14 @@ static void create_pid_file(void)
return;
cleanup_set_pid(pid);
if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666 & ~orig_umask)) == -1) {
if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666)) == -1) {
failure:
cleanup_set_pid(0);
fprintf(stderr, "failed to create pid file %s: %s\n", pid_file, strerror(errno));
rsyserr(FLOG, errno, "failed to create pid file %s", pid_file);
exit_cleanup(RERR_FILEIO);
}
snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
snprintf(pidbuf, sizeof pidbuf, "%d\n", (int)pid);
len = strlen(pidbuf);
if (write(fd, pidbuf, len) != len)
goto failure;
@@ -1055,6 +1179,7 @@ int daemon_main(void)
fprintf(stderr, "Failed to parse config file: %s\n", config_file);
exit_cleanup(RERR_SYNTAX);
}
set_dparams(0);
if (no_detach)
create_pid_file();

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) Andrew Tridgell 1996
* Copyright (C) Paul Mackerras 1996
* Copyright (C) 2004-2009 Wayne Davison
* Copyright (C) 2004-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,7 +27,6 @@ int inc_recurse = 0;
int compat_flags = 0;
int use_safe_inc_flist = 0;
extern int verbose;
extern int am_server;
extern int am_sender;
extern int local_server;
@@ -35,6 +34,7 @@ extern int inplace;
extern int recurse;
extern int use_qsort;
extern int allow_inc_recurse;
extern int preallocate_files;
extern int append_mode;
extern int fuzzy_basis;
extern int read_batch;
@@ -55,7 +55,7 @@ extern char *partial_dir;
extern char *dest_option;
extern char *files_from;
extern char *filesfrom_host;
extern struct filter_list_struct filter_list;
extern filter_rule_list filter_list;
extern int need_unsorted_flist;
#ifdef ICONV_OPTION
extern iconv_t ic_send, ic_recv;
@@ -163,7 +163,7 @@ void setup_protocol(int f_out,int f_in)
exit_cleanup(RERR_PROTOCOL);
}
if (verbose > 3) {
if (DEBUG_GTE(PROTO, 1)) {
rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
am_server? "Server" : "Client", remote_protocol, protocol_version);
}
@@ -190,6 +190,14 @@ void setup_protocol(int f_out,int f_in)
if (read_batch)
check_batch_flags();
#ifndef SUPPORT_PREALLOCATION
if (preallocate_files && !am_sender) {
rprintf(FERROR, "preallocation is not supported on this %s\n",
am_server ? "Server" : "Client");
exit_cleanup(RERR_SYNTAX);
}
#endif
if (protocol_version < 30) {
if (append_mode == 1)
append_mode = 2;
@@ -285,7 +293,7 @@ void setup_protocol(int f_out,int f_in)
read_batch ? "batch file" : "connection");
exit_cleanup(RERR_SYNTAX);
}
use_safe_inc_flist = !!(compat_flags & CF_SAFE_FLIST);
use_safe_inc_flist = (compat_flags & CF_SAFE_FLIST) || protocol_version >= 31;
need_messages_from_generator = 1;
#ifdef CAN_SET_SYMLINK_TIMES
} else if (!am_sender) {
@@ -297,10 +305,10 @@ void setup_protocol(int f_out,int f_in)
unsort_ndx = ++file_extra_cnt;
if (partial_dir && *partial_dir != '/' && (!am_server || local_server)) {
int flags = MATCHFLG_NO_PREFIXES | MATCHFLG_DIRECTORY;
int rflags = FILTRULE_NO_PREFIXES | FILTRULE_DIRECTORY;
if (!am_sender || protocol_version >= 30)
flags |= MATCHFLG_PERISHABLE;
parse_rule(&filter_list, partial_dir, flags, 0);
rflags |= FILTRULE_PERISHABLE;
parse_filter_str(&filter_list, partial_dir, rule_template(rflags), 0);
}

650
config.guess vendored Executable file → Normal file
View File

@@ -1,14 +1,12 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Inc.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2006-07-02'
timestamp='2013-05-16'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -17,26 +15,22 @@ timestamp='2006-07-02'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Per Bothner <per@bothner.com>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
# Originally written by Per Bothner.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit build system type.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -56,8 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -139,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_SYSTEM}" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
eval $set_cc_for_build
cat <<-EOF > $dummy.c
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
#else
LIBC=gnu
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
;;
esac
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@@ -161,6 +175,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
@@ -169,7 +184,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
| grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
@@ -179,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
os=netbsd
os=netbsd
;;
esac
# The OS release
@@ -200,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -222,7 +241,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@@ -268,7 +287,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit ;;
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@@ -294,12 +316,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
echo powerpc-ibm-os400
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
arm:riscos:*:*|arm:RISCOS:*:*)
arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -323,14 +345,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
s390x:SunOS:*:*)
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
echo i386-pc-auroraux${UNAME_RELEASE}
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
eval $set_cc_for_build
SUN_ARCH="i386"
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH="x86_64"
fi
fi
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -374,23 +415,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@@ -460,8 +501,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -474,7 +515,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit ;;
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@@ -531,7 +572,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[45])
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -574,52 +615,52 @@ EOF
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
esac ;;
esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
@@ -639,7 +680,7 @@ EOF
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
grep __LP64__ >/dev/null
grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
@@ -710,22 +751,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit ;;
exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit ;;
exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit ;;
exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit ;;
exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@@ -749,14 +790,14 @@ EOF
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -768,37 +809,51 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
case ${UNAME_MACHINE} in
pc98)
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
i*:MINGW*:*)
*:MINGW64*:*)
echo ${UNAME_MACHINE}-pc-mingw64
exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
x86:Interix*:[3456]*)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T:Interix*:[3456]*)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
*:Interix*:*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
8664:Windows_NT:*)
echo x86_64-pc-mks
exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -819,93 +874,21 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
echo cris-axis-linux-gnu
exit ;;
crisv32:Linux:*:*)
echo crisv32-axis-linux-gnu
exit ;;
frv:Linux:*:*)
echo frv-unknown-linux-gnu
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
mips:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips
#undef mipsel
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mipsel
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips
#else
CPU=
#endif
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^CPU/{
s: ::g
p
}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips64
#undef mips64el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mips64el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips64
#else
CPU=
#endif
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^CPU/{
s: ::g
p
}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
echo or32-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -916,103 +899,126 @@ EOF
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef ${UNAME_MACHINE}
#undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
or1k:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
or32:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
*) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
# Set LC_ALL=C to ensure ld outputs messages in English.
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
s/ .*//
p'`
case "$ld_supported_targets" in
elf32-i386)
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
exit ;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <features.h>
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
LIBC=gnu
# else
LIBC=gnulibc1
# endif
# else
LIBC=gnulibc1
# endif
#else
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
LIBC=gnu
#else
LIBC=gnuaout
#endif
#endif
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^LIBC/{
s: ::g
p
}'`"
test x"${LIBC}" != x && {
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit
}
test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
@@ -1020,11 +1026,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@@ -1041,7 +1047,7 @@ EOF
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
@@ -1056,7 +1062,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@@ -1084,10 +1090,13 @@ EOF
exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
exit ;;
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@@ -1122,8 +1131,18 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1136,7 +1155,7 @@ EOF
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
@@ -1156,10 +1175,10 @@ EOF
echo ns32k-sni-sysv
fi
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@@ -1185,11 +1204,11 @@ EOF
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit ;;
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@@ -1199,6 +1218,12 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
x86_64:Haiku:*:*)
echo x86_64-unknown-haiku
exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1208,6 +1233,15 @@ EOF
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
SX-7:SUPER-UX:*:*)
echo sx7-nec-superux${UNAME_RELEASE}
exit ;;
SX-8:SUPER-UX:*:*)
echo sx8-nec-superux${UNAME_RELEASE}
exit ;;
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1216,9 +1250,21 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
eval $set_cc_for_build
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1232,7 +1278,10 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@@ -1277,13 +1326,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@@ -1298,11 +1347,14 @@ EOF
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
@@ -1320,11 +1372,11 @@ main ()
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
"4"
#else
""
""
#endif
); exit (0);
); exit (0);
#endif
#endif
@@ -1458,9 +1510,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be

382
config.sub vendored Executable file → Normal file
View File

@@ -1,44 +1,40 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Inc.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2006-07-02'
timestamp='2013-04-24'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
@@ -72,8 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -120,12 +115,18 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -148,10 +149,13 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray)
-apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@@ -166,10 +170,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
;;
-hiux*)
os=-hiuxwe2
;;
@@ -214,6 +218,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;;
-lynx*)
os=-lynxos
;;
@@ -238,24 +248,34 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore \
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64vr | mips64vrel \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
@@ -266,30 +286,45 @@ case $basic_machine in
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nios | nios2 \
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| or32 \
| open8 \
| or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k)
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -299,6 +334,21 @@ case $basic_machine in
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
os=-none
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@@ -313,29 +363,37 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64vr-* | mips64vrel-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
@@ -346,31 +404,41 @@ case $basic_machine in
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nios-* | nios2-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-*)
| z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -388,7 +456,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@@ -434,6 +502,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -442,10 +514,35 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -474,8 +571,8 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
cr16c)
basic_machine=cr16c-unknown
cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
@@ -513,6 +610,10 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
@@ -628,7 +729,6 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@@ -667,6 +767,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -678,10 +786,21 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
microblaze*)
basic_machine=microblaze-xilinx
;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -710,10 +829,18 @@ case $basic_machine in
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i386-pc
os=-msys
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -778,6 +905,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -808,6 +941,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
@@ -852,9 +993,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -879,7 +1021,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos)
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc
os=-rdos
;;
@@ -909,6 +1055,10 @@ case $basic_machine in
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
@@ -920,6 +1070,9 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
@@ -941,6 +1094,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
@@ -997,17 +1153,9 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
tile*)
basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
@@ -1076,6 +1224,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
@@ -1084,6 +1235,10 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
@@ -1122,7 +1277,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
@@ -1169,9 +1324,12 @@ esac
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
@@ -1192,21 +1350,23 @@ case $os in
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1214,7 +1374,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers*)
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1253,7 +1413,7 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
-os400*)
os=-os400
;;
-wince*)
@@ -1302,7 +1462,7 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
-tpf*)
os=-tpf
;;
-triton*)
@@ -1338,12 +1498,14 @@ case $os in
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
;;
-none)
;;
*)
@@ -1366,7 +1528,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
spu-*)
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn)
@@ -1378,8 +1543,20 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
c4x-* | tic4x-*)
os=-coff
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1399,19 +1576,22 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
or1k-*)
os=-elf
;;
or32-*)
os=-coff
;;
@@ -1430,7 +1610,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
*-knuth)
*-knuth)
os=-mmixware
;;
*-wec)
@@ -1535,7 +1715,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
-aix*)
-cnk*|-aix*)
vendor=ibm
;;
-beos*)

2
configure vendored
View File

@@ -8,6 +8,8 @@ realconfigure="$dir/configure.sh"
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

View File

@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ(2.59)
RSYNC_VERSION=3.0.9
RSYNC_VERSION=3.1.0
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -39,6 +39,7 @@ AC_PROG_CC
AC_PROG_CPP
AC_PROG_EGREP
AC_PROG_INSTALL
AC_PROG_MKDIR_P
AC_PROG_CC_STDC
AC_SUBST(SHELL)
@@ -78,6 +79,15 @@ fi
AC_ARG_WITH(included-popt,
AC_HELP_STRING([--with-included-popt], [use bundled popt library, not from system]))
AC_ARG_WITH(included-zlib,
AC_HELP_STRING([--with-included-zlib], [use bundled zlib library, not from system]))
AC_ARG_WITH(protected-args,
AC_HELP_STRING([--with-protected-args], [make --protected-args option the default]))
if test x"$with_protected_args" = x"yes"; then
AC_DEFINE_UNQUOTED(RSYNC_USE_PROTECTED_ARGS, 1, [Define to 1 if --protected-args should be the default])
fi
AC_ARG_WITH(rsync-path,
AC_HELP_STRING([--with-rsync-path=PATH], [set default --rsync-path to PATH (default: rsync)]),
[ RSYNC_PATH="$with_rsync_path" ],
@@ -124,8 +134,14 @@ AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
AC_CHECK_PROG(HAVE_YODL2MAN, yodl2man, 1, 0)
if test x$HAVE_YODL2MAN = x1; then
MAKE_MAN=man
else
MAKE_MAN=man-copy
fi
# Some programs on solaris are only found in /usr/xpg4/bin (or work better than others versions).
AC_PATH_PROG(SHELL_PATH, sh, /bin/sh, [/usr/xpg4/bin$PATH_SEPARATOR$PATH])
AC_PATH_PROG(FAKEROOT_PATH, fakeroot, /usr/bin/fakeroot, [/usr/xpg4/bin$PATH_SEPARATOR$PATH])
AC_ARG_WITH(nobody-group,
AC_HELP_STRING([--with-nobody-group=GROUP],
[set the default unprivileged group (default nobody or nogroup)]),
@@ -331,7 +347,8 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.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 \
popt.h popt/popt.h netinet/in_systm.h netinet/ip.h)
popt.h popt/popt.h linux/falloc.h netinet/in_systm.h netinet/ip.h \
zlib.h)
AC_HEADER_MAJOR
AC_CACHE_CHECK([if makedev takes 3 args],rsync_cv_MAKEDEV_TAKES_3_ARGS,[
@@ -379,7 +396,18 @@ AC_TYPE_SIGNAL
AC_TYPE_UID_T
AC_CHECK_TYPES([mode_t,off_t,size_t,pid_t,id_t])
AC_TYPE_GETGROUPS
AC_CHECK_MEMBERS([struct stat.st_rdev])
AC_CHECK_MEMBERS([struct stat.st_rdev,
struct stat.st_mtimensec,
struct stat.st_mtim.tv_nsec],,,[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif])
TYPE_SOCKLEN_T
@@ -573,14 +601,50 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
seteuid strerror putenv iconv_open locale_charset nl_langinfo getxattr \
extattr_get_link sigaction sigprocmask setattrlist \
utimensat)
extattr_get_link sigaction sigprocmask setattrlist getgrouplist \
initgroups utimensat posix_fallocate attropen setvbuf)
dnl cygwin iconv.h defines iconv_open as libiconv_open
if test x"$ac_cv_func_iconv_open" != x"yes"; then
AC_CHECK_FUNC(libiconv_open, [ac_cv_func_iconv_open=yes; AC_DEFINE(HAVE_ICONV_OPEN, 1)])
fi
dnl Preallocation stuff (also fallocate, posix_fallocate function tests above):
AC_CACHE_CHECK([for useable fallocate],rsync_cv_have_fallocate,[
AC_TRY_LINK([#include <fcntl.h>
#include <sys/types.h>],
[fallocate(0, 0, 0, 0);],
rsync_cv_have_fallocate=yes,rsync_cv_have_fallocate=no)])
if test x"$rsync_cv_have_fallocate" = x"yes"; then
AC_DEFINE(HAVE_FALLOCATE, 1, [Define to 1 if you have the fallocate function and it compiles and links without error])
fi
AC_CACHE_CHECK([for SYS_fallocate],rsync_cv_have_sys_fallocate,[
AC_TRY_COMPILE([#include <sys/syscall.h>
#include <sys/types.h>],
[syscall(SYS_fallocate, 0, 0, (loff_t)0, (loff_t)0);],
rsync_cv_have_sys_fallocate=yes,rsync_cv_have_sys_fallocate=no)])
if test x"$rsync_cv_have_sys_fallocate" = x"yes"; then
AC_DEFINE(HAVE_SYS_FALLOCATE, 1, [Define to 1 if you have the SYS_fallocate syscall number])
fi
if test x"$ac_cv_func_posix_fallocate" = x"yes"; then
AC_MSG_CHECKING([whether posix_fallocate is efficient])
case $host_os in
*cygwin*)
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_EFFICIENT_POSIX_FALLOCATE, 1,
[Define if posix_fallocate is efficient (Cygwin)])
;;
*)
AC_MSG_RESULT(no)
;;
esac
fi
dnl End of preallocation stuff
AC_CHECK_FUNCS(getpgrp tcgetpgrp)
if test $ac_cv_func_getpgrp = yes; then
AC_FUNC_GETPGRP
@@ -686,6 +750,8 @@ if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
AC_DEFINE(HAVE_SOCKETPAIR, 1, [Define to 1 if you have the "socketpair" function])
fi
AC_CHECK_FUNCS(getpass, , [AC_LIBOBJ(lib/getpass)])
if test x"$with_included_popt" != x"yes"; then
AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
fi
@@ -714,6 +780,25 @@ else
AC_MSG_RESULT(no)
fi
# We default to using our zlib unless --with-included-zlib=no is given.
if test x"$with_included_zlib" != x"no"; then
with_included_zlib=yes
elif test x"$ac_cv_header_zlib_h" != x"yes"; then
with_included_zlib=yes
fi
if test x"$with_included_zlib" != x"yes"; then
AC_CHECK_LIB(z, deflateParams, , [with_included_zlib=yes])
fi
AC_MSG_CHECKING([whether to use included zlib])
if test x"$with_included_zlib" = x"yes"; then
AC_MSG_RESULT($srcdir/zlib)
BUILD_ZLIB='$(zlib_OBJS)'
CFLAGS="$CFLAGS -I$srcdir/zlib"
else
AC_MSG_RESULT(no)
fi
AC_CACHE_CHECK([for unsigned char],rsync_cv_SIGNED_CHAR_OK,[
AC_TRY_COMPILE([],[signed char *s = ""],
rsync_cv_SIGNED_CHAR_OK=yes,rsync_cv_SIGNED_CHAR_OK=no)])
@@ -867,8 +952,12 @@ AC_SUBST(OBJ_SAVE)
AC_SUBST(OBJ_RESTORE)
AC_SUBST(CC_SHOBJ_FLAG)
AC_SUBST(BUILD_POPT)
AC_SUBST(BUILD_ZLIB)
AC_SUBST(MAKE_MAN)
AC_PATH_PROG([STUNNEL], [stunnel], [stunnel], [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin])
AC_PATH_PROG([STUNNEL4], [stunnel4], [$STUNNEL], [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin])
AC_CHECK_FUNCS(_acl __acl _facl __facl)
#################################################
# check for ACL support
@@ -887,7 +976,7 @@ else
AC_DEFINE(HAVE_UNIXWARE_ACLS, 1, [true if you have UnixWare ACLs])
AC_DEFINE(SUPPORT_ACLS, 1, [Define to 1 to add support for ACLs])
;;
*solaris*|*cygwin*)
solaris*|*cygwin*)
AC_MSG_RESULT(Using solaris ACLs)
AC_DEFINE(HAVE_SOLARIS_ACLS, 1, [true if you have solaris ACLs])
AC_DEFINE(SUPPORT_ACLS, 1)
@@ -956,7 +1045,7 @@ AC_MSG_CHECKING(whether to support extended attributes)
AC_ARG_ENABLE(xattr-support,
AC_HELP_STRING([--disable-xattr-support],
[disable extended attributes]),
[], [case "$ac_cv_func_getxattr$ac_cv_func_extattr_get_link" in
[], [case "$ac_cv_func_getxattr$ac_cv_func_extattr_get_link$ac_cv_func_attropen" in
*yes*) enable_xattr_support=maybe ;;
*) enable_xattr_support=no ;;
esac])
@@ -970,6 +1059,7 @@ else
AC_MSG_RESULT(Using Linux xattrs)
AC_DEFINE(HAVE_LINUX_XATTRS, 1, [True if you have Linux xattrs])
AC_DEFINE(SUPPORT_XATTRS, 1)
AC_DEFINE(NO_SYMLINK_USER_XATTRS, 1, [True if symlinks do not support user xattrs])
;;
darwin*)
AC_MSG_RESULT(Using OS X xattrs)
@@ -984,7 +1074,9 @@ else
AC_DEFINE(SUPPORT_XATTRS, 1)
;;
solaris*)
# Better Solaris support coming in 3.1.0...
AC_MSG_RESULT(Using Solaris xattrs)
AC_DEFINE(HAVE_SOLARIS_XATTRS, 1, [True if you have Solaris xattrs])
AC_DEFINE(SUPPORT_XATTRS, 1)
AC_DEFINE(NO_SYMLINK_XATTRS, 1, [True if symlinks do not support xattrs])
;;
*)

240
delete.c Normal file
View File

@@ -0,0 +1,240 @@
/*
* Deletion routines used in rsync.
*
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include "rsync.h"
extern int am_root;
extern int make_backups;
extern int max_delete;
extern char *backup_dir;
extern char *backup_suffix;
extern int backup_suffix_len;
extern struct stats stats;
int ignore_perishable = 0;
int non_perishable_cnt = 0;
int skipped_deletes = 0;
static inline int is_backup_file(char *fn)
{
int k = strlen(fn) - backup_suffix_len;
return k > 0 && strcmp(fn+k, backup_suffix) == 0;
}
/* The directory is about to be deleted: if DEL_RECURSE is given, delete all
* its contents, otherwise just checks for content. Returns DR_SUCCESS or
* DR_NOT_EMPTY. Note that fname must point to a MAXPATHLEN buffer! (The
* buffer is used for recursion, but returned unchanged.)
*/
static enum delret delete_dir_contents(char *fname, uint16 flags)
{
struct file_list *dirlist;
enum delret ret;
unsigned remainder;
void *save_filters;
int j, dlen;
char *p;
if (DEBUG_GTE(DEL, 3)) {
rprintf(FINFO, "delete_dir_contents(%s) flags=%d\n",
fname, flags);
}
dlen = strlen(fname);
save_filters = push_local_filters(fname, dlen);
non_perishable_cnt = 0;
dirlist = get_dirlist(fname, dlen, 0);
ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS;
if (!dirlist->used)
goto done;
if (!(flags & DEL_RECURSE)) {
ret = DR_NOT_EMPTY;
goto done;
}
p = fname + dlen;
if (dlen != 1 || *fname != '/')
*p++ = '/';
remainder = MAXPATHLEN - (p - fname);
/* We do our own recursion, so make delete_item() non-recursive. */
flags = (flags & ~(DEL_RECURSE|DEL_MAKE_ROOM|DEL_NO_UID_WRITE))
| DEL_DIR_IS_EMPTY;
for (j = dirlist->used; j--; ) {
struct file_struct *fp = dirlist->files[j];
if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) {
if (DEBUG_GTE(DEL, 1)) {
rprintf(FINFO,
"mount point, %s, pins parent directory\n",
f_name(fp, NULL));
}
ret = DR_NOT_EMPTY;
continue;
}
strlcpy(p, fp->basename, remainder);
if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
do_chmod(fname, fp->mode | S_IWUSR);
/* Save stack by recursing to ourself directly. */
if (S_ISDIR(fp->mode)) {
if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS)
ret = DR_NOT_EMPTY;
}
if (delete_item(fname, fp->mode, flags) != DR_SUCCESS)
ret = DR_NOT_EMPTY;
}
fname[dlen] = '\0';
done:
flist_free(dirlist);
pop_local_filters(save_filters);
if (ret == DR_NOT_EMPTY) {
rprintf(FINFO, "cannot delete non-empty directory: %s\n",
fname);
}
return ret;
}
/* Delete a file or directory. If DEL_RECURSE is set in the flags, this will
* delete recursively.
*
* Note that fbuf must point to a MAXPATHLEN buffer if the mode indicates it's
* a directory! (The buffer is used for recursion, but returned unchanged.)
*/
enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
{
enum delret ret;
char *what;
int ok;
if (DEBUG_GTE(DEL, 2)) {
rprintf(FINFO, "delete_item(%s) mode=%o flags=%d\n",
fbuf, (int)mode, (int)flags);
}
if (flags & DEL_NO_UID_WRITE)
do_chmod(fbuf, mode | S_IWUSR);
if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
/* This only happens on the first call to delete_item() since
* delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */
ignore_perishable = 1;
/* If DEL_RECURSE is not set, this just reports emptiness. */
ret = delete_dir_contents(fbuf, flags);
ignore_perishable = 0;
if (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT)
goto check_ret;
/* OK: try to delete the directory. */
}
if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && stats.deleted_files >= max_delete) {
skipped_deletes++;
return DR_AT_LIMIT;
}
if (S_ISDIR(mode)) {
what = "rmdir";
ok = do_rmdir(fbuf) == 0;
} else {
if (make_backups > 0 && !(flags & DEL_FOR_BACKUP) && (backup_dir || !is_backup_file(fbuf))) {
what = "make_backup";
ok = make_backup(fbuf, True);
if (ok == 2) {
what = "unlink";
ok = robust_unlink(fbuf) == 0;
}
} else {
what = "unlink";
ok = robust_unlink(fbuf) == 0;
}
}
if (ok) {
if (!(flags & DEL_MAKE_ROOM)) {
log_delete(fbuf, mode);
stats.deleted_files++;
if (S_ISREG(mode)) {
/* Nothing more to count */
} else if (S_ISDIR(mode))
stats.deleted_dirs++;
#ifdef SUPPORT_LINKS
else if (S_ISLNK(mode))
stats.deleted_symlinks++;
#endif
else if (IS_DEVICE(mode))
stats.deleted_symlinks++;
else
stats.deleted_specials++;
}
ret = DR_SUCCESS;
} else {
if (S_ISDIR(mode) && errno == ENOTEMPTY) {
rprintf(FINFO, "cannot delete non-empty directory: %s\n",
fbuf);
ret = DR_NOT_EMPTY;
} else if (errno != ENOENT) {
rsyserr(FERROR, errno, "delete_file: %s(%s) failed",
what, fbuf);
ret = DR_FAILURE;
} else
ret = DR_SUCCESS;
}
check_ret:
if (ret != DR_SUCCESS && flags & DEL_MAKE_ROOM) {
const char *desc;
switch (flags & DEL_MAKE_ROOM) {
case DEL_FOR_FILE: desc = "regular file"; break;
case DEL_FOR_DIR: desc = "directory"; break;
case DEL_FOR_SYMLINK: desc = "symlink"; break;
case DEL_FOR_DEVICE: desc = "device file"; break;
case DEL_FOR_SPECIAL: desc = "special file"; break;
default: exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */
}
rprintf(FERROR_XFER, "could not make way for %s %s: %s\n",
flags & DEL_FOR_BACKUP ? "backup" : "new",
desc, fbuf);
}
return ret;
}
uint16 get_del_for_flag(uint16 mode)
{
if (S_ISREG(mode))
return DEL_FOR_FILE;
if (S_ISDIR(mode))
return DEL_FOR_DIR;
if (S_ISLNK(mode))
return DEL_FOR_SYMLINK;
if (IS_DEVICE(mode))
return DEL_FOR_DEVICE;
if (IS_SPECIAL(mode))
return DEL_FOR_SPECIAL;
exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */
}

View File

@@ -2,7 +2,7 @@
* Error codes returned by rsync.
*
* Copyright (C) 1998-2000 Andrew Tridgell
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2013 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

745
exclude.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2004-2009 Wayne Davison
* Copyright (C) 2004-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,11 +20,19 @@
*/
#include "rsync.h"
#include "inums.h"
#ifndef ENODATA
#define ENODATA EAGAIN
#endif
/* We want all reads to be aligned on 1K boundries. */
#define ALIGN_BOUNDRY 1024
/* How far past the boundary is an offset? */
#define ALIGNED_OVERSHOOT(oft) ((oft) & (ALIGN_BOUNDRY-1))
/* Round up a length to the next boundary */
#define ALIGNED_LENGTH(len) ((((len) - 1) | (ALIGN_BOUNDRY-1)) + 1)
extern int sparse_files;
static OFF_T sparse_seek = 0;
@@ -76,11 +84,14 @@ static int write_sparse(int f, char *buf, int len)
while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) {
if (ret < 0 && errno == EINTR)
continue;
sparse_seek = 0;
return ret;
}
if (ret != (int)(len - (l1+l2)))
if (ret != (int)(len - (l1+l2))) {
sparse_seek = 0;
return l1+ret;
}
return len;
}
@@ -158,8 +169,7 @@ int write_file(int f, char *buf, int len)
* It gives sliding window access to a file. mmap() is not used because of
* the possibility of another program (such as a mailer) truncating the
* file thus giving us a SIGBUS. */
struct map_struct *map_file(int fd, OFF_T len, int32 read_size,
int32 blk_size)
struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
{
struct map_struct *map;
@@ -171,7 +181,7 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size,
map->fd = fd;
map->file_size = len;
map->def_window_size = read_size;
map->def_window_size = ALIGNED_LENGTH(read_size);
return map;
}
@@ -180,9 +190,8 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size,
/* slide the read window in the file */
char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
{
int32 nread;
OFF_T window_start, read_start;
int32 window_size, read_size, read_offset;
int32 window_size, read_size, read_offset, align_fudge;
if (len == 0)
return NULL;
@@ -197,12 +206,13 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
return map->p + (offset - map->p_offset);
/* nope, we are going to have to do a read. Work out our desired window */
window_start = offset;
align_fudge = (int32)ALIGNED_OVERSHOOT(offset);
window_start = offset - align_fudge;
window_size = map->def_window_size;
if (window_start + window_size > map->file_size)
window_size = (int32)(map->file_size - window_start);
if (len > window_size)
window_size = len;
if (window_size < len + align_fudge)
window_size = ALIGNED_LENGTH(len + align_fudge);
/* make sure we have allocated enough memory for the window */
if (window_size > map->p_size) {
@@ -212,11 +222,9 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
map->p_size = window_size;
}
/* Now try to avoid re-reading any bytes by reusing any bytes
* from the previous buffer. */
if (window_start >= map->p_offset &&
window_start < map->p_offset + map->p_len &&
window_start + window_size >= map->p_offset + map->p_len) {
/* Now try to avoid re-reading any bytes by reusing any bytes from the previous buffer. */
if (window_start >= map->p_offset && window_start < map->p_offset + map->p_len
&& window_start + window_size >= map->p_offset + map->p_len) {
read_start = map->p_offset + map->p_len;
read_offset = (int32)(read_start - window_start);
read_size = window_size - read_offset;
@@ -236,8 +244,8 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
if (map->p_fd_offset != read_start) {
OFF_T ret = do_lseek(map->fd, read_start, SEEK_SET);
if (ret != read_start) {
rsyserr(FERROR, errno, "lseek returned %.0f, not %.0f",
(double)ret, (double)read_start);
rsyserr(FERROR, errno, "lseek returned %s, not %s",
big_num(ret), big_num(read_start));
exit_cleanup(RERR_FILEIO);
}
map->p_fd_offset = read_start;
@@ -246,7 +254,7 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
map->p_len = window_size;
while (read_size > 0) {
nread = read(map->fd, map->p + read_offset, read_size);
int32 nread = read(map->fd, map->p + read_offset, read_size);
if (nread <= 0) {
if (!map->status)
map->status = nread ? errno : ENODATA;
@@ -260,7 +268,7 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
read_size -= nread;
}
return map->p;
return map->p + align_fudge;
}

351
flist.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2002-2009 Wayne Davison
* Copyright (C) 2002-2013 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
@@ -23,16 +23,15 @@
#include "rsync.h"
#include "ifuncs.h"
#include "rounding.h"
#include "inums.h"
#include "io.h"
extern int verbose;
extern int am_root;
extern int am_server;
extern int am_daemon;
extern int am_sender;
extern int am_generator;
extern int inc_recurse;
extern int do_progress;
extern int always_checksum;
extern int module_id;
extern int ignore_errors;
@@ -52,6 +51,7 @@ extern int preserve_hard_links;
extern int preserve_devices;
extern int preserve_specials;
extern int delete_during;
extern int missing_args;
extern int eol_nulls;
extern int relative_paths;
extern int implied_dirs;
@@ -66,17 +66,20 @@ extern int munge_symlinks;
extern int use_safe_inc_flist;
extern int need_unsorted_flist;
extern int sender_symlink_iconv;
extern int output_needs_newline;
extern int sender_keeps_checksum;
extern int unsort_ndx;
extern uid_t our_uid;
extern struct stats stats;
extern char *filesfrom_host;
extern char *usermap, *groupmap;
extern char curr_dir[MAXPATHLEN];
extern struct chmod_mode_struct *chmod_modes;
extern struct filter_list_struct filter_list;
extern struct filter_list_struct daemon_filter_list;
extern filter_rule_list filter_list;
extern filter_rule_list daemon_filter_list;
#ifdef ICONV_OPTION
extern int filesfrom_convert;
@@ -93,11 +96,13 @@ struct file_list *cur_flist, *first_flist, *dir_flist;
int send_dir_ndx = -1, send_dir_depth = -1;
int flist_cnt = 0; /* how many (non-tmp) file list objects exist */
int file_total = 0; /* total of all active items over all file-lists */
int file_old_total = 0; /* total of active items that will soon be gone */
int flist_eof = 0; /* all the file-lists are now known */
#define NORMAL_NAME 0
#define SLASH_ENDING_NAME 1
#define DOTDIR_NAME 2
#define MISSING_NAME 3
/* Starting from protocol version 26, we always use 64-bit ino_t and dev_t
* internally, even if this platform does not allow files to have 64-bit inums.
@@ -122,14 +127,13 @@ static char tmp_sum[MAX_DIGEST_LEN];
static char empty_sum[MAX_DIGEST_LEN];
static int flist_count_offset; /* for --delete --progress */
static int dir_count = 0;
static void flist_sort_and_clean(struct file_list *flist, int strip_root);
static void output_flist(struct file_list *flist);
void init_flist(void)
{
if (verbose > 4) {
if (DEBUG_GTE(FLIST, 4)) {
rprintf(FINFO, "FILE_STRUCT_LEN=%d, EXTRA_LEN=%d\n",
(int)FILE_STRUCT_LEN, (int)EXTRA_LEN);
}
@@ -140,14 +144,13 @@ void init_flist(void)
static int show_filelist_p(void)
{
return verbose && xfer_dirs && !am_server && !inc_recurse;
return INFO_GTE(FLIST, 1) && xfer_dirs && !am_server && !inc_recurse;
}
static void start_filelist_progress(char *kind)
{
rprintf(FCLIENT, "%s ... ", kind);
if (verbose > 1 || do_progress)
rprintf(FCLIENT, "\n");
output_needs_newline = 1;
rflush(FINFO);
}
@@ -158,18 +161,20 @@ static void emit_filelist_progress(int count)
static void maybe_emit_filelist_progress(int count)
{
if (do_progress && show_filelist_p() && (count % 100) == 0)
if (INFO_GTE(FLIST, 2) && show_filelist_p() && (count % 100) == 0)
emit_filelist_progress(count);
}
static void finish_filelist_progress(const struct file_list *flist)
{
if (do_progress) {
if (INFO_GTE(FLIST, 2)) {
/* This overwrites the progress line */
rprintf(FINFO, "%d file%sto consider\n",
flist->used, flist->used == 1 ? " " : "s ");
} else
} else {
output_needs_newline = 0;
rprintf(FINFO, "done\n");
}
}
void show_flist_stats(void)
@@ -191,12 +196,12 @@ static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf)
if (link_stat(path, stp, copy_dirlinks) < 0)
return -1;
if (S_ISLNK(stp->st_mode)) {
int llen = readlink(path, linkbuf, MAXPATHLEN - 1);
int llen = do_readlink(path, linkbuf, MAXPATHLEN - 1);
if (llen < 0)
return -1;
linkbuf[llen] = '\0';
if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) {
if (verbose > 1) {
if (INFO_GTE(SYMSAFE, 1)) {
rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
path, linkbuf);
}
@@ -316,10 +321,10 @@ static void flist_expand(struct file_list *flist, int extra)
new_ptr = realloc_array(flist->files, struct file_struct *,
flist->malloced);
if (verbose >= 2 && flist->malloced != FLIST_START) {
rprintf(FCLIENT, "[%s] expand file_list pointer array to %.0f bytes, did%s move\n",
if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
who_am_i(),
(double)sizeof flist->files[0] * flist->malloced,
big_num(sizeof flist->files[0] * flist->malloced),
(new_ptr == flist->files) ? " not" : "");
}
@@ -403,21 +408,35 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
static gid_t gid;
static const char *user_name, *group_name;
static char lastname[MAXPATHLEN];
#ifdef SUPPORT_HARD_LINKS
int first_hlink_ndx = -1;
#endif
int l1, l2;
int xflags;
/* Initialize starting value of xflags. */
if (protocol_version >= 30 && S_ISDIR(file->mode)) {
dir_count++;
if (file->flags & FLAG_CONTENT_DIR)
xflags = file->flags & FLAG_TOP_DIR;
else if (file->flags & FLAG_IMPLIED_DIR)
xflags = XMIT_TOP_DIR | XMIT_NO_CONTENT_DIR;
else
xflags = XMIT_NO_CONTENT_DIR;
} else
xflags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
/* Initialize starting value of xflags and adjust counts. */
if (S_ISREG(file->mode))
xflags = 0;
else if (S_ISDIR(file->mode)) {
stats.num_dirs++;
if (protocol_version >= 30) {
if (file->flags & FLAG_CONTENT_DIR)
xflags = file->flags & FLAG_TOP_DIR;
else if (file->flags & FLAG_IMPLIED_DIR)
xflags = XMIT_TOP_DIR | XMIT_NO_CONTENT_DIR;
else
xflags = XMIT_NO_CONTENT_DIR;
} else
xflags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
} else {
if (S_ISLNK(file->mode))
stats.num_symlinks++;
else if (IS_DEVICE(file->mode))
stats.num_devices++;
else if (IS_SPECIAL(file->mode))
stats.num_specials++;
xflags = 0;
}
if (file->mode == mode)
xflags |= XMIT_SAME_MODE;
@@ -439,7 +458,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
if (protocol_version < 30 && (uint32)minor(rdev) <= 0xFFu)
xflags |= XMIT_RDEV_MINOR_8_pre30;
}
} else if (preserve_specials && IS_SPECIAL(mode)) {
} else if (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31) {
/* Special files don't need an rdev number, so just make
* the historical transmission of the value efficient. */
if (protocol_version < 28)
@@ -476,6 +495,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
xflags |= XMIT_SAME_TIME;
else
modtime = file->modtime;
if (NSEC_BUMP(file) && protocol_version >= 31)
xflags |= XMIT_MOD_NSEC;
#ifdef SUPPORT_HARD_LINKS
if (tmp_dev != -1) {
@@ -486,6 +507,17 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
np->data = (void*)(long)(first_ndx + ndx + 1);
xflags |= XMIT_HLINK_FIRST;
}
if (DEBUG_GTE(HLINK, 1)) {
if (first_hlink_ndx >= 0) {
rprintf(FINFO, "[%s] #%d hard-links #%d (%sabbrev)\n",
who_am_i(), first_ndx + ndx, first_hlink_ndx,
first_hlink_ndx >= first_ndx ? "" : "un");
} else if (DEBUG_GTE(HLINK, 3)) {
rprintf(FINFO, "[%s] dev:inode for #%d is %s:%s\n",
who_am_i(), first_ndx + ndx,
big_num(tmp_dev), big_num(tmp_ino));
}
}
} else {
if (tmp_dev == dev) {
if (protocol_version >= 28)
@@ -532,11 +564,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
write_byte(f, l2);
write_buf(f, fname + l1, l2);
#ifdef SUPPORT_HARD_LINKS
if (first_hlink_ndx >= 0) {
write_varint(f, first_hlink_ndx);
if (first_hlink_ndx >= first_ndx)
goto the_end;
}
#endif
write_varlong30(f, F_LENGTH(file), 3);
if (!(xflags & XMIT_SAME_TIME)) {
@@ -545,6 +579,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
else
write_int(f, modtime);
}
if (xflags & XMIT_MOD_NSEC)
write_varint(f, F_MOD_NSEC(file));
if (!(xflags & XMIT_SAME_MODE))
write_int(f, to_wire_mode(mode));
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
@@ -572,7 +608,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
}
}
if ((preserve_devices && IS_DEVICE(mode))
|| (preserve_specials && IS_SPECIAL(mode))) {
|| (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31)) {
if (protocol_version < 28) {
if (!(xflags & XMIT_SAME_RDEV_pre28))
write_int(f, (int)rdev);
@@ -623,7 +659,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
write_buf(f, sum, checksum_len);
}
#ifdef SUPPORT_HARD_LINKS
the_end:
#endif
strlcpy(lastname, fname, MAXPATHLEN);
if (S_ISREG(mode) || S_ISLNK(mode))
@@ -652,6 +690,7 @@ 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;
uint32 modtime_nsec;
const char *basename;
struct file_struct *file;
alloc_pool_t *pool;
@@ -684,9 +723,9 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
xbuf outbuf, inbuf;
INIT_CONST_XBUF(outbuf, thisname);
INIT_XBUF(inbuf, lastname, basename_len, -1);
INIT_XBUF(inbuf, lastname, basename_len, (size_t)-1);
if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {
if (iconvbufs(ic_recv, &inbuf, &outbuf, ICB_INIT) < 0) {
io_error |= IOERR_GENERAL;
rprintf(FERROR_UTF8,
"[%s] cannot convert filename: %s (%s)\n",
@@ -726,10 +765,16 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
first_hlink_ndx, flist->ndx_start + flist->used);
exit_cleanup(RERR_PROTOCOL);
}
if (DEBUG_GTE(HLINK, 1)) {
rprintf(FINFO, "[%s] #%d hard-links #%d (%sabbrev)\n",
who_am_i(), flist->used+flist->ndx_start, first_hlink_ndx,
first_hlink_ndx >= flist->ndx_start ? "" : "un");
}
if (first_hlink_ndx >= flist->ndx_start) {
struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];
file_length = F_LENGTH(first);
modtime = first->modtime;
modtime_nsec = F_MOD_NSEC(first);
mode = first->mode;
if (preserve_uid)
uid = F_OWNER(first);
@@ -763,10 +808,14 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
} else
modtime = read_int(f);
}
if (xflags & XMIT_MOD_NSEC)
modtime_nsec = read_varint(f);
else
modtime_nsec = 0;
if (!(xflags & XMIT_SAME_MODE))
mode = from_wire_mode(read_int(f));
if (chmod_modes && !S_ISLNK(mode))
if (chmod_modes && !S_ISLNK(mode) && mode)
mode = tweak_mode(mode, chmod_modes);
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
@@ -776,7 +825,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
uid = (uid_t)read_varint(f);
if (xflags & XMIT_USER_NAME_FOLLOWS)
uid = recv_user_name(f, uid);
else if (inc_recurse && am_root && !numeric_ids)
else if (inc_recurse && am_root && (!numeric_ids || usermap))
uid = match_uid(uid);
}
}
@@ -788,13 +837,13 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
gid_flags = 0;
if (xflags & XMIT_GROUP_NAME_FOLLOWS)
gid = recv_group_name(f, gid, &gid_flags);
else if (inc_recurse && (!am_root || !numeric_ids))
else if (inc_recurse && (!am_root || !numeric_ids || groupmap))
gid = match_gid(gid, &gid_flags);
}
}
if ((preserve_devices && IS_DEVICE(mode))
|| (preserve_specials && IS_SPECIAL(mode))) {
|| (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31)) {
if (protocol_version < 28) {
if (!(xflags & XMIT_SAME_RDEV_pre28))
rdev = (dev_t)read_int(f);
@@ -860,6 +909,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
#if SIZEOF_INT64 >= 8
if (file_length > 0xFFFFFFFFu && S_ISREG(mode))
extra_len += EXTRA_LEN;
#endif
#ifdef HAVE_UTIMENSAT
if (modtime_nsec)
extra_len += EXTRA_LEN;
#endif
if (file_length < 0) {
rprintf(FERROR, "Offset underflow: file-length is negative\n");
@@ -896,6 +949,12 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
file->flags |= FLAG_HLINKED;
#endif
file->modtime = (time_t)modtime;
#ifdef HAVE_UTIMENSAT
if (modtime_nsec) {
file->flags |= FLAG_MOD_NSEC;
OPT_EXTRA(file, 0)->unum = modtime_nsec;
}
#endif
file->len32 = (uint32)file_length;
#if SIZEOF_INT64 >= 8
if (file_length > 0xFFFFFFFFu && S_ISREG(mode)) {
@@ -904,7 +963,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
exit_cleanup(RERR_UNSUPPORTED);
#else
file->flags |= FLAG_LENGTH64;
OPT_EXTRA(file, 0)->unum = (uint32)(file_length >> 32);
OPT_EXTRA(file, NSEC_BUMP(file))->unum = (uint32)(file_length >> 32);
#endif
}
#endif
@@ -984,7 +1043,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
read_sbuf(f, inbuf.buf, inbuf.len);
INIT_XBUF(outbuf, bp, 0, alloc_len);
if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {
if (iconvbufs(ic_recv, &inbuf, &outbuf, ICB_INIT) < 0) {
io_error |= IOERR_GENERAL;
rprintf(FERROR_XFER,
"[%s] cannot convert symlink data for: %s (%s)\n",
@@ -1097,8 +1156,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
if (sanitize_paths)
sanitize_path(thisname, thisname, "", 0, SP_DEFAULT);
if (stp && S_ISDIR(stp->st_mode)) {
st = *stp; /* Needed for "symlink/." with --relative. */
if (stp && (S_ISDIR(stp->st_mode) || stp->st_mode == 0)) {
/* This is needed to handle a "symlink/." with a --relative
* dir, or a request to delete a specific file. */
st = *stp;
*linkname = '\0'; /* make IBM code checker happy */
} else if (readlink_stat(thisname, &st, linkname) != 0) {
int save_errno = errno;
@@ -1139,6 +1200,11 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
full_fname(thisname));
}
return NULL;
} else if (st.st_mode == 0) {
io_error |= IOERR_GENERAL;
rprintf(FINFO, "skipping file with bogus (zero) st_mode: %s\n",
full_fname(thisname));
return NULL;
}
if (filter_level == NO_FILTERS)
@@ -1155,7 +1221,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
if (one_file_system && st.st_dev != filesystem_dev
&& BITS_SETnUNSET(flags, FLAG_CONTENT_DIR, FLAG_TOP_DIR)) {
if (one_file_system > 1) {
if (verbose > 1) {
if (INFO_GTE(MOUNT, 1)) {
rprintf(FINFO,
"[%s] skipping mount-point dir %s\n",
who_am_i(), thisname);
@@ -1204,7 +1270,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
pool = NULL;
}
if (verbose > 2) {
if (DEBUG_GTE(FLIST, 2)) {
rprintf(FINFO, "[%s] make_file(%s,*,%d)\n",
who_am_i(), thisname, filter_level);
}
@@ -1227,11 +1293,21 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
linkname_len = 0;
#endif
#ifdef ST_MTIME_NSEC
if (st.ST_MTIME_NSEC && protocol_version >= 31)
extra_len += EXTRA_LEN;
#endif
#if SIZEOF_CAPITAL_OFF_T >= 8
if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode))
extra_len += EXTRA_LEN;
#endif
if (always_checksum && am_sender && S_ISREG(st.st_mode)) {
file_checksum(thisname, tmp_sum, st.st_size);
if (sender_keeps_checksum)
extra_len += SUM_EXTRA_CNT * EXTRA_LEN;
}
#if EXTRA_ROUNDING > 0
if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;
@@ -1275,11 +1351,17 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
file->flags = flags;
file->modtime = st.st_mtime;
#ifdef ST_MTIME_NSEC
if (st.ST_MTIME_NSEC && protocol_version >= 31) {
file->flags |= FLAG_MOD_NSEC;
OPT_EXTRA(file, 0)->unum = st.ST_MTIME_NSEC;
}
#endif
file->len32 = (uint32)st.st_size;
#if SIZEOF_CAPITAL_OFF_T >= 8
if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode)) {
file->flags |= FLAG_LENGTH64;
OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32);
OPT_EXTRA(file, NSEC_BUMP(file))->unum = (uint32)(st.st_size >> 32);
}
#endif
file->mode = st.st_mode;
@@ -1298,9 +1380,6 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
memcpy(bp + basename_len, linkname, linkname_len);
#endif
if (always_checksum && am_sender && S_ISREG(st.st_mode))
file_checksum(thisname, tmp_sum, st.st_size);
if (am_sender)
F_PATHNAME(file) = pathname;
else if (!pool)
@@ -1312,8 +1391,11 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
return NULL;
}
if (sender_keeps_checksum && S_ISREG(st.st_mode))
memcpy(F_SUM(file), tmp_sum, checksum_len);
if (unsort_ndx)
F_NDX(file) = dir_count;
F_NDX(file) = stats.num_dirs;
return file;
}
@@ -1334,7 +1416,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
if (!file)
return NULL;
if (chmod_modes && !S_ISLNK(file->mode))
if (chmod_modes && !S_ISLNK(file->mode) && file->mode)
file->mode = tweak_mode(file->mode, chmod_modes);
if (f >= 0) {
@@ -1348,6 +1430,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
#endif
#if defined SUPPORT_ACLS || defined SUPPORT_XATTRS
stat_x sx;
init_stat_x(&sx);
#endif
#ifdef SUPPORT_LINKS
@@ -1377,14 +1460,14 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
if (file->dirname) {
INIT_XBUF_STRLEN(inbuf, (char*)file->dirname);
outbuf.size -= 2; /* Reserve room for '/' & 1 more char. */
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0)
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0)
goto convert_error;
outbuf.size += 2;
fbuf[outbuf.len++] = '/';
}
INIT_XBUF_STRLEN(inbuf, (char*)file->basename);
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) {
convert_error:
io_error |= IOERR_GENERAL;
rprintf(FERROR_XFER,
@@ -1398,7 +1481,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
if (symlink_len && sender_symlink_iconv) {
INIT_XBUF(inbuf, (char*)symlink_name, symlink_len, (size_t)-1);
INIT_CONST_XBUF(outbuf, symlink_buf);
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) {
io_error |= IOERR_GENERAL;
f_name(file, fbuf);
rprintf(FERROR_XFER,
@@ -1419,7 +1502,6 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
sx.st.st_mode = file->mode;
sx.acc_acl = sx.def_acl = NULL;
if (get_acl(fname, &sx) < 0) {
io_error |= IOERR_GENERAL;
return NULL;
@@ -1429,7 +1511,6 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
sx.st.st_mode = file->mode;
sx.xattr = NULL;
if (get_xattr(fname, &sx) < 0) {
io_error |= IOERR_GENERAL;
return NULL;
@@ -1700,7 +1781,7 @@ static void send_implied_dirs(int f, struct file_list *flist, char *fname,
item_list *relname_list;
relnamecache **rnpp;
int len, need_new_dir, depth = 0;
struct filter_list_struct save_filter_list = filter_list;
filter_rule_list save_filter_list = filter_list;
flags = (flags | FLAG_IMPLIED_DIR) & ~(FLAG_TOP_DIR | FLAG_CONTENT_DIR);
filter_list.head = filter_list.tail = NULL; /* Don't filter implied dirs. */
@@ -1796,7 +1877,8 @@ static NORETURN void fatal_unsafe_io_error(void)
/* This (sadly) can only happen when pushing data because
* the sender does not know about what kind of delete
* is in effect on the receiving side when pulling. */
rprintf(FERROR_XFER, "FATAL I/O ERROR: dying to avoid a --delete-during issue with a pre-3.0.7 receiver.\n");
rprintf(FERROR_XFER, "FATAL I/O ERROR: dying to avoid a --delete-%s issue with a pre-3.0.7 receiver.\n",
delete_during == 2 ? "delay" : "during");
exit_cleanup(RERR_UNSUPPORTED);
}
@@ -1853,7 +1935,9 @@ static void send1extra(int f, struct file_struct *file, struct file_list *flist)
if (name_type != NORMAL_NAME) {
STRUCT_STAT st;
if (link_stat(fbuf, &st, 1) != 0) {
if (name_type == MISSING_NAME)
memset(&st, 0, sizeof st);
else if (link_stat(fbuf, &st, 1) != 0) {
interpret_stat_error(fbuf, True);
continue;
}
@@ -1870,19 +1954,19 @@ void send_extra_file_list(int f, int at_least)
struct file_list *flist;
int64 start_write;
uint16 prev_flags;
int old_cnt, save_io_error = io_error;
int save_io_error = io_error;
if (flist_eof)
return;
if (at_least < 0)
at_least = file_total - file_old_total + 1;
/* Keep sending data until we have the requested number of
* files in the upcoming file-lists. */
old_cnt = cur_flist->used;
for (flist = first_flist; flist != cur_flist; flist = flist->next)
old_cnt += flist->used;
while (file_total - old_cnt < at_least) {
while (file_total - file_old_total < at_least) {
struct file_struct *file = dir_flist->sorted[send_dir_ndx];
int dir_ndx, dstart = dir_count;
int dir_ndx, dstart = stats.num_dirs;
const char *pathname = F_PATHNAME(file);
int32 *dp;
@@ -1936,13 +2020,13 @@ void send_extra_file_list(int f, int at_least)
flist_sort_and_clean(flist, 0);
add_dirs_to_tree(send_dir_ndx, flist, dir_count - dstart);
add_dirs_to_tree(send_dir_ndx, flist, stats.num_dirs - dstart);
flist_done_allocating(flist);
file_total += flist->used;
stats.flist_size += stats.total_written - start_write;
stats.num_files += flist->used;
if (verbose > 3)
if (DEBUG_GTE(FLIST, 3))
output_flist(flist);
if (DIR_FIRST_CHILD(dp) >= 0) {
@@ -1953,6 +2037,8 @@ void send_extra_file_list(int f, int at_least)
if ((send_dir_ndx = DIR_PARENT(dp)) < 0) {
write_ndx(f, NDX_FLIST_EOF);
flist_eof = 1;
if (DEBUG_GTE(FLIST, 3))
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
change_local_filter_dir(NULL, 0, 0);
goto finish;
}
@@ -1965,7 +2051,7 @@ void send_extra_file_list(int f, int at_least)
}
finish:
if (io_error != save_io_error && !ignore_errors)
if (io_error != save_io_error && protocol_version == 30 && !ignore_errors)
send_msg_int(MSG_IO_ERROR, io_error);
}
@@ -1980,7 +2066,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
struct timeval start_tv, end_tv;
int64 start_write;
int use_ff_fd = 0;
int disable_buffering;
int disable_buffering, reenable_multiplex = -1;
int flags = recurse ? FLAG_CONTENT_DIR : 0;
int reading_remotely = filesfrom_host != NULL;
int rl_flags = (reading_remotely ? 0 : RL_DUMP_COMMENTS)
@@ -1993,7 +2079,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
rprintf(FLOG, "building file list\n");
if (show_filelist_p())
start_filelist_progress("building file list");
else if (inc_recurse && verbose && !am_server)
else if (inc_recurse && INFO_GTE(FLIST, 1) && !am_server)
rprintf(FCLIENT, "sending incremental file list\n");
start_write = stats.total_written;
@@ -2021,6 +2107,12 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
full_fname(argv[0]));
exit_cleanup(RERR_FILESELECT);
}
if (protocol_version < 31) {
/* Older protocols send the files-from data w/o packaging
* it in multiplexed I/O packets, so temporarily switch
* to buffered I/O to match this behavior. */
reenable_multiplex = io_end_multiplex_in(MPLX_TO_BUFFERED);
}
use_ff_fd = 1;
}
@@ -2162,14 +2254,26 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0
|| (name_type != DOTDIR_NAME && is_daemon_excluded(fbuf, S_ISDIR(st.st_mode)))
|| (relative_paths && path_is_daemon_excluded(fbuf, 1))) {
io_error |= IOERR_GENERAL;
rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fbuf));
continue;
if (errno != ENOENT || missing_args == 0) {
/* This is a transfer error, but inhibit deletion
* only if we might be omitting an existing file. */
if (errno != ENOENT)
io_error |= IOERR_GENERAL;
rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fbuf));
continue;
} else if (missing_args == 1) {
/* Just ignore the arg. */
continue;
} else /* (missing_args == 2) */ {
/* Send the arg as a "missing" entry with
* mode 0, which tells the generator to delete it. */
memset(&st, 0, sizeof st);
}
}
/* A dot-dir should not be excluded! */
if (name_type != DOTDIR_NAME
if (name_type != DOTDIR_NAME && st.st_mode != 0
&& is_excluded(fbuf, S_ISDIR(st.st_mode) != 0, ALL_FILTERS))
continue;
@@ -2185,7 +2289,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
p = fn;
} else
fn = p;
send_implied_dirs(f, flist, fbuf, fbuf, p, flags, name_type);
send_implied_dirs(f, flist, fbuf, fbuf, p, flags,
st.st_mode == 0 ? MISSING_NAME : name_type);
if (fn == p)
continue;
}
@@ -2219,6 +2324,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
send_file_name(f, flist, fbuf, &st, flags, NO_FILTERS);
}
if (reenable_multiplex >= 0)
io_start_multiplex_in(reenable_multiplex);
gettimeofday(&end_tv, NULL);
stats.flist_buildtime = (int64)(end_tv.tv_sec - start_tv.tv_sec) * 1000
+ (end_tv.tv_usec - start_tv.tv_usec) / 1000;
@@ -2267,12 +2375,11 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
flist->sorted = flist->files;
flist_sort_and_clean(flist, 0);
file_total += flist->used;
file_old_total += flist->used;
if (numeric_ids <= 0 && !inc_recurse)
send_id_list(f);
set_msg_fd_in(-1);
/* send the io_error flag */
if (protocol_version < 30)
write_int(f, ignore_errors ? 0 : io_error);
@@ -2280,26 +2387,28 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
send_msg_int(MSG_IO_ERROR, io_error);
if (disable_buffering)
io_end_buffering_out();
io_end_buffering_out(IOBUF_FREE_BUFS);
stats.flist_size = stats.total_written - start_write;
stats.num_files = flist->used;
if (verbose > 3)
if (DEBUG_GTE(FLIST, 3))
output_flist(flist);
if (verbose > 2)
if (DEBUG_GTE(FLIST, 2))
rprintf(FINFO, "send_file_list done\n");
if (inc_recurse) {
send_dir_depth = 1;
add_dirs_to_tree(-1, flist, dir_count);
add_dirs_to_tree(-1, flist, stats.num_dirs);
if (!file_total || strcmp(flist->sorted[flist->low]->basename, ".") != 0)
flist->parent_ndx = -1;
flist_done_allocating(flist);
if (send_dir_ndx < 0) {
write_ndx(f, NDX_FLIST_EOF);
flist_eof = 1;
if (DEBUG_GTE(FLIST, 3))
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
}
else if (file_total == 1) {
/* If we're creating incremental file-lists and there
@@ -2307,6 +2416,10 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
* file-list to check if this is a 1-file xfer. */
send_extra_file_list(f, 1);
}
} else {
flist_eof = 1;
if (DEBUG_GTE(FLIST, 3))
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
}
return flist;
@@ -2317,14 +2430,18 @@ struct file_list *recv_file_list(int f)
struct file_list *flist;
int dstart, flags;
int64 start_read;
int save_verbose = verbose;
if (!first_flist)
if (!first_flist) {
if (show_filelist_p())
start_filelist_progress("receiving file list");
else if (inc_recurse && INFO_GTE(FLIST, 1) && !am_server)
rprintf(FCLIENT, "receiving incremental file list\n");
rprintf(FLOG, "receiving file list\n");
if (show_filelist_p())
start_filelist_progress("receiving file list");
else if (inc_recurse && verbose && !am_server && !first_flist)
rprintf(FCLIENT, "receiving incremental file list\n");
if (usermap)
parse_name_map(usermap, True);
if (groupmap)
parse_name_map(groupmap, False);
}
start_read = stats.total_read;
@@ -2344,8 +2461,6 @@ struct file_list *recv_file_list(int f)
dstart = 0;
}
if (am_server && verbose > 2)
verbose = 2;
while ((flags = read_byte(f)) != 0) {
struct file_struct *file;
@@ -2367,24 +2482,33 @@ struct file_list *recv_file_list(int f)
flist_expand(flist, 1);
file = recv_file_entry(f, flist, flags);
if (inc_recurse && S_ISDIR(file->mode)) {
flist_expand(dir_flist, 1);
dir_flist->files[dir_flist->used++] = file;
}
if (S_ISREG(file->mode)) {
/* Already counted */
} else if (S_ISDIR(file->mode)) {
if (inc_recurse) {
flist_expand(dir_flist, 1);
dir_flist->files[dir_flist->used++] = file;
}
stats.num_dirs++;
} else if (S_ISLNK(file->mode))
stats.num_symlinks++;
else if (IS_DEVICE(file->mode))
stats.num_symlinks++;
else
stats.num_specials++;
flist->files[flist->used++] = file;
maybe_emit_filelist_progress(flist->used);
if (verbose > 2) {
if (DEBUG_GTE(FLIST, 2)) {
char *name = f_name(file, NULL);
rprintf(FINFO, "recv_file_name(%s)\n", NS(name));
}
}
file_total += flist->used;
verbose = save_verbose;
if (verbose > 2)
if (DEBUG_GTE(FLIST, 2))
rprintf(FINFO, "received %d names\n", flist->used);
if (show_filelist_p())
@@ -2422,26 +2546,29 @@ struct file_list *recv_file_list(int f)
if (inc_recurse)
flist_done_allocating(flist);
else if (f >= 0)
else if (f >= 0) {
recv_id_list(f, flist);
flist_eof = 1;
if (DEBUG_GTE(FLIST, 3))
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
}
flist_sort_and_clean(flist, relative_paths);
if (protocol_version < 30) {
/* Recv the io_error flag */
if (ignore_errors)
read_int(f);
else
io_error |= read_int(f);
int err = read_int(f);
if (!ignore_errors)
io_error |= err;
} else if (inc_recurse && flist->ndx_start == 1) {
if (!file_total || strcmp(flist->sorted[flist->low]->basename, ".") != 0)
flist->parent_ndx = -1;
}
if (verbose > 3)
if (DEBUG_GTE(FLIST, 3))
output_flist(flist);
if (verbose > 2)
if (DEBUG_GTE(FLIST, 2))
rprintf(FINFO, "recv_file_list done\n");
stats.flist_size += stats.total_read - start_read;
@@ -2458,6 +2585,8 @@ void recv_additional_file_list(int f)
int ndx = read_ndx(f);
if (ndx == NDX_FLIST_EOF) {
flist_eof = 1;
if (DEBUG_GTE(FLIST, 3))
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
change_local_filter_dir(NULL, 0, 0);
} else {
ndx = NDX_FLIST_OFFSET - ndx;
@@ -2469,7 +2598,7 @@ void recv_additional_file_list(int f)
NDX_FLIST_OFFSET - dir_flist->used + 1);
exit_cleanup(RERR_PROTOCOL);
}
if (verbose > 3) {
if (DEBUG_GTE(FLIST, 3)) {
rprintf(FINFO, "[%s] receiving flist for dir %d\n",
who_am_i(), ndx);
}
@@ -2576,14 +2705,16 @@ struct file_list *flist_new(int flags, char *msg)
if (flags & FLIST_TEMP) {
if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0,
out_of_memory, POOL_INTERN)))
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);
out_of_memory,
POOL_INTERN);
if (!flist->file_pool)
out_of_memory(msg);
@@ -2713,7 +2844,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
keep = j, drop = i;
if (!am_sender) {
if (verbose > 1) {
if (DEBUG_GTE(DUP, 1)) {
rprintf(FINFO,
"removing duplicate name %s from file list (%d)\n",
f_name(file, fbuf), drop + flist->ndx_start);
@@ -2854,10 +2985,10 @@ static void output_flist(struct file_list *flist)
} else
root = dir = slash = name = trail = "";
rprintf(FINFO,
"[%s] i=%d %s %s%s%s%s mode=0%o len=%.0f%s%s flags=%x\n",
"[%s] i=%d %s %s%s%s%s mode=0%o len=%s%s%s flags=%x\n",
who, i + flist->ndx_start,
root, dir, slash, name, trail,
(int)file->mode, (double)F_LENGTH(file),
(int)file->mode, comma_num(F_LENGTH(file)),
uidbuf, gidbuf, file->flags);
}
}
@@ -3072,7 +3203,7 @@ struct file_list *get_dirlist(char *dirname, int dlen, int flags)
send_directory(senddir_fd, dirlist, dirname, dlen, FLAG_CONTENT_DIR);
xfer_dirs = save_xfer_dirs;
recurse = save_recurse;
if (do_progress)
if (INFO_GTE(PROGRESS, 1))
flist_count_offset += dirlist->used;
prune_empty_dirs = 0;
@@ -3080,7 +3211,7 @@ struct file_list *get_dirlist(char *dirname, int dlen, int flags)
flist_sort_and_clean(dirlist, 0);
prune_empty_dirs = save_prune_empty_dirs;
if (verbose > 3)
if (DEBUG_GTE(FLIST, 3))
output_flist(dirlist);
return dirlist;

View File

File diff suppressed because it is too large Load Diff

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-2008 Wayne Davison
* Copyright (C) 2003-2013 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

View File

@@ -1,7 +1,7 @@
/*
* Routines to provide a memory-efficient hashtable.
*
* Copyright (C) 2007-2009 Wayne Davison
* Copyright (C) 2007-2013 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
@@ -23,13 +23,13 @@
struct hashtable *hashtable_create(int size, int key64)
{
int req = size;
struct hashtable *tbl;
int node_size = key64 ? sizeof (struct ht_int64_node)
: sizeof (struct ht_int32_node);
/* Pick a power of 2 that can hold the requested size. */
if (size & (size-1) || size < 16) {
int req = size;
size = 16;
while (size < req)
size *= 2;
@@ -43,11 +43,25 @@ struct hashtable *hashtable_create(int size, int key64)
tbl->node_size = node_size;
tbl->key64 = key64 ? 1 : 0;
if (DEBUG_GTE(HASH, 1)) {
char buf[32];
if (req != size)
snprintf(buf, sizeof buf, "req: %d, ", req);
else
*buf = '\0';
rprintf(FINFO, "[%s] created hashtable %lx (%ssize: %d, keys: %d-bit)\n",
who_am_i(), (long)tbl, buf, size, key64 ? 64 : 32);
}
return tbl;
}
void hashtable_destroy(struct hashtable *tbl)
{
if (DEBUG_GTE(HASH, 1)) {
rprintf(FINFO, "[%s] destroyed hashtable %lx (size: %d, keys: %d-bit)\n",
who_am_i(), (long)tbl, tbl->size, tbl->key64 ? 64 : 32);
}
free(tbl->nodes);
free(tbl);
}
@@ -75,6 +89,11 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
tbl->size = size;
tbl->entries = 0;
if (DEBUG_GTE(HASH, 1)) {
rprintf(FINFO, "[%s] growing hashtable %lx (size: %d, keys: %d-bit)\n",
who_am_i(), (long)tbl, size, key64 ? 64 : 32);
}
for (i = size / 2; i-- > 0; ) {
struct ht_int32_node *move_node = HT_NODE(tbl, old_nodes, i);
int64 move_key = HT_KEY(move_node, key64);

99
hlink.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2004-2009 Wayne Davison
* Copyright (C) 2004-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,8 +21,9 @@
*/
#include "rsync.h"
#include "inums.h"
#include "ifuncs.h"
extern int verbose;
extern int dry_run;
extern int list_only;
extern int am_sender;
@@ -31,7 +32,6 @@ extern int do_xfers;
extern int link_dest;
extern int preserve_acls;
extern int preserve_xattrs;
extern int make_backups;
extern int protocol_version;
extern int remove_source_files;
extern int stdout_format_has_i;
@@ -71,8 +71,14 @@ struct ht_int64_node *idev_find(int64 dev, int64 ino)
if (!dev_node || dev_node->key != dev+1) {
/* We keep a separate hash table of inodes for every device. */
dev_node = hashtable_find(dev_tbl, dev+1, 1);
if (!(tbl = dev_node->data))
if (!(tbl = dev_node->data)) {
tbl = dev_node->data = hashtable_create(512, 1);
if (DEBUG_GTE(HLINK, 3)) {
rprintf(FINFO,
"[%s] created hashtable for dev %s\n",
who_am_i(), big_num(dev));
}
}
} else
tbl = dev_node->data;
@@ -206,7 +212,7 @@ void match_hard_links(struct file_list *flist)
}
static int maybe_hard_link(struct file_struct *file, int ndx,
const char *fname, int statret, stat_x *sxp,
char *fname, int statret, stat_x *sxp,
const char *oldname, STRUCT_STAT *old_stp,
const char *realname, int itemizing, enum logcode code)
{
@@ -218,31 +224,24 @@ static int maybe_hard_link(struct file_struct *file, int ndx,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
0, "");
}
if (verbose > 1 && maybe_ATTRS_REPORT)
if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
rprintf(FCLIENT, "%s is uptodate\n", fname);
file->flags |= FLAG_HLINK_DONE;
return 0;
}
if (make_backups > 0) {
if (!make_backup(fname))
return -1;
} else if (robust_unlink(fname)) {
rsyserr(FERROR_XFER, errno, "unlink %s failed",
full_fname(fname));
return -1;
}
}
if (hard_link_one(file, fname, oldname, 0)) {
if (atomic_create(file, fname, oldname, MAKEDEV(0, 0), sxp, statret == 0 ? DEL_FOR_FILE : 0)) {
if (itemizing) {
itemize(fname, file, ndx, statret, sxp,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
realname);
}
if (code != FNONE && verbose)
if (code != FNONE && INFO_GTE(NAME, 1))
rprintf(code, "%s => %s\n", fname, realname);
return 0;
}
return -1;
}
@@ -288,7 +287,7 @@ static char *check_prior(struct file_struct *file, int gnum,
/* Only called if FLAG_HLINKED is set and FLAG_HLINK_FIRST is not. Returns:
* 0 = process the file, 1 = skip the file, -1 = error occurred. */
int hard_link_check(struct file_struct *file, int ndx, const char *fname,
int hard_link_check(struct file_struct *file, int ndx, char *fname,
int statret, stat_x *sxp, int itemizing,
enum logcode code)
{
@@ -307,6 +306,10 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
if (!flist) {
/* The previous file was skipped, so this one is
* treated as if it were the first in its group. */
if (DEBUG_GTE(HLINK, 2)) {
rprintf(FINFO, "hlink for %d (%s,%d): virtual first\n",
ndx, f_name(file, NULL), gnum);
}
return 0;
}
@@ -323,8 +326,16 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
F_HL_PREV(prev_file) = ndx;
file->flags |= FLAG_FILE_SENT;
cur_flist->in_progress++;
if (DEBUG_GTE(HLINK, 2)) {
rprintf(FINFO, "hlink for %d (%s,%d): waiting for %d\n",
ndx, f_name(file, NULL), gnum, F_HL_PREV(file));
}
return 1;
}
if (DEBUG_GTE(HLINK, 2)) {
rprintf(FINFO, "hlink for %d (%s,%d): looking for a leader\n",
ndx, f_name(file, NULL), gnum);
}
return 0;
}
@@ -332,7 +343,6 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
if (!(prev_file->flags & FLAG_HLINK_FIRST)) {
/* The previous previous is FIRST when prev is not. */
prev_name = realname = check_prior(prev_file, gnum, &prev_ndx, &flist);
assert(prev_name != NULL || flist != NULL);
/* Update our previous pointer to point to the FIRST. */
F_HL_PREV(file) = prev_ndx;
}
@@ -340,9 +350,14 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
if (!prev_name) {
int alt_dest;
assert(flist != NULL);
prev_file = flist->files[prev_ndx - flist->ndx_start];
/* F_HL_PREV() is alt_dest value when DONE && FIRST. */
alt_dest = F_HL_PREV(prev_file);
if (DEBUG_GTE(HLINK, 2)) {
rprintf(FINFO, "hlink for %d (%s,%d): found flist match (alt %d)\n",
ndx, f_name(file, NULL), gnum, alt_dest);
}
if (alt_dest >= 0 && dry_run) {
pathjoin(namebuf, MAXPATHLEN, basis_dir[alt_dest],
@@ -356,6 +371,11 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
}
}
if (DEBUG_GTE(HLINK, 2)) {
rprintf(FINFO, "hlink for %d (%s,%d): leader is %d (%s)\n",
ndx, f_name(file, NULL), gnum, prev_ndx, prev_name);
}
if (link_stat(prev_name, &prev_st, 0) < 0) {
if (!dry_run || errno != ENOENT) {
rsyserr(FERROR_XFER, errno, "stat %s failed", full_fname(prev_name));
@@ -371,12 +391,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
char cmpbuf[MAXPATHLEN];
stat_x alt_sx;
int j = 0;
#ifdef SUPPORT_ACLS
alt_sx.acc_acl = alt_sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
alt_sx.xattr = NULL;
#endif
init_stat_x(&alt_sx);
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
if (link_stat(cmpbuf, &alt_sx.st, 0) < 0)
@@ -387,10 +402,10 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
continue;
statret = 1;
if (stdout_format_has_i == 0
|| (verbose < 2 && stdout_format_has_i < 2)) {
|| (!INFO_GTE(NAME, 2) && stdout_format_has_i < 2)) {
itemizing = 0;
code = FNONE;
if (verbose > 1 && maybe_ATTRS_REPORT)
if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
rprintf(FCLIENT, "%s is uptodate\n", fname);
}
break;
@@ -426,16 +441,8 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
}
}
#endif
} else {
#ifdef SUPPORT_ACLS
if (preserve_acls)
free_acl(&alt_sx);
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs)
free_xattr(&alt_sx);
#endif
}
} else
free_stat_x(&alt_sx);
}
if (maybe_hard_link(file, ndx, fname, statret, sxp, prev_name, &prev_st,
@@ -454,7 +461,7 @@ int hard_link_one(struct file_struct *file, const char *fname,
if (do_link(oldname, fname) < 0) {
enum logcode code;
if (terse) {
if (!verbose)
if (!INFO_GTE(NAME, 1))
return 0;
code = FINFO;
} else
@@ -481,7 +488,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
int prev_statret, ndx, prev_ndx = F_HL_PREV(file);
if (stp == NULL && prev_ndx >= 0) {
if (link_stat(fname, &st, 0) < 0) {
if (link_stat(fname, &st, 0) < 0 && !dry_run) {
rsyserr(FERROR_XFER, errno, "stat %s failed",
full_fname(fname));
return;
@@ -499,12 +506,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
} else
our_name = fname;
#ifdef SUPPORT_ACLS
prev_sx.acc_acl = prev_sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
prev_sx.xattr = NULL;
#endif
init_stat_x(&prev_sx);
while ((ndx = prev_ndx) >= 0) {
int val;
@@ -517,14 +519,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
val = maybe_hard_link(file, ndx, prev_name, prev_statret, &prev_sx,
our_name, stp, fname, itemizing, code);
flist->in_progress--;
#ifdef SUPPORT_ACLS
if (preserve_acls)
free_acl(&prev_sx);
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs)
free_xattr(&prev_sx);
#endif
free_stat_x(&prev_sx);
if (val < 0)
continue;
if (remove_source_files == 1 && do_xfers)

View File

@@ -1,6 +1,6 @@
/* Inline functions for rsync.
*
* Copyright (C) 2007-2008 Wayne Davison
* Copyright (C) 2007-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,6 +35,14 @@ realloc_xbuf(xbuf *xb, size_t sz)
xb->size = sz;
}
static inline void
free_xbuf(xbuf *xb)
{
if (xb->buf)
free(xb->buf);
memset(xb, 0, sizeof (xbuf));
}
static inline int
to_wire_mode(mode_t mode)
{
@@ -67,44 +75,32 @@ d_name(struct dirent *di)
#endif
}
static inline int
isDigit(const char *ptr)
static inline void
init_stat_x(stat_x *sx_p)
{
return isdigit(*(unsigned char *)ptr);
#ifdef SUPPORT_ACLS
sx_p->acc_acl = sx_p->def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
sx_p->xattr = NULL;
#endif
}
static inline int
isPrint(const char *ptr)
static inline void
free_stat_x(stat_x *sx_p)
{
return isprint(*(unsigned char *)ptr);
}
static inline int
isSpace(const char *ptr)
{
return isspace(*(unsigned char *)ptr);
}
static inline int
isLower(const char *ptr)
{
return islower(*(unsigned char *)ptr);
}
static inline int
isUpper(const char *ptr)
{
return isupper(*(unsigned char *)ptr);
}
static inline int
toLower(const char *ptr)
{
return tolower(*(unsigned char *)ptr);
}
static inline int
toUpper(const char *ptr)
{
return toupper(*(unsigned char *)ptr);
#ifdef SUPPORT_ACLS
{
extern int preserve_acls;
if (preserve_acls)
free_acl(sx_p);
}
#endif
#ifdef SUPPORT_XATTRS
{
extern int preserve_xattrs;
if (preserve_xattrs)
free_xattr(sx_p);
}
#endif
}

57
inums.h Normal file
View File

@@ -0,0 +1,57 @@
/* Inline functions for rsync.
*
* Copyright (C) 2008 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
static inline char *
big_num(int64 num)
{
return do_big_num(num, 0, NULL);
}
static inline char *
comma_num(int64 num)
{
extern int human_readable;
return do_big_num(num, human_readable != 0, NULL);
}
static inline char *
human_num(int64 num)
{
extern int human_readable;
return do_big_num(num, human_readable, NULL);
}
static inline char *
big_dnum(double dnum, int decimal_digits)
{
return do_big_dnum(dnum, 0, decimal_digits);
}
static inline char *
comma_dnum(double dnum, int decimal_digits)
{
extern int human_readable;
return do_big_dnum(dnum, human_readable != 0, decimal_digits);
}
static inline char *
human_dnum(double dnum, int decimal_digits)
{
extern int human_readable;
return do_big_dnum(dnum, human_readable, decimal_digits);
}

2503
io.c
View File

File diff suppressed because it is too large Load Diff

2
io.h
View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2008 Wayne Davison
* Copyright (C) 2007-2013 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

59
itypes.h Normal file
View File

@@ -0,0 +1,59 @@
/* Inline functions for rsync.
*
* Copyright (C) 2007-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
static inline int
isDigit(const char *ptr)
{
return isdigit(*(unsigned char *)ptr);
}
static inline int
isPrint(const char *ptr)
{
return isprint(*(unsigned char *)ptr);
}
static inline int
isSpace(const char *ptr)
{
return isspace(*(unsigned char *)ptr);
}
static inline int
isLower(const char *ptr)
{
return islower(*(unsigned char *)ptr);
}
static inline int
isUpper(const char *ptr)
{
return isupper(*(unsigned char *)ptr);
}
static inline int
toLower(const char *ptr)
{
return tolower(*(unsigned char *)ptr);
}
static inline int
toUpper(const char *ptr)
{
return toupper(*(unsigned char *)ptr);
}

View File

@@ -20,6 +20,9 @@
*/
#include "rsync.h"
#include "itypes.h"
static char number_separator;
#ifndef HAVE_STRDUP
char *strdup(char *s)
@@ -151,3 +154,122 @@ int sys_gettimeofday(struct timeval *tv)
return gettimeofday(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
* return up to 4 buffers at a time. */
char *do_big_num(int64 num, int human_flag, const char *fract)
{
static char bufs[4][128]; /* more than enough room */
static unsigned int n;
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 = '.';
}
n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
if (human_flag > 1) {
if (human_flag == 2)
HUMANIFY(1000);
else
HUMANIFY(1024);
}
s = bufs[n] + sizeof bufs[0] - 1;
if (fract) {
len = strlen(fract);
s -= len;
strlcpy(s, fract, len + 1);
} else
*s = '\0';
len = 0;
if (!num)
*--s = '0';
if (num < 0) {
/* A maximum-size negated number can't fit as a positive,
* so do one digit in negated form to start us off. */
*--s = (char)(-(num % 10)) + '0';
num = -(num / 10);
len++;
negated = 1;
} else
negated = 0;
while (num) {
if (human_flag) {
if (len == 3) {
*--s = number_separator;
len = 1;
} else
len++;
}
*--s = (char)(num % 10) + '0';
num /= 10;
}
if (negated)
*--s = '-';
return s;
}
/* Return the double number as a string. If the human_flag option is > 1,
* we may output the number in K, M, G, or T units. The buffer we use for
* our result is either a single static buffer defined here, or a buffer
* we get from do_big_num(). */
char *do_big_dnum(double dnum, int human_flag, int decimal_digits)
{
static char tmp_buf[128];
#if SIZEOF_INT64 >= 8
char *fract;
snprintf(tmp_buf, sizeof tmp_buf, "%.*f", decimal_digits, dnum);
if (!human_flag || (dnum < 1000.0 && dnum > -1000.0))
return tmp_buf;
for (fract = tmp_buf+1; isDigit(fract); fract++) {}
return do_big_num((int64)dnum, human_flag, fract);
#else
/* A big number might lose digits converting to a too-short int64,
* so let's just return the raw double conversion. */
snprintf(tmp_buf, sizeof tmp_buf, "%.*f", decimal_digits, dnum);
return tmp_buf;
#endif
}

72
lib/getpass.c Normal file
View File

@@ -0,0 +1,72 @@
/*
* An implementation of getpass for systems that lack one.
*
* Copyright (C) 2013 Roman Donchenko
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, visit the http://fsf.org website.
*/
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include "rsync.h"
char *getpass(const char *prompt)
{
static char password[256];
BOOL tty_changed = False, read_success;
struct termios tty_old, tty_new;
FILE *in = stdin, *out = stderr;
FILE *tty = fopen("/dev/tty", "w+");
if (tty)
in = out = tty;
if (tcgetattr(fileno(in), &tty_old) == 0) {
tty_new = tty_old;
tty_new.c_lflag &= ~(ECHO | ISIG);
if (tcsetattr(fileno(in), TCSAFLUSH, &tty_new) == 0)
tty_changed = True;
}
if (!tty_changed)
fputs("(WARNING: will be visible) ", out);
fputs(prompt, out);
fflush(out);
read_success = fgets(password, sizeof password, in) != NULL;
/* Print the newline that hasn't been echoed. */
fputc('\n', out);
if (tty_changed)
tcsetattr(fileno(in), TCSAFLUSH, &tty_old);
if (tty)
fclose(tty);
if (read_success) {
/* Remove the trailing newline. */
size_t password_len = strlen(password);
if (password_len && password[password_len - 1] == '\n')
password[password_len - 1] = '\0';
return password;
}
return NULL;
}

View File

@@ -95,25 +95,39 @@ for
.I quantum
will produce a quantum that should meet maximal alignment
on most platforms.
If
.B POOL_QALIGN
Unless
.B POOL_NO_QALIGN
is set in the
.IR flags ,
allocations will be aligned to addresses that are a
multiple of
.IR quantum .
A
.B NULL
may be specified for the
.I bomb
function pointer if it is not needed. (See the
.B pool_alloc()
function for how it is used.)
If
.B POOL_CLEAR
is set in the
.IR flags ,
all allocations from the pool will be initialized to zeros.
You may specify a
.B NULL
for the
.I bomb
function pointer if you don't wish to use it. (See the
.B pool_alloc()
function for how it is used.)
If either
.B POOL_PREPEND
or
.B POOL_INTERN
is specified in the
.IR flags ,
each extent's data structure will be allocated at the start of the
.IR size -length
buffer (rather than as a separate, non-pool allocation), with the
former extending the
.I size
to hold the structure, and the latter subtracting the structure's
length from the indicated
.IR size .
.P
.B pool_destroy()
destroys an allocation
@@ -131,8 +145,8 @@ is
.BR 0 ,
.I quantum
bytes will be allocated.
If the pool has been created with
.BR POOL_QALIGN ,
If the pool has been created without
.BR POOL_NO_QALIGN ,
every chunk of memory that is returned will be suitably aligned.
You can use this with the default
.I quantum
@@ -169,7 +183,7 @@ an extent), its memory will be completely freed back to the system.
If
.I addr
is
.BR 0 ,
.BR NULL ,
no memory will be freed, but subsequent allocations will come
from a new extent.
.P

View File

@@ -2,6 +2,8 @@
#define POOL_DEF_EXTENT (32 * 1024)
#define POOL_QALIGN_P2 (1<<16) /* power-of-2 qalign */
struct alloc_pool
{
size_t size; /* extent size */
@@ -13,7 +15,7 @@ struct alloc_pool
/* statistical data */
unsigned long e_created; /* extents created */
unsigned long e_freed; /* extents detroyed */
unsigned long e_freed; /* extents destroyed */
int64 n_allocated; /* calls to alloc */
int64 n_freed; /* calls to free */
int64 b_allocated; /* cum. bytes allocated */
@@ -22,16 +24,18 @@ struct alloc_pool
struct pool_extent
{
struct pool_extent *next;
void *start; /* starting address */
size_t free; /* free bytecount */
size_t bound; /* bytes bound by padding,
* overhead and freed */
struct pool_extent *next;
size_t bound; /* trapped free bytes */
};
struct align_test {
void *foo;
int64 bar;
uchar foo;
union {
int64 i;
void *p;
} bar;
};
#define MINALIGN offsetof(struct align_test, bar)
@@ -43,20 +47,42 @@ struct align_test {
alloc_pool_t
pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags)
{
struct alloc_pool *pool;
struct alloc_pool *pool;
if (!(pool = new(struct alloc_pool)))
return pool;
memset(pool, 0, sizeof (struct alloc_pool));
if (!(pool = new0(struct alloc_pool)))
return NULL;
pool->size = size /* round extent size to min alignment reqs */
? (size + MINALIGN - 1) & ~(MINALIGN - 1)
: POOL_DEF_EXTENT;
if (flags & POOL_INTERN) {
pool->size -= sizeof (struct pool_extent);
flags |= POOL_APPEND;
if ((MINALIGN & (MINALIGN - 1)) != 0) {
if (bomb)
(*bomb)("Compiler error: MINALIGN is not a power of 2\n");
return NULL;
}
pool->quantum = quantum ? quantum : MINALIGN;
if (!size)
size = POOL_DEF_EXTENT;
if (!quantum)
quantum = MINALIGN;
if (flags & POOL_INTERN) {
if (size <= sizeof (struct pool_extent))
size = quantum;
else
size -= sizeof (struct pool_extent);
flags |= POOL_PREPEND;
}
if (quantum <= 1)
flags = (flags | POOL_NO_QALIGN) & ~POOL_QALIGN_P2;
else if (!(flags & POOL_NO_QALIGN)) {
if (size % quantum)
size += quantum - size % quantum;
/* If quantum is a power of 2, we'll avoid using modulus. */
if (!(quantum & (quantum - 1)))
flags |= POOL_QALIGN_P2;
}
pool->size = size;
pool->quantum = quantum;
pool->bomb = bomb;
pool->flags = flags;
@@ -67,17 +93,21 @@ void
pool_destroy(alloc_pool_t p)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
struct pool_extent *cur, *next;
struct pool_extent *cur, *next;
if (!pool)
return;
for (cur = pool->extents; cur; cur = next) {
next = cur->next;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
if (pool->flags & POOL_PREPEND)
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
else {
free(cur->start);
free(cur);
}
}
free(pool);
}
@@ -90,45 +120,40 @@ pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg)
if (!len)
len = pool->quantum;
else if (pool->quantum > 1 && len % pool->quantum)
len += pool->quantum - len % pool->quantum;
else if (pool->flags & POOL_QALIGN_P2) {
if (len & (pool->quantum - 1))
len += pool->quantum - (len & (pool->quantum - 1));
} else if (!(pool->flags & POOL_NO_QALIGN)) {
if (len % pool->quantum)
len += pool->quantum - len % pool->quantum;
}
if (len > pool->size)
goto bomb_out;
if (!pool->extents || len > pool->extents->free) {
void *start;
size_t free;
size_t bound;
size_t skew;
size_t asize;
void *start;
size_t asize;
struct pool_extent *ext;
free = pool->size;
bound = 0;
asize = pool->size;
if (pool->flags & POOL_APPEND)
if (pool->flags & POOL_PREPEND)
asize += sizeof (struct pool_extent);
if (!(start = new_array(char, asize)))
goto bomb_out;
if (pool->flags & POOL_CLEAR)
memset(start, 0, free);
memset(start, 0, asize);
if (pool->flags & POOL_APPEND)
ext = PTR_ADD(start, free);
else if (!(ext = new(struct pool_extent)))
if (pool->flags & POOL_PREPEND) {
ext = start;
start = PTR_ADD(start, sizeof (struct pool_extent));
} else if (!(ext = new(struct pool_extent)))
goto bomb_out;
if (pool->flags & POOL_QALIGN && pool->quantum > 1
&& (skew = (size_t)PTR_ADD(start, free) % pool->quantum)) {
bound += skew;
free -= skew;
}
ext->start = start;
ext->free = free;
ext->bound = bound;
ext->free = pool->size;
ext->bound = 0;
ext->next = pool->extents;
pool->extents = ext;
@@ -160,10 +185,24 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
if (!pool)
return;
if (!addr) {
/* A NULL addr starts a fresh extent for new allocations. */
if ((cur = pool->extents) != NULL && cur->free != pool->size) {
cur->bound += cur->free;
cur->free = 0;
}
return;
}
if (!len)
len = pool->quantum;
else if (pool->quantum > 1 && len % pool->quantum)
len += pool->quantum - len % pool->quantum;
else if (pool->flags & POOL_QALIGN_P2) {
if (len & (pool->quantum - 1))
len += pool->quantum - (len & (pool->quantum - 1));
} else if (!(pool->flags & POOL_NO_QALIGN)) {
if (len % pool->quantum)
len += pool->quantum - len % pool->quantum;
}
pool->n_freed++;
pool->b_freed += len;
@@ -179,19 +218,12 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
if (!prev) {
/* The "live" extent is kept ready for more allocations. */
if (cur->free + cur->bound + len >= pool->size) {
size_t skew;
if (pool->flags & POOL_CLEAR) {
memset(PTR_ADD(cur->start, cur->free), 0,
pool->size - cur->free);
}
cur->free = pool->size;
cur->bound = 0;
if (pool->flags & POOL_QALIGN && pool->quantum > 1
&& (skew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum)) {
cur->bound += skew;
cur->free -= skew;
}
} else if (addr == PTR_ADD(cur->start, cur->free)) {
if (pool->flags & POOL_CLEAR)
memset(addr, 0, len);
@@ -203,9 +235,12 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
if (cur->free + cur->bound >= pool->size) {
prev->next = cur->next;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
if (pool->flags & POOL_PREPEND)
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
else {
free(cur->start);
free(cur);
}
pool->e_freed++;
} else if (prev != pool->extents) {
/* Move the extent to be the first non-live extent. */
@@ -242,18 +277,11 @@ pool_free_old(alloc_pool_t p, void *addr)
prev->next = NULL;
next = cur;
} else {
size_t skew;
/* The most recent live extent can just be reset. */
if (pool->flags & POOL_CLEAR)
memset(addr, 0, pool->size - cur->free);
cur->free = pool->size;
cur->bound = 0;
if (pool->flags & POOL_QALIGN && pool->quantum > 1
&& (skew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum)) {
cur->bound += skew;
cur->free -= skew;
}
next = cur->next;
cur->next = NULL;
}
@@ -264,9 +292,12 @@ pool_free_old(alloc_pool_t p, void *addr)
while ((cur = next) != NULL) {
next = cur->next;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
if (pool->flags & POOL_PREPEND)
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
else {
free(cur->start);
free(cur);
}
pool->e_freed++;
}
}
@@ -313,7 +344,7 @@ int
pool_stats(alloc_pool_t p, int fd, int summarize)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
struct pool_extent *cur;
struct pool_extent *cur;
char buf[BUFSIZ];
int ret = 0;

View File

@@ -1,9 +1,9 @@
#include <stddef.h>
#define POOL_CLEAR (1<<0) /* zero fill allocations */
#define POOL_QALIGN (1<<1) /* align data to quanta */
#define POOL_NO_QALIGN (1<<1) /* don't align data to quanta */
#define POOL_INTERN (1<<2) /* Allocate extent structures */
#define POOL_APPEND (1<<3) /* or appended to extent data */
#define POOL_PREPEND (1<<3) /* or prepend to extent data */
typedef void *alloc_pool_t;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -126,6 +126,150 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size)
return len;
}
#elif HAVE_SOLARIS_XATTRS
static ssize_t read_xattr(int attrfd, void *buf, size_t buflen)
{
STRUCT_STAT sb;
ssize_t ret;
if (fstat(attrfd, &sb) < 0)
ret = -1;
else if (sb.st_size > SSIZE_MAX) {
errno = ERANGE;
ret = -1;
} else if (buflen == 0)
ret = sb.st_size;
else if (sb.st_size > buflen) {
errno = ERANGE;
ret = -1;
} else {
size_t bufpos;
for (bufpos = 0; bufpos < sb.st_size; ) {
ssize_t cnt = read(attrfd, buf + bufpos, sb.st_size - bufpos);
if (cnt <= 0) {
if (cnt < 0 && errno == EINTR)
continue;
bufpos = -1;
break;
}
bufpos += cnt;
}
ret = bufpos;
}
close(attrfd);
return ret;
}
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
{
int attrfd;
if ((attrfd = attropen(path, name, O_RDONLY)) < 0) {
errno = ENOATTR;
return -1;
}
return read_xattr(attrfd, value, size);
}
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
{
int attrfd;
if ((attrfd = openat(filedes, name, O_RDONLY|O_XATTR, 0)) < 0) {
errno = ENOATTR;
return -1;
}
return read_xattr(attrfd, value, size);
}
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
{
int attrfd;
size_t bufpos;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
if ((attrfd = attropen(path, name, O_CREAT|O_TRUNC|O_WRONLY, mode)) < 0)
return -1;
for (bufpos = 0; bufpos < size; ) {
ssize_t cnt = write(attrfd, value+bufpos, size);
if (cnt <= 0) {
if (cnt < 0 && errno == EINTR)
continue;
bufpos = -1;
break;
}
bufpos += cnt;
}
close(attrfd);
return bufpos > 0 ? 0 : -1;
}
int sys_lremovexattr(const char *path, const char *name)
{
int attrdirfd;
int ret;
if ((attrdirfd = attropen(path, ".", O_RDONLY)) < 0)
return -1;
ret = unlinkat(attrdirfd, name, 0);
close(attrdirfd);
return ret;
}
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
{
int attrdirfd;
DIR *dirp;
struct dirent *dp;
ssize_t ret = 0;
if ((attrdirfd = attropen(path, ".", O_RDONLY)) < 0) {
errno = ENOTSUP;
return -1;
}
if ((dirp = fdopendir(attrdirfd)) == NULL) {
close(attrdirfd);
return -1;
}
while ((dp = readdir(dirp))) {
int len = strlen(dp->d_name);
if (dp->d_name[0] == '.' && (len == 1 || (len == 2 && dp->d_name[1] == '.')))
continue;
if (len == 11 && dp->d_name[0] == 'S' && strncmp(dp->d_name, "SUNWattr_r", 10) == 0
&& (dp->d_name[10] == 'o' || dp->d_name[10] == 'w'))
continue;
if ((ret += len+1) > size) {
if (size == 0)
continue;
ret = -1;
errno = ERANGE;
break;
}
memcpy(list, dp->d_name, len+1);
list += len+1;
}
closedir(dirp);
close(attrdirfd);
return ret;
}
#else
#error You need to create xattr compatibility functions.

1014
loadparm.c
View File

File diff suppressed because it is too large Load Diff

192
log.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2000-2001 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,9 +20,9 @@
*/
#include "rsync.h"
#include "ifuncs.h"
#include "itypes.h"
#include "inums.h"
extern int verbose;
extern int dry_run;
extern int am_daemon;
extern int am_server;
@@ -31,16 +31,19 @@ extern int am_generator;
extern int local_server;
extern int quiet;
extern int module_id;
extern int msg_fd_out;
extern int checksum_len;
extern int allow_8bit_chars;
extern int protocol_version;
extern int always_checksum;
extern int preserve_times;
extern int progress_is_active;
extern int msgs2stderr;
extern int stdout_format_has_i;
extern int stdout_format_has_o_or_i;
extern int logfile_format_has_i;
extern int logfile_format_has_o_or_i;
extern int receiver_symlink_times;
extern int64 total_data_written;
extern int64 total_data_read;
extern mode_t orig_umask;
extern char *auth_user;
extern char *stdout_format;
@@ -55,6 +58,8 @@ extern iconv_t ic_recv;
extern char curr_dir[MAXPATHLEN];
extern char *full_module_path;
extern unsigned int module_dirlen;
extern char sender_file_sum[MAX_DIGEST_LEN];
extern const char undetermined_hostname[];
static int log_initialised;
static int logfile_was_closed;
@@ -62,6 +67,11 @@ static FILE *logfile_fp;
struct stats stats;
int got_xfer_error = 0;
int output_needs_newline = 0;
int send_msgs_to_gen = 0;
static int64 initial_data_written;
static int64 initial_data_read;
struct {
int code;
@@ -85,13 +95,13 @@ struct {
{ RERR_MALLOC , "error allocating core memory buffers" },
{ RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" },
{ RERR_VANISHED , "some files vanished before they could be transferred" },
{ RERR_DEL_LIMIT , "the --max-delete limit stopped deletions" },
{ RERR_TIMEOUT , "timeout in data send/receive" },
{ RERR_CONTIMEOUT , "timeout waiting for daemon connection" },
{ RERR_CMD_FAILED , "remote shell failed" },
{ RERR_CMD_KILLED , "remote shell killed" },
{ RERR_CMD_RUN , "remote command could not be run" },
{ RERR_CMD_NOTFOUND,"remote command not found" },
{ RERR_DEL_LIMIT , "the --max-delete limit stopped deletions" },
{ 0, NULL }
};
@@ -113,8 +123,7 @@ static void logit(int priority, const char *buf)
if (logfile_was_closed)
logfile_reopen();
if (logfile_fp) {
fprintf(logfile_fp, "%s [%d] %s",
timestring(time(NULL)), (int)getpid(), buf);
fprintf(logfile_fp, "%s [%d] %s", timestring(time(NULL)), (int)getpid(), buf);
fflush(logfile_fp);
} else {
syslog(priority, "%s", buf);
@@ -241,7 +250,7 @@ static void filtered_fwrite(FILE *f, const char *buf, int len, int use_isprint)
void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
{
int trailing_CR_or_NL;
FILE *f = NULL;
FILE *f = msgs2stderr ? stderr : stdout;
#ifdef ICONV_OPTION
iconv_t ic = is_utf8 && ic_recv != (iconv_t)-1 ? ic_recv : ic_chck;
#else
@@ -253,7 +262,16 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
if (len < 0)
exit_cleanup(RERR_MESSAGEIO);
if (am_server && msg_fd_out >= 0) {
if (msgs2stderr) {
if (!am_daemon) {
if (code == FLOG)
return;
goto output_msg;
}
if (code == FCLIENT)
return;
code = FLOG;
} else if (send_msgs_to_gen) {
assert(!is_utf8);
/* Pass the message to our sibling in native charset. */
send_msg((enum msgcode)code, buf, len, 0);
@@ -306,31 +324,43 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
/* TODO: can we send the error to the user somehow? */
return;
}
f = stderr;
}
output_msg:
switch (code) {
case FERROR_XFER:
got_xfer_error = 1;
/* FALL THROUGH */
case FERROR:
case FERROR_UTF8:
case FERROR_SOCKET:
case FWARNING:
f = stderr;
break;
case FLOG:
case FINFO:
f = am_server ? stderr : stdout;
case FCLIENT:
break;
default:
fprintf(stderr, "Unknown logcode in rwrite(): %d [%s]\n", (int)code, who_am_i());
exit_cleanup(RERR_MESSAGEIO);
}
if (progress_is_active && !am_server) {
if (output_needs_newline) {
fputc('\n', f);
progress_is_active = 0;
output_needs_newline = 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);
buf++;
len--;
}
#ifdef ICONV_CONST
if (ic != (iconv_t)-1) {
xbuf outbuf, inbuf;
@@ -338,10 +368,10 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
int ierrno;
INIT_CONST_XBUF(outbuf, convbuf);
INIT_XBUF(inbuf, (char*)buf, len, -1);
INIT_XBUF(inbuf, (char*)buf, len, (size_t)-1);
while (inbuf.len) {
iconvbufs(ic, &inbuf, &outbuf, 0);
iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT);
ierrno = errno;
if (outbuf.len) {
filtered_fwrite(f, convbuf, outbuf.len, 0);
@@ -436,12 +466,12 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
void rflush(enum logcode code)
{
FILE *f = NULL;
FILE *f;
if (am_daemon || code == FLOG)
return;
if (code == FINFO && !am_server)
if (!am_server && (code == FINFO || code == FCLIENT))
f = stdout;
else
f = stderr;
@@ -449,10 +479,15 @@ void rflush(enum logcode code)
fflush(f);
}
void remember_initial_stats(void)
{
initial_data_read = total_data_read;
initial_data_written = total_data_written;
}
/* A generic logging routine for send/recv, with parameter substitiution. */
static void log_formatted(enum logcode code, const char *format, const char *op,
struct file_struct *file, const char *fname,
struct stats *initial_stats, int iflags,
struct file_struct *file, const char *fname, int iflags,
const char *hlink)
{
char buf[MAXPATHLEN+1024], buf2[MAXPATHLEN], fmt[32];
@@ -475,30 +510,45 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
buf[total] = '\0';
for (p = buf; (p = strchr(p, '%')) != NULL; ) {
int humanize = 0;
s = p++;
c = fmt + 1;
while (*p == '\'') {
humanize++;
p++;
}
if (*p == '-')
*c++ = *p++;
while (isDigit(p) && c - fmt < (int)(sizeof fmt) - 8)
*c++ = *p++;
while (*p == '\'') {
humanize++;
p++;
}
if (!*p)
break;
*c = '\0';
n = NULL;
/* Note for %h and %a: it doesn't matter what fd we pass to
* client_{name,addr} because rsync_module will already have
* forced the answer to be cached (assuming, of course, for %h
* that lp_reverse_lookup(module_id) is true). */
switch (*p) {
case 'h':
if (am_daemon)
n = client_name(0);
if (am_daemon) {
n = lp_reverse_lookup(module_id)
? client_name(0) : undetermined_hostname;
}
break;
case 'a':
if (am_daemon)
n = client_addr(0);
break;
case 'l':
strlcat(fmt, ".0f", sizeof fmt);
strlcat(fmt, "s", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
(double)F_LENGTH(file));
do_big_num(F_LENGTH(file), humanize, NULL));
n = buf2;
break;
case 'U':
@@ -518,9 +568,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
}
break;
case 'p':
strlcat(fmt, "ld", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
(long)getpid());
strlcat(fmt, "d", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt, (int)getpid());
n = buf2;
break;
case 'M':
@@ -607,29 +656,42 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
n = auth_user;
break;
case 'b':
if (am_sender) {
b = stats.total_written -
initial_stats->total_written;
} else {
b = stats.total_read -
initial_stats->total_read;
}
strlcat(fmt, ".0f", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt, (double)b);
if (!(iflags & ITEM_TRANSFER))
b = 0;
else if (am_sender)
b = total_data_written - initial_data_written;
else
b = total_data_read - initial_data_read;
strlcat(fmt, "s", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
do_big_num(b, humanize, NULL));
n = buf2;
break;
case 'c':
if (!am_sender) {
b = stats.total_written -
initial_stats->total_written;
} else {
b = stats.total_read -
initial_stats->total_read;
}
strlcat(fmt, ".0f", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt, (double)b);
if (!(iflags & ITEM_TRANSFER))
b = 0;
else if (!am_sender)
b = total_data_written - initial_data_written;
else
b = total_data_read - initial_data_read;
strlcat(fmt, "s", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
do_big_num(b, humanize, NULL));
n = buf2;
break;
case 'C':
if (protocol_version >= 30
&& (iflags & ITEM_TRANSFER
|| (always_checksum && S_ISREG(file->mode)))) {
const char *sum = iflags & ITEM_TRANSFER
? sender_file_sum : F_SUM(file);
n = sum_as_hex(sum);
} else {
memset(buf2, ' ', checksum_len*2);
buf2[checksum_len*2] = '\0';
n = buf2;
}
break;
case 'i':
if (iflags & ITEM_DELETED) {
n = "*deleting ";
@@ -728,10 +790,12 @@ int log_format_has(const char *format, char esc)
return 0;
for (p = format; (p = strchr(p, '%')) != NULL; ) {
if (*++p == '-')
for (p++; *p == '\''; p++) {} /*SHARED ITERATOR*/
if (*p == '-')
p++;
while (isDigit(p))
p++;
while (*p == '\'') p++;
if (!*p)
break;
if (*p == esc)
@@ -743,19 +807,14 @@ int log_format_has(const char *format, char esc)
/* Log the transfer of a file. If the code is FCLIENT, the output just goes
* to stdout. If it is FLOG, it just goes to the log file. Otherwise we
* output to both. */
void log_item(enum logcode code, struct file_struct *file,
struct stats *initial_stats, int iflags, const char *hlink)
void log_item(enum logcode code, struct file_struct *file, int iflags, const char *hlink)
{
const char *s_or_r = am_sender ? "send" : "recv";
if (code != FLOG && stdout_format && !am_server) {
log_formatted(FCLIENT, stdout_format, s_or_r,
file, NULL, initial_stats, iflags, hlink);
}
if (code != FCLIENT && logfile_format && *logfile_format) {
log_formatted(FLOG, logfile_format, s_or_r,
file, NULL, initial_stats, iflags, hlink);
}
if (code != FLOG && stdout_format && !am_server)
log_formatted(FCLIENT, stdout_format, s_or_r, file, NULL, iflags, hlink);
if (code != FCLIENT && logfile_format && *logfile_format)
log_formatted(FLOG, logfile_format, s_or_r, file, NULL, iflags, hlink);
}
void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
@@ -763,16 +822,16 @@ void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
{
int significant_flags = iflags & SIGNIFICANT_ITEM_FLAGS;
int see_item = itemizing && (significant_flags || *buf
|| stdout_format_has_i > 1 || (verbose > 1 && stdout_format_has_i));
|| stdout_format_has_i > 1 || (INFO_GTE(NAME, 2) && stdout_format_has_i));
int local_change = iflags & ITEM_LOCAL_CHANGE && significant_flags;
if (am_server) {
if (logfile_name && !dry_run && see_item
&& (significant_flags || logfile_format_has_i))
log_item(FLOG, file, &stats, iflags, buf);
log_item(FLOG, file, iflags, buf);
} else if (see_item || local_change || *buf
|| (S_ISDIR(file->mode) && significant_flags)) {
enum logcode code = significant_flags || logfile_format_has_i ? FINFO : FCLIENT;
log_item(code, file, &stats, iflags, buf);
log_item(code, file, iflags, buf);
}
}
@@ -781,13 +840,13 @@ void log_delete(const char *fname, int mode)
static struct {
union file_extras ex[4]; /* just in case... */
struct file_struct file;
} x;
} x; /* Zero-initialized due to static declaration. */
int len = strlen(fname);
const char *fmt;
x.file.mode = mode;
if (!verbose && !stdout_format)
if (!INFO_GTE(DEL, 1) && !stdout_format)
;
else if (am_server && protocol_version >= 29 && len < MAXPATHLEN) {
if (S_ISDIR(mode))
@@ -795,15 +854,14 @@ void log_delete(const char *fname, int mode)
send_msg(MSG_DELETED, fname, len, am_generator);
} else {
fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n";
log_formatted(FCLIENT, fmt, "del.", &x.file, fname, &stats,
ITEM_DELETED, NULL);
log_formatted(FCLIENT, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
}
if (!logfile_name || dry_run || !logfile_format)
return;
fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n";
log_formatted(FLOG, fmt, "del.", &x.file, fname, &stats, ITEM_DELETED, NULL);
log_formatted(FLOG, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
}
/*
@@ -815,10 +873,10 @@ void log_delete(const char *fname, int mode)
void log_exit(int code, const char *file, int line)
{
if (code == 0) {
rprintf(FLOG,"sent %.0f bytes received %.0f bytes total size %.0f\n",
(double)stats.total_written,
(double)stats.total_read,
(double)stats.total_size);
rprintf(FLOG,"sent %s bytes received %s bytes total size %s\n",
comma_num(stats.total_written),
comma_num(stats.total_read),
comma_num(stats.total_size));
} else if (am_server != 2) {
const char *name;

351
main.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,27 +21,30 @@
*/
#include "rsync.h"
#include "ifuncs.h"
#include "inums.h"
#include "io.h"
#if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
#include <locale.h>
#endif
extern int verbose;
extern int dry_run;
extern int list_only;
extern int io_timeout;
extern int am_root;
extern int am_server;
extern int am_sender;
extern int am_daemon;
extern int inc_recurse;
extern int blocking_io;
extern int always_checksum;
extern int remove_source_files;
extern int output_needs_newline;
extern int need_messages_from_generator;
extern int kluge_around_eof;
extern int do_stats;
extern int got_xfer_error;
extern int msgs2stderr;
extern int module_id;
extern int read_only;
extern int copy_links;
extern int copy_dirlinks;
extern int copy_unsafe_links;
@@ -62,31 +65,44 @@ extern int whole_file;
extern int read_batch;
extern int write_batch;
extern int batch_fd;
extern int sock_f_in;
extern int sock_f_out;
extern int filesfrom_fd;
extern int connect_timeout;
extern int send_msgs_to_gen;
extern dev_t filesystem_dev;
extern pid_t cleanup_child_pid;
extern size_t bwlimit_writemax;
extern unsigned int module_dirlen;
extern BOOL flist_receiving_enabled;
extern BOOL shutting_down;
extern int basis_dir_cnt;
extern struct stats stats;
extern char *stdout_format;
extern char *logfile_format;
extern char *filesfrom_host;
extern char *partial_dir;
extern char *dest_option;
extern char *basis_dir[MAX_BASIS_DIRS+1];
extern char *rsync_path;
extern char *shell_cmd;
extern char *batch_name;
extern char *password_file;
extern char *backup_dir;
extern char curr_dir[MAXPATHLEN];
extern char backup_dir_buf[MAXPATHLEN];
extern char *basis_dir[MAX_BASIS_DIRS+1];
extern struct file_list *first_flist;
extern struct filter_list_struct daemon_filter_list;
extern filter_rule_list daemon_filter_list;
uid_t our_uid;
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;
mode_t orig_umask = 0;
int batch_gen_fd = -1;
int sender_keeps_checksum = 0;
/* There's probably never more than at most 2 outstanding child processes,
* but set it higher, just in case. */
@@ -116,7 +132,7 @@ static void show_malloc_stats(void);
pid_t wait_process(pid_t pid, int *status_ptr, int flags)
{
pid_t waited_pid;
do {
waited_pid = waitpid(pid, status_ptr, flags);
} while (waited_pid == -1 && errno == EINTR);
@@ -169,6 +185,30 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
*exit_code_ptr = WEXITSTATUS(status);
}
void write_del_stats(int f)
{
if (read_batch)
write_int(f, NDX_DEL_STATS);
else
write_ndx(f, NDX_DEL_STATS);
write_varint(f, stats.deleted_files - stats.deleted_dirs
- stats.deleted_symlinks - stats.deleted_devices
- stats.deleted_specials);
write_varint(f, stats.deleted_dirs);
write_varint(f, stats.deleted_symlinks);
write_varint(f, stats.deleted_devices);
write_varint(f, stats.deleted_specials);
}
void read_del_stats(int f)
{
stats.deleted_files = read_varint(f);
stats.deleted_files += stats.deleted_dirs = read_varint(f);
stats.deleted_files += stats.deleted_symlinks = read_varint(f);
stats.deleted_files += stats.deleted_devices = read_varint(f);
stats.deleted_files += stats.deleted_specials = read_varint(f);
}
/* This function gets called from all 3 processes. We want the client side
* to actually output the text, but the sender is the only process that has
* all the stats we need. So, if we're a client sender, we do the report.
@@ -185,7 +225,7 @@ static void handle_stats(int f)
total_read = stats.total_read;
total_written = stats.total_written;
if (do_stats && verbose > 1) {
if (INFO_GTE(STATS, 3)) {
/* These come out from every process */
show_malloc_stats();
show_flist_stats();
@@ -239,13 +279,39 @@ static void handle_stats(int f)
}
}
static void output_itemized_counts(const char *prefix, int *counts)
{
static char *labels[] = { "reg", "dir", "link", "dev", "special" };
char buf[1024], *pre = " (";
int j, len = 0;
int total = counts[0];
if (total) {
counts[0] -= counts[1] + counts[2] + counts[3] + counts[4];
for (j = 0; j < 5; j++) {
if (counts[j]) {
len += snprintf(buf+len, sizeof buf - len - 2,
"%s%s: %s",
pre, labels[j], comma_num(counts[j]));
pre = ", ";
}
}
buf[len++] = ')';
}
buf[len] = '\0';
rprintf(FINFO, "%s: %s%s\n", prefix, comma_num(total), buf);
}
static void output_summary(void)
{
if (do_stats) {
if (INFO_GTE(STATS, 2)) {
rprintf(FCLIENT, "\n");
rprintf(FINFO,"Number of files: %d\n", stats.num_files);
rprintf(FINFO,"Number of files transferred: %d\n",
stats.num_transferred_files);
output_itemized_counts("Number of files", &stats.num_files);
if (protocol_version >= 29)
output_itemized_counts("Number of created files", &stats.created_files);
if (protocol_version >= 31)
output_itemized_counts("Number of deleted files", &stats.deleted_files);
rprintf(FINFO,"Number of regular files transferred: %s\n",
comma_num(stats.xferred_files));
rprintf(FINFO,"Total file size: %s bytes\n",
human_num(stats.total_size));
rprintf(FINFO,"Total transferred file size: %s bytes\n",
@@ -258,11 +324,11 @@ static void output_summary(void)
human_num(stats.flist_size));
if (stats.flist_buildtime) {
rprintf(FINFO,
"File list generation time: %.3f seconds\n",
(double)stats.flist_buildtime / 1000);
"File list generation time: %s seconds\n",
comma_dnum((double)stats.flist_buildtime / 1000, 3));
rprintf(FINFO,
"File list transfer time: %.3f seconds\n",
(double)stats.flist_xfertime / 1000);
"File list transfer time: %s seconds\n",
comma_dnum((double)stats.flist_xfertime / 1000, 3));
}
rprintf(FINFO,"Total bytes sent: %s\n",
human_num(total_written));
@@ -270,15 +336,15 @@ static void output_summary(void)
human_num(total_read));
}
if (verbose || do_stats) {
if (INFO_GTE(STATS, 1)) {
rprintf(FCLIENT, "\n");
rprintf(FINFO,
"sent %s bytes received %s bytes %s bytes/sec\n",
human_num(total_written), human_num(total_read),
human_dnum((total_written + total_read)/(0.5 + (endtime - starttime)), 2));
rprintf(FINFO, "total size is %s speedup is %.2f%s\n",
rprintf(FINFO, "total size is %s speedup is %s%s\n",
human_num(stats.total_size),
(double)stats.total_size / (total_written+total_read),
comma_dnum((double)stats.total_size / (total_written+total_read), 2),
write_batch < 0 ? " (BATCH ONLY)" : dry_run ? " (DRY RUN)" : "");
}
@@ -299,7 +365,7 @@ static void show_malloc_stats(void)
rprintf(FCLIENT, "\n");
rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
getpid(), am_server ? "server " : "",
(int)getpid(), am_server ? "server " : "",
am_daemon ? "daemon " : "", who_am_i());
rprintf(FINFO, " arena: %10ld (bytes from sbrk)\n",
(long)mi.arena);
@@ -332,7 +398,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
int *f_in_p, int *f_out_p)
{
int i, argc = 0;
char *args[MAX_ARGS];
char *args[MAX_ARGS], *need_to_free = NULL;
pid_t pid;
int dash_l_set = 0;
@@ -343,7 +409,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
cmd = rsh_env;
if (!cmd)
cmd = RSYNC_RSH;
cmd = strdup(cmd); /* MEMORY LEAK */
cmd = need_to_free = strdup(cmd);
if (!cmd)
goto oom;
@@ -440,7 +506,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
args[argc] = NULL;
if (verbose > 3) {
if (DEBUG_GTE(CMD, 2)) {
for (i = 0; i < argc; i++)
rprintf(FCLIENT, "cmd[%d]=%s ", i, args[i]);
rprintf(FCLIENT, "\n");
@@ -479,6 +545,9 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
send_protected_args(*f_out_p, args);
}
if (need_to_free)
free(need_to_free);
return pid;
oom:
@@ -505,7 +574,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
int statret;
char *cp;
if (verbose > 2) {
if (DEBUG_GTE(RECV, 1)) {
rprintf(FINFO, "get_local_name count=%d %s\n",
file_total, NS(dest_path));
}
@@ -581,7 +650,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
exit_cleanup(RERR_SYNTAX);
}
if (mkdir_defmode(dest_path) != 0) {
if (do_mkdir(dest_path, ACCESSPERMS) != 0) {
rsyserr(FERROR, errno, "mkdir %s failed",
full_fname(dest_path));
exit_cleanup(RERR_FILEIO);
@@ -591,7 +660,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
&& strcmp(flist->files[flist->low]->basename, ".") == 0)
flist->files[0]->flags |= FLAG_DIR_CREATED;
if (verbose)
if (INFO_GTE(NAME, 1))
rprintf(FINFO, "created directory %s\n", dest_path);
if (dry_run) {
@@ -637,48 +706,63 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
static void check_alt_basis_dirs(void)
{
STRUCT_STAT st;
char **dir_p, *slash = strrchr(curr_dir, '/');
char *slash = strrchr(curr_dir, '/');
int j;
for (dir_p = basis_dir; *dir_p; dir_p++) {
if (dry_run > 1 && **dir_p != '/') {
int len = curr_dir_len + 1 + strlen(*dir_p) + 1;
for (j = 0; j < basis_dir_cnt; j++) {
char *bdir = basis_dir[j];
int bd_len = strlen(bdir);
if (bd_len > 1 && bdir[bd_len-1] == '/')
bdir[--bd_len] = '\0';
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(*dir_p, "../", 3) == 0) {
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:
* this ensures that any other ".." references get
* evaluated the same as they would for a live copy. */
*slash = '\0';
pathjoin(new, len, curr_dir, *dir_p + 3);
pathjoin(new, len, curr_dir, bdir + 3);
*slash = '/';
} else
pathjoin(new, len, curr_dir, *dir_p);
*dir_p = new;
}
if (do_stat(*dir_p, &st) < 0) {
rprintf(FWARNING, "%s arg does not exist: %s\n",
dest_option, *dir_p);
} else if (!S_ISDIR(st.st_mode)) {
rprintf(FWARNING, "%s arg is not a dir: %s\n",
dest_option, *dir_p);
pathjoin(new, len, curr_dir, bdir);
basis_dir[j] = bdir = new;
}
if (do_stat(bdir, &st) < 0)
rprintf(FWARNING, "%s arg does not exist: %s\n", dest_option, bdir);
else if (!S_ISDIR(st.st_mode))
rprintf(FWARNING, "%s arg is not a dir: %s\n", dest_option, bdir);
}
}
/* This is only called by the sender. */
static void read_final_goodbye(int f_in)
static void read_final_goodbye(int f_in, int f_out)
{
int i, iflags, xlen;
uchar fnamecmp_type;
char xname[MAXPATHLEN];
shutting_down = True;
if (protocol_version < 29)
i = read_int(f_in);
else {
i = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
xname, &xlen);
i = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type, xname, &xlen);
if (protocol_version >= 31 && i == NDX_DONE) {
if (am_sender)
write_ndx(f_out, NDX_DONE);
else {
if (batch_gen_fd >= 0) {
while (read_int(batch_gen_fd) != NDX_DEL_STATS) {}
read_del_stats(batch_gen_fd);
}
write_int(f_out, NDX_DONE);
}
i = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type, xname, &xlen);
}
}
if (i != NDX_DONE) {
@@ -693,17 +777,15 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
struct file_list *flist;
char *dir = argv[0];
if (verbose > 2) {
rprintf(FINFO, "server_sender starting pid=%ld\n",
(long)getpid());
}
if (DEBUG_GTE(SEND, 1))
rprintf(FINFO, "server_sender starting pid=%d\n", (int)getpid());
if (am_daemon && lp_write_only(module_id)) {
rprintf(FERROR, "ERROR: module is write only\n");
exit_cleanup(RERR_SYNTAX);
return;
}
if (am_daemon && lp_read_only(module_id) && remove_source_files) {
if (am_daemon && read_only && remove_source_files) {
rprintf(FERROR,
"ERROR: --remove-%s-files cannot be used with a read-only module\n",
remove_source_files == 1 ? "source" : "sent");
@@ -728,8 +810,12 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
}
flist = send_file_list(f_out,argc,argv);
if (!flist || flist->used == 0)
if (!flist || flist->used == 0) {
/* Make sure input buffering is off so we can't hang in noop_io_until_death(). */
io_end_buffering_in(0);
/* TODO: we should really exit in a more controlled manner. */
exit_cleanup(0);
}
io_start_buffering_in(f_in);
@@ -737,7 +823,7 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
io_flush(FULL_FLUSH);
handle_stats(f_out);
if (protocol_version >= 24)
read_final_goodbye(f_in);
read_final_goodbye(f_in, f_out);
io_flush(FULL_FLUSH);
exit_cleanup(0);
}
@@ -763,7 +849,17 @@ static int do_recv(int f_in, int f_out, char *local_name)
exit_cleanup(RERR_IPC);
}
io_flush(NORMAL_FLUSH);
if (backup_dir) {
int ret = make_path(backup_dir_buf, MKP_DROP_NAME); /* drops trailing slash */
if (ret < 0)
exit_cleanup(RERR_SYNTAX);
if (ret)
rprintf(FINFO, "Created backup_dir %s\n", backup_dir_buf);
else if (INFO_GTE(BACKUP, 1))
rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
}
io_flush(FULL_FLUSH);
if ((pid = do_fork()) == -1) {
rsyserr(FERROR, errno, "fork failed in do_recv");
@@ -772,38 +868,43 @@ static int do_recv(int f_in, int f_out, char *local_name)
if (pid == 0) {
am_receiver = 1;
send_msgs_to_gen = am_server;
close(error_pipe[0]);
/* We can't let two processes write to the socket at one time. */
io_end_multiplex_out(MPLX_SWITCHING);
if (f_in != f_out)
close(f_out);
sock_f_out = -1;
f_out = error_pipe[1];
/* we can't let two processes write to the socket at one time */
io_end_multiplex_out();
bwlimit_writemax = 0; /* receiver doesn't need to do this */
/* set place to send errors */
set_msg_fd_out(error_pipe[1]);
io_start_buffering_out(error_pipe[1]);
if (read_batch)
io_start_buffering_in(f_in);
io_start_multiplex_out(f_out);
recv_files(f_in, local_name);
recv_files(f_in, f_out, local_name);
io_flush(FULL_FLUSH);
handle_stats(f_in);
send_msg(MSG_DONE, "", 1, 0);
write_varlong(error_pipe[1], stats.total_read, 3);
if (output_needs_newline) {
fputc('\n', stdout);
output_needs_newline = 0;
}
write_int(f_out, NDX_DONE);
send_msg(MSG_STATS, (char*)&stats.total_read, sizeof stats.total_read, 0);
io_flush(FULL_FLUSH);
/* Handle any keep-alive packets from the post-processing work
* that the generator does. */
if (protocol_version >= 29) {
int iflags, xlen;
uchar fnamecmp_type;
char xname[MAXPATHLEN];
kluge_around_eof = -1;
/* This should only get stopped via a USR2 signal. */
read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
xname, &xlen);
read_final_goodbye(f_in, f_out);
rprintf(FERROR, "Invalid packet at end of run [%s]\n",
who_am_i());
@@ -818,19 +919,20 @@ static int do_recv(int f_in, int f_out, char *local_name)
}
am_generator = 1;
flist_receiving_enabled = True;
io_end_multiplex_in();
io_end_multiplex_in(MPLX_SWITCHING);
if (write_batch && !am_server)
stop_write_batch();
close(error_pipe[1]);
if (f_in != f_out)
close(f_in);
sock_f_in = -1;
f_in = error_pipe[0];
io_start_buffering_out(f_out);
set_msg_fd_in(error_pipe[0]);
io_start_buffering_in(error_pipe[0]);
io_start_multiplex_in(f_in);
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && inc_recurse) {
@@ -844,13 +946,13 @@ static int do_recv(int f_in, int f_out, char *local_name)
handle_stats(-1);
io_flush(FULL_FLUSH);
shutting_down = True;
if (protocol_version >= 24) {
/* send a final goodbye message */
write_ndx(f_out, NDX_DONE);
}
io_flush(FULL_FLUSH);
set_msg_fd_in(-1);
kill(pid, SIGUSR2);
wait_process_with_flush(pid, &exit_code);
return exit_code;
@@ -861,20 +963,20 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
int exit_code;
struct file_list *flist;
char *local_name = NULL;
int save_verbose = verbose;
int negated_levels;
if (filesfrom_fd >= 0) {
if (filesfrom_fd >= 0 && !msgs2stderr && protocol_version < 31) {
/* We can't mix messages with files-from data on the socket,
* so temporarily turn off verbose messages. */
verbose = 0;
}
* so temporarily turn off info/debug messages. */
negate_output_levels();
negated_levels = 1;
} else
negated_levels = 0;
if (verbose > 2) {
rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
argc, (long)getpid());
}
if (DEBUG_GTE(RECV, 1))
rprintf(FINFO, "server_recv(%d) starting pid=%d\n", argc, (int)getpid());
if (am_daemon && lp_read_only(module_id)) {
if (am_daemon && read_only) {
rprintf(FERROR,"ERROR: module is read only\n");
exit_cleanup(RERR_SYNTAX);
return;
@@ -892,7 +994,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
}
if (protocol_version >= 30)
io_start_multiplex_in();
io_start_multiplex_in(f_in);
else
io_start_buffering_in(f_in);
recv_filter_list(f_in);
@@ -903,7 +1005,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
* need the IO routines to automatically write out the names
* onto our f_out socket as we read the file-list. This
* avoids both deadlock and extra delays/buffers. */
io_set_filesfrom_fds(filesfrom_fd, f_out);
start_filesfrom_forwarding(filesfrom_fd);
filesfrom_fd = -1;
}
@@ -914,7 +1016,9 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
}
if (inc_recurse && file_total == 1)
recv_additional_file_list(f_in);
verbose = save_verbose;
if (negated_levels)
negate_output_levels();
if (argc > 0)
local_name = get_local_name(flist,argv[0]);
@@ -932,7 +1036,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
if (daemon_filter_list.head) {
char **dir_p;
struct filter_list_struct *elp = &daemon_filter_list;
filter_rule_list *elp = &daemon_filter_list;
for (dir_p = basis_dir; *dir_p; dir_p++) {
char *dir = *dir_p;
@@ -971,12 +1075,16 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
setup_protocol(f_out, f_in);
if (protocol_version >= 23)
io_start_multiplex_out();
io_start_multiplex_out(f_out);
if (am_daemon && io_timeout && protocol_version >= 31)
send_msg_int(MSG_IO_TIMEOUT, io_timeout);
if (am_sender) {
keep_dirlinks = 0; /* Must be disabled on the sender. */
if (need_messages_from_generator)
io_start_multiplex_in();
io_start_multiplex_in(f_in);
else
io_start_buffering_in(f_in);
recv_filter_list(f_in);
do_server_sender(f_in, f_out, argc, argv);
} else
@@ -984,11 +1092,8 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
exit_cleanup(0);
}
/*
* This is called once the connection has been negotiated. It is used
* for rsyncd, remote-shell, and local connections.
*/
/* This is called once the connection has been negotiated. It is used
* for rsyncd, remote-shell, and local connections. */
int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
{
struct file_list *flist = NULL;
@@ -1016,12 +1121,20 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
if (am_sender) {
keep_dirlinks = 0; /* Must be disabled on the sender. */
if (always_checksum
&& (log_format_has(stdout_format, 'C')
|| log_format_has(logfile_format, 'C')))
sender_keeps_checksum = 1;
if (protocol_version >= 30)
io_start_multiplex_out();
io_start_multiplex_out(f_out);
else
io_start_buffering_out(f_out);
if (!filesfrom_host)
set_msg_fd_in(f_in);
if (protocol_version >= 31 || (!filesfrom_host && protocol_version >= 23))
io_start_multiplex_in(f_in);
else
io_start_buffering_in(f_in);
send_filter_list(f_out);
if (filesfrom_host)
filesfrom_fd = f_in;
@@ -1029,20 +1142,20 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
if (write_batch && !am_server)
start_write_batch(f_out);
flist = send_file_list(f_out, argc, argv);
if (verbose > 3)
if (DEBUG_GTE(FLIST, 3))
rprintf(FINFO,"file list sent\n");
if (protocol_version >= 23)
io_start_multiplex_in();
if (protocol_version < 31 && filesfrom_host && protocol_version >= 23)
io_start_multiplex_in(f_in);
io_flush(NORMAL_FLUSH);
send_files(f_in, f_out);
io_flush(FULL_FLUSH);
handle_stats(-1);
if (protocol_version >= 24)
read_final_goodbye(f_in);
read_final_goodbye(f_in, f_out);
if (pid != -1) {
if (verbose > 3)
if (DEBUG_GTE(EXIT, 2))
rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
io_flush(FULL_FLUSH);
wait_process_with_flush(pid, &exit_code);
@@ -1054,15 +1167,17 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
if (!read_batch) {
if (protocol_version >= 23)
io_start_multiplex_in();
io_start_multiplex_in(f_in);
if (need_messages_from_generator)
io_start_multiplex_out();
io_start_multiplex_out(f_out);
else
io_start_buffering_out(f_out);
}
send_filter_list(read_batch ? -1 : f_out);
if (filesfrom_fd >= 0) {
io_set_filesfrom_fds(filesfrom_fd, f_out);
start_filesfrom_forwarding(filesfrom_fd);
filesfrom_fd = -1;
}
@@ -1084,7 +1199,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
}
if (pid != -1) {
if (verbose > 3)
if (DEBUG_GTE(RECV, 1))
rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
io_flush(FULL_FLUSH);
wait_process_with_flush(pid, &exit_code);
@@ -1109,14 +1224,12 @@ static int copy_argv(char *argv[])
}
/**
* Start a client for either type of remote connection. Work out
/* Start a client for either type of remote connection. Work out
* whether the arguments request a remote shell or rsyncd connection,
* and call the appropriate connection function, then run_client.
*
* Calls either start_socket_client (for sockets) or do_cmd and
* client_run (for ssh).
**/
* client_run (for ssh). */
static int start_client(int argc, char *argv[])
{
char *p, *shell_machine = NULL, *shell_user = NULL;
@@ -1203,6 +1316,9 @@ static int start_client(int argc, char *argv[])
remote_argc = argc = 1;
}
if (!rsync_port && remote_argc && !**remote_argv) /* Turn an empty arg into a dot dir. */
*remote_argv = ".";
if (am_sender) {
char *dummy_host;
int dummy_port = rsync_port;
@@ -1238,6 +1354,8 @@ static int start_client(int argc, char *argv[])
rprintf(FERROR, "All source args must use the same port number.\n");
exit_cleanup(RERR_SYNTAX);
}
if (!rsync_port && !*arg) /* Turn an empty arg into a dot dir. */
arg = ".";
remote_argv[i] = arg;
}
}
@@ -1266,10 +1384,10 @@ static int start_client(int argc, char *argv[])
}
}
if (verbose > 3) {
if (DEBUG_GTE(CMD, 2)) {
rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
NS(shell_cmd), NS(shell_machine), NS(shell_user),
remote_argv ? NS(remote_argv[0]) : "");
NS(remote_argv[0]));
}
pid = do_cmd(shell_cmd, shell_machine, shell_user, remote_argv, remote_argc,
@@ -1372,10 +1490,9 @@ const char *get_panic_action(void)
static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
{
char cmd_buf[300];
int ret;
int ret, pid_int = getpid();
snprintf(cmd_buf, sizeof cmd_buf, get_panic_action(),
getpid(), getpid());
snprintf(cmd_buf, sizeof cmd_buf, get_panic_action(), pid_int, pid_int);
/* Unless we failed to execute gdb, we allow the process to
* continue. I'm not sure if that's right. */
@@ -1411,6 +1528,7 @@ int main(int argc,char *argv[])
starttime = time(NULL);
our_uid = MY_UID();
our_gid = MY_GID();
am_root = our_uid == 0;
memset(&stats, 0, sizeof(stats));
@@ -1420,9 +1538,10 @@ int main(int argc,char *argv[])
exit_cleanup(RERR_SYNTAX);
}
/* we set a 0 umask so that correct file permissions can be
* carried across */
orig_umask = umask(0);
/* Get the umask for use in permission calculations. We no longer set
* it to zero; that is ugly and pointless now that all the callers that
* relied on it have been reeducated to work with default ACLs. */
umask(orig_umask = umask(0));
#if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
setlocale(LC_CTYPE, "");

133
match.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,13 +20,14 @@
*/
#include "rsync.h"
#include "inums.h"
extern int verbose;
extern int do_progress;
extern int checksum_seed;
extern int append_mode;
extern int checksum_len;
int updating_basis_file;
char sender_file_sum[MAX_DIGEST_LEN];
static int false_alarms;
static int hash_hits;
@@ -107,10 +108,10 @@ static void matched(int f, struct sum_struct *s, struct map_struct *buf,
int32 n = (int32)(offset - last_match); /* max value: block_size (int32) */
int32 j;
if (verbose > 2 && i >= 0) {
if (DEBUG_GTE(DELTASUM, 2) && i >= 0) {
rprintf(FINFO,
"match at %.0f last_match=%.0f j=%d len=%ld n=%ld\n",
(double)offset, (double)last_match, i,
"match at %s last_match=%s j=%d len=%ld n=%ld\n",
big_num(offset), big_num(last_match), i,
(long)s->sums[i].len, (long)n);
}
@@ -132,7 +133,7 @@ static void matched(int f, struct sum_struct *s, struct map_struct *buf,
else
last_match = offset;
if (buf && do_progress)
if (buf && INFO_GTE(PROGRESS, 1))
show_progress(last_match, buf->file_size);
}
@@ -151,9 +152,9 @@ static void hash_search(int f,struct sum_struct *s,
* coding of the output to work more efficiently. */
want_i = 0;
if (verbose > 2) {
rprintf(FINFO, "hash search b=%ld len=%.0f\n",
(long)s->blength, (double)len);
if (DEBUG_GTE(DELTASUM, 2)) {
rprintf(FINFO, "hash search b=%ld len=%s\n",
(long)s->blength, big_num(len));
}
k = (int32)MIN(len, (OFF_T)s->blength);
@@ -163,41 +164,55 @@ static void hash_search(int f,struct sum_struct *s,
sum = get_checksum1((char *)map, k);
s1 = sum & 0xFFFF;
s2 = sum >> 16;
if (verbose > 3)
if (DEBUG_GTE(DELTASUM, 3))
rprintf(FINFO, "sum=%.8x k=%ld\n", sum, (long)k);
offset = aligned_offset = aligned_i = 0;
end = len + 1 - s->sums[s->count-1].len;
if (verbose > 3) {
rprintf(FINFO, "hash search s->blength=%ld len=%.0f count=%.0f\n",
(long)s->blength, (double)len, (double)s->count);
if (DEBUG_GTE(DELTASUM, 3)) {
rprintf(FINFO, "hash search s->blength=%ld len=%s count=%s\n",
(long)s->blength, big_num(len), big_num(s->count));
}
do {
int done_csum2 = 0;
int32 i;
uint32 hash_entry;
int32 i, *prev;
if (verbose > 4) {
rprintf(FINFO, "offset=%.0f sum=%04x%04x\n",
(double)offset, s2 & 0xFFFF, s1 & 0xFFFF);
if (DEBUG_GTE(DELTASUM, 4)) {
rprintf(FINFO, "offset=%s sum=%04x%04x\n",
big_num(offset), s2 & 0xFFFF, s1 & 0xFFFF);
}
if (tablesize == TRADITIONAL_TABLESIZE) {
if ((i = hash_table[SUM2HASH2(s1,s2)]) < 0)
hash_entry = SUM2HASH2(s1,s2);
if ((i = hash_table[hash_entry]) < 0)
goto null_hash;
sum = (s1 & 0xffff) | (s2 << 16);
} else {
sum = (s1 & 0xffff) | (s2 << 16);
if ((i = hash_table[BIG_SUM2HASH(sum)]) < 0)
hash_entry = BIG_SUM2HASH(sum);
if ((i = hash_table[hash_entry]) < 0)
goto null_hash;
}
prev = &hash_table[hash_entry];
hash_hits++;
do {
int32 l;
/* When updating in-place, the chunk's offset must be
* either >= our offset or identical data at that offset.
* Remove any bypassed entries that we can never use. */
if (updating_basis_file && s->sums[i].offset < offset
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET)) {
*prev = s->sums[i].chain;
continue;
}
prev = &s->sums[i].chain;
if (sum != s->sums[i].sum1)
continue;
@@ -206,16 +221,10 @@ static void hash_search(int f,struct sum_struct *s,
if (l != s->sums[i].len)
continue;
/* in-place: ensure chunk's offset is either >= our
* offset or that the data didn't move. */
if (updating_basis_file && s->sums[i].offset < offset
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET))
continue;
if (verbose > 3) {
if (DEBUG_GTE(DELTASUM, 3)) {
rprintf(FINFO,
"potential match at %.0f i=%ld sum=%08x\n",
(double)offset, (long)i, sum);
"potential match at %s i=%ld sum=%08x\n",
big_num(offset), (long)i, sum);
}
if (!done_csum2) {
@@ -238,7 +247,9 @@ static void hash_search(int f,struct sum_struct *s,
aligned_offset += s->blength;
aligned_i++;
}
if (offset == aligned_offset && aligned_i < s->count) {
if ((offset == aligned_offset
|| (sum == 0 && l == s->blength && aligned_offset + l <= len))
&& aligned_i < s->count) {
if (i != aligned_i) {
if (sum != s->sums[aligned_i].sum1
|| l != s->sums[aligned_i].len
@@ -246,6 +257,27 @@ static void hash_search(int f,struct sum_struct *s,
goto check_want_i;
i = aligned_i;
}
if (offset != aligned_offset) {
/* We've matched some zeros in a spot that is also zeros
* further along in the basis file, if we find zeros ahead
* in the sender's file, we'll output enough literal data
* to re-align with the basis file, and get back to seeking
* instead of writing. */
backup = (int32)(aligned_offset - last_match);
if (backup < 0)
backup = 0;
map = (schar *)map_ptr(buf, aligned_offset - backup, l + backup)
+ backup;
sum = get_checksum1((char *)map, l);
if (sum != s->sums[i].sum1)
goto check_want_i;
get_checksum2((char *)map, l, sum2);
if (memcmp(sum2, s->sums[i].sum2, s->s2length) != 0)
goto check_want_i;
/* OK, we have a re-alignment match. Bump the offset
* forward to the new match point. */
offset = aligned_offset;
}
/* This identical chunk is in the same spot in the old and new file. */
s->sums[i].flags |= SUMFLG_SAME_OFFSET;
want_i = i;
@@ -328,9 +360,6 @@ static void hash_search(int f,struct sum_struct *s,
**/
void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
{
char file_sum[MAX_DIGEST_LEN];
int sum_len;
last_match = 0;
false_alarms = 0;
hash_hits = 0;
@@ -343,7 +372,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
if (append_mode == 2) {
OFF_T j = 0;
for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
if (buf && do_progress)
if (buf && INFO_GTE(PROGRESS, 1))
show_progress(last_match, buf->file_size);
sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
CHUNK_SIZE);
@@ -351,7 +380,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
}
if (last_match < s->flength) {
int32 n = (int32)(s->flength - last_match);
if (buf && do_progress)
if (buf && INFO_GTE(PROGRESS, 1))
show_progress(last_match, buf->file_size);
sum_update(map_ptr(buf, last_match, n), n);
}
@@ -363,12 +392,12 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
if (len > 0 && s->count > 0) {
build_hash_table(s);
if (verbose > 2)
if (DEBUG_GTE(DELTASUM, 2))
rprintf(FINFO,"built hash table\n");
hash_search(f, s, buf, len);
if (verbose > 2)
if (DEBUG_GTE(DELTASUM, 2))
rprintf(FINFO,"done hash search\n");
} else {
OFF_T j;
@@ -378,18 +407,28 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
matched(f, s, buf, len, -1);
}
sum_len = sum_end(file_sum);
/* If we had a read error, send a bad checksum. */
if (buf && buf->status != 0)
file_sum[0]++;
if (sum_end(sender_file_sum) != checksum_len)
overflow_exit("checksum_len"); /* Impossible... */
if (verbose > 2)
/* If we had a read error, send a bad checksum. We use all bits
* off as long as the checksum doesn't happen to be that, in
* which case we turn the last 0 bit into a 1. */
if (buf && buf->status != 0) {
int i;
for (i = 0; i < checksum_len && sender_file_sum[i] == 0; i++) {}
memset(sender_file_sum, 0, checksum_len);
if (i == checksum_len)
sender_file_sum[i-1]++;
}
if (DEBUG_GTE(DELTASUM, 2))
rprintf(FINFO,"sending file_sum\n");
write_buf(f, file_sum, sum_len);
write_buf(f, sender_file_sum, checksum_len);
if (verbose > 2)
if (DEBUG_GTE(DELTASUM, 2)) {
rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
false_alarms, hash_hits, matches);
}
total_hash_hits += hash_hits;
total_false_alarms += false_alarms;
@@ -399,11 +438,11 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
void match_report(void)
{
if (verbose <= 1)
if (!DEBUG_GTE(DELTASUM, 1))
return;
rprintf(FINFO,
"total: matches=%d hash_hits=%d false_alarms=%d data=%.0f\n",
"total: matches=%d hash_hits=%d false_alarms=%d data=%s\n",
total_matches, total_hash_hits, total_false_alarms,
(double)stats.literal_data);
big_num(stats.literal_data));
}

795
options.c
View File

File diff suppressed because it is too large Load Diff

180
packaging/branch-from-patch Executable file
View File

@@ -0,0 +1,180 @@
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
&Getopt::Long::Configure('bundling');
&usage if !&GetOptions(
'branch|b=s' => \( my $master_branch = 'master' ),
'skip-check' => \( my $skip_branch_check ),
'delete' => \( my $delete_local_branches ),
'help|h' => \( my $help_opt ),
);
&usage if $help_opt;
require 'packaging/git-status.pl';
check_git_state($master_branch, !$skip_branch_check, 1);
my %local_branch;
open PIPE, '-|', 'git branch -l' or die "Unable to fork: $!\n";
while (<PIPE>) {
if (m# patch/\Q$master_branch\E/(.*)#o) {
$local_branch{$1} = 1;
}
}
close PIPE;
if ($delete_local_branches) {
foreach my $name (sort keys %local_branch) {
my $branch = "patch/$master_branch/$name";
system 'git', 'branch', '-D', $branch and exit 1;
}
%local_branch = ( );
}
my @patch_list;
foreach (@ARGV) {
if (!-f $_) {
die "File not found: $_\n";
}
die "Filename is not a .diff file: $_\n" unless /\.diff$/;
push @patch_list, $_;
}
exit unless @patch_list;
my(%scanned, %created, %info);
foreach my $patch (@patch_list) {
my($where, $name) = $patch =~ m{^(.*?)([^/]+)\.diff$};
next if $scanned{$name}++;
open IN, '<', $patch or die "Unable to open $patch: $!\n";
my $info = '';
my $commit;
while (<IN>) {
if (m#^based-on: (\S+)#) {
$commit = $1;
last;
}
last if m#^index .*\.\..* \d#;
last if m#^diff --git #;
last if m#^--- (old|a)/#;
$info .= $_;
}
close IN;
$info =~ s/\s+\Z/\n/;
my $parent = $master_branch;
my @patches = $info =~ m#patch -p1 <patches/(\S+)\.diff#g;
if (@patches) {
if ($patches[-1] eq $name) {
pop @patches;
} else {
warn "No identity patch line in $patch\n";
}
if (@patches) {
$parent = pop @patches;
if (!$scanned{$parent}) {
unless (-f "$where$parent.diff") {
die "Unknown parent of $patch: $parent\n";
}
# Add parent to @patch_list so that we will look for the
# parent's parent. Any duplicates will just be ignored.
push @patch_list, "$where$parent.diff";
}
}
} else {
warn "No patch lines found in $patch\n";
}
$info{$name} = [ $parent, $info, $commit ];
}
foreach my $patch (@patch_list) {
create_branch($patch);
}
system 'git', 'checkout', $master_branch and exit 1;
exit;
sub create_branch
{
my($patch) = @_;
my($where, $name) = $patch =~ m{^(.*?)([^/]+)\.diff$};
return if $created{$name}++;
my $ref = $info{$name};
my($parent, $info, $commit) = @$ref;
my $parent_branch;
if ($parent eq $master_branch) {
$parent_branch = $master_branch;
$parent_branch = $commit if defined $commit;
} else {
create_branch("$where/$parent.diff");
$parent_branch = "patch/$master_branch/$parent";
}
my $branch = "patch/$master_branch/$name";
print "\n", '=' x 64, "\nProcessing $branch ($parent_branch)\n";
if ($local_branch{$name}) {
system 'git', 'branch', '-D', $branch and exit 1;
}
system 'git', 'checkout', '-b', $branch, $parent_branch and exit 1;
open OUT, '>', "PATCH.$name" or die $!;
print OUT $info;
close OUT;
system 'git', 'add', "PATCH.$name" and exit 1;
open IN, '<', $patch or die "Unable to open $patch: $!\n";
$_ = join('', <IN>);
close IN;
open PIPE, '|-', 'patch -p1' or die $!;
print PIPE $_;
close PIPE;
system 'rm -f *.orig */*.orig';
while (m#\nnew file mode (\d+)\s+--- /dev/null\s+\Q+++\E b/(.*)#g) {
chmod oct($1), $2;
system 'git', 'add', $2;
}
while (1) {
system 'git status';
print 'Press Enter to commit, Ctrl-C to abort, or type a wild-name to add a new file: ';
$_ = <STDIN>;
last if /^$/;
chomp;
system "git add $_";
}
while (system 'git', 'commit', '-a', '-m', "Creating branch from $name.diff.") {
exit 1 if system '/bin/zsh';
}
}
sub usage
{
die <<EOT;
Usage branch-from-patch [OPTIONS] patches/DIFF...
Options:
-b, --branch=BRANCH Create branches relative to BRANCH if no "based-on"
header was found in the patch file.
--skip-check Skip the check that ensures starting with a clean branch.
--delete Delete all the local patch/BASE/* branches, not just the ones
that are being recreated.
-h, --help Output this help message.
EOT
}

View File

@@ -6,25 +6,28 @@ sub check_git_state
my($master_branch, $fatal_unless_clean, $check_patches_dir) = @_;
my($cur_branch) = check_git_status($fatal_unless_clean);
if ($cur_branch ne $master_branch) {
(my $branch = $cur_branch) =~ s{^patch/([^/]+)/[^/]+$}{$1}; # change patch/BRANCH/PATCH_NAME into BRANCH
if ($branch ne $master_branch) {
print "The checkout is not on the $master_branch branch.\n";
exit 1 if $master_branch ne 'master';
print "Do you want me to continue with --branch=$cur_branch? [n] ";
print "Do you want me to continue with --branch=$branch? [n] ";
$_ = <STDIN>;
exit 1 unless /^y/i;
$_[0] = $master_branch = $cur_branch; # Updates caller's $master_branch too.
$_[0] = $master_branch = $branch; # Updates caller's $master_branch too.
}
if ($check_patches_dir && -d 'patches/.git') {
($cur_branch) = check_git_status($fatal_unless_clean, 'patches');
if ($cur_branch ne $master_branch) {
print "The *patches* checkout is on branch $cur_branch, not branch $master_branch.\n";
($branch) = check_git_status($fatal_unless_clean, 'patches');
if ($branch ne $master_branch) {
print "The *patches* checkout is on branch $branch, not branch $master_branch.\n";
print "Do you want to change it to branch $master_branch? [n] ";
$_ = <STDIN>;
exit 1 unless /^y/i;
system "cd patches && git checkout '$master_branch'";
}
}
return $cur_branch;
}
sub check_git_status

View File

@@ -1,6 +1,6 @@
Summary: A fast, versatile, remote (and local) file-copying tool
Name: rsync
Version: 3.0.9
Version: 3.1.0
%define fullversion %{version}
Release: 1
%define srcdir src
@@ -13,6 +13,14 @@ Prefix: %{_prefix}
BuildRoot: /var/tmp/%{name}-root
License: GPL
%package ssl-client
Summary: Provides rsync-ssl
Requires: stunnel >= 4
%package ssl-daemon
Summary: An stunnel config file to support ssl rsync daemon connections.
Requires: stunnel >= 4
%description
Rsync is a fast and extraordinarily versatile file copying tool. It can
copy locally, to/from another host over any remote shell, or to/from a
@@ -24,12 +32,22 @@ differences between the source files and the existing files in the
destination. Rsync is widely used for backups and mirroring and as an
improved copy command for everyday use.
%description ssl-client
Provides the rsync-ssl script that makes use of stunnel 4 to open an ssl
connection to an rsync daemon (on port 874). This setup does NOT require
any local stunnel daemon to be running to connect to the remote ssl rsyncd.
%description ssl-daemon
Provides a config file for stunnel that will (if you start your stunnel
service) cause stunnel to listen for ssl rsync-daemon connections and run
"rsync --daemon" to handle them.
%prep
# Choose one -- setup source only, or setup source + rsync-patches:
%setup -q -n rsync-%{fullversion}
#%setup -q -b1 -n rsync-%{fullversion}
# If you you used "%setup -q -b1", choose the patches you wish to apply:
# If you you used "%setup -q -b1 ...", choose the patches you wish to apply:
#patch -p1 <patches/acls.diff
#patch -p1 <patches/xattrs.diff
#patch -p1 <patches/remote-option.diff
@@ -46,14 +64,11 @@ make
%install
rm -rf $RPM_BUILD_ROOT
make install install-ssl-client install-ssl-daemon DESTDIR=$RPM_BUILD_ROOT
%makeinstall
mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d
mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d $RPM_BUILD_ROOT/etc/rsync-ssl/certs
install -m 644 packaging/lsb/rsync.xinetd $RPM_BUILD_ROOT/etc/xinetd.d/rsync
#install -p -m 755 support/rsyncdb $RPM_BUILD_ROOT/usr/bin/rsyncdb
%clean
rm -rf $RPM_BUILD_ROOT
@@ -61,13 +76,21 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root)
%doc COPYING NEWS OLDNEWS README support/ tech_report.tex
%config(noreplace) /etc/xinetd.d/rsync
%{_prefix}/bin/rsync*
%{_prefix}/bin/rsync
%{_mandir}/man1/rsync.1*
%{_mandir}/man5/rsyncd.conf.5*
%files ssl-client
%{_prefix}/bin/rsync-ssl
%{_prefix}/bin/stunnel-rsync
%files ssl-daemon
%config(noreplace) /etc/stunnel/rsyncd.conf
%dir /etc/rsync-ssl/certs
%changelog
* Fri Sep 23 2011 Wayne Davison <wayned@samba.org>
Released 3.0.9.
* Sat Sep 28 2013 Wayne Davison <wayned@samba.org>
Released 3.1.0.
* Fri Mar 21 2008 Wayne Davison <wayned@samba.org>
Added installation of /etc/xinetd.d/rsync file and some commented-out

View File

@@ -32,7 +32,7 @@ die "No '$patches_dir' directory was found.\n" unless -d $patches_dir;
die "No '.git' directory present in the current dir.\n" unless -d '.git';
require 'packaging/git-status.pl';
check_git_state($master_branch, !$skip_branch_check, 1);
my $starting_branch = check_git_state($master_branch, !$skip_branch_check, 1);
my $master_commit;
open PIPE, '-|', "git log -1 --no-color $master_branch" or die $!;
@@ -124,7 +124,7 @@ if ($incl_generated_files) {
}
sleep 1 while $last_touch >= time;
system "git checkout $master_branch" and exit 1;
system "git checkout $starting_branch" and exit 1;
exit;

View File

@@ -278,7 +278,7 @@ system "packaging/patch-update --branch=$master_branch";
if ($ans =~ /^y/i) {
print "\nVisiting all \"patch/$master_branch/*\" branches ...\n";
system "packaging/patch-update --branch=$master_branch --shell";
system "packaging/patch-update --branch=$master_branch --skip-check --shell";
}
if (-d 'patches/.git') {

159
params.c
View File

@@ -75,6 +75,7 @@
#include "rsync.h"
#include "ifuncs.h"
#include "itypes.h"
/* -------------------------------------------------------------------------- **
* Constants...
@@ -93,6 +94,8 @@
static char *bufr = NULL;
static int bSize = 0;
static BOOL (*the_sfunc)(char *);
static BOOL (*the_pfunc)(char *, char *);
/* -------------------------------------------------------------------------- **
* Functions...
@@ -223,7 +226,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
bufr[end] = '\0';
if( 0 == end ) /* Don't allow an empty name. */
{
rprintf(FLOG, "%s Empty section name in configuration file.\n", func );
rprintf(FLOG, "%s Empty section name in config file.\n", func );
return( False );
}
if( !sfunc( bufr ) ) /* Got a valid name. Deal with it. */
@@ -236,7 +239,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
if( i < 0 )
{
bufr[end] = '\0';
rprintf(FLOG, "%s Badly formed line in configuration file: %s\n",
rprintf(FLOG, "%s Badly formed line in config file: %s\n",
func, bufr );
return( False );
}
@@ -261,7 +264,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
}
/* We arrive here if we've met the EOF before the closing bracket. */
rprintf(FLOG, "%s Unexpected EOF in the configuration file: %s\n", func, bufr );
rprintf(FLOG, "%s Unexpected EOF in the config file: %s\n", func, bufr );
return( False );
} /* Section */
@@ -315,13 +318,12 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
case '=': /* Equal sign marks end of param name. */
if( 0 == end ) /* Don't allow an empty name. */
{
rprintf(FLOG, "%s Invalid parameter name in config. file.\n", func );
rprintf(FLOG, "%s Invalid parameter name in config file.\n", func );
return( False );
}
bufr[end++] = '\0'; /* Mark end of string & advance. */
i = end; /* New string starts here. */
vstart = end; /* New string is parameter value. */
bufr[i] = '\0'; /* New string is nul, for now. */
i = vstart = end; /* New string starts here. */
c = EatWhitespace(InFile);
break;
case '\n': /* Find continuation char, else error. */
@@ -329,7 +331,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
if( i < 0 )
{
bufr[end] = '\0';
rprintf(FLOG, "%s Ignoring badly formed line in configuration file: %s\n",
rprintf(FLOG, "%s Ignoring badly formed line in config file: %s\n",
func, bufr );
return( True );
}
@@ -343,6 +345,19 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
rprintf(FLOG, "%s Unexpected end-of-file at: %s\n", func, bufr );
return( True );
case ' ':
case '\t':
/* A directive divides at the first space or tab. */
if (*bufr == '&') {
bufr[end++] = '\0';
i = vstart = end;
c = EatWhitespace(InFile);
if (c == '=')
c = EatWhitespace(InFile);
break;
}
/* FALL THROUGH */
default:
if( isspace( c ) ) /* One ' ' per whitespace region. */
{
@@ -360,7 +375,6 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
}
/* Now parse the value. */
c = EatWhitespace( InFile ); /* Again, trim leading whitespace. */
while( (EOF !=c) && (c > 0) )
{
@@ -406,7 +420,88 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
return( pfunc( bufr, &bufr[vstart] ) ); /* Pass name & value to pfunc(). */
} /* Parameter */
static BOOL Parse( FILE *InFile,
static int name_cmp(const void *n1, const void *n2)
{
return strcmp(*(char * const *)n1, *(char * const *)n2);
}
static int include_config(char *include, int manage_globals)
{
STRUCT_STAT sb;
char *match = manage_globals ? "*.conf" : "*.inc";
int ret;
if (do_stat(include, &sb) < 0) {
rsyserr(FLOG, errno, "unable to stat config file \"%s\"", include);
return 0;
}
if (S_ISREG(sb.st_mode)) {
if (manage_globals && the_sfunc)
the_sfunc("]push");
ret = pm_process(include, the_sfunc, the_pfunc);
if (manage_globals && the_sfunc)
the_sfunc("]pop");
} else if (S_ISDIR(sb.st_mode)) {
char buf[MAXPATHLEN], **bpp;
item_list conf_list;
struct dirent *di;
size_t j;
DIR *d;
if (!(d = opendir(include))) {
rsyserr(FLOG, errno, "unable to open config dir \"%s\"", include);
return 0;
}
memset(&conf_list, 0, sizeof conf_list);
while ((di = readdir(d)) != NULL) {
char *dname = d_name(di);
if (!wildmatch(match, dname))
continue;
bpp = EXPAND_ITEM_LIST(&conf_list, char *, 32);
pathjoin(buf, sizeof buf, include, dname);
*bpp = strdup(buf);
}
closedir(d);
if (!(bpp = conf_list.items))
return 1;
if (conf_list.count > 1)
qsort(bpp, conf_list.count, sizeof (char *), name_cmp);
for (j = 0, ret = 1; j < conf_list.count; j++) {
if (manage_globals && the_sfunc)
the_sfunc(j == 0 ? "]push" : "]reset");
if ((ret = pm_process(bpp[j], the_sfunc, the_pfunc)) != 1)
break;
}
if (manage_globals && the_sfunc)
the_sfunc("]pop");
for (j = 0; j < conf_list.count; j++)
free(bpp[j]);
free(bpp);
} else
ret = 0;
return ret;
}
static int parse_directives(char *name, char *val)
{
if (strcasecmp(name, "&include") == 0)
return include_config(val, 1);
if (strcasecmp(name, "&merge") == 0)
return include_config(val, 0);
rprintf(FLOG, "Unknown directive: %s.\n", name);
return 0;
}
static int Parse( FILE *InFile,
BOOL (*sfunc)(char *),
BOOL (*pfunc)(char *, char *) )
/* ------------------------------------------------------------------------ **
@@ -418,7 +513,8 @@ static BOOL Parse( FILE *InFile,
* pfunc - Function to be called when a parameter is scanned.
* See Parameter().
*
* Output: True if the file was successfully scanned, else False.
* Output: 1 if the file was successfully scanned, 2 if the file was
* scanned until a section header with no section function, else 0.
*
* Notes: The input can be viewed in terms of 'lines'. There are four
* types of lines:
@@ -427,7 +523,7 @@ static BOOL Parse( FILE *InFile,
* The remainder of the line is ignored.
* Section - First non-whitespace character is a '['.
* Parameter - The default case.
*
*
* ------------------------------------------------------------------------ **
*/
{
@@ -448,29 +544,39 @@ static BOOL Parse( FILE *InFile,
break;
case '[': /* Section Header. */
if (!sfunc) return True;
if( !Section( InFile, sfunc ) )
return( False );
c = EatWhitespace( InFile );
break;
if (!sfunc)
return 2;
if( !Section( InFile, sfunc ) )
return 0;
c = EatWhitespace( InFile );
break;
case '\\': /* Bogus backslash. */
c = EatWhitespace( InFile );
break;
case '&': /* Handle directives */
the_sfunc = sfunc;
the_pfunc = pfunc;
c = Parameter( InFile, parse_directives, c );
if (c != 1)
return c;
c = EatWhitespace( InFile );
break;
default: /* Parameter line. */
if( !Parameter( InFile, pfunc, c ) )
return( False );
return 0;
c = EatWhitespace( InFile );
break;
}
}
return( True );
return 1;
} /* Parse */
static FILE *OpenConfFile( char *FileName )
/* ------------------------------------------------------------------------ **
* Open a configuration file.
* Open a config file.
*
* Input: FileName - The pathname of the config file to be opened.
*
@@ -485,21 +591,21 @@ static FILE *OpenConfFile( char *FileName )
if( NULL == FileName || 0 == *FileName )
{
rprintf(FLOG, "%s No configuration filename specified.\n", func);
rprintf(FLOG, "%s No config filename specified.\n", func);
return( NULL );
}
OpenedFile = fopen( FileName, "r" );
if( NULL == OpenedFile )
{
rsyserr(FLOG, errno, "unable to open configuration file \"%s\"",
rsyserr(FLOG, errno, "unable to open config file \"%s\"",
FileName);
}
return( OpenedFile );
} /* OpenConfFile */
BOOL pm_process( char *FileName,
int pm_process( char *FileName,
BOOL (*sfunc)(char *),
BOOL (*pfunc)(char *, char *) )
/* ------------------------------------------------------------------------ **
@@ -511,7 +617,8 @@ BOOL pm_process( char *FileName,
* pfunc - A pointer to a function that will be called when
* a parameter name and value are discovered.
*
* Output: TRUE if the file was successfully parsed, else FALSE.
* Output: 1 if the file was successfully parsed, 2 if parsing ended at a
* section header w/o a section function, else 0.
*
* ------------------------------------------------------------------------ **
*/
@@ -549,10 +656,10 @@ BOOL pm_process( char *FileName,
if( !result ) /* Generic failure. */
{
rprintf(FLOG, "%s Failed. Error returned from params.c:parse().\n", func);
return( False );
return 0;
}
return( True ); /* Generic success. */
return result;
} /* pm_process */
/* -------------------------------------------------------------------------- */

19
pipe.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2004-2009 Wayne Davison
* Copyright (C) 2004-2013 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
@@ -26,8 +26,10 @@ extern int am_sender;
extern int am_server;
extern int blocking_io;
extern int filesfrom_fd;
extern mode_t orig_umask;
extern int munge_symlinks;
extern char *logfile_name;
extern int remote_option_cnt;
extern const char **remote_options;
extern struct chmod_mode_struct *chmod_modes;
/**
@@ -49,7 +51,7 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
int to_child_pipe[2];
int from_child_pipe[2];
if (verbose >= 2)
if (DEBUG_GTE(CMD, 1))
print_child_argv("opening connection using:", command);
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
@@ -75,7 +77,6 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
close(to_child_pipe[0]);
if (from_child_pipe[1] != STDOUT_FILENO)
close(from_child_pipe[1]);
umask(orig_umask);
set_blocking(STDIN_FILENO);
if (blocking_io > 0)
set_blocking(STDOUT_FILENO);
@@ -131,6 +132,7 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
am_sender = 0;
am_server = 1;
filesfrom_fd = -1;
munge_symlinks = 0; /* Each side needs its own option. */
chmod_modes = NULL; /* Let the sending side handle this. */
/* Let the client side handle this. */
@@ -139,6 +141,15 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
logfile_close();
}
if (remote_option_cnt) {
int rc = remote_option_cnt + 1;
const char **rv = remote_options;
if (!parse_arguments(&rc, &rv)) {
option_error();
exit_cleanup(RERR_SYNTAX);
}
}
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
close(from_child_pipe[0]) < 0 ||

View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,9 +21,12 @@
*/
#include "rsync.h"
#include "inums.h"
extern int am_server;
extern int flist_eof;
extern int need_unsorted_flist;
extern int output_needs_newline;
extern struct stats stats;
extern struct file_list *cur_flist;
@@ -40,8 +43,6 @@ struct progress_history {
OFF_T ofs;
};
int progress_is_active = 0;
static struct progress_history ph_start;
static struct progress_history ph_list[PROGRESS_HISTORY_SECS];
static int newest_hpos, oldest_hpos;
@@ -66,11 +67,26 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
{
char rembuf[64], eol[128];
const char *units;
int pct = ofs == size ? 100 : (int) (100.0 * ofs / size);
unsigned long diff;
double rate, remain;
int pct;
if (is_last) {
int len = snprintf(eol, sizeof eol,
" (xfr#%d, %s-chk=%d/%d)\n",
stats.xferred_files, flist_eof ? "to" : "ir",
stats.num_files - current_file_index - 1,
stats.num_files);
if (INFO_GTE(PROGRESS, 2)) {
static int last_len = 0;
/* Drop \n and pad with spaces if line got shorter. */
if (last_len < --len)
last_len = len;
eol[last_len] = '\0';
while (last_len > len)
eol[--last_len] = ' ';
is_last = 0;
}
/* Compute stats based on the starting info. */
if (!ph_start.time.tv_sec
|| !(diff = msdiff(&ph_start.time, now)))
@@ -79,6 +95,7 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
/* Switch to total time taken for our last update. */
remain = (double) diff / 1000.0;
} else {
strlcpy(eol, " ", sizeof eol);
/* Compute stats based on recent progress. */
if (!(diff = msdiff(&ph_list[oldest_hpos].time, now)))
diff = 1;
@@ -106,23 +123,21 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
(int) remain % 60);
}
if (is_last) {
snprintf(eol, sizeof eol, " (xfer#%d, to-check=%d/%d)\n",
stats.num_transferred_files,
stats.num_files - current_file_index - 1,
stats.num_files);
} else
strlcpy(eol, "\r", sizeof eol);
progress_is_active = 0;
rprintf(FCLIENT, "%12s %3d%% %7.2f%s %s%s",
output_needs_newline = 0;
pct = ofs == size ? 100 : (int) (100.0 * ofs / size);
rprintf(FCLIENT, "\r%15s %3d%% %7.2f%s %s%s",
human_num(ofs), pct, rate, units, rembuf, eol);
if (!is_last)
progress_is_active = 1;
if (!is_last) {
output_needs_newline = 1;
rflush(FCLIENT);
}
}
void set_current_file_index(struct file_struct *file, int ndx)
{
if (need_unsorted_flist)
if (!file)
current_file_index = cur_flist->used + cur_flist->ndx_start - 1;
else if (need_unsorted_flist)
current_file_index = flist_find(cur_flist, file) + cur_flist->ndx_start;
else
current_file_index = ndx;
@@ -134,9 +149,14 @@ void end_progress(OFF_T size)
if (!am_server) {
struct timeval now;
gettimeofday(&now, NULL);
rprint_progress(size, size, &now, True);
if (INFO_GTE(PROGRESS, 2)) {
rprint_progress(stats.total_transferred_size,
stats.total_size, &now, True);
} else {
rprint_progress(size, size, &now, True);
memset(&ph_start, 0, sizeof ph_start);
}
}
memset(&ph_start, 0, sizeof ph_start);
}
void show_progress(OFF_T ofs, OFF_T size)
@@ -192,5 +212,9 @@ void show_progress(OFF_T ofs, OFF_T size)
return;
#endif
rprint_progress(ofs, size, &now, False);
if (INFO_GTE(PROGRESS, 2)) {
rprint_progress(stats.total_transferred_size,
stats.total_size, &now, False);
} else
rprint_progress(ofs, size, &now, False);
}

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,13 +20,12 @@
*/
#include "rsync.h"
#include "inums.h"
extern int verbose;
extern int dry_run;
extern int do_xfers;
extern int am_root;
extern int am_server;
extern int do_progress;
extern int inc_recurse;
extern int log_before_transfer;
extern int stdout_format_has_i;
@@ -46,17 +45,21 @@ extern int cleanup_got_literal;
extern int remove_source_files;
extern int append_mode;
extern int sparse_files;
extern int preallocate_files;
extern int keep_partial;
extern int checksum_len;
extern int checksum_seed;
extern int inplace;
extern int allowed_lull;
extern int delay_updates;
extern mode_t orig_umask;
extern struct stats stats;
extern char *tmpdir;
extern char *partial_dir;
extern char *basis_dir[MAX_BASIS_DIRS+1];
extern char sender_file_sum[MAX_DIGEST_LEN];
extern struct file_list *cur_flist, *first_flist, *dir_flist;
extern struct filter_list_struct daemon_filter_list;
extern filter_rule_list daemon_filter_list;
static struct bitbag *delayed_bits = NULL;
static int phase = 0, redoing = 0;
@@ -66,6 +69,8 @@ static int updating_basis_or_equiv;
#define TMPNAME_SUFFIX ".XXXXXX"
#define TMPNAME_SUFFIX_LEN ((int)sizeof TMPNAME_SUFFIX - 1)
#define MAX_UNIQUE_NUMBER 999999
#define MAX_UNIQUE_LOOP 100
/* get_tmpname() - create a tmp filename for a given filename
*
@@ -79,12 +84,17 @@ static int updating_basis_or_equiv;
* the basename basically becomes 8 characters longer. In such a case, the
* original name is shortened sufficiently to make it all fit.
*
* If the make_unique arg is True, the XXXXXX string is replaced with a unique
* string that doesn't exist at the time of the check. This is intended to be
* used for creating hard links, symlinks, devices, and special files, since
* normal files should be handled by mkstemp() for safety.
*
* Of course, the only reason the file is based on the original name is to
* make it easier to figure out what purpose a temp file is serving when a
* transfer is in progress. */
int get_tmpname(char *fnametmp, const char *fname)
int get_tmpname(char *fnametmp, const char *fname, BOOL make_unique)
{
int maxname, added, length = 0;
int maxname, length = 0;
const char *f;
char *suf;
@@ -103,6 +113,8 @@ int get_tmpname(char *fnametmp, const char *fname)
}
} else
f = fname;
if (*f == '.') /* avoid an extra leading dot for OS X's sake */
f++;
fnametmp[length++] = '.';
/* The maxname value is bufsize, and includes space for the '\0'.
@@ -110,26 +122,56 @@ int get_tmpname(char *fnametmp, const char *fname)
maxname = MIN(MAXPATHLEN - length - TMPNAME_SUFFIX_LEN,
NAME_MAX - 1 - TMPNAME_SUFFIX_LEN);
if (maxname < 1) {
if (maxname < 0) {
rprintf(FERROR_XFER, "temporary filename too long: %s\n", fname);
fnametmp[0] = '\0';
return 0;
}
added = strlcpy(fnametmp + length, f, maxname);
if (added >= maxname)
added = maxname - 1;
suf = fnametmp + length + added;
if (maxname) {
int added = strlcpy(fnametmp + length, f, maxname);
if (added >= maxname)
added = maxname - 1;
suf = fnametmp + length + added;
/* Trim any dangling high-bit chars if the first-trimmed char (if any) is
* also a high-bit char, just in case we cut into a multi-byte sequence.
* We are guaranteed to stop because of the leading '.' we added. */
if ((int)f[added] & 0x80) {
while ((int)suf[-1] & 0x80)
/* Trim any dangling high-bit chars if the first-trimmed char (if any) is
* also a high-bit char, just in case we cut into a multi-byte sequence.
* We are guaranteed to stop because of the leading '.' we added. */
if ((int)f[added] & 0x80) {
while ((int)suf[-1] & 0x80)
suf--;
}
/* trim one trailing dot before our suffix's dot */
if (suf[-1] == '.')
suf--;
}
} else
suf = fnametmp + length - 1; /* overwrite the leading dot with suffix's dot */
memcpy(suf, TMPNAME_SUFFIX, TMPNAME_SUFFIX_LEN+1);
if (make_unique) {
static unsigned counter_limit;
unsigned counter;
if (!counter_limit) {
counter_limit = (unsigned)getpid() + MAX_UNIQUE_LOOP;
if (counter_limit > MAX_UNIQUE_NUMBER || counter_limit < MAX_UNIQUE_LOOP)
counter_limit = MAX_UNIQUE_LOOP;
}
counter = counter_limit - MAX_UNIQUE_LOOP;
/* This doesn't have to be very good because we don't need
* to worry about someone trying to guess the values: all
* a conflict will do is cause a device, special file, hard
* link, or symlink to fail to be created. Also: avoid
* using mktemp() due to gcc's annoying warning. */
while (1) {
snprintf(suf, TMPNAME_SUFFIX_LEN+1, ".%d", counter);
if (access(fnametmp, 0) < 0)
break;
if (++counter >= counter_limit)
return 0;
}
} else
memcpy(suf, TMPNAME_SUFFIX, TMPNAME_SUFFIX_LEN+1);
return 1;
}
@@ -143,7 +185,7 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
int fd;
mode_t added_perms;
if (!get_tmpname(fnametmp, fname))
if (!get_tmpname(fnametmp, fname, False))
return -1;
if (am_root < 0) {
@@ -166,9 +208,9 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
* information should have been previously transferred, but that may
* not be the case with -R */
if (fd == -1 && relative_paths && errno == ENOENT
&& create_directory_path(fnametmp) == 0) {
&& make_path(fnametmp, MKP_SKIP_SLASH | MKP_DROP_NAME) == 0) {
/* Get back to name with XXXXXX in it. */
get_tmpname(fnametmp, fname);
get_tmpname(fnametmp, fname, False);
fd = do_mkstemp(fnametmp, (file->mode|added_perms) & INITACCESSPERMS);
}
#endif
@@ -186,24 +228,39 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
const char *fname, int fd, OFF_T total_size)
{
static char file_sum1[MAX_DIGEST_LEN];
static char file_sum2[MAX_DIGEST_LEN];
struct map_struct *mapbuf;
struct sum_struct sum;
int32 len, sum_len;
int32 len;
OFF_T offset = 0;
OFF_T offset2;
char *data;
int32 i;
char *map = NULL;
#ifdef SUPPORT_PREALLOCATION
#ifdef PREALLOCATE_NEEDS_TRUNCATE
OFF_T preallocated_len = 0;
#endif
if (preallocate_files && fd != -1 && total_size > 0 && (!inplace || total_size > size_r)) {
/* Try to preallocate enough space for file's eventual length. Can
* reduce fragmentation on filesystems like ext4, xfs, and NTFS. */
if (do_fallocate(fd, 0, total_size) == 0) {
#ifdef PREALLOCATE_NEEDS_TRUNCATE
preallocated_len = total_size;
#endif
} else
rsyserr(FWARNING, errno, "do_fallocate %s", full_fname(fname));
}
#endif
read_sum_head(f_in, &sum);
if (fd_r >= 0 && size_r > 0) {
int32 read_size = MAX(sum.blength * 2, 16*1024);
mapbuf = map_file(fd_r, size_r, read_size, sum.blength);
if (verbose > 2) {
rprintf(FINFO, "recv mapped %s of size %.0f\n",
fname_r, (double)size_r);
if (DEBUG_GTE(DELTASUM, 2)) {
rprintf(FINFO, "recv mapped %s of size %s\n",
fname_r, big_num(size_r));
}
} else
mapbuf = NULL;
@@ -215,9 +272,9 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
sum.flength = (OFF_T)sum.count * sum.blength;
if (sum.remainder)
sum.flength -= sum.blength - sum.remainder;
if (append_mode == 2) {
if (append_mode == 2 && mapbuf) {
for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
if (do_progress)
if (INFO_GTE(PROGRESS, 1))
show_progress(offset, total_size);
sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
CHUNK_SIZE);
@@ -225,27 +282,30 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
}
if (offset < sum.flength) {
int32 len = (int32)(sum.flength - offset);
if (do_progress)
if (INFO_GTE(PROGRESS, 1))
show_progress(offset, total_size);
sum_update(map_ptr(mapbuf, offset, len), len);
}
}
offset = sum.flength;
if (fd != -1 && (j = do_lseek(fd, offset, SEEK_SET)) != offset) {
rsyserr(FERROR_XFER, errno, "lseek of %s returned %.0f, not %.0f",
full_fname(fname), (double)j, (double)offset);
rsyserr(FERROR_XFER, errno, "lseek of %s returned %s, not %s",
full_fname(fname), big_num(j), big_num(offset));
exit_cleanup(RERR_FILEIO);
}
}
while ((i = recv_token(f_in, &data)) != 0) {
if (do_progress)
if (INFO_GTE(PROGRESS, 1))
show_progress(offset, total_size);
if (allowed_lull)
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH | MSK_ACTIVE_RECEIVER);
if (i > 0) {
if (verbose > 3) {
rprintf(FINFO,"data recv %d at %.0f\n",
i,(double)offset);
if (DEBUG_GTE(DELTASUM, 3)) {
rprintf(FINFO,"data recv %d at %s\n",
i, big_num(offset));
}
stats.literal_data += i;
@@ -267,10 +327,10 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
stats.matched_data += len;
if (verbose > 3) {
if (DEBUG_GTE(DELTASUM, 3)) {
rprintf(FINFO,
"chunk[%d] of size %ld at %.0f offset=%.0f%s\n",
i, (long)len, (double)offset2, (double)offset,
"chunk[%d] of size %ld at %s offset=%s%s\n",
i, (long)len, big_num(offset2), big_num(offset),
updating_basis_or_equiv && offset == offset2 ? " (seek)" : "");
}
@@ -289,9 +349,9 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
offset += len;
if ((pos = do_lseek(fd, len, SEEK_CUR)) != offset) {
rsyserr(FERROR_XFER, errno,
"lseek of %s returned %.0f, not %.0f",
"lseek of %s returned %s, not %s",
full_fname(fname),
(double)pos, (double)offset);
big_num(pos), big_num(offset));
exit_cleanup(RERR_FILEIO);
}
continue;
@@ -306,13 +366,20 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
goto report_write_error;
#ifdef HAVE_FTRUNCATE
if (inplace && fd != -1 && do_ftruncate(fd, offset) < 0) {
/* inplace: New data could be shorter than old data.
* preallocate_files: total_size could have been an overestimate.
* Cut off any extra preallocated zeros from dest file. */
if ((inplace
#ifdef PREALLOCATE_NEEDS_TRUNCATE
|| preallocated_len > offset
#endif
) && fd != -1 && do_ftruncate(fd, offset) < 0) {
rsyserr(FERROR_XFER, errno, "ftruncate failed on %s",
full_fname(fname));
}
#endif
if (do_progress)
if (INFO_GTE(PROGRESS, 1))
end_progress(total_size);
if (fd != -1 && offset > 0 && sparse_end(fd, offset) != 0) {
@@ -322,15 +389,16 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
exit_cleanup(RERR_FILEIO);
}
sum_len = sum_end(file_sum1);
if (sum_end(file_sum1) != checksum_len)
overflow_exit("checksum_len"); /* Impossible... */
if (mapbuf)
unmap_file(mapbuf);
read_buf(f_in, file_sum2, sum_len);
if (verbose > 2)
read_buf(f_in, sender_file_sum, checksum_len);
if (DEBUG_GTE(DELTASUM, 2))
rprintf(FINFO,"got file_sum\n");
if (fd != -1 && memcmp(file_sum1, file_sum2, sum_len) != 0)
if (fd != -1 && memcmp(file_sum1, sender_file_sum, checksum_len) != 0)
return 0;
return 1;
}
@@ -350,9 +418,9 @@ static void handle_delayed_updates(char *local_name)
struct file_struct *file = cur_flist->files[ndx];
fname = local_name ? local_name : f_name(file, NULL);
if ((partialptr = partial_dir_fname(fname)) != NULL) {
if (make_backups > 0 && !make_backup(fname))
if (make_backups > 0 && !make_backup(fname, False))
continue;
if (verbose > 2) {
if (DEBUG_GTE(RECV, 1)) {
rprintf(FINFO, "renaming %s to %s\n",
partialptr, fname);
}
@@ -403,16 +471,18 @@ static int we_want_redo(int desired_ndx)
return 0;
}
static int gen_wants_ndx(int desired_ndx)
static int gen_wants_ndx(int desired_ndx, int flist_num)
{
static int next_ndx = -1;
static int done_cnt = 0;
static BOOL got_eof = False;
int flist_num = first_flist->flist_num;
if (got_eof)
return 0;
/* TODO: integrate gen-reading I/O into perform_io() so this is not needed? */
io_flush(FULL_FLUSH);
while (next_ndx < desired_ndx) {
if (inc_recurse && flist_num <= done_cnt)
return 0;
@@ -440,7 +510,7 @@ static int gen_wants_ndx(int desired_ndx)
* main routine for receiver process.
*
* Receiver process runs on the same host as the generator process. */
int recv_files(int f_in, char *local_name)
int recv_files(int f_in, int f_out, char *local_name)
{
int fd1,fd2;
STRUCT_STAT st;
@@ -452,7 +522,6 @@ int recv_files(int f_in, char *local_name)
char fnamecmpbuf[MAXPATHLEN];
uchar fnamecmp_type;
struct file_struct *file;
struct stats initial_stats;
int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i;
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
int max_phase = protocol_version >= 29 ? 2 : 1;
@@ -462,7 +531,7 @@ int recv_files(int f_in, char *local_name)
#endif
int ndx, recv_ok;
if (verbose > 2)
if (DEBUG_GTE(RECV, 1))
rprintf(FINFO, "recv_files(%d) starting\n", cur_flist->used);
if (delay_updates)
@@ -472,24 +541,32 @@ int recv_files(int f_in, char *local_name)
cleanup_disable();
/* This call also sets cur_flist. */
ndx = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
ndx = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type,
xname, &xlen);
if (ndx == NDX_DONE) {
if (!am_server && INFO_GTE(PROGRESS, 2) && cur_flist) {
set_current_file_index(NULL, 0);
end_progress(0);
}
if (inc_recurse && first_flist) {
if (read_batch)
gen_wants_ndx(first_flist->used + first_flist->ndx_start);
if (read_batch) {
ndx = first_flist->used + first_flist->ndx_start;
gen_wants_ndx(ndx, first_flist->flist_num);
}
flist_free(first_flist);
if (first_flist)
continue;
} else if (read_batch && first_flist)
gen_wants_ndx(first_flist->used);
} else if (read_batch && first_flist) {
ndx = first_flist->used;
gen_wants_ndx(ndx, first_flist->flist_num);
}
if (++phase > max_phase)
break;
if (verbose > 2)
if (DEBUG_GTE(RECV, 1))
rprintf(FINFO, "recv_files phase=%d\n", phase);
if (phase == 2 && delay_updates)
handle_delayed_updates(local_name);
send_msg(MSG_DONE, "", 0, 0);
write_int(f_out, NDX_DONE);
continue;
}
@@ -499,11 +576,12 @@ int recv_files(int f_in, char *local_name)
file = dir_flist->files[cur_flist->parent_ndx];
fname = local_name ? local_name : f_name(file, fbuf);
if (verbose > 2)
if (DEBUG_GTE(RECV, 1))
rprintf(FINFO, "recv_files(%s)\n", fname);
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
&& (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
recv_xattr_request(file, f_in);
#endif
@@ -514,6 +592,21 @@ int recv_files(int f_in, char *local_name)
&& !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))
set_file_attrs(fname, file, NULL, fname, 0);
#endif
if (iflags & ITEM_IS_NEW) {
stats.created_files++;
if (S_ISREG(file->mode)) {
/* Nothing further to count. */
} else if (S_ISDIR(file->mode))
stats.created_dirs++;
#ifdef SUPPORT_LINKS
else if (S_ISLNK(file->mode))
stats.created_symlinks++;
#endif
else if (IS_DEVICE(file->mode))
stats.created_devices++;
else
stats.created_specials++;
}
continue;
}
if (phase == 2) {
@@ -543,11 +636,13 @@ int recv_files(int f_in, char *local_name)
csum_length = SHORT_SUM_LENGTH;
redoing = 0;
}
if (iflags & ITEM_IS_NEW)
stats.created_files++;
}
if (!am_server && do_progress)
if (!am_server && INFO_GTE(PROGRESS, 1))
set_current_file_index(file, ndx);
stats.num_transferred_files++;
stats.xferred_files++;
stats.total_transferred_size += F_LENGTH(file);
cleanup_got_literal = 0;
@@ -561,7 +656,7 @@ int recv_files(int f_in, char *local_name)
if (read_batch) {
int wanted = redoing
? we_want_redo(ndx)
: gen_wants_ndx(ndx);
: gen_wants_ndx(ndx, cur_flist->flist_num);
if (!wanted) {
rprintf(FINFO,
"(Skipping batched update for%s \"%s\")\n",
@@ -573,16 +668,21 @@ int recv_files(int f_in, char *local_name)
}
}
if (!log_before_transfer)
remember_initial_stats();
if (!do_xfers) { /* log the transfer */
log_item(FCLIENT, file, &stats, iflags, NULL);
log_item(FCLIENT, file, iflags, NULL);
if (read_batch)
discard_receive_data(f_in, F_LENGTH(file));
continue;
}
if (write_batch < 0) {
log_item(FCLIENT, file, &stats, iflags, NULL);
log_item(FCLIENT, file, iflags, NULL);
if (!am_server)
discard_receive_data(f_in, F_LENGTH(file));
if (inc_recurse)
send_msg_int(MSG_SUCCESS, ndx);
continue;
}
@@ -601,21 +701,26 @@ int recv_files(int f_in, char *local_name)
break;
case FNAMECMP_FUZZY:
if (file->dirname) {
pathjoin(fnamecmpbuf, MAXPATHLEN,
file->dirname, xname);
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, file->dirname, xname);
fnamecmp = fnamecmpbuf;
} else
fnamecmp = xname;
break;
default:
if (fnamecmp_type >= basis_dir_cnt) {
if (fnamecmp_type > FNAMECMP_FUZZY && fnamecmp_type-FNAMECMP_FUZZY <= basis_dir_cnt) {
fnamecmp_type -= FNAMECMP_FUZZY + 1;
if (file->dirname) {
stringjoin(fnamecmpbuf, sizeof fnamecmpbuf,
basis_dir[fnamecmp_type], "/", file->dirname, "/", xname, NULL);
} else
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], xname);
} else if (fnamecmp_type >= basis_dir_cnt) {
rprintf(FERROR,
"invalid basis_dir index: %d.\n",
fnamecmp_type);
exit_cleanup(RERR_PROTOCOL);
}
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
basis_dir[fnamecmp_type], fname);
} else
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], fname);
fnamecmp = fnamecmpbuf;
break;
}
@@ -638,8 +743,6 @@ int recv_files(int f_in, char *local_name)
fnamecmp = fname;
}
initial_stats = stats;
/* open the file */
fd1 = do_open(fnamecmp, O_RDONLY, 0);
@@ -716,7 +819,8 @@ int recv_files(int f_in, char *local_name)
if (fd2 == -1) {
rsyserr(FERROR_XFER, errno, "open %s failed",
full_fname(fname));
}
} else if (updating_basis_or_equiv)
cleanup_set(NULL, NULL, file, fd1, fd2);
} else {
fd2 = open_tmpfile(fnametmp, fname, file);
if (fd2 != -1)
@@ -734,15 +838,15 @@ int recv_files(int f_in, char *local_name)
/* log the transfer */
if (log_before_transfer)
log_item(FCLIENT, file, &initial_stats, iflags, NULL);
else if (!am_server && verbose && do_progress)
log_item(FCLIENT, file, iflags, NULL);
else if (!am_server && INFO_GTE(NAME, 1) && INFO_EQ(PROGRESS, 1))
rprintf(FINFO, "%s\n", fname);
/* recv file data */
recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
fname, fd2, F_LENGTH(file));
log_item(log_code, file, &initial_stats, iflags, NULL);
log_item(log_code, file, iflags, NULL);
if (fd1 != -1)
close(fd1);
@@ -796,7 +900,7 @@ int recv_files(int f_in, char *local_name)
break;
case 0: {
enum logcode msgtype = redoing ? FERROR_XFER : FWARNING;
if (msgtype == FERROR_XFER || verbose) {
if (msgtype == FERROR_XFER || INFO_GTE(NAME, 1)) {
char *errstr, *redostr, *keptstr;
if (!(keep_partial && partialptr) && !inplace)
keptstr = "discarded";
@@ -838,7 +942,7 @@ int recv_files(int f_in, char *local_name)
if (phase == 2 && delay_updates) /* for protocol_version < 29 */
handle_delayed_updates(local_name);
if (verbose > 2)
if (DEBUG_GTE(RECV, 1))
rprintf(FINFO,"recv_files finished\n");
return 0;

View File

@@ -1,7 +1,7 @@
/*
* A pre-compilation helper program to aid in the creation of rounding.h.
*
* Copyright (C) 2007-2009 Wayne Davison
* Copyright (C) 2007-2013 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

12
rsync-ssl.in Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
# This script supports using stunnel to secure an rsync daemon connection.
# Note that this requires at least version 4.x of stunnel.
case "$@" in
*rsync://*) ;;
*::*) ;;
*)
echo "You must use rsync-ssl with a daemon-style hostname." 0>&1
exit 1
;;
esac
exec @bindir@/rsync --rsh=@bindir@/stunnel-rsync "${@}"

240
rsync.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,7 +27,6 @@
#include <langinfo.h>
#endif
extern int verbose;
extern int dry_run;
extern int preserve_acls;
extern int preserve_xattrs;
@@ -36,15 +35,18 @@ extern int preserve_executability;
extern int preserve_times;
extern int am_root;
extern int am_server;
extern int am_daemon;
extern int am_sender;
extern int am_receiver;
extern int am_generator;
extern int am_starting_up;
extern int allow_8bit_chars;
extern int protocol_version;
extern int got_kill_signal;
extern int inc_recurse;
extern int inplace;
extern int flist_eof;
extern int file_old_total;
extern int keep_dirlinks;
extern int make_backups;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
@@ -82,19 +84,20 @@ void setup_iconv(void)
/* It's OK if this fails... */
ic_chck = iconv_open(defset, defset);
if (verbose > 3) {
if (DEBUG_GTE(ICONV, 2)) {
if (ic_chck == (iconv_t)-1) {
rprintf(FINFO,
"note: iconv_open(\"%s\", \"%s\") failed (%d)"
" -- using isprint() instead of iconv().\n",
"msg checking via isprint()"
" (iconv_open(\"%s\", \"%s\") errno: %d)\n",
defset, defset, errno);
} else {
rprintf(FINFO,
"note: iconv_open(\"%s\", \"%s\") succeeded.\n",
defset, defset);
"msg checking charset: %s\n",
defset);
}
}
}
} else
ic_chck = (iconv_t)-1;
# ifdef ICONV_OPTION
if (!iconv_opt)
@@ -124,47 +127,82 @@ void setup_iconv(void)
exit_cleanup(RERR_UNSUPPORTED);
}
if (verbose > 1) {
rprintf(FINFO, "%s charset: %s\n",
am_server ? "server" : "client",
*charset ? charset : "[LOCALE]");
if (DEBUG_GTE(ICONV, 1)) {
rprintf(FINFO, "[%s] charset: %s\n",
who_am_i(), *charset ? charset : "[LOCALE]");
}
# endif
}
/* This function converts the characters in the "in" xbuf into characters
* in the "out" xbuf. The "len" of the "in" xbuf is used starting from its
* "pos". The "size" of the "out" xbuf restricts how many characters can be
* stored, starting at its "pos+len" position. Note that the last byte of
* the buffer is never used, which reserves space for a terminating '\0'.
/* This function converts the chars in the "in" xbuf into characters in the
* "out" xbuf. The ".len" chars of the "in" xbuf is used starting from its
* ".pos". The ".size" of the "out" xbuf restricts how many characters can
* be stored, starting at its ".pos+.len" position. Note that the last byte
* of the "out" xbuf is not used, which reserves space for a trailing '\0'
* (though it is up to the caller to store a trailing '\0', as needed).
*
* We return a 0 on success or a -1 on error. An error also sets errno to
* E2BIG, EILSEQ, or EINVAL (see below); otherwise errno will be set to 0.
* The "in" xbuf is altered to update "pos" and "len". The "out" xbuf has
* data appended, and its "len" incremented. If ICB_EXPAND_OUT is set in
* "flags", the "out" xbuf will also be allocated if empty, and expanded if
* too small (so E2BIG will not be returned). If ICB_INCLUDE_BAD is set in
* "flags", any badly-encoded chars are included verbatim in the "out" xbuf,
* so EILSEQ will not be returned. Likewise for ICB_INCLUDE_INCOMPLETE with
* respect to an incomplete multi-byte char at the end, which ensures that
* EINVAL is not returned. Anytime "in.pos" is 0 we will reset the iconv()
* state prior to processing the characters. */
* The "in" xbuf is altered to update ".pos" and ".len". The "out" xbuf has
* data appended, and its ".len" incremented (see below for a ".size" note).
*
* If ICB_CIRCULAR_OUT is set in "flags", the chars going into the "out" xbuf
* can wrap around to the start, and the xbuf may have its ".size" reduced
* (presumably by 1 byte) if the iconv code doesn't have space to store a
* multi-byte character at the physical end of the ".buf" (though no reducing
* happens if ".pos" is <= 1, since there is no room to wrap around).
*
* If ICB_EXPAND_OUT is set in "flags", the "out" xbuf will be allocated if
* empty, and (as long as ICB_CIRCULAR_OUT is not set) expanded if too small.
* This prevents the return of E2BIG (except for a circular xbuf).
*
* If ICB_INCLUDE_BAD is set in "flags", any badly-encoded chars are included
* verbatim in the "out" xbuf, so EILSEQ will not be returned.
*
* If ICB_INCLUDE_INCOMPLETE is set in "flags", any incomplete multi-byte
* chars are included, which ensures that EINVAL is not returned.
*
* If ICB_INIT is set, the iconv() conversion state is initialized prior to
* processing the characters. */
int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags)
{
ICONV_CONST char *ibuf;
size_t icnt, ocnt;
size_t icnt, ocnt, opos;
char *obuf;
if (!out->size && flags & ICB_EXPAND_OUT)
alloc_xbuf(out, 1024);
if (!out->size && flags & ICB_EXPAND_OUT) {
size_t siz = ROUND_UP_1024(in->len * 2);
alloc_xbuf(out, siz);
} else if (out->len+1 >= out->size) {
/* There is no room to even start storing data. */
if (!(flags & ICB_EXPAND_OUT) || flags & ICB_CIRCULAR_OUT) {
errno = E2BIG;
return -1;
}
realloc_xbuf(out, out->size + ROUND_UP_1024(in->len * 2));
}
if (!in->pos)
if (flags & ICB_INIT)
iconv(ic, NULL, 0, NULL, 0);
ibuf = in->buf + in->pos;
icnt = in->len;
obuf = out->buf + (out->pos + out->len);
ocnt = out->size - (out->pos + out->len) - 1;
opos = out->pos + out->len;
if (flags & ICB_CIRCULAR_OUT) {
if (opos >= out->size) {
opos -= out->size;
/* We know that out->pos is not 0 due to the "no room" check
* above, so this can't go "negative". */
ocnt = out->pos - opos - 1;
} else {
/* Allow the use of all bytes to the physical end of the buffer
* unless pos is 0, in which case we reserve our trailing '\0'. */
ocnt = out->size - opos - (out->pos ? 0 : 1);
}
} else
ocnt = out->size - opos - 1;
obuf = out->buf + opos;
while (icnt) {
while (iconv(ic, &ibuf, &icnt, &obuf, &ocnt) == (size_t)-1) {
@@ -173,31 +211,58 @@ int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags)
if (errno == EINVAL) {
if (!(flags & ICB_INCLUDE_INCOMPLETE))
goto finish;
if (!ocnt)
goto e2big;
} else if (errno == EILSEQ) {
if (!(flags & ICB_INCLUDE_BAD))
goto finish;
} else {
size_t opos = obuf - out->buf;
if (!(flags & ICB_EXPAND_OUT)) {
if (!ocnt)
goto e2big;
} else if (errno == E2BIG) {
size_t siz;
e2big:
opos = obuf - out->buf;
if (flags & ICB_CIRCULAR_OUT && out->pos > 1 && opos > out->pos) {
/* We are in a divided circular buffer at the physical
* end with room to wrap to the start. If iconv() refused
* to use one or more trailing bytes in the buffer, we
* set the size to ignore the unused bytes. */
if (opos < out->size)
reduce_iobuf_size(out, opos);
obuf = out->buf;
ocnt = out->pos - 1;
continue;
}
if (!(flags & ICB_EXPAND_OUT) || flags & ICB_CIRCULAR_OUT) {
errno = E2BIG;
goto finish;
}
realloc_xbuf(out, out->size + 1024);
siz = ROUND_UP_1024(in->len * 2);
realloc_xbuf(out, out->size + siz);
obuf = out->buf + opos;
ocnt += 1024;
ocnt += siz;
continue;
} else {
rsyserr(FERROR, errno, "unexpected error from iconv()");
exit_cleanup(RERR_UNSUPPORTED);
}
*obuf++ = *ibuf++;
ocnt--, icnt--;
if (!icnt)
break;
}
}
errno = 0;
finish:
opos = obuf - out->buf;
if (flags & ICB_CIRCULAR_OUT && opos < out->pos)
opos += out->size;
out->len = opos - out->pos;
in->len = icnt;
in->pos = ibuf - in->buf;
out->len = obuf - out->buf - out->pos;
return errno ? -1 : 0;
}
@@ -216,7 +281,7 @@ void send_protected_args(int fd, char *args[])
for (i = 0; args[i]; i++) {} /* find first NULL */
args[i] = "rsync"; /* set a new arg0 */
if (verbose > 1)
if (DEBUG_GTE(CMD, 1))
print_child_argv("protected args:", args + i + 1);
do {
if (!args[i][0])
@@ -225,7 +290,7 @@ void send_protected_args(int fd, char *args[])
else if (convert) {
INIT_XBUF_STRLEN(inbuf, args[i]);
iconvbufs(ic_send, &inbuf, &outbuf,
ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE);
ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_INIT);
outbuf.buf[outbuf.len] = '\0';
write_buf(fd, outbuf.buf, outbuf.len + 1);
outbuf.len = 0;
@@ -242,13 +307,13 @@ void send_protected_args(int fd, char *args[])
#endif
}
int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
char *buf, int *len_ptr)
{
int len, iflags = 0;
struct file_list *flist;
uchar fnamecmp_type = FNAMECMP_FNAME;
int ndx, save_verbose = verbose;
int ndx;
read_loop:
while (1) {
@@ -258,6 +323,12 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
break;
if (ndx == NDX_DONE)
return ndx;
if (ndx == NDX_DEL_STATS) {
read_del_stats(f_in);
if (am_sender && am_server)
write_del_stats(f_out);
continue;
}
if (!inc_recurse || am_sender) {
int last;
if (first_flist)
@@ -271,7 +342,9 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
}
if (ndx == NDX_FLIST_EOF) {
flist_eof = 1;
send_msg(MSG_FLIST_EOF, "", 0, 0);
if (DEBUG_GTE(FLIST, 3))
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
write_int(f_out, NDX_FLIST_EOF);
continue;
}
ndx = NDX_FLIST_OFFSET - ndx;
@@ -285,18 +358,15 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
exit_cleanup(RERR_PROTOCOL);
}
/* Send everything read from f_in to msg_fd_out. */
if (verbose > 3) {
if (DEBUG_GTE(FLIST, 2)) {
rprintf(FINFO, "[%s] receiving flist for dir %d\n",
who_am_i(), ndx);
}
verbose = 0;
send_msg_int(MSG_FLIST, ndx);
start_flist_forward(f_in);
/* Send all the data we read for this flist to the generator. */
start_flist_forward(ndx);
flist = recv_file_list(f_in);
flist->parent_ndx = ndx;
stop_flist_forward();
verbose = save_verbose;
}
iflags = protocol_version >= 29 ? read_shortint(f_in)
@@ -305,11 +375,19 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
/* Support the protocol-29 keep-alive style. */
if (protocol_version < 30 && ndx == cur_flist->used && iflags == ITEM_IS_NEW) {
if (am_sender)
maybe_send_keepalive();
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH);
goto read_loop;
}
cur_flist = flist_for_ndx(ndx, "read_ndx_and_attrs");
flist = flist_for_ndx(ndx, "read_ndx_and_attrs");
if (flist != cur_flist) {
cur_flist = flist;
if (am_sender) {
file_old_total = cur_flist->used;
for (flist = first_flist; flist != cur_flist; flist = flist->next)
file_old_total += flist->used;
}
}
if (iflags & ITEM_BASIS_TYPE_FOLLOWS)
fnamecmp_type = read_byte(f_in);
@@ -391,12 +469,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
full_fname(fname));
return 0;
}
#ifdef SUPPORT_ACLS
sx2.acc_acl = sx2.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
sx2.xattr = NULL;
#endif
init_stat_x(&sx2);
sxp = &sx2;
inherit = !preserve_perms;
} else
@@ -429,7 +502,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
flags |= ATTRS_SKIP_MTIME;
if (!(flags & ATTRS_SKIP_MTIME)
&& cmp_time(sxp->st.st_mtime, file->modtime) != 0) {
int ret = set_modtime(fname, file->modtime, sxp->st.st_mode);
int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode);
if (ret < 0) {
rsyserr(FERROR_XFER, errno, "failed to set times on %s",
full_fname(fname));
@@ -450,7 +523,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
} else
#endif
if (change_uid || change_gid) {
if (verbose > 2) {
if (DEBUG_GTE(OWN, 1)) {
if (change_uid) {
rprintf(FINFO,
"set uid of %s from %u to %u\n",
@@ -515,27 +588,20 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
}
#endif
if (verbose > 1 && flags & ATTRS_REPORT) {
if (INFO_GTE(NAME, 2) && flags & ATTRS_REPORT) {
if (updated)
rprintf(FCLIENT, "%s\n", fname);
else
rprintf(FCLIENT, "%s is uptodate\n", fname);
}
cleanup:
if (sxp == &sx2) {
#ifdef SUPPORT_ACLS
if (preserve_acls)
free_acl(&sx2);
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs)
free_xattr(&sx2);
#endif
}
if (sxp == &sx2)
free_stat_x(&sx2);
return updated;
}
RETSIGTYPE sig_int(UNUSED(int val))
/* This is only called for SIGINT, SIGHUP, and SIGTERM. */
RETSIGTYPE sig_int(int sig_num)
{
/* KLUGE: if the user hits Ctrl-C while ssh is prompting
* for a password, then our cleanup's sending of a SIGUSR1
@@ -546,6 +612,23 @@ RETSIGTYPE sig_int(UNUSED(int val))
* not ssh waiting for a password, then this tiny delay
* shouldn't hurt anything. */
msleep(400);
/* If we're an rsync daemon listener (not a daemon server),
* we'll exit with status 0 if we received SIGTERM. */
if (am_daemon && !am_server && sig_num == SIGTERM)
exit_cleanup(0);
/* If the signal arrived on the server side (or for the receiver
* process on the client), we want to try to do a controlled shutdown
* that lets the client side (generator process) know what happened.
* To do this, we set a flag and let the normal process handle the
* shutdown. We only attempt this if multiplexed IO is in effect and
* we didn't already set the flag. */
if (!got_kill_signal && (am_server || am_receiver)) {
got_kill_signal = sig_num;
return;
}
exit_cleanup(RERR_SIGNAL);
}
@@ -563,16 +646,17 @@ int finish_transfer(const char *fname, const char *fnametmp,
const char *temp_copy_name = partialptr && *partialptr != '/' ? partialptr : NULL;
if (inplace) {
if (verbose > 2)
if (DEBUG_GTE(RECV, 1))
rprintf(FINFO, "finishing %s\n", fname);
fnametmp = fname;
goto do_set_file_attrs;
}
if (make_backups > 0 && overwriting_basis) {
if (!make_backup(fname))
int ok = make_backup(fname, False);
if (!ok)
return 1;
if (fnamecmp == fname)
if (ok == 1 && fnamecmp == fname)
fnamecmp = get_backup_name(fname);
}
@@ -581,17 +665,15 @@ int finish_transfer(const char *fname, const char *fnametmp,
ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
/* move tmp file over real file */
if (verbose > 2)
if (DEBUG_GTE(RECV, 1))
rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
ret = robust_rename(fnametmp, fname, temp_copy_name,
file->mode & INITACCESSPERMS);
ret = robust_rename(fnametmp, fname, temp_copy_name, file->mode);
if (ret < 0) {
rsyserr(FERROR_XFER, errno, "%s %s -> \"%s\"",
ret == -2 ? "copy" : "rename",
full_fname(fnametmp), fname);
if (!partialptr || (ret == -2 && temp_copy_name)
|| robust_rename(fnametmp, partialptr, NULL,
file->mode & INITACCESSPERMS) < 0)
|| robust_rename(fnametmp, partialptr, NULL, file->mode) < 0)
do_unlink(fnametmp);
return 0;
}

233
rsync.h
View File

@@ -2,7 +2,7 @@
* Copyright (C) 1996, 2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2013 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
@@ -61,6 +61,7 @@
#define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - now */
#define XMIT_HLINK_FIRST (1<<12) /* protocols 30 - now (HLINKED files only) */
#define XMIT_IO_ERROR_ENDLIST (1<<12) /* protocols 31*- now (w/XMIT_EXTENDED_FLAGS) (also protocol 30 w/'f' compat flag) */
#define XMIT_MOD_NSEC (1<<13) /* protocols 31 - now */
/* These flags are used in the live flist data. */
@@ -81,6 +82,7 @@
#define FLAG_LENGTH64 (1<<9) /* sender/receiver/generator */
#define FLAG_SKIP_GROUP (1<<10) /* receiver/generator */
#define FLAG_TIME_FAILED (1<<11)/* generator */
#define FLAG_MOD_NSEC (1<<12) /* sender/receiver/generator */
/* These flags are passed to functions but not stored. */
@@ -96,7 +98,7 @@
== ((unsigned)(b2) & (unsigned)(mask)))
/* update this if you make incompatible changes */
#define PROTOCOL_VERSION 30
#define PROTOCOL_VERSION 31
/* This is used when working on a new protocol version in CVS, and should
* be a new non-zero value for each CVS change that affects the protocol.
@@ -124,7 +126,8 @@
#define OLD_PROTOCOL_VERSION 25
#define MAX_PROTOCOL_VERSION 40
#define FILECNT_LOOKAHEAD 1000
#define MIN_FILECNT_LOOKAHEAD 1000
#define MAX_FILECNT_LOOKAHEAD 10000
#define RSYNC_PORT 873
@@ -132,12 +135,14 @@
#define WRITE_SIZE (32*1024)
#define CHUNK_SIZE (32*1024)
#define MAX_MAP_SIZE (256*1024)
#define IO_BUFFER_SIZE (4092)
#define IO_BUFFER_SIZE (32*1024)
#define MAX_BLOCK_SIZE ((int32)1 << 17)
/* For compatibility with older rsyncs */
#define OLD_MAX_BLOCK_SIZE ((int32)1 << 29)
#define ROUND_UP_1024(siz) ((siz) & (1024-1) ? ((siz) | (1024-1)) + 1 : (siz))
#define IOERR_GENERAL (1<<0) /* For backward compatibility, this must == 1 */
#define IOERR_VANISHED (1<<1)
#define IOERR_DEL_LIMIT (1<<2)
@@ -231,20 +236,46 @@ enum msgcode {
MSG_ERROR_UTF8=FERROR_UTF8, /* sibling logging */
MSG_LOG=FLOG, MSG_CLIENT=FCLIENT, /* sibling logging */
MSG_REDO=9, /* reprocess indicated flist index */
MSG_FLIST=20, /* extra file list over sibling socket */
MSG_FLIST_EOF=21,/* we've transmitted all the file lists */
MSG_STATS=10, /* message has stats data for generator */
MSG_IO_ERROR=22,/* the sending side had an I/O error */
MSG_NOOP=42, /* a do-nothing message */
MSG_IO_TIMEOUT=33,/* tell client about a daemon's timeout value */
MSG_NOOP=42, /* a do-nothing message (legacy protocol-30 only) */
MSG_ERROR_EXIT=86, /* synchronize an error exit (siblings and protocol >= 31) */
MSG_SUCCESS=100,/* successfully updated indicated flist index */
MSG_DELETED=101,/* successfully deleted a file on receiving side */
MSG_NO_SEND=102,/* sender failed to open a file we wanted */
MSG_DONE=86 /* current phase is done */
};
#define NDX_DONE -1
#define NDX_FLIST_EOF -2
#define NDX_DEL_STATS -3
#define NDX_FLIST_OFFSET -101
/* For calling delete_item() and delete_dir_contents(). */
#define DEL_NO_UID_WRITE (1<<0) /* file/dir has our uid w/o write perm */
#define DEL_RECURSE (1<<1) /* if dir, delete all contents */
#define DEL_DIR_IS_EMPTY (1<<2) /* internal delete_FUNCTIONS use only */
#define DEL_FOR_FILE (1<<3) /* making room for a replacement file */
#define DEL_FOR_DIR (1<<4) /* making room for a replacement dir */
#define DEL_FOR_SYMLINK (1<<5) /* making room for a replacement symlink */
#define DEL_FOR_DEVICE (1<<6) /* making room for a replacement device */
#define DEL_FOR_SPECIAL (1<<7) /* making room for a replacement special */
#define DEL_FOR_BACKUP (1<<8) /* the delete is for a backup operation */
#define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL)
enum delret {
DR_SUCCESS = 0, DR_FAILURE, DR_AT_LIMIT, DR_NOT_EMPTY
};
/* Defines for make_path() */
#define MKP_DROP_NAME (1<<0) /* drop trailing filename or trailing slash */
#define MKP_SKIP_SLASH (1<<1) /* skip one or more leading slashes */
/* Defines for maybe_send_keepalive() */
#define MSK_ALLOW_FLUSH (1<<0)
#define MSK_ACTIVE_RECEIVER (1<<1)
#include "errcode.h"
#include "config.h"
@@ -340,7 +371,7 @@ enum msgcode {
#include <utime.h>
#endif
#if defined HAVE_LUTIMES || defined HAVE_UTIMENSAT
#if defined HAVE_UTIMENSAT || defined HAVE_LUTIMES
#define CAN_SET_SYMLINK_TIMES 1
#endif
@@ -352,6 +383,14 @@ enum msgcode {
#define CAN_CHMOD_SYMLINK 1
#endif
#ifdef HAVE_UTIMENSAT
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
#define ST_MTIME_NSEC st_mtim.tv_nsec
#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
#define ST_MTIME_NSEC st_mtimensec
#endif
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
@@ -573,7 +612,7 @@ struct hashtable {
void *nodes;
int32 size, entries;
uint32 node_size;
int key64;
short key64;
};
struct ht_int32_node {
@@ -634,6 +673,23 @@ struct ht_int64_node {
#define ACLS_NEED_MASK 1
#endif
#if defined HAVE_FALLOCATE || HAVE_SYS_FALLOCATE
#ifdef HAVE_LINUX_FALLOC_H
#include <linux/falloc.h>
#endif
#ifdef FALLOC_FL_KEEP_SIZE
#define SUPPORT_PREALLOCATION 1
#elif defined HAVE_FTRUNCATE
#define SUPPORT_PREALLOCATION 1
#define PREALLOCATE_NEEDS_TRUNCATE 1
#endif
#else /* !fallocate */
#if defined HAVE_EFFICIENT_POSIX_FALLOCATE && defined HAVE_FTRUNCATE
#define SUPPORT_PREALLOCATION 1
#define PREALLOCATE_NEEDS_TRUNCATE 1
#endif
#endif
union file_extras {
int32 num;
uint32 unum;
@@ -665,7 +721,9 @@ extern int xattrs_ndx;
#define REQ_EXTRA(f,ndx) ((union file_extras*)(f) - (ndx))
#define OPT_EXTRA(f,bump) ((union file_extras*)(f) - file_extra_cnt - 1 - (bump))
#define NSEC_BUMP(f) ((f)->flags & FLAG_MOD_NSEC ? 1 : 0)
#define LEN64_BUMP(f) ((f)->flags & FLAG_LENGTH64 ? 1 : 0)
#define START_BUMP(f) (NSEC_BUMP(f) + LEN64_BUMP(f))
#define HLINK_BUMP(f) ((f)->flags & (FLAG_HLINKED|FLAG_HLINK_DONE) ? inc_recurse+1 : 0)
#define ACL_BUMP(f) (acls_ndx ? 1 : 0)
@@ -674,9 +732,11 @@ extern int xattrs_ndx;
#define F_LENGTH(f) ((int64)(f)->len32)
#else
#define F_LENGTH(f) ((int64)(f)->len32 + ((f)->flags & FLAG_LENGTH64 \
? (int64)OPT_EXTRA(f, 0)->unum << 32 : 0))
? (int64)OPT_EXTRA(f, NSEC_BUMP(f))->unum << 32 : 0))
#endif
#define F_MOD_NSEC(f) ((f)->flags & FLAG_MOD_NSEC ? OPT_EXTRA(f, 0)->unum : 0)
/* If there is a symlink string, it is always right after the basename */
#define F_SYMLINK(f) ((f)->basename + strlen((f)->basename) + 1)
@@ -694,22 +754,21 @@ extern int xattrs_ndx;
#define F_NDX(f) REQ_EXTRA(f, unsort_ndx)->num
/* These items are per-entry optional: */
#define F_HL_GNUM(f) OPT_EXTRA(f, LEN64_BUMP(f))->num /* non-dirs */
#define F_HL_PREV(f) OPT_EXTRA(f, LEN64_BUMP(f)+inc_recurse)->num /* non-dirs */
#define F_DIR_NODE_P(f) (&OPT_EXTRA(f, LEN64_BUMP(f) \
#define F_HL_GNUM(f) OPT_EXTRA(f, START_BUMP(f))->num /* non-dirs */
#define F_HL_PREV(f) OPT_EXTRA(f, START_BUMP(f)+inc_recurse)->num /* non-dirs */
#define F_DIR_NODE_P(f) (&OPT_EXTRA(f, START_BUMP(f) \
+ DIRNODE_EXTRA_CNT - 1)->num) /* sender dirs */
#define F_DIR_RELNAMES_P(f) (&OPT_EXTRA(f, LEN64_BUMP(f) + DIRNODE_EXTRA_CNT \
#define F_DIR_RELNAMES_P(f) (&OPT_EXTRA(f, START_BUMP(f) + DIRNODE_EXTRA_CNT \
+ PTR_EXTRA_CNT - 1)->num) /* sender dirs */
#define F_DIR_DEFACL(f) OPT_EXTRA(f, LEN64_BUMP(f))->unum /* receiver dirs */
#define F_DIR_DEV_P(f) (&OPT_EXTRA(f, LEN64_BUMP(f) + ACL_BUMP(f) \
#define F_DIR_DEFACL(f) OPT_EXTRA(f, START_BUMP(f))->unum /* receiver dirs */
#define F_DIR_DEV_P(f) (&OPT_EXTRA(f, START_BUMP(f) + ACL_BUMP(f) \
+ DEV_EXTRA_CNT - 1)->unum) /* receiver dirs */
/* This optional item might follow an F_HL_*() item.
* (Note: a device doesn't need to check LEN64_BUMP(f).) */
#define F_RDEV_P(f) (&OPT_EXTRA(f, HLINK_BUMP(f) + DEV_EXTRA_CNT - 1)->unum)
/* This optional item might follow an F_HL_*() item. */
#define F_RDEV_P(f) (&OPT_EXTRA(f, START_BUMP(f) + HLINK_BUMP(f) + DEV_EXTRA_CNT - 1)->unum)
/* The sum is only present on regular files. */
#define F_SUM(f) ((char*)OPT_EXTRA(f, LEN64_BUMP(f) + HLINK_BUMP(f) \
#define F_SUM(f) ((char*)OPT_EXTRA(f, START_BUMP(f) + HLINK_BUMP(f) \
+ SUM_EXTRA_CNT - 1))
/* Some utility defines: */
@@ -794,47 +853,45 @@ struct map_struct {
int status; /* first errno from read errors */
};
#define MATCHFLG_WILD (1<<0) /* pattern has '*', '[', and/or '?' */
#define MATCHFLG_WILD2 (1<<1) /* pattern has '**' */
#define MATCHFLG_WILD2_PREFIX (1<<2) /* pattern starts with "**" */
#define MATCHFLG_WILD3_SUFFIX (1<<3) /* pattern ends with "***" */
#define MATCHFLG_ABS_PATH (1<<4) /* path-match on absolute path */
#define MATCHFLG_INCLUDE (1<<5) /* this is an include, not an exclude */
#define MATCHFLG_DIRECTORY (1<<6) /* this matches only directories */
#define MATCHFLG_WORD_SPLIT (1<<7) /* split rules on whitespace */
#define MATCHFLG_NO_INHERIT (1<<8) /* don't inherit these rules */
#define MATCHFLG_NO_PREFIXES (1<<9) /* parse no prefixes from patterns */
#define MATCHFLG_MERGE_FILE (1<<10)/* specifies a file to merge */
#define MATCHFLG_PERDIR_MERGE (1<<11)/* merge-file is searched per-dir */
#define MATCHFLG_EXCLUDE_SELF (1<<12)/* merge-file name should be excluded */
#define MATCHFLG_FINISH_SETUP (1<<13)/* per-dir merge file needs setup */
#define MATCHFLG_NEGATE (1<<14)/* rule matches when pattern does not */
#define MATCHFLG_CVS_IGNORE (1<<15)/* rule was -C or :C */
#define MATCHFLG_SENDER_SIDE (1<<16)/* rule applies to the sending side */
#define MATCHFLG_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */
#define MATCHFLG_CLEAR_LIST (1<<18)/* this item is the "!" token */
#define MATCHFLG_PERISHABLE (1<<19)/* perishable if parent dir goes away */
#define FILTRULE_WILD (1<<0) /* pattern has '*', '[', and/or '?' */
#define FILTRULE_WILD2 (1<<1) /* pattern has '**' */
#define FILTRULE_WILD2_PREFIX (1<<2) /* pattern starts with "**" */
#define FILTRULE_WILD3_SUFFIX (1<<3) /* pattern ends with "***" */
#define FILTRULE_ABS_PATH (1<<4) /* path-match on absolute path */
#define FILTRULE_INCLUDE (1<<5) /* this is an include, not an exclude */
#define FILTRULE_DIRECTORY (1<<6) /* this matches only directories */
#define FILTRULE_WORD_SPLIT (1<<7) /* split rules on whitespace */
#define FILTRULE_NO_INHERIT (1<<8) /* don't inherit these rules */
#define FILTRULE_NO_PREFIXES (1<<9) /* parse no prefixes from patterns */
#define FILTRULE_MERGE_FILE (1<<10)/* specifies a file to merge */
#define FILTRULE_PERDIR_MERGE (1<<11)/* merge-file is searched per-dir */
#define FILTRULE_EXCLUDE_SELF (1<<12)/* merge-file name should be excluded */
#define FILTRULE_FINISH_SETUP (1<<13)/* per-dir merge file needs setup */
#define FILTRULE_NEGATE (1<<14)/* rule matches when pattern does not */
#define FILTRULE_CVS_IGNORE (1<<15)/* rule was -C or :C */
#define FILTRULE_SENDER_SIDE (1<<16)/* rule applies to the sending side */
#define FILTRULE_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */
#define FILTRULE_CLEAR_LIST (1<<18)/* this item is the "!" token */
#define FILTRULE_PERISHABLE (1<<19)/* perishable if parent dir goes away */
#define MATCHFLGS_FROM_CONTAINER (MATCHFLG_ABS_PATH | MATCHFLG_INCLUDE \
| MATCHFLG_DIRECTORY | MATCHFLG_SENDER_SIDE \
| MATCHFLG_NEGATE | MATCHFLG_RECEIVER_SIDE \
| MATCHFLG_PERISHABLE)
#define FILTRULES_SIDES (FILTRULE_SENDER_SIDE | FILTRULE_RECEIVER_SIDE)
struct filter_struct {
typedef struct filter_struct {
struct filter_struct *next;
char *pattern;
uint32 match_flags;
uint32 rflags;
union {
int slash_cnt;
struct filter_list_struct *mergelist;
} u;
};
} filter_rule;
struct filter_list_struct {
struct filter_struct *head;
struct filter_struct *tail;
typedef struct filter_list_struct {
filter_rule *head;
filter_rule *tail;
filter_rule *parent_dirscan_head;
char *debug_type;
};
} filter_rule_list;
struct stats {
int64 total_size;
@@ -846,8 +903,10 @@ struct stats {
int64 flist_buildtime;
int64 flist_xfertime;
int64 flist_size;
int num_files;
int num_transferred_files;
int num_files, num_dirs, num_symlinks, num_devices, num_specials;
int created_files, created_dirs, created_symlinks, created_devices, created_specials;
int deleted_files, deleted_dirs, deleted_symlinks, deleted_devices, deleted_specials;
int xferred_files;
};
struct chmod_mode_struct;
@@ -882,13 +941,22 @@ typedef struct {
} xbuf;
#define INIT_XBUF(xb, str, ln, sz) (xb).buf = (str), (xb).len = (ln), (xb).size = (sz), (xb).pos = 0
#define INIT_XBUF_STRLEN(xb, str) (xb).buf = (str), (xb).len = strlen((xb).buf), (xb).size = (-1), (xb).pos = 0
#define INIT_XBUF_STRLEN(xb, str) (xb).buf = (str), (xb).len = strlen((xb).buf), (xb).size = (size_t)-1, (xb).pos = 0
/* This one is used to make an output xbuf based on a char[] buffer: */
#define INIT_CONST_XBUF(xb, bf) (xb).buf = (bf), (xb).size = sizeof (bf), (xb).len = (xb).pos = 0
#define ICB_EXPAND_OUT (1<<0)
#define ICB_INCLUDE_BAD (1<<1)
#define ICB_INCLUDE_INCOMPLETE (1<<2)
#define ICB_CIRCULAR_OUT (1<<3)
#define ICB_INIT (1<<4)
#define IOBUF_KEEP_BUFS 0
#define IOBUF_FREE_BUFS 1
#define MPLX_SWITCHING IOBUF_KEEP_BUFS
#define MPLX_ALL_DONE IOBUF_FREE_BUFS
#define MPLX_TO_BUFFERED 2
#define RL_EOL_NULLS (1<<0)
#define RL_DUMP_COMMENTS (1<<1)
@@ -976,6 +1044,9 @@ extern int errno;
#ifdef HAVE_READLINK
#define SUPPORT_LINKS 1
#if !defined NO_SYMLINK_XATTRS && !defined NO_SYMLINK_USER_XATTRS
#define do_readlink(path, buf, bufsiz) readlink(path, buf, bufsiz)
#endif
#endif
#ifdef HAVE_LINK
#define SUPPORT_HARD_LINKS 1
@@ -1155,7 +1226,53 @@ size_t strlcat(char *d, const char *s, size_t bufsize);
#define FD_ZERO(fdsetp) memset(fdsetp, 0, sizeof (fd_set))
#endif
extern int verbose;
extern short info_levels[], debug_levels[];
#define INFO_GTE(flag, lvl) (info_levels[INFO_##flag] >= (lvl))
#define INFO_EQ(flag, lvl) (info_levels[INFO_##flag] == (lvl))
#define DEBUG_GTE(flag, lvl) (debug_levels[DEBUG_##flag] >= (lvl))
#define DEBUG_EQ(flag, lvl) (debug_levels[DEBUG_##flag] == (lvl))
#define INFO_BACKUP 0
#define INFO_COPY (INFO_BACKUP+1)
#define INFO_DEL (INFO_COPY+1)
#define INFO_FLIST (INFO_DEL+1)
#define INFO_MISC (INFO_FLIST+1)
#define INFO_MOUNT (INFO_MISC+1)
#define INFO_NAME (INFO_MOUNT+1)
#define INFO_PROGRESS (INFO_NAME+1)
#define INFO_REMOVE (INFO_PROGRESS+1)
#define INFO_SKIP (INFO_REMOVE+1)
#define INFO_STATS (INFO_SKIP+1)
#define INFO_SYMSAFE (INFO_STATS+1)
#define COUNT_INFO (INFO_SYMSAFE+1)
#define DEBUG_ACL 0
#define DEBUG_BACKUP (DEBUG_ACL+1)
#define DEBUG_BIND (DEBUG_BACKUP+1)
#define DEBUG_CHDIR (DEBUG_BIND+1)
#define DEBUG_CONNECT (DEBUG_CHDIR+1)
#define DEBUG_CMD (DEBUG_CONNECT+1)
#define DEBUG_DEL (DEBUG_CMD+1)
#define DEBUG_DELTASUM (DEBUG_DEL+1)
#define DEBUG_DUP (DEBUG_DELTASUM+1)
#define DEBUG_EXIT (DEBUG_DUP+1)
#define DEBUG_FILTER (DEBUG_EXIT+1)
#define DEBUG_FLIST (DEBUG_FILTER+1)
#define DEBUG_FUZZY (DEBUG_FLIST+1)
#define DEBUG_GENR (DEBUG_FUZZY+1)
#define DEBUG_HASH (DEBUG_GENR+1)
#define DEBUG_HLINK (DEBUG_HASH+1)
#define DEBUG_ICONV (DEBUG_HLINK+1)
#define DEBUG_IO (DEBUG_ICONV+1)
#define DEBUG_OWN (DEBUG_IO+1)
#define DEBUG_PROTO (DEBUG_OWN+1)
#define DEBUG_RECV (DEBUG_PROTO+1)
#define DEBUG_SEND (DEBUG_RECV+1)
#define DEBUG_TIME (DEBUG_SEND+1)
#define COUNT_DEBUG (DEBUG_TIME+1)
#ifndef HAVE_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
@@ -1165,6 +1282,10 @@ const char *inet_ntop(int af, const void *src, char *dst, size_t size);
int inet_pton(int af, const char *src, void *dst);
#endif
#ifndef HAVE_GETPASS
char *getpass(const char *prompt);
#endif
#ifdef MAINTAINER_MODE
const char *get_panic_action(void);
#endif

476
rsync.yo
View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsync)(1)(23 Sep 2011)()()
manpage(rsync)(1)(28 Sep 2013)()()
manpagename(rsync)(a fast, versatile, remote (and local) file-copying tool)
manpagesynopsis()
@@ -331,6 +331,9 @@ manpagesection(OPTIONS SUMMARY)
Here is a short summary of the options available in rsync. Please refer
to the detailed description below for a complete description. verb(
-v, --verbose increase verbosity
--info=FLAGS fine-grained informational verbosity
--debug=FLAGS fine-grained debug verbosity
--msgs2stderr special output handling for debugging
-q, --quiet suppress non-error messages
--no-motd suppress daemon-mode MOTD (see caveat)
-c, --checksum skip based on checksum, not mod-time & size
@@ -351,6 +354,7 @@ to the detailed description below for a complete description. verb(
-L, --copy-links transform symlink into referent file/dir
--copy-unsafe-links only "unsafe" symlinks are transformed
--safe-links ignore symlinks that point outside the tree
--munge-links munge symlinks to make them safer
-k, --copy-dirlinks transform symlink to dir into referent dir
-K, --keep-dirlinks treat symlinked dir on receiver as dir
-H, --hard-links preserve hard links
@@ -366,9 +370,11 @@ to the detailed description below for a complete description. verb(
-D same as --devices --specials
-t, --times preserve modification times
-O, --omit-dir-times omit directories from --times
-J, --omit-link-times omit symlinks from --times
--super receiver attempts super-user activities
--fake-super store/recover privileged attrs using xattrs
-S, --sparse handle sparse files efficiently
--preallocate allocate dest files before writing
-n, --dry-run perform a trial run with no changes made
-W, --whole-file copy files whole (w/o delta-xfer algorithm)
-x, --one-file-system don't cross filesystem boundaries
@@ -385,6 +391,8 @@ to the detailed description below for a complete description. verb(
--delete-delay find deletions during, delete after
--delete-after receiver deletes after transfer, not during
--delete-excluded also delete excluded files from dest dirs
--ignore-missing-args ignore missing source args without error
--delete-missing-args delete missing source args from destination
--ignore-errors delete even if there are I/O errors
--force force deletion of dirs even if not empty
--max-delete=NUM don't delete more than NUM files
@@ -395,6 +403,9 @@ to the detailed description below for a complete description. verb(
--delay-updates put all updated files into place at end
-m, --prune-empty-dirs prune empty directory chains from file-list
--numeric-ids don't map uid/gid values by user/group name
--usermap=STRING custom username mapping
--groupmap=STRING custom groupname mapping
--chown=USER:GROUP simple username/groupname mapping
--timeout=SECONDS set I/O timeout in seconds
--contimeout=SECONDS set daemon connection timeout in seconds
-I, --ignore-times don't skip files that match size and time
@@ -423,18 +434,20 @@ to the detailed description below for a complete description. verb(
--port=PORT specify double-colon alternate port number
--sockopts=OPTIONS specify custom TCP options
--blocking-io use blocking I/O for the remote shell
--outbuf=N|L|B set out buffering to None, Line, or Block
--stats give some file-transfer stats
-8, --8-bit-output leave high-bit chars unescaped in output
-h, --human-readable output numbers in a human-readable format
--progress show progress during transfer
-P same as --partial --progress
-i, --itemize-changes output a change-summary for all updates
-M, --remote-option=OPTION send OPTION to the remote side only
--out-format=FORMAT output updates using the specified FORMAT
--log-file=FILE log what we're doing to the specified FILE
--log-file-format=FMT log updates using the specified FMT
--password-file=FILE read daemon-access password from FILE
--list-only list the files instead of copying them
--bwlimit=KBPS limit I/O bandwidth; KBytes per second
--bwlimit=RATE limit socket I/O bandwidth
--write-batch=FILE write a batched update to FILE
--only-write-batch=FILE like --write-batch but w/o updating dest
--read-batch=FILE read a batched update from FILE
@@ -450,8 +463,9 @@ Rsync can also be run as a daemon, in which case the following options are
accepted: verb(
--daemon run as an rsync daemon
--address=ADDRESS bind to the specified address
--bwlimit=KBPS limit I/O bandwidth; KBytes per second
--bwlimit=RATE limit socket I/O bandwidth
--config=FILE specify alternate rsyncd.conf file
-M, --dparam=OVERRIDE override global daemon config parameter
--no-detach do not detach from the parent
--port=PORT listen on alternate port number
--log-file=FILE override the "log file" setting
@@ -492,14 +506,67 @@ information on what files are being skipped and slightly more
information at the end. More than two bf(-v) options should only be used if
you are debugging rsync.
Note that the names of the transferred files that are output are done using
a default bf(--out-format) of "%n%L", which tells you just the name of the
file and, if the item is a link, where it points. At the single bf(-v)
level of verbosity, this does not mention when a file gets its attributes
changed. If you ask for an itemized list of changed attributes (either
bf(--itemize-changes) or adding "%i" to the bf(--out-format) setting), the
output (on the client) increases to mention all items that are changed in
any way. See the bf(--out-format) option for more details.
In a modern rsync, the bf(-v) option is equivalent to the setting of groups
of bf(--info) and bf(--debug) options. You can choose to use these newer
options in addition to, or in place of using bf(--verbose), as any
fine-grained settings override the implied settings of bf(-v). Both
bf(--info) and bf(--debug) have a way to ask for help that tells you
exactly what flags are set for each increase in verbosity.
dit(bf(--info=FLAGS))
This option lets you have fine-grained control over the
information
output you want to see. An individual flag name may be followed by a level
number, with 0 meaning to silence that output, 1 being the default output
level, and higher numbers increasing the output of that flag (for those
that support higher levels). Use
bf(--info=help)
to see all the available flag names, what they output, and what flag names
are added for each increase in the verbose level. Some examples:
verb( rsync -a --info=progress2 src/ dest/
rsync -avv --info=stats2,misc1,flist0 src/ dest/ )
Note that bf(--info=name)'s output is affected by the bf(--out-format) and
bf(--itemize-changes) (bf(-i)) options. See those options for more
information on what is output and when.
This option was added to 3.1.0, so an older rsync on the server side might
reject your attempts at fine-grained control (if one or more flags needed
to be send to the server and the server was too old to understand them).
dit(bf(--debug=FLAGS))
This option lets you have fine-grained control over the debug
output you want to see. An individual flag name may be followed by a level
number, with 0 meaning to silence that output, 1 being the default output
level, and higher numbers increasing the output of that flag (for those
that support higher levels). Use
bf(--debug=help)
to see all the available flag names, what they output, and what flag names
are added for each increase in the verbose level. Some examples:
verb( rsync -avvv --debug=none src/ dest/
rsync -avA --del --debug=del2,acl src/ dest/ )
Note that some debug messages will only be output when bf(--msgs2stderr) is
specified, especially those pertaining to I/O and buffer debugging.
This option was added to 3.1.0, so an older rsync on the server side might
reject your attempts at fine-grained control (if one or more flags needed
to be send to the server and the server was too old to understand them).
dit(bf(--msgs2stderr)) This option changes rsync to send all its output
directly to stderr rather than to send messages to the client side via the
protocol (which normally outputs info messages via stdout). This is mainly
intended for debugging in order to avoid changing the data sent via the
protocol, since the extra protocol data can change what is being tested.
Keep in mind that a daemon connection does not have a stderr channel to send
messages back to the client side, so if you are doing any daemon-transfer
debugging using this option, you should start up a daemon using bf(--no-detach)
so that you can see the stderr output on the daemon side.
This option has the side-effect of making stderr output get line-buffered so
that the merging of the output of 3 programs happens in a more readable manner.
dit(bf(-q, --quiet)) This option decreases the amount of information you
are given during the transfer, notably suppressing information messages
@@ -838,6 +905,25 @@ which point outside the copied tree. All absolute symlinks are
also ignored. Using this option in conjunction with bf(--relative) may
give unexpected results.
dit(bf(--munge-links)) This option tells rsync to (1) modify all symlinks on
the receiving side in a way that makes them unusable but recoverable (see
below), or (2) to unmunge symlinks on the sending side that had been stored in
a munged state. This is useful if you don't quite trust the source of the data
to not try to slip in a symlink to a unexpected place.
The way rsync disables the use of symlinks is to prefix each one with the
string "/rsyncd-munged/". This prevents the links from being used as long as
that directory does not exist. When this option is enabled, rsync will refuse
to run if that path is a directory or a symlink to a directory.
The option only affects the client side of the transfer, so if you need it to
affect the server, specify it via bf(--remote-option). (Note that in a local
transfer, the client side is the sender.)
This option has no affect on a daemon, since the daemon configures whether it
wants munged symlinks via its "munge symlinks" parameter. See also the
"munge-symlinks" perl script in the support directory of the source code.
dit(bf(-k, --copy-dirlinks)) This option causes the sending side to treat
a symlink to a directory as though it were a real directory. This is
useful if you don't want symlinks to non-directories to be affected, as
@@ -1025,6 +1111,10 @@ consistent executability across all bits:
quote(--chmod=Dg+s,ug+w,Fo-w,+X)
Using octal mode numbers is also allowed:
quote(--chmod=D2775,F664)
It is also legal to specify multiple bf(--chmod) options, as each
additional option is just appended to the list of changes to make.
@@ -1077,6 +1167,9 @@ it is preserving modification times (see bf(--times)). If NFS is sharing
the directories on the receiving side, it is a good idea to use bf(-O).
This option is inferred if you use bf(--backup) without bf(--backup-dir).
dit(bf(-J, --omit-link-times)) This tells rsync to omit symlinks when
it is preserving modification times (see bf(--times)).
dit(bf(--super)) This tells the receiving side to attempt super-user
activities even if the receiving rsync wasn't run by the super-user. These
activities include: preserving users via the bf(--owner) option, preserving
@@ -1103,16 +1196,16 @@ This is a good way to backup data without using a super-user, and to store
ACLs from incompatible systems.
The bf(--fake-super) option only affects the side where the option is used.
To affect the remote side of a remote-shell connection, specify an rsync
path:
To affect the remote side of a remote-shell connection, use the
bf(--remote-option) (bf(-M)) option:
quote(tt( rsync -av --rsync-path="rsync --fake-super" /src/ host:/dest/))
quote(tt( rsync -av -M--fake-super /src/ host:/dest/))
Since there is only one "side" in a local copy, this option affects both
the sending and receiving of files. You'll need to specify a copy using
"localhost" if you need to avoid this, possibly using the "lsh" shell
script (from the support directory) as a substitute for an actual remote
shell (see bf(--rsh)).
For a local copy, this option affects both the source and the destination.
If you wish a local copy to enable this option just for the destination
files, specify bf(-M--fake-super). If you wish a local copy to enable
this option just for the source files, combine bf(--fake-super) with
bf(-M--super).
This option is overridden by both bf(--super) and bf(--no-super).
@@ -1122,6 +1215,17 @@ dit(bf(-S, --sparse)) Try to handle sparse files efficiently so they take
up less space on the destination. Conflicts with bf(--inplace) because it's
not possible to overwrite data in a sparse fashion.
dit(bf(--preallocate)) This tells the receiver to allocate each destination
file to its eventual size before writing data to the file. Rsync will only use
the real filesystem-level preallocation support provided by Linux's
bf(fallocate)(2) system call or Cygwin's bf(posix_fallocate)(3), not the slow
glibc implementation that writes a zero byte into each block.
Without this option, larger files may not be entirely contiguous on the
filesystem, but with this option rsync will probably copy more slowly. If the
destination is not an extent-supporting filesystem (such as ext4, xfs, NTFS,
etc.), this option may have no positive effect at all.
dit(bf(-n, --dry-run)) This makes rsync perform a trial run that doesn't
make any changes (and produces mostly the same output as a real run). It
is most commonly used in combination with the bf(-v, --verbose) and/or
@@ -1203,6 +1307,9 @@ transferring files that are not yet finished (e.g. name the file "foo.new" when
it is written, rename it to "foo" when it is done, and then use the option
bf(--exclude='*.new') for the rsync transfer).
Starting with 3.1.0, rsync will skip the sender-side removal (and output an
error) if the file's size or modify time has not stayed unchanged.
dit(bf(--delete)) This tells rsync to delete extraneous files from the
receiving side (ones that aren't on the sending side), but only for the
directories that are being synchronized. You must have asked rsync to
@@ -1286,6 +1393,23 @@ this way on the receiver, and for a way to protect files from
bf(--delete-excluded).
See bf(--delete) (which is implied) for more details on file-deletion.
dit(bf(--ignore-missing-args)) When rsync is first processing the explicitly
requested source files (e.g. command-line arguments or bf(--files-from)
entries), it is normally an error if the file cannot be found. This option
suppresses that error, and does not try to transfer the file. This does not
affect subsequent vanished-file errors if a file was initially found to be
present and later is no longer there.
dit(bf(--delete-missing-args)) This option takes the behavior of (the implied)
bf(--ignore-missing-args) option a step farther: each missing arg will become
a deletion request of the corresponding destination file on the receiving side
(should it exist). If the destination file is a non-empty directory, it will
only be successfully deleted if --force or --delete are in effect. Other than
that, this option is independent of any other type of delete processing.
The missing source files are represented by special file-list entries which
display as a "*missing" entry in the bf(--list-only) output.
dit(bf(--ignore-errors)) Tells bf(--delete) to go ahead and delete files
even when there are I/O errors.
@@ -1298,15 +1422,17 @@ using bf(--delete-after), and it used to be non-functional unless the
bf(--recursive) option was also enabled.
dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM
files or directories. If that limit is exceeded, a warning is output
and rsync exits with an error code of 25 (new for 3.0.0).
files or directories. If that limit is exceeded, all further deletions are
skipped through the end of the transfer. At the end, rsync outputs a warning
(including a count of the skipped deletions) and exits with an error code
of 25 (unless some more important error condition also occurred).
Also new for version 3.0.0, you may specify bf(--max-delete=0) to be warned
Beginning with version 3.0.0, you may specify bf(--max-delete=0) to be warned
about any extraneous files in the destination without removing any of them.
Older clients interpreted this as "unlimited", so if you don't know what
version the client is, you can use the less obvious bf(--max-delete=-1) as
a backward-compatible way to specify that no deletions be allowed (though
older versions didn't warn when the limit was exceeded).
really old versions didn't warn when the limit was exceeded).
dit(bf(--max-size=SIZE)) This tells rsync to avoid transferring any
file that is larger than the specified SIZE. The SIZE value can be
@@ -1328,11 +1454,15 @@ be offset by one byte in the indicated direction.
Examples: --max-size=1.5mb-1 is 1499999 bytes, and --max-size=2g+1 is
2147483649 bytes.
Note that rsync versions prior to 3.1.0 did not allow bf(--max-size=0).
dit(bf(--min-size=SIZE)) This tells rsync to avoid transferring any
file that is smaller than the specified SIZE, which can help in not
transferring small, junk files.
See the bf(--max-size) option for a description of SIZE and other information.
Note that rsync versions prior to 3.1.0 did not allow bf(--min-size=0).
dit(bf(-B, --block-size=BLOCKSIZE)) This forces the block size used in
rsync's delta-transfer algorithm to a fixed value. It is normally selected based on
the size of each file being updated. See the technical report for details.
@@ -1384,6 +1514,36 @@ machine for use with the bf(--relative) option. For instance:
quote(tt( rsync -avR --rsync-path="cd /a/b && rsync" host:c/d /e/))
dit(bf(-M, --remote-option=OPTION)) This option is used for more advanced
situations where you want certain effects to be limited to one side of the
transfer only. For instance, if you want to pass bf(--log-file=FILE) and
bf(--fake-super) to the remote system, specify it like this:
quote(tt( rsync -av -M --log-file=foo -M--fake-super src/ dest/))
If you want to have an option affect only the local side of a transfer when
it normally affects both sides, send its negation to the remote side. Like
this:
quote(tt( rsync -av -x -M--no-x src/ dest/))
Be cautious using this, as it is possible to toggle an option that will cause
rsync to have a different idea about what data to expect next over the socket,
and that will make it fail in a cryptic fashion.
Note that it is best to use a separate bf(--remote-option) for each option you
want to pass. This makes your useage compatible with the bf(--protect-args)
option. If that option is off, any spaces in your remote options will be split
by the remote shell unless you take steps to protect them.
When performing a local transfer, the "local" side is the sender and the
"remote" side is the receiver.
Note some versions of the popt option-parsing library have a bug in them that
prevents you from using an adjacent arg with an equal in it next to a short
option letter (e.g. tt(-M--log-file=/tmp/foo). If this bug affects your
version of popt, you can use the version of popt that is included with rsync.
dit(bf(-C, --cvs-exclude)) This is a useful shorthand for excluding a
broad range of files that you often don't want to transfer between
systems. It uses a similar algorithm to CVS to determine if
@@ -1548,6 +1708,20 @@ side will also be translated
from the local to the remote character-set. The translation happens before
wild-cards are expanded. See also the bf(--files-from) option.
You may also control this option via the RSYNC_PROTECT_ARGS environment
variable. If this variable has a non-zero value, this option will be enabled
by default, otherwise it will be disabled by default. Either state is
overridden by a manually specified positive or negative version of this option
(note that bf(--no-s) and bf(--no-protect-args) are the negative versions).
Since this option was first introduced in 3.0.0, you'll need to make sure it's
disabled if you ever need to interact with a remote rsync that is older than
that.
Rsync can also be configured (at build time) to have this option enabled by
default (with is overridden by both the environment and the command-line).
This option will eventually become a new default setting at some
as-yet-undetermined point in the future.
dit(bf(-T, --temp-dir=DIR)) This option instructs rsync to use DIR as a
scratch directory when creating temporary copies of the files transferred
on the receiving side. The default behavior is to create each temporary
@@ -1586,6 +1760,10 @@ looks in the same directory as the destination file for either a file that
has an identical size and modified-time, or a similarly-named file. If
found, rsync uses the fuzzy basis file to try to speed up the transfer.
If the option is repeated, the fuzzy scan will also be done in any matching
alternate destination directories that are specified via bf(--compare-dest),
bf(--copy-dest), or bf(--link-dest).
Note that the use of the bf(--delete) option might get rid of any potential
fuzzy-match files, so either use bf(--delete-after) or specify some
filename exclusions if you need to prevent this.
@@ -1597,6 +1775,8 @@ directory). If a file is found in em(DIR) that is identical to the
sender's file, the file will NOT be transferred to the destination
directory. This is useful for creating a sparse backup of just files that
have changed from an earlier backup.
This option is typically used to copy into an empty (or newly created)
directory.
Beginning in version 2.6.4, multiple bf(--compare-dest) directories may be
provided, which will cause rsync to search the list in the order specified
@@ -1609,6 +1789,10 @@ selected to try to speed up the transfer.
If em(DIR) is a relative path, it is relative to the destination directory.
See also bf(--copy-dest) and bf(--link-dest).
NOTE: beginning with version 3.1.0, rsync will remove a file from a non-empty
destination hierarchy if an exact match is found in one of the compare-dest
hierarchies (making the end result more closely match a fresh copy).
dit(bf(--copy-dest=DIR)) This option behaves like bf(--compare-dest), but
rsync will also copy unchanged files found in em(DIR) to the destination
directory using a local copy.
@@ -1646,10 +1830,11 @@ If a match is not found, a basis file from one of the em(DIR)s will be
selected to try to speed up the transfer.
This option works best when copying into an empty destination hierarchy, as
rsync treats existing files as definitive (so it never looks in the link-dest
dirs when a destination file already exists), and as malleable (so it might
change the attributes of a destination file, which affects all the hard-linked
versions).
existing files may get their attributes tweaked, and that can affect alternate
destination files via hard-links. Also, itemizing of changes can get a bit
muddled. Note that prior to version 3.1.0, an alternate-directory exact match
would never be found (nor linked into the destination) when a destination file
already exists.
Note that if you combine this option with bf(--ignore-times), rsync will not
link any files together because it only links identical files together as a
@@ -1701,20 +1886,31 @@ The default list of suffixes that will not be compressed is this (in this
version of rsync):
bf(7z)
bf(ace)
bf(avi)
bf(bz2)
bf(deb)
bf(gpg)
bf(gz)
bf(iso)
bf(jpeg)
bf(jpg)
bf(lz)
bf(lzma)
bf(lzo)
bf(mov)
bf(mp3)
bf(mp4)
bf(ogg)
bf(png)
bf(rar)
bf(rpm)
bf(rzip)
bf(tbz)
bf(tgz)
bf(tlz)
bf(txz)
bf(xz)
bf(z)
bf(zip)
@@ -1739,6 +1935,57 @@ from the source system is used instead. See also the comments on the
the chroot setting affects rsync's ability to look up the names of the
users and groups and what you can do about it.
dit(bf(--usermap=STRING, --groupmap=STRING)) These options allow you to
specify users and groups that should be mapped to other values by the
receiving side. The bf(STRING) is one or more bf(FROM):bf(TO) pairs of
values separated by commas. Any matching bf(FROM) value from the sender is
replaced with a bf(TO) value from the receiver. You may specify usernames
or user IDs for the bf(FROM) and bf(TO) values, and the bf(FROM) value may
also be a wild-card string, which will be matched against the sender's
names (wild-cards do NOT match against ID numbers, though see below for
why a '*' matches everything). You may instead specify a range of ID
numbers via an inclusive range: LOW-HIGH. For example:
verb( --usermap=0-99:nobody,wayne:admin,*:normal --groupmap=usr:1,1:usr)
The first match in the list is the one that is used. You should specify
all your user mappings using a single bf(--usermap) option, and/or all
your group mappings using a single bf(--groupmap) option.
Note that the sender's name for the 0 user and group are not transmitted
to the receiver, so you should either match these values using a 0, or use
the names in effect on the receiving side (typically "root"). All other
bf(FROM) names match those in use on the sending side. All bf(TO) names
match those in use on the receiving side.
Any IDs that do not have a name on the sending side are treated as having an
empty name for the purpose of matching. This allows them to be matched via
a "*" or using an empty name. For instance:
verb( --usermap=:nobody --groupmap=*:nobody)
When the bf(--numeric-ids) option is used, the sender does not send any
names, so all the IDs are treated as having an empty name. This means that
you will need to specify numeric bf(FROM) values if you want to map these
nameless IDs to different values.
For the bf(--usermap) option to have any effect, the bf(-o) (bf(--owner))
option must be used (or implied), and the receiver will need to be running
as a super-user (see also the bf(--fake-super) option). For the bf(--groupmap)
option to have any effect, the bf(-g) (bf(--groups)) option must be used
(or implied), and the receiver will need to have permissions to set that
group.
dit(bf(--chown=USER:GROUP)) This option forces all files to be owned by USER
with group GROUP. This is a simpler interface than using bf(--usermap) and
bf(--groupmap) directly, but it is implemented using those options internally,
so you cannot mix them. If either the USER or GROUP is empty, no mapping for
the omitted user/group will occur. If GROUP is empty, the trailing colon may
be omitted, but if USER is empty, a leading colon must be supplied.
If you specify "--chown=foo:bar, this is exactly the same as specifying
"--usermap=*:foo --groupmap=*:bar", only easier.
dit(bf(--timeout=TIMEOUT)) This option allows you to set a maximum I/O
timeout in seconds. If no data is transferred for the specified time
then rsync will exit. The default is 0, which means no timeout.
@@ -1773,6 +2020,13 @@ rsync defaults to using
blocking I/O, otherwise it defaults to using non-blocking I/O. (Note that
ssh prefers non-blocking I/O.)
dit(bf(--outbuf=MODE)) This sets the output buffering mode. The mode can be
None (aka Unbuffered), Line, or Block (aka Full). You may specify as little
as a single letter for the mode, and use upper or lower case.
The main use of this option is to change Full buffering to Line buffering
when rsync's output is going to a file or pipe.
dit(bf(-i, --itemize-changes)) Requests a simple itemized list of the
changes that are being made to each file, including attribute changes.
This is exactly the same as specifying bf(--out-format='%i %n%L').
@@ -1852,13 +2106,13 @@ dit(bf(--out-format=FORMAT)) This allows you to specify exactly what the
rsync client outputs to the user on a per-update basis. The format is a
text string containing embedded single-character escape sequences prefixed
with a percent (%) character. A default format of "%n%L" is assumed if
bf(-v) is specified (which reports the name
either bf(--info=name) or bf(-v) is specified (this tells you just the name
of the file and, if the item is a link, where it points). For a full list
of the possible escape characters, see the "log format" setting in the
rsyncd.conf manpage.
Specifying the bf(--out-format) option
will mention each file, dir, etc. that gets updated in a significant
Specifying the bf(--out-format) option implies the bf(--info=name) option,
which will mention each file, dir, etc. that gets updated in a significant
way (a transferred file, a recreated symlink/device, or a touched
directory). In addition, if the itemize-changes escape (%i) is included in
the string (e.g. if the bf(--itemize-changes) option was used), the logging
@@ -1883,7 +2137,7 @@ option if you wish to override this.
Here's a example command that requests the remote side to log what is
happening:
verb( rsync -av --rsync-path="rsync --log-file=/tmp/rlog" src/ dest/)
verb( rsync -av --remote-option=--log-file=/tmp/rlog src/ dest/)
This is very useful if you need to debug why a connection is closing
unexpectedly.
@@ -1900,14 +2154,29 @@ is '%i %n%L'.
dit(bf(--stats)) This tells rsync to print a verbose set of statistics
on the file transfer, allowing you to tell how effective rsync's delta-transfer
algorithm is for your data.
algorithm is for your data. This option is equivalent to bf(--info=stats2)
if combined with 0 or 1 bf(-v) options, or bf(--info=stats3) if combined
with 2 or more bf(-v) options.
The current statistics are as follows: quote(itemization(
it() bf(Number of files) is the count of all "files" (in the generic
sense), which includes directories, symlinks, etc.
it() bf(Number of files transferred) is the count of normal files that
were updated via rsync's delta-transfer algorithm, which does not include created
dirs, symlinks, etc.
sense), which includes directories, symlinks, etc. The total count will
be followed by a list of counts by filetype (if the total is non-zero).
For example: "(reg: 5, dir: 3, link: 2, dev: 1, special: 1)" lists the
totals for regular files, directories, symlinks, devices, and special
files. If any of value is 0, it is completely omitted from the list.
it() bf(Number of created files) is the count of how many "files" (generic
sense) were created (as opposed to updated). The total count will be
followed by a list of counts by filetype (if the total is non-zero).
it() bf(Number of deleted files) is the count of how many "files" (generic
sense) were created (as opposed to updated). The total count will be
followed by a list of counts by filetype (if the total is non-zero).
Note that this line is only output if deletions are in effect, and only
if protocol 31 is being used (the default for rsync 3.1.x).
it() bf(Number of regular files transferred) is the count of normal files
that were updated via rsync's delta-transfer algorithm, which does not
include dirs, symlinks, etc. Note that rsync 3.1.0 added the word
"regular" into this heading.
it() bf(Total file size) is the total sum of all file sizes in the transfer.
This does not count any size for directories or special files, but does
include the size of symlinks.
@@ -1946,10 +2215,25 @@ would output as "\#012". A literal backslash that is in a filename is not
escaped unless it is followed by a hash and 3 digits (0-9).
dit(bf(-h, --human-readable)) Output numbers in a more human-readable format.
This makes big numbers output using larger units, with a K, M, or G suffix. If
this option was specified once, these units are K (1000), M (1000*1000), and
G (1000*1000*1000); if the option is repeated, the units are powers of 1024
instead of 1000.
There are 3 possible levels: (1) output numbers with a separator between each
set of 3 digits (either a comma or a period, depending on if the decimal point
is represented by a period or a comma); (2) output numbers in units of 1000
(with a character suffix for larger units -- see below); (3) output numbers in
units of 1024.
The default is human-readable level 1. Each bf(-h) option increases the level
by one. You can take the level down to 0 (to output numbers as pure digits) by
specifing the bf(--no-human-readable) (bf(--no-h)) option.
The unit letters that are appended in levels 2 and 3 are: K (kilo), M (mega),
G (giga), or T (tera). For example, a 1234567-byte file would output as 1.23M
in level-2 (assuming that a period is your local decimal point).
Backward compatibility note: versions of rsync prior to 3.1.0 do not support
human-readable level 1, and they default to level 0. Thus, specifying one or
two bf(-h) options will behave in a comparable manner in old and new versions
as long as you didn't specify a bf(--no-h) option prior to one or more bf(-h)
options. See the bf(--list-only) option for one difference.
dit(bf(--partial)) By default, rsync will delete any partially
transferred file if the transfer is interrupted. In some circumstances
@@ -2078,7 +2362,9 @@ in place of the hide-filter (if that is more natural to you).
dit(bf(--progress)) This option tells rsync to print information
showing the progress of the transfer. This gives a bored user
something to watch.
Implies bf(--verbose) if it wasn't already specified.
With a modern rsync this is the same as specifying
bf(--info=flist2,name,progress), but any user-supplied settings for those
info flags takes precedence (e.g. "--info=flist0 --progress").
While rsync is transferring a regular file, it updates a progress line that
looks like this:
@@ -2100,23 +2386,41 @@ was finishing the matched part of the file.
When the file transfer finishes, rsync replaces the progress line with a
summary line that looks like this:
verb( 1238099 100% 146.38kB/s 0:00:08 (xfer#5, to-check=169/396))
verb( 1,238,099 100% 146.38kB/s 0:00:08 (xfr#5, to-chk=169/396))
In this example, the file was 1238099 bytes long in total, the average rate
In this example, the file was 1,238,099 bytes long in total, the average rate
of transfer for the whole file was 146.38 kilobytes per second over the 8
seconds that it took to complete, it was the 5th transfer of a regular file
during the current rsync session, and there are 169 more files for the
receiver to check (to see if they are up-to-date or not) remaining out of
the 396 total files in the file-list.
In an incremental recursion scan, rsync won't know the total number of files
in the file-list until it reaches the ends of the scan, but since it starts to
transfer files during the scan, it will display a line with the text "ir-chk"
(for incremental recursion check) instead of "to-chk" until the point that it
knows the full size of the list, at which point it will switch to using
"to-chk". Thus, seeing "ir-chk" lets you know that the total count of files
in the file list is still going to increase (and each time it does, the count
of files left to check will increase by the number of the files added to the
list).
dit(bf(-P)) The bf(-P) option is equivalent to bf(--partial) bf(--progress). Its
purpose is to make it much easier to specify these two options for a long
transfer that may be interrupted.
dit(bf(--password-file)) This option allows you to provide a password in a
file for accessing an rsync daemon. The file must not be world readable.
It should contain just the password as the first line of the file (all
other lines are ignored).
There is also a bf(--info=progress2) option that outputs statistics based
on the whole transfer, rather than individual files. Use this flag without
outputting a filename (e.g. avoid bf(-v) or specify bf(--info=name0) if you
want to see how the transfer is doing without scrolling the screen with a
lot of names. (You don't need to specify the bf(--progress) option in
order to use bf(--info=progress2).)
dit(bf(--password-file=FILE)) This option allows you to provide a password for
accessing an rsync daemon via a file or via standard input if bf(FILE) is
bf(-). The file should contain just the password on the first line (all other
lines are ignored). Rsync will exit with an error if bf(FILE) is world
readable or if a root-run rsync command finds a non-root-owned file.
This option does not supply a password to a remote shell transport such as
ssh; to learn how to do that, consult the remote shell's documentation.
@@ -2137,6 +2441,14 @@ without using this option. For example:
verb( rsync -av --list-only foo* dest/)
Starting with rsync 3.1.0, the sizes output by bf(--list-only) are affected
by the bf(--human-readable) option. By default they will contain digit
separators, but higher levels of readability will output the sizes with
unit suffixes. Note also that the column width for the size output has
increased from 11 to 14 characters for all human-readable levels. Use
bf(--no-h) if you want just digits in the sizes, and the old column width
of 11 characters.
Compatibility note: when requesting a remote listing of files from an rsync
that is version 2.6.3 or older, you may encounter an error if you ask for a
non-recursive listing. This is because a file listing implies the bf(--dirs)
@@ -2145,13 +2457,27 @@ avoid this problem, either specify the bf(--no-dirs) option (if you don't
need to expand a directory's content), or turn on recursion and exclude
the content of subdirectories: bf(-r --exclude='/*/*').
dit(bf(--bwlimit=KBPS)) This option allows you to specify a maximum
transfer rate in kilobytes per second. This option is most effective when
using rsync with large files (several megabytes and up). Due to the nature
of rsync transfers, blocks of data are sent, then if rsync determines the
transfer was too fast, it will wait before sending the next data block. The
result is an average transfer rate equaling the specified limit. A value
of zero specifies no limit.
dit(bf(--bwlimit=RATE)) This option allows you to specify the maximum transfer
rate for the data sent over the socket, specified in units per second. The
RATE value can be suffixed with a string to indicate a size multiplier, and may
be a fractional value (e.g. "bf(--bwlimit=1.5m)"). If no suffix is specified,
the value will be assumed to be in units of 1024 bytes (as if "K" or "KiB" had
been appended). See the bf(--max-size) option for a description of all the
available suffixes. A value of zero specifies no limit.
For backward-compatibility reasons, the rate limit will be rounded to the
nearest KiB unit, so no rate smaller than 1024 bytes per second is possible.
Rsync writes data over the socket in blocks, and this option both limits the
size of the blocks that rsync writes, and tries to keep the average transfer
rate at the requested limit. Some "burstiness" may be seen where rsync writes
out a block of data and then sleeps to bring the average rate into compliance.
Due to the internal buffering of data, the bf(--progress) option may not be an
accurate reflection on how fast the data is being sent. This is because some
files can show up as being rapidly sent when the data is quickly buffered,
while other can show up as very slow when the flushing of the output buffer
occurs. This may be fixed in a future version.
dit(bf(--write-batch=FILE)) Record a file that can later be applied to
another identical destination with bf(--read-batch). See the "BATCH MODE"
@@ -2226,15 +2552,15 @@ If rsync was complied without support for IPv6, the bf(--ipv6) option
will have no effect. The bf(--version) output will tell you if this
is the case.
dit(bf(--checksum-seed=NUM)) Set the checksum seed to the integer
NUM. This 4 byte checksum seed is included in each block and file
checksum calculation. By default the checksum seed is generated
by the server and defaults to the current code(time()). This option
is used to set a specific checksum seed, which is useful for
applications that want repeatable block and file checksums, or
in the case where the user wants a more random checksum seed.
Setting NUM to 0 causes rsync to use the default of code(time())
for checksum seed.
dit(bf(--checksum-seed=NUM)) Set the checksum seed to the integer NUM. This 4
byte checksum seed is included in each block and MD4 file checksum calculation
(the more modern MD5 file checksums don't use a seed). By default the checksum
seed is generated by the server and defaults to the current code(time()). This
option is used to set a specific checksum seed, which is useful for
applications that want repeatable block checksums, or in the case where the
user wants a more random checksum seed. Setting NUM to 0 causes rsync to use
the default of code(time()) for checksum seed.
enddit()
manpagesection(DAEMON OPTIONS)
@@ -2259,11 +2585,10 @@ allows you to specify a specific IP address (or hostname) to bind to. This
makes virtual hosting possible in conjunction with the bf(--config) option.
See also the "address" global option in the rsyncd.conf manpage.
dit(bf(--bwlimit=KBPS)) This option allows you to specify a maximum
transfer rate in kilobytes per second for the data the daemon sends.
The client can still specify a smaller bf(--bwlimit) value, but their
requested value will be rounded down if they try to exceed it. See the
client version of this option (above) for some extra details.
dit(bf(--bwlimit=RATE)) This option allows you to specify the maximum transfer
rate for the data the daemon sends over the socket. The client can still
specify a smaller bf(--bwlimit) value, but no larger value will be allowed.
See the client version of this option (above) for some extra details.
dit(bf(--config=FILE)) This specifies an alternate config file than
the default. This is only relevant when bf(--daemon) is specified.
@@ -2271,6 +2596,14 @@ The default is /etc/rsyncd.conf unless the daemon is running over
a remote shell program and the remote user is not the super-user; in that case
the default is rsyncd.conf in the current directory (typically $HOME).
dit(bf(-M, --dparam=OVERRIDE)) This option can be used to set a daemon-config
parameter when starting up rsync in daemon mode. It is equivalent to adding
the parameter at the end of the global settings prior to the first module's
definition. The parameter names can be specified without spaces, if you so
desire. For instance:
verb( rsync --daemon -M pidfile=/path/rsync.pid )
dit(bf(--no-detach)) When running as a daemon, this option instructs
rsync to not detach itself and become a background process. This
option is required when running as a service on Cygwin, and may also
@@ -2981,6 +3314,9 @@ ignore patterns in .cvsignore files. See the bf(--cvs-exclude) option for
more details.
dit(bf(RSYNC_ICONV)) Specify a default bf(--iconv) setting using this
environment variable. (First supported in 3.0.0.)
dit(bf(RSYNC_PROTECT_ARGS)) Specify a non-zero numeric value if you want the
bf(--protect-args) option to be enabled by default, or a zero value to make
sure that it is disabled by default. (First supported in 3.1.0.)
dit(bf(RSYNC_RSH)) The RSYNC_RSH environment variable allows you to
override the default shell used as the transport for rsync. Command line
options are permitted after the command name, just as in the bf(-e) option.
@@ -3025,7 +3361,7 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
manpagesection(VERSION)
This man page is current for version 3.0.9 of rsync.
This man page is current for version 3.1.0 of rsync.
manpagesection(INTERNAL OPTIONS)
@@ -3039,7 +3375,7 @@ ssh login.
manpagesection(CREDITS)
rsync is distributed under the GNU public license. See the file
rsync is distributed under the GNU General Public License. See the file
COPYING for details.
A WEB site is available at

View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsyncd.conf)(5)(23 Sep 2011)()()
manpage(rsyncd.conf)(5)(28 Sep 2013)()()
manpagename(rsyncd.conf)(configuration file for rsync in daemon mode)
manpagesynopsis()
@@ -28,8 +28,9 @@ whitespace in module and parameter names is irrelevant. Leading and
trailing whitespace in a parameter value is discarded. Internal whitespace
within a parameter value is retained verbatim.
Any line beginning with a hash (#) is ignored, as are lines containing
only whitespace.
Any line bf(beginning) with a hash (#) is ignored, as are lines containing
only whitespace. (If a hash occurs after anything other than leading
whitespace, it is considered a part of the line's content.)
Any line ending in a \ is "continued" on the next line in the
customary UNIX fashion.
@@ -78,15 +79,31 @@ You may also include any module parameters in the global part of the
config file in which case the supplied value will override the
default for that parameter.
You may use references to environment variables in the values of parameters.
String parameters will have %VAR% references expanded as late as possible (when
the string is used in the program), allowing for the use of variables that
rsync sets at connection time, such as RSYNC_USER_NAME. Non-string parameters
(such as true/false settings) are expanded when read from the config file. If
a variable does not exist in the environment, or if a sequence of characters is
not a valid reference (such as an un-paired percent sign), the raw characters
are passed through unchanged. This helps with backward compatibility and
safety (e.g. expanding a non-existent %VAR% to an empty string in a path could
result in a very unsafe path). The safest way to insert a literal % into a
value is to use %%.
startdit()
dit(bf(motd file)) This parameter allows you to specify a
"message of the day" to display to clients on each connect. This
usually contains site information and any legal notices. The default
is no motd file.
This can be overridden by the bf(--dparam=motdfile=FILE)
command-line option when starting the daemon.
dit(bf(pid file)) This parameter tells the rsync daemon to write
its process ID to that file. If the file already exists, the rsync
daemon will abort rather than overwrite the file.
This can be overridden by the bf(--dparam=pidfile=FILE)
command-line option when starting the daemon.
dit(bf(port)) You can override the default port the daemon will listen on
by specifying this value (defaults to 873). This is ignored if the daemon
@@ -104,6 +121,9 @@ details on some of the options you may be able to set. By default no
special socket options are set. These settings can also be specified
via the bf(--sockopts) command-line option.
dit(bf(listen backlog)) You can override the default backlog value when the
daemon listens for connections. It defaults to 5.
enddit()
manpagesection(MODULE PARAMETERS)
@@ -117,6 +137,9 @@ name contains whitespace, each internal sequence of whitespace will be
changed into a single space, while leading or trailing whitespace will be
discarded.
As with GLOBAL PARAMETERS, you may use references to environment variables in
the values of parameters. See the GLOBAL PARAMETERS section for more details.
startdit()
dit(bf(comment)) This parameter specifies a description string
@@ -127,6 +150,13 @@ dit(bf(path)) This parameter specifies the directory in the daemon's
filesystem to make available in this module. You must specify this parameter
for each module in tt(rsyncd.conf).
You may base the path's value off of an environment variable by surrounding
the variable name with percent signs. You can even reference a variable
that is set by rsync when the user connects.
For example, this would use the authorizing user's name in the path:
verb( path = /home/%RSYNC_USER_NAME% )
It is fine if the path includes internal spaces -- they will be retained
verbatim (which means that you shouldn't try to escape them). If your final
directory has a trailing space (and this is somehow not something you wish to
@@ -197,8 +227,9 @@ to translate names, and that it is not possible for a user to change those
resources.
dit(bf(munge symlinks)) This parameter tells rsync to modify
all incoming symlinks in a way that makes them unusable but recoverable
(see below). This should help protect your files from user trickery when
all symlinks in the same way as the (non-daemon-affecting)
bf(--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 and the inside-chroot path is "/", otherwise it is enabled.
@@ -266,6 +297,12 @@ If the daemon fails to open the specified file, it will fall back to
using syslog and output an error about the failure. (Note that the
failure to open the specified log file used to be a fatal error.)
This setting can be overridden by using the bf(--log-file=FILE) or
bf(--dparam=logfile=FILE) command-line options. The former overrides
all the log-file parameters of the daemon and all module settings.
The latter sets the daemon's log file and the default for all the
modules, which still allows modules to override the default setting.
dit(bf(syslog facility)) This parameter allows you to
specify the syslog facility name to use when logging messages from the
rsync daemon. You may use any standard syslog facility name which is
@@ -293,27 +330,46 @@ 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.
dit(bf(write only)) This parameter determines whether clients
will be able to download files or not. If "write only" is true then any
attempted downloads will fail. If "write only" is false then downloads
will be possible if file permissions on the daemon side allow them. The
default is for this parameter to be disabled.
dit(bf(list)) This parameter determines if this module should be
listed when the client asks for a listing of available modules. By
setting this to false you can create hidden modules. The default is
for modules to be listable.
dit(bf(list)) This parameter determines whether this module is
listed when the client asks for a listing of available modules. In addition,
if this is false, the daemon will pretend the module does not exist
when a client denied by "hosts allow" or "hosts deny" attempts to access it.
Realize that if "reverse lookup" is disabled globally but enabled for the
module, the resulting reverse lookup to a potentially client-controlled DNS
server may still reveal to the client that it hit an existing module.
The default is for modules to be listable.
dit(bf(uid)) This parameter specifies the user name or user ID that
file transfers to and from that module should take place as when the daemon
was run as root. In combination with the "gid" parameter this determines what
file permissions are available. The default is uid -2, which is normally
the user "nobody".
file permissions are available. The default when run by a super-user is to
switch to the system's "nobody" user. The default for a non-super-user is to
not try to change the user. See also the "gid" parameter.
dit(bf(gid)) This parameter specifies the group name or group ID that
file transfers to and from that module should take place as when the daemon
was run as root. This complements the "uid" parameter. The default is gid -2,
which is normally the group "nobody".
The RSYNC_USER_NAME environment variable may be used to request that rsync run
as the authorizing user. For example, if you want a rsync to run as the same
user that was received for the rsync authentication, this setup is useful:
verb( uid = %RSYNC_USER_NAME%
gid = * )
dit(bf(gid)) This parameter specifies one or more group names/IDs that will be
used when accessing the module. The first one will be the default group, and
any extra ones be set as supplemental groups. You may also specify a "*" as
the first gid in the list, which will be replaced by all the normal groups for
the transfer's user (see "uid"). The default when run by a super-user is to
switch to your OS's "nobody" (or perhaps "nogroup") group with no other
supplementary groups. The default for a non-super-user is to not change any
group attributes (and indeed, your OS may not allow a non-super-user to try to
change their group settings).
dit(bf(fake super)) Setting "fake super = yes" for a module causes the
daemon side to behave as if the bf(--fake-super) command-line option had
@@ -388,10 +444,12 @@ be on to the clients.
See the description of the bf(--chmod) rsync option and the bf(chmod)(1)
manpage for information on the format of this string.
dit(bf(auth users)) This parameter specifies a comma and
space-separated list of usernames that will be allowed to connect to
dit(bf(auth users)) This parameter specifies a comma and/or space-separated
list of authorization rules. In its simplest form, you list the usernames
that will be allowed to connect to
this module. The usernames do not need to exist on the local
system. The usernames may also contain shell wildcard characters. If
system. The rules may contain shell wildcard characters that will be matched
against the username provided by the client for 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
@@ -399,24 +457,65 @@ 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 must be a
real user on the system, or it will be assumed to be a member of no groups.
For example, specifying "@rsync" will match the authenticating user if the
named user is a member of the rsync group.
Finally, options may be specified after a colon (:). The options allow you to
"deny" a user or a group, set the access to "ro" (read-only), or set the access
to "rw" (read/write). Setting an auth-rule-specific ro/rw setting overrides
the module's "read only" setting.
Be sure to put the rules in the order you want them to be matched, because the
checking stops at the first matching user or group, and that is the only auth
that is checked. For example:
verb( auth users = joe:deny @guest:deny admin:rw @rsync:ro susan joe sam )
In the above rule, user joe will be denied access no matter what. Any user
that is in the group "guest" is also denied access. The user "admin" gets
access in read/write mode, but only if the admin user is not in group "guest"
(because the admin user-matching rule would never be reached if the user is in
group "guest"). Any other user who is in group "rsync" will get read-only
access. Finally, users susan, joe, and sam get the ro/rw setting of the
module, but only if the user didn't match an earlier group-matching rule.
See the description of the secrets file for how you can have per-user passwords
as well as per-group passwords. It also explains how a user can authenticate
using their user password or (when applicable) a group password, depending on
what rule is being authenticated.
See also the section entitled "USING RSYNC-DAEMON FEATURES VIA A REMOTE
SHELL CONNECTION" in bf(rsync)(1) for information on how handle an
rsyncd.conf-level username that differs from the remote-shell-level
username when using a remote shell to connect to an rsync daemon.
dit(bf(secrets file)) This parameter specifies the name of
a file that contains the username:password pairs used for
authenticating this module. This file is only consulted if the "auth
users" parameter is specified. The file is line based and contains
username:password pairs separated by a single colon. Any line starting
with a hash (#) is considered a comment and is skipped. The passwords
can contain any characters but be warned that many operating systems
limit the length of passwords that can be typed at the client end, so
you may find that passwords longer than 8 characters don't work.
dit(bf(secrets file)) This parameter specifies the name of a file that contains
the username:password and/or @groupname:password pairs used for authenticating
this module. This file is only consulted if the "auth users" parameter is
specified. The file is line-based and contains one name:password pair per
line. Any line has a hash (#) as the very first character on the line is
considered a comment and is skipped. The passwords can contain any characters
but be warned that many operating systems limit the length of passwords that
can be typed at the client end, so you may find that passwords longer than 8
characters don't work.
The use of group-specific lines are only relevant when the module is being
authorized using a matching "@groupname" rule. When that happens, the user
can be authorized via either their "username:password" line or the
"@groupname:password" line for the group that triggered the authentication.
It is up to you what kind of password entries you want to include, either
users, groups, or both. The use of group rules in "auth users" does not
require that you specify a group password if you do not want to use shared
passwords.
There is no default for the "secrets file" parameter, you must choose a name
(such as tt(/etc/rsyncd.secrets)). The file must normally not be readable
by "other"; see "strict modes".
by "other"; see "strict modes". If the file is not found or is rejected, no
logins for a "user auth" module will be possible.
dit(bf(strict modes)) This parameter determines whether or not
the permissions on the secrets file will be checked. If "strict modes" is
@@ -443,12 +542,14 @@ quote(itemization(
IP address and maskaddr is the netmask in dotted decimal notation for IPv4,
or similar for IPv6, e.g. ffff:ffff:ffff:ffff:: instead of /64. All IP
addresses which match the masked IP address will be allowed in.
it() a hostname. The hostname as determined by a reverse lookup will
be matched (case insensitive) against the pattern. Only an exact
match is allowed in.
it() a hostname pattern using wildcards. These are matched using the
same rules as normal unix filename matching. If the pattern matches
then the client is allowed in.
it() a hostname pattern using wildcards. If the hostname of the connecting IP
(as determined by a reverse lookup) matches the wildcarded name (using the
same rules as normal unix filename matching), the client is allowed in. This
only works if "reverse lookup" is enabled (the default).
it() a hostname. A plain hostname is matched against the reverse DNS of the
connecting IP (if "reverse lookup" is enabled), and/or the IP of the given
hostname is matched against the connecting IP (if "forward lookup" is
enabled, as it is by default). Any match will be allowed in.
))
Note IPv6 link-local addresses can have a scope in the address specification:
@@ -476,6 +577,23 @@ rejected. See the "hosts allow" parameter for more information.
The default is no "hosts deny" parameter, which means all hosts can connect.
dit(bf(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.
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
avoid the lookup. Thus, you probably want to disable it globally and then
enable it for modules that need the information.
dit(bf(forward lookup)) Controls whether the daemon performs a forward lookup
on any hostname specified in an hosts allow/deny setting. By default this is
enabled, allowing the use of an explicit hostname that would not be returned
by reverse DNS of the connecting IP.
dit(bf(ignore errors)) This parameter tells rsyncd to
ignore I/O errors on the daemon when deciding whether to run the delete
phase of the transfer. Normally rsync skips the bf(--delete) step if any
@@ -502,6 +620,11 @@ 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. "bf(%-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 bf(--human-readable)
command-line option, though the default is for human-readability to be off.
Each added apostrophe increases the level (e.g. "bf(%''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.
@@ -512,13 +635,14 @@ rsyncstats.)
The single-character escapes that are understood are as follows:
quote(itemization(
it() %a the remote IP address
it() %a the remote IP address (only available for a daemon)
it() %b the number of bytes actually transferred
it() %B the permission bits of the file (e.g. rwxrwxrwt)
it() %c the total size of the block checksums received for the basis file (only when sending)
it() %C the full-file MD5 checksum if bf(--checksum) is enabled or a file was transferred (only for protocol 30 or above).
it() %f the filename (long form on sender; no trailing "/")
it() %G the gid of the file (decimal) or "DEFAULT"
it() %h the remote host name
it() %h the remote host name (only available for a daemon)
it() %i an itemized list of what is being updated
it() %l the length of the file in bytes
it() %L the string " -> SYMLINK", " => HARDLINK", or "" (where bf(SYMLINK) or bf(HARDLINK) is a filename)
@@ -589,7 +713,12 @@ the sender.
dit(bf(pre-xfer exec), bf(post-xfer exec)) You may specify a command to be run
before and/or after the transfer. If the bf(pre-xfer exec) command fails, the
transfer is aborted before it begins.
transfer is aborted before it begins. Any output from the script on stdout (up
to several KB) will be displayed to the user when aborting, but is NOT
displayed if the script returns success. Any output from the script on stderr
goes to the daemon's stderr, which is typically discarded (though see
--no-detatch option for a way to see the stderr output, which can assist with
debugging).
The following environment variables will be set, though some are
specific to the pre-xfer or the post-xfer environment:
@@ -602,11 +731,14 @@ quote(itemization(
it() bf(RSYNC_USER_NAME): The accessing user's name (empty if no user).
it() bf(RSYNC_PID): A unique number for this transfer.
it() bf(RSYNC_REQUEST): (pre-xfer only) The module/path info specified
by the user (note that the user can specify multiple source files,
so the request can be something like "mod/path1 mod/path2", etc.).
by the user. Note that the user can specify multiple source files,
so the request can be something like "mod/path1 mod/path2", etc.
it() bf(RSYNC_ARG#): (pre-xfer only) The pre-request arguments are set
in these numbered values. RSYNC_ARG0 is always "rsyncd", and the last
value contains a single period.
in these numbered values. RSYNC_ARG0 is always "rsyncd", followed by
the options that were used in RSYNC_ARG1, and so on. There will be a
value of "." indicating that the options are done and the path args
are beginning -- these contain similar information to RSYNC_REQUEST,
but with values separated and the module name stripped off.
it() bf(RSYNC_EXIT_STATUS): (post-xfer only) the server side's exit value.
This will be 0 for a successful run, a positive value for an error that the
server generated, or a -1 if rsync failed to exit properly. Note that an
@@ -621,6 +753,62 @@ module's uid/gid setting) without any chroot restrictions.
enddit()
manpagesection(CONFIG DIRECTIVES)
There are currently two config directives available that allow a config file to
incorporate the contents of other files: bf(&include) and bf(&merge). Both
allow a reference to either a file or a directory. They differ in how
segregated the file's contents are considered to be.
The bf(&include) directive treats each file as more distinct, with each one
inheriting the defaults of the parent file, starting the parameter parsing
as globals/defaults, and leaving the defaults unchanged for the parsing of
the rest of the parent file.
The bf(&merge) directive, on the other hand, treats the file's contents as
if it were simply inserted in place of the directive, and thus it can set
parameters in a module started in another file, can affect the defaults for
other files, etc.
When an bf(&include) or bf(&merge) directive refers to a directory, it will read
in all the bf(*.conf) or bf(*.inc) files (respectively) that are contained inside
that directory (without any
recursive scanning), with the files sorted into alpha order. So, if you have a
directory named "rsyncd.d" with the files "foo.conf", "bar.conf", and
"baz.conf" inside it, this directive:
verb( &include /path/rsyncd.d )
would be the same as this set of directives:
verb( &include /path/rsyncd.d/bar.conf
&include /path/rsyncd.d/baz.conf
&include /path/rsyncd.d/foo.conf )
except that it adjusts as files are added and removed from the directory.
The advantage of the bf(&include) directive is that you can define one or more
modules in a separate file without worrying about unintended side-effects
between the self-contained module files.
The advantage of the bf(&merge) directive is that you can load config snippets
that can be included into multiple module definitions, and you can also set
global values that will affect connections (such as bf(motd file)), or globals
that will affect other include files.
For example, this is a useful /etc/rsyncd.conf file:
verb( port = 873
log file = /var/log/rsync.log
pid file = /var/lock/rsync.lock
&merge /etc/rsyncd.d
&include /etc/rsyncd.d )
This would merge any /etc/rsyncd.d/*.inc files (for global values that should
stay in effect), and then include any /etc/rsyncd.d/*.conf files (defining
modules without any global-value cross-talk).
manpagesection(AUTHENTICATION STRENGTH)
The authentication protocol used in rsync is a 128 bit MD4 based
@@ -706,11 +894,11 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
manpagesection(VERSION)
This man page is current for version 3.0.9 of rsync.
This man page is current for version 3.1.0 of rsync.
manpagesection(CREDITS)
rsync is distributed under the GNU public license. See the file
rsync is distributed under the GNU General Public License. See the file
COPYING for details.
The primary ftp site for rsync is

View File

@@ -232,8 +232,9 @@ echo " scratchbase=$scratchbase"
[ -d "$scratchbase" ] || mkdir "$scratchbase"
suitedir="$srcdir/testsuite"
TESTRUN_TIMEOUT=300
export scratchdir suitedir
export scratchdir suitedir TESTRUN_TIMEOUT
prep_scratch() {
[ -d "$scratchdir" ] && chmod -R u+rwX "$scratchdir" && rm -rf "$scratchdir"
@@ -264,8 +265,13 @@ do
prep_scratch
case "$testscript" in
*hardlinks*) TESTRUN_TIMEOUT=600 ;;
*) TESTRUN_TIMEOUT=300 ;;
esac
set +e
sh $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1
"$TOOLDIR/"testrun $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1
result=$?
set -e

139
sender.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +20,8 @@
*/
#include "rsync.h"
#include "inums.h"
extern int verbose;
extern int do_xfers;
extern int am_server;
extern int am_daemon;
@@ -32,19 +32,22 @@ extern int logfile_format_has_i;
extern int csum_length;
extern int append_mode;
extern int io_error;
extern int flist_eof;
extern int allowed_lull;
extern int preserve_xattrs;
extern int protocol_version;
extern int remove_source_files;
extern int updating_basis_file;
extern int make_backups;
extern int do_progress;
extern int inplace;
extern int batch_fd;
extern int write_batch;
extern int file_old_total;
extern struct stats stats;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
BOOL extra_flist_sending_enabled;
/**
* @file
*
@@ -60,7 +63,7 @@ static struct sum_struct *receive_sums(int f)
{
struct sum_struct *s;
int32 i;
int lull_mod = allowed_lull * 5;
int lull_mod = protocol_version >= 31 ? 0 : allowed_lull * 5;
OFF_T offset = 0;
if (!(s = new(struct sum_struct)))
@@ -70,9 +73,9 @@ static struct sum_struct *receive_sums(int f)
s->sums = NULL;
if (verbose > 3) {
rprintf(FINFO, "count=%.0f n=%ld rem=%ld\n",
(double)s->count, (long)s->blength, (long)s->remainder);
if (DEBUG_GTE(DELTASUM, 3)) {
rprintf(FINFO, "count=%s n=%ld rem=%ld\n",
big_num(s->count), (long)s->blength, (long)s->remainder);
}
if (append_mode > 0) {
@@ -101,13 +104,13 @@ static struct sum_struct *receive_sums(int f)
s->sums[i].len = s->blength;
offset += s->sums[i].len;
if (allowed_lull && !(i % lull_mod))
maybe_send_keepalive();
if (lull_mod && !(i % lull_mod))
maybe_send_keepalive(time(NULL), True);
if (verbose > 3) {
if (DEBUG_GTE(DELTASUM, 3)) {
rprintf(FINFO,
"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
i, s->sums[i].len, (double)s->sums[i].offset,
"chunk[%d] len=%d offset=%s sum1=%08x\n",
i, s->sums[i].len, big_num(s->sums[i].offset),
s->sums[i].sum1);
}
}
@@ -120,8 +123,10 @@ static struct sum_struct *receive_sums(int f)
void successful_send(int ndx)
{
char fname[MAXPATHLEN];
char *failed_op;
struct file_struct *file;
struct file_list *flist;
STRUCT_STAT st;
if (!remove_source_files)
return;
@@ -132,11 +137,31 @@ void successful_send(int ndx)
return;
f_name(file, fname);
if (do_unlink(fname) == 0) {
if (verbose > 1)
if (do_lstat(fname, &st) < 0) {
failed_op = "re-lstat";
goto failed;
}
if (st.st_size != F_LENGTH(file) || st.st_mtime != file->modtime
#ifdef ST_MTIME_NSEC
|| (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file))
#endif
) {
rprintf(FERROR, "ERROR: Skipping sender remove for changed file: %s\n", fname);
return;
}
if (do_unlink(fname) < 0) {
failed_op = "remove";
failed:
if (errno == ENOENT)
rprintf(FINFO, "sender file already removed: %s\n", fname);
else
rsyserr(FERROR, errno, "sender failed to %s %s", failed_op, fname);
} else {
if (INFO_GTE(REMOVE, 1))
rprintf(FINFO, "sender removed %s\n", fname);
} else
rsyserr(FERROR, errno, "sender failed to remove %s", fname);
}
}
static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
@@ -152,7 +177,8 @@ static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
if (iflags & ITEM_XNAME_FOLLOWS)
write_vstring(f_out, buf, len);
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
&& (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
send_xattr_request(fname, file, f_out);
#endif
}
@@ -169,41 +195,51 @@ void send_files(int f_in, int f_out)
int iflags, xlen;
struct file_struct *file;
int phase = 0, max_phase = protocol_version >= 29 ? 2 : 1;
struct stats initial_stats;
int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i;
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
int f_xfer = write_batch < 0 ? batch_fd : f_out;
int save_io_error = io_error;
int ndx, j;
if (verbose > 2)
if (DEBUG_GTE(SEND, 1))
rprintf(FINFO, "send_files starting\n");
while (1) {
if (inc_recurse)
send_extra_file_list(f_out, FILECNT_LOOKAHEAD);
if (inc_recurse) {
send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
extra_flist_sending_enabled = !flist_eof;
}
/* This call also sets cur_flist. */
ndx = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
ndx = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type,
xname, &xlen);
extra_flist_sending_enabled = False;
if (ndx == NDX_DONE) {
if (!am_server && INFO_GTE(PROGRESS, 2) && cur_flist) {
set_current_file_index(NULL, 0);
end_progress(0);
}
if (inc_recurse && first_flist) {
file_old_total -= first_flist->used;
flist_free(first_flist);
if (first_flist) {
if (first_flist == cur_flist)
file_old_total = cur_flist->used;
write_ndx(f_out, NDX_DONE);
continue;
}
}
if (++phase > max_phase)
break;
if (verbose > 2)
if (DEBUG_GTE(SEND, 1))
rprintf(FINFO, "send_files phase=%d\n", phase);
write_ndx(f_out, NDX_DONE);
continue;
}
if (inc_recurse)
send_extra_file_list(f_out, FILECNT_LOOKAHEAD);
send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
if (ndx - cur_flist->ndx_start >= 0)
file = cur_flist->files[ndx - cur_flist->ndx_start];
@@ -219,11 +255,12 @@ void send_files(int f_in, int f_out)
continue;
f_name(file, fname);
if (verbose > 2)
if (DEBUG_GTE(SEND, 1))
rprintf(FINFO, "send_files(%d, %s%s%s)\n", ndx, path,slash,fname);
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
&& (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
recv_xattr_request(file, f_in);
#endif
@@ -231,6 +268,21 @@ void send_files(int f_in, int f_out)
maybe_log_item(file, iflags, itemizing, xname);
write_ndx_and_attrs(f_out, ndx, iflags, fname, file,
fnamecmp_type, xname, xlen);
if (iflags & ITEM_IS_NEW) {
stats.created_files++;
if (S_ISREG(file->mode)) {
/* Nothing further to count. */
} else if (S_ISDIR(file->mode))
stats.created_dirs++;
#ifdef SUPPORT_LINKS
else if (S_ISLNK(file->mode))
stats.created_symlinks++;
#endif
else if (IS_DEVICE(file->mode))
stats.created_devices++;
else
stats.created_specials++;
}
continue;
}
if (phase == 2) {
@@ -254,25 +306,28 @@ void send_files(int f_in, int f_out)
append_mode = -append_mode;
csum_length = SHORT_SUM_LENGTH;
}
if (iflags & ITEM_IS_NEW)
stats.created_files++;
}
updating_basis_file = inplace && (protocol_version >= 29
? fnamecmp_type == FNAMECMP_FNAME : make_backups <= 0);
if (!am_server && do_progress)
if (!am_server && INFO_GTE(PROGRESS, 1))
set_current_file_index(file, ndx);
stats.num_transferred_files++;
stats.xferred_files++;
stats.total_transferred_size += F_LENGTH(file);
if (!log_before_transfer)
remember_initial_stats();
if (!do_xfers) { /* log the transfer */
log_item(FCLIENT, file, &stats, iflags, NULL);
log_item(FCLIENT, file, iflags, NULL);
write_ndx_and_attrs(f_out, ndx, iflags, fname, file,
fnamecmp_type, xname, xlen);
continue;
}
initial_stats = stats;
if (!(s = receive_sums(f_in))) {
io_error |= IOERR_GENERAL;
rprintf(FERROR_XFER, "receive_sums failed\n");
@@ -306,7 +361,7 @@ void send_files(int f_in, int f_out)
rsyserr(FERROR_XFER, errno, "fstat failed");
free_sums(s);
close(fd);
exit_cleanup(RERR_PROTOCOL);
exit_cleanup(RERR_FILEIO);
}
if (st.st_size) {
@@ -315,30 +370,30 @@ void send_files(int f_in, int f_out)
} else
mbuf = NULL;
if (verbose > 2) {
rprintf(FINFO, "send_files mapped %s%s%s of size %.0f\n",
path,slash,fname, (double)st.st_size);
if (DEBUG_GTE(DELTASUM, 2)) {
rprintf(FINFO, "send_files mapped %s%s%s of size %s\n",
path,slash,fname, big_num(st.st_size));
}
write_ndx_and_attrs(f_out, ndx, iflags, fname, file,
fnamecmp_type, xname, xlen);
write_sum_head(f_xfer, s);
if (verbose > 2)
if (DEBUG_GTE(DELTASUM, 2))
rprintf(FINFO, "calling match_sums %s%s%s\n", path,slash,fname);
if (log_before_transfer)
log_item(FCLIENT, file, &initial_stats, iflags, NULL);
else if (!am_server && verbose && do_progress)
log_item(FCLIENT, file, iflags, NULL);
else if (!am_server && INFO_GTE(NAME, 1) && INFO_EQ(PROGRESS, 1))
rprintf(FCLIENT, "%s\n", fname);
set_compression(fname);
match_sums(f_xfer, s, mbuf, st.st_size);
if (do_progress)
if (INFO_GTE(PROGRESS, 1))
end_progress(st.st_size);
log_item(log_code, file, &initial_stats, iflags, NULL);
log_item(log_code, file, iflags, NULL);
if (mbuf) {
j = unmap_file(mbuf);
@@ -353,7 +408,7 @@ void send_files(int f_in, int f_out)
free_sums(s);
if (verbose > 2)
if (DEBUG_GTE(SEND, 1))
rprintf(FINFO, "sender finished %s%s%s\n", path,slash,fname);
/* Flag that we actually sent this entry. */
@@ -365,7 +420,7 @@ void send_files(int f_in, int f_out)
if (io_error != save_io_error && protocol_version >= 30)
send_msg_int(MSG_IO_ERROR, io_error);
if (verbose > 2)
if (DEBUG_GTE(SEND, 1))
rprintf(FINFO, "send files finished\n");
match_report();

View File

@@ -8,5 +8,8 @@
ECHO_T="@ECHO_T@"
ECHO_N="@ECHO_N@"
ECHO_C="@ECHO_C@"
HOST_OS="@host_os@"
SHELL_PATH="@SHELL_PATH@"
FAKEROOT_PATH="@FAKEROOT_PATH@"
export ECHO_T ECHO_N ECHO_C
export ECHO_T ECHO_N ECHO_C HOST_OS SHELL_PATH FAKEROOT_PATH

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
* emulate it using the KAME implementation. */
#include "rsync.h"
#include "ifuncs.h"
#include "itypes.h"
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
@@ -229,7 +229,7 @@ int open_socket_out(char *host, int port, const char *bind_addr,
}
*cp++ = '\0';
strlcpy(portbuf, cp, sizeof portbuf);
if (verbose >= 2) {
if (DEBUG_GTE(CONNECT, 1)) {
rprintf(FINFO, "connection via http proxy %s port %s\n",
h, portbuf);
}
@@ -301,7 +301,7 @@ int open_socket_out(char *host, int port, const char *bind_addr,
s = -1;
continue;
}
if (verbose >= 3) {
if (DEBUG_GTE(CONNECT, 2)) {
char buf[2048];
if ((error = getnameinfo(res->ai_addr, res->ai_addrlen, buf, sizeof buf, NULL, 0, NI_NUMERICHOST)) != 0)
snprintf(buf, sizeof buf, "*getnameinfo failure: %s*", gai_strerror(error));
@@ -310,7 +310,7 @@ int open_socket_out(char *host, int port, const char *bind_addr,
break;
}
if (s < 0 || verbose >= 3) {
if (s < 0 || DEBUG_GTE(CONNECT, 2)) {
char buf[2048];
for (res = res0, j = 0; res; res = res->ai_next, j++) {
if (errnos[j] == 0)
@@ -381,7 +381,7 @@ int open_socket_out_wrapped(char *host, int port, const char *bind_addr,
*t = '\0';
}
if (verbose >= 2) {
if (DEBUG_GTE(CONNECT, 1)) {
rprintf(FINFO, "%sopening tcp connection to %s port %d\n",
prog ? "Using RSYNC_CONNECT_PROG instead of " : "",
host, port);
@@ -489,7 +489,7 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
/* Only output the socket()/bind() messages if we were totally
* unsuccessful, or if the daemon is being run with -vv. */
for (s = 0; s < ecnt; s++) {
if (!i || verbose > 1)
if (!i || DEBUG_GTE(BIND, 1))
rwrite(FLOG, errmsgs[s], strlen(errmsgs[s]), 0);
free(errmsgs[s]);
}
@@ -557,7 +557,7 @@ void start_accept_loop(int port, int (*fn)(int, int))
/* ready to listen */
FD_ZERO(&deffds);
for (i = 0, maxfd = -1; sp[i] >= 0; i++) {
if (listen(sp[i], 5) < 0) {
if (listen(sp[i], lp_listen_backlog()) < 0) {
rsyserr(FERROR, errno, "listen() on socket failed");
#ifdef INET6
if (errno == EADDRINUSE && i > 0) {
@@ -831,7 +831,7 @@ static int sock_exec(const char *prog)
rsyserr(FERROR, errno, "socketpair_tcp failed");
return -1;
}
if (verbose >= 2)
if (DEBUG_GTE(CMD, 1))
rprintf(FINFO, "Running socket program: \"%s\"\n", prog);
pid = fork();

52
stunnel-rsync.in Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/bash
# This must be called as (note the trailing dot):
#
# stunnel-rsync HOSTNAME rsync --server --daemon .
#
# ... which is typically done via the rsync-ssl script, which results in something like this:
#
# rsync --rsh=stunnel-rsync -aiv HOSTNAME::module [ARGS]
#
# This SSL setup based on the files by: http://dozzie.jarowit.net/trac/wiki/RsyncSSL
# Note that this requires at least version 4.x of stunnel.
# The current environment can override using the RSYNC_SSL_* values:
if [ x"$RSYNC_SSL_CERT" = x ]; then
cert=""
else
cert="cert = $RSYNC_SSL_CERT"
fi
if [ x"$RSYNC_SSL_CA_CERT" ]; then
cafile=""
verify=0
else
cafile="CAfile = $RSYNC_SSL_CA_CERT"
verify=3
fi
port=${RSYNC_SSL_PORT:-874}
# If the user specified USER@HOSTNAME::module, then rsync passes us
# the -l USER option too, so we must be prepared to ignore it.
if [ x"$1" = x"-l" ]; then
shift 2
fi
hostname=$1
shift
if [ x"$hostname" = x -o x"$1" != x"rsync" -o x"$2" != x"--server" -o x"$3" != x"--daemon" ]; then
echo "Usage: stunnel-rsync HOSTNAME rsync --server --daemon ." 1>&2
exit 1
fi
# devzero@web.de came up with this no-tmpfile calling syntax:
@stunnel4@ -fd 10 11<&0 <<EOF 10<&0 0<&11 11<&-
foreground = yes
debug = crit
connect = $hostname:$port
client = yes
TIMEOUTclose = 0
verify = $verify
$cert
$cafile
EOF

30
stunnel-rsyncd.conf.in Normal file
View File

@@ -0,0 +1,30 @@
# This config for stunnel will start up rsync for an incoming ssl connection.
foreground = no
#output = /var/log/stunnel-rsyncd.log
pid = /var/run/stunnel-rsyncd.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
compression = rle
# This must be root for rsync to use chroot -- rsync will drop permissions:
setuid = root
setgid = root
[rsync]
accept = 874
# You can set the cert to a combo *.pem file and omit the key, if you like.
cert = /etc/rsync-ssl/certs/server.crt
key = /etc/rsync-ssl/certs/server.key
client = no
# To allow anyone to try an ssl connection, use this:
verify = 0
CAfile = /etc/ssl/ca-bundle.pem
# To allow only cert-authorized clients, use something like this instead of the above:
#verify = 3
#CAfile = /etc/rsync-ssl/certs/allowed-clients.cert.pem
exec = @bindir@/rsync
# You can either share the same config as a normal daemon, or specify a separate config:
execargs = rsync --server --daemon .
#execargs = rsync --server --daemon --config=/etc/rsync-ssl/rsyncd.conf .

View File

@@ -1,5 +1,6 @@
#!/usr/bin/perl -w
#!/usr/bin/perl
use strict;
use warnings;
# Sets mtime and atime of files to the latest commit time in git.
#

126
support/instant-rsyncd Executable file
View File

@@ -0,0 +1,126 @@
#!/bin/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
# invaluable for quick testing, and I use it when writing a list of commands
# that people can paste into a terminal to reproduce a daemon-related bug.
# Sysadmins deploying an rsync daemon for the first time may find it helpful as
# a starting point.
#
# Usage: instant-rsyncd MODULE PORT RSYNCD-USERNAME [RSYNC-PATH]
# The script asks for the rsyncd user's password twice on stdin, once to set it
# and once to log in to test the daemon.
# -- Matt McCutchen <matt@mattmccutchen.net>
set -e
dir="$(pwd)"
echo
echo "This will setup an rsync daemon in $dir"
if [ $# = 0 ]; then
IFS='' read -p 'Module name to create (or return to exit): ' module
[ ! "$module" ] && exit
else
module="$1"
shift
fi
if [ $# = 0 ]; then
IFS='' read -p 'Port number the daemon should listen on [873]: ' port
else
port="$1"
shift
fi
[ "$port" ] || port=873
if [ $# = 0 ]; then
IFS='' read -p 'User name for authentication (empty for none): ' user
else
user="$1"
shift
fi
if [ "$user" ]; then
IFS='' read -s -p 'Desired password: ' password
echo
fi
rsync="$1"
[ "$rsync" ] || rsync=rsync
moduledir="${dir%/}/$module"
mkdir "$module"
cat >rsyncd.conf <<EOF
log file = rsyncd.log
pid file = rsyncd.pid
port = $port
use chroot = no
[$module]
path = $module
read only = false
EOF
if [ "$user" ]; then
cat >>rsyncd.conf <<-EOF
auth users = $user
secrets file = $module.secrets
EOF
touch "$module".secrets
chmod go-rwx "$module".secrets
echo "$user:$password" >"$module".secrets
user="$user@"
fi
cat >start <<EOF
#!/bin/bash
set -e
cd \`dirname \$0\`
! [ -e rsyncd.pid ] || {
echo "Is the daemon already running? If not, delete rsyncd.pid."
exit 1
}
$rsync --daemon --config=rsyncd.conf
EOF
chmod +x start
cat >stop <<"EOF"
#!/bin/bash
set -e
cd `dirname $0`
! [ -e rsyncd.pid ] || kill -s SIGTERM $(< rsyncd.pid)
EOF
chmod +x stop
path="rsync://$user$(hostname):$port/$module/"
if ./start; then
sleep .2
echo
echo "I ran the start command for the daemon. The log file rsyncd.log says:"
echo
cat rsyncd.log
echo
echo "You can start and stop it with ./start and ./stop respectively."
echo "You can customize the configuration file rsyncd.conf."
echo
echo "Give rsync the following path to access the module:"
echo " $path"
echo
if [ "$user" ]; then
echo "Let's test the daemon now. Enter the password you chose at the prompt."
else
echo "Let's test the daemon now."
fi
echo
echo '$' $rsync --list-only "$path"
$rsync --list-only "$path"
echo
echo "You should see an empty folder; it's $moduledir."
else
echo "Something went wrong. Do you see an error message?"
fi

View File

@@ -1,33 +1,81 @@
#!/bin/sh
#!/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 a -l USER option, we try to use "sudo -u USER" to run the
# command.
# 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).
user=''
do_cd=y # Default path is user's home dir, just like ssh.
use strict;
use warnings;
use Getopt::Long;
use English '-no_match_vars';
while : ; do
case "$1" in
-l) user="$2"; shift; shift ;;
-l*) user=`echo "$1" | sed 's/^-l//'`; shift ;;
--no-cd) do_cd=n; shift ;;
-*) shift ;;
localhost) shift; break ;;
*) echo "lsh: unable to connect to host $1" 1>&2; exit 1 ;;
esac
done
&Getopt::Long::Configure('bundling');
&Getopt::Long::Configure('require_order');
GetOptions(
'l=s' => \( my $login_name ),
'1|2|4|6|A|a|C|f|g|k|M|N|n|q|s|T|t|V|v|X|x|Y' => sub { }, # Ignore
'b|c|D|e|F|i|L|m|O|o|p|R|S|w=s' => sub { }, # Ignore
'no-cd' => \( my $no_chdir ),
'sudo' => \( my $use_sudo ),
) or &usage;
&usage unless @ARGV > 1;
if [ "$user" ]; then
prefix=''
if [ $do_cd = y ]; then
home=`perl -e "print((getpwnam('$user'))[7])"`
prefix="cd '$home' ;"
fi
sudo -H -u "$user" sh -c "$prefix $*"
else
[ $do_cd = y ] && cd
eval "${@}"
fi
my $host = shift;
if ($host =~ s/^([^@]+)\@//) {
$login_name = $1;
}
if ($host ne 'localhost') {
die "lsh: unable to connect to host $host\n";
}
my ($home_dir, @cmd);
if ($login_name) {
my ($uid, $gid);
if ($login_name =~ /\D/) {
$uid = getpwnam($login_name);
die "Unknown user: $login_name\n" unless defined $uid;
} else {
$uid = $login_name;
}
($login_name, $gid, $home_dir) = (getpwuid($uid))[0,3,7];
if ($use_sudo) {
unshift @ARGV, "cd '$home_dir' &&" unless $no_chdir;
unshift @cmd, qw( sudo -H -u ), $login_name;
$no_chdir = 1;
} else {
my $groups = "$gid $gid";
while (my ($grgid, $grmembers) = (getgrent)[2,3]) {
if ($grgid != $gid && $grmembers =~ /(^|\s)\Q$login_name\E(\s|$)/o) {
$groups .= " $grgid";
}
}
my ($ruid, $euid) = ($UID, $EUID);
$GID = $EGID = $groups;
$UID = $EUID = $uid;
die "Cannot set ruid: $! (use --sudo?)\n" if $UID == $ruid && $ruid != $uid;
die "Cannot set euid: $! (use --sudo?)\n" if $EUID == $euid && $euid != $uid;
$ENV{USER} = $ENV{USERNAME} = $login_name;
$ENV{HOME} = $home_dir;
}
} else {
$home_dir = (getpwuid($UID))[7];
}
unless ($no_chdir) {
chdir $home_dir or die "Unable to chdir to $home_dir: $!\n";
}
push @cmd, '/bin/sh', '-c', "@ARGV";
exec @cmd;
die "Failed to exec: $!\n";
sub usage
{
die <<EOT;
Usage: lsh [-l user] [--sudo] [--no-cd] localhost COMMAND [...]
EOT
}

35
support/lsh.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/sh
# 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 a -l USER option, we try to use "sudo -u USER" to run the
# command.
user=''
do_cd=y # Default path is user's home dir, just like ssh.
while : ; do
case "$1" in
-l) user="$2"; shift; shift ;;
-l*) user=`echo "$1" | sed 's/^-l//'`; shift ;;
--no-cd) do_cd=n; shift ;;
-*) shift ;;
localhost) shift; break ;;
*) echo "lsh: unable to connect to host $1" 1>&2; exit 1 ;;
esac
done
if [ "$user" ]; then
prefix=''
if [ $do_cd = y ]; then
home=`perl -e "print((getpwnam('$user'))[7])"`
prefix="cd '$home' &&"
fi
sudo -H -u "$user" sh -c "$prefix $*"
else
if [ $do_cd = y ]; then
cd || exit 1
fi
eval "${@}"
fi

15
support/mapfrom Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/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
# a copy FROM the backup area as follows and get the differing ID values
# mapped just like a remote transfer FROM the backed-up machine would do:
#
# rsync -av --usermap=`mapfrom /mnt/backup/etc/passwd` \
# --groupmap=`mapfrom /mnt/backup/etc/group` \
# /mnt/backup/some/src/ /some/dest/
while (<>) {
push @_, "$2:$1" if /^(\w+):[^:]+:(\d+)/;
}
print join(',', @_), "\n";

15
support/mapto Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/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
# a copy TO the backup area as follows and get the differing ID values
# mapped just like a remote transfer TO the backed-up machine would do:
#
# rsync -av --usermap=`mapto /mnt/backup/etc/passwd` \
# --groupmap=`mapto /mnt/backup/etc/group` \
# /some/src/ /mnt/backup/some/dest/
while (<>) {
push @_, "$1:$2" if /^(\w+):[^:]+:(\d+)/;
}
print join(',', @_), "\n";

View File

@@ -74,15 +74,18 @@ our %long_opt = (
'delete-delay' => 0,
'delete-during' => 0,
'delete-excluded' => 0,
'delete-missing-args' => 0,
'existing' => 0,
'fake-super' => 0,
'files-from' => 3,
'force' => 0,
'from0' => 0,
'fuzzy' => 0,
'groupmap' => 1,
'iconv' => 1,
'ignore-errors' => 0,
'ignore-existing' => 0,
'ignore-missing-args' => 0,
'inplace' => 0,
'link-dest' => 2,
'list-only' => 0,
@@ -114,6 +117,7 @@ our %long_opt = (
'temp-dir' => 2,
'timeout' => 1,
'use-qsort' => 0,
'usermap' => 1,
);
### END of options data produced by the cull_options script. ###

17
support/rsync-slash-strip Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
# This script can be used as an rsync command-line filter that strips a single
# trailing slash from each arg. That treats "src/" the same as "src", thus
# you need to use "src/." or "src//" for just the contents of the "src" dir.
# (Note that command-line dir-excludes would need to use "excl//" too.)
#
# To use this, name it something like "rs", put it somewhere in your path, and
# then use "rs" in place of "rsync" when you are typing your copy commands.
args=()
for arg in "${@}"; do
if [[ "$arg" == / ]]; then
args=("${args[@]}" /)
else
args=("${args[@]}" "${arg%/}")
fi
done
exec /usr/bin/rsync "${args[@]}"

121
syscall.c
View File

@@ -4,7 +4,7 @@
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 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
@@ -29,8 +29,13 @@
#include <sys/attr.h>
#endif
#if defined HAVE_SYS_FALLOCATE && !defined HAVE_FALLOCATE
#include <sys/syscall.h>
#endif
extern int dry_run;
extern int am_root;
extern int am_sender;
extern int read_only;
extern int list_only;
extern int preserve_perms;
@@ -53,13 +58,55 @@ int do_unlink(const char *fname)
return unlink(fname);
}
int do_symlink(const char *fname1, const char *fname2)
#ifdef SUPPORT_LINKS
int do_symlink(const char *lnk, const char *fname)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
return symlink(fname1, fname2);
#if defined NO_SYMLINK_XATTRS || defined NO_SYMLINK_USER_XATTRS
/* For --fake-super, we create a normal file with mode 0600
* and write the lnk into it. */
if (am_root < 0) {
int ok, len = strlen(lnk);
int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
if (fd < 0)
return -1;
ok = write(fd, lnk, len) == len;
if (close(fd) < 0)
ok = 0;
return ok ? 0 : -1;
}
#endif
return symlink(lnk, fname);
}
#if defined NO_SYMLINK_XATTRS || defined NO_SYMLINK_USER_XATTRS
ssize_t do_readlink(const char *path, char *buf, size_t bufsiz)
{
/* For --fake-super, we read the link from the file. */
if (am_root < 0) {
int fd = do_open_nofollow(path, O_RDONLY);
if (fd >= 0) {
int len = read(fd, buf, bufsiz);
close(fd);
return len;
}
if (errno != ELOOP)
return -1;
/* A real symlink needs to be turned into a fake one on the receiving
* side, so tell the generator that the link has no length. */
if (!am_sender)
return 0;
/* Otherwise fall through and let the sender report the real length. */
}
return readlink(path, buf, bufsiz);
}
#endif
#endif
#ifdef HAVE_LINK
int do_link(const char *fname1, const char *fname2)
{
@@ -374,3 +421,71 @@ int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec))
#else
#error Need utimes or utime function.
#endif
#ifdef SUPPORT_PREALLOCATION
int do_fallocate(int fd, OFF_T offset, OFF_T length)
{
#ifdef FALLOC_FL_KEEP_SIZE
#define DO_FALLOC_OPTIONS FALLOC_FL_KEEP_SIZE
#else
#define DO_FALLOC_OPTIONS 0
#endif
RETURN_ERROR_IF(dry_run, 0);
RETURN_ERROR_IF_RO_OR_LO;
#if defined HAVE_FALLOCATE
return fallocate(fd, DO_FALLOC_OPTIONS, offset, length);
#elif defined HAVE_SYS_FALLOCATE
return syscall(SYS_fallocate, fd, DO_FALLOC_OPTIONS, (loff_t)offset, (loff_t)length);
#elif defined HAVE_EFFICIENT_POSIX_FALLOCATE
return posix_fallocate(fd, offset, length);
#else
#error Coding error in SUPPORT_PREALLOCATION logic.
#endif
}
#endif
int do_open_nofollow(const char *pathname, int flags)
{
#ifndef O_NOFOLLOW
STRUCT_STAT f_st, l_st;
#endif
int fd;
if (flags != O_RDONLY) {
RETURN_ERROR_IF(dry_run, 0);
RETURN_ERROR_IF_RO_OR_LO;
#ifndef O_NOFOLLOW
/* This function doesn't support write attempts w/o O_NOFOLLOW. */
errno = EINVAL;
return -1;
#endif
}
#ifdef O_NOFOLLOW
fd = open(pathname, flags|O_NOFOLLOW);
#else
if (do_lstat(pathname, &l_st) < 0)
return -1;
if (S_ISLNK(l_st.st_mode)) {
errno = ELOOP;
return -1;
}
if ((fd = open(pathname, flags)) < 0)
return fd;
if (do_fstat(fd, &f_st) < 0) {
close_and_return_error:
{
int save_errno = errno;
close(fd);
errno = save_errno;
}
return -1;
}
if (l_st.st_dev != f_st.st_dev || l_st.st_ino != f_st.st_ino) {
errno = EINVAL;
goto close_and_return_error;
}
#endif
return fd;
}

View File

@@ -3,7 +3,7 @@
* functions, so that module test harnesses can run standalone.
*
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 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
@@ -22,16 +22,18 @@
#include "rsync.h"
int modify_window = 0;
int preallocate_files = 0;
int protect_args = 0;
int module_id = -1;
int checksum_len = 0;
int relative_paths = 0;
int human_readable = 0;
int module_dirlen = 0;
int preserve_acls = 0;
int preserve_times = 0;
int preserve_xattrs = 0;
mode_t orig_umask = 002;
char *partial_dir;
char *module_dir;
struct filter_list_struct daemon_filter_list;
filter_rule_list daemon_filter_list;
void rprintf(UNUSED(enum logcode code), const char *format, ...)
{
@@ -58,7 +60,7 @@ struct filter_list_struct daemon_filter_list;
exit(code);
}
int check_filter(UNUSED(struct filter_list_struct *listp), UNUSED(enum logcode code),
int check_filter(UNUSED(filter_rule_list *listp), UNUSED(enum logcode code),
UNUSED(const char *name), UNUSED(int name_is_dir))
{
/* This function doesn't really get called in this test context, so
@@ -66,14 +68,19 @@ struct filter_list_struct daemon_filter_list;
return 0;
}
int make_bak_dir(UNUSED(const char *fullpath))
int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest))
{
return -1;
}
int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest))
void free_xattr(UNUSED(stat_x *sxp))
{
return -1;
return;
}
void free_acl(UNUSED(stat_x *sxp))
{
return;
}
char *lp_name(UNUSED(int mod))

View File

@@ -2,7 +2,7 @@
* Test harness for unsafe_symlink(). Not linked into rsync itself.
*
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,11 +25,13 @@
int dry_run = 0;
int am_root = 0;
int am_sender = 1;
int read_only = 0;
int list_only = 0;
int verbose = 0;
int human_readable = 0;
int preserve_perms = 0;
int preserve_executability = 0;
short info_levels[COUNT_INFO], debug_levels[COUNT_DEBUG];
int
main(int argc, char **argv)

61
testrun.c Normal file
View File

@@ -0,0 +1,61 @@
/* Run a testsuite script with a timeout. */
#include "rsync.h"
#define DEFAULT_TIMEOUT_SECS (5*60)
#define TIMEOUT_ENV "TESTRUN_TIMEOUT"
int main(int argc, char *argv[])
{
pid_t pid;
char *timeout_env;
int status, timeout_secs, slept = 0;
if (argc < 2) {
fprintf(stderr, "Usage: testrun [SHELL_OPTIONS] TESTSUITE_SCRIPT [ARGS]\n");
exit(1);
}
if ((timeout_env = getenv(TIMEOUT_ENV)) != NULL)
timeout_secs = atoi(timeout_env);
else
timeout_secs = DEFAULT_TIMEOUT_SECS;
if ((pid = fork()) < 0) {
fprintf(stderr, "TESTRUN ERROR: fork failed: %s\n", strerror(errno));
exit(1);
}
if (pid == 0) {
argv[0] = "sh";
execvp(argv[0], argv);
fprintf(stderr, "TESTRUN ERROR: failed to exec %s: %s\n", argv[0], strerror(errno));
_exit(1);
}
while (1) {
int ret = waitpid(pid, &status, WNOHANG);
if (ret > 0)
break;
if (ret < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "TESTRUN ERROR: waitpid failed: %s\n", strerror(errno));
exit(1);
}
if (slept++ > timeout_secs) {
fprintf(stderr, "TESTRUN TIMEOUT: test took over %d seconds.\n", timeout_secs);
if (kill(pid, SIGTERM) < 0)
fprintf(stderr, "TESTRUN ERROR: failed to kill pid %d: %s\n", (int)pid, strerror(errno));
else
fprintf(stderr, "TESTRUN INFO: killed pid %d\n", (int)pid);
exit(1);
}
sleep(1);
}
if (!WIFEXITED(status))
exit(255);
return WEXITSTATUS(status);
}

View File

@@ -1,5 +1,14 @@
#! /bin/sh
test_fail() {
echo "$@" >&2
exit 1
}
echo $0 running
$RSYNC --version || exit 1
$RSYNC --version || test_fail '--version output failed'
$RSYNC --info=help || test_fail '--info=help output failed'
$RSYNC --debug=help || test_fail '--debug=help output failed'

View File

@@ -5,7 +5,7 @@
# Test that rsync handles basic ACL preservation.
. $srcdir/testsuite/rsync.fns
. $suitedir/rsync.fns
$RSYNC --version | grep ", ACLs" >/dev/null || test_skipped "Rsync is configured without ACL support"

View File

@@ -11,7 +11,7 @@
bakdir="$tmpdir/bak"
makepath "$fromdir/deep" "$bakdir"
makepath "$fromdir/deep" "$bakdir/dname"
name1="$fromdir/deep/name1"
name2="$fromdir/deep/name2"
@@ -20,13 +20,13 @@ outfile="$scratchdir/rsync.out"
cat "$srcdir"/[gr]*.[ch] > "$name1"
cat "$srcdir"/[et]*.[ch] > "$name2"
checkit "$RSYNC -avv '$fromdir/' '$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -ai --info=backup '$fromdir/' '$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -avv '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
checkit "$RSYNC -ai --info=backup '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
cat "$srcdir"/[fgpr]*.[ch] > "$name1"
cat "$srcdir"/[etw]*.[ch] > "$name2"
$RSYNC -avv --no-whole-file --backup "$fromdir/" "$todir/" \
$RSYNC -ai --info=backup --no-whole-file --backup "$fromdir/" "$todir/" \
| tee "$outfile"
for fn in deep/name1 deep/name2; do
grep "backed up $fn to $fn~" "$outfile" >/dev/null || test_fail "no backup message output for $fn"
@@ -38,7 +38,7 @@ done
echo deleted-file >"$todir/dname"
cp_touch "$todir/dname" "$chkdir"
checkit "$RSYNC -avv --no-whole-file --delete-delay \
checkit "$RSYNC -ai --info=backup --no-whole-file --delete-delay \
--backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \
| tee "$outfile"
@@ -48,11 +48,11 @@ done
diff -r $diffopt "$chkdir" "$bakdir" || test_fail "backup dir contents are bogus"
rm "$bakdir/dname"
checkit "$RSYNC -avv --del '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
checkit "$RSYNC -ai --info=backup --del '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
cat "$srcdir"/[efgr]*.[ch] > "$name1"
cat "$srcdir"/[ew]*.[ch] > "$name2"
checkit "$RSYNC -avv --inplace --no-whole-file --backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \
checkit "$RSYNC -ai --info=backup --inplace --no-whole-file --backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \
| tee "$outfile"
for fn in deep/name1 deep/name2; do
@@ -60,7 +60,7 @@ for fn in deep/name1 deep/name2; do
done
diff -r $diffopt "$chkdir" "$bakdir" || test_fail "backup dir contents are bogus"
checkit "$RSYNC -avv --inplace --no-whole-file '$fromdir/' '$bakdir/'" "$fromdir" "$bakdir"
checkit "$RSYNC -ai --info=backup --inplace --no-whole-file '$fromdir/' '$bakdir/'" "$fromdir" "$bakdir"
# The script would have aborted on error, so getting here means we've won.
exit 0

View File

@@ -7,7 +7,7 @@
# Test that the --chmod option functions correctly.
. $srcdir/testsuite/rsync.fns
. $suitedir/rsync.fns
# Build some files

View File

@@ -18,14 +18,25 @@ case $0 in
$RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests"
RSYNC="$RSYNC --fake-super"
TLS_ARGS="$TLS_ARGS --fake-super"
case "`xattr 2>&1`" in
*--list:*)
case "$HOST_OS" in
darwin*)
chown() {
own=$1
shift
xattr -s 'rsync.%stat' "100644 0,0 $own" "${@}"
}
;;
solaris*)
chown() {
own=$1
shift
for fn in "${@}"; do
runat "$fn" "$SHELL_PATH" <<EOF
echo "100644 0,0 $own" > rsync.%stat
EOF
done
}
;;
*)
chown() {
own=$1
@@ -40,9 +51,9 @@ case $0 in
case `get_testuid` in
'') ;; # If "id" failed, try to continue...
0) ;;
*) if [ -f /usr/bin/fakeroot ]; then
*) if [ -e "$FAKEROOT_PATH" ]; then
echo "Let's try re-running the script under fakeroot..."
exec /usr/bin/fakeroot /bin/sh "$0"
exec "$FAKEROOT_PATH" "$SHELL_PATH" "$0"
fi
;;
esac

View File

@@ -24,9 +24,9 @@
chkfile="$scratchdir/rsync.chk"
outfile="$scratchdir/rsync.out"
SSH="src/support/lsh --no-cd"
SSH="src/support/lsh.sh --no-cd"
FILE_REPL='s/^\([^d][^ ]*\) *\(..........[0-9]\) /\1 \2 /'
DIR_REPL='s/^\(d[^ ]*\) *[0-9][0-9]* /\1 DIR /'
DIR_REPL='s/^\(d[^ ]*\) *[0-9][.,0-9]* /\1 DIR /'
LS_REPL='s;[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9];####/##/## ##:##:##;'
build_rsyncd_conf
@@ -50,19 +50,22 @@ case `get_testuid` in
;;
esac
$RSYNC -ve "$SSH" --rsync-path="$RSYNC$confopt" localhost::
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
export RSYNC_CONNECT_PROG
$RSYNC -v localhost:: \
| tee "$outfile"
# These have a space-padded 15-char name, then a tab, then a comment.
sed 's/NOCOMMENT//' <<EOT >"$chkfile"
test-from r/o
test-to r/w
test-scratch NOCOMMENT
EOT
$RSYNC -ve "$SSH" --rsync-path="$RSYNC$confopt" localhost:: | tee "$outfile"
echo '===='
diff $diffopt "$chkfile" "$outfile" || test_fail "test 0 failed"
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
export RSYNC_CONNECT_PROG
$RSYNC -v localhost:: | tee "$outfile"
echo '===='
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
$RSYNC -r localhost::test-hidden \

View File

@@ -5,7 +5,7 @@
# Test that rsync obeys default ACLs. -- Matt McCutchen
. $srcdir/testsuite/rsync.fns
. $suitedir/rsync.fns
$RSYNC --version | grep ", ACLs" >/dev/null || test_skipped "Rsync is configured without ACL support"

View File

@@ -19,8 +19,8 @@ case $0 in
$RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests"
RSYNC="$RSYNC --fake-super"
TLS_ARGS="$TLS_ARGS --fake-super"
case "`xattr 2>&1`" in
*--list:*)
case "$HOST_OS" in
darwin*)
mknod() {
fn="$1"
case "$2" in
@@ -34,6 +34,22 @@ case $0 in
xattr -s 'rsync.%stat' "$mode $maj,$min 0:0" "$fn"
}
;;
solaris*)
mknod() {
fn="$1"
case "$2" in
p) mode=10644 ;;
c) mode=20644 ;;
b) mode=60644 ;;
esac
maj="${3:-0}"
min="${4:-0}"
touch "$fn"
runat "$fn" "$SHELL_PATH" <<EOF
echo "$mode $maj,$min 0:0" > rsync.%stat
EOF
}
;;
*)
mknod() {
fn="$1"
@@ -54,9 +70,9 @@ case $0 in
case `get_testuid` in
'') ;; # If "id" failed, try to continue...
0) ;;
*) if [ -f /usr/bin/fakeroot ]; then
*) if [ -e "$FAKEROOT_PATH" ]; then
echo "Let's try re-running the script under fakeroot..."
exec /usr/bin/fakeroot /bin/sh $RUNSHFLAGS "$0"
exec "$FAKEROOT_PATH" "$SHELL_PATH" $RUNSHFLAGS "$0"
fi
test_skipped "Rsync needs root/fakeroot for device tests"
;;
@@ -74,7 +90,7 @@ mknod "$fromdir/char3" c 42 69 || test_skipped "Can't create char device node"
mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node"
mknod "$fromdir/block2" b 42 73 || test_skipped "Can't create block device node"
mknod "$fromdir/block3" b 105 73 || test_skipped "Can't create block device node"
ln "$fromdir/block3" "$fromdir/block2.5" || echo "Skipping hard-linked device test..."
ln "$fromdir/block3" "$fromdir/block3.5" || echo "Skipping hard-linked device test..."
mkfifo "$fromdir/fifo" || mknod "$fromdir/fifo" p || test_skipped "Can't run mkfifo"
# Work around time rounding/truncating issue by touching both files.
touch -r "$fromdir/block" "$fromdir/block" "$fromdir/block2"
@@ -110,14 +126,14 @@ cat <<EOT >"$chkfile"
cDc.t.$dots block
cDc...$dots block2
cD$all_plus block3
hD$all_plus block2.5 => block3
hD$all_plus block3.5 => block3
cD$all_plus char
cD$all_plus char2
cD$all_plus char3
cS$all_plus fifo
EOT
if test ! -r "$fromdir/block2.5"; then
grep -v block2.5 <"$chkfile" >"$chkfile.new"
if test ! -r "$fromdir/block3.5"; then
grep -v block3.5 <"$chkfile" >"$chkfile.new"
mv "$chkfile.new" "$chkfile"
fi
diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
@@ -128,7 +144,7 @@ echo ""
( cd "$todir" && rsync_ls_lR . ) > "$tmpdir/ls-to"
diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to"
if test -r "$fromdir/block2.5"; then
if test -r "$fromdir/block3.5"; then
set -x
$RSYNC -aii --link-dest="$todir" "$fromdir/" "$chkdir/" \
| tee "$outfile"
@@ -136,8 +152,8 @@ if test -r "$fromdir/block2.5"; then
cd$allspace ./
hD$allspace block
hD$allspace block2
hD$allspace block2.5
hD$allspace block3
hD$allspace block3.5
hD$allspace char
hD$allspace char2
hD$allspace char3

View File

@@ -5,7 +5,7 @@
# Test that rsync obeys directory setgid. -- Matt McCutchen
. $srcdir/testsuite/rsync.fns
. $suitedir/rsync.fns
umask 077
@@ -26,7 +26,7 @@ testit() {
echo "File!" >"$scratchdir/file"
echo "#!/bin/sh" >"$scratchdir/program"
mkdir "$scratchdir/dir"
chmod 2764 "$scratchdir/dir" || test_skipped "Can't chmod"
chmod u=rwx,g=rw,g+s,o=r "$scratchdir/dir" || test_skipped "Can't chmod"
chmod 664 "$scratchdir/file"
chmod 775 "$scratchdir/program"
[ -g "$scratchdir/dir" ] || test_skipped "The directory setgid bit vanished!"
@@ -35,7 +35,7 @@ mkdir "$scratchdir/dir/blah"
# Test some target directories
testit setgid-off 700 rw------- rwx------ rwx------
testit setgid-on 2700 rw------- rwx------ rwx--S---
testit setgid-on u=rwx,g=rw,g+s,o-rwx rw------- rwx------ rwx--S---
# Hooray
exit 0

View File

@@ -5,7 +5,7 @@
# Test the --executability or -E option. -- Matt McCutchen
. $srcdir/testsuite/rsync.fns
. $suitedir/rsync.fns
# Put some files in the From directory
mkdir "$fromdir"

View File

@@ -9,6 +9,8 @@
. "$suitedir/rsync.fns"
SSH="$scratchdir/src/support/lsh.sh"
hands_setup
# This list of files skips the contents of "subsubdir" but includes
@@ -26,5 +28,18 @@ $RSYNC -a --exclude=dir/text --exclude='subsubdir/**' "$fromdir/" "$chkdir/"
checkit "$RSYNC -av --files-from='$scratchdir/filelist' '$scratchdir' '$todir/'" "$chkdir" "$todir"
for filehost in '' 'localhost:'; do
for srchost in '' 'localhost:'; do
if [ -z "$srchost" ]; then
desthost='localhost:'
else
desthost=''
fi
rm -rf "$todir"
checkit "$RSYNC -avse '$SSH' --rsync-path='$RSYNC' --files-from='$filehost$scratchdir/filelist' '$srchost$scratchdir' '$desthost$todir/'" "$chkdir" "$todir"
done
done
# The script would have aborted on error, so getting here means we've won.
exit 0

View File

@@ -9,21 +9,23 @@
hands_setup
DEBUG_OPTS="--debug=all0,deltasum0"
# Main script starts here
runtest "basic operation" 'checkit "$RSYNC -av \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
ln "$fromdir/filelist" "$fromdir/dir"
runtest "hard links" 'checkit "$RSYNC -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
runtest "hard links" 'checkit "$RSYNC -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
rm "$todir/text"
runtest "one file" 'checkit "$RSYNC -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
runtest "one file" 'checkit "$RSYNC -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
echo "extra line" >> "$todir/text"
runtest "extra data" 'checkit "$RSYNC -avH --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
runtest "extra data" 'checkit "$RSYNC -avH $DEBUG_OPTS --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
cp "$fromdir/text" "$todir/ThisShouldGo"
runtest " --delete" 'checkit "$RSYNC --delete -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
runtest " --delete" 'checkit "$RSYNC --delete -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
cd "$tmpdir"
rm -rf to from/*dir

View File

@@ -11,7 +11,7 @@
. "$suitedir/rsync.fns"
SSH="$scratchdir/src/support/lsh"
SSH="$scratchdir/src/support/lsh.sh"
outfile="$scratchdir/rsync.out"
@@ -33,11 +33,11 @@ ln "$name2" "$name3" || fail "Can't create hardlink"
cp "$name2" "$name4" || fail "Can't copy file"
cat $srcdir/*.c >"$fromdir/text"
checkit "$RSYNC -aHivv '$fromdir/' '$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -aHivv --debug=HLINK5 '$fromdir/' '$todir/'" "$fromdir" "$todir"
echo "extra extra" >>"$todir/name1"
checkit "$RSYNC -aHivv --no-whole-file '$fromdir/' '$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -aHivv --debug=HLINK5 --no-whole-file '$fromdir/' '$todir/'" "$fromdir" "$todir"
# Add a new link in a new subdirectory to test that we don't try to link
# the files before the directory gets created. We also create a bunch of
@@ -56,27 +56,27 @@ done
ln "$name1" "$fromdir/subdir/down/deep/new-file"
rm "$todir/text"
checkit "$RSYNC -aHivve '$SSH' --rsync-path='$RSYNC' '$fromdir/' localhost:'$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -aHivve '$SSH' --debug=HLINK5 --rsync-path='$RSYNC' '$fromdir/' localhost:'$todir/'" "$fromdir" "$todir"
# Do some duplicate copies using --link-dest and --copy-dest to test that
# we hard-link all locally-inherited items.
checkit "$RSYNC -aHivv --link-dest='$todir' '$fromdir/' '$chkdir/'" "$todir" "$chkdir"
checkit "$RSYNC -aHivv --debug=HLINK5 --link-dest='$todir' '$fromdir/' '$chkdir/'" "$todir" "$chkdir"
rm -rf "$chkdir"
checkit "$RSYNC -aHivv --copy-dest='$todir' '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
checkit "$RSYNC -aHivv --debug=HLINK5 --copy-dest='$todir' '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
# Create a hard link that has only one part in the hierarchy.
echo "This is another file" >"$fromdir/solo"
ln "$fromdir/solo" "$chkdir/solo" || fail "Can't create hardlink"
# Make sure that the checksum data doesn't slide due to an HLINK_BUMP() change.
$RSYNC -aHivc "$fromdir/" "$chkdir/" | tee "$outfile"
$RSYNC -aHivc --debug=HLINK5 "$fromdir/" "$chkdir/" | tee "$outfile"
grep solo "$outfile" && test_fail "Erroneous copy of solo file occurred!"
# Make sure there's nothing wrong with sending a single file with -H
# enabled (this has broken twice so far, so we need this test).
rm -rf "$todir"
$RSYNC -aHivv "$name1" "$todir/"
$RSYNC -aHivv --debug=HLINK5 "$name1" "$todir/"
diff $diffopt "$name1" "$todir" || test_fail "solo copy of name1 failed"
# The script would have aborted on error, so getting here means we've won.

View File

@@ -108,9 +108,9 @@ filter_outfile
cat <<EOT >"$chkfile"
bar/baz/rsync is uptodate
foo/config1 is uptodate
foo/config2
foo/extra is uptodate
foo/sym is uptodate
foo/config2
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
@@ -203,8 +203,8 @@ bar/baz/rsync is uptodate
foo/ is uptodate
foo/config1 is uptodate
foo/config2 is uptodate
foo/extra => foo/config1
foo/sym $is_uptodate
foo/extra => foo/config1
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 10 failed"

View File

@@ -5,7 +5,7 @@
# Test three bugs fixed by my redoing of the missing_below logic.
. $srcdir/testsuite/rsync.fns
. $suitedir/rsync.fns
makepath "$fromdir/subdir" "$todir"
echo data >"$fromdir/subdir/file"

View File

@@ -17,7 +17,6 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
tmpdir="$scratchdir"
fromdir="$tmpdir/from"
todir="$tmpdir/to"
@@ -32,7 +31,7 @@ tab_ch=' ' # a single tab character
# Berkley's nice.
PATH="$PATH:/usr/ucb"
if diff -u "$srcdir/testsuite/rsync.fns" "$srcdir/testsuite/rsync.fns" >/dev/null 2>&1; then
if diff -u "$suitedir/rsync.fns" "$suitedir/rsync.fns" >/dev/null 2>&1; then
diffopt="-u"
else
diffopt="-c"
@@ -263,6 +262,17 @@ build_rsyncd_conf() {
logfile="$scratchdir/rsyncd.log"
hostname=`uname -n`
uid_setting='uid = 0'
gid_setting='gid = 0'
case `get_testuid` in
0) ;;
*)
# Non-root cannot specify uid & gid settings
uid_setting="#$uid_setting"
gid_setting="#$gid_setting"
;;
esac
cat >"$conf" <<EOF
# rsyncd configuration file autogenerated by $0
@@ -274,9 +284,9 @@ log file = $logfile
log format = %i %h [%a] %m (%u) %l %f%L
transfer logging = yes
exclude = ? foobar.baz
max verbosity = 9
uid = 0
gid = 0
max verbosity = 4
$uid_setting
$gid_setting
[test-from]
path = $fromdir

View File

@@ -10,7 +10,7 @@
. "$suitedir/rsync.fns"
SSH="$scratchdir/src/support/lsh"
SSH="$scratchdir/src/support/lsh.sh"
if test x"$rsync_enable_ssh_tests" = xyes; then
if type ssh >/dev/null ; then

View File

@@ -5,13 +5,13 @@
# Test that rsync handles basic xattr preservation.
. $srcdir/testsuite/rsync.fns
. $suitedir/rsync.fns
lnkdir="$tmpdir/lnk"
$RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync is configured without xattr support"
case "`xattr 2>&1`" in
*--list:*)
case "$HOST_OS" in
darwin*)
xset() {
xnam="$1"
xval="$2"
@@ -24,6 +24,27 @@ case "`xattr 2>&1`" in
RSYNC_PREFIX='rsync'
RUSR='rsync.nonuser'
;;
solaris*)
xset() {
xnam="$1"
xval="$2"
shift 2
for fn in "${@}"; do
runat "$fn" "$SHELL_PATH" <<EOF
echo "${xval}" > "${xnam}"
EOF
done
}
xls() {
for fn in "${@}"; do
runat "$fn" "$SHELL_PATH" <<EOF
for x in *; do echo "\$x=\`cat \$x\`"; done
EOF
done
}
RSYNC_PREFIX='rsync'
RUSR='rsync.nonuser'
;;
*)
xset() {
xnam="$1"

31
tls.c
View File

@@ -2,7 +2,7 @@
* Trivial ls for comparing two directories after running an rsync.
*
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 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
@@ -43,10 +43,12 @@
/* These are to make syscall.o shut up. */
int dry_run = 0;
int am_root = 0;
int am_sender = 1;
int read_only = 1;
int list_only = 0;
int link_times = 0;
int link_owner = 0;
int nsec_times = 0;
int preserve_perms = 0;
int preserve_executability = 0;
@@ -146,9 +148,9 @@ static void list_file(const char *fname)
buf.st_uid = buf.st_gid = 0;
strlcpy(linkbuf, " -> ", sizeof linkbuf);
/* const-cast required for silly UNICOS headers */
len = readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
len = do_readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
if (len == -1)
failed("readlink", fname);
failed("do_readlink", fname);
else
/* it's not nul-terminated */
linkbuf[4+len] = 0;
@@ -159,9 +161,10 @@ static void list_file(const char *fname)
permstring(permbuf, buf.st_mode);
if (buf.st_mtime) {
int len;
mt = gmtime(&buf.st_mtime);
snprintf(datebuf, sizeof datebuf,
len = snprintf(datebuf, sizeof datebuf,
"%04d-%02d-%02d %02d:%02d:%02d",
(int)mt->tm_year + 1900,
(int)mt->tm_mon + 1,
@@ -169,8 +172,17 @@ static void list_file(const char *fname)
(int)mt->tm_hour,
(int)mt->tm_min,
(int)mt->tm_sec);
} else
strlcpy(datebuf, " ", sizeof datebuf);
#ifdef ST_MTIME_NSEC
if (nsec_times) {
snprintf(datebuf + len, sizeof datebuf - len,
".%09d", (int)buf.ST_MTIME_NSEC);
}
#endif
} else {
int len = MIN(19 + 9*nsec_times, (int)sizeof datebuf - 1);
memset(datebuf, ' ', len);
datebuf[len] = '\0';
}
/* TODO: Perhaps escape special characters in fname? */
@@ -179,8 +191,8 @@ static void list_file(const char *fname)
printf("%5ld,%6ld",
(long)major(buf.st_rdev),
(long)minor(buf.st_rdev));
} else /* NB: use double for size since it might not fit in a long. */
printf("%12.0f", (double)buf.st_size);
} else
printf("%15s", do_big_num(buf.st_size, 1, NULL));
printf(" %6ld.%-6ld %6ld %s %s%s\n",
(long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
datebuf, fname, linkbuf);
@@ -192,6 +204,9 @@ static struct poptOption long_options[] = {
{"link-owner", 'L', POPT_ARG_NONE, &link_owner, 0, 0, 0 },
#ifdef SUPPORT_XATTRS
{"fake-super", 'f', POPT_ARG_VAL, &am_root, -1, 0, 0 },
#endif
#ifdef ST_MTIME_NSEC
{"nsec", 's', POPT_ARG_NONE, &nsec_times, 0, 0, 0 },
#endif
{"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
{0,0,0,0,0,0,0}

37
token.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2009 Wayne Davison
* Copyright (C) 2003-2013 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +20,15 @@
*/
#include "rsync.h"
#include "ifuncs.h"
#include "zlib/zlib.h"
#include "itypes.h"
#include <zlib.h>
#ifndef Z_INSERT_ONLY
#define Z_INSERT_ONLY Z_SYNC_FLUSH
#endif
extern int do_compression;
extern int protocol_version;
extern int module_id;
extern int def_compress_level;
extern char *skip_compress;
@@ -308,7 +313,7 @@ send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
Z_DEFLATED, -15, 8,
Z_DEFAULT_STRATEGY) != Z_OK) {
rprintf(FERROR, "compression init failed\n");
exit_cleanup(RERR_STREAMIO);
exit_cleanup(RERR_PROTOCOL);
}
if ((obuf = new_array(char, OBUF_SIZE)) == NULL)
out_of_memory("send_deflated_token");
@@ -411,14 +416,18 @@ send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
toklen -= n1;
tx_strm.next_in = (Bytef *)map_ptr(buf, offset, n1);
tx_strm.avail_in = n1;
tx_strm.next_out = (Bytef *) obuf;
tx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
r = deflate(&tx_strm, Z_INSERT_ONLY);
if (r != Z_OK || tx_strm.avail_in != 0) {
rprintf(FERROR, "deflate on token returned %d (%d bytes left)\n",
r, tx_strm.avail_in);
exit_cleanup(RERR_STREAMIO);
}
if (protocol_version >= 31) /* Newer protocols avoid a data-duplicating bug */
offset += n1;
do {
tx_strm.next_out = (Bytef *) obuf;
tx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
r = deflate(&tx_strm, Z_INSERT_ONLY);
if (r != Z_OK) {
rprintf(FERROR, "deflate on token returned %d (%d bytes left)\n",
r, tx_strm.avail_in);
exit_cleanup(RERR_STREAMIO);
}
} while (tx_strm.avail_in != 0);
} while (toklen > 0);
}
}
@@ -452,7 +461,7 @@ static int32 recv_deflated_token(int f, char **data)
rx_strm.zfree = NULL;
if (inflateInit2(&rx_strm, -15) != Z_OK) {
rprintf(FERROR, "inflate init failed\n");
exit_cleanup(RERR_STREAMIO);
exit_cleanup(RERR_PROTOCOL);
}
if (!(cbuf = new_array(char, MAX_DATA_COUNT))
|| !(dbuf = new_array(char, AVAIL_OUT_SIZE(CHUNK_SIZE))))
@@ -593,6 +602,8 @@ static void see_deflate_token(char *buf, int32 len)
} else {
rx_strm.next_in = (Bytef *)buf;
rx_strm.avail_in = blklen;
if (protocol_version >= 31) /* Newer protocols avoid a data-duplicating bug */
buf += blklen;
len -= blklen;
blklen = 0;
}

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