Compare commits

..

218 Commits

Author SHA1 Message Date
Martin Pool
23212669ac Bump version to 2.5.3pre1 2002-02-19 02:16:37 +00:00
Martin Pool
3ce0f9a653 Clean up error message 2002-02-19 01:41:20 +00:00
Martin Pool
d834adc14f Doc 2002-02-19 01:39:11 +00:00
Martin Pool
b84ba8967a rsync prefix on mkdir and pushdir error messages. 2002-02-19 01:07:24 +00:00
Martin Pool
79845f2834 Doc. 2002-02-18 23:36:10 +00:00
Martin Pool
78ece130a4 Change shell syntax to try to please Solaris 2002-02-18 23:09:50 +00:00
Martin Pool
bd37c66630 Fix error handling for failing to fork after accepting a connection --
close fd, sleep, then try again.
2002-02-18 22:58:49 +00:00
Martin Pool
371d1c36b3 Solaris does not have diff -u. 2002-02-18 22:55:21 +00:00
Martin Pool
d0f821ad3d Must use STRUCT_STAT not "struct stat" to be compatible with other
rsync functions.
2002-02-18 22:49:00 +00:00
Martin Pool
ded8347d6b Cope with BSD systems on which mkdir() will not accept a trailing
slash.

<http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html>
2002-02-18 22:44:23 +00:00
Martin Pool
c4a5c57dc3 If the daemon is unable to fork a child to accept a connection, print
an error message.  (Colin Walters)
2002-02-18 22:38:03 +00:00
Martin Pool
404e813c52 Add -vvv trace statement to set_modtime to help with Debian bug
#100295.
2002-02-18 22:25:55 +00:00
Martin Pool
90d0a8db38 This test must specify --times because it compares listings that
include mtimes.
2002-02-18 22:14:46 +00:00
Martin Pool
956ff9ff72 Fix bug that made tls.o not be removed by 'make clean'. 2002-02-18 22:07:44 +00:00
Martin Pool
1eca49c6ed Doc:
#defiine lchown chown

could be bad on systems which have no lchown and where chown
follows symbollic links.  On such systems it might be better not to
try to chown symlinks at all.
2002-02-18 21:46:49 +00:00
Martin Pool
34758d5c15 Ignore SIGPIPE and allow EPIPE to get through to the program so that
we don't get stuck in a recursive loop trying to report a broken pipe
across that same broken pipe.  Debian bug #128632 (Colin Walters)
2002-02-18 20:06:57 +00:00
Martin Pool
befbfe6115 Fix for rsync server processes hanging around after the client
unexpectedly disconnects.  (Colin Walters) (Debian bug #128632)
2002-02-18 19:54:00 +00:00
Martin Pool
900748fca1 rwrite: Doc. 2002-02-18 19:51:12 +00:00
Martin Pool
87ee248169 Document multiplex stuff. 2002-02-18 19:44:04 +00:00
Martin Pool
bb7c4fa361 Doc. 2002-02-18 19:10:28 +00:00
David Dykstra
c613d37048 If a daemon prints an error message of @ERROR, have the client treat the
message as an FERROR rather than an FINFO.
2002-02-18 18:29:48 +00:00
David Dykstra
d52a22e4db Add item about fixing "out of memory in flist_expand" on Sunos4. 2002-02-14 15:27:55 +00:00
David Dykstra
6dfb45bcdf Added the two most important bug fixes to NEWS to make sure they're not
forgotten for the next release.
2002-02-13 18:57:06 +00:00
David Dykstra
145794936f Patch from Jos Backus <josb@cncdsl.com> to use HAVE_SOCKADDR_LEN rather
than HAVE_SOCK_SIN_LEN around use of sin_len.  Correct usage was already
in place in clientname.c.
2002-02-13 18:45:17 +00:00
David Dykstra
301c680fd7 Suggested patch from Jim Ogilvie <jogilvie@us.ibm.com> to print out the
system error message when mkstemp fails.
2002-02-13 18:42:20 +00:00
David Dykstra
d27cbec598 Reversing the order of maybe_emit_filelist_progress() and
emit_filelist_progress() makes the native compilers on systems
including Solaris and Irix happier.
2002-02-13 18:30:27 +00:00
David Dykstra
f5be54d6ab Some systems, notably Sunos4, do not support realloc(NULL, n), so if
nothing has yet been malloced in flist_expand(), call malloc instead of
realloc.  Problem introduced in revision 1.106 of flist.c on January 25.
2002-02-13 18:06:36 +00:00
Martin Pool
1e19f7ba5f At least change INO64_T and DEV64_T back to just 'int64', not
'unsigned int64'.  This should fix some compile problems on machines
where int64 is not a simple integer type, but I'm not convinced it is
the ideal fix.
2002-02-13 02:57:55 +00:00
Martin Pool
db719fb0d7 Factor out code for filelist progress. Copy&paste considered harmful.
Add a little doc about potential optimization of stat() calls.
2002-02-13 02:44:31 +00:00
Martin Pool
b0d4f4c10e Add a test that --owner correctly propagates ownership of files for a
local transfer as root.
2002-02-09 07:43:13 +00:00
Martin Pool
238d23d775 Add a test that --group correctly propagates groups of which the local
user is a member.
2002-02-09 07:42:37 +00:00
Martin Pool
c019068f06 Add $preserve_scratch and $always_log so if you want to see details
about successful tests, you can.
2002-02-09 03:36:33 +00:00
Martin Pool
715d1f4504 Oops -- have to call setgroups() before giving up root.
Doc some of the peculiarities about starting rsyncd as root vs
non-root.
2002-02-09 03:30:22 +00:00
Martin Pool
4f092bee9f Make sure we call setgroups() after setuid(). (Ethan Benson) 2002-02-09 02:18:42 +00:00
David Dykstra
1bbd10fe07 Remove the "rsync:" prefixes on FINFO messages. Return the "building file
list ... done" to the way it was in 2.5.1 and before when not using -P.
Apply the file list progress messages when receiving files in addition to
sending files.
2002-02-07 16:36:12 +00:00
David Dykstra
088aac8597 Make batch mode actually work and add man page documentation. From Jos Backus. 2002-02-06 21:20:48 +00:00
Martin Pool
81c652d5d2 Merge modified --with-rsh patch: we now determine the default
remote-execution command as follows:

 1) if --with-rsh is specified, use that.

 2) otherwise if remsh is in the path, use that.

 3) otherwise use rsh

If remsh is present, we always modify the order of parameters to suit
it.  This is a bit strange.
2002-02-06 04:37:09 +00:00
Martin Pool
d7761c1480 Doc: Rusty's /*/* exclude hack produces spurious output with -vv. 2002-02-06 04:34:40 +00:00
David Dykstra
93689aa51a Add --no-whole-file and --no-blocking-io options 2002-02-05 23:05:31 +00:00
Martin Pool
46e6ad492a Only print the command used to open connections with -vv, not just -v. 2002-02-05 00:37:53 +00:00
Martin Pool
97efa5c36c Roll over NEWS 2002-02-05 00:35:31 +00:00
Martin Pool
0b1ffe2755 Only print the command used to open connections with -vv, not just -v.
<Pine.LNX.4.33L2.0201301015260.11155-100000@phong.blorf.net>
2002-02-05 00:34:03 +00:00
Martin Pool
8c35542d1f Patch from wayned so that add_exclude_list produces clearer debugging
output with -vvv.
2002-02-05 00:25:52 +00:00
Andrew Tridgell
0e9480317d the signed/unsigned change seems to have caused a logic bug on some
systems (only those without large file support perhaps?)

