Compare commits

...

119 Commits

Author SHA1 Message Date
Wayne Davison
54f00c3f89 Preparing for release of 3.0.7 2009-12-31 13:08:07 -08:00
Wayne Davison
1fc8c51705 Allow any gcc to make use of __builtin_alloca for alloca. 2009-12-30 20:03:49 -08:00
Wayne Davison
b04604945d Configure check for -Wno-unused-parameter now tries to link too. 2009-12-30 19:57:47 -08:00
Wayne Davison
808b1d61c0 Fixed the passing of a '/' modifier for an absolute-path filter rule. 2009-12-30 12:25:33 -08:00
Wayne Davison
2f01fb1152 Preparing for release of 3.0.7pre2 2009-12-24 08:31:37 -08:00
Wayne Davison
ae358c1960 Revert to having the receiver handle timeouts on the receiving side.
This will give 3.0.7 the standard timeout handling with just a few
improvements: a fix for the detection of recent sender I/O, the use
of MSG_DATA for really old rsync versions, and better setting of
select_timeout for shorter timeout settings.
2009-12-23 11:36:27 -08:00
Wayne Davison
212dfdb960 Preparing for release of 3.0.7pre1 2009-12-21 18:25:00 -08:00
Wayne Davison
c11a77894b Ensure that the generator gets notified about an I/O error for the dir
that generated the error.  This ensures that a --delete-during avoids
deleting in a newly transferred inc-recurse directory.  Requires 3.0.7
or greater on both sides of the transfer.
2009-12-21 14:40:41 -08:00
Wayne Davison
96cce18ce6 Defer forwarding messages during the forwarding of flist data. 2009-12-21 13:48:44 -08:00
Wayne Davison
a21264a8b9 Mention the compress fix. 2009-12-21 10:52:54 -08:00
Wayne Davison
96486cc534 Mention latest --timeout fixes. 2009-12-21 10:25:15 -08:00
Wayne Davison
e0b1b82d84 Don't die if inflate() returns Z_BUF_ERROR in see_deflate_token(). 2009-12-21 10:15:39 -08:00
Wayne Davison
d94b958400 Improve --timeout method to take into account all socket I/O that is
going on.  The receiving side also switches timeout handling from the
receiver to the generator.  Given this setup, all keep-alive messages
are now sent as empty MSG_DATA messages, with MSG_NOOP messages only
being understood and (when necessary) acted upon to forward a keep-alive
event to an older receiver.  This is both safer and more compatible with
older versions.
2009-12-19 13:39:49 -08:00
Wayne Davison
79731940bb Added an am_receiver variable. 2009-12-19 12:04:25 -08:00
Wayne Davison
bdc038fce0 Use 0-length MSG_DATA when MSG_NOOP is not available
(is both safer and supports older rsyncs).
2009-12-16 13:32:03 -08:00
Wayne Davison
2eacba9c41 Avoid -u option to id since solaris doesn't support it. 2009-12-13 19:35:01 -08:00
Wayne Davison
0c5853c32e Get rid of some unused externs. 2009-12-12 22:43:51 -08:00
Wayne Davison
3baa4d2b31 Include info on who is exiting. 2009-12-12 22:42:35 -08:00
Wayne Davison
018dc6f998 Mention the newly cherry-picked changes. 2009-12-12 17:26:11 -08:00
Wayne Davison
523dad4bb3 Use seteuid() (if available) when using setuid(). 2009-12-12 17:26:05 -08:00
Wayne Davison
e0c17aa3b7 Beginning work on a 3.0.7 release. 2009-12-12 17:25:48 -08:00
Wayne Davison
79870bd269 Don't (wrongly) retouch dir permissions with --fake-super.
(Patch from Matt.)
2009-12-12 17:25:19 -08:00
Wayne Davison
e4368e37fe Add IPv6 detection on cygwin. 2009-12-12 17:25:12 -08:00
Wayne Davison
eee529f571 Save first filename and linenum in case exit_cleanup() recurses. 2009-12-12 17:25:06 -08:00
Wayne Davison
ff4715a7c2 Moved some --iconv text that was supposed to be in --files-from. 2009-12-12 17:24:45 -08:00
Wayne Davison
855983b434 Make sure daemon's io_timeout is used as a maximum value. 2009-12-12 17:24:39 -08:00
Wayne Davison
2455140b04 Fix some man page problems Scott Kostyshak pointed out. 2009-12-12 17:24:33 -08:00
Wayne Davison
ae4d4205e3 Avoid type-punned compiler warnings for the byteorder.h macros
by using inline functions for the 4-char <-> uint32 conversions.
2009-12-12 17:24:29 -08:00
Wayne Davison
9523670032 Improve the "--delete does not work without -r or -d" message. 2009-12-12 17:23:55 -08:00
Wayne Davison
01e57e926c Improve error handling and get rid of a lingering fprintf(). 2009-12-12 17:23:45 -08:00
Wayne Davison
ebbab3788f Fix daemon's conveyance of io_error value from sender. 2009-12-12 17:23:03 -08:00
Wayne Davison
d041c17c40 Avoid an dry-run error trying to stat a prior hard-link
file that hasn't really been created.
2009-12-12 17:22:55 -08:00
Wayne Davison
b2b1af40c2 Rebuild proto.h if config.h changes. 2009-12-12 17:22:43 -08:00
Wayne Davison
c5759a2817 Fix the chmod-temp-dir test if /var/tmp doesn't exist.
Fixes bug 6569.
2009-12-12 17:22:12 -08:00
Wayne Davison
5ef08b8c39 Get section reference right. Fixes bug #6573. 2009-12-12 17:22:05 -08:00
Wayne Davison
03f907e386 Added solaris IPv6 checking to configure. Fixes #6438.
Patch from Tim Spriggs.
2009-12-12 17:21:25 -08:00
Wayne Davison
573e24346c Mention that --whole-file is not the default for a local transfer when
writing a batch file.
2009-12-12 17:21:08 -08:00
Wayne Davison
a415379037 Support an older AIX system that doesn't have ENOTSUP. 2009-12-12 17:20:42 -08:00
Wayne Davison
cc4edc2d78 Switch from inet_aton() to inet_pton() (since we supply a compatibility
function for the latter, it will always exist).
2009-12-12 17:20:35 -08:00
Wayne Davison
07bd6618b9 Allow $RSYNC_TEST_TMP to indicate a good tmp dir for our tests. 2009-12-12 17:19:59 -08:00
Wayne Davison
2daed024b1 Fix a bogus free in uncache_tmp_xattrs(). 2009-08-14 07:04:24 -07:00
Wayne Davison
6622816eff Preparing for release of 3.0.6 2009-05-08 10:07:14 -07:00
Wayne Davison
3f137ce0e2 Fix typo pointed out by Chris Pepper. 2009-05-07 08:04:24 -07:00
Matt McCutchen
d616bff57f Move the description of include/exclude modifiers to a better place
in the man page.
2009-05-05 08:18:36 -07:00
Wayne Davison
40b3a59fc8 Clarify which options are transfer rules, and what that means. 2009-04-27 07:26:04 -07:00
Wayne Davison
4640ae85fe Change sending/receiving/storing of the rdev value for special files.
Since the value is not needed, the (superfluous) sending of the value
is optimized so that a valid rdev value is sent as efficiently as
possible.  The receiver no longer caches an rdev value for special
files, and the generator will always pass a 0 rdev value to do_mknod()
for special files. Fixes bug #6280.
2009-04-26 07:51:50 -07:00
Wayne Davison
24f739c118 Clarify the read-batch fix. 2009-04-13 07:42:20 -07:00
Wayne Davison
996824825f Preparing for release of 3.0.6pre1 2009-04-12 15:28:34 -07:00
Wayne Davison
bbef6566cd Changed the commands used to "make gen" without any stoppage. 2009-04-12 15:19:30 -07:00
Wayne Davison
9be5093726 Don't allow --remove-s*-files with --read-batch. 2009-04-12 13:01:14 -07:00
Wayne Davison
feb8dacc14 Fixed the use of --xattrs with --only-write-batch. 2009-04-12 12:48:59 -07:00
Wayne Davison
ff908116ef Allow a "make reconfigure" to continue, even if the Makefile changes. 2009-04-10 16:24:49 -07:00
Wayne Davison
ea53d161be Fixed an ACL/xattr corruption issue where the --backup option could cause
rsync to associate the wrong ACL/xattr information with received files.
2009-04-10 16:09:39 -07:00
Wayne Davison
7875e6fe63 Don't try to simplify an ACL that has a mask w/o any named values. 2009-04-09 22:52:26 -07:00
Wayne Davison
8e2771aa6e Some improvements to the rsync.yo manpage:
- Mention the switch from MD4 to MD5.
- Mention the default for the --log-file-format option.
2009-04-07 07:40:30 -07:00
Wayne Davison
386f22cec6 Make sure that config.h.in is up-to-date before allowing the
Makefile-updating rule to run ./config.status.
2009-04-04 07:53:14 -07:00
Wayne Davison
272adea36b Fixed --dry-run with --read-batch:
- Avoid sending MSG_NO_SEND to the generator.
- Check if the file is wanted before discarding the batched data.
2009-04-04 07:38:37 -07:00
Wayne Davison
a69b165524 Fixed improper deletion of mount-point hierarchies.
Fixes bug #6240.
2009-03-31 20:26:10 -07:00
Wayne Davison
bf350d7b31 Fixed a word ending that Jesse Weinstein and revamp some of the text
to make it clearer.
2009-03-31 14:35:53 -07:00
Wayne Davison
70a9cd5752 Make symlink iconv work for a local copy.
Fixes issue mention in bug #5615.
2009-03-29 13:25:43 -07:00
Matt McCutchen
42560e2e53 Give a meaningful error message when we fail to write to a batch file. 2009-03-13 09:46:39 -07:00
Wayne Davison
d058d0aecd Simplify an "if" in ssh-basic.test. Fixes bug #6169; 2009-03-06 07:08:49 -08:00
Wayne Davison
af00666a40 Mention the fix to --safe-links/--copy-unsafe-links. 2009-03-03 09:00:29 -08:00
Wayne Davison
2517f5440d Improved the unsafe_symlink() code to not get fooled by extra '/' chars
in the symlink's path.  Added test cases.  This fixes bug #6151.
2009-03-03 08:57:43 -08:00
Wayne Davison
f2522e3f53 Make the backup code call unsafe_symlink() correctly. 2009-03-03 08:57:39 -08:00
Wayne Davison
8fba76d5c3 Mention vanishing-directory fix. 2009-02-14 08:38:24 -08:00
Wayne Davison
782b96d3e2 Handle a link_stat() failure with errno ENOENT as a vanished file. 2009-02-14 08:37:10 -08:00
Wayne Davison
1f6b697f28 Mention the latest configure fixes. 2009-02-14 08:05:07 -08:00
Wayne Davison
919491948e Added --disable-iconv-open option for configure to turn off all use
of the iconv_open() function.  Implies --disable-iconv (which turns
off the --iconv option).  Fixes bug #6107.
2009-02-14 07:57:50 -08:00
Wayne Davison
0ea6f486d9 Moved the --disable-debug check sooner in configure.in so that it
happens prior to checking for the compiler.  Switched no-debug code
to setting ac_cv_prog_cc_g=no.  Fixes bug #6106.
2009-02-14 07:57:36 -08:00
Wayne Davison
9493048c10 Ensure that the sender turns off any msg_fd_in use earlier.
This avoids a problem where an extra message from the sender
could give the generator time to start sending data that will
not be understood by the sender's use of read_msg_fd().
2009-02-04 18:27:07 -08:00
Wayne Davison
4dea1a9492 Do not try to send a symlink with a 0-length value.
This avoids a transfer error in the receiver.
2009-02-04 18:16:16 -08:00
Wayne Davison
650bca3770 A few more improvements to the hostspec-parsing code. 2009-01-28 23:18:45 -08:00
Wayne Davison
794f38099a Fixed the parsing of IPv6 literal addresses with a username
prefixed.  Fixes bug #6067.
2009-01-28 15:58:48 -08:00
Wayne Davison
8250d8a1c6 Fixed a hang in the inc_recurse batch-reading code. 2009-01-17 13:54:52 -08:00
Matt McCutchen
1fb6163c51 Handle simultaneous arrival of multiple connections. 2009-01-17 13:46:11 -08:00
Wayne Davison
7f51d0e849 Avoid a server-side problem with -e is at the start of the short options.
(Bug #6020)
2009-01-17 13:44:06 -08:00
Wayne Davison
ece2d0e415 Fixed bug #6011: use of target in configure. 2009-01-17 13:43:48 -08:00
Wayne Davison
445640e803 Update the copyright year. 2009-01-17 13:41:35 -08:00
Wayne Davison
5ea7c8aae3 Beginning work on a 3.0.6 release. 2009-01-17 13:37:20 -08:00
Wayne Davison
7221063019 Preparing for release of 3.0.5 2008-12-28 18:02:17 -08:00
Wayne Davison
b64ae8b3b4 Avoid a hang when using at least 3 --verbose options on a transfer with
a client sender (which includes local copying).
2008-12-28 17:51:36 -08:00
Wayne Davison
9938bad34a Allow opendir() in send_directory() to fail with ENOENT. 2008-12-27 11:22:02 -08:00
Wayne Davison
1ff3e90507 Make it clearer which configure files changed. 2008-11-15 15:32:02 -08:00
Wayne Davison
b292021e45 Mention a few NEWS items that hadn't been mentioned yet. 2008-11-15 15:25:30 -08:00
Wayne Davison
13e40ca0c6 Preparing for release of 3.0.5pre2 2008-11-15 14:55:30 -08:00
Wayne Davison
8e85627fb3 An ftruncate() failure should result in FERROR_XFER. 2008-11-15 14:49:28 -08:00
Wayne Davison
d552250fbb Tweaked the month guess in OLDNEWS. 2008-11-15 14:38:14 -08:00
Wayne Davison
5436b64557 Change clean_fname() to keep "//" at the start for cygwin. 2008-11-15 14:17:49 -08:00
Wayne Davison
b325dd0326 Change some size_t vars to ints. 2008-11-15 13:29:03 -08:00
Wayne Davison
49818a8378 Make sparse_seek an OFF_T (pointed out by Pedro Valasco). 2008-11-11 18:06:50 -08:00
Wayne Davison
af03a7049c A "make reconfigure" doesn't stop if configure changes. 2008-11-11 15:55:53 -08:00
Wayne Davison
e401b30403 Mention Matt's -K --delete fix. 2008-11-10 07:48:00 -08:00
Matt McCutchen
e512826786 Add flist_find_ignore_dirness() and change delete_in_dir() to use it.
This fixes an issue with -K noticed by eric casteleijn, avoids some
inconsistent itemizing when a file/dir is replaced by a dir/file,
and removes a now-obsolete chunk of code from make_file().
2008-11-10 07:46:41 -08:00
Wayne Davison
ccdc2efd67 Mention the fix for --files-from dot/./paths. 2008-11-09 21:48:21 -08:00
Wayne Davison
b8a1fd6404 Fixed the use of a dot-dir path (foo/./bar) inside of a files-from file. 2008-11-09 21:39:08 -08:00
Wayne Davison
3082dffbe2 Fixed a bunch of "warn_unused_result" compiler warnings. 2008-11-09 18:55:14 -08:00
Wayne Davison
42130f9cb0 Mention hang fix in the NEWS. 2008-11-09 18:07:30 -08:00
Wayne Davison
c6c339cd18 Avoid a potential hang when --remove-*-files is active. 2008-11-09 18:02:11 -08:00
Matt McCutchen
6767ca617b The protect filter automatically added with --backup is not perishable
(see f41152d393), so remove the inaccurate
"p" from the man page.  Noticed by Jacob Balazer:

http://lists.samba.org/archive/rsync/2008-November/022022.html
2008-11-02 20:53:01 -08:00
Wayne Davison
7d9e30d383 Mention the getnameinfo() fix in the NEWS. 2008-10-25 09:47:08 -07:00
Wayne Davison
3f81ad6060 Mention rsync's definition of client and server. 2008-10-25 09:44:21 -07:00
Wayne Davison
723e9f856d Fixed our supplied getnameinfo()'s ability to do a reverse lookup,
as reported in bug 5851.
2008-10-25 08:39:41 -07:00
Wayne Davison
9189e41f6e Added another file-list filter to handle odd-ball systems that don't
seem to size their sprintf() fields correctly.
2008-10-14 07:27:56 -07:00
Wayne Davison
6f6f9d1020 Preparing for release of 3.0.5pre1 2008-10-11 11:41:05 -07:00
Wayne Davison
a76ba8b425 Mention the latest NEWS. 2008-10-11 11:40:40 -07:00
Wayne Davison
b8fd528794 Fixed a glitch when using -s with a remote-shell daemon. 2008-10-11 11:14:43 -07:00
Wayne Davison
0ea5d30479 Don't lookup address "0.0.0.0" when we're a remote-shell daemon.
Gets rid of a DNS delay waiting for a lookup failure.
2008-10-11 11:13:43 -07:00
Wayne Davison
cf1b292201 Fixed send_protected_args() to send "." in place of an empty arg. 2008-10-11 10:16:47 -07:00
Wayne Davison
f3721ed133 Added a fully atomic update if the user has setup a symlink
to a *-1 or *-2 directory.  A few other minor improvements.
2008-10-11 09:29:23 -07:00
Wayne Davison
b1220d62f4 Fix the error message on one of the rename operations. 2008-10-10 06:55:21 -07:00
Wayne Davison
5df89a1a44 Remove bogus "non-empty" qualifier in '*' discussion. 2008-09-26 21:47:53 -07:00
Wayne Davison
d47ac91209 Properly ignore source args on a --read-batch command. 2008-09-26 21:34:40 -07:00
Wayne Davison
7c573428a9 Fixed skipping of unneeded updates in a batch file when incremental
recursion is active.  Added a test for this.  Made batch-mode handle
redos properly (and without hanging).
2008-09-26 21:32:43 -07:00
Wayne Davison
f7e65c7b61 Moved the flist_ndx_{push,pop}() routines from io.c into util.c. 2008-09-26 21:21:52 -07:00
Wayne Davison
fe62d30de8 Fix the %P logfile escape inside a chroot. 2008-09-26 21:19:51 -07:00
Wayne Davison
494895fb4b Initialize xattr data in a couple spots in the hlink code, which avoids
a crash when the xattr pointer's memory happens to start out non-zero.
Also fixed the itemizing of an alt-dest file's xattrs when hard-linking.
2008-09-26 21:10:58 -07:00
Wayne Davison
ac68345a34 Don't send a bogus "-" option to an older server if there were
no short options specified.
2008-09-26 21:09:41 -07:00
Wayne Davison
6a9ade2ded Beginning work on a 3.0.5 release. 2008-09-26 21:07:56 -07:00
65 changed files with 1529 additions and 740 deletions

View File

@@ -59,7 +59,7 @@ CHECK_OBJS=tls.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
@OBJ_RESTORE@
all: conf_stop make_stop rsync$(EXEEXT) @MAKE_MAN@
all: Makefile rsync$(EXEEXT) @MAKE_MAN@
install: all
-mkdir -p ${DESTDIR}${bindir}
@@ -123,8 +123,6 @@ gensend: gen
conf:
cd $(srcdir) && $(MAKE) -f prepare-source.mak conf
conf_stop: configure.sh config.h.in
configure.sh config.h.in: configure.in aclocal.m4
@if test -f configure.sh; then cp -p configure.sh configure.sh.old; else touch configure.sh.old; fi
@if test -f config.h.in; then cp -p config.h.in config.h.in.old; else touch config.h.in.old; fi
@@ -133,32 +131,42 @@ configure.sh config.h.in: configure.in aclocal.m4
@if diff configure.sh configure.sh.old >/dev/null 2>&1; then \
echo "configure.sh is unchanged."; \
rm configure.sh.old; \
else \
echo "configure.sh has CHANGED."; \
fi
@if diff config.h.in config.h.in.old >/dev/null 2>&1; then \
echo "config.h.in is unchanged."; \
rm config.h.in.old; \
else \
echo "config.h.in has CHANGED."; \
fi
@if test -f configure.sh.old -o -f config.h.in.old; then \
echo 'Configure files changed -- perhaps run:'; \
echo ' make reconfigure'; \
exit 1; \
if test "$(MAKECMDGOALS)" = reconfigure; then \
echo 'Continuing with "make reconfigure".'; \
else \
echo 'You may need to run:'; \
echo ' make reconfigure'; \
exit 1; \
fi \
fi
reconfigure: configure.sh
./config.status --recheck
./config.status
make_stop: Makefile
Makefile: Makefile.in config.status
Makefile: Makefile.in config.status configure.sh config.h.in
@if test -f Makefile; then cp -p Makefile Makefile.old; else touch Makefile.old; fi
@./config.status
@if diff Makefile Makefile.old >/dev/null 2>&1; then \
echo "Makefile is unchanged."; \
rm Makefile.old; \
else \
echo "Makefile updated -- rerun your make command."; \
exit 1; \
if test "$(MAKECMDGOALS)" = reconfigure; then \
echo 'Continuing with "make reconfigure".'; \
else \
echo "Makefile updated -- rerun your make command."; \
exit 1; \
fi \
fi
proto: proto.h-tstamp
@@ -166,7 +174,7 @@ proto: proto.h-tstamp
proto.h: proto.h-tstamp
@if test -f proto.h; then :; else cp -p $(srcdir)/proto.h .; fi
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c config.h
perl $(srcdir)/mkproto.pl $(srcdir)/*.c $(srcdir)/lib/compat.c
man: rsync.1 rsyncd.conf.5

84
NEWS
View File

@@ -1,64 +1,64 @@
NEWS for rsync 3.0.4 (6 Sep 2008)
NEWS for rsync 3.0.7 (31 Dec 2009)
Protocol: 30 (unchanged)
Changes since 3.0.3:
Changes since 3.0.6:
BUG FIXES:
- Fixed a bug in the hard-linking code where it would sometimes try to
allocate 0 bytes of memory (which fails on some OSes, such as AIX).
- Fixed a bogus free when using --xattrs with --backup.
- Fixed the hard-linking of files from a device that has a device number
of 0 (which seems to be a common device number on NetBSD).
- Avoid an error when --dry-run was trying to stat a prior hard-link file
that hasn't really been created.
- Fixed the handling of a --partial-dir that cannot be created. This
particularly impacts the --delay-updates option (since the files cannot
be delayed without a partial-dir), and was potentially destructive if
the --remove-source-files was also specified.
- Fixed a problem with --compress (-z) where the receiving side could
return the error "inflate (token) returned -5".
- Fixed a couple issues in the --fake-super handling of xattrs when the
destination files have root-level attributes (e.g. selinux values) that
a non-root copy can't affect.
- Fixed a bug where --delete-during could delete in a directory before it
noticed that the sending side sent an I/O error for that directory (both
sides of the transfer must be at least 3.0.7).
- Improved the keep-alive check in the generator to fire consistently in
incremental-recursion mode when --timeout is enabled.
- Improved --skip-compress's error handling of bad character-sets and got
rid of a lingering debug fprintf().
- The --iconv option now converts the content of a symlink too, instead
of leaving it in the wrong character-set (requires 3.0.4 on both sides
of the transfer).
- Fixed the daemon's conveyance of io_error value from the sender.
- When using --iconv, if a filename fails to convert on the receiving side,
this no longer makes deletions in the root-dir of the transfer fail
silently (the user now gets a warning about deletions being disabled
due to IO error as long as --ignore-errors was not specified).
- An rsync daemon use seteuid() (when available) if it used setuid().
- When using --iconv, if a server-side receiver can't convert a filename,
the error message sent back to the client no longer mangles the name
with the wrong charset conversion.
- Get the permissions right on a --fake-super transferred directory that
needs more owner permissions to emulate root behavior.
- Fixed a potential alignment issue in the IRIX ACL code when allocating
the initial "struct acl" object. Also, cast mallocs to avoid warnings.
- An absolute-path filter rule (i.e. with a '/' modifier) no longer loses
its modifier when sending the filter rules to the remote rsync.
- Changed some errors that were going to stdout to go to stderr.
- Improved the "--delete does not work without -r or -d" message.
- Made human_num() and human_dnum() able to output a negative number
(rather than outputting a cryptic string of punctuation).
- Improved rsync's handling of --timeout to avoid a weird timeout case
where the sender could timeout even though it has recently written data
to the socket (but hasn't read data recently, due to the writing).
ENHANCEMENTS:
- Some misc manpage improvements.
- Rsync will avoid sending an -e option to the server if an older protocol
is requested (and thus the option would not be useful). This lets the
user specify the --protocol=29 option to access an overly-restrictive
server that is rejecting the protocol-30 use of -e to the server.
- Fixed the chmod-temp-dir testsuite on a system without /var/tmp.
- Improved the message output for an RERR_PARTIAL exit.
- Make sure that a timeout specified in the daemon's config is used as a
maximum timeout value when the user also specifies a timeout.
- Improved the error-exit reporting when rsync gets an error trying to
cleanup after an error: the initial error is reported.
- Improved configure's detection of IPv6 for solaris and cygwin.
- The AIX sysacls routines will now return ENOSYS if ENOTSUP is missing.
- Made our (only used if missing) getaddrinfo() routine use inet_pton()
(which we also provide) instead of inet_aton().
- The exit-related debug messages now mention the program's role so it is
clear who output what message.
DEVELOPER RELATED:
- The Makefile will not halt for just a timestamp change on the Makefile
or the configure files, only for actual changes in content.
- Got rid of type-punned compiler warnings output by newer gcc versions.
- Changed some commands in the testsuite's xattrs.test that called "rsync"
instead of "$RSYNC".
- The Makefile now ensures that proto.h will be rebuilt if config.h changes.
- Enhanced the release scripts to be able to handle a branch release and
to do even more consistency checks on the files.
- The testsuite no longer uses "id -u", so it works better on solaris.

190
OLDNEWS
View File

@@ -1,3 +1,190 @@
NEWS for rsync 3.0.6 (8 May 2009)
Protocol: 30 (unchanged)
Changes since 3.0.5:
BUG FIXES:
- Fixed a --read-batch hang when rsync is reading a batch file that was
created from an incremental-recursion transfer.
- Fixed the daemon's socket code to handle the simultaneous arrival of
multiple connections.
- Fix --safe-links/--copy-unsafe-links to properly handle symlinks that
have consecutive slashes in the value.
- Fixed the parsing of an [IPv6_LITERAL_ADDR] when a USER@ is prefixed.
- The sender now skips a (bogus) symlink that has a 0-length value, which
avoids a transfer error in the receiver.
- Fixed a case where the sender could die with a tag-0 error if there was
an I/O during the sending of the file list.
- Fixed the rrsync script to avoid a server-side problem when -e is at the
start of the short options.
- Fixed a problem where a vanished directory could turn into an exit code
23 instead of the proper exit code 24.
- Fixed the --iconv conversion of symlinks when doing a local copy.
- Fixed a problem where --one-file-system was not stopping deletions on the
receiving side when a mount-point directory did not match a directory in
the transfer.
- Fixed the dropping of an ACL mask when no named ACL values were present.
- Fixed an ACL/xattr corruption issue where the --backup option could cause
rsync to associate the wrong ACL/xattr information with received files.
- Fixed the use of --xattrs with --only-write-batch.
- Fixed the use of --dry-run with --read-batch.
- Fixed configure's erroneous use of target.
- Fixed configure's --disable-debug option.
- Fixed a run-time issue for systems that can't find iconv_open() by adding
the --disable-iconv-open configure option.
- Complain and die if the user tries to combine --remove-source-files (or
the deprecated --remove-sent-files) with --read-batch.
- Fixed an failure transferring special files from Solaris to Linux.
NEWS for rsync 3.0.5 (28 Dec 2008)
Protocol: 30 (unchanged)
Changes since 3.0.4:
BUG FIXES:
- Initialize xattr data in a couple spots in the hlink code, which avoids a
crash when the xattr pointer's memory happens to start out non-zero.
Also fixed the itemizing of an alt-dest file's xattrs when hard-linking.
- Don't send a bogus "-" option to an older server if there were no short
options specified.
- Fixed skipping of unneeded updates in a batch file when incremental
recursion is active. Added a test for this. Made batch-mode handle
"redo" files properly (and without hanging).
- Fix the %P logfile escape when the daemon logs from inside a chroot.
- Fixed the use of -s (--protect-args) when used with a remote source or
destination that had an empty path (e.g. "host:"). Also fixed a problem
when -s was used when accessing a daemon via a remote-shell.
- Fixed the use of a dot-dir path (e.g. foo/./bar) inside a --files-from
file when the root of the transfer isn't the current directory.
- Fixed a bug with "-K --delete" removing symlinks to directories when
incremental recursion is active.
- Fixed a hard to trigger hang when using --remove-source-files.
- Got rid of an annoying delay when accessing a daemon via a remote-shell.
- Properly ignore (superfluous) source args on a --read-batch command.
- Improved the manpage's description of the '*' wildcard to remove the
confusing "non-empty" qualifier.
- Fixed reverse lookups in the compatibility-library version of
getnameinfo().
- Fixed a bug when using --sparse on a sparse file that has over 2GB of
consecutive sparse data.
- Avoid a hang when using at least 3 --verbose options on a transfer with a
client sender (which includes local copying).
- Fixed a problem with --delete-delay reporting an error when it was ready
to remove a directory that was now gone.
- Got rid of a bunch of "warn_unused_result" compiler warnings.
- If an ftruncate() on a received file fails, it now causes a partial-
transfer warning.
- Allow a path with a leading "//" to be preserved (CYGWIN only).
ENHANCEMENTS:
- Made the support/atomic-rsync script able to perform a fully atomic
update of the copied hierarchy when the destination is setup using a
particular symlink idiom.
NEWS for rsync 3.0.4 (6 Sep 2008)
Protocol: 30 (unchanged)
Changes since 3.0.3:
BUG FIXES:
- Fixed a bug in the hard-linking code where it would sometimes try to
allocate 0 bytes of memory (which fails on some OSes, such as AIX).
- Fixed the hard-linking of files from a device that has a device number
of 0 (which seems to be a common device number on NetBSD).
- Fixed the handling of a --partial-dir that cannot be created. This
particularly impacts the --delay-updates option (since the files cannot
be delayed without a partial-dir), and was potentially destructive if
the --remove-source-files was also specified.
- Fixed a couple issues in the --fake-super handling of xattrs when the
destination files have root-level attributes (e.g. selinux values) that
a non-root copy can't affect.
- Improved the keep-alive check in the generator to fire consistently in
incremental-recursion mode when --timeout is enabled.
- The --iconv option now converts the content of a symlink too, instead
of leaving it in the wrong character-set (requires 3.0.4 on both sides
of the transfer).
- When using --iconv, if a filename fails to convert on the receiving side,
this no longer makes deletions in the root-dir of the transfer fail
silently (the user now gets a warning about deletions being disabled
due to IO error as long as --ignore-errors was not specified).
- When using --iconv, if a server-side receiver can't convert a filename,
the error message sent back to the client no longer mangles the name
with the wrong charset conversion.
- Fixed a potential alignment issue in the IRIX ACL code when allocating
the initial "struct acl" object. Also, cast mallocs to avoid warnings.
- Changed some errors that were going to stdout to go to stderr.
- Made human_num() and human_dnum() able to output a negative number
(rather than outputting a cryptic string of punctuation).
ENHANCEMENTS:
- Rsync will avoid sending an -e option to the server if an older protocol
is requested (and thus the option would not be useful). This lets the
user specify the --protocol=29 option to access an overly-restrictive
server that is rejecting the protocol-30 use of -e to the server.
- Improved the message output for an RERR_PARTIAL exit.
DEVELOPER RELATED:
- The Makefile will not halt for just a timestamp change on the Makefile
or the configure files, only for actual changes in content.
- Changed some commands in the testsuite's xattrs.test that called "rsync"
instead of "$RSYNC".
- Enhanced the release scripts to be able to handle a branch release and
to do even more consistency checks on the files.
NEWS for rsync 3.0.3 (29 Jun 2008)
Protocol: 30 (unchanged)
Changes since 3.0.2:
@@ -2841,6 +3028,9 @@ Changes since 2.4.6:
Partial Protocol History
RELEASE DATE VER. DATE OF COMMIT* PROTOCOL
31 Dec 2009 3.0.7 30
08 May 2009 3.0.6 30
28 Dec 2008 3.0.5 30
06 Sep 2008 3.0.4 30
29 Jun 2008 3.0.3 30
08 Apr 2008 3.0.2 30

View File

@@ -2,7 +2,7 @@
* Routines to authenticate access to a daemon (hosts allow/deny).
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2004-2008 Wayne Davison
* Copyright (C) 2004-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

52
acls.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2006-2008 Wayne Davison
* Copyright (C) 2006-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -88,6 +88,9 @@ static const rsync_acl empty_rsync_acl = {
static item_list access_acl_list = EMPTY_ITEM_LIST;
static item_list default_acl_list = EMPTY_ITEM_LIST;
static size_t prior_access_count = (size_t)-1;
static size_t prior_default_count = (size_t)-1;
/* === Calculations on ACL types === */
static const char *str_acl_type(SMB_ACL_TYPE_T type)
@@ -137,7 +140,8 @@ static void rsync_acl_strip_perms(rsync_acl *racl)
else {
if (racl->group_obj == racl->mask_obj)
racl->group_obj = NO_ENTRY;
racl->mask_obj = NO_ENTRY;
if (racl->names.count != 0)
racl->mask_obj = NO_ENTRY;
}
racl->other_obj = NO_ENTRY;
}
@@ -749,14 +753,7 @@ static int recv_rsync_acl(item_list *racl_list, SMB_ACL_TYPE_T type, int f)
/* If we received a superfluous mask, throw it away. */
duo_item->racl.mask_obj = NO_ENTRY;
#else
if (!duo_item->racl.names.count) {
/* If we received a superfluous mask, throw it away. */
if (duo_item->racl.mask_obj != NO_ENTRY) {
/* Mask off the group perms with it first. */
duo_item->racl.group_obj &= duo_item->racl.mask_obj | NO_ENTRY;
duo_item->racl.mask_obj = NO_ENTRY;
}
} else if (duo_item->racl.mask_obj == NO_ENTRY) /* Must be non-empty with lists. */
if (duo_item->racl.names.count && duo_item->racl.mask_obj == NO_ENTRY) /* Must be non-empty with lists. */
duo_item->racl.mask_obj = (computed_mask_bits | duo_item->racl.group_obj) & ~NO_ENTRY;
#endif
@@ -794,17 +791,50 @@ static int cache_rsync_acl(rsync_acl *racl, SMB_ACL_TYPE_T type, item_list *racl
/* Turn the ACL data in stat_x into cached ACL data, setting the index
* values in the file struct. */
void cache_acl(struct file_struct *file, stat_x *sxp)
void cache_tmp_acl(struct file_struct *file, stat_x *sxp)
{
if (prior_access_count == (size_t)-1)
prior_access_count = access_acl_list.count;
F_ACL(file) = cache_rsync_acl(sxp->acc_acl,
SMB_ACL_TYPE_ACCESS, &access_acl_list);
if (S_ISDIR(sxp->st.st_mode)) {
if (prior_default_count == (size_t)-1)
prior_default_count = default_acl_list.count;
F_DIR_DEFACL(file) = cache_rsync_acl(sxp->def_acl,
SMB_ACL_TYPE_DEFAULT, &default_acl_list);
}
}
static void uncache_duo_acls(item_list *duo_list, size_t start)
{
acl_duo *duo_item = duo_list->items;
acl_duo *duo_start = duo_item + start;
duo_item += duo_list->count;
duo_list->count = start;
while (duo_item-- > duo_start) {
rsync_acl_free(&duo_item->racl);
if (duo_item->sacl)
sys_acl_free_acl(duo_item->sacl);
}
}
void uncache_tmp_acls(void)
{
if (prior_access_count != (size_t)-1) {
uncache_duo_acls(&access_acl_list, prior_access_count);
prior_access_count = (size_t)-1;
}
if (prior_default_count != (size_t)-1) {
uncache_duo_acls(&default_acl_list, prior_default_count);
prior_default_count = (size_t)-1;
}
}
#ifndef HAVE_OSX_ACLS
static mode_t change_sacl_perms(SMB_ACL_T sacl, rsync_acl *racl, mode_t old_mode, mode_t mode)
{

View File

@@ -2,7 +2,7 @@
* Support rsync daemon authentication.
*
* Copyright (C) 1998-2000 Andrew Tridgell
* Copyright (C) 2002-2008 Wayne Davison
* Copyright (C) 2002-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -2,7 +2,7 @@
* Backup handling code.
*
* Copyright (C) 1999 Andrew Tridgell
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -148,19 +148,25 @@ int make_bak_dir(const char *fullpath)
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(rel, &sx);
cache_acl(file, &sx);
cache_tmp_acl(file, &sx);
free_acl(&sx);
}
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
get_xattr(rel, &sx);
cache_xattr(file, &sx);
cache_tmp_xattr(file, &sx);
free_xattr(&sx);
}
#endif
set_file_attrs(fbuf, file, NULL, NULL, 0);
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
#endif
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
}
}
*p = '/';
@@ -223,20 +229,26 @@ static int keep_backup(const char *fname)
if (!(buf = get_backup_name(fname))) {
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
#endif
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
return 0;
}
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(fname, &sx);
cache_acl(file, &sx);
cache_tmp_acl(file, &sx);
free_acl(&sx);
}
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
get_xattr(fname, &sx);
cache_xattr(file, &sx);
cache_tmp_xattr(file, &sx);
free_xattr(&sx);
}
#endif
@@ -295,7 +307,7 @@ static int keep_backup(const char *fname)
#ifdef SUPPORT_LINKS
if (!kept && preserve_links && S_ISLNK(file->mode)) {
const char *sl = F_SYMLINK(file);
if (safe_symlinks && unsafe_symlink(sl, buf)) {
if (safe_symlinks && unsafe_symlink(sl, fname)) {
if (verbose) {
rprintf(FINFO, "ignoring unsafe symlink %s -> %s\n",
full_fname(buf), sl);
@@ -326,6 +338,12 @@ static int keep_backup(const char *fname)
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
fname);
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
#endif
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
return 1;
}
@@ -344,6 +362,12 @@ static int keep_backup(const char *fname)
set_file_attrs(buf, file, NULL, fname, 0);
preserve_xattrs = save_preserve_xattrs;
unmake_file(file);
#ifdef SUPPORT_ACLS
uncache_tmp_acls();
#endif
#ifdef SUPPORT_XATTRS
uncache_tmp_xattrs();
#endif
if (verbose > 1) {
rprintf(FINFO, "backed up %s to %s\n",

59
batch.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1999 Weiss
* Copyright (C) 2004 Chris Shoemaker
* Copyright (C) 2004-2008 Wayne Davison
* Copyright (C) 2004-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -156,27 +156,37 @@ void check_batch_flags(void)
append_mode = 2;
}
static void write_arg(int fd, char *arg)
static int write_arg(int fd, char *arg)
{
char *x, *s;
int len, ret = 0;
if (*arg == '-' && (x = strchr(arg, '=')) != NULL) {
write(fd, arg, x - arg + 1);
if (write(fd, arg, x - arg + 1) != x - arg + 1)
ret = -1;
arg += x - arg + 1;
}
if (strpbrk(arg, " \"'&;|[]()$#!*?^\\") != NULL) {
write(fd, "'", 1);
if (write(fd, "'", 1) != 1)
ret = -1;
for (s = arg; (x = strchr(s, '\'')) != NULL; s = x + 1) {
write(fd, s, x - s + 1);
write(fd, "'", 1);
if (write(fd, s, x - s + 1) != x - s + 1
|| write(fd, "'", 1) != 1)
ret = -1;
}
write(fd, s, strlen(s));
write(fd, "'", 1);
return;
len = strlen(s);
if (write(fd, s, len) != len
|| write(fd, "'", 1) != 1)
ret = -1;
return ret;
}
write(fd, arg, strlen(arg));
len = strlen(arg);
if (write(fd, arg, len) != len)
ret = -1;
return ret;
}
static void write_filter_rules(int fd)
@@ -205,7 +215,7 @@ static void write_filter_rules(int fd)
* (hopefully) work. */
void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
{
int fd, i, len;
int fd, i, len, err = 0;
char *p, filename[MAXPATHLEN];
stringjoin(filename, sizeof filename,
@@ -219,7 +229,8 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
}
/* Write argvs info to BATCH.sh file */
write_arg(fd, argv[0]);
if (write_arg(fd, argv[0]) < 0)
err = 1;
if (filter_list.head) {
if (protocol_version >= 29)
write_sbuf(fd, " --filter=._-");
@@ -240,25 +251,31 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
i++;
continue;
}
write(fd, " ", 1);
if (write(fd, " ", 1) != 1)
err = 1;
if (strncmp(p, "--write-batch", len = 13) == 0
|| strncmp(p, "--only-write-batch", len = 18) == 0) {
write(fd, "--read-batch", 12);
if (write(fd, "--read-batch", 12) != 12)
err = 1;
if (p[len] == '=') {
write(fd, "=", 1);
write_arg(fd, p + len + 1);
if (write(fd, "=", 1) != 1
|| write_arg(fd, p + len + 1) < 0)
err = 1;
}
} else
write_arg(fd, p);
} else {
if (write_arg(fd, p) < 0)
err = 1;
}
}
if (!(p = check_for_hostspec(argv[argc - 1], &p, &i)))
p = argv[argc - 1];
write(fd, " ${1:-", 6);
write_arg(fd, p);
if (write(fd, " ${1:-", 6) != 6
|| write_arg(fd, p) < 0)
err = 1;
write_byte(fd, '}');
if (filter_list.head)
write_filter_rules(fd);
if (write(fd, "\n", 1) != 1 || close(fd) < 0) {
if (write(fd, "\n", 1) != 1 || close(fd) < 0 || err) {
rsyserr(FERROR, errno, "Batch file %s write error",
filename);
exit_cleanup(RERR_FILEIO);

View File

@@ -19,6 +19,7 @@
*/
#undef CAREFUL_ALIGNMENT
#undef AVOID_BYTEORDER_INLINE
/* We know that the x86 can handle misalignment and has the same
* byte order (LSB-first) as the 32-bit numbers we transmit. */
@@ -32,21 +33,68 @@
#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
#define UVAL(buf,pos) ((uint32)CVAL(buf,pos))
#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
#if CAREFUL_ALIGNMENT
#define PVAL(buf,pos) (UVAL(buf,pos)|UVAL(buf,(pos)+1)<<8)
#define IVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+2)<<16)
#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
#else
/* this handles things for architectures like the 386 that can handle
alignment errors */
/*
WARNING: This section is dependent on the length of int32
being correct. set CAREFUL_ALIGNMENT if it is not.
*/
#define IVALu(buf,pos) IVAL(buf,pos)
#define SIVALu(buf,pos,val) SIVAL(buf,pos,val)
#else /* !CAREFUL_ALIGNMENT */
/* This handles things for architectures like the 386 that can handle alignment errors.
* WARNING: This section is dependent on the length of an int32 (and thus a uint32)
* being correct (4 bytes)! Set CAREFUL_ALIGNMENT if it is not. */
# ifdef AVOID_BYTEORDER_INLINE
#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
#endif
#define IVALu(buf,pos) IVAL(buf,pos)
#define SIVALu(buf,pos,val) SIVAL(buf,pos,val)
# else /* !AVOID_BYTEORDER_INLINE */
static inline uint32
IVALu(const uchar *buf, int pos)
{
union {
const uchar *b;
const uint32 *num;
} u;
u.b = buf + pos;
return *u.num;
}
static inline void
SIVALu(uchar *buf, int pos, uint32 val)
{
union {
uchar *b;
uint32 *num;
} u;
u.b = buf + pos;
*u.num = val;
}
static inline uint32
IVAL(const char *buf, int pos)
{
return IVALu((uchar*)buf, pos);
}
static inline void
SIVAL(char *buf, int pos, uint32 val)
{
SIVALu((uchar*)buf, pos, val);
}
# endif /* !AVOID_BYTEORDER_INLINE */
#endif /* !CAREFUL_ALIGNMENT */

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2004-2008 Wayne Davison
* Copyright (C) 2004-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -58,7 +58,7 @@ void get_checksum2(char *buf, int32 len, char *sum)
md5_begin(&m);
md5_update(&m, (uchar *)buf, len);
if (checksum_seed) {
SIVAL(seedbuf, 0, checksum_seed);
SIVALu(seedbuf, 0, checksum_seed);
md5_update(&m, seedbuf, 4);
}
md5_result(&m, (uchar *)sum);

View File

@@ -2,7 +2,7 @@
* Implement the core of the --chmod option.
*
* Copyright (C) 2002 Scott Howard
* Copyright (C) 2005-2008 Wayne Davison
* Copyright (C) 2005-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
extern int am_server;
extern int am_daemon;
extern int am_receiver;
extern int io_error;
extern int keep_partial;
extern int got_xfer_error;
@@ -94,17 +95,21 @@ pid_t cleanup_child_pid = -1;
NORETURN void _exit_cleanup(int code, const char *file, int line)
{
static int cleanup_step = 0;
static int exit_code = 0;
static int exit_code = 0, exit_line = 0;
static const char *exit_file = NULL;
static int unmodified_code = 0;
SIGACTION(SIGUSR1, SIG_IGN);
SIGACTION(SIGUSR2, SIG_IGN);
if (exit_code) /* Preserve first error code when recursing. */
if (exit_code) { /* Preserve first exit info when recursing. */
code = exit_code;
file = exit_file;
line = exit_line;
}
/* If this is the exit at the end of the run, the server side
* should not attempt to output a message (see log.c). */
* should not attempt to output a message (see log_exit()). */
if (am_server && code == 0)
am_server = 2;
@@ -114,11 +119,13 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
#include "case_N.h" /* case 0: cleanup_step++; */
exit_code = unmodified_code = code;
exit_file = file;
exit_line = line;
if (verbose > 3) {
rprintf(FINFO,
"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
code, file, line);
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
who_am_i(), code, file, line);
}
/* FALLTHROUGH */
@@ -154,7 +161,8 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
/* FALLTHROUGH */
#include "case_N.h"
io_flush(FULL_FLUSH);
if (!code || am_server || am_receiver)
io_flush(FULL_FLUSH);
/* FALLTHROUGH */
#include "case_N.h"
@@ -186,9 +194,9 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
if (verbose > 2) {
rprintf(FINFO,
"_exit_cleanup(code=%d, file=%s, line=%d): "
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): "
"about to call exit(%d)\n",
unmodified_code, file, line, code);
who_am_i(), unmodified_code, file, line, code);
}
/* FALLTHROUGH */

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2002-2008 Wayne Davison
* Copyright (C) 2002-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -108,6 +108,9 @@ char *client_name(int fd)
struct addrinfo hint, *answer;
int err;
if (strcmp(addr, "0.0.0.0") == 0)
return name_buf;
memset(&hint, 0, sizeof hint);
#ifdef AI_NUMERICHOST

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2001-2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2002-2008 Wayne Davison
* Copyright (C) 2002-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -50,14 +50,12 @@ extern int logfile_format_has_i;
extern int logfile_format_has_o_or_i;
extern mode_t orig_umask;
extern char *bind_address;
extern char *sockopts;
extern char *config_file;
extern char *logfile_format;
extern char *files_from;
extern char *tmpdir;
extern struct chmod_mode_struct *chmod_modes;
extern struct filter_list_struct daemon_filter_list;
extern char curr_dir[];
#ifdef ICONV_OPTION
extern char *iconv_opt;
extern iconv_t ic_send, ic_recv;
@@ -75,6 +73,8 @@ struct chmod_mode_struct *daemon_chmod_modes;
char *module_dir = NULL;
unsigned int module_dirlen = 0;
char *full_module_path;
static int rl_nulls = 0;
#ifdef HAVE_SIGACTION
@@ -395,10 +395,20 @@ static int read_arg_from_pipe(int fd, char *buf, int limit)
return bp - buf;
}
static int path_failure(int f_out, const char *dir, BOOL was_chdir)
{
if (was_chdir)
rsyserr(FLOG, errno, "chdir %s failed\n", dir);
else
rprintf(FLOG, "normalize_path(%s) failed\n", dir);
io_printf(f_out, "@ERROR: chdir failed\n");
return -1;
}
static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
{
int argc;
char **argv, **orig_argv, **orig_early_argv, *chroot_path = NULL;
char **argv, **orig_argv, **orig_early_argv, *module_chdir;
char line[BIGPATHBUFLEN];
uid_t uid = (uid_t)-2; /* canonically "nobody" */
gid_t gid = (gid_t)-2;
@@ -501,28 +511,28 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
module_dir = lp_path(i);
if (use_chroot) {
if ((p = strstr(module_dir, "/./")) != NULL) {
*p = '\0';
p += 2;
} else if ((p = strdup("/")) == NULL) /* MEMORY LEAK */
out_of_memory("rsync_module");
*p = '\0'; /* Temporary... */
if (!(module_chdir = normalize_path(module_dir, True, NULL)))
return path_failure(f_out, module_dir, False);
*p = '/';
if (!(p = normalize_path(p + 2, True, &module_dirlen)))
return path_failure(f_out, strstr(module_dir, "/./"), False);
if (!(full_module_path = normalize_path(module_dir, False, NULL)))
full_module_path = module_dir;
module_dir = p;
} else {
if (!(module_chdir = normalize_path(module_dir, False, NULL)))
return path_failure(f_out, module_dir, False);
full_module_path = module_chdir;
module_dir = "/";
module_dirlen = 1;
}
} else {
if (!(module_chdir = normalize_path(module_dir, False, &module_dirlen)))
return path_failure(f_out, module_dir, False);
full_module_path = module_dir = module_chdir;
}
/* We do a change_dir() that doesn't actually call chdir()
* just to make a relative path absolute. */
strlcpy(line, curr_dir, sizeof line);
if (!change_dir(module_dir, CD_SKIP_CHDIR))
goto chdir_failed;
if (strcmp(curr_dir, module_dir) != 0
&& (module_dir = strdup(curr_dir)) == NULL)
out_of_memory("rsync_module");
change_dir(line, CD_SKIP_CHDIR); /* Restore curr_dir. */
if (use_chroot) {
chroot_path = module_dir;
module_dir = p; /* p is "/" or our inside-chroot path */
}
module_dirlen = clean_fname(module_dir, CFN_COLLAPSE_DOT_DOT_DIRS | CFN_DROP_TRAILING_DOT_DIR);
if (module_dirlen == 1) {
module_dirlen = 0;
set_filter_dir("/", 1);
@@ -557,16 +567,8 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
char *modname, *modpath, *hostaddr, *hostname, *username;
int status;
if (!use_chroot)
p = module_dir;
else if (module_dirlen) {
pathjoin(line, sizeof line, chroot_path, module_dir+1);
p = line;
} else
p = chroot_path;
if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
|| asprintf(&modpath, "RSYNC_MODULE_PATH=%s", p) < 0
|| asprintf(&modpath, "RSYNC_MODULE_PATH=%s", full_module_path) < 0
|| asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0
|| asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0
|| asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0)
@@ -600,7 +602,8 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
status = -1;
if (asprintf(&p, "RSYNC_EXIT_STATUS=%d", status) > 0)
putenv(p);
system(lp_postxfer_exec(i));
if (system(lp_postxfer_exec(i)) < 0)
status = -1;
_exit(status);
}
}
@@ -666,25 +669,19 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
* a warning, unless a "require chroot" flag is set,
* in which case we fail.
*/
if (chroot(chroot_path)) {
rsyserr(FLOG, errno, "chroot %s failed", chroot_path);
if (chroot(module_chdir)) {
rsyserr(FLOG, errno, "chroot %s failed", module_chdir);
io_printf(f_out, "@ERROR: chroot failed\n");
return -1;
}
if (!change_dir(module_dir, CD_NORMAL))
goto chdir_failed;
if (module_dirlen)
sanitize_paths = 1;
} else {
if (!change_dir(module_dir, CD_NORMAL)) {
chdir_failed:
rsyserr(FLOG, errno, "chdir %s failed\n", module_dir);
io_printf(f_out, "@ERROR: chdir failed\n");
return -1;
}
sanitize_paths = 1;
module_chdir = module_dir;
}
if (!change_dir(module_chdir, CD_NORMAL))
return path_failure(f_out, module_chdir, True);
if (module_dirlen || !use_chroot)
sanitize_paths = 1;
if ((munge_symlinks = lp_munge_symlinks(i)) < 0)
munge_symlinks = !use_chroot || module_dirlen;
if (munge_symlinks) {
@@ -723,7 +720,11 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
}
#endif
if (setuid(uid)) {
if (setuid(uid) < 0
#ifdef HAVE_SETEUID
|| seteuid(uid) < 0
#endif
) {
rsyserr(FLOG, errno, "setuid %d failed", (int)uid);
io_printf(f_out, "@ERROR: setuid failed\n");
return -1;
@@ -857,7 +858,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
&& (use_chroot ? lp_numeric_ids(i) != False : lp_numeric_ids(i) == True))
numeric_ids = -1; /* Set --numeric-ids w/o breaking protocol. */
if (lp_timeout(i) && lp_timeout(i) > io_timeout)
if (lp_timeout(i) && (!io_timeout || lp_timeout(i) < io_timeout))
set_io_timeout(lp_timeout(i));
/* If we have some incoming/outgoing chmod changes, append them to
@@ -972,20 +973,23 @@ static void create_pid_file(void)
char *pid_file = lp_pid_file();
char pidbuf[16];
pid_t pid = getpid();
int fd;
int fd, len;
if (!pid_file || !*pid_file)
return;
cleanup_set_pid(pid);
if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666 & ~orig_umask)) == -1) {
failure:
cleanup_set_pid(0);
fprintf(stderr, "failed to create pid file %s: %s\n", pid_file, strerror(errno));
rsyserr(FLOG, errno, "failed to create pid file %s", pid_file);
exit_cleanup(RERR_FILEIO);
}
snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
write(fd, pidbuf, strlen(pidbuf));
len = strlen(pidbuf);
if (write(fd, pidbuf, len) != len)
goto failure;
close(fd);
}

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) Andrew Tridgell 1996
* Copyright (C) Paul Mackerras 1996
* Copyright (C) 2004-2008 Wayne Davison
* Copyright (C) 2004-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
int remote_protocol = 0;
int file_extra_cnt = 0; /* count of file-list extras that everyone gets */
int inc_recurse = 0;
int use_safe_inc_flist = 0;
extern int verbose;
extern int am_server;
@@ -73,6 +74,7 @@ int filesfrom_convert = 0;
#define CF_INC_RECURSE (1<<0)
#define CF_SYMLINK_TIMES (1<<1)
#define CF_SYMLINK_ICONV (1<<2)
#define CF_SAFE_FLIST (1<<3)
static const char *client_info;
@@ -255,6 +257,8 @@ void setup_protocol(int f_out,int f_in)
#ifdef ICONV_OPTION
compat_flags |= CF_SYMLINK_ICONV;
#endif
if (local_server || strchr(client_info, 'f') != NULL)
compat_flags |= CF_SAFE_FLIST;
write_byte(f_out, compat_flags);
} else
compat_flags = read_byte(f_in);
@@ -271,7 +275,7 @@ void setup_protocol(int f_out,int f_in)
#endif
#ifdef ICONV_OPTION
sender_symlink_iconv = iconv_opt && (am_server
? strchr(client_info, 's') != NULL
? local_server || strchr(client_info, 's') != NULL
: !!(compat_flags & CF_SYMLINK_ICONV));
#endif
if (inc_recurse && !allow_inc_recurse) {
@@ -281,6 +285,7 @@ void setup_protocol(int f_out,int f_in)
read_batch ? "batch file" : "connection");
exit_cleanup(RERR_SYNTAX);
}
use_safe_inc_flist = !!(compat_flags & CF_SAFE_FLIST);
need_messages_from_generator = 1;
#if defined HAVE_LUTIMES && defined HAVE_UTIMES
} else if (!am_sender) {

View File

@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ(2.59)
RSYNC_VERSION=3.0.4
RSYNC_VERSION=3.0.7
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -13,7 +13,26 @@ AC_DEFINE_UNQUOTED(RSYNC_VERSION, ["$RSYNC_VERSION"], [rsync release version])
LDFLAGS=${LDFLAGS-""}
AC_CANONICAL_TARGET([])
AC_CANONICAL_HOST
# 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([--disable-debug],
[disable debugging symbols and features]))
if test x"$enable_debug" = x"no"; then
AC_MSG_RESULT(no)
ac_cv_prog_cc_g=no
else
AC_MSG_RESULT([yes])
dnl AC_DEFINE(DEBUG, 1, [Define to turn on debugging code that may slow normal operation])
# leave ac_cv_prog_cc_g alone; AC_PROG_CC will try to include -g if it can
fi
dnl Checks for programs.
AC_PROG_CC
@@ -30,27 +49,6 @@ if test x"$ac_cv_prog_cc_stdc" = x"no"; then
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
fi
# 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([--disable-debug],
[disable debugging symbols and features]))
if test x"$enable_debug" = x"no"; then
AC_MSG_RESULT(no)
CFLAGS=${CFLAGS-"-O"}
else
AC_MSG_RESULT([yes])
# leave CFLAGS alone; AC_PROG_CC will try to include -g if it can
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]))
@@ -198,7 +196,7 @@ AC_ARG_ENABLE(ipv6,
[don't even try to use IPv6]))
if test x"$enable_ipv6" != x"no"; then
AC_MSG_CHECKING([ipv6 stack type])
for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta cygwin; do
case $i in
inria)
# http://www.kame.net/
@@ -242,6 +240,16 @@ AC_DEFINE(INET6, 1, [true if you have IPv6])])
CFLAGS="-I/usr/inet6/include $CFLAGS"
fi
;;
solaris)
# http://www.sun.com
AC_EGREP_CPP(yes, [
#include <netinet/ip6.h>
#ifdef __sun
yes
#endif],
[ipv6type=$i;
AC_DEFINE(INET6, 1, [true if you have IPv6])])
;;
toshiba)
AC_EGREP_CPP(yes, [
#include <sys/param.h>
@@ -275,6 +283,15 @@ yes
ipv6libdir=/usr/local/v6/lib;
AC_DEFINE(INET6, 1, [true if you have IPv6])])
;;
cygwin)
AC_EGREP_CPP(yes, [
#include <netinet/in.h>
#ifdef _CYGWIN_IN6_H
yes
#endif],
[ipv6type=$i;
AC_DEFINE(INET6, 1, [true if you have IPv6])])
;;
esac
if test "$ipv6type" != "unknown"; then
break
@@ -553,7 +570,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
memmove lchown vsnprintf snprintf vasprintf asprintf setsid strpbrk \
strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
strerror putenv iconv_open locale_charset nl_langinfo getxattr \
seteuid strerror putenv iconv_open locale_charset nl_langinfo getxattr \
extattr_get_link sigaction sigprocmask setattrlist)
dnl cygwin iconv.h defines iconv_open as libiconv_open
@@ -566,10 +583,19 @@ if test $ac_cv_func_getpgrp = yes; then
AC_FUNC_GETPGRP
fi
AC_ARG_ENABLE(iconv-open,
AC_HELP_STRING([--disable-iconv-open],
[disable all use of iconv_open() function]),
[], [enable_iconv_open=$ac_cv_func_iconv_open])
if test x"$enable_iconv_open" != x"no"; then
AC_DEFINE(USE_ICONV_OPEN, 1, [Define to 1 if you want rsync to make use of iconv_open()])
fi
AC_ARG_ENABLE(iconv,
AC_HELP_STRING([--disable-iconv],
[disable rsync's --iconv option]),
[], [enable_iconv=$ac_cv_func_iconv_open])
[], [enable_iconv=$enable_iconv_open])
AH_TEMPLATE([ICONV_OPTION],
[Define if you want the --iconv option. Specifing a value will set the
default iconv setting (a NULL means no --iconv processing by default).])
@@ -762,7 +788,7 @@ rsync_cv_HAVE_SECURE_MKSTEMP=yes,
rsync_cv_HAVE_SECURE_MKSTEMP=no,
rsync_cv_HAVE_SECURE_MKSTEMP=cross)])
if test x"$rsync_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then
case $target_os in
case $host_os in
hpux*)
dnl HP-UX has a broken mkstemp() implementation they refuse to fix,
dnl so we noisily skip using it. See HP change request JAGaf34426
@@ -962,7 +988,7 @@ if test x"$enable_acl_support" = x"no" -o x"$enable_xattr_support" = x"no" -o x"
AC_MSG_CHECKING([whether $CC supports -Wno-unused-parameter])
OLD_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wno-unused-parameter"
AC_COMPILE_IFELSE([ ], [rsync_warn_flag=yes], [rsync_warn_flag=no])
AC_TRY_LINK([#include <stdio.h>], [printf("hello\n");], [rsync_warn_flag=yes], [rsync_warn_flag=no])
AC_MSG_RESULT([$rsync_warn_flag])
if test x"$rsync_warn_flag" = x"no"; then
CFLAGS="$OLD_CFLAGS"

View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1121,6 +1121,8 @@ char *get_rule_prefix(int match_flags, const char *pat, int for_xfer,
else
legal_len = 0;
if (match_flags & MATCHFLG_ABS_PATH)
*op++ = '/';
if (match_flags & MATCHFLG_NEGATE)
*op++ = '!';
if (match_flags & MATCHFLG_CVS_IGNORE)

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2004-2008 Wayne Davison
* Copyright (C) 2004-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@
extern int sparse_files;
static char last_byte;
static size_t sparse_seek = 0;
static OFF_T sparse_seek = 0;
int sparse_end(int f)
{
@@ -48,9 +48,9 @@ int sparse_end(int f)
}
static int write_sparse(int f, char *buf, size_t len)
static int write_sparse(int f, char *buf, int len)
{
size_t l1 = 0, l2 = 0;
int l1 = 0, l2 = 0;
int ret;
for (l1 = 0; l1 < len && buf[l1] == 0; l1++) {}
@@ -108,7 +108,7 @@ int flush_write_file(int f)
* write_file does not allow incomplete writes. It loops internally
* until len bytes are written or errno is set.
*/
int write_file(int f,char *buf,size_t len)
int write_file(int f, char *buf, int len)
{
int ret = 0;
@@ -125,7 +125,7 @@ int write_file(int f,char *buf,size_t len)
if (!wf_writeBuf)
out_of_memory("write_file");
}
r1 = MIN(len, wf_writeBufSize - wf_writeBufCnt);
r1 = (int)MIN((size_t)len, wf_writeBufSize - wf_writeBufCnt);
if (r1) {
memcpy(wf_writeBuf + wf_writeBufCnt, buf, r1);
wf_writeBufCnt += r1;

172
flist.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2002-2008 Wayne Davison
* Copyright (C) 2002-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,7 +43,6 @@ extern int xfer_dirs;
extern int filesfrom_fd;
extern int one_file_system;
extern int copy_dirlinks;
extern int keep_dirlinks;
extern int preserve_uid;
extern int preserve_gid;
extern int preserve_acls;
@@ -52,6 +51,7 @@ extern int preserve_links;
extern int preserve_hard_links;
extern int preserve_devices;
extern int preserve_specials;
extern int delete_during;
extern int uid_ndx;
extern int gid_ndx;
extern int eol_nulls;
@@ -66,6 +66,7 @@ extern int copy_unsafe_links;
extern int protocol_version;
extern int sanitize_paths;
extern int munge_symlinks;
extern int use_safe_inc_flist;
extern int need_unsorted_flist;
extern int sender_symlink_iconv;
extern int unsort_ndx;
@@ -425,8 +426,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
else
mode = file->mode;
if ((preserve_devices && IS_DEVICE(mode))
|| (preserve_specials && IS_SPECIAL(mode))) {
if (preserve_devices && IS_DEVICE(mode)) {
if (protocol_version < 28) {
if (tmp_rdev == rdev)
xflags |= XMIT_SAME_RDEV_pre28;
@@ -441,6 +441,17 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
if (protocol_version < 30 && (uint32)minor(rdev) <= 0xFFu)
xflags |= XMIT_RDEV_MINOR_8_pre30;
}
} else if (preserve_specials && IS_SPECIAL(mode)) {
/* Special files don't need an rdev number, so just make
* the historical transmission of the value efficient. */
if (protocol_version < 28)
xflags |= XMIT_SAME_RDEV_pre28;
else {
rdev = MAKEDEV(major(rdev), 0);
xflags |= XMIT_SAME_RDEV_MAJOR;
if (protocol_version < 30)
xflags |= XMIT_RDEV_MINOR_8_pre30;
}
} else if (protocol_version < 28)
rdev = MAKEDEV(0, 0);
if (!preserve_uid || ((uid_t)F_OWNER(file) == uid && *lastname))
@@ -725,8 +736,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
uid = F_OWNER(first);
if (preserve_gid)
gid = F_GROUP(first);
if ((preserve_devices && IS_DEVICE(mode))
|| (preserve_specials && IS_SPECIAL(mode))) {
if (preserve_devices && IS_DEVICE(mode)) {
uint32 *devp = F_RDEV_P(first);
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
extra_len += DEV_EXTRA_CNT * EXTRA_LEN;
@@ -801,7 +811,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
rdev_minor = read_int(f);
rdev = MAKEDEV(rdev_major, rdev_minor);
}
extra_len += DEV_EXTRA_CNT * EXTRA_LEN;
if (IS_DEVICE(mode))
extra_len += DEV_EXTRA_CNT * EXTRA_LEN;
file_length = 0;
} else if (protocol_version < 28)
rdev = MAKEDEV(0, 0);
@@ -942,8 +953,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist,
}
}
if ((preserve_devices && IS_DEVICE(mode))
|| (preserve_specials && IS_SPECIAL(mode))) {
if (preserve_devices && IS_DEVICE(mode)) {
uint32 *devp = F_RDEV_P(file);
DEV_MAJOR(devp) = major(rdev);
DEV_MINOR(devp) = minor(rdev);
@@ -1257,10 +1267,11 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
#endif
#ifdef HAVE_STRUCT_STAT_ST_RDEV
if (IS_DEVICE(st.st_mode) || IS_SPECIAL(st.st_mode)) {
if (IS_DEVICE(st.st_mode)) {
tmp_rdev = st.st_rdev;
st.st_size = 0;
}
} else if (IS_SPECIAL(st.st_mode))
st.st_size = 0;
#endif
file->flags = flags;
@@ -1294,25 +1305,6 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
else if (!pool)
F_DEPTH(file) = extra_len / EXTRA_LEN;
/* This code is only used by the receiver when it is building
* a list of files for a delete pass. */
if (keep_dirlinks && linkname_len && flist) {
STRUCT_STAT st2;
int save_mode = file->mode;
file->mode = S_IFDIR; /* Find a directory with our name. */
if (flist_find(dir_flist, file) >= 0
&& x_stat(thisname, &st2, NULL) == 0 && S_ISDIR(st2.st_mode)) {
file->modtime = st2.st_mtime;
file->len32 = 0;
file->mode = st2.st_mode;
if (uid_ndx)
F_OWNER(file) = st2.st_uid;
if (gid_ndx)
F_GROUP(file) = st2.st_gid;
} else
file->mode = save_mode;
}
if (basename_len == 0+1) {
if (!pool)
unmake_file(file);
@@ -1361,6 +1353,14 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
if (preserve_links && S_ISLNK(file->mode)) {
symlink_name = F_SYMLINK(file);
symlink_len = strlen(symlink_name);
if (symlink_len == 0) {
io_error |= IOERR_GENERAL;
f_name(file, fbuf);
rprintf(FERROR_XFER,
"skipping symlink with 0-length value: %s\n",
full_fname(fbuf));
return NULL;
}
} else {
symlink_name = NULL;
symlink_len = 0;
@@ -1597,6 +1597,19 @@ static void add_dirs_to_tree(int parent_ndx, struct file_list *from_flist,
DIR_NEXT_SIBLING(dp) = -1;
}
static void interpret_stat_error(const char *fname, int is_dir)
{
if (errno == ENOENT) {
io_error |= IOERR_VANISHED;
rprintf(FWARNING, "%s has vanished: %s\n",
is_dir ? "directory" : "file", full_fname(fname));
} else {
io_error |= IOERR_GENERAL;
rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fname));
}
}
/* This function is normally called by the sender, but the receiving side also
* calls it from get_dirlist() with f set to -1 so that we just construct the
* file list in memory without sending it over the wire. Also, get_dirlist()
@@ -1616,6 +1629,11 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
assert(flist != NULL);
if (!(d = opendir(fbuf))) {
if (errno == ENOENT) {
if (am_sender) /* Can abuse this for vanished error w/ENOENT: */
interpret_stat_error(fbuf, True);
return;
}
io_error |= IOERR_GENERAL;
rsyserr(FERROR_XFER, errno, "opendir %s failed", full_fname(fbuf));
return;
@@ -1768,6 +1786,15 @@ done:
filter_list = save_filter_list;
}
static NORETURN void fatal_unsafe_io_error(void)
{
/* This (sadly) can only happen when pushing data because
* the sender does not know about what kind of delete
* is in effect on the receiving side when pulling. */
rprintf(FERROR_XFER, "FATAL I/O ERROR: dying to avoid a --delete-during issue with a pre-3.0.7 receiver.\n");
exit_cleanup(RERR_UNSUPPORTED);
}
static void send1extra(int f, struct file_struct *file, struct file_list *flist)
{
char fbuf[MAXPATHLEN];
@@ -1787,9 +1814,7 @@ static void send1extra(int f, struct file_struct *file, struct file_list *flist)
if (one_file_system) {
STRUCT_STAT st;
if (link_stat(fbuf, &st, copy_dirlinks) != 0) {
io_error |= IOERR_GENERAL;
rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fbuf));
interpret_stat_error(fbuf, True);
return;
}
filesystem_dev = st.st_dev;
@@ -1824,9 +1849,7 @@ static void send1extra(int f, struct file_struct *file, struct file_list *flist)
if (name_type != NORMAL_NAME) {
STRUCT_STAT st;
if (link_stat(fbuf, &st, 1) != 0) {
io_error |= IOERR_GENERAL;
rsyserr(FERROR_XFER, errno, "link_stat %s failed",
full_fname(fbuf));
interpret_stat_error(fbuf, True);
continue;
}
send_file_name(f, flist, fbuf, &st, FLAG_TOP_DIR | flags, ALL_FILTERS);
@@ -1887,7 +1910,16 @@ void send_extra_file_list(int f, int at_least)
dp = F_DIR_NODE_P(file);
}
write_byte(f, 0);
if (io_error == save_io_error || ignore_errors)
write_byte(f, 0);
else if (use_safe_inc_flist) {
write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
write_varint(f, io_error);
} else {
if (delete_during)
fatal_unsafe_io_error();
write_byte(f, 0);
}
if (need_unsorted_flist) {
if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
@@ -1962,9 +1994,6 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
start_write = stats.total_written;
gettimeofday(&start_tv, NULL);
if (!orig_dir)
orig_dir = strdup(curr_dir);
if (relative_paths && protocol_version >= 30)
implied_dirs = 1; /* We send flagged implied dirs */
@@ -1990,6 +2019,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
use_ff_fd = 1;
}
if (!orig_dir)
orig_dir = strdup(curr_dir);
while (1) {
char fbuf[MAXPATHLEN], *fn, name_type;
@@ -2184,7 +2216,17 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
stats.flist_buildtime = 1;
start_tv = end_tv;
write_byte(f, 0); /* Indicate end of file list */
/* Indicate end of file list */
if (io_error == 0 || ignore_errors)
write_byte(f, 0);
else if (use_safe_inc_flist) {
write_shortint(f, XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST);
write_varint(f, io_error);
} else {
if (delete_during && inc_recurse)
fatal_unsafe_io_error();
write_byte(f, 0);
}
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && protocol_version >= 30 && !inc_recurse)
@@ -2219,10 +2261,12 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
if (numeric_ids <= 0 && !inc_recurse)
send_id_list(f);
set_msg_fd_in(-1);
/* send the io_error flag */
if (protocol_version < 30)
write_int(f, ignore_errors ? 0 : io_error);
else if (io_error && !ignore_errors)
else if (!use_safe_inc_flist && io_error && !ignore_errors)
send_msg_int(MSG_IO_ERROR, io_error);
if (disable_buffering)
@@ -2263,6 +2307,7 @@ struct file_list *recv_file_list(int f)
struct file_list *flist;
int dstart, flags;
int64 start_read;
int save_verbose = verbose;
if (!first_flist)
rprintf(FLOG, "receiving file list\n");
@@ -2289,13 +2334,27 @@ struct file_list *recv_file_list(int f)
dstart = 0;
}
if (am_server && verbose > 2)
verbose = 2;
while ((flags = read_byte(f)) != 0) {
struct file_struct *file;
flist_expand(flist, 1);
if (protocol_version >= 28 && (flags & XMIT_EXTENDED_FLAGS))
flags |= read_byte(f) << 8;
if (flags == (XMIT_EXTENDED_FLAGS|XMIT_IO_ERROR_ENDLIST)) {
int err;
if (!use_safe_inc_flist) {
rprintf(FERROR, "Invalid flist flag: %x\n", flags);
exit_cleanup(RERR_PROTOCOL);
}
err = read_varint(f);
if (!ignore_errors)
io_error |= err;
break;
}
flist_expand(flist, 1);
file = recv_file_entry(flist, flags, f);
if (inc_recurse && S_ISDIR(file->mode)) {
@@ -2313,6 +2372,7 @@ struct file_list *recv_file_list(int f)
}
}
file_total += flist->used;
verbose = save_verbose;
if (verbose > 2)
rprintf(FINFO, "received %d names\n", flist->used);
@@ -2459,6 +2519,28 @@ int flist_find(struct file_list *flist, struct file_struct *f)
return -1;
}
/* Search for an identically-named item in the file list. Differs from
* flist_find in that an item that agrees with "f" in directory-ness is
* preferred but one that does not is still found. */
int flist_find_ignore_dirness(struct file_list *flist, struct file_struct *f)
{
mode_t save_mode;
int ndx;
/* First look for an item that agrees in directory-ness. */
ndx = flist_find(flist, f);
if (ndx >= 0)
return ndx;
/* Temporarily flip f->mode to look for an item of opposite
* directory-ness. */
save_mode = f->mode;
f->mode = S_ISDIR(f->mode) ? S_IFREG : S_IFDIR;
ndx = flist_find(flist, f);
f->mode = save_mode;
return ndx;
}
/*
* Free up any resources a file_struct has allocated
* and clear the file.
@@ -2976,7 +3058,7 @@ struct file_list *get_dirlist(char *dirname, int dlen, int ignore_filter_rules)
recurse = 0;
xfer_dirs = 1;
send_directory(ignore_filter_rules ? -2 : -1, dirlist, dirname, dlen, 0);
send_directory(ignore_filter_rules ? -2 : -1, dirlist, dirname, dlen, FLAG_CONTENT_DIR);
xfer_dirs = save_xfer_dirs;
recurse = save_recurse;
if (do_progress)

View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -521,7 +521,10 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
f_name(fp, NULL));
continue;
}
if (flist_find(cur_flist, fp) < 0) {
/* Here we want to match regardless of file type. Replacement
* of a file with one of another type is handled separately by
* a delete_item call with a DEL_MAKE_ROOM flag. */
if (flist_find_ignore_dirness(cur_flist, fp) < 0) {
int flags = DEL_RECURSE;
if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)
flags |= DEL_NO_UID_WRITE;
@@ -697,7 +700,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
if (iflags & ITEM_XNAME_FOLLOWS)
write_vstring(sock_f_out, xname, strlen(xname));
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && !dry_run
if (preserve_xattrs && do_xfers
&& iflags & (ITEM_REPORT_XATTR|ITEM_TRANSFER)) {
send_xattr_request(NULL, file,
iflags & ITEM_REPORT_XATTR ? sock_f_out : -1);
@@ -1121,8 +1124,8 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
}
switch (type) {
case TYPE_DIR:
break;
case TYPE_SPECIAL:
break;
case TYPE_DEVICE:
devp = F_RDEV_P(file);
if (sxp->st.st_rdev != MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)))
@@ -1610,8 +1613,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|| (preserve_specials && IS_SPECIAL(file->mode))) {
uint32 *devp = F_RDEV_P(file);
dev_t rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
dev_t rdev;
if (IS_DEVICE(file->mode)) {
uint32 *devp = F_RDEV_P(file);
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
} else
rdev = 0;
if (statret == 0) {
int del_for_flag;
if (IS_DEVICE(file->mode)) {
@@ -1625,7 +1632,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
}
if (statret == 0
&& BITS_EQUAL(sx.st.st_mode, file->mode, _S_IFMT)
&& sx.st.st_rdev == rdev) {
&& (IS_SPECIAL(sx.st.st_mode) || sx.st.st_rdev == rdev)) {
/* The device or special file is identical. */
set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
if (itemizing)
@@ -2026,6 +2033,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
static int counter = 0;
struct file_struct *file;
char *fname;
BOOL fix_dir_perms;
int i, start, end;
if (ndx < 0) {
@@ -2046,11 +2054,13 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
rprintf(FINFO, "touch_up_dirs: %s (%d)\n",
NS(fname), i);
}
/* Be sure not to retouch permissions with --fake-super. */
fix_dir_perms = !am_root && !(file->mode & S_IWUSR);
if (!F_IS_ACTIVE(file) || file->flags & FLAG_MISSING_DIR
|| (!need_retouch_dir_times && file->mode & S_IWUSR))
|| !(need_retouch_dir_times || fix_dir_perms))
continue;
fname = f_name(file, NULL);
if (!(file->mode & S_IWUSR))
if (fix_dir_perms)
do_chmod(fname, file->mode);
if (need_retouch_dir_times) {
STRUCT_STAT st;
@@ -2134,10 +2144,9 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
if (first_flist->in_progress || first_flist->to_redo)
break;
if (!read_batch) {
write_ndx(sock_f_out, NDX_DONE);
write_ndx(sock_f_out, NDX_DONE);
if (!read_batch)
maybe_flush_socket(1);
}
if (delete_during == 2 || !dir_tweaking) {
/* Skip directory touch-up. */
@@ -2206,7 +2215,7 @@ void generate_files(int f_out, const char *local_name)
/* Since we often fill up the outgoing socket and then just sit around
* waiting for the other 2 processes to do their thing, we don't want
* to exit on a timeout. If the data stops flowing, the receiver will
* notice that and let us know via the redo pipe (or its closing). */
* notice that and let us know via the message pipe (or its closing). */
ignore_timeout = 1;
dflt_perms = (ACCESSPERMS & ~orig_umask);
@@ -2300,6 +2309,7 @@ void generate_files(int f_out, const char *local_name)
rprintf(FINFO, "generate_files phase=%d\n", phase);
write_ndx(f_out, NDX_DONE);
/* Reduce round-trip lag-time for a useless delay-updates phase. */
if (protocol_version >= 29 && !delay_updates)
write_ndx(f_out, NDX_DONE);

View File

@@ -1,7 +1,7 @@
/*
* Routines to provide a memory-efficient hashtable.
*
* Copyright (C) 2007-2008 Wayne Davison
* Copyright (C) 2007-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -87,7 +87,7 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
uchar buf[4], *keyp = buf;
int i;
SIVAL(buf, 0, key);
SIVALu(buf, 0, key);
for (ndx = 0, i = 0; i < 4; i++) {
ndx += keyp[i];
ndx += (ndx << 10);

51
hlink.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2004-2008 Wayne Davison
* Copyright (C) 2004-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@ extern int inc_recurse;
extern int do_xfers;
extern int link_dest;
extern int preserve_acls;
extern int preserve_xattrs;
extern int make_backups;
extern int protocol_version;
extern int remove_source_files;
@@ -355,9 +356,13 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
}
if (link_stat(prev_name, &prev_st, 0) < 0) {
rsyserr(FERROR_XFER, errno, "stat %s failed",
full_fname(prev_name));
return -1;
if (!dry_run || errno != ENOENT) {
rsyserr(FERROR_XFER, errno, "stat %s failed", full_fname(prev_name));
return -1;
}
/* A new hard-link will get a new dev & inode, so approximate
* those values in dry-run mode by zeroing them. */
memset(&prev_st, 0, sizeof prev_st);
}
if (statret < 0 && basis_dir[0] != NULL) {
@@ -367,6 +372,9 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
int j = 0;
#ifdef SUPPORT_ACLS
alt_sx.acc_acl = alt_sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
alt_sx.xattr = NULL;
#endif
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
@@ -396,19 +404,37 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
sxp->st = alt_sx.st;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
if (!ACL_READY(*sxp))
free_acl(sxp);
if (!ACL_READY(alt_sx))
get_acl(cmpbuf, sxp);
else {
sxp->acc_acl = alt_sx.acc_acl;
sxp->def_acl = alt_sx.def_acl;
alt_sx.acc_acl = alt_sx.def_acl = NULL;
}
}
#endif
}
#ifdef SUPPORT_ACLS
else if (preserve_acls)
free_acl(&alt_sx);
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
free_xattr(sxp);
if (!XATTR_READY(alt_sx))
get_xattr(cmpbuf, sxp);
else {
sxp->xattr = alt_sx.xattr;
alt_sx.xattr = NULL;
}
}
#endif
} else {
#ifdef SUPPORT_ACLS
if (preserve_acls)
free_acl(&alt_sx);
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs)
free_xattr(&alt_sx);
#endif
}
}
if (maybe_hard_link(file, ndx, fname, statret, sxp, prev_name, &prev_st,
@@ -475,6 +501,9 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
#ifdef SUPPORT_ACLS
prev_sx.acc_acl = prev_sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
prev_sx.xattr = NULL;
#endif
while ((ndx = prev_ndx) >= 0) {
int val;
@@ -490,6 +519,10 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
#ifdef SUPPORT_ACLS
if (preserve_acls)
free_acl(&prev_sx);
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs)
free_xattr(&prev_sx);
#endif
if (val < 0)
continue;

149
io.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2001 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -119,21 +119,34 @@ static char int_byte_extra[64] = {
enum festatus { FES_SUCCESS, FES_REDO, FES_NO_SEND };
static void check_timeout(void)
{
time_t t, chk;
if (!io_timeout || ignore_timeout)
return;
t = time(NULL);
if (!last_io_in)
last_io_in = t;
chk = MAX(last_io_out, last_io_in);
if (t - chk >= io_timeout) {
if (am_server || am_daemon)
exit_cleanup(RERR_TIMEOUT);
rprintf(FERROR, "[%s] io timeout after %d seconds -- exiting\n",
who_am_i(), (int)(t-chk));
exit_cleanup(RERR_TIMEOUT);
}
}
static void readfd(int fd, char *buffer, size_t N);
static void writefd(int fd, const char *buf, size_t len);
static void writefd_unbuffered(int fd, const char *buf, size_t len);
static void mplex_write(int fd, enum msgcode code, const char *buf, size_t len, int convert);
struct flist_ndx_item {
struct flist_ndx_item *next;
int ndx;
};
struct flist_ndx_list {
struct flist_ndx_item *head, *tail;
};
static struct flist_ndx_list redo_list, hlink_list;
static flist_ndx_list redo_list, hlink_list;
struct msg_list_item {
struct msg_list_item *next;
@@ -147,39 +160,6 @@ struct msg_list {
static struct msg_list msg_queue;
static void flist_ndx_push(struct flist_ndx_list *lp, int ndx)
{
struct flist_ndx_item *item;
if (!(item = new(struct flist_ndx_item)))
out_of_memory("flist_ndx_push");
item->next = NULL;
item->ndx = ndx;
if (lp->tail)
lp->tail->next = item;
else
lp->head = item;
lp->tail = item;
}
static int flist_ndx_pop(struct flist_ndx_list *lp)
{
struct flist_ndx_item *next;
int ndx;
if (!lp->head)
return -1;
ndx = lp->head->ndx;
next = lp->head->next;
free(lp->head);
lp->head = next;
if (!next)
lp->tail = NULL;
return ndx;
}
static void got_flist_entry_status(enum festatus status, const char *buf)
{
int ndx = IVAL(buf, 0);
@@ -206,6 +186,11 @@ static void got_flist_entry_status(enum festatus status, const char *buf)
}
break;
case FES_REDO:
if (read_batch) {
if (inc_recurse)
flist->in_progress++;
break;
}
if (inc_recurse)
flist->to_redo++;
flist_ndx_push(&redo_list, ndx);
@@ -215,29 +200,6 @@ static void got_flist_entry_status(enum festatus status, const char *buf)
}
}
static void check_timeout(void)
{
time_t t;
if (!io_timeout || ignore_timeout)
return;
if (!last_io_in) {
last_io_in = time(NULL);
return;
}
t = time(NULL);
if (t - last_io_in >= io_timeout) {
if (!am_server && !am_daemon) {
rprintf(FERROR, "io timeout after %d seconds -- exiting\n",
(int)(t-last_io_in));
}
exit_cleanup(RERR_TIMEOUT);
}
}
/* Note the fds used for the main socket (which might really be a pipe
* for a local transfer, but we can ignore that). */
void io_set_sock_fds(int f_in, int f_out)
@@ -249,13 +211,15 @@ void io_set_sock_fds(int f_in, int f_out)
void set_io_timeout(int secs)
{
io_timeout = secs;
allowed_lull = (io_timeout + 1) / 2;
if (!io_timeout || io_timeout > SELECT_TIMEOUT)
if (!io_timeout || allowed_lull > SELECT_TIMEOUT)
select_timeout = SELECT_TIMEOUT;
else
select_timeout = io_timeout;
select_timeout = allowed_lull;
allowed_lull = read_batch ? 0 : (io_timeout + 1) / 2;
if (read_batch)
allowed_lull = 0;
}
/* Setup the fd used to receive MSG_* messages. Only needed during the
@@ -484,9 +448,14 @@ static void read_msg_fd(void)
* this, sender-side deletions were mostly happening at the end. */
void increment_active_files(int ndx, int itemizing, enum logcode code)
{
/* TODO: tune these limits? */
while (active_filecnt >= (active_bytecnt >= 128*1024 ? 10 : 50)) {
while (1) {
/* TODO: tune these limits? */
int limit = active_bytecnt >= 128*1024 ? 10 : 50;
if (active_filecnt < limit)
break;
check_for_finished_files(itemizing, code, 0);
if (active_filecnt < limit)
break;
if (iobuf_out_cnt)
io_flush(NORMAL_FLUSH);
else
@@ -982,8 +951,8 @@ void maybe_send_keepalive(void)
if (time(NULL) - last_io_out >= allowed_lull) {
if (!iobuf_out || !iobuf_out_cnt) {
if (protocol_version < 29)
return; /* there's nothing we can do */
if (protocol_version >= 30)
send_msg(MSG_DATA, "", 0, 0);
else if (protocol_version >= 30)
send_msg(MSG_NOOP, "", 0, 0);
else {
write_int(sock_f_out, cur_flist->used);
@@ -1000,11 +969,13 @@ void start_flist_forward(int f_in)
assert(iobuf_out != NULL);
assert(iobuf_f_out == msg_fd_out);
flist_forward_from = f_in;
defer_forwarding_messages++;
}
void stop_flist_forward()
void stop_flist_forward(void)
{
flist_forward_from = -1;
defer_forwarding_messages--;
io_flush(FULL_FLUSH);
}
@@ -1071,6 +1042,8 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
iobuf_in_ndx = 0;
break;
case MSG_NOOP:
if (msg_bytes != 0)
goto invalid_msg;
if (am_sender)
maybe_send_keepalive();
break;
@@ -1450,6 +1423,22 @@ static void sleep_for_bwlimit(int bytes_written)
total_written = (sleep_usec - elapsed_usec) * bwlimit / (ONE_SEC/1024);
}
static const char *what_fd_is(int fd)
{
static char buf[20];
if (fd == sock_f_out)
return "socket";
else if (fd == msg_fd_out)
return "message fd";
else if (fd == batch_fd)
return "batch file";
else {
snprintf(buf, sizeof buf, "fd %d", fd);
return buf;
}
}
/* Write len bytes to the file descriptor fd, looping as necessary to get
* the job done and also (in certain circumstances) reading any data on
* msg_fd_in to avoid deadlock.
@@ -1528,8 +1517,8 @@ static void writefd_unbuffered(int fd, const char *buf, size_t len)
if (am_server && fd == msg_fd_out)
exit_cleanup(RERR_STREAMIO);
rsyserr(FERROR, errno,
"writefd_unbuffered failed to write %ld bytes [%s]",
(long)len, who_am_i());
"writefd_unbuffered failed to write %ld bytes to %s [%s]",
(long)len, what_fd_is(fd), who_am_i());
/* If the other side is sending us error messages, try
* to grab any messages they sent before they died. */
while (!am_server && fd == sock_f_out && io_multiplexing_in) {
@@ -1587,10 +1576,8 @@ static void writefd(int fd, const char *buf, size_t len)
if (fd == sock_f_out)
stats.total_written += len;
if (fd == write_batch_monitor_out) {
if ((size_t)write(batch_fd, buf, len) != len)
exit_cleanup(RERR_FILEIO);
}
if (fd == write_batch_monitor_out)
writefd_unbuffered(batch_fd, buf, len);
if (!iobuf_out || fd != iobuf_f_out) {
writefd_unbuffered(fd, buf, len);

View File

@@ -295,9 +295,8 @@ int getaddrinfo(const char *node,
res);
} else if (hints.ai_flags & AI_NUMERICHOST) {
struct in_addr ip;
if (!inet_aton(node, &ip)) {
if (inet_pton(AF_INET, node, &ip) <= 0)
return EAI_FAIL;
}
return getaddr_info_single_addr(service,
ntohl(ip.s_addr),
&hints,
@@ -492,13 +491,10 @@ int getnameinfo(const struct sockaddr *sa, socklen_t salen,
return EAI_FAIL;
}
/* We don't support those. */
if ((node && !(flags & NI_NUMERICHOST))
|| (service && !(flags & NI_NUMERICSERV)))
return EAI_FAIL;
if (node) {
return gethostnameinfo(sa, node, nodelen, flags);
int ret = gethostnameinfo(sa, node, nodelen, flags);
if (ret)
return ret;
}
if (service) {

View File

@@ -38,22 +38,22 @@ static void md5_process(md_context *ctx, const uchar data[CSUM_CHUNK])
C = ctx->C;
D = ctx->D;
X[0] = IVAL(data, 0);
X[1] = IVAL(data, 4);
X[2] = IVAL(data, 8);
X[3] = IVAL(data, 12);
X[4] = IVAL(data, 16);
X[5] = IVAL(data, 20);
X[6] = IVAL(data, 24);
X[7] = IVAL(data, 28);
X[8] = IVAL(data, 32);
X[9] = IVAL(data, 36);
X[10] = IVAL(data, 40);
X[11] = IVAL(data, 44);
X[12] = IVAL(data, 48);
X[13] = IVAL(data, 52);
X[14] = IVAL(data, 56);
X[15] = IVAL(data, 60);
X[0] = IVALu(data, 0);
X[1] = IVALu(data, 4);
X[2] = IVALu(data, 8);
X[3] = IVALu(data, 12);
X[4] = IVALu(data, 16);
X[5] = IVALu(data, 20);
X[6] = IVALu(data, 24);
X[7] = IVALu(data, 28);
X[8] = IVALu(data, 32);
X[9] = IVALu(data, 36);
X[10] = IVALu(data, 40);
X[11] = IVALu(data, 44);
X[12] = IVALu(data, 48);
X[13] = IVALu(data, 52);
X[14] = IVALu(data, 56);
X[15] = IVALu(data, 60);
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
@@ -192,8 +192,8 @@ void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN])
| (ctx->totalN2 << 3);
low = (ctx->totalN << 3);
SIVAL(msglen, 0, low);
SIVAL(msglen, 4, high);
SIVALu(msglen, 0, low);
SIVALu(msglen, 4, high);
last = ctx->totalN & 0x3F;
padn = last < 56 ? 56 - last : 120 - last;
@@ -201,10 +201,10 @@ void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN])
md5_update(ctx, md5_padding, padn);
md5_update(ctx, msglen, 8);
SIVAL(digest, 0, ctx->A);
SIVAL(digest, 4, ctx->B);
SIVAL(digest, 8, ctx->C);
SIVAL(digest, 12, ctx->D);
SIVALu(digest, 0, ctx->A);
SIVALu(digest, 4, ctx->B);
SIVALu(digest, 8, ctx->C);
SIVALu(digest, 12, ctx->D);
}
void get_md5(uchar *out, const uchar *input, int n)

View File

@@ -295,24 +295,30 @@ pool_boundary(alloc_pool_t p, size_t len)
}
#define FDPRINT(label, value) \
snprintf(buf, sizeof buf, label, value), \
write(fd, buf, strlen(buf))
do { \
int len = snprintf(buf, sizeof buf, label, value); \
if (write(fd, buf, len) != len) \
ret = -1; \
} while (0)
#define FDEXTSTAT(ext) \
snprintf(buf, sizeof buf, " %12ld %5ld\n", \
(long) ext->free, \
(long) ext->bound), \
write(fd, buf, strlen(buf))
do { \
int len = snprintf(buf, sizeof buf, " %12ld %5ld\n", \
(long)ext->free, (long)ext->bound); \
if (write(fd, buf, len) != len) \
ret = -1; \
} while (0)
void
int
pool_stats(alloc_pool_t p, int fd, int summarize)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
struct pool_extent *cur;
char buf[BUFSIZ];
int ret = 0;
if (!pool)
return;
return ret;
FDPRINT(" Extent size: %12ld\n", (long) pool->size);
FDPRINT(" Alloc quantum: %12ld\n", (long) pool->quantum);
@@ -324,13 +330,16 @@ pool_stats(alloc_pool_t p, int fd, int summarize)
FDPRINT(" Bytes freed: %12.0f\n", (double) pool->b_freed);
if (summarize)
return;
return ret;
if (!pool->extents)
return;
return ret;
write(fd, "\n", 1);
if (write(fd, "\n", 1) != 1)
ret = -1;
for (cur = pool->extents; cur; cur = cur->next)
FDEXTSTAT(cur);
return ret;
}

View File

@@ -1815,7 +1815,11 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
/* AIX has no DEFAULT */
if ( type == SMB_ACL_TYPE_DEFAULT ) {
#ifdef ENOTSUP
errno = ENOTSUP;
#else
errno = ENOSYS;
#endif
return NULL;
}

View File

@@ -1,6 +1,3 @@
/* This is based on loadparm.c from Samba, written by Andrew Tridgell
and Karl Auer */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,13 +13,14 @@
* with this program; if not, visit the http://fsf.org website.
*/
/* some fixes
/* This is based on loadparm.c from Samba, written by Andrew Tridgell
* and Karl Auer. Some of the changes are:
*
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2009 Wayne Davison <wayned@samba.org>
*/
/*
* Load parameters.
/* Load parameters.
*
* This module provides suitable callback functions for the params
* module. It builds the internal table of service details which is

6
log.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2000-2001 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -55,7 +55,7 @@ extern iconv_t ic_chck;
extern iconv_t ic_send, ic_recv;
#endif
extern char curr_dir[];
extern char *module_dir;
extern char *full_module_path;
extern unsigned int module_dirlen;
static int log_initialised;
@@ -603,7 +603,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
n = timestring(time(NULL));
break;
case 'P':
n = module_dir;
n = full_module_path;
break;
case 'u':
n = auth_user;

14
main.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,7 +33,6 @@ extern int list_only;
extern int am_root;
extern int am_server;
extern int am_sender;
extern int am_generator;
extern int am_daemon;
extern int inc_recurse;
extern int blocking_io;
@@ -81,6 +80,8 @@ extern struct file_list *first_flist;
extern struct filter_list_struct daemon_filter_list;
uid_t our_uid;
int am_receiver = 0; /* Only set to 1 after the receiver/generator fork. */
int am_generator = 0; /* Only set to 1 after the receiver/generator fork. */
int local_server = 0;
int daemon_over_rsh = 0;
mode_t orig_umask = 0;
@@ -469,7 +470,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
#ifdef ICONV_CONST
setup_iconv();
#endif
if (protect_args)
if (protect_args && !daemon_over_rsh)
send_protected_args(*f_out_p, args);
}
@@ -760,6 +761,8 @@ static int do_recv(int f_in, int f_out, char *local_name)
}
if (pid == 0) {
am_receiver = 1;
close(error_pipe[0]);
if (f_in != f_out)
close(f_out);
@@ -1016,7 +1019,6 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
if (write_batch && !am_server)
start_write_batch(f_out);
flist = send_file_list(f_out, argc, argv);
set_msg_fd_in(-1);
if (verbose > 3)
rprintf(FINFO,"file list sent\n");
@@ -1187,8 +1189,8 @@ static int start_client(int argc, char *argv[])
rprintf(FERROR, "remote destination is not allowed with --read-batch\n");
exit_cleanup(RERR_SYNTAX);
}
remote_argv = argv + argc - 1;
remote_argc = 1;
remote_argv = argv += argc - 1;
remote_argc = argc = 1;
}
if (am_sender) {

View File

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

140
options.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2000, 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2002-2008 Wayne Davison
* Copyright (C) 2002-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -78,7 +78,6 @@ int def_compress_level = Z_DEFAULT_COMPRESSION;
int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */
int am_server = 0;
int am_sender = 0;
int am_generator = 0;
int am_starting_up = 1;
int relative_paths = -1;
int implied_dirs = 1;
@@ -228,7 +227,8 @@ static void print_rsync_version(enum logcode f)
STRUCT_STAT *dumstat;
#if SUBPROTOCOL_VERSION != 0
asprintf(&subprotocol, ".PR%d", SUBPROTOCOL_VERSION);
if (asprintf(&subprotocol, ".PR%d", SUBPROTOCOL_VERSION) < 0)
out_of_memory("print_rsync_version");
#endif
#ifdef HAVE_SOCKETPAIR
got_socketpair = "";
@@ -260,7 +260,7 @@ static void print_rsync_version(enum logcode f)
rprintf(f, "%s version %s protocol version %d%s\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
rprintf(f, "Copyright (C) 1996-2008 by Andrew Tridgell, Wayne Davison, and others.\n");
rprintf(f, "Copyright (C) 1996-2009 by Andrew Tridgell, Wayne Davison, and others.\n");
rprintf(f, "Web site: http://rsync.samba.org/\n");
rprintf(f, "Capabilities:\n");
rprintf(f, " %d-bit files, %d-bit inums, %d-bit timestamps, %d-bit long ints,\n",
@@ -1356,6 +1356,12 @@ int parse_arguments(int *argc_p, const char ***argv_p)
"--read-batch cannot be used with --files-from\n");
return 0;
}
if (read_batch && remove_source_files) {
snprintf(err_buf, sizeof err_buf,
"--read-batch cannot be used with --remove-%s-files\n",
remove_source_files == 1 ? "source" : "sent");
return 0;
}
if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
snprintf(err_buf, sizeof err_buf,
"the batch-file name must be %d characters or less.\n",
@@ -1425,7 +1431,7 @@ int parse_arguments(int *argc_p, const char ***argv_p)
}
if (!xfer_dirs && delete_mode) {
snprintf(err_buf, sizeof err_buf,
"--delete does not work without -r or -d.\n");
"--delete does not work without --recursive (-r) or --dirs (-d).\n");
return 0;
}
@@ -1831,6 +1837,7 @@ void server_options(char **args, int *argc_p)
#ifdef ICONV_OPTION
argstr[x++] = 's';
#endif
argstr[x++] = 'f';
}
if (x >= (int)sizeof argstr) { /* Not possible... */
@@ -1840,7 +1847,8 @@ void server_options(char **args, int *argc_p)
argstr[x] = '\0';
args[ac++] = argstr;
if (x > 1)
args[ac++] = argstr;
#ifdef ICONV_OPTION
if (iconv_opt) {
@@ -2073,6 +2081,62 @@ void server_options(char **args, int *argc_p)
out_of_memory("server_options");
}
/* If str points to a valid hostspec, return allocated memory containing the
* [USER@]HOST part of the string, and set the path_start_ptr to the part of
* the string after the host part. Otherwise, return NULL. If port_ptr is
* non-NULL, we must be parsing an rsync:// URL hostname, and we will set
* *port_ptr if a port number is found. Note that IPv6 IPs will have their
* (required for parsing) [ and ] chars elided from the returned string. */
static char *parse_hostspec(char *str, char **path_start_ptr, int *port_ptr)
{
char *s, *host_start = str;
int hostlen = 0, userlen = 0;
char *ret;
for (s = str; ; s++) {
if (!*s) {
/* It is only OK if we run out of string with rsync:// */
if (!port_ptr)
return NULL;
if (!hostlen)
hostlen = s - host_start;
break;
}
if (*s == ':' || *s == '/') {
if (!hostlen)
hostlen = s - host_start;
if (*s++ == '/') {
if (!port_ptr)
return NULL;
} else if (port_ptr) {
*port_ptr = atoi(s);
while (isDigit(s)) s++;
if (*s && *s++ != '/')
return NULL;
}
break;
}
if (*s == '@') {
userlen = s - str + 1;
host_start = s + 1;
} else if (*s == '[') {
if (s != host_start++)
return NULL;
while (*s && *s != ']' && *s != '/') s++; /*SHARED ITERATOR*/
hostlen = s - host_start;
if (*s != ']' || (s[1] && s[1] != '/' && s[1] != ':') || !hostlen)
return NULL;
}
}
*path_start_ptr = s;
ret = new_array(char, userlen + hostlen + 1);
if (userlen)
strlcpy(ret, str, userlen + 1);
strlcpy(ret + userlen, host_start, hostlen + 1);
return ret;
}
/* Look for a HOST specfication of the form "HOST:PATH", "HOST::PATH", or
* "rsync://HOST:PORT/PATH". If found, *host_ptr will be set to some allocated
* memory with the HOST. If a daemon-accessing spec was specified, the value
@@ -2082,68 +2146,28 @@ void server_options(char **args, int *argc_p)
* "[::ffff:127.0.0.1]") which is returned without the '[' and ']'. */
char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
{
char *p;
int not_host;
int hostlen;
char *path;
if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
char *path;
s += strlen(URL_PREFIX);
if ((p = strchr(s, '/')) != NULL) {
hostlen = p - s;
path = p + 1;
} else {
hostlen = strlen(s);
path = "";
*host_ptr = parse_hostspec(s + strlen(URL_PREFIX), &path, port_ptr);
if (*host_ptr) {
if (!*port_ptr)
*port_ptr = RSYNC_PORT;
return path;
}
if (*s == '[' && (p = strchr(s, ']')) != NULL) {
s++;
hostlen = p - s;
if (p[1] == ':')
*port_ptr = atoi(p+2);
} else {
if ((p = strchr(s, ':')) != NULL && p < s + hostlen) {
hostlen = p - s;
*port_ptr = atoi(p+1);
}
}
if (!*port_ptr)
*port_ptr = RSYNC_PORT;
*host_ptr = new_array(char, hostlen + 1);
strlcpy(*host_ptr, s, hostlen + 1);
return path;
}
if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
s++;
hostlen = p - s;
*p = '\0';
not_host = strchr(s, '/') || !strchr(s, ':');
*p = ']';
if (not_host)
return NULL;
p++;
} else {
if (!(p = strchr(s, ':')))
return NULL;
hostlen = p - s;
*p = '\0';
not_host = strchr(s, '/') != NULL;
*p = ':';
if (not_host)
return NULL;
}
*host_ptr = parse_hostspec(s, &path, NULL);
if (!*host_ptr)
return NULL;
*host_ptr = new_array(char, hostlen + 1);
strlcpy(*host_ptr, s, hostlen + 1);
if (p[1] == ':') {
if (*path == ':') {
if (port_ptr && !*port_ptr)
*port_ptr = RSYNC_PORT;
return p + 2;
return path + 1;
}
if (port_ptr)
*port_ptr = 0;
return p + 1;
return path;
}

View File

@@ -1,6 +1,6 @@
Summary: A fast, versatile, remote (and local) file-copying tool
Name: rsync
Version: 3.0.4
Version: 3.0.7
%define fullversion %{version}
Release: 1
%define srcdir src
@@ -66,8 +66,8 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man5/rsyncd.conf.5*
%changelog
* Sat Sep 06 2008 Wayne Davison <wayned@samba.org>
Released 3.0.4.
* Thu Dec 31 2009 Wayne Davison <wayned@samba.org>
Released 3.0.7.
* Fri Mar 21 2008 Wayne Davison <wayned@samba.org>
Added installation of /etc/xinetd.d/rsync file and some commented-out

View File

@@ -10,6 +10,7 @@ use Getopt::Long;
my $patches_dir = 'patches';
my $tmp_dir = "patches.$$";
my $make_gen_cmd = 'make -f prepare-source.mak conf && ./config.status && make gen';
&Getopt::Long::Configure('bundling');
&usage if !&GetOptions(
@@ -50,7 +51,7 @@ close IN;
if ($incl_generated_files) {
die "'$tmp_dir' must not exist in the current directory.\n" if -e $tmp_dir;
mkdir($tmp_dir, 0700) or die "Unable to mkdir($tmp_dir): $!\n";
system "./config.status Makefile && make gen && rsync -a @extra_files $tmp_dir/master/" and exit 1;
system "$make_gen_cmd && rsync -a @extra_files $tmp_dir/master/" and exit 1;
}
our $last_touch = time;
@@ -158,7 +159,7 @@ sub update_patch
print OUT $description{$patch}, "\n";
if ($incl_generated_files) {
system "./config.status Makefile && make gen && rsync -a @extra_files $tmp_dir/$patch/" and exit 1;
system "$make_gen_cmd && rsync -a @extra_files $tmp_dir/$patch/" and exit 1;
}
$last_touch = time;

2
pipe.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2004-2008 Wayne Davison
* Copyright (C) 2004-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -85,7 +85,7 @@ char *alloca(size_t size);
# endif
# endif
# endif
#elif defined(__GNUC__) && defined(__STRICT_ANSI__)
#elif !defined(alloca)
#define alloca __builtin_alloca
#endif

View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -59,6 +59,7 @@ extern struct filter_list_struct daemon_filter_list;
static struct bitbag *delayed_bits = NULL;
static int phase = 0, redoing = 0;
static flist_ndx_list batch_redo_list;
/* We're either updating the basis file or an identical copy: */
static int updating_basis_or_equiv;
@@ -284,8 +285,11 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
goto report_write_error;
#ifdef HAVE_FTRUNCATE
if (inplace && fd != -1)
ftruncate(fd, offset);
if (inplace && fd != -1
&& ftruncate(fd, offset) < 0) {
rsyserr(FERROR_XFER, errno, "ftruncate failed on %s",
full_fname(fname));
}
#endif
if (do_progress)
@@ -348,25 +352,68 @@ static void handle_delayed_updates(char *local_name)
}
}
static int get_next_gen_ndx(int fd, int next_gen_ndx, int desired_ndx)
static void no_batched_update(int ndx, BOOL is_redo)
{
while (next_gen_ndx < desired_ndx) {
if (next_gen_ndx >= 0) {
struct file_struct *file = cur_flist->files[next_gen_ndx];
rprintf(FERROR_XFER,
"(No batched update for%s \"%s\")\n",
file->flags & FLAG_FILE_SENT ? " resend of" : "",
f_name(file, NULL));
}
next_gen_ndx = read_int(fd);
if (next_gen_ndx == -1) {
if (inc_recurse)
next_gen_ndx = first_flist->prev->used + first_flist->prev->ndx_start;
else
next_gen_ndx = cur_flist->used;
struct file_list *flist = flist_for_ndx(ndx, "no_batched_update");
struct file_struct *file = flist->files[ndx - flist->ndx_start];
rprintf(FERROR_XFER, "(No batched update for%s \"%s\")\n",
is_redo ? " resend of" : "", f_name(file, NULL));
if (inc_recurse && !dry_run)
send_msg_int(MSG_NO_SEND, ndx);
}
static int we_want_redo(int desired_ndx)
{
static int redo_ndx = -1;
while (redo_ndx < desired_ndx) {
if (redo_ndx >= 0)
no_batched_update(redo_ndx, True);
if ((redo_ndx = flist_ndx_pop(&batch_redo_list)) < 0)
return 0;
}
if (redo_ndx == desired_ndx) {
redo_ndx = -1;
return 1;
}
return 0;
}
static int gen_wants_ndx(int desired_ndx)
{
static int next_ndx = -1;
static int done_cnt = 0;
static BOOL got_eof = False;
int flist_num = first_flist->flist_num;
if (got_eof)
return 0;
while (next_ndx < desired_ndx) {
if (inc_recurse && flist_num <= done_cnt)
return 0;
if (next_ndx >= 0)
no_batched_update(next_ndx, False);
if ((next_ndx = read_int(batch_gen_fd)) < 0) {
if (inc_recurse) {
done_cnt++;
continue;
}
got_eof = True;
return 0;
}
}
return next_gen_ndx;
if (next_ndx == desired_ndx) {
next_ndx = -1;
return 1;
}
return 0;
}
/**
@@ -375,7 +422,6 @@ static int get_next_gen_ndx(int fd, int next_gen_ndx, int desired_ndx)
* Receiver process runs on the same host as the generator process. */
int recv_files(int f_in, char *local_name)
{
int next_gen_ndx = -1;
int fd1,fd2;
STRUCT_STAT st;
int iflags, xlen;
@@ -410,17 +456,13 @@ int recv_files(int f_in, char *local_name)
xname, &xlen);
if (ndx == NDX_DONE) {
if (inc_recurse && first_flist) {
if (read_batch)
gen_wants_ndx(first_flist->used + first_flist->ndx_start);
flist_free(first_flist);
if (first_flist)
continue;
}
if (read_batch && cur_flist) {
int high = inc_recurse
? first_flist->prev->used + first_flist->prev->ndx_start
: cur_flist->used;
get_next_gen_ndx(batch_gen_fd, next_gen_ndx, high);
next_gen_ndx = -1;
}
} else if (read_batch && first_flist)
gen_wants_ndx(first_flist->used);
if (++phase > max_phase)
break;
if (verbose > 2)
@@ -441,14 +483,14 @@ int recv_files(int f_in, char *local_name)
rprintf(FINFO, "recv_files(%s)\n", fname);
#ifdef SUPPORT_XATTRS
if (iflags & ITEM_REPORT_XATTR && !dry_run)
if (iflags & ITEM_REPORT_XATTR && do_xfers)
recv_xattr_request(file, f_in);
#endif
if (!(iflags & ITEM_TRANSFER)) {
maybe_log_item(file, iflags, itemizing, xname);
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && !dry_run)
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
set_file_attrs(fname, file, NULL, fname, 0);
#endif
continue;
@@ -495,6 +537,21 @@ int recv_files(int f_in, char *local_name)
exit_cleanup(RERR_PROTOCOL);
}
if (read_batch) {
int wanted = redoing
? we_want_redo(ndx)
: gen_wants_ndx(ndx);
if (!wanted) {
rprintf(FINFO,
"(Skipping batched update for%s \"%s\")\n",
redoing ? " resend of" : "",
fname);
discard_receive_data(f_in, F_LENGTH(file));
file->flags |= FLAG_FILE_SENT;
continue;
}
}
if (!do_xfers) { /* log the transfer */
log_item(FCLIENT, file, &stats, iflags, NULL);
if (read_batch)
@@ -508,20 +565,6 @@ int recv_files(int f_in, char *local_name)
continue;
}
if (read_batch) {
next_gen_ndx = get_next_gen_ndx(batch_gen_fd, next_gen_ndx, ndx);
if (ndx < next_gen_ndx) {
rprintf(FINFO,
"(Skipping batched update for \"%s\")\n",
fname);
discard_receive_data(f_in, F_LENGTH(file));
if (inc_recurse)
send_msg_int(MSG_NO_SEND, ndx);
continue;
}
next_gen_ndx = -1;
}
partialptr = partial_dir ? partial_dir_fname(fname) : fname;
if (protocol_version >= 29) {
@@ -719,6 +762,9 @@ int recv_files(int f_in, char *local_name)
cleanup_disable();
if (read_batch)
file->flags |= FLAG_FILE_SENT;
switch (recv_ok) {
case 2:
break;
@@ -751,6 +797,8 @@ int recv_files(int f_in, char *local_name)
keptstr, redostr);
}
if (!redoing) {
if (read_batch)
flist_ndx_push(&batch_redo_list, ndx);
send_msg_int(MSG_REDO, ndx);
file->flags |= FLAG_FILE_SENT;
} else if (inc_recurse)

View File

@@ -1,7 +1,7 @@
/*
* A pre-compilation helper program to aid in the creation of rounding.h.
*
* Copyright (C) 2007-2008 Wayne Davison
* Copyright (C) 2007-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

21
rsync.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +37,7 @@ extern int preserve_times;
extern int am_root;
extern int am_server;
extern int am_sender;
extern int am_receiver;
extern int am_generator;
extern int am_starting_up;
extern int allow_8bit_chars;
@@ -80,7 +81,6 @@ void setup_iconv(void)
# endif
if (!am_server && !allow_8bit_chars) {
/* It's OK if this fails... */
ic_chck = iconv_open(defset, defset);
@@ -221,16 +221,19 @@ void send_protected_args(int fd, char *args[])
if (verbose > 1)
print_child_argv("protected args:", args + i + 1);
do {
if (!args[i][0])
write_buf(fd, ".", 2);
#ifdef ICONV_OPTION
if (convert) {
else if (convert) {
INIT_XBUF_STRLEN(inbuf, args[i]);
iconvbufs(ic_send, &inbuf, &outbuf,
ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE);
outbuf.buf[outbuf.len] = '\0';
write_buf(fd, outbuf.buf, outbuf.len + 1);
outbuf.len = 0;
} else
}
#endif
else
write_buf(fd, args[i], strlen(args[i]) + 1);
} while (args[++i]);
write_byte(fd, 0);
@@ -301,9 +304,8 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
iflags = protocol_version >= 29 ? read_shortint(f_in)
: ITEM_TRANSFER | ITEM_MISSING_DATA;
/* Honor the old-style keep-alive indicator. */
if (protocol_version < 30
&& ndx == cur_flist->used && iflags == ITEM_IS_NEW) {
/* Support the protocol-29 keep-alive style. */
if (protocol_version < 30 && ndx == cur_flist->used && iflags == ITEM_IS_NEW) {
if (am_sender)
maybe_send_keepalive();
goto read_loop;
@@ -650,5 +652,8 @@ const char *who_am_i(void)
{
if (am_starting_up)
return am_server ? "server" : "client";
return am_sender ? "sender" : am_generator ? "generator" : "receiver";
return am_sender ? "sender"
: am_generator ? "generator"
: am_receiver ? "receiver"
: "Receiver"; /* pre-forked receiver */
}

14
rsync.h
View File

@@ -32,7 +32,7 @@
#define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock"
#define URL_PREFIX "rsync://"
#define SYMLINK_PREFIX "/rsyncd-munged/"
#define SYMLINK_PREFIX "/rsyncd-munged/" /* This MUST have a trailing slash! */
#define SYMLINK_PREFIX_LEN ((int)sizeof SYMLINK_PREFIX - 1)
#define BACKUP_SUFFIX "~"
@@ -60,6 +60,7 @@
#define XMIT_RDEV_MINOR_8_pre30 (1<<11) /* protocols 28 - 29 */
#define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - now */
#define XMIT_HLINK_FIRST (1<<12) /* protocols 30 - now (HLINKED files only) */
#define XMIT_IO_ERROR_ENDLIST (1<<12) /* protocols 31*- now (w/XMIT_EXTENDED_FLAGS) (also protocol 30 w/'f' compat flag) */
/* These flags are used in the live flist data. */
@@ -396,7 +397,7 @@ enum msgcode {
# include <limits.h>
#endif
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
#if defined USE_ICONV_OPEN && defined HAVE_ICONV_H
#include <iconv.h>
#ifndef ICONV_CONST
#define ICONV_CONST
@@ -832,6 +833,15 @@ struct stats {
struct chmod_mode_struct;
struct flist_ndx_item {
struct flist_ndx_item *next;
int ndx;
};
typedef struct {
struct flist_ndx_item *head, *tail;
} flist_ndx_list;
#define EMPTY_ITEM_LIST {NULL, 0, 0}
typedef struct {

198
rsync.yo
View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsync)(1)(6 Sep 2008)()()
manpage(rsync)(1)(31 Dec 2009)()()
manpagename(rsync)(a fast, versatile, remote (and local) file-copying tool)
manpagesynopsis()
@@ -70,6 +70,10 @@ destination, the files are listed in an output format similar to "ls -l".
As expected, if neither the source or destination path specify a remote
host, the copy occurs locally (see also the bf(--list-only) option).
Rsync refers to the local side as the "client" and the remote side as the
"server". Don't confuse "server" with an rsync daemon -- a daemon is always a
server, but a server can be either a daemon or a remote-shell spawned process.
manpagesection(SETUP)
See the file README for installation instructions.
@@ -514,7 +518,7 @@ dit(bf(-c, --checksum)) This changes the way rsync checks if the files have
been changed and are in need of a transfer. Without this option, rsync
uses a "quick check" that (by default) checks if each file's size and time
of last modification match between the sender and receiver. This option
changes this to compare a 128-bit MD4 checksum for each file that has a
changes this to compare a 128-bit checksum for each file that has a
matching size. Generating the checksums means that both sides will expend
a lot of disk I/O reading all the data in the files in the transfer (and
this is prior to any reading that will be done to transfer changed files),
@@ -532,6 +536,9 @@ checksum that is generated as the file is transferred, but that
automatic after-the-transfer verification has nothing to do with this
option's before-the-transfer "Does this file need to be updated?" check.
For protocol 30 and beyond (first supported in 3.0.0), the checksum used is
MD5. For older protocols, the checksum used is MD4.
dit(bf(-a, --archive)) This is equivalent to bf(-rlptgoD). It is a quick
way of saying you want recursion and want to preserve almost
everything (with -H being a notable omission).
@@ -619,7 +626,7 @@ quote(tt( rsync -avR /foo/./bar/baz.c remote:/tmp/))
That would create /tmp/bar/baz.c on the remote machine. (Note that the
dot must be followed by a slash, so "/foo/." would not be abbreviated.)
(2) For older rsync versions, you would need to use a chdir to limit the
For older rsync versions, you would need to use a chdir to limit the
source path. For example, when pushing files:
quote(tt( (cd /foo; rsync -avR bar/baz.c remote:/tmp/) ))
@@ -667,7 +674,7 @@ Note that if you don't specify bf(--backup-dir), (1) the
bf(--omit-dir-times) option will be implied, and (2) if bf(--delete) is
also in effect (without bf(--delete-excluded)), rsync will add a "protect"
filter-rule for the backup suffix to the end of all your existing excludes
(e.g. bf(-f "Pp *~")). This will prevent previously backed-up files from being
(e.g. bf(-f "P *~")). This will prevent previously backed-up files from being
deleted. Note that if you are supplying your own filter rules, you may
need to manually insert your own exclude/protect rule somewhere higher up
in the list so that it has a high enough priority to be effective (e.g., if
@@ -697,8 +704,12 @@ date is on the objects. In other words, if the source has a directory
where the destination has a file, the transfer would occur regardless of
the timestamps.
dit(bf(--inplace)) This option changes how rsync transfers a file when the
file's data needs to be updated: instead of the default method of creating
This option is a transfer rule, not an exclude, so it doesn't affect the
data that goes into the file-lists, and thus it doesn't affect deletions.
It just limits the files that the receiver requests to be transferred.
dit(bf(--inplace)) This option changes how rsync transfers a file when
its data needs to be updated: instead of the default method of creating
a new copy of the file and moving it into place when it is complete, rsync
instead writes the updated data directly to the destination file.
@@ -717,7 +728,7 @@ the backup file as the basis file for the transfer).
WARNING: you should not use this option to update files that are being
accessed by others, so be careful when choosing to use this for a copy.
This option is useful for transfer of large files with block-based changes
This option is useful for transferring large files with block-based changes
or appended data, and also on systems that are disk bound, not network
bound.
@@ -937,7 +948,7 @@ a normal user, see the bf(--fake-super) option.
dit(bf(--chmod)) This option tells rsync to apply one or more
comma-separated "chmod" strings to the permission of the files in the
transfer. The resulting value is treated as though it was the permissions
transfer. The resulting value is treated as though it were the permissions
that the sending side supplied for the file, which means that this option
can seem to have no effect on existing files if bf(--perms) is not enabled.
@@ -1007,7 +1018,7 @@ all groups (not just the current user's groups) via the bf(--groups)
option, and copying devices via the bf(--devices) option. This is useful
for systems that allow such activities without being the super-user, and
also for ensuring that you will get errors if the receiving side isn't
being running as the super-user. To turn off super-user activities, the
being run as the super-user. To turn off super-user activities, the
super-user can use bf(--no-super).
dit(bf(--fake-super)) When this option is enabled, rsync simulates
@@ -1046,8 +1057,8 @@ up less space on the destination. Conflicts with bf(--inplace) because it's
not possible to overwrite data in a sparse fashion.
NOTE: Don't use this option when the destination is a Solaris "tmpfs"
filesystem. It doesn't seem to handle seeks over null regions
correctly and ends up corrupting the files.
filesystem. It seems to have problems seeking over null regions,
and ends up corrupting the files.
dit(bf(-n, --dry-run)) This makes rsync perform a trial run that doesn't
make any changes (and produces mostly the same output as a real run). It
@@ -1057,19 +1068,20 @@ to do before one actually runs it.
The output of bf(--itemize-changes) is supposed to be exactly the same on a
dry run and a subsequent real run (barring intentional trickery and system
call failures); if it isn't, that's a bug. Other output is the same to the
extent practical, but may differ in some areas. Notably, a dry run does not
call failures); if it isn't, that's a bug. Other output should be mostly
unchanged, but may differ in some areas. Notably, a dry run does not
send the actual data for file transfers, so bf(--progress) has no effect,
the "bytes sent", "bytes received", "literal data", and "matched data"
statistics are too small, and the "speedup" value is equivalent to a run
where no file transfers are needed.
where no file transfers were needed.
dit(bf(-W, --whole-file)) With this option rsync's delta-transfer algorithm
is not used and the whole file is sent as-is instead. The transfer may be
faster if this option is used when the bandwidth between the source and
destination machines is higher than the bandwidth to disk (especially when the
"disk" is actually a networked filesystem). This is the default when both
the source and destination are specified as local paths.
the source and destination are specified as local paths, but only if no
batch-writing option is in effect.
dit(bf(-x, --one-file-system)) This tells rsync to avoid crossing a
filesystem boundary when recursing. This does not limit the user's ability
@@ -1095,10 +1107,18 @@ yet on the destination. If this option is
combined with the bf(--ignore-existing) option, no files will be updated
(which can be useful if all you want to do is delete extraneous files).
This option is a transfer rule, not an exclude, so it doesn't affect the
data that goes into the file-lists, and thus it doesn't affect deletions.
It just limits the files that the receiver requests to be transferred.
dit(bf(--ignore-existing)) This tells rsync to skip updating files that
already exist on the destination (this does em(not) ignore existing
directories, or nothing would get done). See also bf(--existing).
This option is a transfer rule, not an exclude, so it doesn't affect the
data that goes into the file-lists, and thus it doesn't affect deletions.
It just limits the files that the receiver requests to be transferred.
This option can be useful for those doing backups using the bf(--link-dest)
option when they need to continue a backup run that got interrupted. Since
a bf(--link-dest) run is copied into a new directory hierarchy (when it is
@@ -1133,7 +1153,7 @@ going to be deleted.
If the sending side detects any I/O errors, then the deletion of any
files at the destination will be automatically disabled. This is to
prevent temporary filesystem failures (such as NFS errors) on the
sending side causing a massive deletion of files on the
sending side from causing a massive deletion of files on the
destination. You can override this with the bf(--ignore-errors) option.
The bf(--delete) option may be combined with one of the --delete-WHEN options
@@ -1221,6 +1241,10 @@ file that is larger than the specified SIZE. The SIZE value can be
suffixed with a string to indicate a size multiplier, and
may be a fractional value (e.g. "bf(--max-size=1.5m)").
This option is a transfer rule, not an exclude, so it doesn't affect the
data that goes into the file-lists, and thus it doesn't affect deletions.
It just limits the files that the receiver requests to be transferred.
The suffixes are as follows: "K" (or "KiB") is a kibibyte (1024),
"M" (or "MiB") is a mebibyte (1024*1024), and "G" (or "GiB") is a
gibibyte (1024*1024*1024).
@@ -1235,7 +1259,7 @@ Examples: --max-size=1.5mb-1 is 1499999 bytes, and --max-size=2g+1 is
dit(bf(--min-size=SIZE)) This tells rsync to avoid transferring any
file that is smaller than the specified SIZE, which can help in not
transferring small, junk files.
See the bf(--max-size) option for a description of SIZE.
See the bf(--max-size) option for a description of SIZE and other information.
dit(bf(-B, --block-size=BLOCKSIZE)) This forces the block size used in
rsync's delta-transfer algorithm to a fixed value. It is normally selected based on
@@ -1423,6 +1447,11 @@ quote(tt( rsync -a --files-from=:/path/file-list src:/ /tmp/copy))
This would copy all the files specified in the /path/file-list file that
was located on the remote "src" host.
If the bf(--iconv) and bf(--protect-args) options are specified and the
bf(--files-from) filenames are being sent from one host to another, the
filenames will be translated from the sending host's charset to the
receiving host's charset.
dit(bf(-0, --from0)) This tells rsync that the rules/filenames it reads from a
file are terminated by a null ('\0') character, not a NL, CR, or CR+LF.
This affects bf(--exclude-from), bf(--include-from), bf(--files-from), and any
@@ -1430,18 +1459,14 @@ merged files specified in a bf(--filter) rule.
It does not affect bf(--cvs-exclude) (since all names read from a .cvsignore
file are split on whitespace).
If the bf(--iconv) and bf(--protect-args) options are specified and the
bf(--files-from) filenames are being sent from one host to another, the
filenames will be translated from the sending host's charset to the
receiving host's charset.
dit(bf(-s, --protect-args)) This option sends all filenames and some options to
dit(bf(-s, --protect-args)) This option sends all filenames and most options to
the remote rsync without allowing the remote shell to interpret them. This
means that spaces are not split in names, and any non-wildcard special
characters are not translated (such as ~, $, ;, &, etc.). Wildcards are
expanded on the remote host by rsync (instead of the shell doing it).
If you use this option with bf(--iconv), the args will also be translated
If you use this option with bf(--iconv), the args related to the remote
side will also be translated
from the local to the remote character-set. The translation happens before
wild-cards are expanded. See also the bf(--files-from) option.
@@ -1776,6 +1801,9 @@ specify an empty string, updated files will not be mentioned in the log file.
For a list of the possible escape characters, see the "log format" setting
in the rsyncd.conf manpage.
The default FORMAT used if bf(--log-file) is specified and this option is not
is '%i %n%L'.
dit(bf(--stats)) This tells rsync to print a verbose set of statistics
on the file transfer, allowing you to tell how effective rsync's delta-transfer
algorithm is for your data.
@@ -1925,11 +1953,16 @@ creation of a bunch of useless directories when the sending rsync is
recursively scanning a hierarchy of files using include/exclude/filter
rules.
Note that the use of transfer rules, such as the bf(--min-size) option, does
not affect what goes into the file list, and thus does not leave directories
empty, even if none of the files in a directory match the transfer rule.
Because the file-list is actually being pruned, this option also affects
what directories get deleted when a delete is active. However, keep in
mind that excluded files and directories can prevent existing items from
being deleted (because an exclude hides source files and protects
destination files).
being deleted due to an exclude both hiding source files and protecting
destination files. See the perishable filter-rule option for how to avoid
this.
You can prevent the pruning of certain empty directories from the file-list
by using a global "protect" filter. For instance, this option would ensure
@@ -2098,9 +2131,9 @@ If rsync was complied without support for IPv6, the bf(--ipv6) option
will have no effect. The bf(--version) output will tell you if this
is the case.
dit(bf(--checksum-seed=NUM)) Set the MD4 checksum seed to the integer
dit(bf(--checksum-seed=NUM)) Set the checksum seed to the integer
NUM. This 4 byte checksum seed is included in each block and file
MD4 checksum calculation. By default the checksum seed is generated
checksum calculation. By default the checksum seed is generated
by the server and defaults to the current code(time()). This option
is used to set a specific checksum seed, which is useful for
applications that want repeatable block and file checksums, or
@@ -2276,7 +2309,7 @@ itemization(
it() rsync chooses between doing a simple string match and wildcard
matching by checking if the pattern contains one of these three wildcard
characters: '*', '?', and '[' .
it() a '*' matches any non-empty path component (it stops at slashes).
it() a '*' matches any path component, but it stops at slashes.
it() use '**' to match anything, including slashes.
it() a '?' matches any character except a slash (/).
it() a '[' introduces a character class, such as [a-z] or [[:alpha:]].
@@ -2349,6 +2382,39 @@ itemization(
explicitly included or it would be excluded by the "*")
)
The following modifiers are accepted after a "+" or "-":
itemization(
it() A bf(/) specifies that the include/exclude rule should be matched
against the absolute pathname of the current item. For example,
"-/ /etc/passwd" would exclude the passwd file any time the transfer
was sending files from the "/etc" directory, and "-/ subdir/foo"
would always exclude "foo" when it is in a dir named "subdir", even
if "foo" is at the root of the current transfer.
it() A bf(!) specifies that the include/exclude should take effect if
the pattern fails to match. For instance, "-! */" would exclude all
non-directories.
it() A bf(C) is used to indicate that all the global CVS-exclude rules
should be inserted as excludes in place of the "-C". No arg should
follow.
it() An bf(s) is used to indicate that the rule applies to the sending
side. When a rule affects the sending side, it prevents files from
being transferred. The default is for a rule to affect both sides
unless bf(--delete-excluded) was specified, in which case default rules
become sender-side only. See also the hide (H) and show (S) rules,
which are an alternate way to specify sending-side includes/excludes.
it() An bf(r) is used to indicate that the rule applies to the receiving
side. When a rule affects the receiving side, it prevents files from
being deleted. See the bf(s) modifier for more info. See also the
protect (P) and risk (R) rules, which are an alternate way to
specify receiver-side includes/excludes.
it() A bf(p) indicates that a rule is perishable, meaning that it is
ignored in directories that are being deleted. For instance, the bf(-C)
option's default rules that exclude things like "CVS" and "*.o" are
marked as perishable, and will not prevent a directory that was removed
on the source from being deleted on the destination.
)
manpagesection(MERGE-FILE FILTER RULES)
You can merge whole files into your filter rules by specifying either a
@@ -2397,46 +2463,13 @@ itemization(
"- foo + bar" is parsed as two rules (assuming that prefix-parsing wasn't
also disabled).
it() You may also specify any of the modifiers for the "+" or "-" rules
(below) in order to have the rules that are read in from the file
(above) in order to have the rules that are read in from the file
default to having that modifier set. For instance, "merge,-/ .excl" would
treat the contents of .excl as absolute-path excludes,
while "dir-merge,s .filt" and ":sC" would each make all their
per-directory rules apply only on the sending side.
)
The following modifiers are accepted after a "+" or "-":
itemization(
it() A bf(/) specifies that the include/exclude rule should be matched
against the absolute pathname of the current item. For example,
"-/ /etc/passwd" would exclude the passwd file any time the transfer
was sending files from the "/etc" directory, and "-/ subdir/foo"
would always exclude "foo" when it is in a dir named "subdir", even
if "foo" is at the root of the current transfer.
it() A bf(!) specifies that the include/exclude should take effect if
the pattern fails to match. For instance, "-! */" would exclude all
non-directories.
it() A bf(C) is used to indicate that all the global CVS-exclude rules
should be inserted as excludes in place of the "-C". No arg should
follow.
it() An bf(s) is used to indicate that the rule applies to the sending
side. When a rule affects the sending side, it prevents files from
being transferred. The default is for a rule to affect both sides
unless bf(--delete-excluded) was specified, in which case default rules
become sender-side only. See also the hide (H) and show (S) rules,
which are an alternate way to specify sending-side includes/excludes.
it() An bf(r) is used to indicate that the rule applies to the receiving
side. When a rule affects the receiving side, it prevents files from
being deleted. See the bf(s) modifier for more info. See also the
protect (P) and risk (R) rules, which are an alternate way to
specify receiver-side includes/excludes.
it() A bf(p) indicates that a rule is perishable, meaning that it is
ignored in directories that are being deleted. For instance, the bf(-C)
option's default rules that exclude things like "CVS" and "*.o" are
marked as perishable, and will not prevent a directory that was removed
on the source from being deleted on the destination.
)
Per-directory rules are inherited in all subdirectories of the directory
where the merge-file was found unless the 'n' modifier was used. Each
subdirectory's rules are prefixed to the inherited per-directory rules
@@ -2646,27 +2679,26 @@ of the destination trees. The write-batch option causes the rsync
client to store in a "batch file" all the information needed to repeat
this operation against other, identical destination trees.
To apply the recorded changes to another destination tree, run rsync
with the read-batch option, specifying the name of the same batch
file, and the destination tree. Rsync updates the destination tree
using the information stored in the batch file.
For convenience, one additional file is creating when the write-batch
option is used. This file's name is created by appending
".sh" to the batch filename. The .sh file contains
a command-line suitable for updating a destination tree using that
batch file. It can be executed using a Bourne (or Bourne-like) shell,
optionally
passing in an alternate destination tree pathname which is then used
instead of the original path. This is useful when the destination tree
path differs from the original destination tree path.
Generating the batch file once saves having to perform the file
status, checksum, and data block generation more than once when
updating multiple destination trees. Multicast transport protocols can
be used to transfer the batch update files in parallel to many hosts
at once, instead of sending the same data to every host individually.
To apply the recorded changes to another destination tree, run rsync
with the read-batch option, specifying the name of the same batch
file, and the destination tree. Rsync updates the destination tree
using the information stored in the batch file.
For your convenience, a script file is also created when the write-batch
option is used: it will be named the same as the batch file with ".sh"
appended. This script file contains a command-line suitable for updating a
destination tree using the associated batch file. It can be executed using
a Bourne (or Bourne-like) shell, optionally passing in an alternate
destination tree pathname which is then used instead of the original
destination path. This is useful when the destination tree path on the
current host differs from the one used to create the batch file.
Examples:
quote(
@@ -2758,9 +2790,9 @@ 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
Rsync can also distinguish "safe" and "unsafe" symbolic links. An
example where this might be used is a web site mirror that wishes to
ensure that the rsync module that is copied 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
@@ -2894,7 +2926,7 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
manpagesection(VERSION)
This man page is current for version 3.0.4 of rsync.
This man page is current for version 3.0.7 of rsync.
manpagesection(INTERNAL OPTIONS)
@@ -2927,7 +2959,7 @@ Jean-loup Gailly and Mark Adler.
manpagesection(THANKS)
Especial thanks go out to: John Van Essen, Matt McCutchen, Wesley W. Terpstra,
Special thanks go out to: John Van Essen, Matt McCutchen, Wesley W. Terpstra,
David Dykstra, Jos Backus, Sebastian Krahmer, Martin Pool, and our
gone-but-not-forgotten compadre, J.W. Schultz.

View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsyncd.conf)(5)(6 Sep 2008)()()
manpage(rsyncd.conf)(5)(31 Dec 2009)()()
manpagename(rsyncd.conf)(configuration file for rsync in daemon mode)
manpagesynopsis()
@@ -393,8 +393,8 @@ usernames and passwords are stored in the file specified by the
"secrets file" parameter. The default is for all users to be able to
connect without a password (this is called "anonymous rsync").
See also the "CONNECTING TO AN RSYNC DAEMON OVER A REMOTE SHELL
PROGRAM" section in bf(rsync)(1) for information on how handle an
See also the section entitled "USING RSYNC-DAEMON FEATURES VIA A REMOTE
SHELL CONNECTION" in bf(rsync)(1) for information on how handle an
rsyncd.conf-level username that differs from the remote-shell-level
username when using a remote shell to connect to an rsync daemon.
@@ -700,7 +700,7 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
manpagesection(VERSION)
This man page is current for version 3.0.4 of rsync.
This man page is current for version 3.0.7 of rsync.
manpagesection(CREDITS)

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +22,6 @@
#include "rsync.h"
extern int verbose;
extern int dry_run;
extern int do_xfers;
extern int am_server;
extern int am_daemon;
@@ -153,7 +152,7 @@ static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
if (iflags & ITEM_XNAME_FOLLOWS)
write_vstring(f_out, buf, len);
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && !dry_run)
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
send_xattr_request(fname, file, f_out);
#endif
}
@@ -174,6 +173,7 @@ void send_files(int f_in, int f_out)
int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i;
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
int f_xfer = write_batch < 0 ? batch_fd : f_out;
int save_io_error = io_error;
int ndx, j;
if (verbose > 2)
@@ -223,7 +223,7 @@ void send_files(int f_in, int f_out)
rprintf(FINFO, "send_files(%d, %s%s%s)\n", ndx, path,slash,fname);
#ifdef SUPPORT_XATTRS
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && !dry_run)
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
recv_xattr_request(file, f_in);
#endif
@@ -362,6 +362,9 @@ void send_files(int f_in, int f_out)
if (make_backups < 0)
make_backups = -make_backups;
if (io_error != save_io_error && protocol_version >= 30)
send_msg_int(MSG_IO_ERROR, io_error);
if (verbose > 2)
rprintf(FINFO, "send files finished\n");

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -578,7 +578,7 @@ void start_accept_loop(int port, int (*fn)(int, int))
fds = deffds;
#endif
if (select(maxfd + 1, &fds, NULL, NULL, NULL) != 1)
if (select(maxfd + 1, &fds, NULL, NULL, NULL) < 1)
continue;
for (i = 0, fd = -1; sp[i] >= 0; i++) {
@@ -823,6 +823,7 @@ static int socketpair_tcp(int fd[2])
**/
int sock_exec(const char *prog)
{
pid_t pid;
int fd[2];
if (socketpair_tcp(fd) != 0) {
@@ -831,14 +832,23 @@ int sock_exec(const char *prog)
}
if (verbose >= 2)
rprintf(FINFO, "Running socket program: \"%s\"\n", prog);
if (fork() == 0) {
pid = fork();
if (pid < 0) {
rsyserr(FERROR, errno, "fork");
exit_cleanup(RERR_IPC);
}
if (pid == 0) {
close(fd[0]);
close(0);
close(1);
dup(fd[1]);
dup(fd[1]);
if (dup2(fd[1], STDIN_FILENO) < 0
|| dup2(fd[1], STDOUT_FILENO) < 0) {
fprintf(stderr, "Failed to run \"%s\"\n", prog);
exit(1);
}
exit(system(prog));
}
close(fd[1]);
return fd[0];
}

View File

@@ -6,35 +6,49 @@
# more details and some important caveats!**
use strict;
use warnings;
use Cwd 'abs_path';
my $RSYNC_PROG = '/usr/bin/rsync';
my $RM_PROG = '/bin/rm';
my $dest_dir = $ARGV[-1];
usage(1) if $dest_dir eq '' || $dest_dir =~ /^--/;
&usage if !defined $dest_dir || $dest_dir =~ /(^-|^$)/ || grep(/^--help/, @ARGV);
$dest_dir =~ s{(?<=.)/+$} {};
if (!-d $dest_dir) {
print STDERR "$dest_dir is not a directory.\n\n";
usage(1);
die "$dest_dir is not a directory.\nUse --help for help.\n";
}
if (@_ = grep(/^--(link|compare)-dest/, @ARGV)) {
if (@_ = grep(/^--[a-z]+-dest\b/, @ARGV)) {
$_ = join(' or ', @_);
print STDERR "You may not use $_ as an rsync option.\n\n";
usage(1);
die "You cannot use the $_ option with atomic-rsync.\nUse --help for help.\n";
}
my $symlink_content = readlink $dest_dir; # undef when a real dir
my $dest_arg = $dest_dir;
# This gives us the real destination dir, with all symlinks dereferenced.
$dest_dir = abs_path($dest_dir);
if ($dest_dir eq '/') {
print STDERR 'You must not use "/" as the destination directory.', "\n\n";
usage(1);
die qq|You must not use "/" as the destination directory.\nUse --help for help.\n|;
}
my $old_dir = "$dest_dir~old~";
my $new_dir = $ARGV[-1] = "$dest_dir~new~";
my($old_dir, $new_dir);
if (defined $symlink_content && $dest_dir =~ /-([12])$/) {
my $num = 3 - $1;
$old_dir = undef;
($new_dir = $dest_dir) =~ s/-[12]$/-$num/;
$symlink_content =~ s/-[12]$/-$num/;
} else {
$old_dir = "$dest_dir~old~";
$new_dir = "$dest_dir~new~";
}
system($RM_PROG, '-rf', $old_dir) if -d $old_dir;
$ARGV[-1] = "$new_dir/";
system($RM_PROG, '-rf', $old_dir) if defined $old_dir && -d $old_dir;
system($RM_PROG, '-rf', $new_dir) if -d $new_dir;
if (system($RSYNC_PROG, "--link-dest=$dest_dir", @ARGV)) {
if ($? == -1) {
@@ -48,17 +62,30 @@ if (system($RSYNC_PROG, "--link-dest=$dest_dir", @ARGV)) {
exit $?;
}
rename($dest_dir, $old_dir) or die "Unable to rename $new_dir to $old_dir: $!";
if (!defined $old_dir) {
atomic_symlink($symlink_content, $dest_arg);
exit;
}
rename($dest_dir, $old_dir) or die "Unable to rename $dest_dir to $old_dir: $!";
rename($new_dir, $dest_dir) or die "Unable to rename $new_dir to $dest_dir: $!";
exit;
sub atomic_symlink
{
my($target, $link) = @_;
my $newlink = "$link~new~";
unlink($newlink); # Just in case
symlink($target, $newlink) or die "Unable to symlink $newlink -> $target: $!\n";
rename($newlink, $link) or die "Unable to rename $newlink to $link: $!\n";
}
sub usage
{
my($ret) = @_;
my $fh = $ret ? *STDERR : *STDOUT;
print $fh <<EOT;
die <<EOT;
Usage: atomic-rsync [RSYNC-OPTIONS] HOST:/SOURCE/DIR/ /DEST/DIR/
atomic-rsync [RSYNC-OPTIONS] HOST::MOD/DIR/ /DEST/DIR/
@@ -67,24 +94,29 @@ creating a new hierarchy (using hard-links to leverage the existing files),
and then swapping the new hierarchy into place. You must be pulling files
to a local directory, and that directory must already exist. For example:
mkdir /local/files-1
ln -s files-1 /local/files
atomic-rsync -av host:/remote/files/ /local/files/
This would make the transfer to the directory /local/files~new~ and then
swap out /local/files at the end of the transfer by renaming it to
/local/files~old~ and putting the new directory into its place. The
/local/files~old~ directory will be preserved until the next update, at
which point it will be deleted.
If /local/files is a symlink to a directory that ends in -1 or -2, the
copy will go to the alternate suffix and the symlink will be changed to
point to the new dir. This is a fully atomic update. If the destination
is not a symlink (or not a symlink to a *-1 or a *-2 directory), this
will instead create a directory with "~new~" suffixed, move the current
directory to a name with "~old~" suffixed, and then move the ~new~
directory to the original destination name (this double rename is not
fully atomic, but is rapid). In both cases, the prior destintaion
directory will be preserved until the next update, at which point it
will be deleted.
Do NOT specify this command:
In all likelihood, you do NOT want to specify this command:
atomic-rsync -av host:/remote/files /local/
... UNLESS you want the entire /local dir to be swapped out!
See the "rsync" command for its list of options. You may not use the
--link-dest or --compare-dest options (since this script uses --link-dest
to make the transfer efficient). Also, the destination directory cannot
be "/".
--link-dest, --compare-dest, or --copy-dest options (since this script
uses --link-dest to make the transfer efficient).
EOT
exit $ret;
}

View File

@@ -143,7 +143,8 @@ while ($command =~ /((?:[^\s\\]+|\\.[^\s\\]*)+)/g) {
if ($_ eq '.') {
$in_options = 0;
} else {
next if /^-$short_no_arg+(e\d*\.\w*)?$/o || /^-$short_with_num\d+$/o;
die "$0: invalid option: '-'\n" if $_ eq '-';
next if /^-$short_no_arg*(e\d*\.\w*)?$/o || /^-$short_with_num\d+$/o;
my($opt,$arg) = /^--([^=]+)(?:=(.*))?$/;
my $disabled;

View File

@@ -4,7 +4,7 @@
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -3,7 +3,7 @@
* functions, so that module test harnesses can run standalone.
*
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -2,7 +2,7 @@
* Test harness for unsafe_symlink(). Not linked into rsync itself.
*
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -41,6 +41,8 @@ runtest "--read-batch from daemon" 'checkit "$RSYNC -av --read-batch=BATCH \"$to
rm -rf "$todir"
runtest "BATCH.sh use of --read-batch" 'checkit "./BATCH.sh" "$chkdir" "$todir"'
runtest "do-nothing re-run of batch" 'checkit "./BATCH.sh" "$chkdir" "$todir"'
rm -rf "$todir"
mkdir "$todir" || test_fail "failed to restore empty destination directory"
runtest "daemon recv --write-batch" 'checkit "\"$ignore23\" $RSYNC -av --write-batch=BATCH \"$fromdir/\" rsync://localhost/test-to" "$chkdir" "$todir"'

View File

@@ -13,12 +13,19 @@
hands_setup
tmpdir2=/tmp
tmpdir2=$RSYNC_TEST_TMP
if [ x"$tmpdir2" = x ]; then
tmpdir2=/tmp
fi
sdev=`$TOOLDIR/getfsdev $scratchdir`
tdev=`$TOOLDIR/getfsdev $tmpdir2`
if [ x$sdev = x$tdev ]; then
tmpdir2=/var/tmp
tdev=`$TOOLDIR/getfsdev $tmpdir2`
if [ -d $tmpdir2 ]; then
tdev=`$TOOLDIR/getfsdev $tmpdir2`
else
tdev="$sdev"
fi
[ x$sdev = x$tdev ] && test_skipped "Can't find a tmp dir on a different file system"
fi

View File

@@ -37,7 +37,7 @@ case $0 in
;;
*)
RSYNC="$RSYNC --super"
case `id -u` in
case `get_testuid` in
'') ;; # If "id" failed, try to continue...
0) ;;
*) if [ -f /usr/bin/fakeroot ]; then

View File

@@ -25,6 +25,7 @@ chkfile="$scratchdir/rsync.chk"
outfile="$scratchdir/rsync.out"
SSH="src/support/lsh --no-cd"
FILE_REPL='s/^\([^d][^ ]*\) *\(..........[0-9]\) /\1 \2 /'
DIR_REPL='s/^\(d[^ ]*\) *[0-9][0-9]* /\1 DIR /'
LS_REPL='s;[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9];####/##/## ##:##:##;'
@@ -41,7 +42,7 @@ cd "$scratchdir"
ln -s test-rsyncd.conf rsyncd.conf
confopt=''
case `id -u` in
case `get_testuid` in
0)
# Root needs to specify the config file, or it uses /etc/rsyncd.conf.
echo "Forcing --config=$conf"
@@ -65,7 +66,7 @@ EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
$RSYNC -r localhost::test-hidden \
| sed "$DIR_REPL" | sed "$LS_REPL" \
| sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \
| tee "$outfile"
cat <<EOT >"$chkfile"
drwxr-xr-x DIR ####/##/## ##:##:## .
@@ -79,7 +80,7 @@ EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
$RSYNC -r localhost::test-from/f* \
| sed "$DIR_REPL" | sed "$LS_REPL" \
| sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \
| tee "$outfile"
cat <<EOT >"$chkfile"
drwxr-xr-x DIR ####/##/## ##:##:## foo

View File

@@ -51,7 +51,7 @@ case $0 in
esac
;;
*)
case `id -u` in
case `get_testuid` in
'') ;; # If "id" failed, try to continue...
0) ;;
*) if [ -f /usr/bin/fakeroot ]; then

30
testsuite/files-from.test Normal file
View File

@@ -0,0 +1,30 @@
#!/bin/sh
# Copyright (C) 2008 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that --files-from=FILE works right.
. "$suitedir/rsync.fns"
hands_setup
# This list of files skips the contents of "subsubdir" but includes
# the contents of "subsubdir2" due to its trailing slash.
cat >"$scratchdir/filelist" <<EOT
from/./
from/./dir/subdir
from/./dir/subdir/subsubdir
from/./dir/subdir/subsubdir2/
from/./dir/subdir/foobar.baz
EOT
# Create a chkdir without the content that we expect to be omitted.
$RSYNC -a --exclude=dir/text --exclude='subsubdir/**' "$fromdir/" "$chkdir/"
checkit "$RSYNC -av --files-from='$scratchdir/filelist' '$scratchdir' '$todir/'" "$chkdir" "$todir"
# The script would have aborted on error, so getting here means we've won.
exit 0

View File

@@ -100,6 +100,10 @@ rsync_ls_lR() {
find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls" $TLS_ARGS
}
get_testuid() {
id 2>/dev/null | sed 's/^[^0-9]*\([0-9][0-9]*\).*/\1/'
}
check_perms() {
perms=`"$TOOLDIR/tls" "$1" | sed 's/^[-d]\(.........\).*/\1/'`
if test $perms = $2; then

View File

@@ -18,7 +18,7 @@ if test x"$rsync_enable_ssh_tests" = xyes; then
fi
fi
if ! [ "`$SSH -o'BatchMode yes' localhost echo yes`" = "yes" ]; then
if [ "`$SSH -o'BatchMode yes' localhost echo yes`" != "yes" ]; then
test_skipped "Skipping SSH tests because ssh conection to localhost not authorised"
fi

View File

@@ -19,33 +19,41 @@ test_unsafe() {
fi
}
test_unsafe file from safe
test_unsafe dir/file from safe
test_unsafe dir/./file from safe
test_unsafe dir/. from safe
test_unsafe dir/ from safe
test_unsafe file from safe
test_unsafe dir/file from safe
test_unsafe dir/./file from safe
test_unsafe dir/. from safe
test_unsafe dir/ from safe
test_unsafe /etc/passwd from unsafe
test_unsafe //../etc/passwd from unsafe
test_unsafe //./etc/passwd from unsafe
test_unsafe /etc/passwd from unsafe
test_unsafe //../etc/passwd from unsafe
test_unsafe //./etc/passwd from unsafe
test_unsafe ./foo from safe
test_unsafe ../foo from unsafe
test_unsafe ../dest from/dir safe
test_unsafe ./foo from safe
test_unsafe ../foo from unsafe
test_unsafe ./../foo from unsafe
test_unsafe .//../foo from unsafe
test_unsafe ./../foo from/.. unsafe
test_unsafe ../dest from/dir safe
test_unsafe ../../dest from//dir unsafe
test_unsafe ..//../dest from/dir unsafe
test_unsafe .. from/file safe
test_unsafe ../.. from/file unsafe
test_unsafe dir/.. from safe
test_unsafe dir/../.. from unsafe
test_unsafe .. from/file safe
test_unsafe ../.. from/file unsafe
test_unsafe ..//.. from//file unsafe
test_unsafe dir/.. from safe
test_unsafe dir/../.. from unsafe
test_unsafe dir/..//.. from unsafe
test_unsafe '' from unsafe
test_unsafe '' from unsafe
# Based on tests from unsafe-links by Vladim<69>r Michl
test_unsafe ../../unsafe/unsafefile from/safe unsafe
test_unsafe ../files/file1 from/safe safe
test_unsafe ../../unsafe/unsafefile from/safe unsafe
test_unsafe ..//../unsafe/unsafefile from/safe unsafe
test_unsafe ../files/file1 from/safe safe
test_unsafe ../../unsafe/unsafefile safe unsafe
test_unsafe ../files/file1 safe unsafe
test_unsafe ../../unsafe/unsafefile safe unsafe
test_unsafe ../files/file1 safe unsafe
test_unsafe ../../unsafe/unsafefile `pwd`/from/safe safe
test_unsafe ../files/file1 `pwd`/from/safe safe
test_unsafe ../../unsafe/unsafefile `pwd`/from/safe safe
test_unsafe ../files/file1 `pwd`/from/safe safe

2
tls.c
View File

@@ -2,7 +2,7 @@
* Trivial ls for comparing two directories after running an rsync.
*
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

15
token.c
View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,12 +45,12 @@ static void add_suffix(struct suffix_tree **prior, char ltr, const char *str)
if (ltr == '[') {
const char *after = strchr(str, ']');
/* Just skip bogus character classes. */
if (!after++)
/* Treat "[foo" and "[]" as having a literal '['. */
if (after && after++ != str+1) {
while ((ltr = *str++) != ']')
add_suffix(prior, ltr, after);
return;
while ((ltr = *str++) != ']')
add_suffix(prior, ltr, after);
return;
}
}
for (node = *prior; node; prior = &node->sibling, node = node->sibling) {
@@ -100,7 +100,6 @@ static void add_nocompress_suffixes(const char *str)
} while (*++f != '/' && *f);
*t++ = '\0';
fprintf(stderr, "adding `%s'\n", buf);
add_suffix(&suftree, *buf, buf+1);
}
@@ -599,7 +598,7 @@ static void see_deflate_token(char *buf, int32 len)
rx_strm.next_out = (Bytef *)dbuf;
rx_strm.avail_out = AVAIL_OUT_SIZE(CHUNK_SIZE);
r = inflate(&rx_strm, Z_SYNC_FLUSH);
if (r != Z_OK) {
if (r != Z_OK && r != Z_BUF_ERROR) {
rprintf(FERROR, "inflate (token) returned %d\n", r);
exit_cleanup(RERR_STREAMIO);
}

View File

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

137
util.c
View File

@@ -4,7 +4,7 @@
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -806,7 +806,8 @@ int count_dir_elements(const char *p)
return cnt;
}
/* Turns multiple adjacent slashes into a single slash, drops all leading or
/* Turns multiple adjacent slashes into a single slash (possible exception:
* the preserving of two leading slashes at the start), drops all leading or
* interior "." elements unless CFN_KEEP_DOT_DIRS is flagged. Will also drop
* a trailing '.' after a '/' if CFN_DROP_TRAILING_DOT_DIR is flagged, removes
* a trailing slash (perhaps after removing the aforementioned dot) unless
@@ -821,9 +822,16 @@ unsigned int clean_fname(char *name, int flags)
if (!name)
return 0;
if ((anchored = *f == '/') != 0)
if ((anchored = *f == '/') != 0) {
*t++ = *f++;
else if (flags & CFN_KEEP_DOT_DIRS && *f == '.' && f[1] == '/') {
#ifdef __CYGWIN__
/* If there are exactly 2 slashes at the start, preserve
* them. Would break daemon excludes unless the paths are
* really treated differently, so used this sparingly. */
if (*f == '/' && f[1] != '/')
*t++ = *f++;
#endif
} else if (flags & CFN_KEEP_DOT_DIRS && *f == '.' && f[1] == '/') {
*t++ = *f++;
*t++ = *f++;
}
@@ -979,7 +987,10 @@ int change_dir(const char *dir, int set_path_only)
if (!initialised) {
initialised = 1;
getcwd(curr_dir, sizeof curr_dir - 1);
if (getcwd(curr_dir, sizeof curr_dir - 1) == NULL) {
rsyserr(FERROR, errno, "getcwd()");
exit_cleanup(RERR_FILESELECT);
}
curr_dir_len = strlen(curr_dir);
}
@@ -1025,6 +1036,34 @@ int change_dir(const char *dir, int set_path_only)
return 1;
}
/* This will make a relative path absolute and clean it up via clean_fname().
* Returns the string, which might be newly allocated, or NULL on error. */
char *normalize_path(char *path, BOOL force_newbuf, unsigned int *len_ptr)
{
unsigned int len;
if (*path != '/') { /* Make path absolute. */
int len = strlen(path);
if (curr_dir_len + 1 + len >= sizeof curr_dir)
return NULL;
curr_dir[curr_dir_len] = '/';
memcpy(curr_dir + curr_dir_len + 1, path, len + 1);
if (!(path = strdup(curr_dir)))
out_of_memory("normalize_path");
curr_dir[curr_dir_len] = '\0';
} else if (force_newbuf) {
if (!(path = strdup(path)))
out_of_memory("normalize_path");
}
len = clean_fname(path, CFN_COLLAPSE_DOT_DOT_DIRS | CFN_DROP_TRAILING_DOT_DIR);
if (len_ptr)
*len_ptr = len;
return path;
}
/**
* Return a quoted string with the full pathname of the indicated filename.
* The string " (in MODNAME)" may also be appended. The returned pointer
@@ -1129,12 +1168,13 @@ int handle_partial_dir(const char *fname, int create)
return 1;
}
/**
* Determine if a symlink points outside the current directory tree.
/* Determine if a symlink points outside the current directory tree.
* This is considered "unsafe" because e.g. when mirroring somebody
* else's machine it might allow them to establish a symlink to
* /etc/passwd, and then read it through a web server.
*
* Returns 1 if unsafe, 0 if safe.
*
* Null symlinks and absolute symlinks are always unsafe.
*
* Basically here we are concerned with symlinks whose target contains
@@ -1142,17 +1182,11 @@ int handle_partial_dir(const char *fname, int create)
* transferred directory. We are not allowed to go back up and
* reenter.
*
* @param dest Target of the symlink in question.
* "dest" is the target of the symlink in question.
*
* @param src Top source directory currently applicable. Basically this
* is the first parameter to rsync in a simple invocation, but it's
* modified by flist.c in slightly complex ways.
*
* @retval True if unsafe
* @retval False is unsafe
*
* @sa t_unsafe.c
**/
* "src" is the top source directory currently applicable at the level
* of the referenced symlink. This is usually the symlink's full path
* (including its name), as referenced from the root of the transfer. */
int unsafe_symlink(const char *dest, const char *src)
{
const char *name, *slash;
@@ -1164,33 +1198,33 @@ int unsafe_symlink(const char *dest, const char *src)
/* find out what our safety margin is */
for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
if (strncmp(name, "../", 3) == 0) {
depth = 0;
} else if (strncmp(name, "./", 2) == 0) {
/* nothing */
} else {
/* ".." segment starts the count over. "." segment is ignored. */
if (*name == '.' && (name[1] == '/' || (name[1] == '.' && name[2] == '/'))) {
if (name[1] == '.')
depth = 0;
} else
depth++;
}
while (slash[1] == '/') slash++; /* just in case src isn't clean */
}
if (strcmp(name, "..") == 0)
if (*name == '.' && name[1] == '.' && name[2] == '\0')
depth = 0;
for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
if (strncmp(name, "../", 3) == 0) {
/* if at any point we go outside the current directory
then stop - it is unsafe */
if (--depth < 0)
return 1;
} else if (strncmp(name, "./", 2) == 0) {
/* nothing */
} else {
if (*name == '.' && (name[1] == '/' || (name[1] == '.' && name[2] == '/'))) {
if (name[1] == '.') {
/* if at any point we go outside the current directory
then stop - it is unsafe */
if (--depth < 0)
return 1;
}
} else
depth++;
}
while (slash[1] == '/') slash++;
}
if (strcmp(name, "..") == 0)
if (*name == '.' && name[1] == '.' && name[2] == '\0')
depth--;
return (depth < 0);
return depth < 0;
}
#define HUMANIFY(mult) \
@@ -1593,6 +1627,39 @@ int bitbag_next_bit(struct bitbag *bb, int after)
return -1;
}
void flist_ndx_push(flist_ndx_list *lp, int ndx)
{
struct flist_ndx_item *item;
if (!(item = new(struct flist_ndx_item)))
out_of_memory("flist_ndx_push");
item->next = NULL;
item->ndx = ndx;
if (lp->tail)
lp->tail->next = item;
else
lp->head = item;
lp->tail = item;
}
int flist_ndx_pop(flist_ndx_list *lp)
{
struct flist_ndx_item *next;
int ndx;
if (!lp->head)
return -1;
ndx = lp->head->ndx;
next = lp->head->next;
free(lp->head);
lp->head = next;
if (!next)
lp->tail = NULL;
return ndx;
}
void *expand_item_list(item_list *lp, size_t item_size,
const char *desc, int incr)
{

View File

@@ -1,7 +1,7 @@
/*
* Test suite for the wildmatch code.
*
* Copyright (C) 2003-2008 Wayne Davison
* Copyright (C) 2003-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -3,7 +3,7 @@
* Written by Jay Fenlason, vaguely based on the ACLs patch.
*
* Copyright (C) 2004 Red Hat, Inc.
* Copyright (C) 2006-2008 Wayne Davison
* Copyright (C) 2006-2009 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -81,6 +81,8 @@ static char *namebuf = NULL;
static item_list empty_xattr = EMPTY_ITEM_LIST;
static item_list rsync_xal_l = EMPTY_ITEM_LIST;
static size_t prior_xattr_count = (size_t)-1;
/* ------------------------------------------------------------------------- */
static void rsync_xal_free(item_list *xalp)
@@ -724,13 +726,15 @@ void receive_xattr(struct file_struct *file, int f)
/* Turn the xattr data in stat_x into cached xattr data, setting the index
* values in the file struct. */
void cache_xattr(struct file_struct *file, stat_x *sxp)
void cache_tmp_xattr(struct file_struct *file, stat_x *sxp)
{
int ndx;
if (!sxp->xattr)
return;
if (prior_xattr_count == (size_t)-1)
prior_xattr_count = rsync_xal_l.count;
ndx = find_matching_xattr(sxp->xattr);
if (ndx < 0)
rsync_xal_store(sxp->xattr); /* adds item to rsync_xal_l */
@@ -738,6 +742,21 @@ void cache_xattr(struct file_struct *file, stat_x *sxp)
F_XATTR(file) = ndx;
}
void uncache_tmp_xattrs(void)
{
if (prior_xattr_count != (size_t)-1) {
item_list *xattr_item = rsync_xal_l.items;
item_list *xattr_start = xattr_item + prior_xattr_count;
xattr_item += rsync_xal_l.count;
rsync_xal_l.count = prior_xattr_count;
while (xattr_item-- > xattr_start) {
rsync_xal_free(xattr_item);
free(xattr_item->items);
}
prior_xattr_count = (size_t)-1;
}
}
static int rsync_xal_set(const char *fname, item_list *xalp,
const char *fnamecmp, stat_x *sxp)
{
@@ -970,7 +989,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
fst.st_mode &= (_S_IFMT | CHMOD_BITS);
fmode = new_mode & (_S_IFMT | CHMOD_BITS);
if (IS_DEVICE(fmode) || IS_SPECIAL(fmode)) {
if (IS_DEVICE(fmode)) {
uint32 *devp = F_RDEV_P(file);
rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
} else
@@ -981,7 +1000,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode)
| (S_ISDIR(fst.st_mode) ? 0700 : 0600);
if (fst.st_mode != mode)
do_chmod(fname, mode);
if (!IS_DEVICE(fst.st_mode) && !IS_SPECIAL(fst.st_mode))
if (!IS_DEVICE(fst.st_mode))
fst.st_rdev = 0; /* just in case */
if (mode == fmode && fst.st_rdev == rdev