Compare commits

...

126 Commits

Author SHA1 Message Date
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
Martin Pool
2f8dc29182 Update notes 2001-12-02 13:22:55 +00:00
Martin Pool
6066594bbe Improved estimation algorithm for time-to-complete. 2001-12-02 13:07:07 +00:00
Martin Pool
40c0289176 Typo fix by Tom Schmidt 2001-12-02 13:02:17 +00:00
Martin Pool
acf1af0cd9 const-cast required for silly UNICOS headers 2001-12-02 12:37:48 +00:00
Martin Pool
62791bdfa2 Also estimate time remaining. 2001-12-02 08:56:25 +00:00
Martin Pool
47f1218d69 Progress indicator now shows estimated rate of transfer (e.g. kB/s).
Based on a patch from Rik Faith, but modified to make sure we do only
one rprintf call, and that we never end up with two copies of the line
printed out.
2001-12-02 08:38:51 +00:00
Martin Pool
1179355dab Revert change from 1.39, because it causes a crash because of
attempting to free a static string.  (Thankyou to Paul Mackerras.)
There's still a small leak here.
2001-12-02 08:16:15 +00:00
Martin Pool
3d807132e4 Fix test suite breakage in calling tls.
Clean up test directory on completion.
2001-12-02 07:22:54 +00:00
Martin Pool
42d0b4c280 Bump version 2001-12-02 07:21:55 +00:00
Martin Pool
d313ae7d23 Move old news from release 2.5.0. 2001-12-02 07:17:50 +00:00
Martin Pool
28a69e25ea More notes from email. 2001-12-02 07:07:43 +00:00
Martin Pool
ad911a7ac3 Typo fix from Matt Kraai <kraai@debian.org> 2001-12-02 06:17:33 +00:00
Martin Pool
5575de140d Add note about device major/minor numbers, and about ACLs 2001-12-02 05:12:39 +00:00
David Dykstra
a5ce1eb1af Add "$(OBJS): config.h" so everything will rebuild if config.h changes. 2001-11-30 22:21:20 +00:00
Martin Pool
76a78cd8bc Add message to ignore warnings about mktemp 2001-11-30 22:06:29 +00:00
39 changed files with 1820 additions and 948 deletions

View File

@@ -1,3 +1,4 @@
testtmp.*
ID
Makefile
config.cache

View File

