Compare commits

..

251 Commits

Author SHA1 Message Date
Wayne Davison
1ddcdaf3f6 Preparing for release of 3.0.8 2011-03-26 14:34:18 -07:00
Wayne Davison
93562b1941 Mention CVE-2011-1097. 2011-03-26 14:31:45 -07:00
Wayne Davison
959bd70820 Tweak dir xattrs after the writability fudging. 2011-03-26 10:17:14 -07:00
Wayne Davison
a7271fb30f Avoid re-setting xattrs on a hard-linked file w/the same xattrs.
Improved the xattrs testing to include hard-linking.
2011-03-26 10:01:37 -07:00
Wayne Davison
277036153a Mention the latest changes. 2011-03-20 19:46:27 -07:00
Wayne Davison
bc6363f9ab Enhance the -liconv check for OS X. Fixes bug 8018. 2011-03-20 19:31:58 -07:00
Wayne Davison
e71130fd77 Don't send user/group names for ACLs with --numeric-ids.
Fixes bug 8020.
2011-03-18 14:42:28 -07:00
Wayne Davison
38c9f1becf Get rid of an unused extern. 2011-03-17 11:25:12 -07:00
Wayne Davison
779663fc6c Fix xattrs test on OS X. 2011-03-13 20:48:55 -07:00
Wayne Davison
9562cc8925 A few minor NEWS improvements. 2011-02-26 08:10:27 -08:00
Wayne Davison
a945aa19d9 Clarify what extraneous hard link are. 2011-02-23 07:19:23 -08:00
Wayne Davison
2a1d251750 Get rid of obsolete tempfs warning. 2011-02-22 15:37:13 -08:00
Wayne Davison
8750f64ec7 Preparing for release of 3.0.8pre1 2011-02-22 11:03:42 -08:00
Wayne Davison
922895d9a3 Mention even more fixes. 2011-02-22 10:58:33 -08:00
Wayne Davison
72193c82a6 Some uid/gid fixes for (id_t)-1.
The code now avoids any special internal meaning for gid -1.  If chown()
is called with a uid or gid of -1, complain that the ID is not settable
and signal a transfer error.
2011-02-22 10:48:13 -08:00
Wayne Davison
b178eb04d3 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:51:14 -08:00
Wayne Davison
3158b8df6c Fix --force with --one-file-system w/o --delete. 2011-02-22 08:21:08 -08:00
Wayne Davison
aa3640c09b Fix issue with devices-fake test. 2011-02-22 07:59:08 -08:00
Wayne Davison
07b5c770db Fix test 5's failure message. 2011-02-22 07:41:02 -08:00
Wayne Davison
8b7f20b6d3 Mention latest changes. 2011-02-21 11:32:51 -08:00
Wayne Davison
1dabd5dc9a A few more xattr-support fixes from the master branch. 2011-02-21 11:32:51 -08:00
Wayne Davison
58d657c98f Be clear on which part(s) of testsuite's checkit() failed. 2011-02-21 11:32:51 -08:00
Wayne Davison
e46262f36d Fix issues with unchanged_attrs() for symlinks. 2011-02-21 11:32:51 -08:00
Wayne Davison
4d92246a54 Use ftruncate() at the end of a --sparse file.
Fixes bug 7337.
2011-02-21 11:32:51 -08:00
Wayne Davison
8f48ba03b5 Integrate time-setting fixes/improvements from the master branch. 2011-02-21 11:32:48 -08:00
Wayne Davison
eb8058577d Make case_N.h more generic. 2011-02-21 10:20:58 -08:00
Wayne Davison
3c624bba85 Better mask handling, including some changes to help solaris. 2011-02-21 10:20:58 -08:00
Wayne Davison
24e76f840e Pass "new_mode" to set_acl() and change its return values. 2011-02-21 10:20:58 -08:00
Wayne Davison
b62ea517f6 Put file descriptor arg at the start of the arg list for consistency. 2011-02-21 10:20:58 -08:00
Wayne Davison
a6b3c2b512 Added more missing NEWS items. 2011-02-20 23:51:25 -08:00
Wayne Davison
4e95f91f27 Some manpage enhancements. 2011-02-20 23:48:19 -08:00
Wayne Davison
fad4ab9d0b Suggest a better solution for a make without wildcard support. 2011-02-20 23:48:19 -08:00
Wayne Davison
f91b15fbd6 Add .hg dir exclude to default_cvsignore list.
Fixes bug 7957.
2011-02-20 23:48:19 -08:00
Wayne Davison
83b94efa6b Switch over to Matt's idea of using FLAG_OWNED_BY_US. 2011-01-29 22:19:14 -08:00
Wayne Davison
2064c28d6d Move FLAG_DEL_NEEDS_UID into the "not stored" section. 2011-01-29 20:52:38 -08:00
Wayne Davison
c499002e51 Fix a random flist data bug w/delete, inc-recurse, and no -o.
Fixes bug 7936.
2011-01-29 19:25:53 -08:00
Wayne Davison
c8255147b0 Optimize finding the sum that matches our --inplace position. 2011-01-16 17:23:55 -08:00
Wayne Davison
eee85e3c36 Make sure an alternate --inplace sum has the right length
and add missing break in --inplace same-offset loop.
2011-01-14 15:45:12 -08:00
Wayne Davison
0c0219fe84 Some fixes and improvements from the master branch. 2011-01-13 23:03:59 -08:00
Wayne Davison
a92edcbf5c Avoid splitting a multi-byte character when trimming a name.
Fixes bug 7816.  Also makes the get_tmpname() code and comments
more like the master.
2011-01-03 20:07:28 -08:00
Wayne Davison
17549c95de Mention that sorting the --files-from input is helpful. 2011-01-03 19:49:29 -08:00
Wayne Davison
9d6fe1a6f0 Avoid reading ACL/xattr info on filetypes not being copied.
Make Linux avoid xattr access on symlinks.
Make OS X avoid xattr access on device/special files.
Fixes bug 5458.
2011-01-03 11:23:19 -08:00
Wayne Davison
c43624c575 Mention the latest changes. 2011-01-01 21:24:36 -08:00
Wayne Davison
4baef8d663 Make xattrs.test more like the master version. 2011-01-01 21:24:27 -08:00
Wayne Davison
c3ee6ac369 Avoid directory permission issues with --fake-super.
Fixes bug 7070.
2011-01-01 16:57:08 -08:00
Wayne Davison
63c5ac38a2 Report all socket connection errors if we fail.
Fixes bug 6588.
2011-01-01 13:55:03 -08:00
Wayne Davison
ce41e68995 Itemize xattrs of a missing dir from an alt-dest dir.
Fixes bug 6576.
2011-01-01 13:03:23 -08:00
Wayne Davison
8538db7829 Use full_fname() for system error messages. 2011-01-01 12:33:53 -08:00
Wayne Davison
559bd2ff31 Tweak the year. 2011-01-01 11:51:29 -08:00
Wayne Davison
485a40318c Protect a remote filename that starts with a dash. 2010-12-23 22:08:34 -08:00
Wayne Davison
ede8cae34b Tweak some apostrophes to make editor highlighting less problematic. 2010-12-19 09:11:46 -08:00
Wayne Davison
58ab32037d Optimize --inplace chunck search to avoid a non-aligned search. 2010-12-18 08:27:03 -08:00
Wayne Davison
00cde6582c Mention seek effect of an unmoved --inplace chunk. 2010-12-18 08:17:03 -08:00
Wayne Davison
e6ba6e1107 Improve description of --chmod example. 2010-12-18 08:13:52 -08:00
Wayne Davison
efad2e85ea Fix crash when --backup-dir is excessively long. 2010-12-16 22:20:10 -08:00
Wayne Davison
c463617443 Some quoting fixes/improvements. 2010-09-06 08:42:02 -07:00
Wayne Davison
6abb59adf6 If we create an off_t type, define SIZEOF_OFF_T. 2010-09-06 08:26:50 -07:00
Wayne Davison
d79bc5c791 Fix rsync_xal_set reference in an error. 2010-09-06 08:09:20 -07:00
Wayne Davison
10cd07c225 Avoid infinite loop if the file's length is negative.
Fixes bug 4664.
2010-09-06 08:05:26 -07:00
Wayne Davison
62e9eb7bc2 Mention need of wildcard support in make.
See bug 7625.
2010-08-28 18:05:20 -07:00
Wayne Davison
de20d72541 Remove duplication for -x option. 2010-08-28 18:04:09 -07:00
Wayne Davison
f8cd1c4730 A couple more NEWS items. 2010-07-03 09:30:44 -07:00
Wayne Davison
5de3fe19b6 Always use lchmod() if it is available. 2010-07-03 09:22:50 -07:00
Wayne Davison
0ac2d243bf Mention what -XX (repeated --xattrs) does. 2010-07-03 09:22:13 -07:00
Matt McCutchen
14556a30b3 Document the "copy-some-dirlinks" trick in the man page.
Originally explained at:

http://lists.samba.org/archive/rsync/2006-February/014838.html
2010-07-03 09:21:10 -07:00
Matt McCutchen
8c1f2d53ec Fix erroneous "--fake-user" in the rsyncd.conf(5) man page. 2010-07-03 09:20:07 -07:00
Matt McCutchen
f532cede11 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-07-03 09:19:01 -07:00
Wayne Davison
05022e00a2 More NEWS. 2010-07-03 08:56:09 -07:00
Wayne Davison
24a743b565 If a module has no path setting, return an error. 2010-07-03 08:54:40 -07:00
Wayne Davison
e36f5c9f6c Mention latest changes. 2010-07-03 08:49:46 -07:00
Wayne Davison
c9c3215698 Refer to the right lsetxattr() caller in a error message. 2010-07-03 08:47:02 -07:00
Wayne Davison
dbfde9e50a Fix compression-ignoring of upper-case suffixes.
Fixes bug 7512.
2010-07-03 08:47:02 -07:00
Wayne Davison
1cdb5e1c86 Fix a couple socketpair_tcp() issues (see bug 7514). 2010-07-03 08:47:02 -07:00
Wayne Davison
24afdc500a Fix a typo that Andrea Gelmini pointed out. 2010-07-03 08:40:23 -07:00
Wayne Davison
303759b803 Get rid of trailing whitespace. 2010-07-03 08:40:23 -07:00
Matt McCutchen
a699f7c6af Man page description of --xattrs should not assume a push. 2010-07-03 08:37:25 -07:00
Wayne Davison
a250fa251b More manpage improvements. 2010-07-03 08:35:44 -07:00
Matt McCutchen
e44aa644c2 Amplify the man page description of --hard-links (see bug 3693), and
improve that of --inplace while I'm at it.
2010-07-03 08:33:24 -07:00
Wayne Davison
ef67c238b5 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.
2010-07-03 08:27:38 -07:00
Wayne Davison
111599be2b Mention 2010 in the main copyright. 2010-07-03 08:24:58 -07:00
Wayne Davison
8e918e1861 Make an empty-string dest-dir the same as "." again. 2010-07-03 08:23:31 -07:00
Wayne Davison
0874fc4872 Setup for 3.0.8dev. 2010-06-30 09:19:01 -07:00
Wayne Davison
55dbbdeafe Fixed inconsistencies reported by packaging/var-checker. 2010-06-30 09:17:26 -07:00
Wayne Davison
cbd27d5e18 Update support/rrsync and some packaging/* scripts. 2010-06-30 09:17:13 -07:00
Matt McCutchen
178ccdde7d Rename configure.in to configure.ac, the current autoconf standard. 2010-06-30 08:29:48 -07:00
Wayne Davison
e51bb8f330 Write out the right compat_flags value into the batch file. 2010-06-26 16:14:15 -07:00
Wayne Davison
6d9207bd38 Turn some asserts into descriptive errors. 2010-06-26 16:13:58 -07:00
Wayne Davison
6b87566744 Make sure our use of idev_find() hashtable is right
while also supporting older rsyncs that send dev == 0.
2010-06-26 16:13:20 -07:00
Wayne Davison
b384d71e53 Make sure that the code doesn't try to use an illegal key. 2010-06-26 11:32:14 -07:00
Wayne Davison
11f4f34ed9 Fix daemon-filter crash issue (bug 7489). 2010-06-04 23:10:47 -07:00
Wayne Davison
fe2c582af8 Removing now-redundant path-size check from send_if_directory(). 2010-03-31 15:00:53 -07:00
Wayne Davison
2ecd8b7cd2 Fix directory-length overflow bug (7057). 2010-03-26 16:56:40 -07:00
Wayne Davison
54f00c3f89 Preparing for release of 3.0.7 2009-12-31 13:08:07 -08:00
Wayne Davison
1fc8c51705 Allow any gcc to make use of __builtin_alloca for alloca. 2009-12-30 20:03:49 -08:00
Wayne Davison
b04604945d Configure check for -Wno-unused-parameter now tries to link too. 2009-12-30 19:57:47 -08:00
Wayne Davison
808b1d61c0 Fixed the passing of a '/' modifier for an absolute-path filter rule. 2009-12-30 12:25:33 -08:00
Wayne Davison
2f01fb1152 Preparing for release of 3.0.7pre2 2009-12-24 08:31:37 -08:00
Wayne Davison
ae358c1960 Revert to having the receiver handle timeouts on the receiving side.
This will give 3.0.7 the standard timeout handling with just a few
improvements: a fix for the detection of recent sender I/O, the use
of MSG_DATA for really old rsync versions, and better setting of
select_timeout for shorter timeout settings.
2009-12-23 11:36:27 -08:00
Wayne Davison
212dfdb960 Preparing for release of 3.0.7pre1 2009-12-21 18:25:00 -08:00
Wayne Davison
c11a77894b Ensure that the generator gets notified about an I/O error for the dir
that generated the error.  This ensures that a --delete-during avoids
deleting in a newly transferred inc-recurse directory.  Requires 3.0.7
or greater on both sides of the transfer.
2009-12-21 14:40:41 -08:00
Wayne Davison
96cce18ce6 Defer forwarding messages during the forwarding of flist data. 2009-12-21 13:48:44 -08:00
Wayne Davison
a21264a8b9 Mention the compress fix. 2009-12-21 10:52:54 -08:00
Wayne Davison
96486cc534 Mention latest --timeout fixes. 2009-12-21 10:25:15 -08:00
Wayne Davison
e0b1b82d84 Don't die if inflate() returns Z_BUF_ERROR in see_deflate_token(). 2009-12-21 10:15:39 -08:00
Wayne Davison
d94b958400 Improve --timeout method to take into account all socket I/O that is
going on.  The receiving side also switches timeout handling from the
receiver to the generator.  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 13:39:49 -08:00
Wayne Davison
79731940bb Added an am_receiver variable. 2009-12-19 12:04:25 -08:00
Wayne Davison
bdc038fce0 Use 0-length MSG_DATA when MSG_NOOP is not available
(is both safer and supports older rsyncs).
2009-12-16 13:32:03 -08:00
Wayne Davison
2eacba9c41 Avoid -u option to id since solaris doesn't support it. 2009-12-13 19:35:01 -08:00
Wayne Davison
0c5853c32e Get rid of some unused externs. 2009-12-12 22:43:51 -08:00
Wayne Davison
3baa4d2b31 Include info on who is exiting. 2009-12-12 22:42:35 -08:00
Wayne Davison
018dc6f998 Mention the newly cherry-picked changes. 2009-12-12 17:26:11 -08:00
Wayne Davison
523dad4bb3 Use seteuid() (if available) when using setuid(). 2009-12-12 17:26:05 -08:00
Wayne Davison
e0c17aa3b7 Beginning work on a 3.0.7 release. 2009-12-12 17:25:48 -08:00
Wayne Davison
79870bd269 Don't (wrongly) retouch dir permissions with --fake-super.
(Patch from Matt.)
2009-12-12 17:25:19 -08:00
Wayne Davison
e4368e37fe Add IPv6 detection on cygwin. 2009-12-12 17:25:12 -08:00
Wayne Davison
eee529f571 Save first filename and linenum in case exit_cleanup() recurses. 2009-12-12 17:25:06 -08:00
Wayne Davison
ff4715a7c2 Moved some --iconv text that was supposed to be in --files-from. 2009-12-12 17:24:45 -08:00
Wayne Davison
855983b434 Make sure daemon's io_timeout is used as a maximum value. 2009-12-12 17:24:39 -08:00
Wayne Davison
2455140b04 Fix some man page problems Scott Kostyshak pointed out. 2009-12-12 17:24:33 -08:00
Wayne Davison
ae4d4205e3 Avoid type-punned compiler warnings for the byteorder.h macros
by using inline functions for the 4-char <-> uint32 conversions.
2009-12-12 17:24:29 -08:00
Wayne Davison
9523670032 Improve the "--delete does not work without -r or -d" message. 2009-12-12 17:23:55 -08:00
Wayne Davison
01e57e926c Improve error handling and get rid of a lingering fprintf(). 2009-12-12 17:23:45 -08:00
Wayne Davison
ebbab3788f Fix daemon's conveyance of io_error value from sender. 2009-12-12 17:23:03 -08:00
Wayne Davison
d041c17c40 Avoid an dry-run error trying to stat a prior hard-link
file that hasn't really been created.
2009-12-12 17:22:55 -08:00
Wayne Davison
b2b1af40c2 Rebuild proto.h if config.h changes. 2009-12-12 17:22:43 -08:00
Wayne Davison
c5759a2817 Fix the chmod-temp-dir test if /var/tmp doesn't exist.
Fixes bug 6569.
2009-12-12 17:22:12 -08:00
Wayne Davison
5ef08b8c39 Get section reference right. Fixes bug #6573. 2009-12-12 17:22:05 -08:00
Wayne Davison
03f907e386 Added solaris IPv6 checking to configure. Fixes #6438.
Patch from Tim Spriggs.
2009-12-12 17:21:25 -08:00
Wayne Davison
573e24346c Mention that --whole-file is not the default for a local transfer when
writing a batch file.
2009-12-12 17:21:08 -08:00
Wayne Davison
a415379037 Support an older AIX system that doesn't have ENOTSUP. 2009-12-12 17:20:42 -08:00
Wayne Davison
cc4edc2d78 Switch from inet_aton() to inet_pton() (since we supply a compatibility
function for the latter, it will always exist).
2009-12-12 17:20:35 -08:00
Wayne Davison
07bd6618b9 Allow $RSYNC_TEST_TMP to indicate a good tmp dir for our tests. 2009-12-12 17:19:59 -08:00
Wayne Davison
2daed024b1 Fix a bogus free in uncache_tmp_xattrs(). 2009-08-14 07:04:24 -07:00
Wayne Davison
6622816eff Preparing for release of 3.0.6 2009-05-08 10:07:14 -07:00
Wayne Davison
3f137ce0e2 Fix typo pointed out by Chris Pepper. 2009-05-07 08:04:24 -07:00
Matt McCutchen
d616bff57f Move the description of include/exclude modifiers to a better place
in the man page.
2009-05-05 08:18:36 -07:00
Wayne Davison
40b3a59fc8 Clarify which options are transfer rules, and what that means. 2009-04-27 07:26:04 -07:00
Wayne Davison
4640ae85fe Change sending/receiving/storing of the rdev value for special files.
Since the value is not needed, the (superfluous) sending of the value
is optimized so that a valid rdev value is sent 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:51:50 -07:00
Wayne Davison
24f739c118 Clarify the read-batch fix. 2009-04-13 07:42:20 -07:00
Wayne Davison
996824825f Preparing for release of 3.0.6pre1 2009-04-12 15:28:34 -07:00
Wayne Davison
bbef6566cd Changed the commands used to "make gen" without any stoppage. 2009-04-12 15:19:30 -07:00
Wayne Davison
9be5093726 Don't allow --remove-s*-files with --read-batch. 2009-04-12 13:01:14 -07:00
Wayne Davison
feb8dacc14 Fixed the use of --xattrs with --only-write-batch. 2009-04-12 12:48:59 -07:00
Wayne Davison
ff908116ef Allow a "make reconfigure" to continue, even if the Makefile changes. 2009-04-10 16:24:49 -07:00
Wayne Davison
ea53d161be 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:09:39 -07:00
Wayne Davison
7875e6fe63 Don't try to simplify an ACL that has a mask w/o any named values. 2009-04-09 22:52:26 -07:00
Wayne Davison
8e2771aa6e 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:40:30 -07:00
Wayne Davison
386f22cec6 Make sure that config.h.in is up-to-date before allowing the
Makefile-updating rule to run ./config.status.
2009-04-04 07:53:14 -07:00
Wayne Davison
272adea36b 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:38:37 -07:00
Wayne Davison
a69b165524 Fixed improper deletion of mount-point hierarchies.
Fixes bug #6240.
2009-03-31 20:26:10 -07:00
Wayne Davison
bf350d7b31 Fixed a word ending that Jesse Weinstein and revamp some of the text
to make it clearer.
2009-03-31 14:35:53 -07:00
Wayne Davison
70a9cd5752 Make symlink iconv work for a local copy.
Fixes issue mention in bug #5615.
2009-03-29 13:25:43 -07:00
Matt McCutchen
42560e2e53 Give a meaningful error message when we fail to write to a batch file. 2009-03-13 09:46:39 -07:00
Wayne Davison
d058d0aecd Simplify an "if" in ssh-basic.test. Fixes bug #6169; 2009-03-06 07:08:49 -08:00
Wayne Davison
af00666a40 Mention the fix to --safe-links/--copy-unsafe-links. 2009-03-03 09:00:29 -08:00
Wayne Davison
2517f5440d 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:57:43 -08:00
Wayne Davison
f2522e3f53 Make the backup code call unsafe_symlink() correctly. 2009-03-03 08:57:39 -08:00
Wayne Davison
8fba76d5c3 Mention vanishing-directory fix. 2009-02-14 08:38:24 -08:00
Wayne Davison
782b96d3e2 Handle a link_stat() failure with errno ENOENT as a vanished file. 2009-02-14 08:37:10 -08:00
Wayne Davison
1f6b697f28 Mention the latest configure fixes. 2009-02-14 08:05:07 -08:00
Wayne Davison
919491948e 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:57:50 -08:00
Wayne Davison
0ea6f486d9 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:57:36 -08:00
Wayne Davison
9493048c10 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:27:07 -08:00
Wayne Davison
4dea1a9492 Do not try to send a symlink with a 0-length value.
This avoids a transfer error in the receiver.
2009-02-04 18:16:16 -08:00
Wayne Davison
650bca3770 A few more improvements to the hostspec-parsing code. 2009-01-28 23:18:45 -08:00
Wayne Davison
794f38099a Fixed the parsing of IPv6 literal addresses with a username
prefixed.  Fixes bug #6067.
2009-01-28 15:58:48 -08:00
Wayne Davison
8250d8a1c6 Fixed a hang in the inc_recurse batch-reading code. 2009-01-17 13:54:52 -08:00
Matt McCutchen
1fb6163c51 Handle simultaneous arrival of multiple connections. 2009-01-17 13:46:11 -08:00
Wayne Davison
7f51d0e849 Avoid a server-side problem with -e is at the start of the short options.
(Bug #6020)
2009-01-17 13:44:06 -08:00
Wayne Davison
ece2d0e415 Fixed bug #6011: use of target in configure. 2009-01-17 13:43:48 -08:00
Wayne Davison
445640e803 Update the copyright year. 2009-01-17 13:41:35 -08:00
Wayne Davison
5ea7c8aae3 Beginning work on a 3.0.6 release. 2009-01-17 13:37:20 -08:00
Wayne Davison
7221063019 Preparing for release of 3.0.5 2008-12-28 18:02:17 -08:00
Wayne Davison
b64ae8b3b4 Avoid a hang when using at least 3 --verbose options on a transfer with
a client sender (which includes local copying).
2008-12-28 17:51:36 -08:00
Wayne Davison
9938bad34a Allow opendir() in send_directory() to fail with ENOENT. 2008-12-27 11:22:02 -08:00
Wayne Davison
1ff3e90507 Make it clearer which configure files changed. 2008-11-15 15:32:02 -08:00
Wayne Davison
b292021e45 Mention a few NEWS items that hadn't been mentioned yet. 2008-11-15 15:25:30 -08:00
Wayne Davison
13e40ca0c6 Preparing for release of 3.0.5pre2 2008-11-15 14:55:30 -08:00
Wayne Davison
8e85627fb3 An ftruncate() failure should result in FERROR_XFER. 2008-11-15 14:49:28 -08:00
Wayne Davison
d552250fbb Tweaked the month guess in OLDNEWS. 2008-11-15 14:38:14 -08:00
Wayne Davison
5436b64557 Change clean_fname() to keep "//" at the start for cygwin. 2008-11-15 14:17:49 -08:00
Wayne Davison
b325dd0326 Change some size_t vars to ints. 2008-11-15 13:29:03 -08:00
Wayne Davison
49818a8378 Make sparse_seek an OFF_T (pointed out by Pedro Valasco). 2008-11-11 18:06:50 -08:00
Wayne Davison
af03a7049c A "make reconfigure" doesn't stop if configure changes. 2008-11-11 15:55:53 -08:00
Wayne Davison
e401b30403 Mention Matt's -K --delete fix. 2008-11-10 07:48:00 -08:00
Matt McCutchen
e512826786 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:46:41 -08:00
Wayne Davison
ccdc2efd67 Mention the fix for --files-from dot/./paths. 2008-11-09 21:48:21 -08:00
Wayne Davison
b8a1fd6404 Fixed the use of a dot-dir path (foo/./bar) inside of a files-from file. 2008-11-09 21:39:08 -08:00
Wayne Davison
3082dffbe2 Fixed a bunch of "warn_unused_result" compiler warnings. 2008-11-09 18:55:14 -08:00
Wayne Davison
42130f9cb0 Mention hang fix in the NEWS. 2008-11-09 18:07:30 -08:00
Wayne Davison
c6c339cd18 Avoid a potential hang when --remove-*-files is active. 2008-11-09 18:02:11 -08:00
Matt McCutchen
6767ca617b 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:53:01 -08:00
Wayne Davison
7d9e30d383 Mention the getnameinfo() fix in the NEWS. 2008-10-25 09:47:08 -07:00
Wayne Davison
3f81ad6060 Mention rsync's definition of client and server. 2008-10-25 09:44:21 -07:00
Wayne Davison
723e9f856d Fixed our supplied getnameinfo()'s ability to do a reverse lookup,
as reported in bug 5851.
2008-10-25 08:39:41 -07:00
Wayne Davison
9189e41f6e Added another file-list filter to handle odd-ball systems that don't
seem to size their sprintf() fields correctly.
2008-10-14 07:27:56 -07:00
Wayne Davison
6f6f9d1020 Preparing for release of 3.0.5pre1 2008-10-11 11:41:05 -07:00
Wayne Davison
a76ba8b425 Mention the latest NEWS. 2008-10-11 11:40:40 -07:00
Wayne Davison
b8fd528794 Fixed a glitch when using -s with a remote-shell daemon. 2008-10-11 11:14:43 -07:00
Wayne Davison
0ea5d30479 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:13:43 -07:00
Wayne Davison
cf1b292201 Fixed send_protected_args() to send "." in place of an empty arg. 2008-10-11 10:16:47 -07:00
Wayne Davison
f3721ed133 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:29:23 -07:00
Wayne Davison
b1220d62f4 Fix the error message on one of the rename operations. 2008-10-10 06:55:21 -07:00
Wayne Davison
5df89a1a44 Remove bogus "non-empty" qualifier in '*' discussion. 2008-09-26 21:47:53 -07:00
Wayne Davison
d47ac91209 Properly ignore source args on a --read-batch command. 2008-09-26 21:34:40 -07:00
Wayne Davison
7c573428a9 Fixed skipping of unneeded updates in a batch file when incremental
recursion is active.  Added a test for this.  Made batch-mode handle
redos properly (and without hanging).
2008-09-26 21:32:43 -07:00
Wayne Davison
f7e65c7b61 Moved the flist_ndx_{push,pop}() routines from io.c into util.c. 2008-09-26 21:21:52 -07:00
Wayne Davison
fe62d30de8 Fix the %P logfile escape inside a chroot. 2008-09-26 21:19:51 -07:00
Wayne Davison
494895fb4b 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-26 21:10:58 -07:00
Wayne Davison
ac68345a34 Don't send a bogus "-" option to an older server if there were
no short options specified.
2008-09-26 21:09:41 -07:00
Wayne Davison
6a9ade2ded Beginning work on a 3.0.5 release. 2008-09-26 21:07:56 -07:00
Wayne Davison
d596d389fe Preparing for release of 3.0.4 2008-09-06 09:32:26 -07:00
Wayne Davison
bc2337717e A few more improvements and a mention of the latest fix. 2008-09-06 08:03:52 -07:00
Wayne Davison
3df40f044a Changed some "rsync" commands into proper "$RSYNC" commands. 2008-09-03 12:14:13 -07:00
Wayne Davison
d11a5b80c1 Made human_num() and human_dnum() able to output negative numbers. 2008-09-01 13:25:41 -07:00
Wayne Davison
deea1f70bd Got rid of the check_for_io_err code, as it could cause a hang.
The io_error issue will be fixed in a better way in 3.1.0.
2008-08-31 09:51:29 -07:00
Wayne Davison
a91e678324 Some minor improvements to the flushing code to try to make it
even more solid.
2008-08-24 13:39:44 -07:00
Wayne Davison
25a22d8501 Make the !flist_eof assumption explicit before the check_for_io_err
code calls wait_for_receiver().
2008-08-24 12:33:22 -07:00
Wayne Davison
fac9e234ae Added /support/savetransfer to .gitignore. 2008-08-17 09:28:06 -07:00
Wayne Davison
f3d87ee972 An improved RERR_PARTIAL message. 2008-08-17 09:25:34 -07:00
Wayne Davison
9bed85542c Changed flist_for_ndx() to optionally die with an error
if the index isn't found.
2008-08-14 07:32:18 -07:00
Wayne Davison
5b979530a7 Made an error of readlink_stat() use the right function name. 2008-08-10 07:31:45 -07:00
Wayne Davison
7ec8baaa7e Make sure that the hlink node->data allocation doesn't fail. 2008-08-08 07:47:31 -07:00
Wayne Davison
8c2c008984 Improved a couple NEWS items. 2008-08-05 18:43:51 -07:00
Wayne Davison
719a29e1cf Preparing for release of 3.0.4pre2 2008-08-02 14:06:31 -07:00
Wayne Davison
4a95d61251 Tweaked the symlink iconv buffer size and fixed a comment. 2008-08-02 13:45:15 -07:00
Wayne Davison
fc088e30c8 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:25:17 -07:00
Wayne Davison
aef51b4c68 Refer to the symlink's contents as "symlink data", not "symlink name". 2008-08-02 10:18:10 -07:00
Wayne Davison
7790ee3684 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:03:49 -07:00
Wayne Davison
ed12c8eb21 Skip new symlink conversion step if the remote rsync is not
new enough to do symlink content conversions.
2008-08-02 07:04:54 -07:00
Wayne Davison
91dd3d0d48 The --iconv option now converts the content of a symlink too. 2008-08-01 19:20:41 -07:00
Wayne Davison
95d1d2a9a4 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:00:21 -07:00
Wayne Davison
a808346dbe 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:00:18 -07:00
Wayne Davison
fa181223d8 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:00:09 -07:00
Wayne Davison
9ed569486f Output an FERROR* for a general io_error, and an FWARNING for other
io_error flags.
2008-07-31 07:57:55 -07:00
Wayne Davison
2fa069d85f Mention a missing sender-side hash improvment that went out in 3.0.0. 2008-07-30 08:33:35 -07:00
Wayne Davison
a25aed50e6 Make hard-linking work when a device has an st_dev of 0. 2008-07-29 18:08:51 -07:00
Wayne Davison
302e4346c2 Mention some mount options that can interfere with --link-dest. 2008-07-28 18:24:25 -07:00
Wayne Davison
8e5eafccdf Back-porting some manpage improvements. 2008-07-28 17:07:38 -07:00
Wayne Davison
e88b92bade Preparing for release of 3.0.4pre1 2008-07-24 17:03:26 -07:00
Wayne Davison
f8722dba56 Fixed the --fake-super test in the xattrs testsuite when there are
root-level xattrs on the files (e.g. selinux values).
2008-07-24 07:57:57 -07:00
Wayne Davison
ee03cb99d9 Fixed the timeout/flush loop-check logic to work properly with
incremental recursion.
2008-07-23 23:37:11 -07:00
Wayne Davison
92d706a274 Don't interrupt the make if a generated build file didn't really change. 2008-07-23 23:28:57 -07:00
Wayne Davison
581c830c56 A couple xattr fixes for --fake-super. 2008-07-23 23:12:39 -07:00
Wayne Davison
9e58ef45f3 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-23 23:09:15 -07:00
Wayne Davison
05bd05a7a1 Pass --branch option to patch-update script. 2008-07-23 17:13:29 -07:00
Wayne Davison
89b6b4ce4b We only need to deal with local patch branches now. 2008-07-23 14:32:58 -07:00
Wayne Davison
68cdc3b791 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 21:35:21 -07:00
Wayne Davison
209371b891 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-22 21:34:20 -07:00
Wayne Davison
6fd2662982 Allow a release from a non-master branch. 2008-07-22 09:11:34 -07:00
Wayne Davison
1fdf0302c0 Start the 3.0.4 branch. 2008-07-22 09:11:22 -07:00
130 changed files with 6546 additions and 14222 deletions

4
.gitignore vendored
View File

@@ -23,15 +23,11 @@ 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,7 +4,6 @@
prefix=@prefix@
datarootdir=@datarootdir@
exec_prefix=@exec_prefix@
stunnel4=@STUNNEL4@
bindir=@bindir@
mandir=@mandir@
@@ -19,42 +18,40 @@ INSTALLCMD=@INSTALL@
INSTALLMAN=@INSTALL@
srcdir=@srcdir@
MKDIR_P=@MKDIR_P@
VPATH=$(srcdir)
SHELL=/bin/sh
VERSION=@RSYNC_VERSION@
VERSION=@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 itypes.h inums.h \
lib/pool_alloc.h
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.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@
zlib_OBJS=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
ZLIBOBJ=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 util2.o main.o checksum.o match.o syscall.o log.o backup.o delete.o
util.o main.o checksum.o match.o syscall.o log.o backup.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) @BUILD_ZLIB@ @BUILD_POPT@
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @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) \
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(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 testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o
CHECK_OBJS=tls.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:
@@ -62,30 +59,16 @@ CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
@OBJ_RESTORE@
all: Makefile rsync$(EXEEXT) rsync-ssl stunnel-rsync stunnel-rsyncd.conf @MAKE_MAN@
all: Makefile rsync$(EXEEXT) @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
@@ -118,9 +101,6 @@ 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)
@@ -131,7 +111,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 util2.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.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)
@@ -189,17 +169,6 @@ 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
@@ -208,11 +177,9 @@ 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 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
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
rsync.1: rsync.yo
yodl2man -o rsync.1 $(srcdir)/rsync.yo
@@ -234,7 +201,6 @@ 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
@@ -273,9 +239,6 @@ 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)

337
NEWS
View File

@@ -1,243 +1,138 @@
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.
NEWS for rsync 3.0.8 (26 Mar 2011)
Protocol: 30 (unchanged)
Changes since 3.0.7:
BUG FIXES:
- Fixed a bug in the iconv code when EINVAL or EILSEQ is returned with a
full output buffer.
- Fixed two buffer-overflow issues: one where a directory path that is
exactly MAXPATHLEN was not handled correctly, and one handling a
--backup-dir that is extra extra large.
- Fixed some rare bugs in --iconv processing that might cause a multibyte
character to get translated incorrectly.
- Fixed a data-corruption issue when preserving hard-links without
preserving file ownership, and doing deletions either before or during
the transfer (CVE-2011-1097). This fixes some assert errors in the
hard-linking code, and some potential failed checksums (via -c) that
should have matched.
- Fixed a bogus "vanished file" error if some files were specified with
"./" prefixes and others were not.
- Fixed a potential crash when an rsync daemon has a filter/exclude list
and the transfer is using ACLs or xattrs.
- Fixed a bug in --sparse where an extra gap could get inserted after a
partial write.
- Fixed a hang if a really large file is being processed by an rsync that
can't handle 64-bit numbers. Rsync will now complain about the file
being too big and skip it.
- Changed the way --progress overwrites its prior output in order to make
it nearly impossible for the progress to get overwritten by an error.
- For devices and special files, we now avoid gathering useless ACL and/or
xattr information for files that aren't being copied. (The un-copied
files are still put into the file list, but there's no need to gather
data that is not going to be used.) This ensures that if the user uses
--no-D, that rsync can't possibly complain about being unable to gather
extended information from special files that are in the file list (but
not in the transfer).
- 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.
- Properly handle requesting remote filenames that start with a dash. This
avoids a potential error where a filename could be interpreted as a
(usually invalid) option.
- 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.
- Fixed a bug in the comparing of upper-case letters in file suffixes for
--skip-compress.
- 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.
- If an rsync daemon has a module configured without a path setting, rsync
will now disallow access to that module.
- 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 "..".
- If the destination arg is an empty string, it will be treated as a
reference to the current directory (as 2.x used to do).
- 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).
- If rsync was compiled with a newer time-setting function (such as
lutimes), rsync will fall-back to an older function (such as utimes) on a
system where the newer function is not around. This helps to make the
rsync binary more portable in mixed-OS-release situations.
- 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.
- Fixed a batch-file writing bug that would not write out the full set of
compatibility flags that the transfer was using. This fixes a potential
protocol problem for a batch file that contains a sender-side I/O error:
it would have been sent in a way that the batch-reader wasn't expecting.
- Fix an issue in the msleep() function if time jumps backwards.
- Some improvements to the hard-linking code to ensure that device-number
hashing is working right, and to supply more information if the hard-link
code fails.
- Fix daemon-server module-name splitting bug where an arg would get split
even if --protect-args was used.
- The --inplace code was improved to not search for an impossible checksum
position. The quadruple-verbose chunk[N] message will now mention when
an inplace chunk was handled by a seek rather than a read+write.
- Improved ACL mask handling, e.g. for Solaris.
- Fixed a bug that prevented --numeric-ids from disabling the translation
of user/group IDs for ACLs.
- Fixed an issue where an xattr and/or ACL transfer that used an alt-dest
option (e.g. --link-dest) could output an error trying to itemize the
changes against the alt-dest directory's xattr/ACL info but was instead
trying to access the not-yet-existing new destination directory.
- Improved xattr system-error messages to mention the full path to the
file.
- The --link-dest checking for identical symlinks now avoids considering
attribute differences that cannot be changed on the receiver.
- Avoid trying to read/write xattrs on certain file types for certain OSes.
Improved configure to set NO_SYMLINK_XATTRS, NO_DEVICE_XATTRS, and/or
NO_SPECIAL_XATTRS defines in config.h.
- Improved the unsafe-symlink errors messages.
- Fixed a bug setting xattrs on new files that aren't user writable.
- Avoid re-setting xattrs on a hard-linked file w/the same xattrs.
- Fixed a bug with --fake-super when copying files and dirs that aren't
user writable.
- Fixed a bug where a sparse file could have its last sparse block turned
into a real block when rsync sets the file size (requires ftruncate).
- If a temp-file name is too long, rsync now avoids truncating the name in
the middle of adjacent high-bit characters. This prevents a potential
filename error if the filesystem doesn't allow a name to contain an
invalid multi-byte sequence.
- If a muli-protocol socket connection fails (i.e., when contacting a
daemon), we now report all the failures, not just the last one. This
avoids losing a relevant error (e.g. an IPv4 connection-refused error)
that happened before the final error (e.g. an IPv6 protocol-not-supported
error).
- Generate a transfer error if we try to call chown with a -1 for a uid or
a gid (which is not settable).
- Fixed the working of --force when used with --one-file-system.
- Fix the popt arg parsing so that an option that doesn't take an arg will
reject an attempt to supply one (can configure --with-included-popt if
your system's popt library doesn't yet have this fix).
- A couple minor option tweaks to the support/rrsync script, and also some
regex changes that make vim highlighting happier.
- Fixed some issues in the support/mnt-excl script.
- Various manpage improvements.
ENHANCEMENTS:
- 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.
- 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.
- 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.
- 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).
- Added a "T" (terabyte) category to the --human-readable size suffixes.
- Added the --usermap/--groupmap/--chown options for manipulating file
ownership during the copy.
- 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).
- 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
- Added ".hg/" to the default cvs excludes (see -C & --cvs-exclude).
DEVELOPER RELATED:
- Added more conditional debug output.
- Use lchmod() whenever it is available (not just on symlinks).
- Fixed some build issues for android and minix.
- A couple fixes to the socketpair_tcp() routine.
- Updated the helper scripts in the packaging subdirectory.
- Renamed configure.in to configure.ac.
- Fixed configure's checking for iconv routines for newer OS X versions.
- Fixed the testsuite/xattrs.test script on OS X.

198
OLDNEWS
View File

@@ -1,199 +1,3 @@
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:
BUG FIXES:
- Fixed two buffer-overflow issues: one where a directory path that is
exactly MAXPATHLEN was not handled correctly, and one handling a
--backup-dir that is extra extra large.
- Fixed a data-corruption issue when preserving hard-links without
preserving file ownership, and doing deletions either before or during
the transfer (CVE-2011-1097). This fixes some assert errors in the
hard-linking code, and some potential failed checksums (via -c) that
should have matched.
- Fixed a potential crash when an rsync daemon has a filter/exclude list
and the transfer is using ACLs or xattrs.
- Fixed a hang if a really large file is being processed by an rsync that
can't handle 64-bit numbers. Rsync will now complain about the file
being too big and skip it.
- For devices and special files, we now avoid gathering useless ACL and/or
xattr information for files that aren't being copied. (The un-copied
files are still put into the file list, but there's no need to gather
data that is not going to be used.) This ensures that if the user uses
--no-D, that rsync can't possibly complain about being unable to gather
extended information from special files that are in the file list (but
not in the transfer).
- Properly handle requesting remote filenames that start with a dash. This
avoids a potential error where a filename could be interpreted as a
(usually invalid) option.
- Fixed a bug in the comparing of upper-case letters in file suffixes for
--skip-compress.
- If an rsync daemon has a module configured without a path setting, rsync
will now disallow access to that module.
- If the destination arg is an empty string, it will be treated as a
reference to the current directory (as 2.x used to do).
- If rsync was compiled with a newer time-setting function (such as
lutimes), rsync will fall-back to an older function (such as utimes) on a
system where the newer function is not around. This helps to make the
rsync binary more portable in mixed-OS-release situations.
- Fixed a batch-file writing bug that would not write out the full set of
compatibility flags that the transfer was using. This fixes a potential
protocol problem for a batch file that contains a sender-side I/O error:
it would have been sent in a way that the batch-reader wasn't expecting.
- Some improvements to the hard-linking code to ensure that device-number
hashing is working right, and to supply more information if the hard-link
code fails.
- The --inplace code was improved to not search for an impossible checksum
position. The quadruple-verbose chunk[N] message will now mention when
an inplace chunk was handled by a seek rather than a read+write.
- Improved ACL mask handling, e.g. for Solaris.
- Fixed a bug that prevented --numeric-ids from disabling the translation
of user/group IDs for ACLs.
- Fixed an issue where an xattr and/or ACL transfer that used an alt-dest
option (e.g. --link-dest) could output an error trying to itemize the
changes against the alt-dest directory's xattr/ACL info but was instead
trying to access the not-yet-existing new destination directory.
- Improved xattr system-error messages to mention the full path to the
file.
- The --link-dest checking for identical symlinks now avoids considering
attribute differences that cannot be changed on the receiver.
- Avoid trying to read/write xattrs on certain file types for certain OSes.
Improved configure to set NO_SYMLINK_XATTRS, NO_DEVICE_XATTRS, and/or
NO_SPECIAL_XATTRS defines in config.h.
- Improved the unsafe-symlink errors messages.
- Fixed a bug setting xattrs on new files that aren't user writable.
- Avoid re-setting xattrs on a hard-linked file w/the same xattrs.
- Fixed a bug with --fake-super when copying files and dirs that aren't
user writable.
- Fixed a bug where a sparse file could have its last sparse block turned
into a real block when rsync sets the file size (requires ftruncate).
- If a temp-file name is too long, rsync now avoids truncating the name in
the middle of adjacent high-bit characters. This prevents a potential
filename error if the filesystem doesn't allow a name to contain an
invalid multi-byte sequence.
- If a muli-protocol socket connection fails (i.e., when contacting a
daemon), we now report all the failures, not just the last one. This
avoids losing a relevant error (e.g. an IPv4 connection-refused error)
that happened before the final error (e.g. an IPv6 protocol-not-supported
error).
- Generate a transfer error if we try to call chown with a -1 for a uid or
a gid (which is not settable).
- Fixed the working of --force when used with --one-file-system.
- Fix the popt arg parsing so that an option that doesn't take an arg will
reject an attempt to supply one (can configure --with-included-popt if
your system's popt library doesn't yet have this fix).
- A couple minor option tweaks to the support/rrsync script, and also some
regex changes that make vim highlighting happier.
- Fixed some issues in the support/mnt-excl script.
- Various manpage improvements.
ENHANCEMENTS:
- Added ".hg/" to the default cvs excludes (see -C & --cvs-exclude).
DEVELOPER RELATED:
- Use lchmod() whenever it is available (not just on symlinks).
- A couple fixes to the socketpair_tcp() routine.
- Updated the helper scripts in the packaging subdirectory.
- Renamed configure.in to configure.ac.
- 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)
Changes since 3.0.6:
@@ -3290,8 +3094,6 @@ Changes since 2.4.6:
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
08 May 2009 3.0.6 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-2013 Wayne Davison
* Copyright (C) 2004-2009 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,50 +20,14 @@
#include "rsync.h"
static int allow_forward_dns;
extern const char undetermined_hostname[];
static int match_hostname(const char **host_ptr, const char *addr, const char *tok)
static int match_hostname(char *host, char *tok)
{
struct hostent *hp;
unsigned int i;
const char *host = *host_ptr;
if (!host || !*host)
return 0;
/* 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;
return wildmatch(tok, host);
}
static int match_binary(const char *b1, const char *b2, const char *mask, int addrlen)
static int match_binary(char *b1, char *b2, char *mask, int addrlen)
{
int i;
@@ -92,7 +56,7 @@ static void make_mask(char *mask, int plen, int addrlen)
return;
}
static int match_address(const char *addr, const char *tok)
static int match_address(char *addr, char *tok)
{
char *p;
struct addrinfo hints, *resa, *rest;
@@ -106,16 +70,24 @@ static int match_address(const char *addr, const 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 (tok[strspn(tok, ".0123456789")] && strchr(tok, ':') == NULL) {
/* Fail quietly if tok is a hostname (not an address) */
if (strspn(tok, ".0123456789") != len
#ifdef INET6
&& strchr(tok, ':') == NULL
#endif
) {
if (p)
*p = '/';
return 0;
@@ -238,7 +210,7 @@ static int match_address(const char *addr, const char *tok)
return ret;
}
static int access_match(const char *list, const char *addr, const char **host_ptr)
static int access_match(char *list, char *addr, char *host)
{
char *tok;
char *list2 = strdup(list);
@@ -247,9 +219,11 @@ static int access_match(const char *list, const char *addr, const char **host_pt
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_ptr, addr, tok) || match_address(addr, tok)) {
if (match_hostname(host, tok) || match_address(addr, tok)) {
free(list2);
return 1;
}
@@ -259,21 +233,16 @@ static int access_match(const char *list, const char *addr, const char **host_pt
return 0;
}
int allow_access(const char *addr, const char **host_ptr, int i)
int allow_access(char *addr, char *host, char *allow_list, char *deny_list)
{
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_ptr))
if (access_match(allow_list, addr, host))
return 1;
/* For an allow-list w/o a deny-list, disallow non-matches. */
if (!deny_list)
@@ -282,7 +251,7 @@ int allow_access(const char *addr, const char **host_ptr, int i)
/* 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_ptr))
if (deny_list && access_match(deny_list, addr, host))
return 0;
/* Allow all other access. */

10
acls.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2006-2013 Wayne Davison
* Copyright (C) 2006-2009 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
@@ -495,15 +495,9 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl,
}
racl->user_obj = IVAL(buf, 0);
if (racl->user_obj == NO_ENTRY)
racl->user_obj = (mode >> 6) & 7;
racl->group_obj = IVAL(buf, 4);
if (racl->group_obj == NO_ENTRY)
racl->group_obj = (mode >> 3) & 7;
racl->mask_obj = IVAL(buf, 8);
racl->other_obj = IVAL(buf, 12);
if (racl->other_obj == NO_ENTRY)
racl->other_obj = mode & 7;
if (cnt) {
char *bp = buf + 4*4;
@@ -1143,7 +1137,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 (DEBUG_GTE(ACL, 1))
if (verbose > 2)
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-2013 Wayne Davison
* Copyright (C) 2002-2009 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,9 +19,7 @@
*/
#include "rsync.h"
#include "itypes.h"
extern int read_only;
extern char *password_file;
/***************************************************************************
@@ -78,6 +76,129 @@ 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, ok = 1;
const char *envpw = getenv("RSYNC_PASSWORD");
if (!filename)
return NULL;
if ((fd = open(filename,O_RDONLY)) < 0) {
rsyserr(FWARNING, errno, "could not open password file \"%s\"",
filename);
if (envpw)
rprintf(FINFO, "falling back to RSYNC_PASSWORD environment variable.\n");
return NULL;
}
if (do_stat(filename, &st) == -1) {
rsyserr(FWARNING, errno, "stat(%s)", filename);
ok = 0;
} else if ((st.st_mode & 06) != 0) {
rprintf(FWARNING, "password file must not be other-accessible\n");
ok = 0;
} else if (MY_UID() == 0 && st.st_uid != 0) {
rprintf(FWARNING, "password file must be owned by root when running as root\n");
ok = 0;
}
if (!ok) {
close(fd);
rprintf(FWARNING, "continuing without password file\n");
if (envpw)
rprintf(FINFO, "falling back to RSYNC_PASSWORD environment variable.\n");
return NULL;
}
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);
}
return NULL;
}
/* 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)
@@ -93,125 +214,6 @@ 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.
*
@@ -224,12 +226,9 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
char *users = lp_auth_users(module);
char challenge[MAX_DIGEST_LEN*2];
char line[BIGPATHBUFLEN];
char **auth_uid_groups = NULL;
int auth_uid_groups_cnt = -1;
const char *err = NULL;
int group_match = -1;
char secret[512];
char pass2[MAX_DIGEST_LEN*2];
char *tok, *pass;
char opt_ch = '\0';
/* if no auth list then allow anyone in! */
if (!users || !*users)
@@ -239,7 +238,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, 0)
if (!read_line_old(f_in, line, sizeof line)
|| (pass = strchr(line, ' ')) == NULL) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"invalid challenge response\n",
@@ -252,91 +251,36 @@ 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")) {
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
}
if (wildmatch(tok, line))
break;
}
free(users);
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);
if (!tok) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"unauthorized user\n",
lp_name(module), host, addr);
return NULL;
}
if (opt_ch == 'r')
read_only = 1;
else if (opt_ch == 'w')
read_only = 0;
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;
}
return strdup(line);
}

493
backup.c
View File