this fixes it
2002-02-03 01:38:39 +00:00
David Dykstra
b695d088cf Better explanation of --force. It is applicable whenever --delete is
not in effect.
2002-01-29 21:52:57 +00:00
David Dykstra
81dc5750ca A more accurate description of --force as I know it. 2002-01-28 21:09:03 +00:00
David Dykstra
d82434cf27 Clarify the --force entry in the rsync man page. 2002-01-28 17:06:04 +00:00
Martin Pool
cd6058f3d4 Oops, version should be just 2.5.2. 2002-01-25 23:19:21 +00:00
Martin Pool
9be3ba223c Bump version to 2.5.3. 2002-01-25 23:16:18 +00:00
Martin Pool
a261989cda More signedness fixes; should be harmless. 2002-01-25 23:07:33 +00:00
Martin Pool
7b5c3eb05e io_end_buffering doesn't need (or use) it's fd parameter: there's only
one multiplexed stream.
2002-01-25 23:01:50 +00:00
Martin Pool
0feec72eee DEV64_t and INO64_T should probably be unsigned 2002-01-25 23:00:21 +00:00
Martin Pool
be8bd99aa4 check_name doesn't need a socklen_t, because it knows what is inside
each sockaddr type.
2002-01-25 22:59:37 +00:00
Martin Pool
355b8bcd73 Add test case for device nodes. This test will be skipped unless you
run "make check" as root.
2002-01-25 10:56:43 +00:00
Martin Pool
d58e4c273c When comparing directories, use find . to call diff, rather than
diff -r.  Two reasons: diff -r might not work everywhere, and it also
might complain about nonregular files.
2002-01-25 10:55:59 +00:00
Martin Pool
a217ad3095 Add test_skipped function. 2002-01-25 10:47:47 +00:00
Martin Pool
3d6feada8a New --ignore-existing option, patch previously distributed with
Vipul's Razor.  (Debian #124286)
2002-01-25 10:42:23 +00:00
Martin Pool
5f78da2025 Fix for device nodes. (dann frazier) (Debian #129135) 2002-01-25 10:39:08 +00:00
Martin Pool
a05e4fa512 Fix for device nodes. (dann frazier) (Debian #129135) 2002-01-25 10:28:13 +00:00
Martin Pool
2119a4c462 Another DEV64_T change. 2002-01-25 10:16:11 +00:00
Martin Pool
1d5a1da9f8 With -vv, when the file list grows, show a message. 2002-01-25 10:12:36 +00:00
Martin Pool
2e7d19945c With -vv, when the file list grows, show a message. 2002-01-25 10:12:02 +00:00
Martin Pool
5d2c5c4c73 Undo overzealous deletion. 2002-01-25 10:09:00 +00:00
Martin Pool
8694312695 Add dummy show_flist_stats(). 2002-01-25 10:06:36 +00:00
Martin Pool
d9d6bc5278 Factor out code to grow the file list into a common location. 2002-01-25 10:05:49 +00:00
Martin Pool
ebed4c3af0 indent -kr -i8 2002-01-25 09:59:00 +00:00
Martin Pool
172875cf15 Add link to the message that introduced string_area. 2002-01-25 09:54:21 +00:00
Martin Pool
4d26e9e4f4 mallinfo is implemented. 2002-01-25 09:45:45 +00:00
Martin Pool
8f4455f296 Notes about flist. 2002-01-25 09:44:17 +00:00
Martin Pool
2e1d43deb2 Ignore autoconf fluff. 2002-01-25 02:53:48 +00:00
Martin Pool
6780f72000 Add code to compare sin6_addrs. 2002-01-25 02:45:09 +00:00
Martin Pool
39e01d2d4b Back out last change -- to see whether an address is spoofed, we don't
want to look at the whole sockaddr, but rather just at the sin_addr
that it contains.

Also fix silly bug where ai_flags was set incorrectly for getaddrinfo.
2002-01-25 02:43:35 +00:00
Martin Pool
f75502950b compare_addrinfo_sockaddr: Add code to compare AF_INET6 addresses. 2002-01-25 02:37:20 +00:00
Martin Pool
974f27e7e9 Split out code to compare addrinfo and sockaddr into it's own
function.  The comparison cannot be done just byte-by-byte, because
different parts of the sockaddr will be meaningful depending on the
protocol.  It looks like on some systems the library sets the unused
parts to 0, but this is not reliable.  IPv6 not implemented yet.
2002-01-25 02:29:53 +00:00
Martin Pool
af32f69eb0 Doc. 2002-01-25 02:15:58 +00:00
Martin Pool
0cd2f40764 The name resolution stuff is getting complicated -- split it out into
its own file.
2002-01-25 02:13:04 +00:00
Martin Pool
0d95824995 Verbose messages for spoof check... doesn't work on old linux libc? 2002-01-24 09:42:52 +00:00
Martin Pool
bbc09ffba9 When doing a name->addr translation to check for spoofing, give the
resolver the address family of the original address as a hint, so that
we're more likely to find the correct A or AAAA record.,
2002-01-24 08:52:28 +00:00
Martin Pool
a4677968cf Message on successful configuration. 2002-01-24 08:50:35 +00:00
Martin Pool
03b1cddc31 Fix comment.
Bump version to 2.5.2pre3
2002-01-24 08:42:21 +00:00
Martin Pool
9c2dd04993 Name resolution on machines supporting IPv6 is improved. 2002-01-24 08:20:51 +00:00
Martin Pool
a84a93fafe ignore gmon.out 2002-01-24 08:19:28 +00:00
Martin Pool
5fdcc397b1 Fix getpeername call. 2002-01-24 08:16:27 +00:00
Martin Pool
5664871e5f size_t fix. 2002-01-24 08:09:46 +00:00
Martin Pool
55d9e0fada write_batch_csums_file: Opaque IO buffers should be void*. 2002-01-24 08:08:56 +00:00
Martin Pool
929e3011c6 Fix cast that was breaking HP/UX. 2002-01-24 08:07:35 +00:00
Martin Pool
07d70ff560 Move both calls to getpeername into a common wrapper function that
handles IPV4_MAPPED addresses.
2002-01-24 08:05:22 +00:00
Martin Pool
58c2960960 Must get declarations from addrinfo.h before prototypes. 2002-01-24 07:22:38 +00:00
Martin Pool
00d943d513 Another size_t warning 2002-01-24 05:57:49 +00:00
Martin Pool
71c780da06 check_name: Print out name *before* clobbering it. 2002-01-24 05:57:22 +00:00
Martin Pool
3b18cba889 Try to fix error on Solaris:
+ [ -f /export/home/build/build_farm/rsync/testtmp.symlink-ignore/to/referent ]
+ [ -d /export/home/build/build_farm/rsync/testtmp.symlink-ignore/to/from ]
+ [ -L /export/home/build/build_farm/rsync/testtmp.symlink-ignore/to/dangling ]
./testsuite/symlink-ignore.test: test: argument expected

Solaris says it supports -L, so I'm not sure what's happening...
2002-01-24 05:54:47 +00:00
Martin Pool
2974e20550 If name lookup fails, then show the relevant IP address in the error message. 2002-01-24 05:41:46 +00:00
Martin Pool
430d841a2c At the connections that just get a list of modules are not logged,
but they should be.
2002-01-24 04:49:07 +00:00
Martin Pool
31ec50d7da rsync_module: If host-based access fails, show the exact name/address
used for the check in the error message.  (Just in case...)
2002-01-24 04:41:09 +00:00
Martin Pool
5ad0e46f08 Show command used to start connection child. 2002-01-24 04:36:00 +00:00
Martin Pool
1b5814e338 indent -kr -i8 2002-01-24 04:26:55 +00:00
Martin Pool
255810c0d6 Doc.
Oops, connection program message was in the wrong place.
2002-01-24 04:24:12 +00:00
Martin Pool
5d2640376e Show helper program with -v when opening connection.
Doc.
2002-01-24 04:21:42 +00:00
Martin Pool
d02984bbb7 Doc. 2002-01-24 04:19:41 +00:00
Martin Pool
0f9555207a Fix const 2002-01-24 04:07:07 +00:00
Martin Pool
885448d74c Unbreak the old behavior of using UNKNOWN as a hostname if any of the
addr->name->addr translations fail, because people might count on this
in "hosts deny" lines.
2002-01-24 04:03:06 +00:00
Martin Pool
b14545b3ff Fix inverted sense of error check. 2002-01-24 03:31:28 +00:00
Martin Pool
9a5a86734f Refactor client_name() into smaller functions.
Better messages for DNS failure.

If we can get a reverse name for an IP address, but not confirm that
it is correct using a forward lookup then we still proceed to use the
name, but also emit a warning.
2002-01-24 03:28:20 +00:00
Martin Pool
d1d1505045 Doc. 2002-01-24 03:03:20 +00:00
Martin Pool
144ce1dc21 Bump version to 2.5.2pre2. 2002-01-24 03:01:42 +00:00
Martin Pool
aa126974ba log_formatted: Fill the log buffer with nuls to make sure we cannot
accidentally leave the string unterminated.
2002-01-24 02:41:38 +00:00
Martin Pool
707de53457 Another harmless size_t warning. 2002-01-24 02:33:45 +00:00
Martin Pool
10f83cf43d Doc. 2002-01-23 08:08:48 +00:00
Martin Pool
59ee743c5f More size_t fixes. 2002-01-23 08:04:54 +00:00
Martin Pool
d54765c442 Just for variety we have some socklen_t fixes too. 2002-01-23 07:57:43 +00:00
Martin Pool
91262d5d3e Refactor code in send_sums to remove repeated ternaries. 2002-01-23 07:54:13 +00:00
Martin Pool
1c09c743b1 indent -kr -i8 2002-01-23 07:52:52 +00:00
Martin Pool
06ce139fcc Fix more ints that ought to be size_t's. 2002-01-23 07:48:35 +00:00
Martin Pool
fae5bb3183 Doc.
do_hard_links() actually only looks at the global hardlink table, so
it can be a (void) fn.  (Another gcc warning...)
2002-01-23 07:42:30 +00:00
Martin Pool
6fe25398d6 Fix another int that ought to be a size_t. 2002-01-23 07:36:23 +00:00
Martin Pool
909ce14fc4 indent -kr -i8 2002-01-23 07:34:26 +00:00
Martin Pool
935b920120 Another signedness fix to quieten Sun cc warning. 2002-01-23 07:32:29 +00:00
Martin Pool
b31427cd4a Skip this for now; it's a known bug 2002-01-23 07:28:38 +00:00
Martin Pool
e2e3379d79 Bump version to 2.5.2pre1. 2002-01-23 07:22:03 +00:00
Martin Pool
6b1ef85dd8 Note batch-mode changes. 2002-01-23 07:18:58 +00:00
Martin Pool
92325ada0c Note about proxy authentication and SOCKS. 2002-01-23 07:12:57 +00:00
Martin Pool
1707e0f9e2 Indent. 2002-01-23 06:48:13 +00:00
Martin Pool
7ff701e816 Update thankyou list.
Clarify email addresses.
2002-01-23 05:59:10 +00:00
Martin Pool
2e3c141795 Note that batch mode is currently experimental. 2002-01-23 05:53:58 +00:00
Martin Pool
76f79ba748 Patch from Jos Backus -- Fix breakage from dev_t to DEV64_T in batch
mode.

Also, drop -f and -F for batch mode: these should be reserved for
options that are more commonly used.

It also appends a newline to the argvs file and skips adding the
source directory to the command line.
2002-01-23 05:51:06 +00:00
Martin Pool
9dd891bb28 Signedness security patch from Sebastian Krahmer <krahmer@suse.de> --
in some cases we were not sufficiently careful about reading integers
from the network.

Also, make sure log messages are always nul-terminated.
2002-01-23 04:57:18 +00:00
Martin Pool
99f106d1cf If using gcc, then also turn on -W to get even more warnings.
Remove obsolete message.
2002-01-23 03:52:06 +00:00
Martin Pool
3816cae745 Don't need to reread configuration on SIGHUP because we always do that
on new connections.
2002-01-21 01:57:13 +00:00
David Dykstra
759c0627e1 Aack! Since released version 2.5.0, the --whole-file option was accidentally
changed to --whole.  Change it back.  Anybody who wants to use this option
with any version of rsync will have to switch to using -W.
2002-01-15 21:25:55 +00:00
Martin Pool
e03dfae507 Change gratuituous strlcat's into strlcpy, since we already know the
length of the existing string.
2002-01-15 11:50:32 +00:00
Martin Pool
c7677b892a Clearer doc. 2002-01-15 11:32:30 +00:00
Martin Pool
da7b63972d Add --enable-profile to turn on gprof. This is not perfect, because
it seems to only write to ./gmon.out, and that causes trouble when
there are several rsync processes in the same directory.  But you can
make it work.
2002-01-15 11:20:26 +00:00
Martin Pool
499957d9ba Update 2002-01-15 10:47:59 +00:00
Martin Pool
582250008b The Ted T'so school of program optimization: make progress visible and
people will think it's faster.

So now with --progress rsync will show you how many files it has seen
as it builds the file_list.
2002-01-15 10:43:51 +00:00
Martin Pool
a9b31409d5 Remove unused variable. 2002-01-15 10:04:48 +00:00
Martin Pool
98355b8086 Oops, getaddrinfo returns an error code (not -1) for error. -Wall is
good.
2002-01-15 10:04:11 +00:00
Martin Pool
70ed474b38 Define _GNU_SOURCE so that we get all necessary prototypes. 2002-01-15 09:53:27 +00:00
Martin Pool
4775934364 If using GCC, try to turn on -Wall. I want to be clean with respect
to -Wall.
2002-01-15 09:43:21 +00:00
Martin Pool
25f2cb3d6b Fix for <http://rsync.samba.org/cgi-bin/rsync/incoming?id=3750>
temp files must be opened through do_open so that binary modes is used
on cygwin.  (Chris Boucher)
2002-01-14 00:16:51 +00:00
Martin Pool
154f9a3aca Ignore testtmp directories. 2002-01-13 23:57:13 +00:00
Martin Pool
b9df3bf20c DOc. 2002-01-11 08:37:42 +00:00
Martin Pool
6abd193fe3 Always use 64-bit ino_t and dev_t internally, so that we can detect
hardlinks if coming from a larger platform.  Add heaps of comments
explaining why this is so.
2002-01-11 08:25:32 +00:00
Martin Pool
362099a512 More comments about IPv6 stuff.
If a reverse name lookup fails, show the name that we were trying to
look up.
2002-01-11 08:24:34 +00:00
Martin Pool
fdfc3dc9f3 When checking what was copied, use specific -d -f -L flags to test
rather than -e.  (Perhaps Solaris doesn't have test -e?)
2002-01-11 08:08:34 +00:00
Martin Pool
4937459225 The current version of rsync is expected to fail to eliminate all
duplicates from list.
2002-01-11 08:02:43 +00:00
Martin Pool
be2f866b4c Add concept of expected-failure. 2002-01-11 08:01:05 +00:00
Martin Pool
f08aacf7d6 Give cleaner output from "make check" 2002-01-11 07:41:50 +00:00
Martin Pool
4fa6112efe Bump version number.
Now finished merging across work from experimental BK repository.
2002-01-11 07:30:50 +00:00
Martin Pool
1623ba6889 Improved duplicates test: check that each file is
copied once and exactly once.
2002-01-11 07:29:53 +00:00
Martin Pool
766526c791 Check whether code to eliminate duplicate filenames works
(hint: it does not.)
2002-01-11 07:29:02 +00:00
Martin Pool
5c15e29f2b Better mallinfo() output in --stats 2002-01-11 07:26:39 +00:00
Martin Pool
0413e1605f Update copyright 2002-01-11 07:25:54 +00:00
Martin Pool
0e5a1f8352 Doc 2002-01-11 07:24:31 +00:00
Martin Pool
e5a2b8544d Look for mallinfo() and use it to display
heap usage information in --stats
2002-01-11 07:16:11 +00:00
Martin Pool
736a6a291c In protocol version 26, always
send 64-bit ino_t and dev_t.  We also need to try to use 64-bit
ino_t internally *even if* this platform does not have 64-bit
inums itself, because we need to find duplicate inums when
coming from a larger platform with --hardlinks.
2002-01-11 07:15:16 +00:00
Martin Pool
6e69cff118 Autoindent
Add copyright
2002-01-11 07:11:43 +00:00
Martin Pool
cf72f20426 Improved test framework and test for hardlink handling 2002-01-11 07:11:23 +00:00
Martin Pool
d479210cee Bump version 2002-01-11 07:10:25 +00:00
Martin Pool
b781537597 Merge ChangeSet@1.12: Add test case for -H 2002-01-11 07:09:53 +00:00
Martin Pool
ea1438dad8 Merge ChangeSet@1.12: tls now shows number of links to a file to aid in testing -H 2002-01-11 07:09:22 +00:00
Martin Pool
d2e9d069b4 Merge ChangeSet@1.10: Documentation about flist scalabilityTODO 2002-01-11 07:07:49 +00:00
Martin Pool
58379559cc Merge ChangeSet@1.9: Documentation about flist scalability 2002-01-11 07:07:30 +00:00
Martin Pool
b3e6c81565 Merge ChangeSet@1.4: Documentation about flist scalability 2002-01-11 07:05:30 +00:00
Martin Pool
a6a3c3df45 Merge ChangeSet@1.4: Documentation about future development. 2002-01-11 07:04:37 +00:00
Martin Pool
6e3d4c4045 Oops, fix date. 2002-01-03 07:18:17 +00:00
rsync-bugs
ca60b701ee preparing for release of 2.5.1 2002-01-03 07:11:10 +00:00
Martin Pool
e24c0b98d7 Cleanup. 2002-01-03 07:08:35 +00:00
David Dykstra
f389ac80a9 Removed debugging statement that was added to sig_int() by the rsync+ patch
integration.  It was causing the format of the daemon log to be messed up
because of the leading \n.
2001-12-20 15:33:13 +00:00
Martin Pool
50f2f002d9 Suggestion from David Stein
verbose output

  Indicate whether files are new, updated, or deleted
2001-12-20 01:23:28 +00:00
Martin Pool
9ec7528475 Typo 2001-12-18 06:48:56 +00:00
Martin Pool
a8e2a43a09 Get rid of global_opts struct as suggested by Dave -- too many
problems with initialization.
2001-12-18 06:47:40 +00:00
Martin Pool
eb06fa95e4 Documentation fixes based on mail from Edward Welbourne, and an
attempted explanation of rsync's symbolic-link handling.
2001-12-18 06:45:28 +00:00
Martin Pool
1db8b61de7 Add an "unsafe" symlink to the symlink test case so we can see what happens. 2001-12-18 06:26:26 +00:00
Martin Pool
38c66db8d6 Note about hardlink performance. 2001-12-18 06:25:31 +00:00
Martin Pool
f8be7d4219 Refactor code for setting local address on outgoing connections. If a
local address is specified, then try all addrinfo records for it.
2001-12-18 06:21:33 +00:00
Martin Pool
13e29995f5 Get rid of global_opts struct as suggested by Dave -- too many
problems with initialization.

Change the algorithm from trying to open an inbound socket with
getaddrinfo: keep trying suggested addresses until we find one on
which we can both get a socket and bind.  Not convinced this is the
best, but it's probably better.
2001-12-18 05:54:57 +00:00
Martin Pool
7c583c7316 Note rsyncd-over-ssh and documentation TODOs. 2001-12-18 01:33:56 +00:00
Martin Pool
9fecec5e85 Fix from Jeff Garzik for inet_ntop prototype errors on some Linux
distributions: we were failing to define HAVE_INET_NTOP, so our
prototype in rsync.h came through.

Also rerun autoheader, and have comment for HAVE_SOCKADDR_STORAGE.
2001-12-18 01:32:27 +00:00
Martin Pool
9e696bd468 Update README so that Paulus doesn't get bug reports anymore :-)
I think this document needs to be reworked to better explain how to
use rsync, but not right now.
2001-12-18 01:07:20 +00:00
David Dykstra
6ab6d4bfc1 When INET6 is not defined, meaning that IPv6 is not supported, need to
initalize the global_opts.af_hint to AF_INET or systems such as Linux that
have a native getaddrinfo() because they support IPv6 will attempt to
create IPv6 sockets.  This brings up a problem with the new global_opts
structure; in order to initialize them to a value other than 0, we need to
explicitly initialize them all in an order that matches the order in
rsync.h.  I think that's more inconvenient & error prone than keeping
global variables.
2001-12-14 18:25:51 +00:00
David Dykstra
cb1bcc7ebb open_socket_in was attempting to try all the protocols returned from
getaddrinfo(), but only if a corresponding call to socket() returned one of
three *NOSUPPORT errno codes.  A Redhat 6.2 system was observed returning
EINVAL instead so it never went on to try IPv4.  This update adds EINVAL to
the list.  Question: why not always continue through the list regardless of
what errno is?
2001-12-14 18:00:54 +00:00
Martin Pool
19ba7d6318 Verbose. 2001-12-14 05:55:21 +00:00
Martin Pool
7753ca1f49 Only show test output if it failed. 2001-12-14 05:54:24 +00:00
Martin Pool
d52a796c39 Be less verbose. 2001-12-14 05:52:25 +00:00
Martin Pool
60514d457c Fix quoting. 2001-12-14 05:44:04 +00:00
Martin Pool
5bc00efe42 Perhaps Solaris sh wants us to explicitly exit 0, rather than just
using the last return code?
2001-12-14 05:27:42 +00:00
Martin Pool
c45f3133bc More error messages. 2001-12-14 05:19:15 +00:00
Martin Pool
fb47591de0 Typo. 2001-12-14 05:17:52 +00:00
Martin Pool
514d129c49 Make scratch directory properly. 2001-12-14 05:01:48 +00:00
Martin Pool
db843fc12d Doc. 2001-12-14 02:18:31 +00:00
Martin Pool
63787382d8 Clearer error messages. 2001-12-14 02:16:20 +00:00
Martin Pool
85d4d142d8 Clearer error messages. 2001-12-14 02:14:58 +00:00
Martin Pool
3cd2af41e4 Add a test that when none of -l, -L, -a are specified symlinks are not
copied at all.
2001-12-14 02:01:46 +00:00
Martin Pool
b214eda4f0 Clean scratch directory between each test run. 2001-12-14 01:52:43 +00:00
Martin Pool
0771727d41 Readlink(2) does not nul-terminate the output buffer, so we were
getting corrupt output when listing more than one symlink.
2001-12-14 01:48:48 +00:00
Martin Pool
a5d74a1876 Fix contact details. 2001-12-14 01:09:23 +00:00
Martin Pool
23bf32f767 Don't define DEBUG with --enable-debug, because that makes zlib emit strange messages 2001-12-09 21:48:13 +00:00
Martin Pool
87a819edee IRIX cc cares that the operands to the ternary have the same type. 2001-12-05 13:48:41 +00:00
Martin Pool
27a1234874 Be more strict about 'enum logcode' rather than int. IRIX compiler
picked this up -- quite neat.
2001-12-05 13:45:51 +00:00
Martin Pool
51f289d1e6 Some platforms don't have sa_family_t. 2001-12-05 13:44:37 +00:00
Martin Pool
d0d6dc61e8 Bump version 2001-12-05 13:41:38 +00:00
Martin Pool
d91c8c50d2 RFC2553 just says that sockaddr_storage has to have initial fields
isomorphic to sa_family etc from a struct sockaddr, not what they're
called.  On some platforms they seem not to be called ss_family.
Rather than guess, we will try casting to a sockaddr and looking
through that -- I think this is what the RFC intends.
2001-12-05 13:25:29 +00:00
Martin Pool
e20a4f84d6 Some platforms may have getaddrinfo() but not sockaddr_storage. 2001-12-05 13:19:16 +00:00
Martin Pool
bbd6f4ba8e Document --no-detach. 2001-12-05 13:10:24 +00:00
Martin Pool
2a951cd2f9 Fix help message for --address option 2001-12-05 13:06:26 +00:00
Martin Pool
a538066d5a Add --no-detach option for W32, daemontools, etc. 2001-12-05 13:03:16 +00:00
Martin Pool
c10b0bdd50 Doc 2001-12-05 13:02:11 +00:00
Martin Pool
431efc8979 Doc. 2001-12-05 12:56:06 +00:00
Martin Pool
2d6dbe290c Change back to using sockaddr_storage rather than sockaddr_in. If
sockaddr_storage is not defined, then supply our own definition that
will hopefully satisfy RFC2553 but also compile on all supported
platforms.

Thankyou to YOSHIFUJI Hideaki, SUMIKAWA Munechika and Jun-ichiro
"itojun" Hagino.
2001-12-05 12:48:46 +00:00
Martin Pool
c33e3e3967 Suggestions from KAME IPv6 newsletter. 2001-12-05 12:25:36 +00:00
Martin Pool
71b3374bd5 Note from tpot that sighup should have standard behaviour of reinitializing. 2001-12-05 00:58:20 +00:00
David Dykstra
de343e3cce Don't print out the directory name twice in verbose mode; it was being
printed a second time when the modification time of the directory was
being set, and that time around recv_files() calls recv_generator() with
an f_out of -1 so check that before printing the directory name.
2001-12-03 18:37:33 +00:00
Martin Pool
384958ed3d Note about crash from Ayamura KIKUCHI 2001-12-02 22:47:30 +00:00
Martin Pool
1cd5beeb06 batch reindent 2001-12-02 22:28:50 +00:00
Martin Pool
4c70e359d0 Bump version 2001-12-02 22:26:09 +00:00
Martin Pool
f9c3005bff Fix FP usage. 2001-12-02 14:12:03 +00:00
Martin Pool
9147074d8b Oops, units bug. 2001-12-02 13:58:03 +00:00
Martin Pool
7007bddaef Show time-remaining as hh:mm:ss. 2001-12-02 13:45:38 +00:00
44 changed files with 3006 additions and 1534 deletions

View File

@@ -4,10 +4,15 @@ config.cache
config.h
config.log
config.status
gmon.out
rsync
shconfig
testdir
tests-dont-exist
testtmp
testtmp.*
tls
zlib/dummy
confdefs.h
conftest.c
conftest.log

View File

@@ -29,13 +29,14 @@ ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
zlib/zutil.o zlib/adler32.o
OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o main.o checksum.o match.o syscall.o log.o backup.o
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o batch.o
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o batch.o \
clientname.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) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
tls_OBJ = tls.o syscall.o lib/permstring.o
TLS_OBJ = tls.o syscall.o lib/permstring.o
# Programs we must have to run the test cases
CHECK_PROGS = rsync tls
@@ -67,8 +68,8 @@ rsync: $(OBJS)
$(OBJS): config.h
tls: $(tls_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(tls_OBJ) $(LIBS)
tls: $(TLS_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
Makefile: Makefile.in configure config.status
echo "WARNING: You need to run ./config.status --recheck"

42
NEWS
View File

@@ -1,15 +1,39 @@
rsync 2.5.1 (sometime in 2001?)
rsync 2.5.3 (not released yet)
SECURITY FIXES:
* Make sure that supplementary groups are removed from a server
process after changing uid and gid. (Ethan Benson)
BUG FIXES:
* Fixed problem that in many cases caused the error message
unexpected read size of 0 in map_ptr
and resulted in the wrong data being copied.
* Fixed compilation errors on some systems caused by the use of
"unsigned int64" in rsync.h.
* Fixed problem on systems such as Sunos4 that do not support realloc
on a NULL pointer; error was "out of memory in flist_expand".
* Fix for rsync server processes hanging around after the client
unexpectedly disconnects. (Colin Walters) (Debian bug #128632)
* Cope with BSD systems on which mkdir() will not accept a trailing
slash.
ENHANCEMENTS:
* --progress and -P now show estimated data transfer rate (in a
multiple of bytes/s) and estimated time to completion. Based
on a patch by Rik Faith.
* Command to initiate connections is only shown with -vv, rather
than -v as in 2.5.2. Output from plain -v is more similar to
what was historically used so as not to break scripts that try
to parse the output.
BUG FIXES:
* rsync.1 typo fix by Matt Kraai
* Added --no-whole-file and --no-blocking-io options (Dave Dykstra)
* Fix for segfault in rsyncd.conf parser by Paul Mackerras
* Made the --write-batch and --read-batch options actually work
and added documentation in the man page (Jos Backus)
* Test suite typo fixes Tom Schmidt
* If the daemon is unable to fork a child to accept a connection,
print an error message. (Colin Walters)

74
OLDNEWS
View File

@@ -1,3 +1,77 @@
rsync 2.5.2 (26 Jan 2002)
SECURITY FIXES:
* Signedness security patch from Sebastian Krahmer
<krahmer@suse.de> -- in some cases we were not sufficiently
careful about reading integers from the network.
BUG FIXES:
* Fix possible string mangling in log files.
* Fix for setting local address of outgoing sockets.
* Better handling of hardlinks and devices on platforms with
64-bit dev_t or ino_t.
* Name resolution on machines supporting IPv6 is improved.
* Fix for device nodes. (dann frazier) (Debian #129135)
ENHANCEMENTS:
* With -v, rsync now shows the command used to initiate an ssh/rsh
connection.
* --statistics now shows memory heap usage on platforms that
support mallinfo().
* "The Ted T'so school of program optimization": make progress
visible and people will think it's faster. (With --progress,
rsync will show you how many files it has seen as it builds the
file_list, giving some indication that it has not hung.)
* Improvements to batch mode support. This is still experimental
but testing would be welcome. (Jos Backus)
* New --ignore-existing option, patch previously distributed with
Vipul's Razor. (Debian #124286)
rsync 2.5.1 (2002-01-03)
BUG FIXES:
* Fix for segfault in --daemon mode configuration parser. (Paul
Mackerras)
* Correct string<->address parsing for both IPv4 and 6.
(YOSHIFUJI Hideaki, SUMIKAWA Munechika and Jun-ichiro "itojun"
Hagino)
* Various fixes for IPv6 support. (Dave Dykstra)
* rsync.1 typo fix. (Matt Kraai)
* Test suite typo fixes. (Tom Schmidt)
* rsync.1 grammar and clarity improvements. (Edward
Welbourne)
* Correction to ./configure tests for inet_ntop. (Jeff Garzik)
ENHANCEMENTS:
* --progress and -P now show estimated data transfer rate (in a
multiple of bytes/s) and estimated time to completion. (Rik
Faith)
* --no-detach option, required to run as a W32 service and also
useful when running on Unix under daemontools, AIX's SRC, or a
debugger. (Max Bowsher, Jos Backus)
* Clearer error messages for some conditions.
rsync 2.5.0 (2001-11-30)
ANNOUNCEMENTS

13
README
View File

@@ -143,9 +143,7 @@ This will give you access to the bug tracking system used by the
developers of rsync and will allow you to look at other bug reports or
submit a new bug report.
If you don't have web access then mail bug reports to
rsync-bugs@samba.org or (if you think it will be of interest to lots
of people) send it to rsync@samba.org
If you don't have web access then mail bug reports to rsync@samba.org.
CVS TREE
@@ -167,11 +165,12 @@ details.
COPYRIGHT
---------
Rsync was written by Andrew Tridgell and Paul Mackerras, and is
available under the GNU General Public License.
rsync was originally written by Andrew Tridgell and has been improved
by many developers around the world. rsync may be used, modified and
redistributed only under the terms of the GNU General Public License,
found in the file COPYING in this distribution, or at
tridge@samba.org
paulus@cs.anu.edu.au
http://www.fsf.org/licenses/gpl.html
AVAILABILITY

182
TODO
View File

@@ -32,15 +32,159 @@ use chroot
for people who want to generate the file list using a find(1)
command or a script.
File list structure in memory
Rather than one big array, perhaps have a tree in memory mirroring
the directory tree.
This might make sorting much faster! (I'm not sure it's a big CPU
problem, mind you.)
It might also reduce memory use in storing repeated directory names
-- again I'm not sure this is a problem.
Performance
Traverse just one directory at a time. Tridge says it's possible.
Can possibly also be smarter about memory use while looking for hard
links by reducing the refcount as we find alternative names.
At the moment rsync reads the whole file list into memory at the
start, which makes us use a lot of memory and also not pipeline
network access as much as we could.
Handling duplicate names
We need to be careful of duplicate names getting into the file list.
See clean_flist(). This could happen if multiple arguments include
the same file. Bad.
I think duplicates are only a problem if they're both flowing
through the pipeline at the same time. For example we might have
updated the first occurrence after reading the checksums for the
second. So possibly we just need to make sure that we don't have
both in the pipeline at the same time.
Possibly if we did one directory at a time that would be sufficient.
Alternatively we could pre-process the arguments to make sure no
duplicates will ever be inserted. There could be some bad cases
when we're collapsing symlinks.
We could have a hash table.
The root of the problem is that we do not want more than one file
list entry referring to the same file. At first glance there are
several ways this could happen: symlinks, hardlinks, and repeated
names on the command line.
If names are repeated on the command line, they may be present in
different forms, perhaps by traversing directory paths in different
ways, traversing paths including symlinks. Also we need to allow
for expansion of globs by rsync.
At the moment, clean_flist() requires having the entire file list in
memory. Duplicate names are detected just by a string comparison.
We don't need to worry about hard links causing duplicates because
files are never updated in place. Similarly for symlinks.
I think even if we're using a different symlink mode we don't need
to worry.
Unless we're really clever this will introduce a protocol
incompatibility, so we need to be able to accept the old format as
well.
Memory accounting
At exit, show how much memory was used for the file list, etc.
Also we do a wierd exponential-growth allocation in flist.c. I'm
not sure this makes sense with modern mallocs. At any rate it will
make us allocate a huge amount of memory for large file lists.
Hard-link handling
At the moment hardlink handling is very expensive, so it's off by
default. It does not need to be so.
Since most of the solutions are rather intertwined with the file
list it is probably better to fix that first, although fixing
hardlinks is possibly simpler.
We can rule out hardlinked directories since they will probably
screw us up in all kinds of ways. They simply should not be used.
At the moment rsync only cares about hardlinks to regular files. I
guess you could also use them for sockets, devices and other beasts,
but I have not seen them.
When trying to reproduce hard links, we only need to worry about
files that have more than one name (nlinks>1 && !S_ISDIR).
The basic point of this is to discover alternate names that refer to
the same file. All operations, including creating the file and
writing modifications to it need only to be done for the first name.
For all later names, we just create the link and then leave it
alone.
If hard links are to be preserved:
Before the generator/receiver fork, the list of files is received
from the sender (recv_file_list), and a table for detecting hard
links is built.
The generator looks for hard links within the file list and does
not send checksums for them, though it does send other metadata.
The sender sends the device number and inode with file entries, so
that files are uniquely identified.
The receiver goes through and creates hard links (do_hard_links)
after all data has been written, but before directory permissions
are set.
At the moment device and inum are sent as 4-byte integers, which
will probably cause problems on large filesystems. On Linux the
kernel uses 64-bit ino_t's internally, and people will soon have
filesystems big enough to use them. We ought to follow NFS4 in
using 64-bit device and inode identification, perhaps with a
protocol version bump.
Once we've seen all the names for a particular file, we no longer
need to think about it and we can deallocate the memory.
We can also have the case where there are links to a file that are
not in the tree being transferred. There's nothing we can do about
that. Because we rename the destination into place after writing,
any hardlinks to the old file are always going to be orphaned. In
fact that is almost necessary because otherwise we'd get really
confused if we were generating checksums for one name of a file and
modifying another.
At the moment the code seems to make a whole second copy of the file
list, which seems unnecessary.
We should have a test case that exercises hard links. Since it
might be hard to compare ./tls output where the inodes change we
might need a little program to check whether several names refer to
the same file.
IPv6
Implement suggestions from http://www.kame.net/newsletter/19980604/
and ftp://ftp.iij.ad.jp/pub/RFC/rfc2553.txt
If a host has multiple addresses, then listen try to connect to all
in order until we get through. (getaddrinfo may return multiple
addresses.) This is kind of implemented already.
Possibly also when starting as a server we may need to listen on
multiple passive addresses. This might be a bit harder, because we
may need to select on all of them. Hm.
Define a syntax for IPv6 literal addresses. Since they include
colons, they tend to break most naming systems, including ours.
Based on the HTTP IPv6 syntax, I think we should use
@@ -87,6 +231,26 @@ logging
monitor progress in a log file can do so more easily. See
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
At the connections that just get a list of modules are not logged,
but they should be.
rsyncd over ssh
There are already some patches to do this.
proxy authentication
Allow RSYNC_PROXY to be http://user:pass@proxy.foo:3128/, and do
HTTP Basic Proxy-Authentication.
Multiple schemes are possible, up to and including the insanity that
is NTLM, but Basic probably covers most cases.
SOCKS
Add --with-socks, and then perhaps a command-line option to put them
on or off. This might be more reliable than LD_PRELOAD hacks.
PLATFORMS ------------------------------------------------------------
Win32
@@ -102,6 +266,10 @@ Win32
we are correct to call close(), because shutdown() discards
untransmitted data.
DOCUMENTATION --------------------------------------------------------
Update README
BUILD FARM -----------------------------------------------------------
Add machines
@@ -124,7 +292,12 @@ NICE -----------------------------------------------------------------
hang/timeout friendliness
On
verbose output
Indicate whether files are new, updated, or deleted
At end of transfer, show how many files were or were not transferred
correctly.
internationalization
@@ -143,3 +316,4 @@ rsyncsh
current host, directory and so on. We can probably even do
completion of remote filenames.
%K%

View File

@@ -105,8 +105,8 @@ static int get_secret(int module, char *user, char *secret, int len)
while (!found) {
int i = 0;
memset(line, 0, sizeof(line));
while (i<(sizeof(line)-1)) {
memset(line, 0, sizeof line);
while ((size_t) i < (sizeof(line)-1)) {
if (read(fd, &line[i], 1) != 1) {
memset(line, 0, sizeof(line));
close(fd);

898
batch.c
View File

File diff suppressed because it is too large Load Diff

282
clientname.c Normal file
View File

@@ -0,0 +1,282 @@
/* -*- c-file-style: "linux" -*-
rsync -- fast file replication program
Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
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 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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/**
* @file clientname.c
*
* Functions for looking up the remote name or addr of a socket.
*
* This file is now converted to use the new-style getaddrinfo()
* interface, which supports IPv6 but is also supported on recent
* IPv4-only machines. On systems that don't have that interface, we
* emulate it using the KAME implementation.
**/
#include "rsync.h"
static const char default_name[] = "UNKNOWN";
/**
* Return the IP addr of the client as a string
**/
char *client_addr(int fd)
{
struct sockaddr_storage ss;
socklen_t length = sizeof ss;
static char addr_buf[100];
static int initialised;
if (initialised) return addr_buf;
initialised = 1;
client_sockaddr(fd, &ss, &length);
getnameinfo((struct sockaddr *)&ss, length,
addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
return addr_buf;
}
static int get_sockaddr_family(const struct sockaddr_storage *ss)
{
return ((struct sockaddr *) ss)->sa_family;
}
/**
* Return the DNS name of the client.
*
* The name is statically cached so that repeated lookups are quick,
* so there is a limit of one lookup per customer.
*
* If anything goes wrong, including the name->addr->name check, then
* we just use "UNKNOWN", so you can use that value in hosts allow
* lines.
**/
char *client_name(int fd)
{
struct sockaddr_storage ss;
socklen_t ss_len = sizeof ss;
static char name_buf[100];
static char port_buf[100];
static int initialised;
if (initialised) return name_buf;
strcpy(name_buf, default_name);
initialised = 1;
client_sockaddr(fd, &ss, &ss_len);
if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf, port_buf, sizeof port_buf))
check_name(fd, &ss, name_buf, port_buf);
return name_buf;
}
/**
* Get the sockaddr for the client.
*
* If it comes in as an ipv4 address mapped into IPv6 format then we
* convert it back to a regular IPv4.
**/
void client_sockaddr(int fd,
struct sockaddr_storage *ss,
socklen_t *ss_len)
{
if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
/* FIXME: Can we really not continue? */
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
fd, strerror(errno));
exit_cleanup(RERR_SOCKETIO);
}
#ifdef INET6
if (get_sockaddr_family(ss) == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
/* OK, so ss is in the IPv6 family, but it is really
* an IPv4 address: something like
* "::ffff:10.130.1.2". If we use it as-is, then the
* reverse lookup might fail or perhaps something else
* bad might happen. So instead we convert it to an
* equivalent address in the IPv4 address family. */
struct sockaddr_in6 sin6;
struct sockaddr_in *sin;
memcpy(&sin6, ss, sizeof(sin6));
sin = (struct sockaddr_in *)ss;
memset(sin, 0, sizeof(*sin));
sin->sin_family = AF_INET;
*ss_len = sizeof(struct sockaddr_in);
#ifdef HAVE_SOCKADDR_LEN
sin->sin_len = *ss_len;
#endif
sin->sin_port = sin6.sin6_port;
/* There is a macro to extract the mapped part
* (IN6_V4MAPPED_TO_SINADDR ?), but it does not seem
* to be present in the Linux headers. */
memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
sizeof(sin->sin_addr));
}
#endif
}
/**
* Look up a name from @p ss into @p name_buf.
**/
int lookup_name(int fd, const struct sockaddr_storage *ss,
socklen_t ss_len,
char *name_buf, size_t name_buf_len,
char *port_buf, size_t port_buf_len)
{
int name_err;
/* reverse lookup */
name_err = getnameinfo((struct sockaddr *) ss, ss_len,
name_buf, name_buf_len,
port_buf, port_buf_len,
NI_NAMEREQD | NI_NUMERICSERV);
if (name_err != 0) {
strcpy(name_buf, default_name);
rprintf(FERROR, RSYNC_NAME ": name lookup failed for %s: %s\n",
client_addr(fd),
gai_strerror(name_err));
return name_err;
}
return 0;
}
/**
* Compare an addrinfo from the resolver to a sockinfo.
*
* Like strcmp, returns 0 for identical.
**/
int compare_addrinfo_sockaddr(const struct addrinfo *ai,
const struct sockaddr_storage *ss)
{
int ss_family = get_sockaddr_family(ss);
const char fn[] = "compare_addrinfo_sockaddr";
if (ai->ai_family != ss_family) {
rprintf(FERROR,
"%s: response family %d != %d\n",
fn, ai->ai_family, ss_family);
return 1;
}
/* The comparison method depends on the particular AF. */
if (ss_family == AF_INET) {
const struct sockaddr_in *sin1, *sin2;
sin1 = (const struct sockaddr_in *) ss;
sin2 = (const struct sockaddr_in *) ai->ai_addr;
return memcmp(&sin1->sin_addr, &sin2->sin_addr,
sizeof sin1->sin_addr);
}
#ifdef INET6
else if (ss_family == AF_INET6) {
const struct sockaddr_in6 *sin1, *sin2;
sin1 = (const struct sockaddr_in6 *) ss;
sin2 = (const struct sockaddr_in6 *) ai->ai_addr;
return memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
sizeof sin1->sin6_addr);
}
#endif /* INET6 */
else {
/* don't know */
return 1;
}
}
/**
* Do a forward lookup on @p name_buf and make sure it corresponds to
* @p ss -- otherwise we may be being spoofed. If we suspect we are,
* then we don't abort the connection but just emit a warning, and
* change @p name_buf to be "UNKNOWN".
**/
int check_name(int fd,
const struct sockaddr_storage *ss,
char *name_buf,
const char *port_buf)
{
struct addrinfo hints, *res, *res0;
int error;
int ss_family = get_sockaddr_family(ss);
memset(&hints, 0, sizeof(hints));
hints.ai_family = ss_family;
hints.ai_flags = AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(name_buf, port_buf, &hints, &res0);
if (error) {
rprintf(FERROR,
RSYNC_NAME ": forward name lookup for %s failed: %s\n",
name_buf, gai_strerror(error));
strcpy(name_buf, default_name);
return error;
}
/* Given all these results, we expect that one of them will be
* the same as ss. The comparison is a bit complicated. */
for (res = res0; res; res = res->ai_next) {
if (!compare_addrinfo_sockaddr(res, ss))
break; /* OK, identical */
}
if (!res0) {
/* We hit the end of the list without finding an
* address that was the same as ss. */
rprintf(FERROR, RSYNC_NAME
": no known address for \"%s\": "
"spoofed address?\n",
name_buf);
strcpy(name_buf, default_name);
} else if (res == NULL) {
/* We hit the end of the list without finding an
* address that was the same as ss. */
rprintf(FERROR, RSYNC_NAME
": %s is not a known address for \"%s\": "
"spoofed address?\n",
client_addr(fd),
name_buf);
strcpy(name_buf, default_name);
}
freeaddrinfo(res0);
return 0;
}

View File

@@ -45,6 +45,7 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
extern char *shell_cmd;
extern int kludge_around_eof;
extern char *bind_address;
extern int default_af_hint;
if (argc == 0 && !am_sender) {
extern int list_only;
@@ -78,8 +79,10 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
if (!user) user = getenv("USER");
if (!user) user = getenv("LOGNAME");
if (verbose >= 2) {
}
fd = open_socket_out_wrapped (host, rsync_port, bind_address,
global_opts.af_hint);
default_af_hint);
if (fd == -1) {
exit_cleanup(RERR_SOCKETIO);
}
@@ -126,7 +129,10 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
if (strcmp(line,"@RSYNCD: EXIT") == 0) exit(0);
rprintf(FINFO,"%s\n", line);
if (strncmp(line, "@ERROR", 6) == 0)
rprintf(FERROR,"%s\n", line);
else
rprintf(FINFO,"%s\n", line);
}
kludge_around_eof = False;
@@ -167,9 +173,9 @@ static int rsync_module(int fd, int i)
if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
rprintf(FERROR,"rsync denied on module %s from %s (%s)\n",
name, client_name(fd), client_addr(fd));
name, host, addr);
io_printf(fd,"@ERROR: access denied to %s from %s (%s)\n",
name, client_name(fd), client_addr(fd));
name, host, addr);
return -1;
}
@@ -279,6 +285,26 @@ static int rsync_module(int fd, int i)
}
if (am_root) {
#ifdef HAVE_SETGROUPS
/* Get rid of any supplementary groups this process
* might have inheristed. */
if (setgroups(0, NULL)) {
rsyserr(FERROR, errno, "setgroups failed");
io_printf(fd, "@ERROR: setgroups failed\n");
return -1;
}
#endif
/* 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(FERROR, errno, "setgid %d failed", (int) gid);
io_printf(fd,"@ERROR: setgid failed\n");
@@ -486,6 +512,7 @@ int daemon_main(void)
extern char *config_file;
extern int orig_umask;
char *pid_file;
extern int no_detach;
if (is_a_socket(STDIN_FILENO)) {
int i;
@@ -501,7 +528,8 @@ int daemon_main(void)
return start_daemon(STDIN_FILENO);
}
become_daemon();
if (!no_detach)
become_daemon();
if (!lp_load(config_file, 1)) {
exit_cleanup(RERR_SYNTAX);
@@ -513,7 +541,8 @@ int daemon_main(void)
RSYNC_VERSION,
rsync_port);
/* TODO: If listening on a particular address, then show that
* address too. */
* address too. In fact, why not just do inet_ntop on the
* local address??? */
if (((pid_file = lp_pid_file()) != NULL) && (*pid_file != '\0')) {
char pidbuf[16];

View File

@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ(2.52)
RSYNC_VERSION=2.5.1pre1
RSYNC_VERSION=2.5.3pre1
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -22,13 +22,18 @@ AC_PROG_INSTALL
AC_PROG_CC_STDC
AC_SUBST(SHELL)
AC_DEFINE([_GNU_SOURCE], 1,
[Define _GNU_SOURCE so that we get all necessary prototypes])
if test "$xac_cv_prog_cc_stdc" = xno
then
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
fi
# compile with optimisation and without debugging by default, unless
# --debug is given. We must decide this before testing the compiler.
# We must decide this before testing the compiler.
# Please allow this to default to yes, so that your users have more
# chance of getting a useful stack trace if problems occur.
AC_MSG_CHECKING([whether to include debugging symbols])
AC_ARG_ENABLE(debug,
@@ -43,12 +48,33 @@ then
else
AC_MSG_RESULT([yes])
# leave CFLAGS alone; AC_PROG_CC will try to include -g if it can
AC_DEFINE(DEBUG, 1, [Define to turn on debugging code that may slow normal operation])
dnl AC_DEFINE(DEBUG, 1, [Define to turn on debugging code that may slow normal operation])
dnl CFLAGS=${CFLAGS-"-g"}
fi
AC_ARG_ENABLE(profile,
AC_HELP_STRING([--enable-profile],
[turn on CPU profiling (default no)],
[], []))
if test x"$enable_profile" = xyes
then
CFLAGS="$CFLAGS -pg"
fi
# This is needed for our included version of popt. Kind of silly, but
# I don't want our version too far out of sync.
CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
# If GCC, turn on warnings.
if test "x$GCC" = "xyes"
then
CFLAGS="$CFLAGS -Wall -W"
fi
AC_ARG_WITH(included-popt,
[ --with-included-popt use bundled popt library, not from system])
@@ -56,11 +82,26 @@ AC_ARG_WITH(rsync-path,
[ --with-rsync-path=PATH set default --rsync-path to PATH (default: \"rsync\")],
[ RSYNC_PATH="$with_rsync_path" ],
[ RSYNC_PATH="rsync" ])
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [ ])
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [location of rsync on remote machine])
AC_ARG_WITH(rsh,
AC_HELP_STRING([--with-rsh=CMD], [set rsh command to CMD (default: \"remsh\" or \"rsh\")]))
AC_CHECK_PROG(HAVE_REMSH, remsh, 1, 0)
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [ ])
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [remote shell is remsh not rsh])
if test x"$with_rsh" != x
then
RSYNC_RSH="$with_rsh"
elif test x"$HAVE_REMSH" = x1
then
RSYNC_RSH="remsh"
else
RSYNC_RSH="rsh"
fi
AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
# arrgh. libc in the current debian stable screws up the largefile
# stuff, getting byte range locking wrong
@@ -204,6 +245,7 @@ AC_CHECK_HEADERS(compat.h sys/param.h ctype.h sys/wait.h sys/ioctl.h)
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h)
AC_CHECK_HEADERS(glob.h alloca.h mcheck.h sys/sysctl.h arpa/inet.h arpa/nameser.h)
AC_CHECK_HEADERS(netdb.h)
AC_CHECK_HEADERS(malloc.h)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
@@ -268,13 +310,13 @@ fi
AC_CHECK_LIB(resolv, inet_ntop)
AC_MSG_NOTICE([Looking in libraries: $LIBS])
dnl AC_MSG_NOTICE([Looking in libraries: $LIBS])
AC_CHECK_FUNC(inet_ntop, , AC_LIBOBJ(lib/inet_ntop))
AC_CHECK_FUNC(inet_pton, , AC_LIBOBJ(lib/inet_pton))
AC_CHECK_FUNCS(inet_ntop, , AC_LIBOBJ(lib/inet_ntop))
AC_CHECK_FUNCS(inet_pton, , AC_LIBOBJ(lib/inet_pton))
AC_CHECK_FUNC(getaddrinfo, , AC_LIBOBJ(lib/getaddrinfo))
AC_CHECK_FUNC(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
AC_CHECK_FUNCS(getaddrinfo, , AC_LIBOBJ(lib/getaddrinfo))
AC_CHECK_FUNCS(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
AC_CHECK_MEMBER([struct sockaddr.sa_len],
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
@@ -284,6 +326,15 @@ AC_CHECK_MEMBER([struct sockaddr.sa_len],
#include <sys/socket.h>
])
AC_MSG_CHECKING(struct sockaddr_storage)
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/socket.h>],
[struct sockaddr_storage x;],
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1,
[Define if you have strct sockaddr_storage.] ),
AC_MSG_RESULT(no))
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
#
AC_CHECK_FUNCS(strcasecmp)
@@ -300,7 +351,7 @@ AC_FUNC_UTIME_NULL
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk)
AC_CHECK_FUNCS(strlcat strlcpy mtrace)
AC_CHECK_FUNCS(strlcat strlcpy mtrace mallinfo setgroups)
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
AC_TRY_RUN([
@@ -516,3 +567,7 @@ AC_SUBST(BUILD_POPT)
AC_CONFIG_FILES([Makefile lib/dummy zlib/dummy popt/dummy shconfig])
AC_OUTPUT
AC_MSG_RESULT()
AC_MSG_RESULT([ rsync ${RSYNC_VERSION} configuration successful])
AC_MSG_RESULT()

View File

@@ -26,6 +26,7 @@
#define RERR_PROTOCOL 2 /* protocol incompatibility */
#define RERR_FILESELECT 3 /* errors selecting input/output files, dirs */
#define RERR_UNSUPPORTED 4 /* requested action not supported */
#define RERR_STARTCLIENT 5 /* error starting client-server protocol */
#define RERR_SOCKETIO 10 /* error in socket IO */
#define RERR_FILEIO 11 /* error in file IO */

View File

@@ -201,9 +201,11 @@ void add_exclude_list(const char *pattern, struct exclude_struct ***list, int in
if (!*list || !((*list)[len] = make_exclude(pattern, include)))
out_of_memory("add_exclude");
if (verbose > 2)
rprintf(FINFO,"add_exclude(%s)\n",pattern);
if (verbose > 2) {
rprintf(FINFO,"add_exclude(%s,%s)\n",pattern,
include ? "include" : "exclude");
}
(*list)[len+1] = NULL;
}
@@ -260,7 +262,10 @@ void send_exclude_list(int f)
extern int remote_version;
extern int list_only, recurse;
/* this is a complete hack - blame Rusty */
/* This is a complete hack - blame Rusty.
*
* FIXME: This pattern shows up in the output of
* report_exclude_result(), which is not ideal. */
if (list_only && !recurse) {
add_exclude("/*/*", 0);
}
@@ -299,7 +304,8 @@ void send_exclude_list(int f)
void recv_exclude_list(int f)
{
char line[MAXPATHLEN];
int l;
unsigned int l;
while ((l=read_int(f))) {
if (l >= MAXPATHLEN) overflow("recv_exclude_list");
read_sbuf(f,line,l);

View File

@@ -1,5 +1,6 @@
/*
Copyright (C) Andrew Tridgell 1998
Copyright (C) 2002 by Martin Pool
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
@@ -36,9 +37,9 @@ int sparse_end(int f)
}
static int write_sparse(int f,char *buf,int len)
static int write_sparse(int f,char *buf,size_t len)
{
int l1=0,l2=0;
size_t l1=0, l2=0;
int ret;
for (l1=0;l1<len && buf[l1]==0;l1++) ;
@@ -56,10 +57,11 @@ static int write_sparse(int f,char *buf,int len)
if (l1 == len)
return len;
if ((ret=write(f,buf+l1,len-(l1+l2))) != len-(l1+l2)) {
if (ret == -1 || ret == 0) return ret;
ret = write(f, buf + l1, len - (l1+l2));
if (ret == -1 || ret == 0)
return ret;
else if (ret != (int) (len - (l1+l2)))
return (l1+ret);
}
if (l2 > 0)
do_lseek(f,l2,SEEK_CUR);
@@ -69,7 +71,7 @@ static int write_sparse(int f,char *buf,int len)
int write_file(int f,char *buf,int len)
int write_file(int f,char *buf,size_t len)
{
int ret = 0;

951
flist.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,10 @@
/* -*- c-file-style: "linux" -*-
rsync -- fast file replication program
Copyright (C) 1996-2000 by Andrew Tridgell
Copyright (C) Paul Mackerras 1996
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
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,6 +31,7 @@ extern int am_root;
extern int preserve_devices;
extern int preserve_hard_links;
extern int update_only;
extern int opt_ignore_existing;
extern int whole_file;
extern int block_size;
extern int csum_length;
@@ -99,25 +103,30 @@ static int adapt_block_size(struct file_struct *file, int bsize)
/*
send a sums struct down a fd
*/
static void send_sums(struct sum_struct *s,int f_out)
static void send_sums(struct sum_struct *s, int f_out)
{
int i;
/* tell the other guy how many we are going to be doing and how many
bytes there are in the last chunk */
write_int(f_out,s?s->count:0);
write_int(f_out,s?s->n:block_size);
write_int(f_out,s?s->remainder:0);
if (s) {
size_t i;
if (!s) return;
/* tell the other guy how many we are going to be
doing and how many bytes there are in the last
chunk */
write_int(f_out, s->count);
write_int(f_out, s->n);
write_int(f_out, s->remainder);
for (i=0;i<s->count;i++) {
write_int(f_out,s->sums[i].sum1);
write_buf(f_out,s->sums[i].sum2,csum_length);
for (i = 0; i < s->count; i++) {
write_int(f_out, s->sums[i].sum1);
write_buf(f_out, s->sums[i].sum2, csum_length);
}
} else {
/* we don't have checksums */
write_int(f_out, 0);
write_int(f_out, block_size);
write_int(f_out, 0);
}
}
/*
generate a stream of signatures/checksums that describe a buffer
@@ -210,7 +219,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
if (only_existing && statret == -1 && errno == ENOENT) {
/* we only want to update existing files */
if (verbose > 1) rprintf(FINFO,"not creating %s\n",fname);
if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
return;
}
@@ -230,10 +239,11 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
* we need to delete it. If it doesn't exist, then
* recursively create it. */
if (dry_run) return;
if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
if (statret == 0 && !S_ISDIR(st.st_mode)) {
if (robust_unlink(fname) != 0) {
rprintf(FERROR,"recv_generator: unlink %s: %s\n",
rprintf(FERROR, RSYNC_NAME
": recv_generator: unlink \"%s\" to make room for directory: %s\n",
fname,strerror(errno));
return;
}
@@ -243,11 +253,13 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
if (!(relative_paths && errno==ENOENT &&
create_directory_path(fname)==0 &&
do_mkdir(fname,file->mode)==0)) {
rprintf(FERROR,"recv_generator: mkdir %s: %s (2)\n",
rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
fname,strerror(errno));
}
}
if (set_perms(fname,file,NULL,0) && verbose)
/* f_out is set to -1 when doing final directory
permission and modification time repair */
if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
rprintf(FINFO,"%s/\n",fname);
return;
}
@@ -260,7 +272,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
if (safe_symlinks && unsafe_symlink(file->link, fname)) {
if (verbose) {
rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n",
rprintf(FINFO,"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
fname,file->link);
}
return;
@@ -269,21 +281,26 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
l = readlink(fname,lnk,MAXPATHLEN-1);
if (l > 0) {
lnk[l] = 0;
/* A link already pointing to the
* right place -- no further action
* required. */
if (strcmp(lnk,file->link) == 0) {
set_perms(fname,file,&st,1);
return;
}
}
}
/* Not a symlink, so delete whatever's
* already there and put a new symlink
* in place. */
delete_file(fname);
}
if (do_symlink(file->link,fname) != 0) {
rprintf(FERROR,"symlink %s -> %s : %s\n",
rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
fname,file->link,strerror(errno));
} else {
set_perms(fname,file,NULL,0);
if (verbose) {
rprintf(FINFO,"%s -> %s\n",
fname,file->link);
rprintf(FINFO,"%s -> %s\n", fname,file->link);
}
}
#endif
@@ -315,12 +332,12 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
if (preserve_hard_links && check_hard_link(file)) {
if (verbose > 1)
rprintf(FINFO,"%s is a hard link\n",f_name(file));
rprintf(FINFO, "\"%s\" is a hard link\n",f_name(file));
return;
}
if (!S_ISREG(file->mode)) {
rprintf(FINFO,"skipping non-regular file %s\n",fname);
rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
return;
}
@@ -345,7 +362,9 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
if (!dry_run) send_sums(NULL,f_out);
} else {
if (verbose > 1)
rprintf(FERROR,"recv_generator failed to open %s\n",fname);
rprintf(FERROR, RSYNC_NAME
": recv_generator failed to open \"%s\": %s\n",
fname, strerror(errno));
}
return;
}
@@ -361,6 +380,12 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
return;
}
if (opt_ignore_existing && fnamecmp == fname) {
if (verbose > 1)
rprintf(FINFO,"%s exists\n",fname);
return;
}
if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
if (verbose > 1)
rprintf(FINFO,"%s is newer\n",fname);
@@ -388,7 +413,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
fd = do_open(fnamecmp, O_RDONLY, 0);
if (fd == -1) {
rprintf(FERROR,"failed to open %s, continuing : %s\n",fnamecmp,strerror(errno));
rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
/* pretend the file didn't exist */
write_int(f_out,i);
send_sums(NULL,f_out);

151
hlink.c
View File

@@ -1,6 +1,7 @@
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
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,19 +24,22 @@ extern int dry_run;
extern int verbose;
#if SUPPORT_HARD_LINKS
static int hlink_compare(struct file_struct *f1,struct file_struct *f2)
static int hlink_compare(struct file_struct *f1, struct file_struct *f2)
{
if (!S_ISREG(f1->mode) && !S_ISREG(f2->mode)) return 0;
if (!S_ISREG(f1->mode)) return -1;
if (!S_ISREG(f2->mode)) return 1;
if (!S_ISREG(f1->mode) && !S_ISREG(f2->mode))
return 0;
if (!S_ISREG(f1->mode))
return -1;
if (!S_ISREG(f2->mode))
return 1;
if (f1->dev != f2->dev)
return (int)(f1->dev>f2->dev?1:-1);
if (f1->dev != f2->dev)
return (int) (f1->dev > f2->dev ? 1 : -1);
if (f1->inode != f2->inode)
return (int)(f1->inode>f2->inode?1:-1);
if (f1->inode != f2->inode)
return (int) (f1->inode > f2->inode ? 1 : -1);
return file_compare(&f1,&f2);
return file_compare(&f1, &f2);
}
@@ -47,22 +51,25 @@ void init_hard_links(struct file_list *flist)
{
#if SUPPORT_HARD_LINKS
int i;
if (flist->count < 2) return;
if (flist->count < 2)
return;
if (hlink_list) free(hlink_list);
if (!(hlink_list =
(struct file_struct *)malloc(sizeof(hlink_list[0])*flist->count)))
if (hlink_list)
free(hlink_list);
if (!(hlink_list =
(struct file_struct *) malloc(sizeof(hlink_list[0]) *
flist->count)))
out_of_memory("init_hard_links");
for (i = 0; i < flist->count; i++)
memcpy(&hlink_list[i], flist->files[i], sizeof(hlink_list[0]));
memcpy(&hlink_list[i], flist->files[i],
sizeof(hlink_list[0]));
qsort(hlink_list,flist->count,
sizeof(hlink_list[0]),
(int (*)())hlink_compare);
qsort(hlink_list, flist->count,
sizeof(hlink_list[0]), (int (*)()) hlink_compare);
hlink_count=flist->count;
hlink_count = flist->count;
#endif
}
@@ -71,86 +78,102 @@ void init_hard_links(struct file_list *flist)
int check_hard_link(struct file_struct *file)
{
#if SUPPORT_HARD_LINKS
int low=0,high=hlink_count-1;
int ret=0;
int low = 0, high = hlink_count - 1;
int ret = 0;
if (!hlink_list || !S_ISREG(file->mode)) return 0;
if (!hlink_list || !S_ISREG(file->mode))
return 0;
while (low != high) {
int mid = (low+high)/2;
ret = hlink_compare(&hlink_list[mid],file);
if (ret == 0) {
low = mid;
break;
}
if (ret > 0)
high=mid;
else
low=mid+1;
}
while (low != high) {
int mid = (low + high) / 2;
ret = hlink_compare(&hlink_list[mid], file);
if (ret == 0) {
low = mid;
break;
}
if (ret > 0)
high = mid;
else
low = mid + 1;
}
if (hlink_compare(&hlink_list[low],file) != 0) return 0;
if (hlink_compare(&hlink_list[low], file) != 0)
return 0;
if (low > 0 &&
S_ISREG(hlink_list[low-1].mode) &&
file->dev == hlink_list[low-1].dev &&
file->inode == hlink_list[low-1].inode)
return 1;
if (low > 0 &&
S_ISREG(hlink_list[low - 1].mode) &&
file->dev == hlink_list[low - 1].dev &&
file->inode == hlink_list[low - 1].inode)
return 1;
#endif
return 0;
return 0;
}
#if SUPPORT_HARD_LINKS
static void hard_link_one(int i)
{
STRUCT_STAT st1,st2;
STRUCT_STAT st1, st2;
if (link_stat(f_name(&hlink_list[i-1]),&st1) != 0) return;
if (link_stat(f_name(&hlink_list[i - 1]), &st1) != 0)
return;
if (link_stat(f_name(&hlink_list[i]),&st2) != 0) {
if (do_link(f_name(&hlink_list[i-1]),f_name(&hlink_list[i])) != 0) {
if (link_stat(f_name(&hlink_list[i]), &st2) != 0) {
if (do_link
(f_name(&hlink_list[i - 1]),
f_name(&hlink_list[i])) != 0) {
if (verbose > 0)
rprintf(FINFO,"link %s => %s : %s\n",
rprintf(FINFO, "link %s => %s : %s\n",
f_name(&hlink_list[i]),
f_name(&hlink_list[i-1]),strerror(errno));
f_name(&hlink_list[i - 1]),
strerror(errno));
return;
}
} else {
if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino) return;
if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino)
return;
if (robust_unlink(f_name(&hlink_list[i])) != 0 ||
do_link(f_name(&hlink_list[i-1]),f_name(&hlink_list[i])) != 0) {
do_link(f_name(&hlink_list[i - 1]),
f_name(&hlink_list[i])) != 0) {
if (verbose > 0)
rprintf(FINFO,"link %s => %s : %s\n",
rprintf(FINFO, "link %s => %s : %s\n",
f_name(&hlink_list[i]),
f_name(&hlink_list[i-1]),strerror(errno));
f_name(&hlink_list[i - 1]),
strerror(errno));
return;
}
}
if (verbose > 0)
rprintf(FINFO,"%s => %s\n",
f_name(&hlink_list[i]),f_name(&hlink_list[i-1]));
rprintf(FINFO, "%s => %s\n",
f_name(&hlink_list[i]),
f_name(&hlink_list[i - 1]));
}
#endif
/* create any hard links in the flist */
void do_hard_links(struct file_list *flist)
/**
* Create any hard links in the global hlink_list. They were put
* there by running init_hard_links on the filelist.
**/
void do_hard_links(void)
{
#if SUPPORT_HARD_LINKS
int i;
if (!hlink_list) return;
for (i=1;i<hlink_count;i++) {
if (!hlink_list)
return;
for (i = 1; i < hlink_count; i++) {
if (S_ISREG(hlink_list[i].mode) &&
S_ISREG(hlink_list[i-1].mode) &&
hlink_list[i].basename && hlink_list[i-1].basename &&
hlink_list[i].dev == hlink_list[i-1].dev &&
hlink_list[i].inode == hlink_list[i-1].inode) {
S_ISREG(hlink_list[i - 1].mode) &&
hlink_list[i].basename && hlink_list[i - 1].basename &&
hlink_list[i].dev == hlink_list[i - 1].dev &&
hlink_list[i].inode == hlink_list[i - 1].inode) {
hard_link_one(i);
}
}
}
#endif
}

92
io.c
View File

@@ -19,11 +19,22 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
socket and pipe IO utilities used in rsync
/**
*
* @file io.c
*
* Socket and pipe IO utilities used in rsync.
*
* rsync provides its own multiplexing system, which is used to send
* stderr and stdout over a single socket. We need this because
* stdout normally carries the binary data stream, and stderr all our
* error messages.
*
* For historical reasons this is off during the start of the
* connection, but it's switched on quite early using
* io_start_multiplex_out() and io_start_multiplex_in().
**/
tridge, June 1996
*/
#include "rsync.h"
/* if no timeout is specified then use a 60 second select timeout */
@@ -49,7 +60,7 @@ int kludge_around_eof = False;
static int io_error_fd = -1;
static void read_loop(int fd, char *buf, int len);
static void read_loop(int fd, char *buf, size_t len);
static void check_timeout(void)
{
@@ -86,7 +97,7 @@ void io_set_error_fd(int fd)
static void read_error_fd(void)
{
char buf[200];
int n;
size_t n;
int fd = io_error_fd;
int tag, len;
@@ -103,7 +114,8 @@ static void read_error_fd(void)
while (len) {
n = len;
if (n > (sizeof(buf)-1)) n = sizeof(buf)-1;
if (n > (sizeof(buf)-1))
n = sizeof(buf)-1;
read_loop(fd, buf, n);
rwrite((enum logcode)tag, buf, n);
len -= n;
@@ -163,7 +175,7 @@ static void die_from_readerr (int err)
* give a better explanation. We can tell whether the connection has
* started by looking e.g. at whether the remote version is known yet.
*/
static int read_timeout (int fd, char *buf, int len)
static int read_timeout (int fd, char *buf, size_t len)
{
int n, ret=0;
@@ -236,7 +248,7 @@ static int read_timeout (int fd, char *buf, int len)
/*! Continue trying to read len bytes - don't return until len has
been read. */
static void read_loop (int fd, char *buf, int len)
static void read_loop (int fd, char *buf, size_t len)
{
while (len) {
int n = read_timeout(fd, buf, len);
@@ -253,10 +265,10 @@ static void read_loop (int fd, char *buf, int len)
*
* Never returns <= 0.
*/
static int read_unbuffered(int fd, char *buf, int len)
static int read_unbuffered(int fd, char *buf, size_t len)
{
static int remaining;
int tag, ret=0;
static size_t remaining;
int tag, ret = 0;
char line[1024];
if (!io_multiplexing_in || fd != multiplex_in_fd)
@@ -271,23 +283,24 @@ static int read_unbuffered(int fd, char *buf, int len)
continue;
}
read_loop (fd, line, 4);
read_loop(fd, line, 4);
tag = IVAL(line, 0);
remaining = tag & 0xFFFFFF;
tag = tag >> 24;
if (tag == MPLEX_BASE) continue;
if (tag == MPLEX_BASE)
continue;
tag -= MPLEX_BASE;
if (tag != FERROR && tag != FINFO) {
rprintf(FERROR,"unexpected tag %d\n", tag);
rprintf(FERROR, "unexpected tag %d\n", tag);
exit_cleanup(RERR_STREAMIO);
}
if (remaining > sizeof(line)-1) {
rprintf(FERROR,"multiplexing overflow %d\n\n",
if (remaining > sizeof(line) - 1) {
rprintf(FERROR, "multiplexing overflow %d\n\n",
remaining);
exit_cleanup(RERR_STREAMIO);
}
@@ -295,7 +308,7 @@ static int read_unbuffered(int fd, char *buf, int len)
read_loop(fd, line, remaining);
line[remaining] = 0;
rprintf((enum logcode)tag,"%s", line);
rprintf((enum logcode) tag, "%s", line);
remaining = 0;
}
@@ -303,12 +316,13 @@ static int read_unbuffered(int fd, char *buf, int len)
}
/* do a buffered read from fd. don't return until all N bytes
have been read. If all N can't be read then exit with an error */
static void readfd (int fd, char *buffer, int N)
static void readfd (int fd, char *buffer, size_t N)
{
int ret;
int total=0;
size_t total=0;
while (total < N) {
io_flush();
@@ -356,12 +370,12 @@ int64 read_longint(int f)
return ret;
}
void read_buf(int f,char *buf,int len)
void read_buf(int f,char *buf,size_t len)
{
readfd(f,buf,len);
}
void read_sbuf(int f,char *buf,int len)
void read_sbuf(int f,char *buf,size_t len)
{
read_buf (f,buf,len);
buf[len] = 0;
@@ -374,10 +388,11 @@ unsigned char read_byte(int f)
return c;
}
/* write len bytes to fd */
static void writefd_unbuffered(int fd,char *buf,int len)
/* Write len bytes to fd. This underlies the multiplexing system,
* which is always called by application code. */
static void writefd_unbuffered(int fd,char *buf,size_t len)
{
int total = 0;
size_t total = 0;
fd_set w_fds, r_fds;
int fd_count, count;
struct timeval tv;
@@ -424,7 +439,8 @@ static void writefd_unbuffered(int fd,char *buf,int len)
}
if (FD_ISSET(fd, &w_fds)) {
int ret, n = len-total;
int ret;
size_t n = len-total;
ret = write(fd,buf+total,n);
if (ret == -1 && errno == EINTR) {
@@ -438,8 +454,11 @@ static void writefd_unbuffered(int fd,char *buf,int len)
}
if (ret <= 0) {
rprintf(FERROR,
"error writing %d unbuffered bytes"
/* Don't try to write errors back
* across the stream */
io_multiplexing_close();
rprintf(FERROR, RSYNC_NAME
": error writing %d unbuffered bytes"
" - exiting: %s\n", len,
strerror(errno));
exit_cleanup(RERR_STREAMIO);
@@ -483,10 +502,10 @@ void io_start_buffering(int fd)
/* write an message to a multiplexed stream. If this fails then rsync
exits */
static void mplex_write(int fd, enum logcode code, char *buf, int len)
static void mplex_write(int fd, enum logcode code, char *buf, size_t len)
{
char buffer[4096];
int n = len;
size_t n = len;
SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
@@ -523,8 +542,7 @@ void io_flush(void)
}
/* XXX: fd is ignored, which seems a little strange. */
void io_end_buffering(int fd)
void io_end_buffering(void)
{
io_flush();
if (!io_multiplexing_out) {
@@ -533,7 +551,7 @@ void io_end_buffering(int fd)
}
}
static void writefd(int fd,char *buf,int len)
static void writefd(int fd,char *buf,size_t len)
{
stats.total_written += len;
@@ -545,7 +563,7 @@ static void writefd(int fd,char *buf,int len)
}
while (len) {
int n = MIN(len, IO_BUFFER_SIZE-io_buffer_count);
int n = MIN((int) len, IO_BUFFER_SIZE-io_buffer_count);
if (n > 0) {
memcpy(io_buffer+io_buffer_count, buf, n);
buf += n;
@@ -587,7 +605,7 @@ void write_longint(int f, int64 x)
writefd(f,b,8);
}
void write_buf(int f,char *buf,int len)
void write_buf(int f,char *buf,size_t len)
{
writefd(f,buf,len);
}
@@ -606,7 +624,7 @@ void write_byte(int f,unsigned char c)
int read_line(int f, char *buf, int maxlen)
int read_line(int f, char *buf, size_t maxlen)
{
while (maxlen) {
buf[0] = 0;
@@ -664,7 +682,7 @@ void io_start_multiplex_in(int fd)
}
/* write an message to the multiplexed error stream */
int io_multiplex_write(enum logcode code, char *buf, int len)
int io_multiplex_write(enum logcode code, char *buf, size_t len)
{
if (!io_multiplexing_out) return 0;

View File

@@ -97,8 +97,10 @@
#ifndef HAVE_STRLCPY
/* like strncpy but does not 0 fill the buffer and always null
terminates. bufsize is the size of the destination buffer */
/* Like strncpy but does not 0 fill the buffer and always null
* terminates. bufsize is the size of the destination buffer.
*
* Returns the index of the terminating byte. */
size_t strlcpy(char *d, const char *s, size_t bufsize)
{
size_t len = strlen(s);

58
log.c
View File

@@ -41,6 +41,7 @@ struct {
{ RERR_PROTOCOL , "protocol incompatibility" },
{ RERR_FILESELECT , "errors selecting input/output files, dirs" },
{ RERR_UNSUPPORTED, "requested action not supported" },
{ RERR_STARTCLIENT, "error starting client-server protocol" },
{ RERR_SOCKETIO , "error in socket IO" },
{ RERR_FILEIO , "error in file IO" },
{ RERR_STREAMIO , "error in rsync protocol data stream" },
@@ -236,7 +237,11 @@ void rwrite(enum logcode code, char *buf, int len)
return;
}
/* if that fails, try to pass it to the other end */
/* If that fails, try to pass it to the other end.
*
* io_multiplex_write can fail if we do not have a multiplexed
* connection at the moment, in which case we fall through and
* log locally instead. */
if (am_server && io_multiplex_write(code, buf, len)) {
return;
}
@@ -286,13 +291,14 @@ void rprintf(enum logcode code, const char *format, ...)
int len;
va_start(ap, format);
/* Note: might return -1 */
len = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
/* Deal with buffer overruns. Instead of panicking, just
* truncate the resulting string. Note that some vsnprintf()s
* return -1 on truncation, e.g., glibc 2.0.6 and earlier. */
if (len > sizeof(buf)-1 || len < 0) {
if ((size_t) len > sizeof(buf)-1 || len < 0) {
const char ellipsis[] = "[...]";
/* Reset length, and zero-terminate the end of our buffer */
@@ -331,18 +337,23 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
{
va_list ap;
char buf[1024];
int len, sys_len;
int len;
size_t sys_len;
char *sysmsg;
va_start(ap, format);
/* Note: might return <0 */
len = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
if (len > sizeof(buf)-1) exit_cleanup(RERR_MESSAGEIO);
/* TODO: Put in RSYNC_NAME at the start. */
if ((size_t) len > sizeof(buf)-1)
exit_cleanup(RERR_MESSAGEIO);
sysmsg = strerror(errcode);
sys_len = strlen(sysmsg);
if (len + 3 + sys_len > sizeof(buf) - 1)
if ((size_t) len + 3 + sys_len > sizeof(buf) - 1)
exit_cleanup(RERR_MESSAGEIO);
strcpy(buf + len, ": ");
@@ -399,12 +410,18 @@ static void log_formatted(enum logcode code,
char buf[1024];
char buf2[1024];
char *p, *s, *n;
int l;
size_t l;
extern struct stats stats;
extern int am_sender;
extern int am_daemon;
int64 b;
/* We expand % codes one by one in place in buf. We don't
* copy in the terminating nul of the inserted strings, but
* rather keep going until we reach the nul of the format.
* Just to make sure we don't clobber that nul and therefore
* accidentally keep going, we zero the buffer now. */
memset(buf, 0, sizeof buf);
strlcpy(buf, format, sizeof(buf));
for (s=&buf[0];
@@ -462,21 +479,30 @@ static void log_formatted(enum logcode code,
break;
}
if (!n) continue;
/* n is the string to be inserted in place of this %
* code; l is its length not including the trailing
* NUL */
if (!n)
continue;
l = strlen(n);
if ((l-1) + ((int)(s - &buf[0])) > sizeof(buf)) {
if (l + ((int)(s - &buf[0])) >= sizeof(buf)) {
rprintf(FERROR,"buffer overflow expanding %%%c - exiting\n",
p[0]);
exit_cleanup(RERR_MESSAGEIO);
}
/* Shuffle the rest of the string along to make space for n */
if (l != 2) {
memmove(s+(l-1), s+1, strlen(s+1)+1);
}
/* Copy in n but NOT its nul, because the format sting
* probably continues after this. */
memcpy(p, n, l);
/* Skip over inserted string; continue looking */
s = p+l;
}
@@ -540,20 +566,16 @@ void log_exit(int code, const char *file, int line)
}
}
/* log the incoming transfer of a file for interactive use, this
will be called at the end where the client was run
it i called when a file starts to be transferred
*/
/*
* Log the incoming transfer of a file for interactive use,
* this will be called at the end where the client was run.
* Called when a file starts to be transferred.
*/
void log_transfer(struct file_struct *file, const char *fname)
{
extern int verbose;
if (!verbose) return;
rprintf(FINFO,"%s\n", fname);
rprintf(FINFO, "%s\n", fname);
}

126
main.c
View File

@@ -2,7 +2,7 @@
Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) Paul Mackerras 1996
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
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 @@ struct stats stats;
extern int verbose;
static void show_malloc_stats(void);
/****************************************************************************
wait for a process to exit, calling io_flush while waiting
@@ -56,6 +57,12 @@ static void report(int f)
extern int remote_version;
int send_stats;
if (do_stats) {
/* These come out from every process */
show_malloc_stats();
show_flist_stats();
}
if (am_daemon) {
log_exit(0, __FILE__, __LINE__);
if (f == -1 || !am_sender) return;
@@ -126,6 +133,38 @@ static void report(int f)
}
/**
* If our C library can get malloc statistics, then show them to FINFO
**/
static void show_malloc_stats(void)
{
#ifdef HAVE_MALLINFO
struct mallinfo mi;
extern int am_server;
extern int am_sender;
extern int am_daemon;
mi = mallinfo();
rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
getpid(),
am_server ? "server " : "",
am_daemon ? "daemon " : "",
am_sender ? "sender" : "receiver");
rprintf(FINFO, " arena: %10d (bytes from sbrk)\n", mi.arena);
rprintf(FINFO, " ordblks: %10d (chunks not in use)\n", mi.ordblks);
rprintf(FINFO, " smblks: %10d\n", mi.smblks);
rprintf(FINFO, " hblks: %10d (chunks from mmap)\n", mi.hblks);
rprintf(FINFO, " hblkhd: %10d (bytes from mmap)\n", mi.hblkhd);
rprintf(FINFO, " usmblks: %10d\n", mi.usmblks);
rprintf(FINFO, " fsmblks: %10d\n", mi.fsmblks);
rprintf(FINFO, " uordblks: %10d (bytes used)\n", mi.uordblks);
rprintf(FINFO, " fordblks: %10d (bytes free)\n", mi.fordblks);
rprintf(FINFO, " keepcost: %10d (bytes in releasable chunk)\n", mi.keepcost);
#endif /* HAVE_MALLINFO */
}
/* Start the remote shell. cmd may be NULL to use the default. */
static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
{
@@ -138,7 +177,7 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
extern int blocking_io;
extern int read_batch;
if (!read_batch && !local_server) { /* dw -- added read_batch */
if (!read_batch && !local_server) {
if (!cmd)
cmd = getenv(RSYNC_RSH_ENV);
if (!cmd)
@@ -168,10 +207,11 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
args[argc++] = rsync_path;
if ((blocking_io == -1) && (strcmp(cmd, RSYNC_RSH) == 0))
blocking_io = 1;
server_options(args,&argc);
if (strcmp(cmd, RSYNC_RSH) == 0) blocking_io = 1;
}
args[argc++] = ".";
@@ -190,7 +230,7 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
if (local_server) {
if (read_batch)
create_flist_from_batch();
create_flist_from_batch(); /* sets batch_flist */
ret = local_child(argc, args, f_in, f_out);
} else {
ret = piped_child(args,f_in,f_out);
@@ -240,7 +280,8 @@ static char *get_local_name(struct file_list *flist,char *name)
return name;
if (do_mkdir(name,0777 & ~orig_umask) != 0) {
rprintf(FERROR,"mkdir %s : %s (1)\n",name,strerror(errno));
rprintf(FERROR, RSYNC_NAME ": mkdir %s: %s\n",
name, strerror(errno));
exit_cleanup(RERR_FILEIO);
} else {
if (verbose > 0)
@@ -248,8 +289,8 @@ static char *get_local_name(struct file_list *flist,char *name)
}
if (!push_dir(name, 0)) {
rprintf(FERROR,"push_dir %s : %s (2)\n",
name,strerror(errno));
rprintf(FERROR, RSYNC_NAME ": push_dir %s: %s\n",
name, strerror(errno));
exit_cleanup(RERR_FILESELECT);
}
@@ -403,8 +444,8 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
extern int am_daemon;
extern int module_id;
extern int am_sender;
extern int read_batch; /* dw */
extern struct file_list *batch_flist; /* dw */
extern int read_batch;
extern struct file_list *batch_flist;
if (verbose > 2)
rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
@@ -430,7 +471,7 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
if (delete_mode && !delete_excluded)
recv_exclude_list(f_in);
if (read_batch) /* dw */
if (read_batch)
flist = batch_flist;
else
flist = recv_file_list(f_in);
@@ -457,7 +498,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
extern int cvs_exclude;
extern int am_sender;
extern int remote_version;
extern int read_batch; /* dw */
extern int read_batch;
setup_protocol(f_out, f_in);
@@ -468,7 +509,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
io_start_multiplex_out(f_out);
if (am_sender) {
if (!read_batch) { /* dw */
if (!read_batch) {
recv_exclude_list(f_in);
if (cvs_exclude)
add_cvs_excludes();
@@ -487,19 +528,19 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
*/
int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
{
struct file_list *flist;
struct file_list *flist = NULL;
int status = 0, status2 = 0;
char *local_name = NULL;
extern int am_sender;
extern int remote_version;
extern pid_t cleanup_child_pid;
extern int write_batch; /* dw */
extern int read_batch; /* dw */
extern struct file_list *batch_flist; /* dw */
extern int write_batch;
extern int read_batch;
extern struct file_list *batch_flist;
cleanup_child_pid = pid;
if (read_batch)
flist = batch_flist; /* dw */
flist = batch_flist;
set_nonblocking(f_in);
set_nonblocking(f_out);
@@ -542,7 +583,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
list_only = 1;
}
if (!write_batch) /* dw */
if (!write_batch)
send_exclude_list(f_out);
flist = recv_file_list(f_in);
@@ -618,6 +659,7 @@ static int start_client(int argc, char *argv[])
extern char *shell_cmd;
extern int rsync_port;
extern int whole_file;
extern int write_batch;
extern int read_batch;
int rc;
@@ -645,7 +687,7 @@ static int start_client(int argc, char *argv[])
return start_socket_client(host, path, argc-1, argv+1);
}
if (!read_batch) { /* dw */
if (!read_batch) {
p = find_colon(argv[0]);
if (p) {
@@ -671,8 +713,12 @@ static int start_client(int argc, char *argv[])
p = find_colon(argv[argc-1]);
if (!p) {
local_server = 1;
/* disable "rsync algorithm" when both sides local */
whole_file = 1;
/*
* disable "rsync algorithm" when both sides local,
* except when creating a batch update
*/
if (!write_batch && whole_file == -1)
whole_file = 1;
} else if (p[1] == ':') {
*p = 0;
return start_socket_client(argv[argc-1], p+2, argc-1, argv);
@@ -694,9 +740,9 @@ static int start_client(int argc, char *argv[])
argc--;
}
} else {
am_sender = 1; /* dw */
local_server = 1; /* dw */
shell_path = argv[argc-1]; /* dw */
am_sender = 1;
local_server = 1;
shell_path = argv[argc-1];
}
if (shell_machine) {
@@ -761,12 +807,12 @@ int main(int argc,char *argv[])
extern int am_daemon;
extern int am_server;
int ret;
extern int read_batch; /* dw */
extern int write_batch; /* dw */
extern char *batch_ext; /* dw */
int orig_argc; /* dw */
extern int write_batch;
int orig_argc;
char **orig_argv;
orig_argc = argc; /* dw */
orig_argc = argc;
orig_argv = argv;
signal(SIGUSR1, sigusr1_handler);
signal(SIGUSR2, sigusr2_handler);
@@ -794,23 +840,21 @@ int main(int argc,char *argv[])
}
signal(SIGINT,SIGNAL_CAST sig_int);
signal(SIGPIPE,SIGNAL_CAST sig_int);
signal(SIGHUP,SIGNAL_CAST sig_int);
signal(SIGTERM,SIGNAL_CAST sig_int);
/* Ignore SIGPIPE; we consistently check error codes and will
* see the EPIPE. */
signal(SIGPIPE, SIG_IGN);
/* Initialize push_dir here because on some old systems getcwd
(implemented by forking "pwd" and reading its output) doesn't
work when there are other child processes. Also, on all systems
that implement getcwd that way "pwd" can't be found after chroot. */
push_dir(NULL,0);
if (write_batch) { /* dw */
create_batch_file_ext();
write_batch_argvs_file(orig_argc, argc, argv);
}
if (read_batch) { /* dw */
set_batch_file_ext(batch_ext);
if (write_batch && !am_server) {
write_batch_argvs_file(orig_argc, orig_argv);
}
if (am_daemon) {
@@ -839,7 +883,9 @@ int main(int argc,char *argv[])
}
ret = start_client(argc, argv);
exit_cleanup(ret);
if (ret == -1)
exit_cleanup(RERR_STARTCLIENT);
else
exit_cleanup(ret);
return ret;
}

View File

@@ -71,7 +71,7 @@ static void build_hash_table(struct sum_struct *s)
if (!tag_table || !targets)
out_of_memory("build_hash_table");
for (i=0;i<s->count;i++) {
for (i=0;i<(int) s->count;i++) {
targets[i].i = i;
targets[i].t = gettag(s->sums[i].sum1);
}
@@ -175,7 +175,7 @@ static void hash_search(int f,struct sum_struct *s,
sum = (s1 & 0xffff) | (s2 << 16);
tag_hits++;
for (; j<s->count && targets[j].t == t; j++) {
for (; j < (int) s->count && targets[j].t == t; j++) {
int l, i = targets[j].i;
if (sum != s->sums[i].sum1) continue;
@@ -201,7 +201,7 @@ static void hash_search(int f,struct sum_struct *s,
/* we've found a match, but now check to see
if last_i can hint at a better match */
for (j++; j<s->count && targets[j].t == t; j++) {
for (j++; j < (int) s->count && targets[j].t == t; j++) {
int i2 = targets[j].i;
if (i2 == last_i + 1) {
if (sum != s->sums[i2].sum1) break;
@@ -246,7 +246,8 @@ static void hash_search(int f,struct sum_struct *s,
match. The 3 reads are caused by the
running match, the checksum update and the
literal send. */
if (offset-last_match >= CHUNK_SIZE+s->n &&
if (offset > last_match &&
offset-last_match >= CHUNK_SIZE+s->n &&
(end-offset > CHUNK_SIZE)) {
matched(f,s,buf,offset - s->n, -2);
}

126
options.c
View File

@@ -1,7 +1,7 @@
/* -*- c-file-style: "linux" -*-
Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) 2000-2001 by Martin Pool <mbp@samba.org>
Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
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,7 +22,7 @@
#include "popt.h"
int make_backups = 0;
int whole_file = 0;
int whole_file = -1;
int copy_links = 0;
int preserve_links = 0;
int preserve_hard_links = 0;
@@ -65,6 +65,7 @@ int size_only=0;
int bwlimit=0;
int delete_after=0;
int only_existing=0;
int opt_ignore_existing=0;
int max_delete=0;
int ignore_errors=0;
#ifdef _WIN32
@@ -72,13 +73,22 @@ int modify_window=2;
#else
int modify_window=0;
#endif
int blocking_io=0;
int blocking_io=-1;
/** Global options set from command line. **/
struct global_opts global_opts;
/** Network address family. **/
#ifdef INET6
int default_af_hint = 0; /* Any protocol */
#else
int default_af_hint = AF_INET; /* Must use IPv4 */
#endif
int read_batch=0; /* dw */
int write_batch=0; /* dw */
/** Do not go into the background when run as --daemon. Good
* for debugging and required for running as a service on W32,
* or under Unix process-monitors. **/
int no_detach = 0;
int write_batch = 0;
int read_batch = 0;
char *backup_suffix = BACKUP_SUFFIX;
char *tmpdir = NULL;
@@ -96,7 +106,7 @@ int quiet = 0;
int always_checksum = 0;
int list_only = 0;
char *batch_ext = NULL;
char *batch_prefix = NULL;
static int modify_window_set;
@@ -106,12 +116,13 @@ static int modify_window_set;
char *bind_address;
static void print_rsync_version(int f)
static void print_rsync_version(enum logcode f)
{
char const *got_socketpair = "no ";
char const *hardlinks = "no ";
char const *links = "no ";
char const *ipv6 = "no ";
STRUCT_STAT *dumstat;
#ifdef HAVE_SOCKETPAIR
got_socketpair = "";
@@ -132,13 +143,20 @@ static void print_rsync_version(int f)
rprintf(f, "%s version %s protocol version %d\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
rprintf(f,
"Copyright (C) 1996-2001 by Andrew Tridgell and others\n");
"Copyright (C) 1996-2002 by Andrew Tridgell and others\n");
rprintf(f, "<http://rsync.samba.org/>\n");
rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
"%shard links, %ssymlinks, batchfiles, %sIPv6\n\n",
"%shard links, %ssymlinks, batchfiles, %sIPv6,\n",
(int) (sizeof(OFF_T) * 8),
got_socketpair, hardlinks, links, ipv6);
/* Note that this field may not have type ino_t. It depends
* on the complicated interaction between largefile feature
* macros. */
rprintf(f, " %d-bit system inums, %d-bit internal inums\n",
(int) (sizeof(dumstat->st_ino) * 8),
(int) (sizeof(INO64_T) * 8));
#ifdef NO_INT64
rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
#endif
@@ -171,8 +189,8 @@ void usage(enum logcode F)
rprintf(F," --backup-dir make backups into this directory\n");
rprintf(F," --suffix=SUFFIX override backup suffix\n");
rprintf(F," -u, --update update only (don't overwrite newer files)\n");
rprintf(F," -l, --links preserve soft links\n");
rprintf(F," -L, --copy-links treat soft links like regular files\n");
rprintf(F," -l, --links copy symlinks as symlinks\n");
rprintf(F," -L, --copy-links copy the referent of symlinks\n");
rprintf(F," --copy-unsafe-links copy links outside the source tree\n");
rprintf(F," --safe-links ignore links outside the destination tree\n");
rprintf(F," -H, --hard-links preserve hard links\n");
@@ -184,12 +202,14 @@ void usage(enum logcode F)
rprintf(F," -S, --sparse handle sparse files efficiently\n");
rprintf(F," -n, --dry-run show what would have been transferred\n");
rprintf(F," -W, --whole-file copy whole files, no incremental checks\n");
rprintf(F," --no-whole-file turn off --whole-file\n");
rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
rprintf(F," -B, --block-size=SIZE checksum blocking size (default %d)\n",BLOCK_SIZE);
rprintf(F," -e, --rsh=COMMAND specify rsh replacement\n");
rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
rprintf(F," --existing only update files that already exist\n");
rprintf(F," --ignore-existing ignore files that already exist on the receiving side\n");
rprintf(F," --delete delete files that don't exist on the sending side\n");
rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
rprintf(F," --delete-after delete after transferring, not before\n");
@@ -212,17 +232,19 @@ void usage(enum logcode F)
rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n");
rprintf(F," --version print version number\n");
rprintf(F," --daemon run as a rsync daemon\n");
rprintf(F," --address bind to the specified address\n");
rprintf(F," --no-detach do not detach from the parent\n");
rprintf(F," --address=ADDRESS bind to the specified address\n");
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
rprintf(F," --port=PORT specify alternate rsyncd port number\n");
rprintf(F," --blocking-io use blocking IO for the remote shell\n");
rprintf(F," --no-blocking-io turn off --blocking-io\n");
rprintf(F," --stats give some file transfer stats\n");
rprintf(F," --progress show progress during transfer\n");
rprintf(F," --log-format=FORMAT log file transfers using specified format\n");
rprintf(F," --password-file=FILE get password from FILE\n");
rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
rprintf(F," -f --read-batch=EXT read batch file\n");
rprintf(F," -F --write-batch write batch file\n");
rprintf(F," --write-batch=PREFIX write batch fileset starting with PREFIX\n");
rprintf(F," --read-batch=PREFIX read batch fileset starting with PREFIX\n");
rprintf(F," -h, --help show this help screen\n");
#ifdef INET6
rprintf(F," -4 prefer IPv4\n");
@@ -243,7 +265,8 @@ enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR,
OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO,
OPT_MODIFY_WINDOW};
OPT_NO_BLOCKING_IO, OPT_NO_WHOLE_FILE,
OPT_MODIFY_WINDOW, OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_IGNORE_EXISTING};
static struct poptOption long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
@@ -257,6 +280,7 @@ static struct poptOption long_options[] = {
{"one-file-system", 'x', POPT_ARG_NONE, &one_file_system},
{"delete", 0, POPT_ARG_NONE, &delete_mode},
{"existing", 0, POPT_ARG_NONE, &only_existing},
{"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing},
{"delete-after", 0, POPT_ARG_NONE, &delete_after},
{"delete-excluded", 0, POPT_ARG_NONE, 0, OPT_DELETE_EXCLUDED},
{"force", 0, POPT_ARG_NONE, &force_delete},
@@ -274,7 +298,8 @@ static struct poptOption long_options[] = {
{"update", 'u', POPT_ARG_NONE, &update_only},
{"links", 'l', POPT_ARG_NONE, &preserve_links},
{"copy-links", 'L', POPT_ARG_NONE, &copy_links},
{"whole", 'W', POPT_ARG_NONE, &whole_file},
{"whole-file", 'W', POPT_ARG_NONE, &whole_file},
{"no-whole-file", 0, POPT_ARG_NONE, 0, OPT_NO_WHOLE_FILE},
{"copy-unsafe-links", 0, POPT_ARG_NONE, &copy_unsafe_links},
{"perms", 'p', POPT_ARG_NONE, &preserve_perms},
{"owner", 'o', POPT_ARG_NONE, &preserve_uid},
@@ -298,11 +323,13 @@ static struct poptOption long_options[] = {
/* TODO: Should this take an optional int giving the compression level? */
{"compress", 'z', POPT_ARG_NONE, &do_compression},
{"daemon", 0, POPT_ARG_NONE, &am_daemon},
{"no-detach", 0, POPT_ARG_NONE, &no_detach},
{"stats", 0, POPT_ARG_NONE, &do_stats},
{"progress", 0, POPT_ARG_NONE, &do_progress},
{"partial", 0, POPT_ARG_NONE, &keep_partial},
{"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors},
{"blocking-io", 0, POPT_ARG_NONE, &blocking_io},
{"no-blocking-io", 0, POPT_ARG_NONE, 0, OPT_NO_BLOCKING_IO},
{0, 'P', POPT_ARG_NONE, 0, 'P'},
{"config", 0, POPT_ARG_STRING, &config_file},
{"port", 0, POPT_ARG_INT, &rsync_port},
@@ -311,11 +338,11 @@ static struct poptOption long_options[] = {
{"address", 0, POPT_ARG_STRING, &bind_address, 0},
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir},
{"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links},
{"read-batch", 'f', POPT_ARG_STRING, &batch_ext, 'f'},
{"write-batch", 'F', POPT_ARG_NONE, &write_batch, 0},
{"read-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_READ_BATCH},
{"write-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_WRITE_BATCH},
#ifdef INET6
{0, '4', POPT_ARG_VAL, &global_opts.af_hint, AF_INET },
{0, '6', POPT_ARG_VAL, &global_opts.af_hint, AF_INET6 },
{0, '4', POPT_ARG_VAL, &default_af_hint, AF_INET },
{0, '6', POPT_ARG_VAL, &default_af_hint, AF_INET6 },
#endif
{0,0,0,0}
};
@@ -432,8 +459,12 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
add_exclude_file(poptGetOptArg(pc), 1, 0);
break;
case OPT_INCLUDE_FROM:
add_exclude_file(poptGetOptArg(pc), 1, 1);
case OPT_NO_WHOLE_FILE:
whole_file = 0;
break;
case OPT_NO_BLOCKING_IO:
blocking_io = 0;
break;
case 'h':
@@ -491,9 +522,13 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
keep_partial = 1;
break;
case OPT_WRITE_BATCH:
/* popt stores the filename in batch_prefix for us */
write_batch = 1;
break;
case 'f':
/* The filename is stored for us by popt */
case OPT_READ_BATCH:
/* popt stores the filename in batch_prefix for us */
read_batch = 1;
break;
@@ -509,6 +544,22 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
}
}
if (write_batch && read_batch) {
snprintf(err_buf,sizeof(err_buf),
"write-batch and read-batch can not be used together\n");
rprintf(FERROR,"ERROR: write-batch and read-batch"
" can not be used together\n");
return 0;
}
if (do_compression && (write_batch || read_batch)) {
snprintf(err_buf,sizeof(err_buf),
"compress can not be used with write-batch or read-batch\n");
rprintf(FERROR,"ERROR: compress can not be used with"
" write-batch or read-batch\n");
return 0;
}
*argv = poptGetArgs(pc);
if (*argv)
*argc = count_args(*argv);
@@ -530,10 +581,16 @@ void server_options(char **args,int *argc)
static char mdelete[30];
static char mwindow[30];
static char bw[50];
static char fext[20]; /* dw */
/* Leave room for ``--(write|read)-batch='' */
static char fext[MAXPATHLEN + 15];
int i, x;
if (whole_file == -1)
whole_file = 0;
if (blocking_io == -1)
blocking_io = 0;
args[ac++] = "--server";
if (!am_sender)
@@ -585,8 +642,6 @@ void server_options(char **args,int *argc)
argstr[x++] = 'S';
if (do_compression)
argstr[x++] = 'z';
if (write_batch)
argstr[x++] = 'F'; /* dw */
/* this is a complete hack - blame Rusty
@@ -609,8 +664,14 @@ void server_options(char **args,int *argc)
args[ac++] = mdelete;
}
if (batch_ext != NULL) {
sprintf(fext,"-f%s",batch_ext);
if (batch_prefix != NULL) {
char *fmt = "";
if (write_batch)
fmt = "--write-batch=%s";
else
if (read_batch)
fmt = "--read-batch=%s";
snprintf(fext,sizeof(fext),fmt,batch_prefix);
args[ac++] = fext;
}
@@ -668,6 +729,9 @@ void server_options(char **args,int *argc)
if (only_existing && am_sender)
args[ac++] = "--existing";
if (opt_ignore_existing && am_sender)
args[ac++] = "--ignore-existing";
if (tmpdir) {
args[ac++] = "--temp-dir";
args[ac++] = tmpdir;

View File

@@ -1,10 +1,10 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.0
Version: 2.5.1
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.0.tar.gz
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync

View File

@@ -1,10 +1,10 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.0
Version: 2.5.1
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.0.tar.gz
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync

View File

@@ -1,10 +1,10 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.0
Version: 2.5.1
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.0.tar.gz
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync

View File

@@ -38,8 +38,8 @@ extern int make_backups;
extern char *backup_suffix;
static struct delete_list {
dev_t dev;
INO_T inode;
DEV64_T dev;
INO64_T inode;
} *delete_list;
static int dlist_len, dlist_alloc_len;
@@ -206,7 +206,8 @@ static int get_tmpname(char *fnametmp, char *fname)
static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
OFF_T total_size)
{
int i,n,remainder,len,count;
int i;
unsigned int n,remainder,len,count;
OFF_T offset = 0;
OFF_T offset2;
char *data;
@@ -248,7 +249,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
i = -(i+1);
offset2 = i*(OFF_T)n;
len = n;
if (i == count-1 && remainder != 0)
if (i == (int) count-1 && remainder != 0)
len = remainder;
stats.matched_data += len;
@@ -264,7 +265,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
sum_update(map,len);
}
if (fd != -1 && write_file(fd,map,len) != len) {
if (fd != -1 && write_file(fd,map,len) != (int) len) {
rprintf(FERROR,"write failed on %s : %s\n",
fname,strerror(errno));
exit_cleanup(RERR_FILEIO);
@@ -423,7 +424,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
access because of a similar race condition. */
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
if (fd2 == -1) {
rprintf(FERROR,"mkstemp %s failed\n",fnametmp);
rprintf(FERROR,"mkstemp %s failed: %s\n",fnametmp,strerror(errno));
receive_data(f_in,buf,-1,NULL,file->length);
if (buf) unmap_file(buf);
continue;
@@ -488,7 +489,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
}
if (preserve_hard_links)
do_hard_links(flist);
do_hard_links();
/* now we need to fix any directory permissions that were
modified during the transfer */

View File

@@ -226,7 +226,6 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
void sig_int(void)
{
rprintf(FINFO,"\nrsync.c:sig_int() called.\n");
exit_cleanup(RERR_SIGNAL);
}

90
rsync.h
View File

@@ -1,7 +1,7 @@
/*
Copyright (C) by Andrew Tridgell 1996, 2000
Copyright (C) Paul Mackerras 1996
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
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
@@ -49,7 +49,7 @@
#define SAME_TIME (1<<7)
/* update this if you make incompatible changes */
#define PROTOCOL_VERSION 25
#define PROTOCOL_VERSION 26
/* We refuse to interoperate with versions that are not in this range.
* Note that we assume we'll work with later versions: the onus is on
@@ -85,11 +85,9 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#include "config.h"
#if HAVE_REMSH
#define RSYNC_RSH "remsh"
#else
#define RSYNC_RSH "rsh"
#endif
/* The default RSYNC_RSH is always set in config.h, either to "remsh",
* "rsh", or otherwise something specified by the user. HAVE_REMSH
* controls parameter munging for HP/UX, etc. */
#include <sys/types.h>
@@ -185,6 +183,10 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#include <glob.h>
#endif
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
/* these are needed for the uid/gid mapping code */
#include <pwd.h>
#include <grp.h>
@@ -263,17 +265,44 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#elif HAVE_LONGLONG
#define int64 long long
#else
/* As long as it gets... */
#define int64 off_t
#define NO_INT64
#endif
#if HAVE_SHORT_INO_T
# define INO_T uint32
#elif HAVE_INO_T
# define INO_T ino_t
#else
# define INO_T unsigned
#endif
/* 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. That's because the
* receiver needs to find duplicate (dev,ino) tuples to detect
* hardlinks, and it might have files coming from a platform
* that has 64-bit inums.
*
* The only exception is if we're on a platform with no 64-bit type at
* all.
*
* Because we use read_longint() to get these off the wire, if you
* transfer devices or hardlinks with dev or inum > 2**32 to a machine
* with no 64-bit types then you will get an overflow error. Probably
* not many people have that combination of machines, and you can
* avoid it by not preserving hardlinks or not transferring device
* nodes. It's not clear that any other behaviour is better.
*
* Note that if you transfer devices from a 64-bit-devt machine (say,
* Solaris) to a 32-bit-devt machine (say, Linux-2.2/x86) then the
* device numbers will be truncated. But it's a kind of silly thing
* to do anyhow.
*
* FIXME: In future, we should probable split the device number into
* major/minor, and transfer the two parts as 32-bit ints. That gives
* you somewhat more of a chance that they'll come from a big machine
* to a little one in a useful way.
*
* FIXME: Really we need an unsigned type, and we perhaps ought to
* cope with platforms on which this is an unsigned int or even a
* struct. Later.
*/
#define INO64_T int64
#define DEV64_T int64
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
@@ -304,9 +333,13 @@ struct file_struct {
time_t modtime;
OFF_T length;
mode_t mode;
INO_T inode;
dev_t dev;
dev_t rdev;
INO64_T inode;
/** Device this file lives upon */
DEV64_T dev;
/** If this is a device node, the device number. */
DEV64_T rdev;
uid_t uid;
gid_t gid;
char *basename;
@@ -342,11 +375,11 @@ struct sum_buf {
};
struct sum_struct {
OFF_T flength; /* total file length */
int count; /* how many chunks */
int remainder; /* flength % block_length */
int n; /* block_length */
struct sum_buf *sums; /* points to info for each chunk */
OFF_T flength; /* total file length */
size_t count; /* how many chunks */
size_t remainder; /* flength % block_length */
size_t n; /* block_length */
struct sum_buf *sums; /* points to info for each chunk */
};
struct map_struct {
@@ -387,9 +420,11 @@ static inline int flist_up(struct file_list *flist, int i)
}
#include "byteorder.h"
#include "proto.h"
#include "lib/mdfour.h"
#include "lib/permstring.h"
#include "lib/addrinfo.h"
#include "proto.h"
/* We have replacement versions of these if they're missing. */
#ifndef HAVE_ASPRINTF
@@ -426,6 +461,9 @@ extern int errno;
#define SUPPORT_LINKS HAVE_READLINK
#define SUPPORT_HARD_LINKS HAVE_LINK
/* This could be bad on systems which have no lchown and where chown
* follows symbollic links. On such systems it might be better not to
* try to chown symlinks at all. */
#ifndef HAVE_LCHOWN
#define lchown chown
#endif
@@ -563,12 +601,6 @@ size_t strlcat(char *d, const char *s, size_t bufsize);
extern int verbose;
extern struct global_opts {
/** Network address family. **/
int af_hint;
} global_opts;
#ifndef HAVE_INET_NTOP
const char *
inet_ntop(int af, const void *src, char *dst, size_t size);

254
rsync.yo
View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsync)(1)(29 May 2001)()()
manpage(rsync)(1)(25 Jan 2002)()()
manpagename(rsync)(faster, flexible replacement for rcp)
manpagesynopsis()
@@ -19,7 +19,7 @@ manpagedescription()
rsync is a program that behaves in much the same way that rcp does,
but has many more options and uses the rsync remote-update protocol to
greatly speedup file transfers when the destination file already
greatly speed up file transfers when the destination file already
exists.
The rsync remote-update protocol allows rsync to transfer just the
@@ -81,7 +81,7 @@ Once installed you can use rsync to any machine that you can use rsh
to. rsync uses rsh for its communications, unless both the source and
destination are local.
You can also specify an alternative to rsh, by either using the -e
You can also specify an alternative to rsh, either by using the -e
command line option, or by setting the RSYNC_RSH environment variable.
One common substitute is to use ssh, which offers a high degree of
@@ -139,10 +139,10 @@ It is also possible to use rsync without using rsh or ssh as the
transport. In this case you will connect to a remote rsync server
running on TCP port 873.
You may establish the connetcion via a web proxy by setting the
You may establish the connection via a web proxy by setting the
environment variable RSYNC_PROXY to a hostname:port pair pointing to
your web proxy. Note that your web proxy must allow proxying to port
873, this must be configured in your proxy servers ruleset.
your web proxy. Note that your web proxy's configuration must allow
proxying to port 873.
Using rsync in this way is the same as using it with rsh or ssh except
that:
@@ -226,8 +226,8 @@ verb(
--backup-dir make backups into this directory
--suffix=SUFFIX override backup suffix
-u, --update update only (don't overwrite newer files)
-l, --links preserve soft links
-L, --copy-links treat soft links like regular files
-l, --links copy symlinks as symlinks
-L, --copy-links copy the referent of symlinks
--copy-unsafe-links copy links outside the source tree
--safe-links ignore links outside the destination tree
-H, --hard-links preserve hard links
@@ -239,12 +239,14 @@ verb(
-S, --sparse handle sparse files efficiently
-n, --dry-run show what would have been transferred
-W, --whole-file copy whole files, no incremental checks
--no-whole-file turn off --whole-file
-x, --one-file-system don't cross filesystem boundaries
-B, --block-size=SIZE checksum blocking size (default 700)
-e, --rsh=COMMAND specify rsh replacement
--rsync-path=PATH specify path to rsync on the remote machine
-C, --cvs-exclude auto ignore files in the same way CVS does
--existing only update files that already exist
--ignore-existing ignore files that already exist on the receiving side
--delete delete files that don't exist on the sending side
--delete-excluded also delete excluded files on the receiving side
--delete-after delete after transferring, not before
@@ -267,17 +269,19 @@ verb(
--include-from=FILE don't exclude patterns listed in FILE
--version print version number
--daemon run as a rsync daemon
--address bind to the specified address
--no-detach do not detach from the parent
--address=ADDRESS bind to the specified address
--config=FILE specify alternate rsyncd.conf file
--port=PORT specify alternate rsyncd port number
--blocking-io use blocking IO for the remote shell
--no-blocking-io turn off --blocking-io
--stats give some file transfer stats
--progress show progress during transfer
--log-format=FORMAT log file transfers using specified format
--password-file=FILE get password from FILE
--bwlimit=KBPS limit I/O bandwidth, KBytes per second
-f, --read-batch=FILE read batch file
-F, --write-batch write batch file
--read-batch=PREFIX read batch fileset starting with PREFIX
--write-batch=PREFIX write batch fileset starting with PREFIX
-h, --help show this help screen
@@ -377,17 +381,16 @@ dit(bf(-u, --update)) This forces rsync to skip any files for which the
destination file already exists and has a date later than the source
file.
dit(bf(-l, --links)) This tells rsync to recreate symbolic links on the
remote system to be the same as the local system. Without this
option, all symbolic links are skipped.
dit(bf(-l, --links)) When symlinks are encountered, recreate the
symlink on the destination.
dit(bf(-L, --copy-links)) This tells rsync to treat symbolic links just
like ordinary files.
dit(bf(-L, --copy-links)) When symlinks are encountered, the file that
they point to is copied, rather than the symlink.
dit(bf(--copy-unsafe-links)) This tells rsync to treat symbolic links that
point outside the source tree like ordinary files. Absolute symlinks are
also treated like ordinary files, and so are any symlinks in the source
path itself when --relative is used.
dit(bf(--copy-unsafe-links)) This tells rsync to copy the referent of
symbolic links that point outside the source tree. Absolute symlinks
are also treated like ordinary files, and so are any symlinks in the
source path itself when --relative is used.
dit(bf(--safe-links)) This tells rsync to ignore any symbolic links
which point outside the destination tree. All absolute symlinks are
@@ -410,19 +413,21 @@ target machines is higher than the bandwidth to disk (especially when the
"disk" is actually a networked file system). This is the default when both
the source and target are on the local machine.
dit(bf(--no-whole-file)) Turn off --whole-file, for use when it is the
default.
dit(bf(-p, --perms)) This option causes rsync to update the remote
permissions to be the same as the local permissions.
dit(bf(-o, --owner)) This option causes rsync to update the remote owner
of the file to be the same as the local owner. This is only available
to the super-user. Note that if the source system is a daemon using chroot,
the --numeric-ids option is implied because the source system cannot get
access to the usernames.
dit(bf(-o, --owner)) This option causes rsync to set the owner of the
destination file to be the same as the source file. On most systems,
only the super-user can set file ownership.
dit(bf(-g, --group)) This option causes rsync to update the remote group
of the file to be the same as the local group. If the receving system is
not running as the super-user, only groups that the receiver is a member of
will be preserved (by group name, not group id number).
dit(bf(-g, --group)) This option causes rsync to set the group of the
destination file to be the same as the source file. If the receiving
program is not running as the super-user, only groups that the
receiver is a member of will be preserved (by group name, not group id
number).
dit(bf(-D, --devices)) This option causes rsync to transfer character and
block device information to the remote system to recreate these
@@ -453,6 +458,10 @@ contents of only one filesystem.
dit(bf(--existing)) This tells rsync not to create any new files -
only update files that already exist on the destination.
dit(bf(--ignore-existing))
This tells rsync not to update files that already exist on
the destination.
dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM
files or directories. This is useful when mirroring very large trees
to prevent disasters.
@@ -486,12 +495,9 @@ dit(bf(--ignore-errors)) Tells --delete to go ahead and delete files
even when there are IO errors.
dit(bf(--force)) This options tells rsync to delete directories even if
they are not empty. This applies to both the --delete option and to
cases where rsync tries to copy a normal file but the destination
contains a directory of the same name.
Since this option was added, deletions were reordered to be done depth-first
so it is hardly ever needed anymore except in very obscure cases.
they are not empty when they are to be replaced by non-directories. This
is only relevant without --delete because deletions are now done depth-first.
Requires the --recursive option (which is implied by -a) to have any effect.
dit(bf(-B , --block-size=BLOCKSIZE)) This controls the block size used in
the rsync algorithm. See the technical report for details.
@@ -550,8 +556,9 @@ quote(RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state
then files listed in a $HOME/.cvsignore are added to the list and any
files listed in the CVSIGNORE environment variable (space delimited).
Finally in each directory any files listed in the .cvsignore file in
that directory are added to the list.
Finally, any file is ignored if it is in the same directory as a
.cvsignore file and matches one of the patterns listed therein. See
the bf(cvs(1)) manual for more information.
dit(bf(--csum-length=LENGTH)) By default the primary checksum used in
rsync is a very strong 16 byte MD4 checksum. In most cases you will
@@ -608,21 +615,33 @@ what ownership to give files. The special uid 0 and the special group
0 are never mapped via user/group names even if the --numeric-ids
option is not specified.
If the source system is a daemon using chroot, or if a user or group name
does not exist on the destination system, then the numeric id from the
source system is used instead.
If the source system is a daemon using chroot, or if a user or group
name does not exist on the destination system, then the numeric id
from the source system is used instead.
dit(bf(--timeout=TIMEOUT)) This option allows you to set a maximum IO
timeout in seconds. If no data is transferred for the specified time
then rsync will exit. The default is 0, which means no timeout.
dit(bf(--daemon)) This tells rsync that it is to run as a rsync
daemon. If standard input is a socket then rsync will assume that it
is being run via inetd, otherwise it will detach from the current
terminal and become a background daemon. The daemon will read the
config file (/etc/rsyncd.conf) on each connect made by a client and
respond to requests accordingly. See the rsyncd.conf(5) man page for more
details.
dit(bf(--daemon)) This tells rsync that it is to run as a daemon. The
daemon may be accessed using the bf(host::module) or
bf(rsync://host/module/) syntax.
If standard input is a socket then rsync will assume that it is being
run via inetd, otherwise it will detach from the current terminal and
become a background daemon. The daemon will read the config file
(/etc/rsyncd.conf) on each connect made by a client and respond to
requests accordingly. See the rsyncd.conf(5) man page for more
details.
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
be useful when rsync is supervised by a program such as
bf(daemontools) or AIX's bf(System Resource Controller).
bf(--no-detach) is also recommended when rsync is run under a
debugger. This option has no effect if rsync is run from inetd or
sshd.
dit(bf(--address)) By default rsync will bind to the wildcard address
when run as a daemon with the --daemon option or when connecting to a
@@ -643,6 +662,9 @@ the default "rsh", this defaults to blocking IO, otherwise it defaults to
non-blocking IO. You may find the --blocking-io option is needed for some
remote shells that can't handle non-blocking IO. Ssh prefers blocking IO.
dit(bf(--no-blocking-io)) Turn off --blocking-io, for use when it is the
default.
dit(bf(--log-format=FORMAT)) This allows you to specify exactly what the
rsync client logs to stdout on a per-file basis. The log format is
specified using the same format conventions as the log format option in
@@ -684,10 +706,13 @@ transfer was too fast, it will wait before sending the next data block. The
result is an average transfer rate equalling the specified limit. A value
of zero specifies no limit.
dit(bf(--read-batch)) Apply a previously generated change batch.
dit(bf(--write-batch=PREFIX)) Generate a set of files that can be
transferred as a batch update. Each filename in the set starts with
PREFIX. See the "BATCH MODE" section for details.
dit(bf(--write-batch)) Generate a set of files that can be transferred
as a batch update.
dit(bf(--read-batch=PREFIX)) Apply a previously generated change batch,
using the fileset whose filenames start with PREFIX. See the "BATCH
MODE" section for details.
enddit()
@@ -696,7 +721,7 @@ manpagesection(EXCLUDE PATTERNS)
The exclude and include patterns specified to rsync allow for flexible
selection of which files to transfer and which files to skip.
rsync builds a ordered list of include/exclude options as specified on
rsync builds an ordered list of include/exclude options as specified on
the command line. When a filename is encountered, rsync checks the
name against each exclude/include pattern in turn. The first matching
pattern is acted on. If it is an exclude pattern, then that file is
@@ -749,7 +774,7 @@ itemize(
part of an include option. The "- " part is discarded before matching.
it() if the pattern is a single exclamation mark ! then the current
exclude list is reset, removing all previous exclude patterns.
include/exclude list is reset, removing all previously defined patterns.
)
The +/- rules are most useful in exclude lists, allowing you to have a
@@ -781,27 +806,110 @@ itemize(
manpagesection(BATCH MODE)
The following call generates 4 files that encapsulate the information
for synchronizing the contents of bf(target_dir) with the updates found in
bf(src_dir)
bf(Note:) Batch mode should be considered experimental in this version
of rsync. The interface or behaviour may change before it stabilizes.
quote(
$ rsync -F [other rsync options here] \nl()
/somewhere/src_dir /somewhere/target_dir
)
Batch mode can be used to apply the same set of updates to many
identical systems. Suppose one has a tree which is replicated on a
number of hosts. Now suppose some changes have been made to this
source tree and those changes need to be propagated to the other
hosts. In order to do this using batch mode, rsync is run with the
write-batch option to apply the changes made to the source tree to one
of the destination trees. The write-batch option causes the rsync
client to store the information needed to repeat this operation against
other destination trees in a batch update fileset (see below). The
filename of each file in the fileset starts with a prefix specified by
the user as an argument to the write-batch option. This fileset is
then copied to each remote host, where rsync is run with the read-batch
option, again specifying the same prefix, and the destination tree.
Rsync updates the destination tree using the information stored in the
batch update fileset.
The generated files are labeled with a common timestamp:
The fileset consists of 4 files:
itemize(
it() bf(rsync_argvs.<timestamp>) command-line arguments
it() bf(rsync_flist.<timestamp>) rsync internal file metadata
it() bf(rsync_csums.<timestamp>) rsync checksums
it() bf(rsync_delta.<timestamp>) data blocks for file update & change
it() bf(<prefix>.rsync_argvs) command-line arguments
it() bf(<prefix>.rsync_flist) rsync internal file metadata
it() bf(<prefix>.rsync_csums) rsync checksums
it() bf(<prefix>.rsync_delta) data blocks for file update & change
)
The .rsync_argvs file contains a command-line suitable for updating a
destination tree using that batch update fileset. It can be executed
using a Bourne(-like) shell, optionally passing in an alternate
destination tree pathname which is then used instead of the original
path. This is useful when the destination tree path differs from the
original destination tree path.
Generating the batch update fileset once saves having to perform the
file status, checksum and data block generation more than once when
updating multiple destination trees. Multicast transport protocols can
be used to transfer the batch update files in parallel to many hosts at
once, instead of sending the same data to every host individually.
Example:
verb(
$ rsync --write_batch=pfx -a /source/dir/ /adest/dir/
$ rcp pfx.rsync_* remote:
$ rsh remote rsync --read_batch=pfx -a /bdest/dir/
# or alternatively
$ rsh remote ./pfx.rsync_argvs /bdest/dir/
)
In this example, rsync is used to update /adest/dir/ with /source/dir/
and the information to repeat this operation is stored in the files
pfx.rsync_*. These files are then copied to the machine named "remote".
Rsync is then invoked on "remote" to update /bdest/dir/ the same way as
/adest/dir/. The last line shows the rsync_argvs file being used to
invoke rsync.
Caveats:
The read-batch option expects the destination tree it is meant to update
to be identical to the destination tree that was used to create the
batch update fileset. When a difference between the destination trees
is encountered the update will fail at that point, leaving the
destination tree in a partially updated state. In that case, rsync can
be used in its regular (non-batch) mode of operation to fix up the
destination tree.
The rsync version used on all destinations should be identical to the
one used on the original destination.
The -z/--compress option does not work in batch mode and yields a usage
error. A separate compression tool can be used instead to reduce the
size of the batch update files for transport to the destination.
The -n/--dryrun option does not work in batch mode and yields a runtime
error.
See bf(http://www.ils.unc.edu/i2dsi/unc_rsync+.html) for papers and technical
reports.
manpagesection(SYMBOLIC LINKS)
Three basic behaviours are possible when rsync encounters a symbolic
link in the source directory.
By default, symbolic links are not transferred at all. A message
"skipping non-regular" file is emitted for any symlinks that exist.
If bf(--links) is specified, then symlinks are recreated with the same
target on the destination. Note that bf(--archive) implies
bf(--links).
If bf(--copy-links) is specified, then symlinks are "collapsed" by
copying their referent, rather than the symlink.
rsync also distinguishes "safe" and "unsafe" symbolic links. An
example where this might be used is a web site mirror that wishes
ensure the rsync module they copy does not include symbolic links to
bf(/etc/passwd) in the public section of the site. Using
bf(--copy-unsafe-links) will cause any links to be copied as the file
they point to on the destination. Using bf(--safe-links) will cause
unsafe links to be ommitted altogether.
manpagesection(DIAGNOSTICS)
rsync occasionally produces error messages that may seem a little
@@ -927,16 +1035,22 @@ Jean-loup Gailly and Mark Adler.
manpagesection(THANKS)
Thanks to Richard Brent, Brendan Mackay, Bill Waite, Stephen Rothwell
and David Bell for helpful suggestions and testing of rsync. I've
probably missed some people, my apologies if I have.
and David Bell for helpful suggestions, patches and testing of rsync.
I've probably missed some people, my apologies if I have.
Especial thanks also to: David Dykstra, Jos Backus, Sebastian Krahmer.
manpageauthor()
rsync was written by Andrew Tridgell and Paul Mackerras. They may be
contacted via email at tridge@samba.org and
Paul.Mackerras@cs.anu.edu.au
rsync was written by Andrew Tridgell <tridge@samba.org> and Paul
Mackerras.
rsync is now also maintained by Martin Pool <mbp@samba.org>
rsync is now maintained by Martin Pool <mbp@samba.org>.
Mailing lists for support and development are available at
url(http://lists.samba.org)(lists.samba.org)
If you suspect you have found a security vulnerability in rsync,
please send it directly to Martin Pool and Andrew Tridgell. For other
enquiries, please use the mailing list.

View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
# Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version
@@ -160,16 +160,27 @@ missing=0
passed=0
failed=0
scratchdir=./testtmp
[ -d "$scratchdir" ] && rm -r "$scratchdir"
mkdir "$scratchdir"
scratchdir=`cd $scratchdir && pwd`
echo " scratchdir=$scratchdir"
# Prefix for scratch directory. We create separate directories for
# each test case, so that they can be left behind in case of failure
# to aid investigation.
scratchbase="`pwd`"/testtmp
echo " scratchbase=$scratchbase"
suitedir="$srcdir/testsuite"
export scratchdir suitedir
prep_scratch() {
[ -d "$scratchdir" ] && rm -rf "$scratchdir"
mkdir "$scratchdir"
return 0
}
maybe_discard_scratch() {
[ x"$preserve_scratch" != xyes ] && [ -d "$scratchdir" ] && rm -rf "$scratchdir"
return 0
}
if [ "x$whichtests" = x ]
then
whichtests="*.test"
@@ -177,29 +188,49 @@ fi
for testscript in $suitedir/$whichtests
do
testbase=`echo $testscript | sed 's!.*/!!'`
testbase=`echo $testscript | sed 's!.*/!!' | sed -e 's/.test\$//'`
scratchdir="$scratchbase.$testbase"
echo "----- $testbase starting"
prep_scratch
if sh $RUNSHFLAGS "$testscript"
set +e
sh $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1
result=$?
set -e
if [ "x$always_log" = xyes -o \( $result != 0 -a $result != 77 -a $result != 78 \) ]
then
echo "----- $testbase completed successfully"
passed=`expr $passed + 1`
else
case $? in
77)
echo "----- $testbase skipped"
skipped=`expr $skipped + 1`
;;
*)
echo "----- $testbase failed!"
failed=`expr $failed + 1`
if [ "x$nopersist" = "xyes" ]
then
exit 1
fi
esac
echo "----- $testbase log follows"
cat "$scratchdir/test.log"
echo "----- $testbase log ends"
fi
case $result in
0)
echo "PASS $testbase"
passed=`expr $passed + 1`
maybe_discard_scratch
;;
77)
echo "SKIP $testbase"
skipped=`expr $skipped + 1`
maybe_discard_scratch
;;
78)
# It failed, but we expected that. don't dump out error logs,
# because most users won't want to see them. But do leave
# the working directory around.
echo "XFAIL $testbase"
failed=`expr $failed + 1`
;;
*)
echo "FAIL $testbase"
failed=`expr $failed + 1`
if [ "x$nopersist" = "xyes" ]
then
exit 1
fi
esac
done
echo '------------------------------------------------------------'

View File

@@ -55,14 +55,14 @@ static struct sum_struct *receive_sums(int f)
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
if (!s->sums) out_of_memory("receive_sums");
for (i=0;i<s->count;i++) {
for (i=0; i < (int) s->count;i++) {
s->sums[i].sum1 = read_int(f);
read_buf(f,s->sums[i].sum2,csum_length);
s->sums[i].offset = offset;
s->sums[i].i = i;
if (i == s->count-1 && s->remainder != 0) {
if (i == (int) s->count-1 && s->remainder != 0) {
s->sums[i].len = s->remainder;
} else {
s->sums[i].len = s->n;
@@ -159,13 +159,14 @@ void send_files(struct file_list *flist,int f_out,int f_in)
initial_stats = stats;
s = receive_sums(f_in);
if (write_batch) /* dw */
write_batch_csum_info(&i,flist->count,s);
if (!s) {
io_error = 1;
rprintf(FERROR,"receive_sums failed\n");
return;
}
if (write_batch)
write_batch_csum_info(&i,flist->count,s);
if (!read_batch) {
fd = do_open(fname, O_RDONLY, 0);

307
socket.c
View File

@@ -1,7 +1,9 @@
/* -*- c-file-style: "linux" -*-
rsync -- fast file replication program
Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
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,13 +24,15 @@
* @file socket.c
*
* Socket functions used in rsync.
*
* This file is now converted to use the new-style getaddrinfo()
* interface, which supports IPv6 but is also supported on recent
* IPv4-only machines. On systems that don't have that interface, we
* emulate it using the KAME implementation.
**/
#include "rsync.h"
#ifndef HAVE_GETADDRINFO
#include "lib/addrinfo.h"
#endif
/* Establish a proxy connection on an open socket to a web roxy by
* using the CONNECT method. */
@@ -38,7 +42,7 @@ static int establish_proxy_connection(int fd, char *host, int port)
char *cp;
snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
if (write(fd, buffer, strlen(buffer)) != strlen(buffer)) {
if (write(fd, buffer, strlen(buffer)) != (int) strlen(buffer)) {
rprintf(FERROR, "failed to write to proxy: %s\n",
strerror(errno));
return -1;
@@ -94,6 +98,39 @@ static int establish_proxy_connection(int fd, char *host, int port)
}
/**
* Try to set the local address for a newly-created socket. Return -1
* if this fails.
**/
int try_bind_local(int s,
int ai_family, int ai_socktype,
const char *bind_address)
{
int error;
struct addrinfo bhints, *bres_all, *r;
memset(&bhints, 0, sizeof(bhints));
bhints.ai_family = ai_family;
bhints.ai_socktype = ai_socktype;
bhints.ai_flags = AI_PASSIVE;
if ((error = getaddrinfo(bind_address, NULL, &bhints, &bres_all))) {
rprintf(FERROR, RSYNC_NAME ": getaddrinfo %s: %s\n",
bind_address, gai_strerror(error));
return -1;
}
for (r = bres_all; r; r = r->ai_next) {
if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
continue;
return s;
}
/* no error message; there might be some problem that allows
* creation of the socket but not binding, perhaps if the
* machine has no ipv6 address of this name. */
return -1;
}
/**
* Open a socket to a tcp remote host with the specified port .
@@ -121,7 +158,6 @@ int open_socket_out(char *host, int port, const char *bind_address,
int type = SOCK_STREAM;
int error;
int s;
int result;
struct addrinfo hints, *res0, *res;
char portbuf[10];
char *h;
@@ -162,32 +198,22 @@ int open_socket_out(char *host, int port, const char *bind_address,
}
s = -1;
/* Try to connect to all addresses for this machine until we get
* through. It might e.g. be multi-homed, or have both IPv4 and IPv6
* addresses. We need to create a socket for each record, since the
* address record tells us what protocol to use to try to connect. */
for (res = res0; res; res = res->ai_next) {
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0)
continue;
if (bind_address) {
struct addrinfo bhints, *bres;
memset(&bhints, 0, sizeof(bhints));
bhints.ai_family = res->ai_family;
bhints.ai_socktype = type;
bhints.ai_flags = AI_PASSIVE;
error = getaddrinfo(bind_address, NULL, &bhints, &bres);
if (error) {
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s <noport>: %s\n",
bind_address, gai_strerror(error));
if (bind_address)
if (try_bind_local(s, res->ai_family, type,
bind_address) == -1) {
close(s);
s = -1;
continue;
}
if (bres->ai_next) {
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s resolved to multiple hosts\n",
bind_address);
freeaddrinfo(bres);
continue;
}
bind(s, bres->ai_addr, bres->ai_addrlen);
}
if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
close(s);
@@ -263,7 +289,7 @@ static int open_socket_in(int type, int port, const char *bind_address,
{
int one=1;
int s;
struct addrinfo hints, *res, *resp;
struct addrinfo hints, *all_ai, *resp;
char portbuf[10];
int error;
@@ -272,53 +298,43 @@ static int open_socket_in(int type, int port, const char *bind_address,
hints.ai_socktype = type;
hints.ai_flags = AI_PASSIVE;
snprintf(portbuf, sizeof(portbuf), "%d", port);
error = getaddrinfo(bind_address, portbuf, &hints, &res);
error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
if (error) {
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
bind_address, gai_strerror(error));
return -1;
}
/* XXX: Do we need to care about getting multiple results
* back? I think probably not; if the user passed
* bind_address == NULL and we set AI_PASSIVE then we ought to
* get a wildcard result. */
resp = res;
while (1) {
s = socket(resp->ai_family, resp->ai_socktype, resp->ai_protocol);
/* We may not be able to create the socket, if for example the
* machine knows about IPv6 in the C library, but not in the
* kernel. */
for (resp = all_ai; resp; resp = resp->ai_next) {
s = socket(resp->ai_family, resp->ai_socktype,
resp->ai_protocol);
if (s >= 0) {
break; /* got a socket */
} else if ((resp = resp->ai_next)) {
switch (errno) {
case EPROTONOSUPPORT:
case EAFNOSUPPORT:
case EPFNOSUPPORT:
/* See if there's another address that will work... */
continue;
}
if (s == -1)
/* See if there's another address that will work... */
continue;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(char *)&one, sizeof one);
/* now we've got a socket - we need to bind it */
if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
/* Nope, try another */
close(s);
continue;
}
rprintf(FERROR, RSYNC_NAME ": open inbound socket"
"(dom=%d, type=%d, proto=%d) failed: %s\n",
resp->ai_family, resp->ai_socktype, resp->ai_protocol,
strerror(errno));
goto fail;
return s;
}
setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
"%s\n",
port,
strerror(errno));
/* now we've got a socket - we need to bind it */
if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
rprintf(FERROR, RSYNC_NAME ": bind failed on port %d\n", port);
close(s);
goto fail;
}
return s;
fail:
freeaddrinfo(res);
freeaddrinfo(all_ai);
return -1;
}
@@ -353,10 +369,10 @@ void start_accept_loop(int port, int (*fn)(int ))
{
int s;
extern char *bind_address;
extern int default_af_hint;
/* open an incoming socket */
s = open_socket_in(SOCK_STREAM, port, bind_address,
global_opts.af_hint);
s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
if (s == -1)
exit_cleanup(RERR_SOCKETIO);
@@ -371,9 +387,10 @@ void start_accept_loop(int port, int (*fn)(int ))
for each incoming connection */
while (1) {
fd_set fds;
pid_t pid;
int fd;
struct sockaddr addr;
int in_addrlen = sizeof(addr);
struct sockaddr_storage addr;
socklen_t addrlen = sizeof addr;
/* close log file before the potentially very long select so
file can be trimmed by another process instead of growing
@@ -389,7 +406,7 @@ void start_accept_loop(int port, int (*fn)(int ))
if(!FD_ISSET(s, &fds)) continue;
fd = accept(s,(struct sockaddr *)&addr,&in_addrlen);
fd = accept(s,(struct sockaddr *)&addr,&addrlen);
if (fd == -1) continue;
@@ -402,15 +419,26 @@ void start_accept_loop(int port, int (*fn)(int ))
while (waitpid(-1, NULL, WNOHANG) > 0);
#endif
if (fork()==0) {
if ((pid = fork()) == 0) {
close(s);
/* open log file in child before possibly giving
up privileges */
log_open();
_exit(fn(fd));
} else if (pid < 0) {
rprintf(FERROR,
RSYNC_NAME
": could not create child server process: %s\n",
strerror(errno));
close(fd);
/* This might have happened because we're
* overloaded. Sleep briefly before trying to
* accept again. */
sleep(2);
} else {
/* Parent doesn't need this fd anymore. */
close(fd);
}
close(fd);
}
}
@@ -550,123 +578,6 @@ void become_daemon(void)
}
}
/**
* Return the IP addr of the client as a string
**/
char *client_addr(int fd)
{
struct sockaddr ss;
int length = sizeof(ss);
static char addr_buf[100];
static int initialised;
if (initialised) return addr_buf;
initialised = 1;
if (getpeername(fd, &ss, &length)) {
exit_cleanup(RERR_SOCKETIO);
}
getnameinfo(&ss, length,
addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
return addr_buf;
}
/**
* Return the DNS name of the client
**/
char *client_name(int fd)
{
struct sockaddr ss;
int length = sizeof(ss);
static char name_buf[100];
static char port_buf[100];
char *def = "UNKNOWN";
static int initialised;
struct addrinfo hints, *res, *res0;
int error;
if (initialised) return name_buf;
initialised = 1;
strcpy(name_buf,def);
if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
/* FIXME: Can we really not continue? */
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
fd, strerror(errno));
exit_cleanup(RERR_SOCKETIO);
}
#ifdef INET6
if (ss.sa_family == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&ss)->sin6_addr)) {
struct sockaddr_in6 sin6;
struct sockaddr_in *sin;
memcpy(&sin6, &ss, sizeof(sin6));
sin = (struct sockaddr_in *)&ss;
memset(sin, 0, sizeof(*sin));
sin->sin_family = AF_INET;
length = sizeof(struct sockaddr_in);
#ifdef HAVE_SOCKADDR_LEN
sin->sin_len = length;
#endif
sin->sin_port = sin6.sin6_port;
memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
sizeof(sin->sin_addr));
}
#endif
/* reverse lookup */
if (getnameinfo((struct sockaddr *)&ss, length,
name_buf, sizeof(name_buf), port_buf, sizeof(port_buf),
NI_NAMEREQD | NI_NUMERICSERV) != 0) {
strcpy(name_buf, def);
rprintf(FERROR, "reverse name lookup failed\n");
}
/* forward lookup */
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_flags = AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(name_buf, port_buf, &hints, &res0);
if (error) {
strcpy(name_buf, def);
rprintf(FERROR,
RSYNC_NAME ": forward name lookup for %s failed: %s\n",
port_buf,
gai_strerror(error));
return name_buf;
}
/* XXX sin6_flowinfo and other fields */
for (res = res0; res; res = res->ai_next) {
if (res->ai_family != ss.sa_family)
continue;
if (res->ai_addrlen != length)
continue;
if (memcmp(res->ai_addr, &ss, res->ai_addrlen) == 0)
break;
}
/* TODO: Do a forward lookup as well to prevent spoofing */
if (res == NULL) {
strcpy(name_buf, def);
rprintf(FERROR, RSYNC_NAME ": "
"reverse name lookup mismatch on fd%d - spoofed address?\n",
fd);
}
freeaddrinfo(res0);
return name_buf;
}
/*******************************************************************
this is like socketpair but uses tcp. It is used by the Samba
@@ -691,7 +602,7 @@ static int socketpair_tcp(int fd[2])
if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
memset(&sock2, 0, sizeof(sock2));
#ifdef HAVE_SOCK_SIN_LEN
#ifdef HAVE_SOCKADDR_LEN
sock2.sin_len = sizeof(sock2);
#endif
sock2.sin_family = PF_INET;
@@ -735,16 +646,20 @@ static int socketpair_tcp(int fd[2])
}
/*******************************************************************
run a program on a local tcp socket, this is used to launch smbd
when regression testing
the return value is a socket which is attached to a subprocess
running "prog". stdin and stdout are attached. stderr is left
attached to the original stderr
******************************************************************/
/**
* Run a program on a local tcp socket, so that we can talk to it's
* stdin and stdout. This is used to fake a connection to a daemon
* for testing -- not for the normal case of running SSH.
*
* @return a socket which is attached to a subprocess running
* "prog". stdin and stdout are attached. stderr is left attached to
* the original stderr
**/
int sock_exec(const char *prog)
{
int fd[2];
if (socketpair_tcp(fd) != 0) {
rprintf (FERROR, RSYNC_NAME
": socketpair_tcp failed (%s)\n",
@@ -757,10 +672,12 @@ int sock_exec(const char *prog)
close(1);
dup(fd[1]);
dup(fd[1]);
if (verbose > 3)
if (verbose > 3) {
/* Can't use rprintf because we've forked. */
fprintf (stderr,
RSYNC_NAME ": execute socket program \"%s\"\n",
prog);
}
exit (system (prog));
}
close (fd[1]);

View File

@@ -1,5 +1,6 @@
/*
Copyright (C) Andrew Tridgell 1998
Copyright (C) 2002 by Martin Pool
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
@@ -16,9 +17,12 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
syscall wrappers to ensure that nothing gets done in dry_run mode
*/
/**
* @file syscall.c
*
* Syscall wrappers to ensure that nothing gets done in dry_run mode
* and to handle system peculiarities.
**/
#include "rsync.h"
@@ -106,13 +110,24 @@ int do_rename(char *fname1, char *fname2)
return rename(fname1, fname2);
}
int do_mkdir(char *fname, mode_t mode)
{
if (dry_run) return 0;
CHECK_RO
int l;
if (dry_run)
return 0;
CHECK_RO;
/* Some BSD systems cannot make a directory if the name
* contains a trailing slash.
* <http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html> */
if ((l = strlen(fname)) && (fname[l-1] == '/'))
fname[l-1] = '/';
return mkdir(fname, mode);
}
/* like mkstemp but forces permissions */
int do_mkstemp(char *template, mode_t perms)
{
@@ -132,7 +147,7 @@ int do_mkstemp(char *template, mode_t perms)
}
#else
if (!mktemp(template)) return -1;
return open(template, O_RDWR|O_EXCL|O_CREAT, perms);
return do_open(template, O_RDWR|O_EXCL|O_CREAT, perms);
#endif
}

36
testsuite/chgrp.test Normal file
View File

@@ -0,0 +1,36 @@
#! /bin/sh
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that rsync with -gr will preserve groups when the user running
# the test is a member of them. Hopefully they're in at least one
# test.
. $srcdir/testsuite/rsync.fns
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
mygrps="`groups`" || fail "Can't get groups"
mkdir "$fromdir"
for g in $mygrps
do
name="$fromdir/foo-$g"
date > "$name"
chgrp "$g" "$name" || fail "Can't chgrp"
done
sleep 2
checkit "rsync -rtgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
exit 0
# last [] may have failed but if we get here then we've won

38
testsuite/chown.test Normal file
View File

@@ -0,0 +1,38 @@
#! /bin/sh
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that when rsync is running as root and has -a it correctly sets
# the ownership of the destination.
# We don't know what users will be present on this system, so we just
# use random numeric uids and gids.
. $srcdir/testsuite/rsync.fns
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
mkdir "$fromdir"
name1="$fromdir/name1"
name2="$fromdir/name2"
echo "This is the file" > "$name1"
echo "This is the other file" > "$name2"
chown 5000 "$name1" || test_skipped "Can't chown"
chown 5001 "$name2" || test_skipped "Can't chown"
chgrp 5002 "$name1" || test_skipped "Can't chgrp"
chgrp 5003 "$name2" || test_skipped "Can't chgrp"
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
exit 0
# last [] may have failed but if we get here then we've won

29
testsuite/devices.test Normal file
View File

@@ -0,0 +1,29 @@
#! /bin/sh
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync handling of devices. This can only run if you're root.
. $srcdir/testsuite/rsync.fns
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
# TODO: Need to test whether hardlinks are possible on this OS/filesystem
mkdir "$fromdir"
mknod "$fromdir/char" 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?"
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
exit 0
# last [] may have failed but if we get here then we've won

57
testsuite/duplicates.test Normal file
View File

@@ -0,0 +1,57 @@
#! /bin/sh
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL see
# COPYING).
# Test rsync handling of duplicate filenames.
# It's quite possible that the user might specify the same source file
# more than once on the command line, perhaps through shell variables
# or wildcard expansions. It might cause problems for rsync if the
# same name occurred more than once in the file list, because we might
# be trying to update the first copy and generate checksums for the
# second copy at the same time. See clean_flist() for the implementation.
# We don't need to worry about hardlinks or symlinks. Because we
# always rename-and-replace the new copy, they can't affect us.
# This test is not great, because it is a timing-dependent bug.
. $srcdir/testsuite/rsync.fns
echo "SKIP THIS FOR NOW; It's a known bug"
exit 77
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
mkdir "$fromdir"
name1="$fromdir/name1"
name2="$fromdir/name2"
echo "This is the file" > "$name1"
ln -s "$name1" "$name2" || fail "can't create symlink"
outfile="$scratchdir/rsync.out"
checkit "rsync -avv \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
| tee "$outfile"
# Make sure each file was only copied once...
if [ `grep -c '^name1$' "$outfile"` != 1 ]
then
test_xfail "name1 was not copied exactly once"
fi
if [ `grep -c '^name2$' "$outfile"` != 1 ]
then
test_xfail "name2 was not copied exactly once"
fi
exit 0
# last [] may have failed but if we get here then we've won

38
testsuite/hardlinks.test Normal file
View File

@@ -0,0 +1,38 @@
#! /bin/sh
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync handling of hardlinks. By default (in 2.5.1) rsync does
# not detect symlinks and they get split into different files. If you
# specify -H, then hard links are detected and recreated as hardlinks
# on the other end.
. $srcdir/testsuite/rsync.fns
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
# TODO: Need to test whether hardlinks are possible on this OS/filesystem
mkdir "$fromdir"
name1="$fromdir/name1"
name2="$fromdir/name2"
name3="$fromdir/name3"
name4="$fromdir/name4"
echo "This is the file" > "$name1"
ln "$name1" "$name2" || fail "Can't create hardlink"
ln "$name2" "$name3" || fail "Can't create hardlink"
cp "$name2" "$name4" || fail "Can't copy file"
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
exit 0
# last [] may have failed but if we get here then we've won

View File

@@ -7,7 +7,7 @@
. "$suitedir/rsync.fns"
set -x
# set -x
hands_setup

View File

@@ -135,35 +135,35 @@ makepath () {
# there are any difference. If there are, explain them.
checkit() {
log=${LOG}
failed=
# the log accumulates all output; we only display it if there
# is a problem.
echo "Running: \"$1\"" >${log}
echo "">>${log}
eval "$1" >>${log} 2>&1
# We can just write everything to stdout/stderr, because the
# wrapper hides it unless there is a problem.
echo "Running: \"$1\""
eval "$1"
status=$?
if [ $status != 0 ]; then
failed="YES";
fi
echo "-------------">>${log}
echo "check how the files compare with diff:">>${log}
echo "">>${log}
diff -cr $2 $3 >>${log} 2>&1 || failed=YES
echo "-------------">>${log}
echo "check how the directory listings compare with diff:">>${log}
echo "">>${log}
( cd "$2" && rsync_ls_lR . ) > ${TMP}/ls-from 2>>${log}
( cd "$3" && rsync_ls_lR . ) > ${TMP}/ls-to 2>>${log}
diff -c ${TMP}/ls-from ${TMP}/ls-to >>${log} 2>&1 || failed=YES
echo "-------------"
echo "check how the files compare with diff:"
echo ""
for f in `cd "$2"; find . -type f -print `
do
diff -c "$2"/"$f" "$3"/"$f" || failed=YES
done
echo "-------------"
echo "check how the directory listings compare with diff:"
echo ""
( cd "$2" && rsync_ls_lR . ) > ${TMP}/ls-from
( cd "$3" && rsync_ls_lR . ) > ${TMP}/ls-to
diff -c ${TMP}/ls-from ${TMP}/ls-to || failed=YES
if [ -z "${failed}" ] ; then
rm $log
return 0
else
cat ${log}
rm ${log}
return 1
fi
}
@@ -210,5 +210,34 @@ EOF
}
build_symlinks() {
fromdir="$scratchdir/from"
todir="$scratchdir/to"
mkdir "$fromdir"
date >"$fromdir/referent"
ln -s referent "$fromdir/relative"
ln -s "$fromdir/referent" "$fromdir/absolute"
ln -s nonexistent "$fromdir/dangling"
ln -s "$srcdir/rsync.c" "$fromdir/unsafe"
}
test_fail() {
echo "$@" >&2
exit 1
}
test_skipped() {
echo "$@" >&2
exit 77
}
# It failed, but we expected that. don't dump out error logs,
# because most users won't want to see them. But do leave
# the working directory around.
test_xfail() {
echo "$@" >&2
exit 78
}
# be reproducible
umask 077

View File

@@ -0,0 +1,40 @@
#! /bin/sh
# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync's somewhat over-featured symlink control: the default
# behaviour is that symlinks should not be copied at all.
. $srcdir/testsuite/rsync.fns
set -x
build_symlinks || test_fail "failed to build symlinks"
# Copy recursively, but without -l or -L or -a, and all the symlinks
# should be missing.
"$rsync_bin" -r "$fromdir/" "$todir" || test_fail "rsync returned $?"
[ -f "${todir}/referent" ] || test_fail "referent was not copied"
[ -d "${todir}/from" ] && test_fail "extra level of directories"
if [ -L "${todir}/dangling" ]
then
test_fail "dangling symlink was copied"
fi
if [ -L "${todir}/relative" ]
then
test_fail "relative symlink was copied"
fi
if [ -L "${todir}/absolute" ]
then
test_fail "absolute symlink was copied"
fi
exit 0
# last [] may have failed but if we get here then we've one

15
tls.c
View File

@@ -1,6 +1,6 @@
/* -*- c-file-style: "linux" -*-
*
* Copyright (C) 2001 by Martin Pool <mbp@samba.org>
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
@@ -62,7 +62,7 @@ static void failed (char const *what,
static void list_file (const char *fname)
{
struct stat buf;
STRUCT_STAT buf;
char permbuf[PERMSTRING_SIZE];
struct tm *mt;
char datebuf[50];
@@ -80,12 +80,18 @@ static void list_file (const char *fname)
* undefined. Also it tends not to be possible to reset a
* symlink's mtime, so we have to ignore it too. */
if (S_ISLNK(buf.st_mode)) {
int len;
buf.st_mode &= ~0777;
buf.st_mtime = (time_t)0;
buf.st_uid = buf.st_gid = 0;
strcpy(linkbuf, " -> ");
/* const-cast required for silly UNICOS headers */
readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
len = readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
if (len == -1)
failed("readlink", fname);
else
/* it's not nul-terminated */
linkbuf[4+len] = 0;
} else {
linkbuf[0] = 0;
}
@@ -111,9 +117,10 @@ static void list_file (const char *fname)
/* NB: need to pass size as a double because it might be be
* too large for a long. */
printf("%s %12.0f %6d.%-6d %s %s%s\n",
printf("%s %12.0f %6d.%-6d %6d %s %s%s\n",
permbuf, (double) buf.st_size,
buf.st_uid, buf.st_gid,
buf.st_nlink,
datebuf, fname, linkbuf);
}

164
util.c
View File

@@ -2,7 +2,7 @@
Copyright (C) 1996-2000 by Andrew Tridgell
Copyright (C) Paul Mackerras 1996
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
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
@@ -84,6 +84,26 @@ int fd_pair(int fd[2])
}
void print_child_argv(char **cmd)
{
rprintf(FINFO, "opening connection using ");
for (; *cmd; cmd++) {
/* Look for characters that ought to be quoted. This
* is not a great quoting algorithm, but it's
* sufficient for a log message. */
if (strspn(*cmd, "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789"
",.-_=+@/") != strlen(*cmd)) {
rprintf(FINFO, "\"%s\" ", *cmd);
} else {
rprintf(FINFO, "%s ", *cmd);
}
}
rprintf(FINFO, "\n");
}
/* this is derived from CVS code
note that in the child STDIN is set to blocking and STDOUT
@@ -94,59 +114,63 @@ int fd_pair(int fd[2])
used to cope with badly broken rsh implementations like the one on
solaris.
*/
pid_t piped_child(char **command,int *f_in,int *f_out)
pid_t piped_child(char **command, int *f_in, int *f_out)
{
pid_t pid;
int to_child_pipe[2];
int from_child_pipe[2];
extern int blocking_io;
pid_t pid;
int to_child_pipe[2];
int from_child_pipe[2];
extern int blocking_io;
if (verbose >= 2) {
print_child_argv(command);
}
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
rprintf(FERROR,"pipe: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
rprintf(FERROR, "pipe: %s\n", strerror(errno));
exit_cleanup(RERR_IPC);
}
pid = do_fork();
if (pid == -1) {
rprintf(FERROR,"fork: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
pid = do_fork();
if (pid == -1) {
rprintf(FERROR, "fork: %s\n", strerror(errno));
exit_cleanup(RERR_IPC);
}
if (pid == 0)
{
extern int orig_umask;
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
close(from_child_pipe[0]) < 0 ||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
if (to_child_pipe[0] != STDIN_FILENO) 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) {
set_blocking(STDOUT_FILENO);
}
execvp(command[0], command);
rprintf(FERROR,"Failed to exec %s : %s\n",
command[0],strerror(errno));
exit_cleanup(RERR_IPC);
}
if (pid == 0) {
extern int orig_umask;
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
close(from_child_pipe[0]) < 0 ||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
rprintf(FERROR, "Failed to dup/close : %s\n",
strerror(errno));
exit_cleanup(RERR_IPC);
}
if (to_child_pipe[0] != STDIN_FILENO)
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) {
set_blocking(STDOUT_FILENO);
}
execvp(command[0], command);
rprintf(FERROR, "Failed to exec %s : %s\n",
command[0], strerror(errno));
exit_cleanup(RERR_IPC);
}
if (close(from_child_pipe[1]) < 0 ||
close(to_child_pipe[0]) < 0) {
rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
rprintf(FERROR, "Failed to close : %s\n", strerror(errno));
exit_cleanup(RERR_IPC);
}
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
return pid;
return pid;
}
pid_t local_child(int argc, char **argv,int *f_in,int *f_out)
@@ -173,10 +197,7 @@ pid_t local_child(int argc, char **argv,int *f_in,int *f_out)
extern int am_sender;
extern int am_server;
if (read_batch)
am_sender = 0;
else
am_sender = !am_sender;
am_sender = read_batch ? 0 : !am_sender;
am_server = 1;
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
@@ -219,10 +240,18 @@ void overflow(char *str)
int set_modtime(char *fname,time_t modtime)
int set_modtime(char *fname, time_t modtime)
{
extern int dry_run;
if (dry_run) return 0;
if (dry_run)
return 0;
if (verbose > 2) {
rprintf(FINFO, "set modtime of %s to (%ld) %s",
fname, (long) modtime,
asctime(localtime(&modtime)));
}
{
#ifdef HAVE_UTIMBUF
struct utimbuf tbuf;
@@ -275,7 +304,7 @@ int create_directory_path(char *fname)
derived from GNU C's cccp.c.
*/
static int full_write(int desc, char *ptr, int len)
static int full_write(int desc, char *ptr, size_t len)
{
int total_written;
@@ -301,11 +330,11 @@ static int full_write(int desc, char *ptr, int len)
for an error.
derived from GNU C's cccp.c. */
static int safe_read(int desc, char *ptr, int len)
static int safe_read(int desc, char *ptr, size_t len)
{
int n_chars;
if (len <= 0)
if (len == 0)
return len;
#ifdef EINTR
@@ -538,7 +567,7 @@ static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
globfree(&globbuf);
return;
}
for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
for (i=0; i<(maxargs - (*argc)) && i < (int) globbuf.gl_pathc;i++) {
if (i == 0) free(argv[*argc]);
argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
if (!argv[(*argc) + i]) out_of_memory("glob_expand");
@@ -835,9 +864,10 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
{
int pct = (ofs == size) ? 100 : (int)((100.0*ofs)/size);
unsigned long diff = msdiff(&start_time, now);
double rate = diff ? ((ofs-start_ofs) / diff) * 1000.0/1024.0 : 0;
const char *units, *rem_units;
double remain = rate ? (size-ofs) / rate : 0.0;
double rate = diff ? (double) (ofs-start_ofs) * 1000.0 / diff / 1024.0 : 0;
const char *units;
double remain = rate ? (double) (size-ofs) / rate / 1000.0: 0.0;
int remain_h, remain_m, remain_s;
if (rate > 1024*1024) {
rate /= 1024.0 * 1024.0;
@@ -849,19 +879,13 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
units = "kB/s";
}
if (remain > 5*60*60) {
remain /= 60*60;
rem_units = "h";
} if (remain > 5*60) {
remain /= 60;
rem_units = "m";
} else {
rem_units = "s";
}
remain_s = (int) remain % 60;
remain_m = (int) (remain / 60.0) % 60;
remain_h = (int) (remain / 3600.0);
rprintf(FINFO, "%12.0f %3d%% %7.2f%s %6.0f%s%s",
rprintf(FINFO, "%12.0f %3d%% %7.2f%s %4d:%02d:%02d%s",
(double) ofs, pct, rate, units,
remain, rem_units,
remain_h, remain_m, remain_s,
is_last ? "\n" : "\r");
}