@@ -62,8 +62,11 @@ install-strip:
$(MAKE) INSTALLCMD='$(INSTALLCMD) -s' install
rsync: $(OBJS)
@echo "Please ignore warnings below about mktemp -- it is used in a safe way"
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
$(OBJS): config.h
tls: $(tls_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(tls_OBJ) $(LIBS)

121
NEWS
View File

@@ -1,114 +1,29 @@
rsync 2.5.0 (2001-11-30) -*- indented-text -*-
rsync 2.5.2 (???)
ANNOUNCEMENTS
SECURITY FIXES:
* Martin Pool <mbp@samba.org> is now a co-maintainer.
NEW FEATURES
* Support for LSB-compliant packaging <http://www.linuxbase.org/>
* Shell wildcards are allowed in "auth users" lines.
* Merged UNC rsync+ patch to support creation of standalone patch
sets. By Bert J. Dempsey and Debra Weiss, updated by Jos
Backus. <http://www.ils.unc.edu/i2dsi/unc_rsync+.html>
* IPv6 support based on a patch from KAME.net, on systems
including modern versions of Linux, Solaris, and HP-UX. Also
includes IPv6 compatibility functions for old OSs by the
Internet Software Consortium, Paul Vixie, the OpenSSH
portability project, and OpenBSD.
ENHANCEMENTS
* Include/exclude cluestick: with -vv, print out whether files are
included or excluded and why.
* Many error messages have more friendly explanations and more
details.
* Manual page improvements plus scanty protocol documentation.
* When running as --daemon in the background and using a "log
file" rsyncd.conf directive, close the log file every time it is
open when going to sleep on the socket. This allows the log
file to get cleaned out by another process.
* Change to using libpopt rather than getopt for processing
options. This makes the code cleaner and the behaviour more
consistent across platforms. popt is included and built if not
installed on the platform.
* More details in --version, including note about whether 64-bit
files, symlinks and hardlinks are supported.
* MD4 code may use less CPU cycles.
* Use mkstemp on systems where it is secure. If we use mktemp,
explain that we do it in a secure way.
* --whole-file is the default when source and target are on the
local machine.
* 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 for various bugs causing rsync to hang.
* Fix possible string mangling in log files.
* Attempt to fix Large File Summit support on AIX.
* Fix for setting local address of outgoing sockets.
* Attempt to fix error handling lockup bug.
* Better handling of hardlinks and devices on platforms with
64-bit dev_t or ino_t.
* Give a non-0 exit code if *any* of the files we have been asked
to transfer fail to transfer
ENHANCEMENTS:
* For log messages containing ridiculously long strings that might
overflow a buffer rsync no longer aborts, but rather prints an
ellipsis at the end of the string. (Patch from Ed Santiago.)
* --statistics now shows memory heap usage on platforms that
support mallinfo().
PLATFORMS:
* "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.)
* Improved support for UNICOS (tested on Cray T3E and Cray SV1)
* autoconf2.52 (or later) is now required to rebuild the autoconf
scripts. It is not required to simply build rsync.
* Platforms thought to work in this release:
Cray SV1 UNICOS 10.0.0.8 cc
Debian Linux 2.2 UltraSparc gcc
Debian Linux testing/unstable ARM gcc
FreeBSD 3.3-RELEASE i386 cc
FreeBSD 4.1.1-RELEASE i386 cc
FreeBSD 4.3-STABLE i386 cc
HP PA-RISC HP-UX 10.20 gcc
HP PA-RISC HP-UX 11.11 cc
IRIX 6.5 MIPS cc
IRIX 6.5 MIPS gcc
Mac OS X PPC (--disable-ipv6) cc
NetBSD 1.5 i386 gcc
NetBSD Current i386 cc
OpenBSD 2.5 Sparc gcc
OpenBSD 2.9 i386 cc
OpenBSD Current i386 cc
RedHat 6.2 i386 gcc
RedHat 6.2 i386 insure++
RedHat 7.0 i386 gcc
RedHat 7.1 i386 (Kernel 2.4.10) gcc
Slackware 8.0 i686 (Kernel 2.4.10)
Solaris 8 UltraSparc cc
Solaris 8 UltraSparc gcc
Solaris 8 i386 gcc
SuSE 7.1 i386 gcc2.95.2
SuSE 7.1 ppc gcc2.95.2
i386-pc-sco3.2v5.0.5 cc
i386-pc-sco3.2v5.0.5 gcc
powerpc-ibm-aix4.3.3.0 cc
i686-unknown-sysv5UnixWare7.1.0 gcc
i686-unknown-sysv5UnixWare7.1.0 cc
TESTING:
* The existing test.sh script by Phil Hands has been merged into a
test framework that works from both "make check" and the Samba
build farm.
* Improvements to batch mode support. This is still experimental
but testing would be welcome. (Jos Backus)

148
OLDNEWS Normal file
View File

@@ -0,0 +1,148 @@
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
* Martin Pool <mbp@samba.org> is now a co-maintainer.
NEW FEATURES
* Support for LSB-compliant packaging <http://www.linuxbase.org/>
* Shell wildcards are allowed in "auth users" lines.
* Merged UNC rsync+ patch to support creation of standalone patch
sets. By Bert J. Dempsey and Debra Weiss, updated by Jos
Backus. <http://www.ils.unc.edu/i2dsi/unc_rsync+.html>
* IPv6 support based on a patch from KAME.net, on systems
including modern versions of Linux, Solaris, and HP-UX. Also
includes IPv6 compatibility functions for old OSs by the
Internet Software Consortium, Paul Vixie, the OpenSSH
portability project, and OpenBSD.
ENHANCEMENTS
* Include/exclude cluestick: with -vv, print out whether files are
included or excluded and why.
* Many error messages have more friendly explanations and more
details.
* Manual page improvements plus scanty protocol documentation.
* When running as --daemon in the background and using a "log
file" rsyncd.conf directive, close the log file every time it is
open when going to sleep on the socket. This allows the log
file to get cleaned out by another process.
* Change to using libpopt rather than getopt for processing
options. This makes the code cleaner and the behaviour more
consistent across platforms. popt is included and built if not
installed on the platform.
* More details in --version, including note about whether 64-bit
files, symlinks and hardlinks are supported.
* MD4 code may use less CPU cycles.
* Use mkstemp on systems where it is secure. If we use mktemp,
explain that we do it in a secure way.
* --whole-file is the default when source and target are on the
local machine.
BUG FIXES:
* Fix for various bugs causing rsync to hang.
* Attempt to fix Large File Summit support on AIX.
* Attempt to fix error handling lockup bug.
* Give a non-0 exit code if *any* of the files we have been asked
to transfer fail to transfer
* For log messages containing ridiculously long strings that might
overflow a buffer rsync no longer aborts, but rather prints an
ellipsis at the end of the string. (Patch from Ed Santiago.)
PLATFORMS:
* Improved support for UNICOS (tested on Cray T3E and Cray SV1)
* autoconf2.52 (or later) is now required to rebuild the autoconf
scripts. It is not required to simply build rsync.
* Platforms thought to work in this release:
Cray SV1 UNICOS 10.0.0.8 cc
Debian Linux 2.2 UltraSparc gcc
Debian Linux testing/unstable ARM gcc
FreeBSD 3.3-RELEASE i386 cc
FreeBSD 4.1.1-RELEASE i386 cc
FreeBSD 4.3-STABLE i386 cc
HP PA-RISC HP-UX 10.20 gcc
HP PA-RISC HP-UX 11.11 cc
IRIX 6.5 MIPS cc
IRIX 6.5 MIPS gcc
Mac OS X PPC (--disable-ipv6) cc
NetBSD 1.5 i386 gcc
NetBSD Current i386 cc
OpenBSD 2.5 Sparc gcc
OpenBSD 2.9 i386 cc
OpenBSD Current i386 cc
RedHat 6.2 i386 gcc
RedHat 6.2 i386 insure++
RedHat 7.0 i386 gcc
RedHat 7.1 i386 (Kernel 2.4.10) gcc
Slackware 8.0 i686 (Kernel 2.4.10)
Solaris 8 UltraSparc cc
Solaris 8 UltraSparc gcc
Solaris 8 i386 gcc
SuSE 7.1 i386 gcc2.95.2
SuSE 7.1 ppc gcc2.95.2
i386-pc-sco3.2v5.0.5 cc
i386-pc-sco3.2v5.0.5 gcc
powerpc-ibm-aix4.3.3.0 cc
i686-unknown-sysv5UnixWare7.1.0 gcc
i686-unknown-sysv5UnixWare7.1.0 cc
TESTING:
* The existing test.sh script by Phil Hands has been merged into a
test framework that works from both "make check" and the Samba
build farm.

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

194
TODO
View File

@@ -32,15 +32,152 @@ use chroot
for people who want to generate the file list using a find(1)
command or a script.
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.
We can try using the GNU/SVID/XPG mallinfo() function to get some
heap statistics.
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
@@ -61,6 +198,48 @@ Errors
eof" give a message that is more detailed if possible and also more
helpful.
File attributes
Device major/minor numbers should be at least 32 bits each. See
http://lists.samba.org/pipermail/rsync/2001-November/005357.html
Transfer ACLs. Need to think of a standard representation.
Probably better not to even try to convert between NT and POSIX.
Possibly can share some code with Samba.
Empty directories
With the current common --include '*/' --exclude '*' pattern, people
can end up with many empty directories. We might avoid this by
lazily creating such directories.
zlib
Perhaps don't use our own zlib. Will we actually be incompatible,
or just be slightly less efficient?
logging
Perhaps flush stdout after each filename, so that people trying to
monitor progress in a log file can do so more easily. See
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
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 ------------------------------------------------------------
@@ -77,6 +256,10 @@ Win32
we are correct to call close(), because shutdown() discards
untransmitted data.
DOCUMENTATION --------------------------------------------------------
Update README
BUILD FARM -----------------------------------------------------------
Add machines
@@ -99,7 +282,9 @@ NICE -----------------------------------------------------------------
hang/timeout friendliness
On
verbose output
Indicate whether files are new, updated, or deleted
internationalization
@@ -118,3 +303,4 @@ rsyncsh
current host, directory and so on. We can probably even do
completion of remote filenames.
%K%

855
batch.c
View File

File diff suppressed because it is too large Load Diff

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;
@@ -79,7 +80,7 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
if (!user) user = getenv("LOGNAME");
fd = open_socket_out_wrapped (host, rsync_port, bind_address,
global_opts.af_hint);
default_af_hint);
if (fd == -1) {
exit_cleanup(RERR_SOCKETIO);
}
@@ -486,6 +487,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 +503,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 +516,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.0
RSYNC_VERSION=2.5.2pre1
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -22,6 +22,9 @@ 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])
@@ -30,6 +33,9 @@ fi
# compile with optimisation and without debugging by default, unless
# --debug is given. 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,
AC_HELP_STRING([--enable-debug],
@@ -43,12 +49,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])
@@ -204,6 +231,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 +296,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 +312,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 +337,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)
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
AC_TRY_RUN([

View File

@@ -299,7 +299,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

@@ -36,7 +36,7 @@ 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;
int ret;
@@ -69,7 +69,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;

104
flist.c
View File

@@ -1,7 +1,7 @@
/*
Copyright (C) Andrew Tridgell 1996
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
@@ -18,7 +18,14 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* generate and receive file lists */
/** @file flist.c
* Generate and receive file lists
*
* @todo Get rid of the string_area optimization. Efficiently
* allocating blocks is the responsibility of the system's malloc
* library, not of rsync.
*
**/
#include "rsync.h"
@@ -59,6 +66,35 @@ static struct file_struct null_file;
static void clean_flist(struct file_list *flist, int strip_root);
static int show_build_progress_p(void)
{
extern int do_progress;
return do_progress && verbose && recurse && !am_server;
}
/**
* True if we're local, etc, and should emit progress emssages.
**/
static void emit_build_progress(const struct file_list *flist)
{
rprintf(FINFO,
" %d files...\r",
flist->count);
}
static void finish_build_progress(const struct file_list *flist)
{
if (verbose && recurse && !am_server) {
/* This overwrites the progress line, if any. */
rprintf(FINFO, RSYNC_NAME ": %d files to consider.\n",
flist->count);
}
}
static struct string_area *string_area_new(int size)
{
struct string_area *a;
@@ -297,8 +333,15 @@ static void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
#if SUPPORT_HARD_LINKS
if (preserve_hard_links && S_ISREG(file->mode)) {
write_int(f,(int)file->dev);
write_int(f,(int)file->inode);
if (remote_version < 26) {
/* 32-bit dev_t and ino_t */
write_int(f,(int)file->dev);
write_int(f,(int)file->inode);
} else {
/* 64-bit dev_t and ino_t */
write_longint(f, file->dev);
write_longint(f, file->inode);
}
}
#endif
@@ -332,7 +375,7 @@ static void receive_file_entry(struct file_struct **fptr,
static gid_t last_gid;
static char lastname[MAXPATHLEN];
char thisname[MAXPATHLEN];
int l1=0,l2=0;
unsigned int l1=0,l2=0;
char *p;
struct file_struct *file;
@@ -399,6 +442,10 @@ static void receive_file_entry(struct file_struct **fptr,
if (preserve_links && S_ISLNK(file->mode)) {
int l = read_int(f);
if (l < 0) {
rprintf(FERROR,"overflow: l=%d\n", l);
overflow("receive_file_entry");
}
file->link = (char *)malloc(l+1);
if (!file->link) out_of_memory("receive_file_entry 2");
read_sbuf(f,file->link,l);
@@ -409,8 +456,13 @@ static void receive_file_entry(struct file_struct **fptr,
#if SUPPORT_HARD_LINKS
if (preserve_hard_links && S_ISREG(file->mode)) {
file->dev = read_int(f);
file->inode = read_int(f);
if (remote_version < 26) {
file->dev = read_int(f);
file->inode = read_int(f);
} else {
file->dev = read_longint(f);
file->inode = read_longint(f);
}
}
#endif
@@ -464,7 +516,8 @@ static int skip_filesystem(char *fname, STRUCT_STAT *st)
}
#define STRDUP(ap, p) (ap ? string_area_strdup(ap, p) : strdup(p))
#define MALLOC(ap, i) (ap ? string_area_malloc(ap, i) : malloc(i))
/* IRIX cc cares that the operands to the ternary have the same type. */
#define MALLOC(ap, i) (ap ? (void*) string_area_malloc(ap, i) : malloc(i))
/* create a file_struct for a named file */
struct file_struct *make_file(int f, char *fname, struct string_area **ap,
@@ -606,7 +659,10 @@ void send_file_name(int f,struct file_list *flist,char *fname,
file = make_file(f,fname, &flist->string_area, 0);
if (!file) return;
if (!file) return;
if (show_build_progress_p() & !(flist->count % 100))
emit_build_progress(flist);
if (flist->count >= flist->malloced) {
if (flist->malloced < 1000)
@@ -697,6 +753,11 @@ static void send_directory(int f,struct file_list *flist,char *dir)
}
/*
*
* I *think* f==-1 means that the list should just be built in memory
* and not transmitted. But who can tell? -- mbp
*/
struct file_list *send_file_list(int f,int argc,char *argv[])
{
int i,l;
@@ -707,7 +768,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
int64 start_write;
if (verbose && recurse && !am_server && f != -1) {
rprintf(FINFO,"building file list ... ");
rprintf(FINFO, RSYNC_NAME ": building file list...\n");
if (verbose > 1)
rprintf(FINFO, "\n");
rflush(FINFO);
@@ -830,8 +891,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
send_file_entry(NULL,f,0);
}
if (verbose && recurse && !am_server && f != -1)
rprintf(FINFO,"done\n");
finish_build_progress(flist);
clean_flist(flist, 0);
@@ -962,6 +1022,10 @@ oom:
}
/*
* XXX: This is currently the hottest function while building the file
* list, because building f_name()s every time is expensive.
**/
int file_compare(struct file_struct **f1,struct file_struct **f2)
{
if (!(*f1)->basename && !(*f2)->basename) return 0;
@@ -1084,6 +1148,10 @@ static void clean_flist(struct file_list *flist, int strip_root)
}
}
/* FIXME: There is a bug here when filenames are repeated more
* than once, because we don't handle freed files when doing
* the comparison. */
if (strip_root) {
/* we need to strip off the root directory in the case
of relative paths, but this must be done _after_
@@ -1119,6 +1187,10 @@ static void clean_flist(struct file_list *flist, int strip_root)
/*
* return the full filename of a flist entry
*
* This function is too expensive at the moment, because it copies
* strings when often we only want to compare them. In any case,
* using strlcat is silly because it will walk the string repeatedly.
*/
char *f_name(struct file_struct *f)
{
@@ -1131,9 +1203,11 @@ char *f_name(struct file_struct *f)
n = (n+1)%10;
if (f->dirname) {
strlcpy(p, f->dirname, MAXPATHLEN);
strlcat(p, "/", MAXPATHLEN);
strlcat(p, f->basename, MAXPATHLEN);
int off;
off = strlcpy(p, f->dirname, MAXPATHLEN);
off += strlcpy(p+off, "/", MAXPATHLEN-off);
off += strlcpy(p+off, f->basename, MAXPATHLEN-off);
} else {
strlcpy(p, f->basename, MAXPATHLEN);
}

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
@@ -99,25 +102,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 +218,8 @@ 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, RSYNC_NAME
": 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,RSYNC_NAME ": ignoring unsafe symlink \"%s\" -> \"%s\"\n",
fname,file->link);
}
return;
@@ -269,20 +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",
rprintf(FINFO,RSYNC_NAME": %s -> %s\n",
fname,file->link);
}
}
@@ -315,12 +333,14 @@ 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, RSYNC_NAME
": \"%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, RSYNC_NAME
": skipping non-regular file \"%s\"\n",fname);
return;
}
@@ -345,7 +365,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;
}
@@ -388,7 +410,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
}

58
io.c
View File

@@ -49,7 +49,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 +86,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 +103,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 +164,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 +237,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 +254,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 +272,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 +297,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 +305,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 +359,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;
@@ -375,9 +378,9 @@ unsigned char read_byte(int f)
}
/* write len bytes to fd */
static void writefd_unbuffered(int fd,char *buf,int len)
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 +427,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) {
@@ -483,10 +487,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);
@@ -533,7 +537,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;
@@ -587,7 +591,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 +610,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 +668,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);