@@ -2,7 +2,7 @@
* Backup handling code.
*
* Copyright (C) 1999 Andrew Tridgell
* Copyright (C) 2003-2013 Wayne Davison
* Copyright (C) 2003-2009 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,218 +34,210 @@ extern char backup_dir_buf[MAXPATHLEN];
extern char *backup_suffix;
extern char *backup_dir;
/* 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. */
/* make a complete pathname for backup file */
char *get_backup_name(const char *fname)
{
if (backup_dir) {
/* copy fname into backup_dir_buf while validating the dirs. */
if (copy_valid_path(fname))
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)
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;
}
/* 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)
/* simple backup creates a backup with a suffix in the same directory */
static int make_simple_backup(const char *fname)
{
#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;
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;
}
/* We prefer to rename a regular file rather than copy it. */
if (!S_ISREG(stp->st_mode) || errno == EEXIST || errno == EISDIR)
return 0;
/* 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;
}
#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... */
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;
}
if (DEBUG_GTE(BACKUP, 1))
rprintf(FINFO, "make_backup: RENAME %s successful.\n", from);
return 1;
}
return 0;
}
/* 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)
/* 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)
{
stat_x sx;
struct file_struct *file;
int save_preserve_xattrs;
char *buf = get_backup_name(fname);
int ret = 0;
char *buf;
int save_preserve_xattrs = preserve_xattrs;
int kept = 0;
int ret_code;
if (!buf)
return 0;
init_stat_x(&sx);
/* Return success if no file to keep. */
/* return 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
/* 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)))
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;
}
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(fname, &sx);
@@ -264,34 +256,87 @@ int make_backup(const char *fname, BOOL prefer_rename)
/* 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))) {
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;
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;
}
#ifdef SUPPORT_LINKS
if (!ret && preserve_links && S_ISLNK(file->mode)) {
if (!kept && preserve_links && S_ISLNK(file->mode)) {
const char *sl = F_SYMLINK(file);
if (safe_symlinks && unsafe_symlink(sl, fname)) {
if (INFO_GTE(SYMSAFE, 1)) {
if (verbose) {
rprintf(FINFO, "not backing up unsafe symlink \"%s\" -> \"%s\"\n",
fname, sl);
}
ret = 2;
kept = 1;
} else {
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;
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;
}
}
#endif
if (!ret && !S_ISREG(file->mode)) {
rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname);
if (!kept && !S_ISREG(file->mode)) {
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
fname);
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
@@ -299,33 +344,23 @@ int make_backup(const char *fname, BOOL prefer_rename)
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
return 2;
return 1;
}
/* Copy to backup tree if a file. */
if (!ret) {
if (copy_file(fname, buf, -1, file->mode) < 0) {
/* move to keep tree if a file */
if (!kept) {
if (robust_move(fname, buf) != 0) {
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
full_fname(fname), buf);
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
#endif
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
return 0;
} 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... */
}
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();
@@ -334,8 +369,18 @@ int make_backup(const char *fname, BOOL prefer_rename)
uncache_tmp_xattrs();
#endif
success:
if (INFO_GTE(BACKUP, 1))
rprintf(FINFO, "backed up %s to %s\n", fname, buf);
return ret;
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);
}

16
batch.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1999 Weiss
* Copyright (C) 2004 Chris Shoemaker
* Copyright (C) 2004-2013 Wayne Davison
* Copyright (C) 2004-2009 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.h>
#include "zlib/zlib.h"
#include <time.h>
extern int eol_nulls;
@@ -43,7 +43,7 @@ extern char *batch_name;
extern char *iconv_opt;
#endif
extern filter_rule_list filter_list;
extern struct filter_list_struct filter_list;
int batch_stream_flags;
@@ -135,7 +135,7 @@ void check_batch_flags(void)
set ? "Please" : "Do not");
exit_cleanup(RERR_SYNTAX);
}
if (INFO_GTE(MISC, 1)) {
if (verbose) {
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)
{
filter_rule *ent;
struct filter_struct *ent;
write_sbuf(fd, " <<'#E#'\n");
for (ent = filter_list.head; ent; ent = ent->next) {
unsigned int plen;
char *p = get_rule_prefix(ent, "- ", 0, &plen);
char *p = get_rule_prefix(ent->match_flags, "- ", 0, &plen);
write_buf(fd, p, plen);
write_sbuf(fd, ent->pattern);
if (ent->rflags & FILTRULE_DIRECTORY)
if (ent->match_flags & MATCHFLG_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_IXUSR);
S_IRUSR | S_IWUSR | S_IEXEC);
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-2013 Wayne Davison
* Copyright (C) 2007-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

View File

@@ -1,7 +1,7 @@
/*
* Allow an arbitrary sequence of case labels.
*
* Copyright (C) 2006-2013 Wayne Davison
* Copyright (C) 2006-2010 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-2013 Wayne Davison
* Copyright (C) 2004-2009 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-2013 Wayne Davison
* Copyright (C) 2005-2009 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,6 @@
*/
#include "rsync.h"
#include "itypes.h"
extern mode_t orig_umask;
@@ -36,12 +35,10 @@ 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
@@ -90,10 +87,6 @@ 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;
@@ -106,8 +99,7 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
where = what = op = topoct = topbits = flags = 0;
}
switch (state) {
case STATE_1ST_HALF:
if (state != STATE_2ND_HALF) {
switch (*modestr) {
case 'D':
if (flags & FLAG_FILES_ONLY)
@@ -146,17 +138,10 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
state = STATE_2ND_HALF;
break;
default:
if (isDigit(modestr) && *modestr < '8' && !where) {
op = CHMOD_SET;
state = STATE_OCTAL_NUM;
where = 1;
what = *modestr - '0';
} else
state = STATE_ERROR;
state = STATE_ERROR;
break;
}
break;
case STATE_2ND_HALF:
} else {
switch (*modestr) {
case 'r':
what |= 4;
@@ -183,15 +168,6 @@ 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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,14 +28,9 @@ 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
@@ -87,7 +82,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 = -1, cleanup_fd_w = -1;
static int cleanup_fd_r, cleanup_fd_w;
static pid_t cleanup_pid = 0;
pid_t cleanup_child_pid = -1;
@@ -102,15 +97,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 first_code = 0;
static int unmodified_code = 0;
SIGACTION(SIGUSR1, SIG_IGN);
SIGACTION(SIGUSR2, SIG_IGN);
if (!exit_code) { /* Preserve first error exit info when recursing. */
exit_code = code;
exit_file = file;
exit_line = line < 0 ? -line : line;
if (exit_code) { /* Preserve first exit info when recursing. */
code = exit_code;
file = exit_file;
line = exit_line;
}
/* If this is the exit at the end of the run, the server side
@@ -124,14 +119,11 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
#include "case_N.h" /* case 0: */
switch_step++;
first_code = code;
exit_code = unmodified_code = code;
exit_file = file;
exit_line = line;
if (output_needs_newline) {
fputc('\n', stdout);
output_needs_newline = 0;
}
if (DEBUG_GTE(EXIT, 2)) {
if (verbose > 3) {
rprintf(FINFO,
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
who_am_i(), code, file, line);
@@ -146,8 +138,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 > exit_code)
exit_code = status;
if (status > code)
code = exit_code = status;
}
}
@@ -155,43 +147,25 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
#include "case_N.h"
switch_step++;
if (cleanup_got_literal && (cleanup_fname || cleanup_fd_w != -1)) {
if (cleanup_got_literal && cleanup_fname && cleanup_new_fname
&& keep_partial && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
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 (flush_ok_after_signal) {
flush_ok_after_signal = False;
if (code == RERR_SIGNAL)
io_flush(FULL_FLUSH);
}
if (!exit_code && !code)
if (!code || am_server || am_receiver)
io_flush(FULL_FLUSH);
/* FALLTHROUGH */
@@ -200,7 +174,7 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
if (cleanup_fname)
do_unlink(cleanup_fname);
if (exit_code)
if (code)
kill_all(SIGUSR1);
if (cleanup_pid && cleanup_pid == getpid()) {
char *pidf = lp_pid_file();
@@ -208,55 +182,34 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
unlink(lp_pid_file());
}
if (exit_code == 0) {
if (code)
exit_code = code;
if (code == 0) {
if (io_error & IOERR_DEL_LIMIT)
exit_code = RERR_DEL_LIMIT;
code = exit_code = RERR_DEL_LIMIT;
if (io_error & IOERR_VANISHED)
exit_code = RERR_VANISHED;
code = exit_code = RERR_VANISHED;
if (io_error & IOERR_GENERAL || got_xfer_error)
exit_code = RERR_PARTIAL;
code = exit_code = RERR_PARTIAL;
}
/* 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);
if (code || am_daemon || (logfile_name && (am_server || !verbose)))
log_exit(code, file, line);
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
if (DEBUG_GTE(EXIT, 1)) {
if (verbose > 2) {
rprintf(FINFO,
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): "
"about to call exit(%d)\n",
who_am_i(), first_code, exit_file, exit_line, exit_code);
who_am_i(), unmodified_code, file, line, code);
}
/* FALLTHROUGH */
#include "case_N.h"
switch_step++;
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)
if (am_server && code)
msleep(100);
close_all();
@@ -265,13 +218,12 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
break;
}
exit(exit_code);
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-2013 Wayne Davison
* Copyright (C) 2002-2009 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,6 +41,7 @@ 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;
@@ -48,14 +49,11 @@ 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 ((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);
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);
/* 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-2013 Wayne Davison
* Copyright (C) 2002-2009 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,10 @@
*/
#include "rsync.h"
#include "itypes.h"
#include "ifuncs.h"
extern int quiet;
extern int verbose;
extern int dry_run;
extern int output_motd;
extern int list_only;
@@ -36,7 +37,6 @@ 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 filter_rule_list daemon_filter_list;
extern struct filter_list_struct 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,12 +81,6 @@ 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().
@@ -164,7 +158,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, 0)) {
if (!read_line_old(f_in, buf, bufsiz)) {
if (am_client)
rprintf(FERROR, "rsync: did not see server greeting\n");
return -1;
@@ -276,7 +270,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
sargs[sargc] = NULL;
if (DEBUG_GTE(CMD, 1))
if (verbose > 1)
print_child_argv("sending daemon args:", sargs);
io_printf(f_out, "%.*s\n", modlen, modname);
@@ -286,7 +280,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, 0)) {
if (!read_line_old(f_in, line, sizeof line)) {
rprintf(FERROR, "rsync: didn't get server startup line\n");
return -1;
}
@@ -340,7 +334,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(f_in);
io_start_multiplex_in();
}
free(modname);
@@ -348,83 +342,61 @@ 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 write_fd, int read_fd, char *request,
static char *finish_pre_exec(pid_t pid, int fd, char *request,
char **early_argv, char **argv)
{
char buf[BIGPATHBUFLEN], *bp;
int j = 0, status = -1, msglen = sizeof buf - 1;
int j = 0, status = -1;
if (!request)
request = "(NONE)";
write_buf(write_fd, request, strlen(request)+1);
write_buf(fd, request, strlen(request)+1);
if (early_argv) {
for ( ; *early_argv; early_argv++)
write_buf(write_fd, *early_argv, strlen(*early_argv)+1);
write_buf(fd, *early_argv, strlen(*early_argv)+1);
j = 1; /* Skip arg0 name in argv. */
}
for ( ; argv[j]; j++)
write_buf(write_fd, argv[j], strlen(argv[j])+1);
write_byte(write_fd, 0);
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';
}
for ( ; argv[j]; j++) {
write_buf(fd, argv[j], strlen(argv[j])+1);
if (argv[j][0] == '.' && argv[j][1] == '\0')
break;
}
*bp = '\0';
write_byte(fd, 0);
close(read_fd);
close(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%s\n%s",
if (asprintf(&e, "pre-xfer exec returned failure (%d)%s%s\n",
status, status < 0 ? ": " : "",
status < 0 ? strerror(errno) : "",
*buf ? ":" : "", buf) < 0)
return "out_of_memory in finish_pre_exec\n";
status < 0 ? strerror(errno) : "") < 0)
out_of_memory("finish_pre_exec");
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)
{
@@ -436,91 +408,20 @@ static int path_failure(int f_out, const char *dir, BOOL was_chdir)
return -1;
}
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)
static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
{
int argc;
char **argv, **orig_argv, **orig_early_argv, *module_chdir;
char line[BIGPATHBUFLEN];
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
struct passwd *pw = NULL;
#endif
uid_t uid;
int set_uid;
uid_t uid = (uid_t)-2; /* canonically "nobody" */
gid_t gid = (gid_t)-2;
char *p, *err_msg = NULL;
char *name = lp_name(i);
int use_chroot = lp_use_chroot(i);
int ret, pre_exec_arg_fd = -1, pre_exec_error_fd = -1;
int save_munge_symlinks;
int ret, pre_exec_fd = -1;
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)
@@ -528,14 +429,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
iconv_opt = NULL;
#endif
/* 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)) {
if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
rprintf(FLOG, "rsync denied on module %s from %s (%s)\n",
name, host, addr);
if (!lp_list(i))
@@ -567,17 +461,18 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
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'))
@@ -585,53 +480,37 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
if (logfile_format_has_i || log_format_has(logfile_format, 'o'))
logfile_format_has_o_or_i = 1;
uid = MY_UID();
am_root = (uid == 0);
am_root = (MY_UID() == 0);
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");
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);
return -1;
}
#endif
if (add_a_group(f_out, p) < 0)
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);
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);
@@ -661,7 +540,6 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
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;
@@ -670,32 +548,45 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
set_filter_dir(module_dir, module_dirlen);
p = lp_filter(i);
parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
parse_rule(&daemon_filter_list, p, MATCHFLG_WORD_SPLIT,
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3);
p = lp_include_from(i);
parse_filter_file(&daemon_filter_list, p, rule_template(FILTRULE_INCLUDE),
parse_filter_file(&daemon_filter_list, p, MATCHFLG_INCLUDE,
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
p = lp_include(i);
parse_filter_str(&daemon_filter_list, p,
rule_template(FILTRULE_INCLUDE | FILTRULE_WORD_SPLIT),
parse_rule(&daemon_filter_list, p,
MATCHFLG_INCLUDE | MATCHFLG_WORD_SPLIT,
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES);
p = lp_exclude_from(i);
parse_filter_file(&daemon_filter_list, p, rule_template(0),
parse_filter_file(&daemon_filter_list, p, 0,
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
p = lp_exclude(i);
parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
parse_rule(&daemon_filter_list, p, MATCHFLG_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. */
@@ -707,18 +598,18 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
return -1;
}
if (pid) {
close(f_in);
if (f_out != f_in)
close(f_out);
set_env_num("RSYNC_PID", (long)pid);
if (asprintf(&p, "RSYNC_PID=%ld", (long)pid) > 0)
putenv(p);
if (wait_process(pid, &status, 0) < 0)
status = -1;
set_env_num("RSYNC_RAW_STATUS", status);
if (asprintf(&p, "RSYNC_RAW_STATUS=%d", status) > 0)
putenv(p);
if (WIFEXITED(status))
status = WEXITSTATUS(status);
else
status = -1;
set_env_num("RSYNC_EXIT_STATUS", status);
if (asprintf(&p, "RSYNC_EXIT_STATUS=%d", status) > 0)
putenv(p);
if (system(lp_postxfer_exec(i)) < 0)
status = -1;
_exit(status);
@@ -728,9 +619,10 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
* 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 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) {
int fds[2];
if (asprintf(&p, "RSYNC_PID=%ld", (long)getpid()) > 0)
putenv(p);
if (pipe(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;
@@ -738,43 +630,37 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
if (pre_exec_pid == 0) {
char buf[BIGPATHBUFLEN];
int j, len;
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);
close(fds[1]);
set_blocking(fds[0]);
len = read_arg_from_pipe(fds[0], buf, BIGPATHBUFLEN);
if (len <= 0)
_exit(1);
set_env_str("RSYNC_REQUEST", buf);
if (asprintf(&p, "RSYNC_REQUEST=%s", buf) > 0)
putenv(p);
for (j = 0; ; j++) {
len = read_arg_from_pipe(pre_exec_arg_fd, buf,
len = read_arg_from_pipe(fds[0], 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(pre_exec_arg_fd);
close(fds[0]);
close(STDIN_FILENO);
dup2(pre_exec_error_fd, STDOUT_FILENO);
close(pre_exec_error_fd);
close(STDOUT_FILENO);
status = system(lp_prexfer_exec(i));
if (!WIFEXITED(status))
_exit(1);
_exit(WEXITSTATUS(status));
}
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);
close(fds[0]);
set_blocking(fds[1]);
pre_exec_fd = fds[1];
}
umask(0);
}
#endif
@@ -808,47 +694,46 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
munge_symlinks = !use_chroot || module_dirlen;
if (munge_symlinks) {
STRUCT_STAT st;
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);
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);
io_printf(f_out, "@ERROR: daemon security issue -- contact admin\n", name);
exit_cleanup(RERR_UNSUPPORTED);
}
}
if (gid_count) {
if (setgid(gid_list[0])) {
rsyserr(FLOG, errno, "setgid %ld failed", (long)gid_list[0]);
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);
io_printf(f_out, "@ERROR: setgid failed\n");
return -1;
}
#ifdef HAVE_SETGROUPS
/* Set the group(s) we want to be active. */
if (setgroups(gid_count, gid_list)) {
/* Get rid of any supplementary groups this process
* might have inheristed. */
if (setgroups(1, &gid)) {
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 %ld failed", (long)uid);
rsyserr(FLOG, errno, "setuid %d failed", (int)uid);
io_printf(f_out, "@ERROR: setuid failed\n");
return -1;
}
@@ -871,9 +756,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
read_args(f_in, name, line, sizeof line, rl_nulls, &argv, &argc, &request);
orig_argv = argv;
save_munge_symlinks = munge_symlinks;
reset_output_levels(); /* future verbosity is controlled by client options */
verbose = 0; /* future verbosity is controlled by client options */
ret = parse_arguments(&argc, (const char ***) &argv);
if (protect_args && ret) {
orig_early_argv = orig_argv;
@@ -884,11 +767,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
} 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_arg_fd, pre_exec_error_fd,
request, orig_early_argv, orig_argv);
err_msg = finish_pre_exec(pre_exec_pid, pre_exec_fd, request,
orig_early_argv, orig_argv);
}
if (orig_early_argv)
@@ -926,12 +807,13 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
#ifndef DEBUG
/* don't allow the logs to be flooded too fast */
limit_output_verbosity(lp_max_verbosity(i));
if (verbose > lp_max_verbosity(i))
verbose = lp_max_verbosity(i);
#endif
if (protocol_version < 23
&& (protocol_version == 22 || am_sender))
io_start_multiplex_out(f_out);
io_start_multiplex_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
@@ -955,19 +837,13 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
if (files_from)
write_byte(f_out, 0);
}
io_start_multiplex_out(f_out);
io_start_multiplex_out();
}
if (!ret || err_msg) {
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
if (err_msg)
rwrite(FERROR, err_msg, strlen(err_msg), 0);
else
option_error();
msleep(400);
exit_cleanup(RERR_UNSUPPORTED);
@@ -1015,7 +891,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
with "list = False". */
static void send_listing(int fd)
{
int n = lp_num_modules();
int n = lp_numservices();
int i;
for (i = 0; i < n; i++) {
@@ -1044,7 +920,7 @@ static int load_config(int globals_only)
int start_daemon(int f_in, int f_out)
{
char line[1024];
const char *addr, *host;
char *addr, *host;
int i;
io_set_sock_fds(f_in, f_out);
@@ -1057,7 +933,7 @@ int start_daemon(int f_in, int f_out)
exit_cleanup(RERR_SYNTAX);
addr = client_addr(f_in);
host = lp_reverse_lookup(-1) ? client_name(f_in) : undetermined_hostname;
host = client_name(f_in);
rprintf(FLOG, "connect from %s (%s)\n", host, addr);
if (!am_server) {
@@ -1069,7 +945,7 @@ int start_daemon(int f_in, int f_out)
return -1;
line[0] = 0;
if (!read_line_old(f_in, line, sizeof line, 0))
if (!read_line_old(f_in, line, sizeof line))
return -1;
if (!*line || strcmp(line, "#list") == 0) {
@@ -1111,14 +987,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)) == -1) {
if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666 & ~orig_umask)) == -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, "%d\n", (int)pid);
snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
len = strlen(pidbuf);
if (write(fd, pidbuf, len) != len)
goto failure;
@@ -1179,7 +1055,6 @@ 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();
@@ -1196,7 +1071,7 @@ int daemon_main(void)
rprintf(FLOG, "rsyncd version %s starting, listening on port %d\n",
RSYNC_VERSION, rsync_port);
/* TODO: If listening on a particular address, then show that
* address too. In fact, why not just do getnameinfo on the
* address too. In fact, why not just do inet_ntop on the
* local address??? */
start_accept_loop(rsync_port, start_daemon);

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) Andrew Tridgell 1996
* Copyright (C) Paul Mackerras 1996
* Copyright (C) 2004-2013 Wayne Davison
* Copyright (C) 2004-2009 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,6 +27,7 @@ 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;
@@ -34,7 +35,6 @@ 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 filter_rule_list filter_list;
extern struct filter_list_struct 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 (DEBUG_GTE(PROTO, 1)) {
if (verbose > 3) {
rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
am_server? "Server" : "Client", remote_protocol, protocol_version);
}
@@ -190,14 +190,6 @@ 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;
@@ -293,7 +285,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) || protocol_version >= 31;
use_safe_inc_flist = !!(compat_flags & CF_SAFE_FLIST);
need_messages_from_generator = 1;
#ifdef CAN_SET_SYMLINK_TIMES
} else if (!am_sender) {
@@ -305,10 +297,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 rflags = FILTRULE_NO_PREFIXES | FILTRULE_DIRECTORY;
int flags = MATCHFLG_NO_PREFIXES | MATCHFLG_DIRECTORY;
if (!am_sender || protocol_version >= 30)
rflags |= FILTRULE_PERISHABLE;
parse_filter_str(&filter_list, partial_dir, rule_template(rflags), 0);
flags |= MATCHFLG_PERISHABLE;
parse_rule(&filter_list, partial_dir, flags, 0);
}

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

@@ -1,12 +1,14 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2013 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Inc.
timestamp='2013-05-16'
timestamp='2006-07-02'
# 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
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -15,23 +17,27 @@ timestamp='2013-05-16'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# 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. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# Originally written by Per Bothner.
#
# 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.
# 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.
#
# 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.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit build system type.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
@@ -50,7 +56,8 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright 1992-2013 Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
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."
@@ -132,33 +139,12 @@ 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 tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@@ -175,7 +161,6 @@ 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
@@ -184,7 +169,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 -q __ELF__
| grep __ELF__ >/dev/null
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
@@ -194,7 +179,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
os=netbsd
os=netbsd
;;
esac
# The OS release
@@ -215,10 +200,6 @@ 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}
@@ -241,7 +222,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
@@ -287,10 +268,7 @@ 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'`
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
exit ;;
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
@@ -316,12 +294,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:*:*)
@@ -345,33 +323,14 @@ 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: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/[^.]*//'`
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -415,23 +374,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 ;;
@@ -501,8 +460,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 ] || \
@@ -515,7 +474,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit ;;
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@@ -572,7 +531,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[4567])
*:AIX:*:[45])
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
@@ -615,52 +574,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
@@ -680,7 +639,7 @@ EOF
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
grep __LP64__ >/dev/null
then
HP_ARCH="hppa2.0w"
else
@@ -751,22 +710,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 ;;
@@ -790,14 +749,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}
@@ -809,51 +768,37 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
case ${UNAME_MACHINE} in
pc98)
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
*:MINGW64*:*)
echo ${UNAME_MACHINE}-pc-mingw64
exit ;;
*:MINGW*:*)
i*: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 ;;
*: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 ;;
x86:Interix*:[3456]*)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T:Interix*:[3456]*)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
[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
@@ -874,21 +819,93 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`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/[-(].*//'`-${LIBC}
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
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
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -899,126 +916,103 @@ EOF
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
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}
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}
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-${LIBC} ;;
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
*) echo hppa-unknown-linux-${LIBC} ;;
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
esac
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-${LIBC}
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
echo ${UNAME_MACHINE}-ibm-linux
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
x86_64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
echo x86_64-unknown-linux-gnu
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
@@ -1026,11 +1020,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:*:*)
@@ -1047,7 +1041,7 @@ EOF
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
@@ -1062,7 +1056,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 ;;
@@ -1090,13 +1084,10 @@ 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 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 ;;
# 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 ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@@ -1131,18 +1122,8 @@ 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; } ;;
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; } ;;
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1155,7 +1136,7 @@ EOF
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
@@ -1175,10 +1156,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
@@ -1204,11 +1185,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 ;;
@@ -1218,12 +1199,6 @@ 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 ;;
@@ -1233,15 +1208,6 @@ 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 ;;
@@ -1250,21 +1216,9 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
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
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1278,10 +1232,7 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
NSE-?:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@@ -1326,13 +1277,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 ;;
@@ -1347,14 +1298,11 @@ 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_
@@ -1372,11 +1320,11 @@ main ()
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
"4"
#else
""
""
#endif
); exit (0);
); exit (0);
#endif
#endif
@@ -1510,9 +1458,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://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
and
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
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 Normal file → Executable file
View File