View File

@@ -386,9 +386,16 @@ static void init_service(service *pservice)
/**
* Assign a copy of @p v to @p *s, freeing any existing values and
* handling NULL strings. @p *v must be initialized when this is
* called, either to NULL or a malloc'd string.
* Assign a copy of @p v to @p *s. Handles NULL strings. @p *v must
* be initialized when this is called, either to NULL or a malloc'd
* string.
*
* @fixme There is a small leak here in that sometimes the existing
* value will be dynamically allocated, and the old copy is lost.
* However, we can't always deallocate the old value, because in the
* case of sDefault, it points to a static string. It would be nice
* to have either all-strdup'd values, or to never need to free
* memory.
**/
static void string_set(char **s, const char *v)
{
@@ -396,8 +403,6 @@ static void string_set(char **s, const char *v)
*s = NULL;
return;
}
if (*s)
free(*s);
*s = strdup(v);
if (!*s)
exit_cleanup(RERR_MALLOC);

16
log.c
View File

@@ -286,13 +286,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 +332,21 @@ 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);
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,7 +403,7 @@ 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;
@@ -466,7 +470,7 @@ static void log_formatted(enum logcode code,
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);

44
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,11 @@ static void report(int f)
extern int remote_version;
int send_stats;
if (do_stats) {
/* These come out from every process */
show_malloc_stats();
}
if (am_daemon) {
log_exit(0, __FILE__, __LINE__);
if (f == -1 || !am_sender) return;
@@ -126,6 +132,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)
{
@@ -765,8 +803,10 @@ int main(int argc,char *argv[])
extern int write_batch; /* dw */
extern char *batch_ext; /* dw */
int orig_argc; /* dw */
char **orig_argv;
orig_argc = argc; /* dw */
orig_argv = argv;
signal(SIGUSR1, sigusr1_handler);
signal(SIGUSR2, sigusr2_handler);
@@ -806,7 +846,7 @@ int main(int argc,char *argv[])
if (write_batch) { /* dw */
create_batch_file_ext();
write_batch_argvs_file(orig_argc, argc, argv);
write_batch_argvs_file(orig_argc, orig_argv);
}
if (read_batch) { /* dw */

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
@@ -74,11 +74,21 @@ int modify_window=0;
#endif
int blocking_io=0;
/** 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 read_batch=0;
int write_batch=0;
char *backup_suffix = BACKUP_SUFFIX;
char *tmpdir = NULL;
@@ -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");
@@ -212,7 +230,8 @@ 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");
@@ -221,8 +240,8 @@ void usage(enum logcode F)
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," --read-batch=EXT read batch file\n");
rprintf(F," --write-batch write batch file\n");
rprintf(F," -h, --help show this help screen\n");
#ifdef INET6
rprintf(F," -4 prefer IPv4\n");
@@ -243,7 +262,7 @@ 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_MODIFY_WINDOW, OPT_READ_BATCH, OPT_WRITE_BATCH};
static struct poptOption long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
@@ -274,7 +293,7 @@ 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},
{"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,6 +317,7 @@ 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},
@@ -311,11 +331,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_ext, OPT_READ_BATCH},
{"write-batch", 0, POPT_ARG_NONE, &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}
};
@@ -491,9 +511,8 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
keep_partial = 1;
break;
case 'f':
/* The filename is stored for us by popt */
case OPT_READ_BATCH:
/* The filename is stored in batch_ext for us by popt */
read_batch = 1;
break;
@@ -530,7 +549,8 @@ void server_options(char **args,int *argc)
static char mdelete[30];
static char mwindow[30];
static char bw[50];
static char fext[20]; /* dw */
static char fext[20];
static char wbatch[14];
int i, x;
@@ -585,8 +605,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 +627,13 @@ void server_options(char **args,int *argc)
args[ac++] = mdelete;
}
if (write_batch) {
snprintf(wbatch,sizeof(wbatch),"--write-batch");
args[ac++] = wbatch;
}
if (batch_ext != NULL) {
sprintf(fext,"-f%s",batch_ext);
snprintf(fext,sizeof(fext),"--read-batch=%s",batch_ext);
args[ac++] = fext;
}

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

76
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
@@ -185,6 +185,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 +267,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 +335,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 +377,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 {
@@ -390,6 +425,7 @@ static inline int flist_up(struct file_list *flist, int i)
#include "proto.h"
#include "lib/mdfour.h"
#include "lib/permstring.h"
#include "lib/addrinfo.h"
/* We have replacement versions of these if they're missing. */
#ifndef HAVE_ASPRINTF
@@ -563,12 +599,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);

146
rsync.yo
View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsync)(1)(29 May 2001)()()
manpage(rsync)(1)(14 Dec 2001)()()
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
@@ -267,7 +267,8 @@ 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
@@ -276,8 +277,8 @@ verb(
--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=FILE read batch file
--write-batch write batch file
-h, --help show this help screen
@@ -377,17 +378,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
@@ -413,16 +413,15 @@ the source and target are on the local machine.
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
@@ -493,7 +492,7 @@ 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.
dit(bf(-B , --block_size=BLOCKSIZE)) This controls the block size used in
dit(bf(-B , --block-size=BLOCKSIZE)) This controls the block size used in
the rsync algorithm. See the technical report for details.
dit(bf(-e, --rsh=COMMAND)) This option allows you to choose an alternative
@@ -550,8 +549,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 +608,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
@@ -696,7 +708,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 +761,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,12 +793,15 @@ itemize(
manpagesection(BATCH MODE)
bf(Note:) Batch mode should be considered experimental in this version
of rsync. The interface or behaviour may change before it stabilizes.
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)
quote(
$ rsync -F [other rsync options here] \nl()
$ rsync --write-batch [other rsync options here] \nl()
/somewhere/src_dir /somewhere/target_dir
)
@@ -802,6 +817,29 @@ it() bf(rsync_delta.<timestamp>) data blocks for file update & change
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 +965,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
}
discard_scratch() {
[ -d "$scratchdir" ] && rm -rf "$scratchdir"
return 0
}
if [ "x$whichtests" = x ]
then
whichtests="*.test"
@@ -177,29 +188,45 @@ 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"
then
echo "----- $testbase completed succesfully"
set +e
sh $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1
result=$?
set -e
case $result in
0)
echo "PASS $testbase"
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
fi
discard_scratch
;;
77)
echo "SKIP $testbase"
skipped=`expr $skipped + 1`
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"
echo "----- $testbase failed: log follows"
cat "$scratchdir/test.log"
echo "----- $testbase log ends"
failed=`expr $failed + 1`
if [ "x$nopersist" = "xyes" ]
then
exit 1
fi
esac
done
echo '------------------------------------------------------------'

View File

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

184
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,14 +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. */
static int establish_proxy_connection(int fd, char *host, int port)
@@ -94,6 +97,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 +157,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 +197,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 +288,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 +297,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 +368,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);
@@ -372,8 +387,8 @@ void start_accept_loop(int port, int (*fn)(int ))
while (1) {
fd_set fds;
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 +404,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;
@@ -555,8 +570,8 @@ void become_daemon(void)
**/
char *client_addr(int fd)
{
struct sockaddr ss;
int length = sizeof(ss);
struct sockaddr_storage ss;
socklen_t length = sizeof ss;
static char addr_buf[100];
static int initialised;
@@ -564,23 +579,29 @@ char *client_addr(int fd)
initialised = 1;
if (getpeername(fd, &ss, &length)) {
if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
exit_cleanup(RERR_SOCKETIO);
}
getnameinfo(&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
**/
char *client_name(int fd)
{
struct sockaddr ss;
int length = sizeof(ss);
struct sockaddr_storage ss;
socklen_t length = sizeof ss;
static char name_buf[100];
static char port_buf[100];
char *def = "UNKNOWN";
@@ -602,8 +623,14 @@ char *client_name(int fd)
}
#ifdef INET6
if (ss.sa_family == AF_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;
@@ -616,6 +643,9 @@ char *client_name(int fd)
sin->sin_len = length;
#endif
sin->sin_port = sin6.sin6_port;
/* FIXME: Isn't there a macro we can use here rather
* than grovelling through the struct? It might be
* wrong on some systems. */
memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
sizeof(sin->sin_addr));
}
@@ -646,7 +676,7 @@ char *client_name(int fd)
/* XXX sin6_flowinfo and other fields */
for (res = res0; res; res = res->ai_next) {
if (res->ai_family != ss.sa_family)
if (res->ai_family != get_sockaddr_family(&ss))
continue;
if (res->ai_addrlen != length)
continue;
@@ -654,13 +684,11 @@ char *client_name(int fd)
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);
"reverse name lookup for \"%s\" failed on fd%d - spoofed address? \n",
name_buf, fd);
}
freeaddrinfo(res0);