@@ -1,40 +1,44 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2013 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Inc.
timestamp='2013-04-24'
timestamp='2006-07-02'
# 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
# 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
# (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, see <http://www.gnu.org/licenses/>.
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# 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. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# the same distribution terms that you use for the rest of that program.
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# 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.
@@ -68,7 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2013 Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
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."
@@ -115,18 +120,12 @@ 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-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-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 ]
@@ -149,13 +148,10 @@ 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 | -microblaze*)
-apple | -axis | -knuth | -cray)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@@ -170,10 +166,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
;;
-hiux*)
os=-hiuxwe2
;;
@@ -218,12 +214,6 @@ 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
;;
@@ -248,34 +238,24 @@ 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 | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| 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 | microblazeel | mcore | mep | metag \
| maxq | mb | microblaze | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
@@ -286,45 +266,30 @@ case $basic_machine in
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| nios | nios2 \
| ns16k | ns32k \
| open8 \
| or1k | or32 \
| or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| 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 \
| sh | sh[1234] | sh[24]a | 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 \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -334,21 +299,6 @@ 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.
@@ -363,37 +313,29 @@ 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-* | arceb-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| f30[01]-* | f700-* | 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-* | metag-* \
| microblaze-* | microblazeel-* \
| m88110-* | m88k-* | maxq-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
@@ -404,41 +346,31 @@ case $basic_machine in
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[24]a-* | 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-* | sv1-* | sx?-* \
| tahoe-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa-* \
| ymp-* \
| z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -456,7 +388,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@@ -502,10 +434,6 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -514,35 +442,10 @@ 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
@@ -571,8 +474,8 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
cr16 | cr16-*)
basic_machine=cr16-unknown
cr16c)
basic_machine=cr16c-unknown
os=-elf
;;
crds | unos)
@@ -610,10 +513,6 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
@@ -729,6 +628,7 @@ 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
@@ -767,14 +667,6 @@ 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
;;
@@ -786,21 +678,10 @@ 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
;;
@@ -829,18 +710,10 @@ 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
@@ -905,12 +778,6 @@ 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
;;
@@ -941,14 +808,6 @@ 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
;;
@@ -993,10 +852,9 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
ppc | ppcbe) basic_machine=powerpc-unknown
ppc) basic_machine=powerpc-unknown
;;
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -1021,11 +879,7 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
rdos)
basic_machine=i386-pc
os=-rdos
;;
@@ -1055,10 +909,6 @@ case $basic_machine in
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
@@ -1070,9 +920,6 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
@@ -1094,9 +941,6 @@ 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
;;
@@ -1153,9 +997,17 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
tile*)
basic_machine=$basic_machine-unknown
os=-linux-gnu
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
@@ -1224,9 +1076,6 @@ 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
@@ -1235,10 +1084,6 @@ 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
@@ -1277,7 +1122,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
@@ -1324,12 +1169,9 @@ 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|'`
;;
@@ -1350,23 +1192,21 @@ 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* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -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* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1374,7 +1214,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* | -drops* | -es*)
| -skyos* | -haiku* | -rdos* | -toppers*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1413,7 +1253,7 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
-os400*)
os=-os400
;;
-wince*)
@@ -1462,7 +1302,7 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
-tpf*)
os=-tpf
;;
-triton*)
@@ -1498,14 +1338,12 @@ case $os in
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
;;
-none)
;;
*)
@@ -1528,10 +1366,7 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
os=-elf
;;
spu-*)
spu-*)
os=-elf
;;
*-acorn)
@@ -1543,20 +1378,8 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1576,22 +1399,19 @@ 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
;;
@@ -1610,7 +1430,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
*-knuth)
*-knuth)
os=-mmixware
;;
*-wec)
@@ -1715,7 +1535,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
-cnk*|-aix*)
-aix*)
vendor=ibm
;;
-beos*)

2
configure vendored
View File

@@ -8,8 +8,6 @@ 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.1.0
RSYNC_VERSION=3.0.8
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -39,7 +39,6 @@ AC_PROG_CC
AC_PROG_CPP
AC_PROG_EGREP
AC_PROG_INSTALL
AC_PROG_MKDIR_P
AC_PROG_CC_STDC
AC_SUBST(SHELL)
@@ -79,15 +78,6 @@ 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" ],
@@ -134,14 +124,8 @@ 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)]),
@@ -347,8 +331,7 @@ 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 linux/falloc.h netinet/in_systm.h netinet/ip.h \
zlib.h)
popt.h popt/popt.h)
AC_HEADER_MAJOR
AC_CACHE_CHECK([if makedev takes 3 args],rsync_cv_MAKEDEV_TAKES_3_ARGS,[
@@ -396,18 +379,7 @@ 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,
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])
AC_CHECK_MEMBERS([struct stat.st_rdev])
TYPE_SOCKLEN_T
@@ -601,50 +573,14 @@ 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 getgrouplist \
initgroups utimensat posix_fallocate attropen setvbuf)
extattr_get_link sigaction sigprocmask setattrlist \
utimensat)
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
@@ -739,19 +675,13 @@ AC_TRY_RUN([
main() {
int fd[2];
#ifdef __CYGWIN__
exit(1);
#else
exit((socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1);
#endif
}],
rsync_cv_HAVE_SOCKETPAIR=yes,rsync_cv_HAVE_SOCKETPAIR=no,rsync_cv_HAVE_SOCKETPAIR=cross)])
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
@@ -780,25 +710,6 @@ 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)])
@@ -952,12 +863,8 @@ 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
@@ -976,7 +883,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)
@@ -1045,7 +952,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$ac_cv_func_attropen" in
[], [case "$ac_cv_func_getxattr$ac_cv_func_extattr_get_link" in
*yes*) enable_xattr_support=maybe ;;
*) enable_xattr_support=no ;;
esac])
@@ -1059,7 +966,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])
AC_DEFINE(NO_SYMLINK_XATTRS, 1, [True if symlinks do not support xattrs])
;;
darwin*)
AC_MSG_RESULT(Using OS X xattrs)
@@ -1073,12 +980,6 @@ else
AC_DEFINE(HAVE_FREEBSD_XATTRS, 1, [True if you have FreeBSD xattrs])
AC_DEFINE(SUPPORT_XATTRS, 1)
;;
solaris*)
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])
;;
*)
if test x"$enable_xattr_support" = x"yes"; then
AC_MSG_ERROR(Failed to find extended attribute support)

240
delete.c
View File

@@ -1,240 +0,0 @@
/*
* 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-2013 Wayne Davison
* Copyright (C) 2003-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

737
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-2013 Wayne Davison
* Copyright (C) 2004-2009 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,19 +20,11 @@
*/
#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;
@@ -84,14 +76,11 @@ 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))) {
sparse_seek = 0;
if (ret != (int)(len - (l1+l2)))
return l1+ret;
}
return len;
}
@@ -169,7 +158,8 @@ 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;
@@ -181,7 +171,7 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
map->fd = fd;
map->file_size = len;
map->def_window_size = ALIGNED_LENGTH(read_size);
map->def_window_size = read_size;
return map;
}
@@ -190,8 +180,9 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_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, align_fudge;
int32 window_size, read_size, read_offset;
if (len == 0)
return NULL;
@@ -206,13 +197,12 @@ 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 */
align_fudge = (int32)ALIGNED_OVERSHOOT(offset);
window_start = offset - align_fudge;
window_start = offset;
window_size = map->def_window_size;
if (window_start + window_size > map->file_size)
window_size = (int32)(map->file_size - window_start);
if (window_size < len + align_fudge)
window_size = ALIGNED_LENGTH(len + align_fudge);
if (len > window_size)
window_size = len;
/* make sure we have allocated enough memory for the window */
if (window_size > map->p_size) {
@@ -222,9 +212,11 @@ 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;
@@ -244,8 +236,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 %s, not %s",
big_num(ret), big_num(read_start));
rsyserr(FERROR, errno, "lseek returned %.0f, not %.0f",
(double)ret, (double)read_start);
exit_cleanup(RERR_FILEIO);
}
map->p_fd_offset = read_start;
@@ -254,7 +246,7 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
map->p_len = window_size;
while (read_size > 0) {
int32 nread = read(map->fd, map->p + read_offset, read_size);
nread = read(map->fd, map->p + read_offset, read_size);
if (nread <= 0) {
if (!map->status)
map->status = nread ? errno : ENODATA;
@@ -268,7 +260,7 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
read_size -= nread;
}
return map->p + align_fudge;
return map->p;
}

375
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-2013 Wayne Davison
* Copyright (C) 2002-2009 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,15 +23,16 @@
#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;
@@ -51,7 +52,6 @@ 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,20 +66,17 @@ 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 filter_rule_list filter_list;
extern filter_rule_list daemon_filter_list;
extern struct filter_list_struct filter_list;
extern struct filter_list_struct daemon_filter_list;
#ifdef ICONV_OPTION
extern int filesfrom_convert;
@@ -96,13 +93,11 @@ 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.
@@ -127,13 +122,14 @@ 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 (DEBUG_GTE(FLIST, 4)) {
if (verbose > 4) {
rprintf(FINFO, "FILE_STRUCT_LEN=%d, EXTRA_LEN=%d\n",
(int)FILE_STRUCT_LEN, (int)EXTRA_LEN);
}
@@ -144,13 +140,14 @@ void init_flist(void)
static int show_filelist_p(void)
{
return INFO_GTE(FLIST, 1) && xfer_dirs && !am_server && !inc_recurse;
return verbose && xfer_dirs && !am_server && !inc_recurse;
}
static void start_filelist_progress(char *kind)
{
rprintf(FCLIENT, "%s ... ", kind);
output_needs_newline = 1;
if (verbose > 1 || do_progress)
rprintf(FCLIENT, "\n");
rflush(FINFO);
}
@@ -161,20 +158,18 @@ static void emit_filelist_progress(int count)
static void maybe_emit_filelist_progress(int count)
{
if (INFO_GTE(FLIST, 2) && show_filelist_p() && (count % 100) == 0)
if (do_progress && show_filelist_p() && (count % 100) == 0)
emit_filelist_progress(count);
}
static void finish_filelist_progress(const struct file_list *flist)
{
if (INFO_GTE(FLIST, 2)) {
if (do_progress) {
/* This overwrites the progress line */
rprintf(FINFO, "%d file%sto consider\n",
flist->used, flist->used == 1 ? " " : "s ");
} else {
output_needs_newline = 0;
} else
rprintf(FINFO, "done\n");
}
}
void show_flist_stats(void)
@@ -196,12 +191,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 = do_readlink(path, linkbuf, MAXPATHLEN - 1);
int llen = readlink(path, linkbuf, MAXPATHLEN - 1);
if (llen < 0)
return -1;
linkbuf[llen] = '\0';
if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) {
if (INFO_GTE(SYMSAFE, 1)) {
if (verbose > 1) {
rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
path, linkbuf);
}
@@ -321,10 +316,10 @@ static void flist_expand(struct file_list *flist, int extra)
new_ptr = realloc_array(flist->files, struct file_struct *,
flist->malloced);
if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
if (verbose >= 2 && flist->malloced != FLIST_START) {
rprintf(FCLIENT, "[%s] expand file_list pointer array to %.0f bytes, did%s move\n",
who_am_i(),
big_num(sizeof flist->files[0] * flist->malloced),
(double)sizeof flist->files[0] * flist->malloced,
(new_ptr == flist->files) ? " not" : "");
}
@@ -408,35 +403,21 @@ 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 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;
}
/* 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 */
if (file->mode == mode)
xflags |= XMIT_SAME_MODE;
@@ -458,7 +439,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) && protocol_version < 31) {
} else if (preserve_specials && IS_SPECIAL(mode)) {
/* Special files don't need an rdev number, so just make
* the historical transmission of the value efficient. */
if (protocol_version < 28)
@@ -495,8 +476,6 @@ 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) {
@@ -507,17 +486,6 @@ 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)
@@ -564,13 +532,11 @@ 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)) {
@@ -579,8 +545,6 @@ 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)) {
@@ -608,7 +572,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) && protocol_version < 31)) {
|| (preserve_specials && IS_SPECIAL(mode))) {
if (protocol_version < 28) {
if (!(xflags & XMIT_SAME_RDEV_pre28))
write_int(f, (int)rdev);
@@ -659,9 +623,7 @@ 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))
@@ -690,7 +652,6 @@ 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;
@@ -723,9 +684,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, (size_t)-1);
INIT_XBUF(inbuf, lastname, basename_len, -1);
if (iconvbufs(ic_recv, &inbuf, &outbuf, ICB_INIT) < 0) {
if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {
io_error |= IOERR_GENERAL;
rprintf(FERROR_UTF8,
"[%s] cannot convert filename: %s (%s)\n",
@@ -765,16 +726,10 @@ 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);
@@ -808,14 +763,10 @@ 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) && mode)
if (chmod_modes && !S_ISLNK(mode))
mode = tweak_mode(mode, chmod_modes);
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
@@ -825,7 +776,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 || usermap))
else if (inc_recurse && am_root && !numeric_ids)
uid = match_uid(uid);
}
}
@@ -837,13 +788,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 || groupmap))
else if (inc_recurse && (!am_root || !numeric_ids))
gid = match_gid(gid, &gid_flags);
}
}
if ((preserve_devices && IS_DEVICE(mode))
|| (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31)) {
|| (preserve_specials && IS_SPECIAL(mode))) {
if (protocol_version < 28) {
if (!(xflags & XMIT_SAME_RDEV_pre28))
rdev = (dev_t)read_int(f);
@@ -909,10 +860,6 @@ 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");
@@ -949,12 +896,6 @@ 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)) {
@@ -963,7 +904,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, NSEC_BUMP(file))->unum = (uint32)(file_length >> 32);
OPT_EXTRA(file, 0)->unum = (uint32)(file_length >> 32);
#endif
}
#endif
@@ -1043,7 +984,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, ICB_INIT) < 0) {
if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {
io_error |= IOERR_GENERAL;
rprintf(FERROR_XFER,
"[%s] cannot convert symlink data for: %s (%s)\n",
@@ -1156,10 +1097,8 @@ 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) || 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;
if (stp && S_ISDIR(stp->st_mode)) {
st = *stp; /* Needed for "symlink/." with --relative. */
*linkname = '\0'; /* make IBM code checker happy */
} else if (readlink_stat(thisname, &st, linkname) != 0) {
int save_errno = errno;
@@ -1200,11 +1139,6 @@ 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)
@@ -1221,7 +1155,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 (INFO_GTE(MOUNT, 1)) {
if (verbose > 1) {
rprintf(FINFO,
"[%s] skipping mount-point dir %s\n",
who_am_i(), thisname);
@@ -1270,7 +1204,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
pool = NULL;
}
if (DEBUG_GTE(FLIST, 2)) {
if (verbose > 2) {
rprintf(FINFO, "[%s] make_file(%s,*,%d)\n",
who_am_i(), thisname, filter_level);
}
@@ -1293,21 +1227,11 @@ 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;
@@ -1351,17 +1275,11 @@ 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, NSEC_BUMP(file))->unum = (uint32)(st.st_size >> 32);
OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32);
}
#endif
file->mode = st.st_mode;
@@ -1380,6 +1298,9 @@ 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)
@@ -1391,11 +1312,8 @@ 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) = stats.num_dirs;
F_NDX(file) = dir_count;
return file;
}
@@ -1416,7 +1334,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) && file->mode)
if (chmod_modes && !S_ISLNK(file->mode))
file->mode = tweak_mode(file->mode, chmod_modes);
if (f >= 0) {
@@ -1430,7 +1348,6 @@ 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
@@ -1460,14 +1377,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, ICB_INIT) < 0)
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0)
goto convert_error;
outbuf.size += 2;
fbuf[outbuf.len++] = '/';
}
INIT_XBUF_STRLEN(inbuf, (char*)file->basename);
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) {
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {
convert_error:
io_error |= IOERR_GENERAL;
rprintf(FERROR_XFER,
@@ -1481,7 +1398,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, ICB_INIT) < 0) {
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {
io_error |= IOERR_GENERAL;
f_name(file, fbuf);
rprintf(FERROR_XFER,
@@ -1502,6 +1419,7 @@ 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;
@@ -1511,6 +1429,7 @@ 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;
@@ -1727,12 +1646,11 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
remainder = 0;
for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
unsigned name_len;
char *dname = d_name(di);
if (dname[0] == '.' && (dname[1] == '\0'
|| (dname[1] == '.' && dname[2] == '\0')))
continue;
name_len = strlcpy(p, dname, remainder);
unsigned name_len = strlcpy(p, dname, remainder);
if (name_len >= remainder) {
char save = fbuf[len];
fbuf[len] = '\0';
@@ -1781,7 +1699,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;
filter_rule_list save_filter_list = filter_list;
struct filter_list_struct 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. */
@@ -1877,8 +1795,7 @@ 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-%s issue with a pre-3.0.7 receiver.\n",
delete_during == 2 ? "delay" : "during");
rprintf(FERROR_XFER, "FATAL I/O ERROR: dying to avoid a --delete-during issue with a pre-3.0.7 receiver.\n");
exit_cleanup(RERR_UNSUPPORTED);
}
@@ -1935,9 +1852,7 @@ static void send1extra(int f, struct file_struct *file, struct file_list *flist)
if (name_type != NORMAL_NAME) {
STRUCT_STAT st;
if (name_type == MISSING_NAME)
memset(&st, 0, sizeof st);
else if (link_stat(fbuf, &st, 1) != 0) {
if (link_stat(fbuf, &st, 1) != 0) {
interpret_stat_error(fbuf, True);
continue;
}
@@ -1954,19 +1869,19 @@ void send_extra_file_list(int f, int at_least)
struct file_list *flist;
int64 start_write;
uint16 prev_flags;
int save_io_error = io_error;
int old_cnt, 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. */
while (file_total - file_old_total < at_least) {
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) {
struct file_struct *file = dir_flist->sorted[send_dir_ndx];
int dir_ndx, dstart = stats.num_dirs;
int dir_ndx, dstart = dir_count;
const char *pathname = F_PATHNAME(file);
int32 *dp;
@@ -2020,13 +1935,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, stats.num_dirs - dstart);
add_dirs_to_tree(send_dir_ndx, flist, dir_count - dstart);
flist_done_allocating(flist);
file_total += flist->used;
stats.flist_size += stats.total_written - start_write;
stats.num_files += flist->used;
if (DEBUG_GTE(FLIST, 3))
if (verbose > 3)
output_flist(flist);
if (DIR_FIRST_CHILD(dp) >= 0) {
@@ -2037,8 +1952,6 @@ 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;
}
@@ -2051,7 +1964,7 @@ void send_extra_file_list(int f, int at_least)
}
finish:
if (io_error != save_io_error && protocol_version == 30 && !ignore_errors)
if (io_error != save_io_error && !ignore_errors)
send_msg_int(MSG_IO_ERROR, io_error);
}
@@ -2066,7 +1979,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, reenable_multiplex = -1;
int disable_buffering;
int flags = recurse ? FLAG_CONTENT_DIR : 0;
int reading_remotely = filesfrom_host != NULL;
int rl_flags = (reading_remotely ? 0 : RL_DUMP_COMMENTS)
@@ -2079,7 +1992,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 && INFO_GTE(FLIST, 1) && !am_server)
else if (inc_recurse && verbose && !am_server)
rprintf(FCLIENT, "sending incremental file list\n");
start_write = stats.total_written;
@@ -2107,12 +2020,6 @@ 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;
}
@@ -2194,8 +2101,12 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
fn = fbuf;
/* A leading ./ can be used in relative mode to affect
* the dest dir without its name being in the path. */
if (*fn == '.' && fn[1] == '/' && fn[2] && !implied_dot_dir)
implied_dot_dir = -1;
if (*fn == '.' && fn[1] == '/' && !implied_dot_dir) {
send_file_name(f, flist, ".", NULL,
(flags | FLAG_IMPLIED_DIR) & ~FLAG_CONTENT_DIR,
ALL_FILTERS);
implied_dot_dir = 1;
}
len = clean_fname(fn, CFN_KEEP_TRAILING_SLASH
| CFN_DROP_TRAILING_DOT_DIR);
if (len == 1) {
@@ -2233,20 +2144,11 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
dirlen = dir ? strlen(dir) : 0;
if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
if (!change_pathname(NULL, dir, -dirlen))
goto bad_path;
continue;
lastdir = pathname;
lastdir_len = pathname_len;
} else if (!change_pathname(NULL, lastdir, lastdir_len)) {
bad_path:
if (implied_dot_dir < 0)
implied_dot_dir = 0;
} else if (!change_pathname(NULL, lastdir, lastdir_len))
continue;
}
if (implied_dot_dir < 0) {
implied_dot_dir = 1;
send_file_name(f, flist, ".", NULL, (flags | FLAG_IMPLIED_DIR) & ~FLAG_CONTENT_DIR, ALL_FILTERS);
}
if (fn != fbuf)
memmove(fbuf, fn, len + 1);
@@ -2254,26 +2156,14 @@ 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))) {
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);
}
io_error |= IOERR_GENERAL;
rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fbuf));
continue;
}
/* A dot-dir should not be excluded! */
if (name_type != DOTDIR_NAME && st.st_mode != 0
if (name_type != DOTDIR_NAME
&& is_excluded(fbuf, S_ISDIR(st.st_mode) != 0, ALL_FILTERS))
continue;
@@ -2289,8 +2179,7 @@ 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,
st.st_mode == 0 ? MISSING_NAME : name_type);
send_implied_dirs(f, flist, fbuf, fbuf, p, flags, name_type);
if (fn == p)
continue;
}
@@ -2324,9 +2213,6 @@ 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;
@@ -2375,11 +2261,12 @@ 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);
@@ -2387,28 +2274,26 @@ 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(IOBUF_FREE_BUFS);
io_end_buffering_out();
stats.flist_size = stats.total_written - start_write;
stats.num_files = flist->used;
if (DEBUG_GTE(FLIST, 3))
if (verbose > 3)
output_flist(flist);
if (DEBUG_GTE(FLIST, 2))
if (verbose > 2)
rprintf(FINFO, "send_file_list done\n");
if (inc_recurse) {
send_dir_depth = 1;
add_dirs_to_tree(-1, flist, stats.num_dirs);
add_dirs_to_tree(-1, flist, dir_count);
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
@@ -2416,10 +2301,6 @@ 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;
@@ -2430,18 +2311,14 @@ 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 (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");
if (!first_flist)
rprintf(FLOG, "receiving file list\n");
if (usermap)
parse_name_map(usermap, True);
if (groupmap)
parse_name_map(groupmap, False);
}
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");
start_read = stats.total_read;
@@ -2461,6 +2338,8 @@ 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;
@@ -2482,33 +2361,24 @@ struct file_list *recv_file_list(int f)
flist_expand(flist, 1);
file = recv_file_entry(f, flist, flags);
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++;
if (inc_recurse && S_ISDIR(file->mode)) {
flist_expand(dir_flist, 1);
dir_flist->files[dir_flist->used++] = file;
}
flist->files[flist->used++] = file;
maybe_emit_filelist_progress(flist->used);
if (DEBUG_GTE(FLIST, 2)) {
if (verbose > 2) {
char *name = f_name(file, NULL);
rprintf(FINFO, "recv_file_name(%s)\n", NS(name));
}
}
file_total += flist->used;
verbose = save_verbose;
if (DEBUG_GTE(FLIST, 2))
if (verbose > 2)
rprintf(FINFO, "received %d names\n", flist->used);
if (show_filelist_p())
@@ -2546,29 +2416,26 @@ 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 */
int err = read_int(f);
if (!ignore_errors)
io_error |= err;
if (ignore_errors)
read_int(f);
else
io_error |= read_int(f);
} else if (inc_recurse && flist->ndx_start == 1) {
if (!file_total || strcmp(flist->sorted[flist->low]->basename, ".") != 0)
flist->parent_ndx = -1;
}
if (DEBUG_GTE(FLIST, 3))
if (verbose > 3)
output_flist(flist);
if (DEBUG_GTE(FLIST, 2))
if (verbose > 2)
rprintf(FINFO, "recv_file_list done\n");
stats.flist_size += stats.total_read - start_read;
@@ -2585,8 +2452,6 @@ 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;
@@ -2598,7 +2463,7 @@ void recv_additional_file_list(int f)
NDX_FLIST_OFFSET - dir_flist->used + 1);
exit_cleanup(RERR_PROTOCOL);
}
if (DEBUG_GTE(FLIST, 3)) {
if (verbose > 3) {
rprintf(FINFO, "[%s] receiving flist for dir %d\n",
who_am_i(), ndx);
}
@@ -2705,16 +2570,14 @@ 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);
@@ -2844,7 +2707,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
keep = j, drop = i;
if (!am_sender) {
if (DEBUG_GTE(DUP, 1)) {
if (verbose > 1) {
rprintf(FINFO,
"removing duplicate name %s from file list (%d)\n",
f_name(file, fbuf), drop + flist->ndx_start);
@@ -2985,10 +2848,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=%s%s%s flags=%x\n",
"[%s] i=%d %s %s%s%s%s mode=0%o len=%.0f%s%s flags=%x\n",
who, i + flist->ndx_start,
root, dir, slash, name, trail,
(int)file->mode, comma_num(F_LENGTH(file)),
(int)file->mode, (double)F_LENGTH(file),
uidbuf, gidbuf, file->flags);
}
}
@@ -3203,7 +3066,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 (INFO_GTE(PROGRESS, 1))
if (do_progress)
flist_count_offset += dirlist->used;
prune_empty_dirs = 0;
@@ -3211,7 +3074,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 (DEBUG_GTE(FLIST, 3))
if (verbose > 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-2013 Wayne Davison
* Copyright (C) 2003-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 version 3 as

View File

@@ -1,7 +1,7 @@
/*
* Routines to provide a memory-efficient hashtable.
*
* Copyright (C) 2007-2013 Wayne Davison
* Copyright (C) 2007-2009 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,25 +43,11 @@ 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);
}
@@ -89,11 +75,6 @@ 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-2013 Wayne Davison
* Copyright (C) 2004-2009 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,8 @@
*/
#include "rsync.h"
#include "inums.h"
#include "ifuncs.h"
extern int verbose;
extern int dry_run;
extern int list_only;
extern int am_sender;
@@ -32,6 +31,7 @@ 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,14 +71,8 @@ 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;
@@ -212,7 +206,7 @@ void match_hard_links(struct file_list *flist)
}
static int maybe_hard_link(struct file_struct *file, int ndx,
char *fname, int statret, stat_x *sxp,
const char *fname, int statret, stat_x *sxp,
const char *oldname, STRUCT_STAT *old_stp,
const char *realname, int itemizing, enum logcode code)
{
@@ -224,24 +218,31 @@ static int maybe_hard_link(struct file_struct *file, int ndx,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
0, "");
}
if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
if (verbose > 1 && 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 (atomic_create(file, fname, oldname, MAKEDEV(0, 0), sxp, statret == 0 ? DEL_FOR_FILE : 0)) {
if (hard_link_one(file, fname, oldname, 0)) {
if (itemizing) {
itemize(fname, file, ndx, statret, sxp,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
realname);
}
if (code != FNONE && INFO_GTE(NAME, 1))
if (code != FNONE && verbose)
rprintf(code, "%s => %s\n", fname, realname);
return 0;
}
return -1;
}
@@ -287,7 +288,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, char *fname,
int hard_link_check(struct file_struct *file, int ndx, const char *fname,
int statret, stat_x *sxp, int itemizing,
enum logcode code)
{
@@ -306,10 +307,6 @@ int hard_link_check(struct file_struct *file, int ndx, 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;
}
@@ -326,16 +323,8 @@ int hard_link_check(struct file_struct *file, int ndx, 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;
}
@@ -343,6 +332,7 @@ int hard_link_check(struct file_struct *file, int ndx, 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;
}
@@ -350,14 +340,9 @@ int hard_link_check(struct file_struct *file, int ndx, 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],
@@ -371,11 +356,6 @@ int hard_link_check(struct file_struct *file, int ndx, 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));
@@ -391,7 +371,12 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
char cmpbuf[MAXPATHLEN];
stat_x alt_sx;
int j = 0;
init_stat_x(&alt_sx);
#ifdef SUPPORT_ACLS
alt_sx.acc_acl = alt_sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
alt_sx.xattr = NULL;
#endif
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
if (link_stat(cmpbuf, &alt_sx.st, 0) < 0)
@@ -402,10 +387,10 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
continue;
statret = 1;
if (stdout_format_has_i == 0
|| (!INFO_GTE(NAME, 2) && stdout_format_has_i < 2)) {
|| (verbose < 2 && stdout_format_has_i < 2)) {
itemizing = 0;
code = FNONE;
if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
if (verbose > 1 && maybe_ATTRS_REPORT)
rprintf(FCLIENT, "%s is uptodate\n", fname);
}
break;
@@ -441,8 +426,16 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
}
}
#endif
} else
free_stat_x(&alt_sx);
} else {
#ifdef SUPPORT_ACLS
if (preserve_acls)
free_acl(&alt_sx);
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs)
free_xattr(&alt_sx);
#endif
}
}
if (maybe_hard_link(file, ndx, fname, statret, sxp, prev_name, &prev_st,
@@ -461,7 +454,7 @@ int hard_link_one(struct file_struct *file, const char *fname,
if (do_link(oldname, fname) < 0) {
enum logcode code;
if (terse) {
if (!INFO_GTE(NAME, 1))
if (!verbose)
return 0;
code = FINFO;
} else
@@ -488,7 +481,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 && !dry_run) {
if (link_stat(fname, &st, 0) < 0) {
rsyserr(FERROR_XFER, errno, "stat %s failed",
full_fname(fname));
return;
@@ -506,7 +499,12 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
} else
our_name = fname;
init_stat_x(&prev_sx);
#ifdef SUPPORT_ACLS
prev_sx.acc_acl = prev_sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
prev_sx.xattr = NULL;
#endif
while ((ndx = prev_ndx) >= 0) {
int val;
@@ -519,7 +517,14 @@ 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--;
free_stat_x(&prev_sx);
#ifdef SUPPORT_ACLS
if (preserve_acls)
free_acl(&prev_sx);
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs)
free_xattr(&prev_sx);
#endif
if (val < 0)
continue;
if (remove_source_files == 1 && do_xfers)

View File

@@ -1,6 +1,6 @@
/* Inline functions for rsync.
*
* Copyright (C) 2007-2013 Wayne Davison
* Copyright (C) 2007-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
@@ -35,14 +35,6 @@ 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)
{
@@ -75,32 +67,44 @@ d_name(struct dirent *di)
#endif
}
static inline void
init_stat_x(stat_x *sx_p)
static inline int
isDigit(const char *ptr)
{
#ifdef SUPPORT_ACLS
sx_p->acc_acl = sx_p->def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
sx_p->xattr = NULL;
#endif
return isdigit(*(unsigned char *)ptr);
}
static inline void
free_stat_x(stat_x *sx_p)
static inline int
isPrint(const 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
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);
}

57
inums.h
View File

@@ -1,57 +0,0 @@
/* 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);
}

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

View File

@@ -1,59 +0,0 @@
/* 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,9 +20,6 @@
*/
#include "rsync.h"
#include "itypes.h"
static char number_separator;
#ifndef HAVE_STRDUP
char *strdup(char *s)
@@ -154,122 +151,3 @@ 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
}

View File

@@ -1,72 +0,0 @@
/*
* 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,39 +95,25 @@ for
.I quantum
will produce a quantum that should meet maximal alignment
on most platforms.
Unless
.B POOL_NO_QALIGN
If
.B POOL_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.
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 .
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.)
.P
.B pool_destroy()
destroys an allocation
@@ -145,8 +131,8 @@ is
.BR 0 ,
.I quantum
bytes will be allocated.
If the pool has been created without
.BR POOL_NO_QALIGN ,
If the pool has been created with
.BR POOL_QALIGN ,
every chunk of memory that is returned will be suitably aligned.
You can use this with the default
.I quantum
@@ -183,7 +169,7 @@ an extent), its memory will be completely freed back to the system.
If
.I addr
is
.BR NULL ,
.BR 0 ,
no memory will be freed, but subsequent allocations will come
from a new extent.
.P

View File

@@ -2,8 +2,6 @@
#define POOL_DEF_EXTENT (32 * 1024)
#define POOL_QALIGN_P2 (1<<16) /* power-of-2 qalign */
struct alloc_pool
{
size_t size; /* extent size */
@@ -15,7 +13,7 @@ struct alloc_pool
/* statistical data */
unsigned long e_created; /* extents created */
unsigned long e_freed; /* extents destroyed */
unsigned long e_freed; /* extents detroyed */
int64 n_allocated; /* calls to alloc */
int64 n_freed; /* calls to free */
int64 b_allocated; /* cum. bytes allocated */
@@ -24,18 +22,16 @@ struct alloc_pool
struct pool_extent
{
struct pool_extent *next;
void *start; /* starting address */
size_t free; /* free bytecount */
size_t bound; /* trapped free bytes */
size_t bound; /* bytes bound by padding,
* overhead and freed */
struct pool_extent *next;
};
struct align_test {
uchar foo;
union {
int64 i;
void *p;
} bar;
void *foo;
int64 bar;
};
#define MINALIGN offsetof(struct align_test, bar)
@@ -47,42 +43,20 @@ 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 = new0(struct alloc_pool)))
return NULL;
if ((MINALIGN & (MINALIGN - 1)) != 0) {
if (bomb)
(*bomb)("Compiler error: MINALIGN is not a power of 2\n");
return NULL;
}
if (!size)
size = POOL_DEF_EXTENT;
if (!quantum)
quantum = MINALIGN;
if (!(pool = new(struct alloc_pool)))
return pool;
memset(pool, 0, sizeof (struct alloc_pool));
pool->size = size /* round extent size to min alignment reqs */
? (size + MINALIGN - 1) & ~(MINALIGN - 1)
: POOL_DEF_EXTENT;
if (flags & POOL_INTERN) {
if (size <= sizeof (struct pool_extent))
size = quantum;
else
size -= sizeof (struct pool_extent);
flags |= POOL_PREPEND;
pool->size -= sizeof (struct pool_extent);
flags |= POOL_APPEND;
}
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->quantum = quantum ? quantum : MINALIGN;
pool->bomb = bomb;
pool->flags = flags;
@@ -93,21 +67,17 @@ 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;
if (pool->flags & POOL_PREPEND)
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
else {
free(cur->start);
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
}
}
free(pool);
}
@@ -120,40 +90,45 @@ pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg)
if (!len)
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;
}
else if (pool->quantum > 1 && 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 asize;
void *start;
size_t free;
size_t bound;
size_t skew;
size_t asize;
struct pool_extent *ext;
free = pool->size;
bound = 0;
asize = pool->size;
if (pool->flags & POOL_PREPEND)
if (pool->flags & POOL_APPEND)
asize += sizeof (struct pool_extent);
if (!(start = new_array(char, asize)))
goto bomb_out;
if (pool->flags & POOL_CLEAR)
memset(start, 0, asize);
memset(start, 0, free);
if (pool->flags & POOL_PREPEND) {
ext = start;
start = PTR_ADD(start, sizeof (struct pool_extent));
} else if (!(ext = new(struct pool_extent)))
if (pool->flags & POOL_APPEND)
ext = PTR_ADD(start, free);
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 = pool->size;
ext->bound = 0;
ext->free = free;
ext->bound = bound;
ext->next = pool->extents;
pool->extents = ext;
@@ -185,24 +160,10 @@ 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->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;
}
else if (pool->quantum > 1 && len % pool->quantum)
len += pool->quantum - len % pool->quantum;
pool->n_freed++;
pool->b_freed += len;
@@ -218,12 +179,19 @@ 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);
@@ -235,12 +203,9 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
if (cur->free + cur->bound >= pool->size) {
prev->next = cur->next;
if (pool->flags & POOL_PREPEND)
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
else {
free(cur->start);
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
}
pool->e_freed++;
} else if (prev != pool->extents) {
/* Move the extent to be the first non-live extent. */
@@ -277,11 +242,18 @@ 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;
}
@@ -292,12 +264,9 @@ pool_free_old(alloc_pool_t p, void *addr)
while ((cur = next) != NULL) {
next = cur->next;
if (pool->flags & POOL_PREPEND)
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
else {
free(cur->start);
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
}
pool->e_freed++;
}
}
@@ -344,7 +313,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_NO_QALIGN (1<<1) /* don't align data to quanta */
#define POOL_QALIGN (1<<1) /* align data to quanta */
#define POOL_INTERN (1<<2) /* Allocate extent structures */
#define POOL_PREPEND (1<<3) /* or prepend to extent data */
#define POOL_APPEND (1<<3) /* or appended to extent data */
typedef void *alloc_pool_t;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -126,150 +126,6 @@ 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