View File

@@ -132,7 +132,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
}

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

View File

@@ -26,3 +26,5 @@ cp ${FROM}/text ${TO}/ThisShouldGo
runtest " --delete" 'checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
checkforlogs ${LOG}.?
hands_cleanup

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

@@ -53,7 +53,8 @@ hands_setup() {
# Clean before creation
rm -rf $FROM
rm -rf $TO
[ -d $TMP ] || mkdir $TMP
[ -d $FROM ] || mkdir $FROM
[ -d $TO ] || mkdir $TO
@@ -72,7 +73,7 @@ hands_setup() {
mkdir ${FROM}/emptydir
# a hundred lines of text or so
rsync_ls_lR ${srcdir} > ${FROM}/filelist
rsync_ls_lR "${srcdir}" > ${FROM}/filelist
# This might fail on systems that don't have -n
echo $ECHO_N "This file has no trailing lf$ECHO_C" > ${FROM}/nolf
@@ -94,6 +95,11 @@ hands_setup() {
}
hands_cleanup() {
rm -r "$TMP"
}
####################
@@ -129,35 +135,31 @@ 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 ""
diff -cr $2 $3 || failed=YES
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
}
@@ -204,3 +206,29 @@ 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
}
# 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,29 @@
#! /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"
[ -L "$todir/dangling" ] && test_fail "dangling symlink was copied"
[ -L "$todir/relative" ] && test_fail "relative symlink was copied"
[ -L "$todir/absolute" ] && test_fail "absolute symlink was copied"
exit 0
# last [] may have failed but if we get here then we've one