190
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-2013 Wayne Davison
* Copyright (C) 2003-2009 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 "itypes.h"
#include "inums.h"
#include "ifuncs.h"
extern int verbose;
extern int dry_run;
extern int am_daemon;
extern int am_server;
@@ -31,19 +31,16 @@ extern int am_generator;
extern int local_server;
extern int quiet;
extern int module_id;
extern int checksum_len;
extern int msg_fd_out;
extern int allow_8bit_chars;
extern int protocol_version;
extern int always_checksum;
extern int preserve_times;
extern int msgs2stderr;
extern int progress_is_active;
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;
@@ -58,8 +55,6 @@ 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;
@@ -67,11 +62,6 @@ 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;
@@ -95,13 +85,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 }
};
@@ -123,7 +113,8 @@ 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);
@@ -250,7 +241,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 = msgs2stderr ? stderr : stdout;
FILE *f = NULL;
#ifdef ICONV_OPTION
iconv_t ic = is_utf8 && ic_recv != (iconv_t)-1 ? ic_recv : ic_chck;
#else
@@ -262,16 +253,7 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
if (len < 0)
exit_cleanup(RERR_MESSAGEIO);
if (msgs2stderr) {
if (!am_daemon) {
if (code == FLOG)
return;
goto output_msg;
}
if (code == FCLIENT)
return;
code = FLOG;
} else if (send_msgs_to_gen) {
if (am_server && msg_fd_out >= 0) {
assert(!is_utf8);
/* Pass the message to our sibling in native charset. */
send_msg((enum msgcode)code, buf, len, 0);
@@ -324,43 +306,31 @@ 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:
case FCLIENT:
f = am_server ? stderr : stdout;
break;
default:
fprintf(stderr, "Unknown logcode in rwrite(): %d [%s]\n", (int)code, who_am_i());
exit_cleanup(RERR_MESSAGEIO);
}
if (output_needs_newline) {
if (progress_is_active && !am_server) {
fputc('\n', f);
output_needs_newline = 0;
progress_is_active = 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;
@@ -368,10 +338,10 @@ output_msg:
int ierrno;
INIT_CONST_XBUF(outbuf, convbuf);
INIT_XBUF(inbuf, (char*)buf, len, (size_t)-1);
INIT_XBUF(inbuf, (char*)buf, len, -1);
while (inbuf.len) {
iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT);
iconvbufs(ic, &inbuf, &outbuf, 0);
ierrno = errno;
if (outbuf.len) {
filtered_fwrite(f, convbuf, outbuf.len, 0);
@@ -466,12 +436,12 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
void rflush(enum logcode code)
{
FILE *f;
FILE *f = NULL;
if (am_daemon || code == FLOG)
return;
if (!am_server && (code == FINFO || code == FCLIENT))
if (code == FINFO && !am_server)
f = stdout;
else
f = stderr;
@@ -479,15 +449,10 @@ 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, int iflags,
struct file_struct *file, const char *fname,
struct stats *initial_stats, int iflags,
const char *hlink)
{
char buf[MAXPATHLEN+1024], buf2[MAXPATHLEN], fmt[32];
@@ -510,45 +475,30 @@ 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 = lp_reverse_lookup(module_id)
? client_name(0) : undetermined_hostname;
}
if (am_daemon)
n = client_name(0);
break;
case 'a':
if (am_daemon)
n = client_addr(0);
break;
case 'l':
strlcat(fmt, "s", sizeof fmt);
strlcat(fmt, ".0f", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
do_big_num(F_LENGTH(file), humanize, NULL));
(double)F_LENGTH(file));
n = buf2;
break;
case 'U':
@@ -568,8 +518,9 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
}
break;
case 'p':
strlcat(fmt, "d", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt, (int)getpid());
strlcat(fmt, "ld", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
(long)getpid());
n = buf2;
break;
case 'M':
@@ -656,41 +607,28 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
n = auth_user;
break;
case '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));
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);
n = buf2;
break;
case 'c':
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);
if (!am_sender) {
b = stats.total_written -
initial_stats->total_written;
} else {
memset(buf2, ' ', checksum_len*2);
buf2[checksum_len*2] = '\0';
n = buf2;
b = stats.total_read -
initial_stats->total_read;
}
strlcat(fmt, ".0f", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt, (double)b);
n = buf2;
break;
case 'i':
if (iflags & ITEM_DELETED) {
@@ -790,12 +728,10 @@ int log_format_has(const char *format, char esc)
return 0;
for (p = format; (p = strchr(p, '%')) != NULL; ) {
for (p++; *p == '\''; p++) {} /*SHARED ITERATOR*/
if (*p == '-')
if (*++p == '-')
p++;
while (isDigit(p))
p++;
while (*p == '\'') p++;
if (!*p)
break;
if (*p == esc)
@@ -807,14 +743,19 @@ 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, int iflags, const char *hlink)
void log_item(enum logcode code, struct file_struct *file,
struct stats *initial_stats, 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, iflags, hlink);
if (code != FCLIENT && logfile_format && *logfile_format)
log_formatted(FLOG, logfile_format, s_or_r, file, NULL, iflags, hlink);
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);
}
}
void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
@@ -822,16 +763,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 || (INFO_GTE(NAME, 2) && stdout_format_has_i));
|| stdout_format_has_i > 1 || (verbose > 1 && 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, iflags, buf);
log_item(FLOG, file, &stats, 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, iflags, buf);
log_item(code, file, &stats, iflags, buf);
}
}
@@ -840,13 +781,13 @@ void log_delete(const char *fname, int mode)
static struct {
union file_extras ex[4]; /* just in case... */
struct file_struct file;
} x; /* Zero-initialized due to static declaration. */
} x;
int len = strlen(fname);
const char *fmt;
x.file.mode = mode;
if (!INFO_GTE(DEL, 1) && !stdout_format)
if (!verbose && !stdout_format)
;
else if (am_server && protocol_version >= 29 && len < MAXPATHLEN) {
if (S_ISDIR(mode))
@@ -854,14 +795,15 @@ 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, ITEM_DELETED, NULL);
log_formatted(FCLIENT, fmt, "del.", &x.file, fname, &stats,
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, ITEM_DELETED, NULL);
log_formatted(FLOG, fmt, "del.", &x.file, fname, &stats, ITEM_DELETED, NULL);
}
/*
@@ -873,10 +815,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 %s bytes received %s bytes total size %s\n",
comma_num(stats.total_written),
comma_num(stats.total_read),
comma_num(stats.total_size));
rprintf(FLOG,"sent %.0f bytes received %.0f bytes total size %.0f\n",
(double)stats.total_written,
(double)stats.total_read,
(double)stats.total_size);
} else if (am_server != 2) {
const char *name;

353
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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,30 +21,27 @@
*/
#include "rsync.h"
#include "inums.h"
#include "ifuncs.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;
@@ -65,44 +62,31 @@ 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 filter_rule_list daemon_filter_list;
extern struct filter_list_struct 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. */
@@ -132,7 +116,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);
@@ -185,30 +169,6 @@ 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.
@@ -225,7 +185,7 @@ static void handle_stats(int f)
total_read = stats.total_read;
total_written = stats.total_written;
if (INFO_GTE(STATS, 3)) {
if (do_stats && verbose > 1) {
/* These come out from every process */
show_malloc_stats();
show_flist_stats();
@@ -279,39 +239,13 @@ 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 (INFO_GTE(STATS, 2)) {
if (do_stats) {
rprintf(FCLIENT, "\n");
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,"Number of files: %d\n", stats.num_files);
rprintf(FINFO,"Number of files transferred: %d\n",
stats.num_transferred_files);
rprintf(FINFO,"Total file size: %s bytes\n",
human_num(stats.total_size));
rprintf(FINFO,"Total transferred file size: %s bytes\n",
@@ -324,11 +258,11 @@ static void output_summary(void)
human_num(stats.flist_size));
if (stats.flist_buildtime) {
rprintf(FINFO,
"File list generation time: %s seconds\n",
comma_dnum((double)stats.flist_buildtime / 1000, 3));
"File list generation time: %.3f seconds\n",
(double)stats.flist_buildtime / 1000);
rprintf(FINFO,
"File list transfer time: %s seconds\n",
comma_dnum((double)stats.flist_xfertime / 1000, 3));
"File list transfer time: %.3f seconds\n",
(double)stats.flist_xfertime / 1000);
}
rprintf(FINFO,"Total bytes sent: %s\n",
human_num(total_written));
@@ -336,15 +270,15 @@ static void output_summary(void)
human_num(total_read));
}
if (INFO_GTE(STATS, 1)) {
if (verbose || do_stats) {
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 %s%s\n",
rprintf(FINFO, "total size is %s speedup is %.2f%s\n",
human_num(stats.total_size),
comma_dnum((double)stats.total_size / (total_written+total_read), 2),
(double)stats.total_size / (total_written+total_read),
write_batch < 0 ? " (BATCH ONLY)" : dry_run ? " (DRY RUN)" : "");
}
@@ -365,7 +299,7 @@ static void show_malloc_stats(void)
rprintf(FCLIENT, "\n");
rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
(int)getpid(), am_server ? "server " : "",
getpid(), am_server ? "server " : "",
am_daemon ? "daemon " : "", who_am_i());
rprintf(FINFO, " arena: %10ld (bytes from sbrk)\n",
(long)mi.arena);
@@ -398,7 +332,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], *need_to_free = NULL;
char *args[MAX_ARGS];
pid_t pid;
int dash_l_set = 0;
@@ -409,7 +343,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 = need_to_free = strdup(cmd);
cmd = strdup(cmd); /* MEMORY LEAK */
if (!cmd)
goto oom;
@@ -506,7 +440,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
args[argc] = NULL;
if (DEBUG_GTE(CMD, 2)) {
if (verbose > 3) {
for (i = 0; i < argc; i++)
rprintf(FCLIENT, "cmd[%d]=%s ", i, args[i]);
rprintf(FCLIENT, "\n");
@@ -545,9 +479,6 @@ 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:
@@ -574,7 +505,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
int statret;
char *cp;
if (DEBUG_GTE(RECV, 1)) {
if (verbose > 2) {
rprintf(FINFO, "get_local_name count=%d %s\n",
file_total, NS(dest_path));
}
@@ -595,7 +526,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
if ((*dest_path != '.' || dest_path[1] != '\0')
&& (check_filter(&daemon_filter_list, FLOG, dest_path, 0) < 0
|| check_filter(&daemon_filter_list, FLOG, dest_path, 1) < 0)) {
rprintf(FERROR, "ERROR: daemon has excluded destination \"%s\"\n",
rprintf(FERROR, "skipping daemon-excluded destination \"%s\"\n",
dest_path);
exit_cleanup(RERR_FILESELECT);
}
@@ -650,7 +581,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
exit_cleanup(RERR_SYNTAX);
}
if (do_mkdir(dest_path, ACCESSPERMS) != 0) {
if (mkdir_defmode(dest_path) != 0) {
rsyserr(FERROR, errno, "mkdir %s failed",
full_fname(dest_path));
exit_cleanup(RERR_FILEIO);
@@ -660,7 +591,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 (INFO_GTE(NAME, 1))
if (verbose)
rprintf(FINFO, "created directory %s\n", dest_path);
if (dry_run) {
@@ -706,63 +637,48 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
static void check_alt_basis_dirs(void)
{
STRUCT_STAT st;
char *slash = strrchr(curr_dir, '/');
int j;
char **dir_p, *slash = strrchr(curr_dir, '/');
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;
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;
char *new = new_array(char, len);
if (!new)
out_of_memory("check_alt_basis_dirs");
if (slash && strncmp(bdir, "../", 3) == 0) {
if (slash && strncmp(*dir_p, "../", 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, bdir + 3);
pathjoin(new, len, curr_dir, *dir_p + 3);
*slash = '/';
} else
pathjoin(new, len, curr_dir, bdir);
basis_dir[j] = bdir = new;
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);
}
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, int f_out)
static void read_final_goodbye(int f_in)
{
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, 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);
}
i = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
xname, &xlen);
}
if (i != NDX_DONE) {
@@ -777,15 +693,17 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
struct file_list *flist;
char *dir = argv[0];
if (DEBUG_GTE(SEND, 1))
rprintf(FINFO, "server_sender starting pid=%d\n", (int)getpid());
if (verbose > 2) {
rprintf(FINFO, "server_sender starting pid=%ld\n",
(long)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 && read_only && remove_source_files) {
if (am_daemon && lp_read_only(module_id) && remove_source_files) {
rprintf(FERROR,
"ERROR: --remove-%s-files cannot be used with a read-only module\n",
remove_source_files == 1 ? "source" : "sent");
@@ -810,12 +728,8 @@ 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) {
/* 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. */
if (!flist || flist->used == 0)
exit_cleanup(0);
}
io_start_buffering_in(f_in);
@@ -823,7 +737,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, f_out);
read_final_goodbye(f_in);
io_flush(FULL_FLUSH);
exit_cleanup(0);
}
@@ -849,17 +763,7 @@ static int do_recv(int f_in, int f_out, char *local_name)
exit_cleanup(RERR_IPC);
}
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);
io_flush(NORMAL_FLUSH);
if ((pid = do_fork()) == -1) {
rsyserr(FERROR, errno, "fork failed in do_recv");
@@ -868,43 +772,38 @@ 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];
bwlimit_writemax = 0; /* receiver doesn't need to do this */
/* we can't let two processes write to the socket at one time */
io_end_multiplex_out();
if (read_batch)
io_start_buffering_in(f_in);
io_start_multiplex_out(f_out);
/* set place to send errors */
set_msg_fd_out(error_pipe[1]);
io_start_buffering_out(error_pipe[1]);
recv_files(f_in, f_out, local_name);
recv_files(f_in, local_name);
io_flush(FULL_FLUSH);
handle_stats(f_in);
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);
send_msg(MSG_DONE, "", 1, 0);
write_varlong(error_pipe[1], stats.total_read, 3);
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_final_goodbye(f_in, f_out);
read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
xname, &xlen);
rprintf(FERROR, "Invalid packet at end of run [%s]\n",
who_am_i());
@@ -919,20 +818,19 @@ static int do_recv(int f_in, int f_out, char *local_name)
}
am_generator = 1;
flist_receiving_enabled = True;
io_end_multiplex_in(MPLX_SWITCHING);
io_end_multiplex_in();
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);
io_start_multiplex_in(f_in);
set_msg_fd_in(error_pipe[0]);
io_start_buffering_in(error_pipe[0]);
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && inc_recurse) {
@@ -946,13 +844,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;
@@ -963,20 +861,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 negated_levels;
int save_verbose = verbose;
if (filesfrom_fd >= 0 && !msgs2stderr && protocol_version < 31) {
if (filesfrom_fd >= 0) {
/* We can't mix messages with files-from data on the socket,
* so temporarily turn off info/debug messages. */
negate_output_levels();
negated_levels = 1;
} else
negated_levels = 0;
* so temporarily turn off verbose messages. */
verbose = 0;
}
if (DEBUG_GTE(RECV, 1))
rprintf(FINFO, "server_recv(%d) starting pid=%d\n", argc, (int)getpid());
if (verbose > 2) {
rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
argc, (long)getpid());
}
if (am_daemon && read_only) {
if (am_daemon && lp_read_only(module_id)) {
rprintf(FERROR,"ERROR: module is read only\n");
exit_cleanup(RERR_SYNTAX);
return;
@@ -994,7 +892,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
}
if (protocol_version >= 30)
io_start_multiplex_in(f_in);
io_start_multiplex_in();
else
io_start_buffering_in(f_in);
recv_filter_list(f_in);
@@ -1005,7 +903,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. */
start_filesfrom_forwarding(filesfrom_fd);
io_set_filesfrom_fds(filesfrom_fd, f_out);
filesfrom_fd = -1;
}
@@ -1016,9 +914,7 @@ 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);
if (negated_levels)
negate_output_levels();
verbose = save_verbose;
if (argc > 0)
local_name = get_local_name(flist,argv[0]);
@@ -1036,7 +932,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
if (daemon_filter_list.head) {
char **dir_p;
filter_rule_list *elp = &daemon_filter_list;
struct filter_list_struct *elp = &daemon_filter_list;
for (dir_p = basis_dir; *dir_p; dir_p++) {
char *dir = *dir_p;
@@ -1075,16 +971,12 @@ 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(f_out);
if (am_daemon && io_timeout && protocol_version >= 31)
send_msg_int(MSG_IO_TIMEOUT, io_timeout);
io_start_multiplex_out();
if (am_sender) {
keep_dirlinks = 0; /* Must be disabled on the sender. */
if (need_messages_from_generator)
io_start_multiplex_in(f_in);
else
io_start_buffering_in(f_in);
io_start_multiplex_in();
recv_filter_list(f_in);
do_server_sender(f_in, f_out, argc, argv);
} else
@@ -1092,8 +984,11 @@ 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;
@@ -1121,20 +1016,12 @@ 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(f_out);
io_start_multiplex_out();
else
io_start_buffering_out(f_out);
if (protocol_version >= 31 || (!filesfrom_host && protocol_version >= 23))
io_start_multiplex_in(f_in);
else
io_start_buffering_in(f_in);
if (!filesfrom_host)
set_msg_fd_in(f_in);
send_filter_list(f_out);
if (filesfrom_host)
filesfrom_fd = f_in;
@@ -1142,20 +1029,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 (DEBUG_GTE(FLIST, 3))
if (verbose > 3)
rprintf(FINFO,"file list sent\n");
if (protocol_version < 31 && filesfrom_host && protocol_version >= 23)
io_start_multiplex_in(f_in);
if (protocol_version >= 23)
io_start_multiplex_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, f_out);
read_final_goodbye(f_in);
if (pid != -1) {
if (DEBUG_GTE(EXIT, 2))
if (verbose > 3)
rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
io_flush(FULL_FLUSH);
wait_process_with_flush(pid, &exit_code);
@@ -1167,17 +1054,15 @@ 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(f_in);
io_start_multiplex_in();
if (need_messages_from_generator)
io_start_multiplex_out(f_out);
else
io_start_buffering_out(f_out);
io_start_multiplex_out();
}
send_filter_list(read_batch ? -1 : f_out);
if (filesfrom_fd >= 0) {
start_filesfrom_forwarding(filesfrom_fd);
io_set_filesfrom_fds(filesfrom_fd, f_out);
filesfrom_fd = -1;
}
@@ -1199,7 +1084,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
}
if (pid != -1) {
if (DEBUG_GTE(RECV, 1))
if (verbose > 3)
rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
io_flush(FULL_FLUSH);
wait_process_with_flush(pid, &exit_code);
@@ -1224,12 +1109,14 @@ 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;
@@ -1316,9 +1203,6 @@ 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;
@@ -1354,8 +1238,6 @@ 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;
}
}
@@ -1384,10 +1266,10 @@ static int start_client(int argc, char *argv[])
}
}
if (DEBUG_GTE(CMD, 2)) {
if (verbose > 3) {
rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
NS(shell_cmd), NS(shell_machine), NS(shell_user),
NS(remote_argv[0]));
remote_argv ? NS(remote_argv[0]) : "");
}
pid = do_cmd(shell_cmd, shell_machine, shell_user, remote_argv, remote_argc,
@@ -1490,9 +1372,10 @@ const char *get_panic_action(void)
static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
{
char cmd_buf[300];
int ret, pid_int = getpid();
int ret;
snprintf(cmd_buf, sizeof cmd_buf, get_panic_action(), pid_int, pid_int);
snprintf(cmd_buf, sizeof cmd_buf, get_panic_action(),
getpid(), getpid());
/* Unless we failed to execute gdb, we allow the process to
* continue. I'm not sure if that's right. */
@@ -1528,7 +1411,6 @@ 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));
@@ -1538,10 +1420,9 @@ int main(int argc,char *argv[])
exit_cleanup(RERR_SYNTAX);
}
/* 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));
/* we set a 0 umask so that correct file permissions can be
* carried across */
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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,13 @@
*/
#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;
@@ -108,10 +107,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 (DEBUG_GTE(DELTASUM, 2) && i >= 0) {
if (verbose > 2 && i >= 0) {
rprintf(FINFO,
"match at %s last_match=%s j=%d len=%ld n=%ld\n",
big_num(offset), big_num(last_match), i,
"match at %.0f last_match=%.0f j=%d len=%ld n=%ld\n",
(double)offset, (double)last_match, i,
(long)s->sums[i].len, (long)n);
}
@@ -133,7 +132,7 @@ static void matched(int f, struct sum_struct *s, struct map_struct *buf,
else
last_match = offset;
if (buf && INFO_GTE(PROGRESS, 1))
if (buf && do_progress)
show_progress(last_match, buf->file_size);
}
@@ -152,9 +151,9 @@ static void hash_search(int f,struct sum_struct *s,
* coding of the output to work more efficiently. */
want_i = 0;
if (DEBUG_GTE(DELTASUM, 2)) {
rprintf(FINFO, "hash search b=%ld len=%s\n",
(long)s->blength, big_num(len));
if (verbose > 2) {
rprintf(FINFO, "hash search b=%ld len=%.0f\n",
(long)s->blength, (double)len);
}
k = (int32)MIN(len, (OFF_T)s->blength);
@@ -164,55 +163,41 @@ static void hash_search(int f,struct sum_struct *s,
sum = get_checksum1((char *)map, k);
s1 = sum & 0xFFFF;
s2 = sum >> 16;
if (DEBUG_GTE(DELTASUM, 3))
if (verbose > 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 (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));
if (verbose > 3) {
rprintf(FINFO, "hash search s->blength=%ld len=%.0f count=%.0f\n",
(long)s->blength, (double)len, (double)s->count);
}
do {
int done_csum2 = 0;
uint32 hash_entry;
int32 i, *prev;
int32 i;
if (DEBUG_GTE(DELTASUM, 4)) {
rprintf(FINFO, "offset=%s sum=%04x%04x\n",
big_num(offset), s2 & 0xFFFF, s1 & 0xFFFF);
if (verbose > 4) {
rprintf(FINFO, "offset=%.0f sum=%04x%04x\n",
(double)offset, s2 & 0xFFFF, s1 & 0xFFFF);
}
if (tablesize == TRADITIONAL_TABLESIZE) {
hash_entry = SUM2HASH2(s1,s2);
if ((i = hash_table[hash_entry]) < 0)
if ((i = hash_table[SUM2HASH2(s1,s2)]) < 0)
goto null_hash;
sum = (s1 & 0xffff) | (s2 << 16);
} else {
sum = (s1 & 0xffff) | (s2 << 16);
hash_entry = BIG_SUM2HASH(sum);
if ((i = hash_table[hash_entry]) < 0)
if ((i = hash_table[BIG_SUM2HASH(sum)]) < 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;
@@ -221,10 +206,16 @@ static void hash_search(int f,struct sum_struct *s,
if (l != s->sums[i].len)
continue;
if (DEBUG_GTE(DELTASUM, 3)) {
/* 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) {
rprintf(FINFO,
"potential match at %s i=%ld sum=%08x\n",
big_num(offset), (long)i, sum);
"potential match at %.0f i=%ld sum=%08x\n",
(double)offset, (long)i, sum);
}
if (!done_csum2) {
@@ -247,9 +238,7 @@ static void hash_search(int f,struct sum_struct *s,
aligned_offset += s->blength;
aligned_i++;
}
if ((offset == aligned_offset
|| (sum == 0 && l == s->blength && aligned_offset + l <= len))
&& aligned_i < s->count) {
if (offset == aligned_offset) {
if (i != aligned_i) {
if (sum != s->sums[aligned_i].sum1
|| l != s->sums[aligned_i].len
@@ -257,27 +246,6 @@ 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;
@@ -360,6 +328,9 @@ 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;
@@ -372,7 +343,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 && INFO_GTE(PROGRESS, 1))
if (buf && do_progress)
show_progress(last_match, buf->file_size);
sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
CHUNK_SIZE);
@@ -380,7 +351,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 && INFO_GTE(PROGRESS, 1))
if (buf && do_progress)
show_progress(last_match, buf->file_size);
sum_update(map_ptr(buf, last_match, n), n);
}
@@ -392,12 +363,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 (DEBUG_GTE(DELTASUM, 2))
if (verbose > 2)
rprintf(FINFO,"built hash table\n");
hash_search(f, s, buf, len);
if (DEBUG_GTE(DELTASUM, 2))
if (verbose > 2)
rprintf(FINFO,"done hash search\n");
} else {
OFF_T j;
@@ -407,28 +378,18 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
matched(f, s, buf, len, -1);
}
if (sum_end(sender_file_sum) != checksum_len)
overflow_exit("checksum_len"); /* Impossible... */
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 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))
if (verbose > 2)
rprintf(FINFO,"sending file_sum\n");
write_buf(f, sender_file_sum, checksum_len);
write_buf(f, file_sum, sum_len);
if (DEBUG_GTE(DELTASUM, 2)) {
if (verbose > 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;
@@ -438,11 +399,11 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
void match_report(void)
{
if (!DEBUG_GTE(DELTASUM, 1))
if (verbose <= 1)
return;
rprintf(FINFO,
"total: matches=%d hash_hits=%d false_alarms=%d data=%s\n",
"total: matches=%d hash_hits=%d false_alarms=%d data=%.0f\n",
total_matches, total_hash_hits, total_false_alarms,
big_num(stats.literal_data));
(double)stats.literal_data);
}

799
options.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,180 +0,0 @@
#!/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,28 +6,25 @@ sub check_git_state
my($master_branch, $fatal_unless_clean, $check_patches_dir) = @_;
my($cur_branch) = check_git_status($fatal_unless_clean);
(my $branch = $cur_branch) =~ s{^patch/([^/]+)/[^/]+$}{$1}; # change patch/BRANCH/PATCH_NAME into BRANCH
if ($branch ne $master_branch) {
if ($cur_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=$branch? [n] ";
print "Do you want me to continue with --branch=$cur_branch? [n] ";
$_ = <STDIN>;
exit 1 unless /^y/i;
$_[0] = $master_branch = $branch; # Updates caller's $master_branch too.
$_[0] = $master_branch = $cur_branch; # Updates caller's $master_branch too.
}
if ($check_patches_dir && -d 'patches/.git') {
($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";
($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";
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.1.0
Version: 3.0.8
%define fullversion %{version}
Release: 1
%define srcdir src
@@ -13,14 +13,6 @@ 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
@@ -32,22 +24,12 @@ 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
@@ -64,11 +46,14 @@ make
%install
rm -rf $RPM_BUILD_ROOT
make install install-ssl-client install-ssl-daemon DESTDIR=$RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d $RPM_BUILD_ROOT/etc/rsync-ssl/certs
%makeinstall
mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d
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
@@ -76,21 +61,13 @@ 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
* Sat Sep 28 2013 Wayne Davison <wayned@samba.org>
Released 3.1.0.
* Sat Mar 26 2011 Wayne Davison <wayned@samba.org>
Released 3.0.8.
* 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';
my $starting_branch = check_git_state($master_branch, !$skip_branch_check, 1);
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 $starting_branch" and exit 1;
system "git checkout $master_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 --skip-check --shell";
system "packaging/patch-update --branch=$master_branch --shell";
}
if (-d 'patches/.git') {

159
params.c
View File

@@ -75,7 +75,6 @@
#include "rsync.h"
#include "ifuncs.h"
#include "itypes.h"
/* -------------------------------------------------------------------------- **
* Constants...
@@ -94,8 +93,6 @@
static char *bufr = NULL;
static int bSize = 0;
static BOOL (*the_sfunc)(char *);
static BOOL (*the_pfunc)(char *, char *);
/* -------------------------------------------------------------------------- **
* Functions...
@@ -226,7 +223,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 config file.\n", func );
rprintf(FLOG, "%s Empty section name in configuration file.\n", func );
return( False );
}
if( !sfunc( bufr ) ) /* Got a valid name. Deal with it. */
@@ -239,7 +236,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
if( i < 0 )
{
bufr[end] = '\0';
rprintf(FLOG, "%s Badly formed line in config file: %s\n",
rprintf(FLOG, "%s Badly formed line in configuration file: %s\n",
func, bufr );
return( False );
}
@@ -264,7 +261,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 config file: %s\n", func, bufr );
rprintf(FLOG, "%s Unexpected EOF in the configuration file: %s\n", func, bufr );
return( False );
} /* Section */
@@ -318,12 +315,13 @@ 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 = vstart = end; /* New string starts here. */
c = EatWhitespace(InFile);
i = end; /* New string starts here. */
vstart = end; /* New string is parameter value. */
bufr[i] = '\0'; /* New string is nul, for now. */
break;
case '\n': /* Find continuation char, else error. */
@@ -331,7 +329,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 config file: %s\n",
rprintf(FLOG, "%s Ignoring badly formed line in configuration file: %s\n",
func, bufr );
return( True );
}
@@ -345,19 +343,6 @@ 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. */
{
@@ -375,6 +360,7 @@ 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) )
{
@@ -420,88 +406,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
return( pfunc( bufr, &bufr[vstart] ) ); /* Pass name & value to pfunc(). */
} /* Parameter */
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,
static BOOL Parse( FILE *InFile,
BOOL (*sfunc)(char *),
BOOL (*pfunc)(char *, char *) )
/* ------------------------------------------------------------------------ **
@@ -513,8 +418,7 @@ static int Parse( FILE *InFile,
* pfunc - Function to be called when a parameter is scanned.
* See Parameter().
*
* Output: 1 if the file was successfully scanned, 2 if the file was
* scanned until a section header with no section function, else 0.
* Output: True if the file was successfully scanned, else False.
*
* Notes: The input can be viewed in terms of 'lines'. There are four
* types of lines:
@@ -523,7 +427,7 @@ static int Parse( FILE *InFile,
* The remainder of the line is ignored.
* Section - First non-whitespace character is a '['.
* Parameter - The default case.
*
*
* ------------------------------------------------------------------------ **
*/
{
@@ -544,39 +448,29 @@ static int Parse( FILE *InFile,
break;
case '[': /* Section Header. */
if (!sfunc)
return 2;
if( !Section( InFile, sfunc ) )
return 0;
c = EatWhitespace( InFile );
break;
if (!sfunc) return True;
if( !Section( InFile, sfunc ) )
return( False );
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 0;
return( False );
c = EatWhitespace( InFile );
break;
}
}
return 1;
return( True );
} /* Parse */
static FILE *OpenConfFile( char *FileName )
/* ------------------------------------------------------------------------ **
* Open a config file.
* Open a configuration file.
*
* Input: FileName - The pathname of the config file to be opened.
*
@@ -591,21 +485,21 @@ static FILE *OpenConfFile( char *FileName )
if( NULL == FileName || 0 == *FileName )
{
rprintf(FLOG, "%s No config filename specified.\n", func);
rprintf(FLOG, "%s No configuration filename specified.\n", func);
return( NULL );
}
OpenedFile = fopen( FileName, "r" );
if( NULL == OpenedFile )
{
rsyserr(FLOG, errno, "unable to open config file \"%s\"",
rsyserr(FLOG, errno, "unable to open configuration file \"%s\"",
FileName);
}
return( OpenedFile );
} /* OpenConfFile */
int pm_process( char *FileName,
BOOL pm_process( char *FileName,
BOOL (*sfunc)(char *),
BOOL (*pfunc)(char *, char *) )
/* ------------------------------------------------------------------------ **
@@ -617,8 +511,7 @@ int pm_process( char *FileName,
* pfunc - A pointer to a function that will be called when
* a parameter name and value are discovered.
*
* Output: 1 if the file was successfully parsed, 2 if parsing ended at a
* section header w/o a section function, else 0.
* Output: TRUE if the file was successfully parsed, else FALSE.
*
* ------------------------------------------------------------------------ **
*/
@@ -656,10 +549,10 @@ int pm_process( char *FileName,
if( !result ) /* Generic failure. */
{
rprintf(FLOG, "%s Failed. Error returned from params.c:parse().\n", func);
return 0;
return( False );
}
return result;
return( True ); /* Generic success. */
} /* 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-2013 Wayne Davison
* Copyright (C) 2004-2009 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,10 +26,8 @@ extern int am_sender;
extern int am_server;
extern int blocking_io;
extern int filesfrom_fd;
extern int munge_symlinks;
extern mode_t orig_umask;
extern char *logfile_name;
extern int remote_option_cnt;
extern const char **remote_options;
extern struct chmod_mode_struct *chmod_modes;
/**
@@ -51,7 +49,7 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
int to_child_pipe[2];
int from_child_pipe[2];
if (DEBUG_GTE(CMD, 1))
if (verbose >= 2)
print_child_argv("opening connection using:", command);
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
@@ -77,6 +75,7 @@ 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);
@@ -132,7 +131,6 @@ 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. */
@@ -141,15 +139,6 @@ 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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,12 +21,9 @@
*/
#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;
@@ -43,6 +40,8 @@ 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;
@@ -67,26 +66,11 @@ 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)))
@@ -95,7 +79,6 @@ 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;
@@ -123,21 +106,23 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
(int) remain % 60);
}
output_needs_newline = 0;
pct = ofs == size ? 100 : (int) (100.0 * ofs / size);
rprintf(FCLIENT, "\r%15s %3d%% %7.2f%s %s%s",
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",
human_num(ofs), pct, rate, units, rembuf, eol);
if (!is_last) {
output_needs_newline = 1;
rflush(FCLIENT);
}
if (!is_last)
progress_is_active = 1;
}
void set_current_file_index(struct file_struct *file, int ndx)
{
if (!file)
current_file_index = cur_flist->used + cur_flist->ndx_start - 1;
else if (need_unsorted_flist)
if (need_unsorted_flist)
current_file_index = flist_find(cur_flist, file) + cur_flist->ndx_start;
else
current_file_index = ndx;
@@ -149,14 +134,9 @@ void end_progress(OFF_T size)
if (!am_server) {
struct timeval now;
gettimeofday(&now, NULL);
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);
}
rprint_progress(size, size, &now, True);
}
memset(&ph_start, 0, sizeof ph_start);
}
void show_progress(OFF_T ofs, OFF_T size)
@@ -212,9 +192,5 @@ void show_progress(OFF_T ofs, OFF_T size)
return;
#endif
if (INFO_GTE(PROGRESS, 2)) {
rprint_progress(stats.total_transferred_size,
stats.total_size, &now, False);
} else
rprint_progress(ofs, size, &now, False);
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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,12 +20,13 @@
*/
#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;
@@ -45,21 +46,17 @@ 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 filter_rule_list daemon_filter_list;
extern struct filter_list_struct daemon_filter_list;
static struct bitbag *delayed_bits = NULL;
static int phase = 0, redoing = 0;
@@ -69,8 +66,6 @@ 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
*
@@ -84,17 +79,12 @@ 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, BOOL make_unique)
int get_tmpname(char *fnametmp, const char *fname)
{
int maxname, length = 0;
int maxname, added, length = 0;
const char *f;
char *suf;
@@ -113,8 +103,6 @@ int get_tmpname(char *fnametmp, const char *fname, BOOL make_unique)
}
} 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'.
@@ -122,56 +110,26 @@ int get_tmpname(char *fnametmp, const char *fname, BOOL make_unique)
maxname = MIN(MAXPATHLEN - length - TMPNAME_SUFFIX_LEN,
NAME_MAX - 1 - TMPNAME_SUFFIX_LEN);
if (maxname < 0) {
if (maxname < 1) {
rprintf(FERROR_XFER, "temporary filename too long: %s\n", fname);
fnametmp[0] = '\0';
return 0;
}
if (maxname) {
int added = strlcpy(fnametmp + length, f, maxname);
if (added >= maxname)
added = maxname - 1;
suf = fnametmp + length + added;
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)
suf--;
}
/* trim one trailing dot before our suffix's dot */
if (suf[-1] == '.')
/* 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--;
} else
suf = fnametmp + length - 1; /* overwrite the leading dot with suffix's dot */
}
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);
memcpy(suf, TMPNAME_SUFFIX, TMPNAME_SUFFIX_LEN+1);
return 1;
}
@@ -185,7 +143,7 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
int fd;
mode_t added_perms;
if (!get_tmpname(fnametmp, fname, False))
if (!get_tmpname(fnametmp, fname))
return -1;
if (am_root < 0) {
@@ -208,9 +166,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
&& make_path(fnametmp, MKP_SKIP_SLASH | MKP_DROP_NAME) == 0) {
&& create_directory_path(fnametmp) == 0) {
/* Get back to name with XXXXXX in it. */
get_tmpname(fnametmp, fname, False);
get_tmpname(fnametmp, fname);
fd = do_mkstemp(fnametmp, (file->mode|added_perms) & INITACCESSPERMS);
}
#endif
@@ -228,39 +186,24 @@ 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;
int32 len, sum_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 (DEBUG_GTE(DELTASUM, 2)) {
rprintf(FINFO, "recv mapped %s of size %s\n",
fname_r, big_num(size_r));
if (verbose > 2) {
rprintf(FINFO, "recv mapped %s of size %.0f\n",
fname_r, (double)size_r);
}
} else
mapbuf = NULL;
@@ -272,9 +215,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 && mapbuf) {
if (append_mode == 2) {
for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
if (INFO_GTE(PROGRESS, 1))
if (do_progress)
show_progress(offset, total_size);
sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
CHUNK_SIZE);
@@ -282,30 +225,27 @@ 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 (INFO_GTE(PROGRESS, 1))
if (do_progress)
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 %s, not %s",
full_fname(fname), big_num(j), big_num(offset));
rsyserr(FERROR_XFER, errno, "lseek of %s returned %.0f, not %.0f",
full_fname(fname), (double)j, (double)offset);
exit_cleanup(RERR_FILEIO);
}
}
while ((i = recv_token(f_in, &data)) != 0) {
if (INFO_GTE(PROGRESS, 1))
if (do_progress)
show_progress(offset, total_size);
if (allowed_lull)
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH | MSK_ACTIVE_RECEIVER);
if (i > 0) {
if (DEBUG_GTE(DELTASUM, 3)) {
rprintf(FINFO,"data recv %d at %s\n",
i, big_num(offset));
if (verbose > 3) {
rprintf(FINFO,"data recv %d at %.0f\n",
i,(double)offset);
}
stats.literal_data += i;
@@ -327,10 +267,10 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
stats.matched_data += len;
if (DEBUG_GTE(DELTASUM, 3)) {
if (verbose > 3) {
rprintf(FINFO,
"chunk[%d] of size %ld at %s offset=%s%s\n",
i, (long)len, big_num(offset2), big_num(offset),
"chunk[%d] of size %ld at %.0f offset=%.0f%s\n",
i, (long)len, (double)offset2, (double)offset,
updating_basis_or_equiv && offset == offset2 ? " (seek)" : "");
}
@@ -349,9 +289,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 %s, not %s",
"lseek of %s returned %.0f, not %.0f",
full_fname(fname),
big_num(pos), big_num(offset));
(double)pos, (double)offset);
exit_cleanup(RERR_FILEIO);
}
continue;
@@ -366,20 +306,13 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
goto report_write_error;
#ifdef HAVE_FTRUNCATE
/* 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) {
if (inplace && fd != -1 && do_ftruncate(fd, offset) < 0) {
rsyserr(FERROR_XFER, errno, "ftruncate failed on %s",
full_fname(fname));
}
#endif
if (INFO_GTE(PROGRESS, 1))
if (do_progress)
end_progress(total_size);
if (fd != -1 && offset > 0 && sparse_end(fd, offset) != 0) {
@@ -389,16 +322,15 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
exit_cleanup(RERR_FILEIO);
}
if (sum_end(file_sum1) != checksum_len)
overflow_exit("checksum_len"); /* Impossible... */
sum_len = sum_end(file_sum1);
if (mapbuf)
unmap_file(mapbuf);
read_buf(f_in, sender_file_sum, checksum_len);
if (DEBUG_GTE(DELTASUM, 2))
read_buf(f_in, file_sum2, sum_len);
if (verbose > 2)
rprintf(FINFO,"got file_sum\n");
if (fd != -1 && memcmp(file_sum1, sender_file_sum, checksum_len) != 0)
if (fd != -1 && memcmp(file_sum1, file_sum2, sum_len) != 0)
return 0;
return 1;
}
@@ -418,9 +350,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, False))
if (make_backups > 0 && !make_backup(fname))
continue;
if (DEBUG_GTE(RECV, 1)) {
if (verbose > 2) {
rprintf(FINFO, "renaming %s to %s\n",
partialptr, fname);
}
@@ -471,18 +403,16 @@ static int we_want_redo(int desired_ndx)
return 0;
}
static int gen_wants_ndx(int desired_ndx, int flist_num)
static int gen_wants_ndx(int desired_ndx)
{
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;
@@ -510,7 +440,7 @@ static int gen_wants_ndx(int desired_ndx, int flist_num)
* main routine for receiver process.
*
* Receiver process runs on the same host as the generator process. */
int recv_files(int f_in, int f_out, char *local_name)
int recv_files(int f_in, char *local_name)
{
int fd1,fd2;
STRUCT_STAT st;
@@ -522,6 +452,7 @@ int recv_files(int f_in, int f_out, 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;
@@ -531,7 +462,7 @@ int recv_files(int f_in, int f_out, char *local_name)
#endif
int ndx, recv_ok;
if (DEBUG_GTE(RECV, 1))
if (verbose > 2)
rprintf(FINFO, "recv_files(%d) starting\n", cur_flist->used);
if (delay_updates)
@@ -541,32 +472,24 @@ int recv_files(int f_in, int f_out, char *local_name)
cleanup_disable();
/* This call also sets cur_flist. */
ndx = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type,
ndx = read_ndx_and_attrs(f_in, &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) {
ndx = first_flist->used + first_flist->ndx_start;
gen_wants_ndx(ndx, first_flist->flist_num);
}
if (read_batch)
gen_wants_ndx(first_flist->used + first_flist->ndx_start);
flist_free(first_flist);
if (first_flist)
continue;
} else if (read_batch && first_flist) {
ndx = first_flist->used;
gen_wants_ndx(ndx, first_flist->flist_num);
}
} else if (read_batch && first_flist)
gen_wants_ndx(first_flist->used);
if (++phase > max_phase)
break;
if (DEBUG_GTE(RECV, 1))
if (verbose > 2)
rprintf(FINFO, "recv_files phase=%d\n", phase);
if (phase == 2 && delay_updates)
handle_delayed_updates(local_name);
write_int(f_out, NDX_DONE);
send_msg(MSG_DONE, "", 0, 0);
continue;
}
@@ -576,12 +499,11 @@ int recv_files(int f_in, int f_out, char *local_name)
file = dir_flist->files[cur_flist->parent_ndx];
fname = local_name ? local_name : f_name(file, fbuf);
if (DEBUG_GTE(RECV, 1))
if (verbose > 2)
rprintf(FINFO, "recv_files(%s)\n", fname);
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
&& (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
recv_xattr_request(file, f_in);
#endif
@@ -592,21 +514,6 @@ int recv_files(int f_in, int f_out, 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) {
@@ -636,13 +543,11 @@ int recv_files(int f_in, int f_out, char *local_name)
csum_length = SHORT_SUM_LENGTH;
redoing = 0;
}
if (iflags & ITEM_IS_NEW)
stats.created_files++;
}
if (!am_server && INFO_GTE(PROGRESS, 1))
if (!am_server && do_progress)
set_current_file_index(file, ndx);
stats.xferred_files++;
stats.num_transferred_files++;
stats.total_transferred_size += F_LENGTH(file);
cleanup_got_literal = 0;
@@ -656,7 +561,7 @@ int recv_files(int f_in, int f_out, char *local_name)
if (read_batch) {
int wanted = redoing
? we_want_redo(ndx)
: gen_wants_ndx(ndx, cur_flist->flist_num);
: gen_wants_ndx(ndx);
if (!wanted) {
rprintf(FINFO,
"(Skipping batched update for%s \"%s\")\n",
@@ -668,21 +573,16 @@ int recv_files(int f_in, int f_out, char *local_name)
}
}
if (!log_before_transfer)
remember_initial_stats();
if (!do_xfers) { /* log the transfer */
log_item(FCLIENT, file, iflags, NULL);
log_item(FCLIENT, file, &stats, iflags, NULL);
if (read_batch)
discard_receive_data(f_in, F_LENGTH(file));
continue;
}
if (write_batch < 0) {
log_item(FCLIENT, file, iflags, NULL);
log_item(FCLIENT, file, &stats, iflags, NULL);
if (!am_server)
discard_receive_data(f_in, F_LENGTH(file));
if (inc_recurse)
send_msg_int(MSG_SUCCESS, ndx);
continue;
}
@@ -701,26 +601,21 @@ int recv_files(int f_in, int f_out, char *local_name)
break;
case FNAMECMP_FUZZY:
if (file->dirname) {
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, file->dirname, xname);
pathjoin(fnamecmpbuf, MAXPATHLEN,
file->dirname, xname);
fnamecmp = fnamecmpbuf;
} else
fnamecmp = xname;
break;
default:
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) {
if (fnamecmp_type >= basis_dir_cnt) {
rprintf(FERROR,
"invalid basis_dir index: %d.\n",
fnamecmp_type);
exit_cleanup(RERR_PROTOCOL);
} else
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], fname);
}
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
basis_dir[fnamecmp_type], fname);
fnamecmp = fnamecmpbuf;
break;
}
@@ -743,6 +638,8 @@ int recv_files(int f_in, int f_out, char *local_name)
fnamecmp = fname;
}
initial_stats = stats;
/* open the file */
fd1 = do_open(fnamecmp, O_RDONLY, 0);
@@ -819,8 +716,7 @@ int recv_files(int f_in, int f_out, 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)
@@ -838,15 +734,15 @@ int recv_files(int f_in, int f_out, char *local_name)
/* log the transfer */
if (log_before_transfer)
log_item(FCLIENT, file, iflags, NULL);
else if (!am_server && INFO_GTE(NAME, 1) && INFO_EQ(PROGRESS, 1))
log_item(FCLIENT, file, &initial_stats, iflags, NULL);
else if (!am_server && verbose && do_progress)
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, iflags, NULL);
log_item(log_code, file, &initial_stats, iflags, NULL);
if (fd1 != -1)
close(fd1);
@@ -900,7 +796,7 @@ int recv_files(int f_in, int f_out, char *local_name)
break;
case 0: {
enum logcode msgtype = redoing ? FERROR_XFER : FWARNING;
if (msgtype == FERROR_XFER || INFO_GTE(NAME, 1)) {
if (msgtype == FERROR_XFER || verbose) {
char *errstr, *redostr, *keptstr;
if (!(keep_partial && partialptr) && !inplace)
keptstr = "discarded";
@@ -942,7 +838,7 @@ int recv_files(int f_in, int f_out, char *local_name)
if (phase == 2 && delay_updates) /* for protocol_version < 29 */
handle_delayed_updates(local_name);
if (DEBUG_GTE(RECV, 1))
if (verbose > 2)
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-2013 Wayne Davison
* Copyright (C) 2007-2009 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,12 +0,0 @@
#!/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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,6 +27,7 @@
#include <langinfo.h>
#endif
extern int verbose;
extern int dry_run;
extern int preserve_acls;
extern int preserve_xattrs;
@@ -35,18 +36,15 @@ 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;
@@ -84,20 +82,19 @@ void setup_iconv(void)
/* It's OK if this fails... */
ic_chck = iconv_open(defset, defset);
if (DEBUG_GTE(ICONV, 2)) {
if (verbose > 3) {
if (ic_chck == (iconv_t)-1) {
rprintf(FINFO,
"msg checking via isprint()"
" (iconv_open(\"%s\", \"%s\") errno: %d)\n",
"note: iconv_open(\"%s\", \"%s\") failed (%d)"
" -- using isprint() instead of iconv().\n",
defset, defset, errno);
} else {
rprintf(FINFO,
"msg checking charset: %s\n",
defset);
"note: iconv_open(\"%s\", \"%s\") succeeded.\n",
defset, defset);
}
}
} else
ic_chck = (iconv_t)-1;
}
# ifdef ICONV_OPTION
if (!iconv_opt)
@@ -127,82 +124,47 @@ void setup_iconv(void)
exit_cleanup(RERR_UNSUPPORTED);
}
if (DEBUG_GTE(ICONV, 1)) {
rprintf(FINFO, "[%s] charset: %s\n",
who_am_i(), *charset ? charset : "[LOCALE]");
if (verbose > 1) {
rprintf(FINFO, "%s charset: %s\n",
am_server ? "server" : "client",
*charset ? charset : "[LOCALE]");
}
# endif
}
/* 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).
*
/* 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'.
* 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 (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. */
* 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. */
int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags)
{
ICONV_CONST char *ibuf;
size_t icnt, ocnt, opos;
size_t icnt, ocnt;
char *obuf;
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 (!out->size && flags & ICB_EXPAND_OUT)
alloc_xbuf(out, 1024);
if (flags & ICB_INIT)
if (!in->pos)
iconv(ic, NULL, 0, NULL, 0);
ibuf = in->buf + in->pos;
icnt = in->len;
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;
obuf = out->buf + (out->pos + out->len);
ocnt = out->size - (out->pos + out->len) - 1;
while (icnt) {
while (iconv(ic, &ibuf, &icnt, &obuf, &ocnt) == (size_t)-1) {
@@ -211,58 +173,31 @@ 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;
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) {
} else {
size_t opos = obuf - out->buf;
if (!(flags & ICB_EXPAND_OUT)) {
errno = E2BIG;
goto finish;
}
siz = ROUND_UP_1024(in->len * 2);
realloc_xbuf(out, out->size + siz);
realloc_xbuf(out, out->size + 1024);
obuf = out->buf + opos;
ocnt += siz;
ocnt += 1024;
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;
}
@@ -281,7 +216,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 (DEBUG_GTE(CMD, 1))
if (verbose > 1)
print_child_argv("protected args:", args + i + 1);
do {
if (!args[i][0])
@@ -290,7 +225,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_INIT);
ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE);
outbuf.buf[outbuf.len] = '\0';
write_buf(fd, outbuf.buf, outbuf.len + 1);
outbuf.len = 0;
@@ -307,13 +242,13 @@ void send_protected_args(int fd, char *args[])
#endif
}
int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
int read_ndx_and_attrs(int f_in, 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;
int ndx, save_verbose = verbose;
read_loop:
while (1) {
@@ -323,12 +258,6 @@ int read_ndx_and_attrs(int f_in, int f_out, 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)
@@ -342,9 +271,7 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
}
if (ndx == NDX_FLIST_EOF) {
flist_eof = 1;
if (DEBUG_GTE(FLIST, 3))
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
write_int(f_out, NDX_FLIST_EOF);
send_msg(MSG_FLIST_EOF, "", 0, 0);
continue;
}
ndx = NDX_FLIST_OFFSET - ndx;
@@ -358,15 +285,18 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
exit_cleanup(RERR_PROTOCOL);
}
if (DEBUG_GTE(FLIST, 2)) {
/* Send everything read from f_in to msg_fd_out. */
if (verbose > 3) {
rprintf(FINFO, "[%s] receiving flist for dir %d\n",
who_am_i(), ndx);
}
/* Send all the data we read for this flist to the generator. */
start_flist_forward(ndx);
verbose = 0;
send_msg_int(MSG_FLIST, ndx);
start_flist_forward(f_in);
flist = recv_file_list(f_in);
flist->parent_ndx = ndx;
stop_flist_forward();
verbose = save_verbose;
}
iflags = protocol_version >= 29 ? read_shortint(f_in)
@@ -375,19 +305,11 @@ int read_ndx_and_attrs(int f_in, int f_out, 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(time(NULL), MSK_ALLOW_FLUSH);
maybe_send_keepalive();
goto read_loop;
}
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;
}
}
cur_flist = flist_for_ndx(ndx, "read_ndx_and_attrs");
if (iflags & ITEM_BASIS_TYPE_FOLLOWS)
fnamecmp_type = read_byte(f_in);
@@ -469,7 +391,12 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
full_fname(fname));
return 0;
}
init_stat_x(&sx2);
#ifdef SUPPORT_ACLS
sx2.acc_acl = sx2.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
sx2.xattr = NULL;
#endif
sxp = &sx2;
inherit = !preserve_perms;
} else
@@ -502,7 +429,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, F_MOD_NSEC(file), sxp->st.st_mode);
int ret = set_modtime(fname, file->modtime, sxp->st.st_mode);
if (ret < 0) {
rsyserr(FERROR_XFER, errno, "failed to set times on %s",
full_fname(fname));
@@ -523,7 +450,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
} else
#endif
if (change_uid || change_gid) {
if (DEBUG_GTE(OWN, 1)) {
if (verbose > 2) {
if (change_uid) {
rprintf(FINFO,
"set uid of %s from %u to %u\n",
@@ -588,20 +515,27 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
}
#endif
if (INFO_GTE(NAME, 2) && flags & ATTRS_REPORT) {
if (verbose > 1 && flags & ATTRS_REPORT) {
if (updated)
rprintf(FCLIENT, "%s\n", fname);
else
rprintf(FCLIENT, "%s is uptodate\n", fname);
}
cleanup:
if (sxp == &sx2)
free_stat_x(&sx2);
if (sxp == &sx2) {
#ifdef SUPPORT_ACLS
if (preserve_acls)
free_acl(&sx2);
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs)
free_xattr(&sx2);
#endif
}
return updated;
}
/* This is only called for SIGINT, SIGHUP, and SIGTERM. */
RETSIGTYPE sig_int(int sig_num)
RETSIGTYPE sig_int(UNUSED(int val))
{
/* KLUGE: if the user hits Ctrl-C while ssh is prompting
* for a password, then our cleanup's sending of a SIGUSR1
@@ -612,23 +546,6 @@ RETSIGTYPE sig_int(int sig_num)
* 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);
}
@@ -646,17 +563,16 @@ int finish_transfer(const char *fname, const char *fnametmp,
const char *temp_copy_name = partialptr && *partialptr != '/' ? partialptr : NULL;
if (inplace) {
if (DEBUG_GTE(RECV, 1))
if (verbose > 2)
rprintf(FINFO, "finishing %s\n", fname);
fnametmp = fname;
goto do_set_file_attrs;
}
if (make_backups > 0 && overwriting_basis) {
int ok = make_backup(fname, False);
if (!ok)
if (!make_backup(fname))
return 1;
if (ok == 1 && fnamecmp == fname)
if (fnamecmp == fname)
fnamecmp = get_backup_name(fname);
}
@@ -665,15 +581,17 @@ int finish_transfer(const char *fname, const char *fnametmp,
ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
/* move tmp file over real file */
if (DEBUG_GTE(RECV, 1))
if (verbose > 2)
rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
ret = robust_rename(fnametmp, fname, temp_copy_name, file->mode);
ret = robust_rename(fnametmp, fname, temp_copy_name,
file->mode & INITACCESSPERMS);
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) < 0)
|| robust_rename(fnametmp, partialptr, NULL,
file->mode & INITACCESSPERMS) < 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-2013 Wayne Davison
* Copyright (C) 2003-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
@@ -61,7 +61,6 @@
#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. */
@@ -82,7 +81,6 @@
#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. */
@@ -98,7 +96,7 @@
== ((unsigned)(b2) & (unsigned)(mask)))
/* update this if you make incompatible changes */
#define PROTOCOL_VERSION 31
#define PROTOCOL_VERSION 30
/* 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.
@@ -126,8 +124,7 @@
#define OLD_PROTOCOL_VERSION 25
#define MAX_PROTOCOL_VERSION 40
#define MIN_FILECNT_LOOKAHEAD 1000
#define MAX_FILECNT_LOOKAHEAD 10000
#define FILECNT_LOOKAHEAD 1000
#define RSYNC_PORT 873
@@ -135,14 +132,12 @@
#define WRITE_SIZE (32*1024)
#define CHUNK_SIZE (32*1024)
#define MAX_MAP_SIZE (256*1024)
#define IO_BUFFER_SIZE (32*1024)
#define IO_BUFFER_SIZE (4092)
#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)
@@ -236,46 +231,20 @@ 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_STATS=10, /* message has stats data for generator */
MSG_FLIST=20, /* extra file list over sibling socket */
MSG_FLIST_EOF=21,/* we've transmitted all the file lists */
MSG_IO_ERROR=22,/* the sending side had an I/O error */
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_NOOP=42, /* a do-nothing message */
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"
@@ -371,7 +340,7 @@ enum delret {
#include <utime.h>
#endif
#if defined HAVE_UTIMENSAT || defined HAVE_LUTIMES
#if defined HAVE_LUTIMES || defined HAVE_UTIMENSAT
#define CAN_SET_SYMLINK_TIMES 1
#endif
@@ -383,14 +352,6 @@ enum delret {
#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
@@ -612,7 +573,7 @@ struct hashtable {
void *nodes;
int32 size, entries;
uint32 node_size;
short key64;
int key64;
};
struct ht_int32_node {
@@ -673,23 +634,6 @@ 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;
@@ -721,9 +665,7 @@ 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)
@@ -732,11 +674,9 @@ 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, NSEC_BUMP(f))->unum << 32 : 0))
? (int64)OPT_EXTRA(f, 0)->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)
@@ -754,21 +694,22 @@ 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, 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) \
#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) \
+ DIRNODE_EXTRA_CNT - 1)->num) /* sender dirs */
#define F_DIR_RELNAMES_P(f) (&OPT_EXTRA(f, START_BUMP(f) + DIRNODE_EXTRA_CNT \
#define F_DIR_RELNAMES_P(f) (&OPT_EXTRA(f, LEN64_BUMP(f) + DIRNODE_EXTRA_CNT \
+ PTR_EXTRA_CNT - 1)->num) /* sender dirs */
#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) \
#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) \
+ DEV_EXTRA_CNT - 1)->unum) /* receiver dirs */
/* 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)
/* 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)
/* The sum is only present on regular files. */
#define F_SUM(f) ((char*)OPT_EXTRA(f, START_BUMP(f) + HLINK_BUMP(f) \
#define F_SUM(f) ((char*)OPT_EXTRA(f, LEN64_BUMP(f) + HLINK_BUMP(f) \
+ SUM_EXTRA_CNT - 1))
/* Some utility defines: */
@@ -853,45 +794,47 @@ struct map_struct {
int status; /* first errno from read errors */
};
#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 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 FILTRULES_SIDES (FILTRULE_SENDER_SIDE | FILTRULE_RECEIVER_SIDE)
#define MATCHFLGS_FROM_CONTAINER (MATCHFLG_ABS_PATH | MATCHFLG_INCLUDE \
| MATCHFLG_DIRECTORY | MATCHFLG_SENDER_SIDE \
| MATCHFLG_NEGATE | MATCHFLG_RECEIVER_SIDE \
| MATCHFLG_PERISHABLE)
typedef struct filter_struct {
struct filter_struct {
struct filter_struct *next;
char *pattern;
uint32 rflags;
uint32 match_flags;
union {
int slash_cnt;
struct filter_list_struct *mergelist;
} u;
} filter_rule;
};
typedef struct filter_list_struct {
filter_rule *head;
filter_rule *tail;
filter_rule *parent_dirscan_head;
struct filter_list_struct {
struct filter_struct *head;
struct filter_struct *tail;
char *debug_type;
} filter_rule_list;
};
struct stats {
int64 total_size;
@@ -903,10 +846,8 @@ struct stats {
int64 flist_buildtime;
int64 flist_xfertime;
int64 flist_size;
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;
int num_files;
int num_transferred_files;
};
struct chmod_mode_struct;
@@ -941,22 +882,13 @@ 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 = (size_t)-1, (xb).pos = 0
#define INIT_XBUF_STRLEN(xb, str) (xb).buf = (str), (xb).len = strlen((xb).buf), (xb).size = (-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)
@@ -1044,9 +976,6 @@ 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
@@ -1226,53 +1155,7 @@ size_t strlcat(char *d, const char *s, size_t bufsize);
#define FD_ZERO(fdsetp) memset(fdsetp, 0, sizeof (fd_set))
#endif
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)
extern int verbose;
#ifndef HAVE_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
@@ -1282,10 +1165,6 @@ 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