14
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
@@ -80,11 +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, " -> ");
readlink(fname, linkbuf+4, sizeof(linkbuf) - 4);
/* const-cast required for silly UNICOS headers */
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;
}
@@ -110,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);
}

94
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
@@ -173,10 +173,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 ||
@@ -275,7 +272,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 +298,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
@@ -811,28 +808,91 @@ int u_strcmp(const char *cs1, const char *cs2)
return (int)*s1 - (int)*s2;
}
static OFF_T last_ofs;
static OFF_T last_ofs;
static struct timeval print_time;
static struct timeval start_time;
static OFF_T start_ofs;
static unsigned long msdiff(struct timeval *t1, struct timeval *t2)
{
return (t2->tv_sec - t1->tv_sec) * 1000
+ (t2->tv_usec - t1->tv_usec) / 1000;
}
/**
* @param ofs Current position in file
* @param size Total size of file
* @param is_last True if this is the last time progress will be
* printed for this file, so we should output a newline. (Not
* necessarily the same as all bytes being received.)
**/
static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
int is_last)
{
int pct = (ofs == size) ? 100 : (int)((100.0*ofs)/size);
unsigned long diff = msdiff(&start_time, now);
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;
units = "GB/s";
} else if (rate > 1024) {
rate /= 1024.0;
units = "MB/s";
} else {
units = "kB/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 %4d:%02d:%02d%s",
(double) ofs, pct, rate, units,
remain_h, remain_m, remain_s,
is_last ? "\n" : "\r");
}
void end_progress(OFF_T size)
{
extern int do_progress, am_server;
if (do_progress && !am_server) {
rprintf(FINFO,"%.0f (100%%)\n", (double)size);
struct timeval now;
gettimeofday(&now, NULL);
rprint_progress(size, size, &now, True);
}
last_ofs = 0;
last_ofs = 0;
start_ofs = 0;
print_time.tv_sec = print_time.tv_usec = 0;
start_time.tv_sec = start_time.tv_usec = 0;
}
void show_progress(OFF_T ofs, OFF_T size)
{
extern int do_progress, am_server;
struct timeval now;
if (do_progress && !am_server) {
if (ofs > last_ofs + 1000) {
int pct = (int)((100.0*ofs)/size);
rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
last_ofs = ofs;
}
gettimeofday(&now, NULL);
if (!start_time.tv_sec && !start_time.tv_usec) {
start_time.tv_sec = now.tv_sec;
start_time.tv_usec = now.tv_usec;
start_ofs = ofs;
}
if (do_progress
&& !am_server
&& ofs > last_ofs + 1000
&& msdiff(&print_time, &now) > 250) {
rprint_progress(ofs, size, &now, False);
last_ofs = ofs;
print_time.tv_sec = now.tv_sec;
print_time.tv_usec = now.tv_usec;
}
}