523
rsync.yo
View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsync)(1)(28 Sep 2013)()()
manpage(rsync)(1)(26 Mar 2011)()()
manpagename(rsync)(a fast, versatile, remote (and local) file-copying tool)
manpagesynopsis()
@@ -281,19 +281,6 @@ daemon (including stand-alone and inetd configurations).
If you're using one of the remote-shell transports for the transfer, there is
no need to manually start an rsync daemon.
manpagesection(SORTED TRANSFER ORDER)
Rsync always sorts the specified filenames into its internal transfer list.
This handles the merging together of the contents of identically named
directories, makes it easy to remove duplicate filenames, and may confuse
someone when the files are transferred in a different order than what was
given on the command-line.
If you need a particular file to be transferred prior to another, either
separate the files into different rsync calls, or consider using
bf(--delay-updates) (which doesn't affect the sorted transfer order, but
does make the final file-updating phase happen much more rapidly).
manpagesection(EXAMPLES)
Here are some examples of how I use rsync.
@@ -331,9 +318,6 @@ 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
@@ -354,7 +338,6 @@ 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
@@ -370,11 +353,9 @@ 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
@@ -386,13 +367,11 @@ to the detailed description below for a complete description. verb(
--remove-source-files sender removes synchronized files (non-dir)
--del an alias for --delete-during
--delete delete extraneous files from dest dirs
--delete-before receiver deletes before xfer, not during
--delete-during receiver deletes during the transfer
--delete-before receiver deletes before transfer (default)
--delete-during receiver deletes during xfer, not before
--delete-delay find deletions during, delete after
--delete-after receiver deletes after transfer, not during
--delete-after receiver deletes after transfer, not before
--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
@@ -403,9 +382,6 @@ 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
@@ -434,20 +410,18 @@ 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=RATE limit socket I/O bandwidth
--bwlimit=KBPS limit I/O bandwidth; KBytes per second
--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
@@ -463,9 +437,8 @@ 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=RATE limit socket I/O bandwidth
--bwlimit=KBPS limit I/O bandwidth; KBytes per second
--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
@@ -478,17 +451,11 @@ accepted: verb(
manpageoptions()
Rsync accepts both long (double-dash + word) and short (single-dash + letter)
options. The full list of the available options are described below. If an
option can be specified in more than one way, the choices are comma-separated.
Some options only have a long variant, not a short. If the option takes a
parameter, the parameter is only listed after the long variant, even though it
must also be specified for the short. When specifying a parameter, you can
either use the form --option=param or replace the '=' with whitespace. The
parameter may need to be quoted in some manner for it to survive the shell's
command-line parsing. Keep in mind that a leading tilde (~) in a filename is
substituted by your shell, so --option=~/foo will not change the tilde into
your home directory (remove the '=' for that).
rsync uses the GNU long options package. Many of the command line
options have two variants, one short and one long. These are shown
below, separated by commas. Some options only have a long variant.
The '=' for options that take a parameter is optional; whitespace
can be used instead.
startdit()
dit(bf(--help)) Print a short help page describing the options
@@ -506,67 +473,14 @@ 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.
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.
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.
dit(bf(-q, --quiet)) This option decreases the amount of information you
are given during the transfer, notably suppressing information messages
@@ -905,25 +819,6 @@ 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
@@ -1096,7 +991,7 @@ used by bf(--fake-super)) unless you repeat the option (e.g. -XX). This
"copy all xattrs" mode cannot be used with bf(--fake-super).
dit(bf(--chmod)) This option tells rsync to apply one or more
comma-separated "chmod" modes to the permission of the files in the
comma-separated "chmod" strings to the permission of the files in the
transfer. The resulting value is treated as though it were the permissions
that the sending side supplied for the file, which means that this option
can seem to have no effect on existing files if bf(--perms) is not enabled.
@@ -1111,10 +1006,6 @@ 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.
@@ -1167,9 +1058,6 @@ 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
@@ -1196,16 +1084,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, use the
bf(--remote-option) (bf(-M)) option:
To affect the remote side of a remote-shell connection, specify an rsync
path:
quote(tt( rsync -av -M--fake-super /src/ host:/dest/))
quote(tt( rsync -av --rsync-path="rsync --fake-super" /src/ host:/dest/))
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).
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)).
This option is overridden by both bf(--super) and bf(--no-super).
@@ -1215,17 +1103,6 @@ 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
@@ -1297,19 +1174,6 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending
side the files (meaning non-directories) that are a part of the transfer
and have been successfully duplicated on the receiving side.
Note that you should only use this option on source files that are quiescent.
If you are using this to move files that show up in a particular directory over
to another host, make sure that the finished files get renamed into the source
directory, not directly written into it, so that rsync can't possibly transfer
a file that is not yet fully written. If you can't first write the files into
a different directory, you should use a naming idiom that lets rsync avoid
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
@@ -1393,23 +1257,6 @@ 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.
@@ -1422,17 +1269,15 @@ 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, 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).
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).
Beginning with version 3.0.0, you may specify bf(--max-delete=0) to be warned
Also new for 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
really old versions didn't warn when the limit was exceeded).
older 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
@@ -1454,15 +1299,11 @@ 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.
@@ -1514,36 +1355,6 @@ 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
@@ -1708,20 +1519,6 @@ 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
@@ -1760,10 +1557,6 @@ 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.
@@ -1775,8 +1568,6 @@ 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
@@ -1789,10 +1580,6 @@ 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.
@@ -1830,11 +1617,10 @@ 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
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.
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).
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
@@ -1886,31 +1672,20 @@ 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)
@@ -1935,57 +1710,6 @@ 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.
@@ -2020,13 +1744,6 @@ 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').
@@ -2106,13 +1823,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
either bf(--info=name) or bf(-v) is specified (this tells you just the name
bf(-v) is specified (which reports 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 implies the bf(--info=name) option,
which will mention each file, dir, etc. that gets updated in a significant
Specifying the bf(--out-format) option
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
@@ -2137,7 +1854,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 --remote-option=--log-file=/tmp/rlog src/ dest/)
verb( rsync -av --rsync-path="rsync --log-file=/tmp/rlog" src/ dest/)
This is very useful if you need to debug why a connection is closing
unexpectedly.
@@ -2154,29 +1871,14 @@ 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. 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.
algorithm is for your data.
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. 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.
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.
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.
@@ -2215,25 +1917,10 @@ 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.
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.
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.
dit(bf(--partial)) By default, rsync will delete any partially
transferred file if the transfer is interrupted. In some circumstances
@@ -2362,9 +2049,7 @@ 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.
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").
Implies bf(--verbose) if it wasn't already specified.
While rsync is transferring a regular file, it updates a progress line that
looks like this:
@@ -2386,41 +2071,23 @@ 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( 1,238,099 100% 146.38kB/s 0:00:08 (xfr#5, to-chk=169/396))
verb( 1238099 100% 146.38kB/s 0:00:08 (xfer#5, to-check=169/396))
In this example, the file was 1,238,099 bytes long in total, the average rate
In this example, the file was 1238099 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.
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.
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).
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.
@@ -2441,14 +2108,6 @@ 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)
@@ -2457,27 +2116,13 @@ 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=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(--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(--write-batch=FILE)) Record a file that can later be applied to
another identical destination with bf(--read-batch). See the "BATCH MODE"
@@ -2552,15 +2197,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 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.
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.
enddit()
manpagesection(DAEMON OPTIONS)
@@ -2585,10 +2230,11 @@ 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=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(--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(--config=FILE)) This specifies an alternate config file than
the default. This is only relevant when bf(--daemon) is specified.
@@ -2596,14 +2242,6 @@ 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
@@ -3314,9 +2952,6 @@ 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.
@@ -3361,7 +2996,7 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
manpagesection(VERSION)
This man page is current for version 3.1.0 of rsync.
This man page is current for version 3.0.8 of rsync.
manpagesection(INTERNAL OPTIONS)
@@ -3375,7 +3010,7 @@ ssh login.
manpagesection(CREDITS)
rsync is distributed under the GNU General Public License. See the file
rsync is distributed under the GNU 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)(28 Sep 2013)()()
manpage(rsyncd.conf)(5)(26 Mar 2011)()()
manpagename(rsyncd.conf)(configuration file for rsync in daemon mode)
manpagesynopsis()
@@ -28,9 +28,8 @@ 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 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 beginning with a hash (#) is ignored, as are lines containing
only whitespace.
Any line ending in a \ is "continued" on the next line in the
customary UNIX fashion.
@@ -79,31 +78,15 @@ 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
@@ -121,9 +104,6 @@ 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)
@@ -137,9 +117,6 @@ 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
@@ -150,19 +127,6 @@ 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
fix), append a trailing slash to the path to avoid losing the trailing
whitespace.
dit(bf(use chroot)) If "use chroot" is true, the rsync daemon will chroot
to the "path" before starting the file transfer with the client. This has
the advantage of extra protection against possible implementation security
@@ -227,9 +191,8 @@ 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 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
all incoming symlinks in a way that makes them unusable but recoverable
(see 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.
@@ -297,12 +260,6 @@ 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
@@ -330,46 +287,27 @@ 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 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(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(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 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.
file permissions are available. The default is uid -2, which is normally
the user "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(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".
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
@@ -444,12 +382,10 @@ 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/or space-separated
list of authorization rules. In its simplest form, you list the usernames
that will be allowed to connect to
dit(bf(auth users)) This parameter specifies a comma and
space-separated list of usernames that will be allowed to connect to
this module. The usernames do not need to exist on the local
system. The rules may contain shell wildcard characters that will be matched
against the username provided by the client for authentication. If
system. The usernames may also contain shell wildcard characters. 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
@@ -457,65 +393,24 @@ 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 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.
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.
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". If the file is not found or is rejected, no
logins for a "user auth" module will be possible.
by "other"; see "strict modes".
dit(bf(strict modes)) This parameter determines whether or not
the permissions on the secrets file will be checked. If "strict modes" is
@@ -542,14 +437,12 @@ 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 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.
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.
))
Note IPv6 link-local addresses can have a scope in the address specification:
@@ -577,23 +470,6 @@ 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
@@ -620,11 +496,6 @@ 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.
@@ -635,14 +506,13 @@ rsyncstats.)
The single-character escapes that are understood are as follows:
quote(itemization(
it() %a the remote IP address (only available for a daemon)
it() %a the remote IP address
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 (only available for a daemon)
it() %h the remote host name
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)
@@ -713,12 +583,7 @@ 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. 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).
transfer is aborted before it begins.
The following environment variables will be set, though some are
specific to the pre-xfer or the post-xfer environment:
@@ -731,14 +596,11 @@ 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", 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.
in these numbered values. RSYNC_ARG0 is always "rsyncd", and the last
value contains a single period.
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
@@ -753,62 +615,6 @@ 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
@@ -894,11 +700,11 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
manpagesection(VERSION)
This man page is current for version 3.1.0 of rsync.
This man page is current for version 3.0.8 of rsync.
manpagesection(CREDITS)
rsync is distributed under the GNU General Public License. See the file
rsync is distributed under the GNU public license. See the file
COPYING for details.
The primary ftp site for rsync is

View File

@@ -129,10 +129,7 @@ RUNSHFLAGS='-e'
export RUNSHFLAGS
# for Solaris
if [ -d /usr/xpg4/bin ]; then
PATH="/usr/xpg4/bin/:$PATH"
export PATH
fi
[ -d /usr/xpg4/bin ] && PATH="/usr/xpg4/bin/:$PATH"
if [ "x$loglevel" != x ] && [ "$loglevel" -gt 8 ]; then
if set -x; then
@@ -232,9 +229,8 @@ echo " scratchbase=$scratchbase"
[ -d "$scratchbase" ] || mkdir "$scratchbase"
suitedir="$srcdir/testsuite"
TESTRUN_TIMEOUT=300
export scratchdir suitedir TESTRUN_TIMEOUT
export scratchdir suitedir
prep_scratch() {
[ -d "$scratchdir" ] && chmod -R u+rwX "$scratchdir" && rm -rf "$scratchdir"
@@ -265,13 +261,8 @@ do
prep_scratch
case "$testscript" in
*hardlinks*) TESTRUN_TIMEOUT=600 ;;
*) TESTRUN_TIMEOUT=300 ;;
esac
set +e
"$TOOLDIR/"testrun $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1
sh $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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,22 +32,19 @@ 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
*
@@ -63,7 +60,7 @@ static struct sum_struct *receive_sums(int f)
{
struct sum_struct *s;
int32 i;
int lull_mod = protocol_version >= 31 ? 0 : allowed_lull * 5;
int lull_mod = allowed_lull * 5;
OFF_T offset = 0;
if (!(s = new(struct sum_struct)))
@@ -73,9 +70,9 @@ static struct sum_struct *receive_sums(int f)
s->sums = NULL;
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 (verbose > 3) {
rprintf(FINFO, "count=%.0f n=%ld rem=%ld\n",
(double)s->count, (long)s->blength, (long)s->remainder);
}
if (append_mode > 0) {
@@ -104,13 +101,13 @@ static struct sum_struct *receive_sums(int f)
s->sums[i].len = s->blength;
offset += s->sums[i].len;
if (lull_mod && !(i % lull_mod))
maybe_send_keepalive(time(NULL), True);
if (allowed_lull && !(i % lull_mod))
maybe_send_keepalive();
if (DEBUG_GTE(DELTASUM, 3)) {
if (verbose > 3) {
rprintf(FINFO,
"chunk[%d] len=%d offset=%s sum1=%08x\n",
i, s->sums[i].len, big_num(s->sums[i].offset),
"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
i, s->sums[i].len, (double)s->sums[i].offset,
s->sums[i].sum1);
}
}
@@ -123,10 +120,8 @@ 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;
@@ -137,31 +132,11 @@ void successful_send(int ndx)
return;
f_name(file, fname);
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))
if (do_unlink(fname) == 0) {
if (verbose > 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,
@@ -177,8 +152,7 @@ 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
&& (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
send_xattr_request(fname, file, f_out);
#endif
}
@@ -195,51 +169,41 @@ 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 (DEBUG_GTE(SEND, 1))
if (verbose > 2)
rprintf(FINFO, "send_files starting\n");
while (1) {
if (inc_recurse) {
send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
extra_flist_sending_enabled = !flist_eof;
}
if (inc_recurse)
send_extra_file_list(f_out, FILECNT_LOOKAHEAD);
/* This call also sets cur_flist. */
ndx = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type,
ndx = read_ndx_and_attrs(f_in, &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 (DEBUG_GTE(SEND, 1))
if (verbose > 2)
rprintf(FINFO, "send_files phase=%d\n", phase);
write_ndx(f_out, NDX_DONE);
continue;
}
if (inc_recurse)
send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
send_extra_file_list(f_out, FILECNT_LOOKAHEAD);
if (ndx - cur_flist->ndx_start >= 0)
file = cur_flist->files[ndx - cur_flist->ndx_start];
@@ -255,12 +219,11 @@ void send_files(int f_in, int f_out)
continue;
f_name(file, fname);
if (DEBUG_GTE(SEND, 1))
if (verbose > 2)
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
&& (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
recv_xattr_request(file, f_in);
#endif
@@ -268,21 +231,6 @@ 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) {
@@ -306,28 +254,25 @@ 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 && INFO_GTE(PROGRESS, 1))
if (!am_server && do_progress)
set_current_file_index(file, ndx);
stats.xferred_files++;
stats.num_transferred_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, iflags, NULL);
log_item(FCLIENT, file, &stats, 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");
@@ -361,7 +306,7 @@ void send_files(int f_in, int f_out)
rsyserr(FERROR_XFER, errno, "fstat failed");
free_sums(s);
close(fd);
exit_cleanup(RERR_FILEIO);
exit_cleanup(RERR_PROTOCOL);
}
if (st.st_size) {
@@ -370,30 +315,30 @@ void send_files(int f_in, int f_out)
} else
mbuf = NULL;
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));
if (verbose > 2) {
rprintf(FINFO, "send_files mapped %s%s%s of size %.0f\n",
path,slash,fname, (double)st.st_size);
}
write_ndx_and_attrs(f_out, ndx, iflags, fname, file,
fnamecmp_type, xname, xlen);
write_sum_head(f_xfer, s);
if (DEBUG_GTE(DELTASUM, 2))
if (verbose > 2)
rprintf(FINFO, "calling match_sums %s%s%s\n", path,slash,fname);
if (log_before_transfer)
log_item(FCLIENT, file, iflags, NULL);
else if (!am_server && INFO_GTE(NAME, 1) && INFO_EQ(PROGRESS, 1))
log_item(FCLIENT, file, &initial_stats, iflags, NULL);
else if (!am_server && verbose && do_progress)
rprintf(FCLIENT, "%s\n", fname);
set_compression(fname);
match_sums(f_xfer, s, mbuf, st.st_size);
if (INFO_GTE(PROGRESS, 1))
if (do_progress)
end_progress(st.st_size);
log_item(log_code, file, iflags, NULL);
log_item(log_code, file, &initial_stats, iflags, NULL);
if (mbuf) {
j = unmap_file(mbuf);
@@ -408,7 +353,7 @@ void send_files(int f_in, int f_out)
free_sums(s);
if (DEBUG_GTE(SEND, 1))
if (verbose > 2)
rprintf(FINFO, "sender finished %s%s%s\n", path,slash,fname);
/* Flag that we actually sent this entry. */
@@ -420,7 +365,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 (DEBUG_GTE(SEND, 1))
if (verbose > 2)
rprintf(FINFO, "send files finished\n");
match_report();

View File

@@ -8,8 +8,5 @@
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 HOST_OS SHELL_PATH FAKEROOT_PATH
export ECHO_T ECHO_N ECHO_C

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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,13 +25,9 @@
* emulate it using the KAME implementation. */
#include "rsync.h"
#include "itypes.h"
#ifdef HAVE_NETINET_IN_SYSTM_H
#include "ifuncs.h"
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#include <netinet/tcp.h>
extern char *bind_address;
@@ -229,7 +225,7 @@ int open_socket_out(char *host, int port, const char *bind_addr,
}
*cp++ = '\0';
strlcpy(portbuf, cp, sizeof portbuf);
if (DEBUG_GTE(CONNECT, 1)) {
if (verbose >= 2) {
rprintf(FINFO, "connection via http proxy %s port %s\n",
h, portbuf);
}
@@ -301,29 +297,22 @@ int open_socket_out(char *host, int port, const char *bind_addr,
s = -1;
continue;
}
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));
rprintf(FINFO, "Connected to %s (%s)\n", h, buf);
}
break;
}
freeaddrinfo(res0);
if (s < 0 || DEBUG_GTE(CONNECT, 2)) {
if (s < 0) {
char buf[2048];
for (res = res0, j = 0; res; res = res->ai_next, j++) {
if (errnos[j] == 0)
continue;
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));
if (inet_ntop(res->ai_family, res->ai_addr->sa_data + 2, buf, sizeof buf) == NULL)
strlcpy(buf, "*inet_ntop failed*", sizeof buf);
rsyserr(FERROR, errnos[j], "failed to connect to %s (%s)", h, buf);
}
if (s < 0)
s = -1;
s = -1;
}
freeaddrinfo(res0);
free(errnos);
return s;
@@ -381,7 +370,7 @@ int open_socket_out_wrapped(char *host, int port, const char *bind_addr,
*t = '\0';
}
if (DEBUG_GTE(CONNECT, 1)) {
if (verbose >= 2) {
rprintf(FINFO, "%sopening tcp connection to %s port %d\n",
prog ? "Using RSYNC_CONNECT_PROG instead of " : "",
host, port);
@@ -489,7 +478,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 || DEBUG_GTE(BIND, 1))
if (!i || verbose > 1)
rwrite(FLOG, errmsgs[s], strlen(errmsgs[s]), 0);
free(errmsgs[s]);
}
@@ -557,7 +546,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], lp_listen_backlog()) < 0) {
if (listen(sp[i], 5) < 0) {
rsyserr(FERROR, errno, "listen() on socket failed");
#ifdef INET6
if (errno == EADDRINUSE && i > 0) {
@@ -646,9 +635,7 @@ struct
} socket_options[] = {
{"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
{"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
#ifdef SO_BROADCAST
{"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
#endif
#ifdef TCP_NODELAY
{"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
#endif
@@ -831,7 +818,7 @@ static int sock_exec(const char *prog)
rsyserr(FERROR, errno, "socketpair_tcp failed");
return -1;
}
if (DEBUG_GTE(CMD, 1))
if (verbose >= 2)
rprintf(FINFO, "Running socket program: \"%s\"\n", prog);
pid = fork();

View File

@@ -1,52 +0,0 @@
#!/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

View File

@@ -1,30 +0,0 @@
# 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,6 +1,5 @@
#!/usr/bin/perl
#!/usr/bin/perl -w
use strict;
use warnings;
# Sets mtime and atime of files to the latest commit time in git.
#

View File

@@ -1,126 +0,0 @@
#!/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,81 +1,35 @@
#!/usr/bin/perl
#!/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 -l USER, we try to become the USER, either directly (must
# be root) or by using "sudo -H -u USER" (requires --sudo option).
# we get a -l USER option, we try to use "sudo -u USER" to run the
# command.
use strict;
use warnings;
use Getopt::Long;
use English '-no_match_vars';
user=''
prefix=''
do_cd=y # Default path is user's home dir, just like ssh.
&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;
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
my $host = shift;
if ($host =~ s/^([^@]+)\@//) {
$login_name = $1;
}
if ($host ne 'localhost') {
die "lsh: unable to connect to host $host\n";
}
if [ "$user" ]; then
prefix="sudo -H -u '$user'"
if [ $do_cd = y ]; then
home=`perl -e "print((getpwnam('$user'))[7])"`
# Yeah, this may fail, but attempts to get sudo to cd are harder.
cd $home
fi
elif [ $do_cd = y ]; then
cd
fi
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
}
eval $prefix "${@}"

View File

@@ -1,35 +0,0 @@
#!/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

View File

@@ -1,15 +0,0 @@
#!/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";

View File

@@ -1,15 +0,0 @@
#!/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

@@ -18,7 +18,7 @@
# easily adapted to read /etc/mtab or similar.
#
# ADDENDUM: The addition of the --filter option (which has support for
# absolute-anchored excludes) can make this script unneeded in some
# absolute-anchored excludes) can make this screen unneeded in some
# scenarios. If you don't need delete protection on the receiving side
# (or if the destination path is identical to the source path), then you
# can exclude some absolute paths from the transfer based on the mount

View File

@@ -74,18 +74,15 @@ 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,
@@ -117,7 +114,6 @@ our %long_opt = (
'temp-dir' => 2,
'timeout' => 1,
'use-qsort' => 0,
'usermap' => 1,
);
### END of options data produced by the cull_options script. ###

View File

@@ -1,17 +0,0 @@
#!/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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,13 +29,8 @@
#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;
@@ -58,55 +53,13 @@ int do_unlink(const char *fname)
return unlink(fname);
}
#ifdef SUPPORT_LINKS
int do_symlink(const char *lnk, const char *fname)
int do_symlink(const char *fname1, const char *fname2)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
#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);
return symlink(fname1, fname2);
}
#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)
{
@@ -421,71 +374,3 @@ 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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,18 +22,16 @@
#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;
filter_rule_list daemon_filter_list;
struct filter_list_struct daemon_filter_list;
void rprintf(UNUSED(enum logcode code), const char *format, ...)
{
@@ -60,7 +58,7 @@ filter_rule_list daemon_filter_list;
exit(code);
}
int check_filter(UNUSED(filter_rule_list *listp), UNUSED(enum logcode code),
int check_filter(UNUSED(struct filter_list_struct *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
@@ -68,19 +66,14 @@ filter_rule_list daemon_filter_list;
return 0;
}
int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest))
int make_bak_dir(UNUSED(const char *fullpath))
{
return -1;
}
void free_xattr(UNUSED(stat_x *sxp))
int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest))
{
return;
}
void free_acl(UNUSED(stat_x *sxp))
{
return;
return -1;
}
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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,13 +25,11 @@
int dry_run = 0;
int am_root = 0;
int am_sender = 1;
int read_only = 0;
int list_only = 0;
int human_readable = 0;
int verbose = 0;
int preserve_perms = 0;
int preserve_executability = 0;
short info_levels[COUNT_INFO], debug_levels[COUNT_DEBUG];
int
main(int argc, char **argv)

View File

@@ -1,61 +0,0 @@
/* 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,14 +1,5 @@
#! /bin/sh
test_fail() {
echo "$@" >&2
exit 1
}
echo $0 running
$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'
$RSYNC --version || exit 1

View File

@@ -5,7 +5,7 @@
# Test that rsync handles basic ACL preservation.
. $suitedir/rsync.fns
. $srcdir/testsuite/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/dname"
makepath "$fromdir/deep" "$bakdir"
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 -ai --info=backup '$fromdir/' '$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -avv '$fromdir/' '$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -ai --info=backup '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
checkit "$RSYNC -avv '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
cat "$srcdir"/[fgpr]*.[ch] > "$name1"
cat "$srcdir"/[etw]*.[ch] > "$name2"
$RSYNC -ai --info=backup --no-whole-file --backup "$fromdir/" "$todir/" \
$RSYNC -avv --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 -ai --info=backup --no-whole-file --delete-delay \
checkit "$RSYNC -avv --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 -ai --info=backup --del '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
checkit "$RSYNC -avv --del '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
cat "$srcdir"/[efgr]*.[ch] > "$name1"
cat "$srcdir"/[ew]*.[ch] > "$name2"
checkit "$RSYNC -ai --info=backup --inplace --no-whole-file --backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \
checkit "$RSYNC -avv --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 -ai --info=backup --inplace --no-whole-file '$fromdir/' '$bakdir/'" "$fromdir" "$bakdir"
checkit "$RSYNC -avv --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.
. $suitedir/rsync.fns
. $srcdir/testsuite/rsync.fns
# Build some files

View File

@@ -18,25 +18,14 @@ 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 "$HOST_OS" in
darwin*)
case "`xattr 2>&1`" in
*--list:*)
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
@@ -51,9 +40,9 @@ EOF
case `get_testuid` in
'') ;; # If "id" failed, try to continue...
0) ;;
*) if [ -e "$FAKEROOT_PATH" ]; then
*) if [ -f /usr/bin/fakeroot ]; then
echo "Let's try re-running the script under fakeroot..."
exec "$FAKEROOT_PATH" "$SHELL_PATH" "$0"
exec /usr/bin/fakeroot /bin/sh "$0"
fi
;;
esac

View File

@@ -24,9 +24,9 @@
chkfile="$scratchdir/rsync.chk"
outfile="$scratchdir/rsync.out"
SSH="src/support/lsh.sh --no-cd"
SSH="src/support/lsh --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,22 +50,19 @@ 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
. $suitedir/rsync.fns
. $srcdir/testsuite/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 "$HOST_OS" in
darwin*)
case "`xattr 2>&1`" in
*--list:*)
mknod() {
fn="$1"
case "$2" in
@@ -34,22 +34,6 @@ 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"
@@ -70,9 +54,9 @@ EOF
case `get_testuid` in
'') ;; # If "id" failed, try to continue...
0) ;;
*) if [ -e "$FAKEROOT_PATH" ]; then
*) if [ -f /usr/bin/fakeroot ]; then
echo "Let's try re-running the script under fakeroot..."
exec "$FAKEROOT_PATH" "$SHELL_PATH" $RUNSHFLAGS "$0"
exec /usr/bin/fakeroot /bin/sh $RUNSHFLAGS "$0"
fi
test_skipped "Rsync needs root/fakeroot for device tests"
;;
@@ -90,7 +74,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/block3.5" || echo "Skipping hard-linked device test..."
ln "$fromdir/block3" "$fromdir/block2.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"
@@ -126,14 +110,14 @@ cat <<EOT >"$chkfile"
cDc.t.$dots block
cDc...$dots block2
cD$all_plus block3
hD$all_plus block3.5 => block3
hD$all_plus block2.5 => block3
cD$all_plus char
cD$all_plus char2
cD$all_plus char3
cS$all_plus fifo
EOT
if test ! -r "$fromdir/block3.5"; then
grep -v block3.5 <"$chkfile" >"$chkfile.new"
if test ! -r "$fromdir/block2.5"; then
grep -v block2.5 <"$chkfile" >"$chkfile.new"
mv "$chkfile.new" "$chkfile"
fi
diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
@@ -144,7 +128,7 @@ echo ""
( cd "$todir" && rsync_ls_lR . ) > "$tmpdir/ls-to"
diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to"
if test -r "$fromdir/block3.5"; then
if test -r "$fromdir/block2.5"; then
set -x
$RSYNC -aii --link-dest="$todir" "$fromdir/" "$chkdir/" \
| tee "$outfile"
@@ -152,8 +136,8 @@ if test -r "$fromdir/block3.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
. $suitedir/rsync.fns
. $srcdir/testsuite/rsync.fns
umask 077
@@ -26,7 +26,7 @@ testit() {
echo "File!" >"$scratchdir/file"
echo "#!/bin/sh" >"$scratchdir/program"
mkdir "$scratchdir/dir"
chmod u=rwx,g=rw,g+s,o=r "$scratchdir/dir" || test_skipped "Can't chmod"
chmod 2764 "$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 u=rwx,g=rw,g+s,o-rwx rw------- rwx------ rwx--S---
testit setgid-on 2700 rw------- rwx------ rwx--S---
# Hooray
exit 0

View File

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

View File

@@ -9,8 +9,6 @@
. "$suitedir/rsync.fns"
SSH="$scratchdir/src/support/lsh.sh"
hands_setup
# This list of files skips the contents of "subsubdir" but includes
@@ -28,18 +26,5 @@ $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,23 +9,21 @@
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 $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
runtest "hard links" 'checkit "$RSYNC -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
rm "$todir/text"
runtest "one file" 'checkit "$RSYNC -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
runtest "one file" 'checkit "$RSYNC -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
echo "extra line" >> "$todir/text"
runtest "extra data" 'checkit "$RSYNC -avH $DEBUG_OPTS --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
runtest "extra data" 'checkit "$RSYNC -avH --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
cp "$fromdir/text" "$todir/ThisShouldGo"
runtest " --delete" 'checkit "$RSYNC --delete -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
runtest " --delete" 'checkit "$RSYNC --delete -avH \"$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.sh"
SSH="$scratchdir/src/support/lsh"
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 --debug=HLINK5 '$fromdir/' '$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -aHivv '$fromdir/' '$todir/'" "$fromdir" "$todir"
echo "extra extra" >>"$todir/name1"
checkit "$RSYNC -aHivv --debug=HLINK5 --no-whole-file '$fromdir/' '$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -aHivv --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' --debug=HLINK5 --rsync-path='$RSYNC' '$fromdir/' localhost:'$todir/'" "$fromdir" "$todir"
checkit "$RSYNC -aHivve '$SSH' --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 --debug=HLINK5 --link-dest='$todir' '$fromdir/' '$chkdir/'" "$todir" "$chkdir"
checkit "$RSYNC -aHivv --link-dest='$todir' '$fromdir/' '$chkdir/'" "$todir" "$chkdir"
rm -rf "$chkdir"
checkit "$RSYNC -aHivv --debug=HLINK5 --copy-dest='$todir' '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
checkit "$RSYNC -aHivv --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 --debug=HLINK5 "$fromdir/" "$chkdir/" | tee "$outfile"
$RSYNC -aHivc "$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 --debug=HLINK5 "$name1" "$todir/"
$RSYNC -aHivv "$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/sym $is_uptodate
foo/extra => foo/config1
foo/sym $is_uptodate
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.
. $suitedir/rsync.fns
. $srcdir/testsuite/rsync.fns
makepath "$fromdir/subdir" "$todir"
echo data >"$fromdir/subdir/file"

View File

@@ -17,6 +17,7 @@
# 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"
@@ -31,7 +32,7 @@ tab_ch=' ' # a single tab character
# Berkley's nice.
PATH="$PATH:/usr/ucb"
if diff -u "$suitedir/rsync.fns" "$suitedir/rsync.fns" >/dev/null 2>&1; then
if diff -u "$srcdir/testsuite/rsync.fns" "$srcdir/testsuite/rsync.fns" >/dev/null 2>&1; then
diffopt="-u"
else
diffopt="-c"
@@ -262,17 +263,6 @@ 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
@@ -284,9 +274,9 @@ log file = $logfile
log format = %i %h [%a] %m (%u) %l %f%L
transfer logging = yes
exclude = ? foobar.baz
max verbosity = 4
$uid_setting
$gid_setting
max verbosity = 9
uid = 0
gid = 0
[test-from]
path = $fromdir

View File

@@ -10,7 +10,7 @@
. "$suitedir/rsync.fns"
SSH="$scratchdir/src/support/lsh.sh"
SSH="$scratchdir/src/support/lsh"
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.
. $suitedir/rsync.fns
. $srcdir/testsuite/rsync.fns
lnkdir="$tmpdir/lnk"
$RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync is configured without xattr support"
case "$HOST_OS" in
darwin*)
case "`xattr 2>&1`" in
*--list:*)
xset() {
xnam="$1"
xval="$2"
@@ -24,27 +24,6 @@ darwin*)
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-2013 Wayne Davison
* Copyright (C) 2003-2009 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,12 +43,10 @@
/* 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;
@@ -148,9 +146,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 = do_readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
len = readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
if (len == -1)
failed("do_readlink", fname);
failed("readlink", fname);
else
/* it's not nul-terminated */
linkbuf[4+len] = 0;
@@ -161,10 +159,9 @@ static void list_file(const char *fname)
permstring(permbuf, buf.st_mode);
if (buf.st_mtime) {
int len;
mt = gmtime(&buf.st_mtime);
len = snprintf(datebuf, sizeof datebuf,
snprintf(datebuf, sizeof datebuf,
"%04d-%02d-%02d %02d:%02d:%02d",
(int)mt->tm_year + 1900,
(int)mt->tm_mon + 1,
@@ -172,17 +169,8 @@ static void list_file(const char *fname)
(int)mt->tm_hour,
(int)mt->tm_min,
(int)mt->tm_sec);
#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';
}
} else
strlcpy(datebuf, " ", sizeof datebuf);
/* TODO: Perhaps escape special characters in fname? */
@@ -191,8 +179,8 @@ static void list_file(const char *fname)
printf("%5ld,%6ld",
(long)major(buf.st_rdev),
(long)minor(buf.st_rdev));
} else
printf("%15s", do_big_num(buf.st_size, 1, NULL));
} else /* NB: use double for size since it might not fit in a long. */
printf("%12.0f", (double)buf.st_size);
printf(" %6ld.%-6ld %6ld %s %s%s\n",
(long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
datebuf, fname, linkbuf);
@@ -204,9 +192,6 @@ 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}

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