mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-25 07:15:35 -04:00
Compare commits
187 Commits
v2.4.7pre2
...
v2.5.2pre1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10f83cf43d | ||
|
|
59ee743c5f | ||
|
|
d54765c442 | ||
|
|
91262d5d3e | ||
|
|
1c09c743b1 | ||
|
|
06ce139fcc | ||
|
|
fae5bb3183 | ||
|
|
6fe25398d6 | ||
|
|
909ce14fc4 | ||
|
|
935b920120 | ||
|
|
b31427cd4a | ||
|
|
e2e3379d79 | ||
|
|
6b1ef85dd8 | ||
|
|
92325ada0c | ||
|
|
1707e0f9e2 | ||
|
|
7ff701e816 | ||
|
|
2e3c141795 | ||
|
|
76f79ba748 | ||
|
|
9dd891bb28 | ||
|
|
99f106d1cf | ||
|
|
3816cae745 | ||
|
|
759c0627e1 | ||
|
|
e03dfae507 | ||
|
|
c7677b892a | ||
|
|
da7b63972d | ||
|
|
499957d9ba | ||
|
|
582250008b | ||
|
|
a9b31409d5 | ||
|
|
98355b8086 | ||
|
|
70ed474b38 | ||
|
|
4775934364 | ||
|
|
25f2cb3d6b | ||
|
|
154f9a3aca | ||
|
|
b9df3bf20c | ||
|
|
6abd193fe3 | ||
|
|
362099a512 | ||
|
|
fdfc3dc9f3 | ||
|
|
4937459225 | ||
|
|
be2f866b4c | ||
|
|
f08aacf7d6 | ||
|
|
4fa6112efe | ||
|
|
1623ba6889 | ||
|
|
766526c791 | ||
|
|
5c15e29f2b | ||
|
|
0413e1605f | ||
|
|
0e5a1f8352 | ||
|
|
e5a2b8544d | ||
|
|
736a6a291c | ||
|
|
6e69cff118 | ||
|
|
cf72f20426 | ||
|
|
d479210cee | ||
|
|
b781537597 | ||
|
|
ea1438dad8 | ||
|
|
d2e9d069b4 | ||
|
|
58379559cc | ||
|
|
b3e6c81565 | ||
|
|
a6a3c3df45 | ||
|
|
6e3d4c4045 | ||
|
|
ca60b701ee | ||
|
|
e24c0b98d7 | ||
|
|
f389ac80a9 | ||
|
|
50f2f002d9 | ||
|
|
9ec7528475 | ||
|
|
a8e2a43a09 | ||
|
|
eb06fa95e4 | ||
|
|
1db8b61de7 | ||
|
|
38c66db8d6 | ||
|
|
f8be7d4219 | ||
|
|
13e29995f5 | ||
|
|
7c583c7316 | ||
|
|
9fecec5e85 | ||
|
|
9e696bd468 | ||
|
|
6ab6d4bfc1 | ||
|
|
cb1bcc7ebb | ||
|
|
19ba7d6318 | ||
|
|
7753ca1f49 | ||
|
|
d52a796c39 | ||
|
|
60514d457c | ||
|
|
5bc00efe42 | ||
|
|
c45f3133bc | ||
|
|
fb47591de0 | ||
|
|
514d129c49 | ||
|
|
db843fc12d | ||
|
|
63787382d8 | ||
|
|
85d4d142d8 | ||
|
|
3cd2af41e4 | ||
|
|
b214eda4f0 | ||
|
|
0771727d41 | ||
|
|
a5d74a1876 | ||
|
|
23bf32f767 | ||
|
|
87a819edee | ||
|
|
27a1234874 | ||
|
|
51f289d1e6 | ||
|
|
d0d6dc61e8 | ||
|
|
d91c8c50d2 | ||
|
|
e20a4f84d6 | ||
|
|
bbd6f4ba8e | ||
|
|
2a951cd2f9 | ||
|
|
a538066d5a | ||
|
|
c10b0bdd50 | ||
|
|
431efc8979 | ||
|
|
2d6dbe290c | ||
|
|
c33e3e3967 | ||
|
|
71b3374bd5 | ||
|
|
de343e3cce | ||
|
|
384958ed3d | ||
|
|
1cd5beeb06 | ||
|
|
4c70e359d0 | ||
|
|
f9c3005bff | ||
|
|
9147074d8b | ||
|
|
7007bddaef | ||
|
|
2f8dc29182 | ||
|
|
6066594bbe | ||
|
|
40c0289176 | ||
|
|
acf1af0cd9 | ||
|
|
62791bdfa2 | ||
|
|
47f1218d69 | ||
|
|
1179355dab | ||
|
|
3d807132e4 | ||
|
|
42d0b4c280 | ||
|
|
d313ae7d23 | ||
|
|
28a69e25ea | ||
|
|
ad911a7ac3 | ||
|
|
5575de140d | ||
|
|
a5ce1eb1af | ||
|
|
76a78cd8bc | ||
|
|
0b25efc12a | ||
|
|
64cae087b6 | ||
|
|
b7cc59c503 | ||
|
|
7eb8d18a99 | ||
|
|
e7bf3e5e87 | ||
|
|
5aafd07b37 | ||
|
|
053f3a831d | ||
|
|
a2d2e5c047 | ||
|
|
dd3a922035 | ||
|
|
0e916c6038 | ||
|
|
87fcb63975 | ||
|
|
68b2cc5538 | ||
|
|
4dcf3697ff | ||
|
|
ea77525546 | ||
|
|
17d5a07ec2 | ||
|
|
3966b9c609 | ||
|
|
1c47fbd96b | ||
|
|
1691bdcafc | ||
|
|
6a5ef41fb3 | ||
|
|
09b6f4b00d | ||
|
|
7067b0aa28 | ||
|
|
112e731150 | ||
|
|
1336e41460 | ||
|
|
7c1b7890d3 | ||
|
|
dd0700b025 | ||
|
|
04d8e8b25f | ||
|
|
3723efcb1d | ||
|
|
054b40b6fa | ||
|
|
6773a7798f | ||
|
|
2d4c8e5945 | ||
|
|
087173c887 | ||
|
|
57835c00ad | ||
|
|
4ed886ae6e | ||
|
|
740819ef7b | ||
|
|
829230689e | ||
|
|
77ba4cc2f9 | ||
|
|
e94989fe4d | ||
|
|
c11b88061f | ||
|
|
647c5433f8 | ||
|
|
8f694072a5 | ||
|
|
9a689986c6 | ||
|
|
3174b31d96 | ||
|
|
4eb61975b7 | ||
|
|
76e26e1042 | ||
|
|
9069dfd005 | ||
|
|
2be5d2daad | ||
|
|
22cd0063e5 | ||
|
|
3d2e458a4d | ||
|
|
a57568d716 | ||
|
|
61f543cade | ||
|
|
b8771f9615 | ||
|
|
d5d4b28220 | ||
|
|
a037edaccd | ||
|
|
356bbb8351 | ||
|
|
1f0fa9318a | ||
|
|
15c1707887 | ||
|
|
9dec7aa9c1 | ||
|
|
bc3d7454e0 | ||
|
|
56901bc7c3 | ||
|
|
5c7f570b16 | ||
|
|
4f6e5fe323 |
@@ -1,3 +1,4 @@
|
||||
testtmp.*
|
||||
ID
|
||||
Makefile
|
||||
config.cache
|
||||
|
||||
27
INSTALL
27
INSTALL
@@ -13,3 +13,30 @@ As of 2.4.7, rsync uses Eric Troan's popt option-parsing library. A
|
||||
cut-down copy of release 1.5 is included in the rsync distribution,
|
||||
and will be used it there is no popt library on your build host, or if
|
||||
the --with-included-popt option is passed to ./configure.
|
||||
|
||||
|
||||
|
||||
HP-UX NOTES
|
||||
-----------
|
||||
|
||||
The HP-UX 10.10 "bundled" C compiler seems not to be able to cope with
|
||||
ANSI C. You may see this error message in config.log if ./configure
|
||||
fails:
|
||||
|
||||
(Bundled) cc: "configure", line 2162: error 1705: Function prototypes are an ANSI feature.
|
||||
|
||||
Install gcc or HP's "ANSI/C Compiler".
|
||||
|
||||
|
||||
|
||||
MAC OSX NOTES
|
||||
-------------
|
||||
|
||||
Mac OS X (Darwin) seems to have an IPv6 stack, but it does not
|
||||
completely implement the "New Sockets" API.
|
||||
|
||||
<http://www.ipv6.org/impl/mac.html> says that Apple do not support
|
||||
IPv6 yet. If your build fails, try again with --disable-ipv6.
|
||||
|
||||
|
||||
|
||||
|
||||
21
Makefile.in
21
Makefile.in
@@ -23,6 +23,7 @@ VERSION=@VERSION@
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
LIBOBJ=lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
|
||||
lib/permstring.o \
|
||||
@LIBOBJS@
|
||||
ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
|
||||
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
|
||||
@@ -34,7 +35,7 @@ popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
|
||||
popt/popthelp.o popt/poptparse.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
|
||||
|
||||
tls_OBJ = tls.o syscall.o
|
||||
tls_OBJ = tls.o syscall.o lib/permstring.o
|
||||
|
||||
# Programs we must have to run the test cases
|
||||
CHECK_PROGS = rsync tls
|
||||
@@ -61,8 +62,11 @@ install-strip:
|
||||
$(MAKE) INSTALLCMD='$(INSTALLCMD) -s' install
|
||||
|
||||
rsync: $(OBJS)
|
||||
@echo "Please ignore warnings below about mktemp -- it is used in a safe way"
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
|
||||
|
||||
$(OBJS): config.h
|
||||
|
||||
tls: $(tls_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(tls_OBJ) $(LIBS)
|
||||
|
||||
@@ -83,17 +87,12 @@ proto:
|
||||
cat *.c lib/compat.c | awk -f mkproto.awk > proto.h
|
||||
|
||||
clean:
|
||||
rm -f *~ $(OBJS) rsync
|
||||
rm -f *~ $(OBJS) rsync $(TLS_OBJ) tls
|
||||
rm -rf ./testtmp
|
||||
rm -f config.cache
|
||||
|
||||
distclean: clean
|
||||
rm -f config.h config.cache config.status Makefile
|
||||
|
||||
# missing functions
|
||||
getaddrinfo.o: lib/getaddrinfo.c
|
||||
$(CC) -I. -I$(srcdir) -I$(srcdir)/lib $(CFLAGS) -c lib/getaddrinfo.c
|
||||
getnameinfo.o: lib/getnameinfo.c
|
||||
$(CC) -I. -I$(srcdir) -I$(srcdir)/lib $(CFLAGS) -c lib/getnameinfo.c
|
||||
rm -f Makefile config.h config.status
|
||||
|
||||
# this target is really just for my use. It only works on a limited
|
||||
# range of machines and is used to produce a list of potentially
|
||||
@@ -123,13 +122,13 @@ test: check
|
||||
# might lose in the future where POSIX diverges from old sh.
|
||||
|
||||
check: all $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 rsync_bin=`pwd`/rsync srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin=`pwd`/rsync srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
|
||||
# This does *not* depend on building or installing: you can use it to
|
||||
# check a version installed from a binary or some other source tree,
|
||||
# if you want.
|
||||
|
||||
installcheck: $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 rsync_bin="$(bindir)/rsync" srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin="$(bindir)/rsync" srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
|
||||
# TODO: Add 'dist' target; need to know which files will be included
|
||||
|
||||
84
NEWS
84
NEWS
@@ -1,77 +1,29 @@
|
||||
rsync 2.4.7 (sometime in 2001, maybe :)
|
||||
rsync 2.5.2 (???)
|
||||
|
||||
ANNOUNCEMENTS
|
||||
SECURITY FIXES:
|
||||
|
||||
* Martin Pool <mbp@samba.org> is now a co-maintainer.
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
* Support for LSB-compliant packaging <http://www.linuxbase.org/>
|
||||
|
||||
* Shell wildcards are allowed in "auth users" lines.
|
||||
|
||||
* Merged UNC rsync+ patch to support creation of standalone patch
|
||||
sets. By Bert J. Dempsey and Debra Weiss, updated by Jos
|
||||
Backus. <http://www.ils.unc.edu/i2dsi/unc_rsync+.html>
|
||||
|
||||
* Merged IPv6 patch from KAME.net.
|
||||
|
||||
ENHANCEMENTS
|
||||
|
||||
* Include/exclude cluestick: with -vv, print out whether files are
|
||||
included or excluded and why.
|
||||
|
||||
* Many error messages have more friendly explanations and more
|
||||
details.
|
||||
|
||||
* Manual page improvements plus scanty protocol documentation.
|
||||
|
||||
* When running as --daemon in the background and using a "log
|
||||
file" rsyncd.conf directive, close the log file every time it is
|
||||
open when going to sleep on the socket. This allows the log
|
||||
file to get cleaned out by another process.
|
||||
|
||||
* Change to using libpopt rather than getopt for processing
|
||||
options. This makes the code cleaner and the behaviour more
|
||||
consistent across platforms. popt is included and built if not
|
||||
installed on the platform.
|
||||
|
||||
* More details in --version, including note about whether 64-bit
|
||||
files, symlinks and hardlinks are supported.
|
||||
|
||||
* MD4 code may use less CPU cycles.
|
||||
|
||||
* Use mkstemp on systems where it is secure. If we use mktemp,
|
||||
explain that we do it in a secure way.
|
||||
|
||||
* --whole-file is the default when source and target are on the
|
||||
local machine.
|
||||
* Signedness security patch from Sebastian Krahmer
|
||||
<krahmer@suse.de> -- in some cases we were not sufficiently
|
||||
careful about reading integers from the network.
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix for various bugs causing rsync to hang.
|
||||
* Fix possible string mangling in log files.
|
||||
|
||||
* Attempt to fix Large File Summit support on AIX.
|
||||
* Fix for setting local address of outgoing sockets.
|
||||
|
||||
* Attempt to fix error handling lockup bug.
|
||||
* Better handling of hardlinks and devices on platforms with
|
||||
64-bit dev_t or ino_t.
|
||||
|
||||
* Give a non-0 exit code if *any* of the files we have been asked
|
||||
to transfer fail to transfer
|
||||
ENHANCEMENTS:
|
||||
|
||||
* For log messages containing ridiculously long strings that might
|
||||
overflow a buffer rsync no longer aborts, but rather prints an
|
||||
ellipsis at the end of the string. (Patch from Ed Santiago.)
|
||||
* --statistics now shows memory heap usage on platforms that
|
||||
support mallinfo().
|
||||
|
||||
PLATFORMS:
|
||||
|
||||
* Improved support for UNICOS (tested on Cray T3E and Cray SV1)
|
||||
|
||||
* autoconf2.52 (or later) is now required to rebuild the autoconf
|
||||
scripts. It is not required to simply build rsync.
|
||||
|
||||
TESTING:
|
||||
|
||||
* The existing test.sh script by Phil Hands has been merged into a
|
||||
test framework that works from both "make check" and the Samba
|
||||
build farm.
|
||||
* "The Ted T'so school of program optimization": make progress
|
||||
visible and people will think it's faster. (With --progress,
|
||||
rsync will show you how many files it has seen as it builds the
|
||||
file_list, giving some indication that it has not hung.)
|
||||
|
||||
* Improvements to batch mode support. This is still experimental
|
||||
but testing would be welcome. (Jos Backus)
|
||||
|
||||
148
OLDNEWS
Normal file
148
OLDNEWS
Normal file
@@ -0,0 +1,148 @@
|
||||
rsync 2.5.1 (2002-01-03)
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix for segfault in --daemon mode configuration parser. (Paul
|
||||
Mackerras)
|
||||
|
||||
* Correct string<->address parsing for both IPv4 and 6.
|
||||
(YOSHIFUJI Hideaki, SUMIKAWA Munechika and Jun-ichiro "itojun"
|
||||
Hagino)
|
||||
|
||||
* Various fixes for IPv6 support. (Dave Dykstra)
|
||||
|
||||
* rsync.1 typo fix. (Matt Kraai)
|
||||
|
||||
* Test suite typo fixes. (Tom Schmidt)
|
||||
|
||||
* rsync.1 grammar and clarity improvements. (Edward
|
||||
Welbourne)
|
||||
|
||||
* Correction to ./configure tests for inet_ntop. (Jeff Garzik)
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* --progress and -P now show estimated data transfer rate (in a
|
||||
multiple of bytes/s) and estimated time to completion. (Rik
|
||||
Faith)
|
||||
|
||||
* --no-detach option, required to run as a W32 service and also
|
||||
useful when running on Unix under daemontools, AIX's SRC, or a
|
||||
debugger. (Max Bowsher, Jos Backus)
|
||||
|
||||
* Clearer error messages for some conditions.
|
||||
|
||||
rsync 2.5.0 (2001-11-30)
|
||||
|
||||
ANNOUNCEMENTS
|
||||
|
||||
* Martin Pool <mbp@samba.org> is now a co-maintainer.
|
||||
|
||||
NEW FEATURES
|
||||
|
||||
* Support for LSB-compliant packaging <http://www.linuxbase.org/>
|
||||
|
||||
* Shell wildcards are allowed in "auth users" lines.
|
||||
|
||||
* Merged UNC rsync+ patch to support creation of standalone patch
|
||||
sets. By Bert J. Dempsey and Debra Weiss, updated by Jos
|
||||
Backus. <http://www.ils.unc.edu/i2dsi/unc_rsync+.html>
|
||||
|
||||
* IPv6 support based on a patch from KAME.net, on systems
|
||||
including modern versions of Linux, Solaris, and HP-UX. Also
|
||||
includes IPv6 compatibility functions for old OSs by the
|
||||
Internet Software Consortium, Paul Vixie, the OpenSSH
|
||||
portability project, and OpenBSD.
|
||||
|
||||
ENHANCEMENTS
|
||||
|
||||
* Include/exclude cluestick: with -vv, print out whether files are
|
||||
included or excluded and why.
|
||||
|
||||
* Many error messages have more friendly explanations and more
|
||||
details.
|
||||
|
||||
* Manual page improvements plus scanty protocol documentation.
|
||||
|
||||
* When running as --daemon in the background and using a "log
|
||||
file" rsyncd.conf directive, close the log file every time it is
|
||||
open when going to sleep on the socket. This allows the log
|
||||
file to get cleaned out by another process.
|
||||
|
||||
* Change to using libpopt rather than getopt for processing
|
||||
options. This makes the code cleaner and the behaviour more
|
||||
consistent across platforms. popt is included and built if not
|
||||
installed on the platform.
|
||||
|
||||
* More details in --version, including note about whether 64-bit
|
||||
files, symlinks and hardlinks are supported.
|
||||
|
||||
* MD4 code may use less CPU cycles.
|
||||
|
||||
* Use mkstemp on systems where it is secure. If we use mktemp,
|
||||
explain that we do it in a secure way.
|
||||
|
||||
* --whole-file is the default when source and target are on the
|
||||
local machine.
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix for various bugs causing rsync to hang.
|
||||
|
||||
* Attempt to fix Large File Summit support on AIX.
|
||||
|
||||
* Attempt to fix error handling lockup bug.
|
||||
|
||||
* Give a non-0 exit code if *any* of the files we have been asked
|
||||
to transfer fail to transfer
|
||||
|
||||
* For log messages containing ridiculously long strings that might
|
||||
overflow a buffer rsync no longer aborts, but rather prints an
|
||||
ellipsis at the end of the string. (Patch from Ed Santiago.)
|
||||
|
||||
PLATFORMS:
|
||||
|
||||
* Improved support for UNICOS (tested on Cray T3E and Cray SV1)
|
||||
|
||||
* autoconf2.52 (or later) is now required to rebuild the autoconf
|
||||
scripts. It is not required to simply build rsync.
|
||||
|
||||
* Platforms thought to work in this release:
|
||||
|
||||
Cray SV1 UNICOS 10.0.0.8 cc
|
||||
Debian Linux 2.2 UltraSparc gcc
|
||||
Debian Linux testing/unstable ARM gcc
|
||||
FreeBSD 3.3-RELEASE i386 cc
|
||||
FreeBSD 4.1.1-RELEASE i386 cc
|
||||
FreeBSD 4.3-STABLE i386 cc
|
||||
HP PA-RISC HP-UX 10.20 gcc
|
||||
HP PA-RISC HP-UX 11.11 cc
|
||||
IRIX 6.5 MIPS cc
|
||||
IRIX 6.5 MIPS gcc
|
||||
Mac OS X PPC (--disable-ipv6) cc
|
||||
NetBSD 1.5 i386 gcc
|
||||
NetBSD Current i386 cc
|
||||
OpenBSD 2.5 Sparc gcc
|
||||
OpenBSD 2.9 i386 cc
|
||||
OpenBSD Current i386 cc
|
||||
RedHat 6.2 i386 gcc
|
||||
RedHat 6.2 i386 insure++
|
||||
RedHat 7.0 i386 gcc
|
||||
RedHat 7.1 i386 (Kernel 2.4.10) gcc
|
||||
Slackware 8.0 i686 (Kernel 2.4.10)
|
||||
Solaris 8 UltraSparc cc
|
||||
Solaris 8 UltraSparc gcc
|
||||
Solaris 8 i386 gcc
|
||||
SuSE 7.1 i386 gcc2.95.2
|
||||
SuSE 7.1 ppc gcc2.95.2
|
||||
i386-pc-sco3.2v5.0.5 cc
|
||||
i386-pc-sco3.2v5.0.5 gcc
|
||||
powerpc-ibm-aix4.3.3.0 cc
|
||||
i686-unknown-sysv5UnixWare7.1.0 gcc
|
||||
i686-unknown-sysv5UnixWare7.1.0 cc
|
||||
|
||||
TESTING:
|
||||
|
||||
* The existing test.sh script by Phil Hands has been merged into a
|
||||
test framework that works from both "make check" and the Samba
|
||||
build farm.
|
||||
13
README
13
README
@@ -143,9 +143,7 @@ This will give you access to the bug tracking system used by the
|
||||
developers of rsync and will allow you to look at other bug reports or
|
||||
submit a new bug report.
|
||||
|
||||
If you don't have web access then mail bug reports to
|
||||
rsync-bugs@samba.org or (if you think it will be of interest to lots
|
||||
of people) send it to rsync@samba.org
|
||||
If you don't have web access then mail bug reports to rsync@samba.org.
|
||||
|
||||
|
||||
CVS TREE
|
||||
@@ -167,11 +165,12 @@ details.
|
||||
COPYRIGHT
|
||||
---------
|
||||
|
||||
Rsync was written by Andrew Tridgell and Paul Mackerras, and is
|
||||
available under the GNU General Public License.
|
||||
rsync was originally written by Andrew Tridgell and has been improved
|
||||
by many developers around the world. rsync may be used, modified and
|
||||
redistributed only under the terms of the GNU General Public License,
|
||||
found in the file COPYING in this distribution, or at
|
||||
|
||||
tridge@samba.org
|
||||
paulus@cs.anu.edu.au
|
||||
http://www.fsf.org/licenses/gpl.html
|
||||
|
||||
|
||||
AVAILABILITY
|
||||
|
||||
280
TODO
280
TODO
@@ -16,21 +16,284 @@ Cross-test versions
|
||||
some testing and also be the most common case for having different
|
||||
versions and not being able to upgrade.
|
||||
|
||||
use chroot
|
||||
|
||||
If the platform doesn't support it, then don't even try.
|
||||
|
||||
If running as non-root, then don't fail, just give a warning.
|
||||
(There was a thread about this a while ago?)
|
||||
|
||||
http://lists.samba.org/pipermail/rsync/2001-August/thread.html
|
||||
http://lists.samba.org/pipermail/rsync/2001-September/thread.html
|
||||
|
||||
--files-from
|
||||
|
||||
Avoids traversal. Better option than a pile of --include statements
|
||||
for people who want to generate the file list using a find(1)
|
||||
command or a script.
|
||||
|
||||
|
||||
Performance
|
||||
|
||||
Traverse just one directory at a time. Tridge says it's possible.
|
||||
|
||||
At the moment rsync reads the whole file list into memory at the
|
||||
start, which makes us use a lot of memory and also not pipeline
|
||||
network access as much as we could.
|
||||
|
||||
|
||||
Handling duplicate names
|
||||
|
||||
We need to be careful of duplicate names getting into the file list.
|
||||
See clean_flist(). This could happen if multiple arguments include
|
||||
the same file. Bad.
|
||||
|
||||
I think duplicates are only a problem if they're both flowing
|
||||
through the pipeline at the same time. For example we might have
|
||||
updated the first occurrence after reading the checksums for the
|
||||
second. So possibly we just need to make sure that we don't have
|
||||
both in the pipeline at the same time.
|
||||
|
||||
Possibly if we did one directory at a time that would be sufficient.
|
||||
|
||||
Alternatively we could pre-process the arguments to make sure no
|
||||
duplicates will ever be inserted. There could be some bad cases
|
||||
when we're collapsing symlinks.
|
||||
|
||||
We could have a hash table.
|
||||
|
||||
The root of the problem is that we do not want more than one file
|
||||
list entry referring to the same file. At first glance there are
|
||||
several ways this could happen: symlinks, hardlinks, and repeated
|
||||
names on the command line.
|
||||
|
||||
If names are repeated on the command line, they may be present in
|
||||
different forms, perhaps by traversing directory paths in different
|
||||
ways, traversing paths including symlinks. Also we need to allow
|
||||
for expansion of globs by rsync.
|
||||
|
||||
At the moment, clean_flist() requires having the entire file list in
|
||||
memory. Duplicate names are detected just by a string comparison.
|
||||
|
||||
We don't need to worry about hard links causing duplicates because
|
||||
files are never updated in place. Similarly for symlinks.
|
||||
|
||||
I think even if we're using a different symlink mode we don't need
|
||||
to worry.
|
||||
|
||||
Unless we're really clever this will introduce a protocol
|
||||
incompatibility, so we need to be able to accept the old format as
|
||||
well.
|
||||
|
||||
|
||||
Memory accounting
|
||||
|
||||
At exit, show how much memory was used for the file list, etc.
|
||||
|
||||
Also we do a wierd exponential-growth allocation in flist.c. I'm
|
||||
not sure this makes sense with modern mallocs. At any rate it will
|
||||
make us allocate a huge amount of memory for large file lists.
|
||||
|
||||
We can try using the GNU/SVID/XPG mallinfo() function to get some
|
||||
heap statistics.
|
||||
|
||||
|
||||
Hard-link handling
|
||||
|
||||
At the moment hardlink handling is very expensive, so it's off by
|
||||
default. It does not need to be so.
|
||||
|
||||
Since most of the solutions are rather intertwined with the file
|
||||
list it is probably better to fix that first, although fixing
|
||||
hardlinks is possibly simpler.
|
||||
|
||||
We can rule out hardlinked directories since they will probably
|
||||
screw us up in all kinds of ways. They simply should not be used.
|
||||
|
||||
At the moment rsync only cares about hardlinks to regular files. I
|
||||
guess you could also use them for sockets, devices and other beasts,
|
||||
but I have not seen them.
|
||||
|
||||
When trying to reproduce hard links, we only need to worry about
|
||||
files that have more than one name (nlinks>1 && !S_ISDIR).
|
||||
|
||||
The basic point of this is to discover alternate names that refer to
|
||||
the same file. All operations, including creating the file and
|
||||
writing modifications to it need only to be done for the first name.
|
||||
For all later names, we just create the link and then leave it
|
||||
alone.
|
||||
|
||||
If hard links are to be preserved:
|
||||
|
||||
Before the generator/receiver fork, the list of files is received
|
||||
from the sender (recv_file_list), and a table for detecting hard
|
||||
links is built.
|
||||
|
||||
The generator looks for hard links within the file list and does
|
||||
not send checksums for them, though it does send other metadata.
|
||||
|
||||
The sender sends the device number and inode with file entries, so
|
||||
that files are uniquely identified.
|
||||
|
||||
The receiver goes through and creates hard links (do_hard_links)
|
||||
after all data has been written, but before directory permissions
|
||||
are set.
|
||||
|
||||
At the moment device and inum are sent as 4-byte integers, which
|
||||
will probably cause problems on large filesystems. On Linux the
|
||||
kernel uses 64-bit ino_t's internally, and people will soon have
|
||||
filesystems big enough to use them. We ought to follow NFS4 in
|
||||
using 64-bit device and inode identification, perhaps with a
|
||||
protocol version bump.
|
||||
|
||||
Once we've seen all the names for a particular file, we no longer
|
||||
need to think about it and we can deallocate the memory.
|
||||
|
||||
We can also have the case where there are links to a file that are
|
||||
not in the tree being transferred. There's nothing we can do about
|
||||
that. Because we rename the destination into place after writing,
|
||||
any hardlinks to the old file are always going to be orphaned. In
|
||||
fact that is almost necessary because otherwise we'd get really
|
||||
confused if we were generating checksums for one name of a file and
|
||||
modifying another.
|
||||
|
||||
At the moment the code seems to make a whole second copy of the file
|
||||
list, which seems unnecessary.
|
||||
|
||||
We should have a test case that exercises hard links. Since it
|
||||
might be hard to compare ./tls output where the inodes change we
|
||||
might need a little program to check whether several names refer to
|
||||
the same file.
|
||||
|
||||
IPv6
|
||||
|
||||
Implement suggestions from http://www.kame.net/newsletter/19980604/
|
||||
and ftp://ftp.iij.ad.jp/pub/RFC/rfc2553.txt
|
||||
|
||||
If a host has multiple addresses, then listen try to connect to all
|
||||
in order until we get through. (getaddrinfo may return multiple
|
||||
addresses.) This is kind of implemented already.
|
||||
|
||||
Possibly also when starting as a server we may need to listen on
|
||||
multiple passive addresses. This might be a bit harder, because we
|
||||
may need to select on all of them. Hm.
|
||||
|
||||
Define a syntax for IPv6 literal addresses. Since they include
|
||||
colons, they tend to break most naming systems, including ours.
|
||||
Based on the HTTP IPv6 syntax, I think we should use
|
||||
|
||||
rsync://[::1]/foo/bar
|
||||
[::1]::bar
|
||||
|
||||
which should just take a small change to the parser code.
|
||||
|
||||
Errors
|
||||
|
||||
If we hang or get SIGINT, then explain where we were up to. Perhaps
|
||||
have a static buffer that contains the current function name, or
|
||||
some kind of description of what we were trying to do. This is a
|
||||
little easier on people than needing to run strace/truss.
|
||||
|
||||
"The dungeon collapses! You are killed." Rather than "unexpected
|
||||
eof" give a message that is more detailed if possible and also more
|
||||
helpful.
|
||||
|
||||
File attributes
|
||||
|
||||
Device major/minor numbers should be at least 32 bits each. See
|
||||
http://lists.samba.org/pipermail/rsync/2001-November/005357.html
|
||||
|
||||
Transfer ACLs. Need to think of a standard representation.
|
||||
Probably better not to even try to convert between NT and POSIX.
|
||||
Possibly can share some code with Samba.
|
||||
|
||||
Empty directories
|
||||
|
||||
With the current common --include '*/' --exclude '*' pattern, people
|
||||
can end up with many empty directories. We might avoid this by
|
||||
lazily creating such directories.
|
||||
|
||||
zlib
|
||||
|
||||
Perhaps don't use our own zlib. Will we actually be incompatible,
|
||||
or just be slightly less efficient?
|
||||
|
||||
logging
|
||||
|
||||
Perhaps flush stdout after each filename, so that people trying to
|
||||
monitor progress in a log file can do so more easily. See
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
|
||||
|
||||
rsyncd over ssh
|
||||
|
||||
There are already some patches to do this.
|
||||
|
||||
proxy authentication
|
||||
|
||||
Allow RSYNC_PROXY to be http://user:pass@proxy.foo:3128/, and do
|
||||
HTTP Basic Proxy-Authentication.
|
||||
|
||||
Multiple schemes are possible, up to and including the insanity that
|
||||
is NTLM, but Basic probably covers most cases.
|
||||
|
||||
SOCKS
|
||||
|
||||
Add --with-socks, and then perhaps a command-line option to put them
|
||||
on or off. This might be more reliable than LD_PRELOAD hacks.
|
||||
|
||||
PLATFORMS ------------------------------------------------------------
|
||||
|
||||
Win32
|
||||
|
||||
Don't detach, because this messes up --srvany.
|
||||
|
||||
http://sources.redhat.com/ml/cygwin/2001-08/msg00234.html
|
||||
|
||||
According to "Effective TCP/IP Programming" (??) close() on a socket
|
||||
has incorrect behaviour on Windows -- it sends a RST packet to the
|
||||
other side, which gives a "connection reset by peer" error. On that
|
||||
platform we should probably do shutdown() instead. However, on Unix
|
||||
we are correct to call close(), because shutdown() discards
|
||||
untransmitted data.
|
||||
|
||||
DOCUMENTATION --------------------------------------------------------
|
||||
|
||||
Update README
|
||||
|
||||
BUILD FARM -----------------------------------------------------------
|
||||
|
||||
Add machines
|
||||
|
||||
AMDAHL UTS (Dave Dykstra)
|
||||
|
||||
Cygwin (on different versions of Win32?)
|
||||
|
||||
HP-UX variants (via HP?)
|
||||
|
||||
SCO
|
||||
|
||||
NICE -----------------------------------------------------------------
|
||||
|
||||
Merge IPv6 support ***
|
||||
--no-detach and --no-fork options
|
||||
|
||||
A patch is available at
|
||||
Very useful for debugging. Also good when running under a
|
||||
daemon-monitoring process that tries to restart the service when the
|
||||
parent exits.
|
||||
|
||||
ftp://ftp.kame.net/pub/kame/misc/rsync-244-v6-20000802.diff.gz
|
||||
hang/timeout friendliness
|
||||
|
||||
but tridge reckons it needs to be cleaned up before it can be
|
||||
accepted.
|
||||
verbose output
|
||||
|
||||
Indicate whether files are new, updated, or deleted
|
||||
|
||||
This is now on the track-kameipv6 branch and can be moved across any
|
||||
time. The KAME people say that it should work on machines without
|
||||
IPv6 stacks.
|
||||
internationalization
|
||||
|
||||
Change to using gettext(). Probably need to ship this for platforms
|
||||
that don't have it.
|
||||
|
||||
Solicit translations.
|
||||
|
||||
Does anyone care?
|
||||
|
||||
rsyncsh
|
||||
|
||||
@@ -40,3 +303,4 @@ rsyncsh
|
||||
current host, directory and so on. We can probably even do
|
||||
completion of remote filenames.
|
||||
|
||||
%K%
|
||||
|
||||
4
aclocal.m4
vendored
4
aclocal.m4
vendored
@@ -43,8 +43,8 @@ AC_DEFUN([TYPE_SOCKLEN_T],
|
||||
for arg2 in "struct sockaddr" void; do
|
||||
for t in int size_t unsigned long "unsigned long"; do
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int getpeername (int, $arg2 *, $t *);
|
||||
],[
|
||||
|
||||
@@ -45,6 +45,7 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
extern char *shell_cmd;
|
||||
extern int kludge_around_eof;
|
||||
extern char *bind_address;
|
||||
extern int default_af_hint;
|
||||
|
||||
if (argc == 0 && !am_sender) {
|
||||
extern int list_only;
|
||||
@@ -78,7 +79,8 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
if (!user) user = getenv("USER");
|
||||
if (!user) user = getenv("LOGNAME");
|
||||
|
||||
fd = open_socket_out_wrapped (host, rsync_port, bind_address);
|
||||
fd = open_socket_out_wrapped (host, rsync_port, bind_address,
|
||||
default_af_hint);
|
||||
if (fd == -1) {
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
@@ -485,6 +487,7 @@ int daemon_main(void)
|
||||
extern char *config_file;
|
||||
extern int orig_umask;
|
||||
char *pid_file;
|
||||
extern int no_detach;
|
||||
|
||||
if (is_a_socket(STDIN_FILENO)) {
|
||||
int i;
|
||||
@@ -500,7 +503,8 @@ int daemon_main(void)
|
||||
return start_daemon(STDIN_FILENO);
|
||||
}
|
||||
|
||||
become_daemon();
|
||||
if (!no_detach)
|
||||
become_daemon();
|
||||
|
||||
if (!lp_load(config_file, 1)) {
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
@@ -512,7 +516,8 @@ int daemon_main(void)
|
||||
RSYNC_VERSION,
|
||||
rsync_port);
|
||||
/* TODO: If listening on a particular address, then show that
|
||||
* address too. */
|
||||
* address too. In fact, why not just do inet_ntop on the
|
||||
* local address??? */
|
||||
|
||||
if (((pid_file = lp_pid_file()) != NULL) && (*pid_file != '\0')) {
|
||||
char pidbuf[16];
|
||||
|
||||
269
configure.in
269
configure.in
@@ -5,6 +5,12 @@ AC_CONFIG_SRCDIR([byteorder.h])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PREREQ(2.52)
|
||||
|
||||
RSYNC_VERSION=2.5.2pre1
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
|
||||
|
||||
AC_DEFINE_UNQUOTED(RSYNC_VERSION, ["$RSYNC_VERSION"], [rsync release version])
|
||||
|
||||
LDFLAGS=${LDFLAGS-""}
|
||||
|
||||
AC_CANONICAL_TARGET([])
|
||||
@@ -13,15 +19,23 @@ dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_CC_STDC
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
RSYNC_VERSION=2.4.7pre2
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_DEFINE_UNQUOTED(RSYNC_VERSION, ["$RSYNC_VERSION"], [rsync release version])
|
||||
AC_DEFINE([_GNU_SOURCE], 1,
|
||||
[Define _GNU_SOURCE so that we get all necessary prototypes])
|
||||
|
||||
if test "$xac_cv_prog_cc_stdc" = xno
|
||||
then
|
||||
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
|
||||
fi
|
||||
|
||||
# compile with optimisation and without debugging by default, unless
|
||||
# --debug is given. We must decide this before testing the compiler.
|
||||
|
||||
# Please allow this to default to yes, so that your users have more
|
||||
# chance of getting a useful stack trace if problems occur.
|
||||
|
||||
AC_MSG_CHECKING([whether to include debugging symbols])
|
||||
AC_ARG_ENABLE(debug,
|
||||
AC_HELP_STRING([--enable-debug],
|
||||
@@ -35,12 +49,33 @@ then
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
# leave CFLAGS alone; AC_PROG_CC will try to include -g if it can
|
||||
AC_DEFINE(DEBUG, 1, [Define to turn on debugging code that may slow normal operation])
|
||||
dnl AC_DEFINE(DEBUG, 1, [Define to turn on debugging code that may slow normal operation])
|
||||
dnl CFLAGS=${CFLAGS-"-g"}
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
AC_ARG_ENABLE(profile,
|
||||
AC_HELP_STRING([--enable-profile],
|
||||
[turn on CPU profiling (default no)],
|
||||
[], []))
|
||||
if test x"$enable_profile" = xyes
|
||||
then
|
||||
CFLAGS="$CFLAGS -pg"
|
||||
fi
|
||||
|
||||
|
||||
# This is needed for our included version of popt. Kind of silly, but
|
||||
# I don't want our version too far out of sync.
|
||||
CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
|
||||
|
||||
# If GCC, turn on warnings.
|
||||
if test "x$GCC" = "xyes"
|
||||
then
|
||||
CFLAGS="$CFLAGS -Wall -W"
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(included-popt,
|
||||
[ --with-included-popt use bundled popt library, not from system])
|
||||
|
||||
@@ -90,29 +125,15 @@ if test x"$rsync_cv_HAVE_BROKEN_LARGEFILE" != x"yes"; then
|
||||
AC_SYS_LARGEFILE
|
||||
fi
|
||||
|
||||
|
||||
|
||||
AC_DEFINE(ss_family, __ss_family, [KAME hack])
|
||||
AC_DEFINE(ss_len, __ss_len, [KAME hack])
|
||||
|
||||
CFLAGS="$CFLAGS"
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
AC_HELP_STRING([--disable-ipv6], [do not try to support IPv6]))
|
||||
AC_MSG_CHECKING([whether IPv6 is explicitly disabled])
|
||||
if test "$xenable_ipv6" = xyes
|
||||
then
|
||||
AC_MSG_RESULT(yes)
|
||||
ipv6=no
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
ipv6=yes
|
||||
fi
|
||||
|
||||
ipv6type=unknown
|
||||
ipv6lib=none
|
||||
ipv6trylibc=no
|
||||
ipv6trylibc=yes
|
||||
|
||||
if test "$ipv6" = "yes"; then
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
AC_HELP_STRING([--disable-ipv6], [don't even try to use IPv6]))
|
||||
|
||||
if test "x$enable_ipv6" != xno
|
||||
then
|
||||
AC_MSG_CHECKING([ipv6 stack type])
|
||||
for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
|
||||
case $i in
|
||||
@@ -197,152 +218,10 @@ yes
|
||||
fi
|
||||
done
|
||||
AC_MSG_RESULT($ipv6type)
|
||||
|
||||
AC_SEARCH_LIBS(getaddrinfo, inet6)
|
||||
fi
|
||||
|
||||
if test "$ipv6" = "yes" -a -f /usr/local/v6/lib/libinet6.a; then
|
||||
ac_inet6_LDFLAGS="inet6"
|
||||
ipv6libdir=/usr/local/v6/lib
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/v6/lib"
|
||||
AC_CHECK_LIB(inet6, getaddrinfo, , ipv6lib="$ac_inet6_LDFLAGS")
|
||||
fi
|
||||
|
||||
if test "$ipv6" = "yes" -a -f /usr/lib/libinet6.a; then
|
||||
ac_inet6_LDFLAGS="inet6"
|
||||
AC_CHECK_LIB(inet6, getaddrinfo, , ipv6lib="$ac_inet6_LDFLAGS")
|
||||
fi
|
||||
|
||||
if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then
|
||||
if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then
|
||||
LIBS="-L$ipv6libdir -l$ipv6lib $LIBS"
|
||||
echo "You have $ipv6lib library, using it"
|
||||
else
|
||||
if test "$ipv6trylibc" = "yes"; then
|
||||
echo "You do not have $ipv6lib library, using libc"
|
||||
else
|
||||
echo 'Fatal: no $ipv6lib library found. cannot continue.'
|
||||
echo "You need to fetch lib$ipv6lib.a from appropriate"
|
||||
echo 'ipv6 kit and compile beforehand.'
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(getaddrinfo bug)
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
main()
|
||||
{
|
||||
int passive, gaierr, inet4 = 0, inet6 = 0;
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
char straddr[INET6_ADDRSTRLEN], strport[16];
|
||||
|
||||
for (passive = 0; passive <= 1; passive++) {
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = passive ? AI_PASSIVE : 0;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
|
||||
(void)gai_strerror(gaierr);
|
||||
goto bad;
|
||||
}
|
||||
for (ai = aitop; ai; ai = ai->ai_next) {
|
||||
if (ai->ai_addr == NULL ||
|
||||
ai->ai_addrlen == 0 ||
|
||||
getnameinfo(ai->ai_addr, ai->ai_addrlen,
|
||||
straddr, sizeof(straddr), strport, sizeof(strport),
|
||||
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
|
||||
goto bad;
|
||||
}
|
||||
switch (ai->ai_family) {
|
||||
case AF_INET:
|
||||
if (strcmp(strport, "54321") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
if (passive) {
|
||||
if (strcmp(straddr, "0.0.0.0") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(straddr, "127.0.0.1") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
inet4++;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (strcmp(strport, "54321") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
if (passive) {
|
||||
if (strcmp(straddr, "::") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(straddr, "::1") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
inet6++;
|
||||
break;
|
||||
case AF_UNSPEC:
|
||||
goto bad;
|
||||
break;
|
||||
default:
|
||||
/* another family support? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(inet4 == 0 || inet4 == 2))
|
||||
goto bad;
|
||||
if (!(inet6 == 0 || inet6 == 2))
|
||||
goto bad;
|
||||
|
||||
if (aitop)
|
||||
freeaddrinfo(aitop);
|
||||
exit(0);
|
||||
|
||||
bad:
|
||||
if (aitop)
|
||||
freeaddrinfo(aitop);
|
||||
exit(1);
|
||||
}
|
||||
],
|
||||
AC_MSG_RESULT(good)
|
||||
buggygetaddrinfo=no,
|
||||
AC_MSG_RESULT(buggy)
|
||||
buggygetaddrinfo=yes,
|
||||
AC_MSG_RESULT(buggy)
|
||||
buggygetaddrinfo=yes)
|
||||
|
||||
if test "$buggygetaddrinfo" = "yes"; then
|
||||
if test "$ipv6" = "yes" -a "$ipv6type" != "linux"; then
|
||||
echo 'Fatal: You must get working getaddrinfo() function.'
|
||||
echo ' or you can specify "--disable-ipv6"'.
|
||||
exit 1
|
||||
elif test "$ipv6type" = "linux"; then
|
||||
echo 'Warning: getaddrinfo() implementation on your system seems be buggy.'
|
||||
echo ' Better upgreade your system library to newest version'
|
||||
echo ' of GNU C library (aka glibc).'
|
||||
fi
|
||||
fi
|
||||
AC_REPLACE_FUNCS(getaddrinfo getnameinfo)
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr.sa_len],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_TIME
|
||||
@@ -350,7 +229,9 @@ AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h unistd.h utime.h grp.h)
|
||||
AC_CHECK_HEADERS(compat.h sys/param.h ctype.h sys/wait.h sys/ioctl.h)
|
||||
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h)
|
||||
AC_CHECK_HEADERS(glob.h alloca.h mcheck.h)
|
||||
AC_CHECK_HEADERS(glob.h alloca.h mcheck.h sys/sysctl.h arpa/inet.h arpa/nameser.h)
|
||||
AC_CHECK_HEADERS(netdb.h)
|
||||
AC_CHECK_HEADERS(malloc.h)
|
||||
|
||||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
@@ -413,7 +294,33 @@ if test x"$ac_cv_func_connect" = x"no"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
AC_CHECK_LIB(resolv, inet_ntop)
|
||||
|
||||
dnl AC_MSG_NOTICE([Looking in libraries: $LIBS])
|
||||
|
||||
AC_CHECK_FUNCS(inet_ntop, , AC_LIBOBJ(lib/inet_ntop))
|
||||
AC_CHECK_FUNCS(inet_pton, , AC_LIBOBJ(lib/inet_pton))
|
||||
|
||||
AC_CHECK_FUNCS(getaddrinfo, , AC_LIBOBJ(lib/getaddrinfo))
|
||||
AC_CHECK_FUNCS(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr.sa_len],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(struct sockaddr_storage)
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <sys/socket.h>],
|
||||
[struct sockaddr_storage x;],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1,
|
||||
[Define if you have strct sockaddr_storage.] ),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
|
||||
#
|
||||
AC_CHECK_FUNCS(strcasecmp)
|
||||
@@ -421,20 +328,26 @@ if test x"$ac_cv_func_strcasecmp" = x"no"; then
|
||||
AC_CHECK_LIB(resolv, strcasecmp)
|
||||
fi
|
||||
|
||||
AC_FUNC_MEMCMP
|
||||
dnl At the moment we don't test for a broken memcmp(), because all we
|
||||
dnl need to do is test for equality, not comparison, and it seems that
|
||||
dnl every platform has a memcmp that can do at least that.
|
||||
dnl AC_FUNC_MEMCMP
|
||||
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
|
||||
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy mtrace)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy mtrace mallinfo)
|
||||
|
||||
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
|
||||
AC_TRY_RUN([#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
main() {
|
||||
int fd[2];
|
||||
exit((socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1);
|
||||
}],
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
main() {
|
||||
int fd[2];
|
||||
exit((socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1);
|
||||
}],
|
||||
rsync_cv_HAVE_SOCKETPAIR=yes,rsync_cv_HAVE_SOCKETPAIR=no,rsync_cv_HAVE_SOCKETPAIR=cross)])
|
||||
if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
|
||||
AC_DEFINE(HAVE_SOCKETPAIR, 1, [ ])
|
||||
|
||||
@@ -299,7 +299,8 @@ void send_exclude_list(int f)
|
||||
void recv_exclude_list(int f)
|
||||
{
|
||||
char line[MAXPATHLEN];
|
||||
int l;
|
||||
unsigned int l;
|
||||
|
||||
while ((l=read_int(f))) {
|
||||
if (l >= MAXPATHLEN) overflow("recv_exclude_list");
|
||||
read_sbuf(f,line,l);
|
||||
|
||||
4
fileio.c
4
fileio.c
@@ -36,7 +36,7 @@ int sparse_end(int f)
|
||||
}
|
||||
|
||||
|
||||
static int write_sparse(int f,char *buf,int len)
|
||||
static int write_sparse(int f,char *buf,size_t len)
|
||||
{
|
||||
int l1=0,l2=0;
|
||||
int ret;
|
||||
@@ -69,7 +69,7 @@ static int write_sparse(int f,char *buf,int len)
|
||||
|
||||
|
||||
|
||||
int write_file(int f,char *buf,int len)
|
||||
int write_file(int f,char *buf,size_t len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
||||
155
flist.c
155
flist.c
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -17,7 +18,14 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* generate and receive file lists */
|
||||
/** @file flist.c
|
||||
* Generate and receive file lists
|
||||
*
|
||||
* @todo Get rid of the string_area optimization. Efficiently
|
||||
* allocating blocks is the responsibility of the system's malloc
|
||||
* library, not of rsync.
|
||||
*
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -58,6 +66,35 @@ static struct file_struct null_file;
|
||||
|
||||
static void clean_flist(struct file_list *flist, int strip_root);
|
||||
|
||||
|
||||
static int show_build_progress_p(void)
|
||||
{
|
||||
extern int do_progress;
|
||||
|
||||
return do_progress && verbose && recurse && !am_server;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if we're local, etc, and should emit progress emssages.
|
||||
**/
|
||||
static void emit_build_progress(const struct file_list *flist)
|
||||
{
|
||||
rprintf(FINFO,
|
||||
" %d files...\r",
|
||||
flist->count);
|
||||
}
|
||||
|
||||
|
||||
static void finish_build_progress(const struct file_list *flist)
|
||||
{
|
||||
if (verbose && recurse && !am_server) {
|
||||
/* This overwrites the progress line, if any. */
|
||||
rprintf(FINFO, RSYNC_NAME ": %d files to consider.\n",
|
||||
flist->count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct string_area *string_area_new(int size)
|
||||
{
|
||||
struct string_area *a;
|
||||
@@ -111,24 +148,14 @@ static char *string_area_strdup(struct string_area **ap, const char *src)
|
||||
|
||||
static void list_file_entry(struct file_struct *f)
|
||||
{
|
||||
char perms[11] = "----------";
|
||||
char *perm_map = "rwxrwxrwx";
|
||||
int i;
|
||||
char perms[11];
|
||||
|
||||
if (!f->basename)
|
||||
/* this can happen if duplicate names were removed */
|
||||
return;
|
||||
|
||||
for (i=0;i<9;i++) {
|
||||
if (f->mode & (1<<i)) perms[9-i] = perm_map[8-i];
|
||||
}
|
||||
if (S_ISLNK(f->mode)) perms[0] = 'l';
|
||||
if (S_ISDIR(f->mode)) perms[0] = 'd';
|
||||
if (S_ISBLK(f->mode)) perms[0] = 'b';
|
||||
if (S_ISCHR(f->mode)) perms[0] = 'c';
|
||||
if (S_ISSOCK(f->mode)) perms[0] = 's';
|
||||
if (S_ISFIFO(f->mode)) perms[0] = 'p';
|
||||
|
||||
permstring(perms, f->mode);
|
||||
|
||||
if (preserve_links && S_ISLNK(f->mode)) {
|
||||
rprintf(FINFO,"%s %11.0f %s %s -> %s\n",
|
||||
perms,
|
||||
@@ -185,12 +212,18 @@ int link_stat(const char *Path, STRUCT_STAT *Buffer)
|
||||
This function is used to check if a file should be included/excluded
|
||||
from the list of files based on its name and type etc
|
||||
*/
|
||||
static int match_file_name(char *fname,STRUCT_STAT *st)
|
||||
static int check_exclude_file(int f,char *fname,STRUCT_STAT *st)
|
||||
{
|
||||
if (check_exclude(fname,local_exclude_list,st)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
extern int delete_excluded;
|
||||
|
||||
/* f is set to -1 when calculating deletion file list */
|
||||
if ((f == -1) && delete_excluded) {
|
||||
return 0;
|
||||
}
|
||||
if (check_exclude(fname,local_exclude_list,st)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* used by the one_file_system code */
|
||||
@@ -300,8 +333,15 @@ static void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
if (preserve_hard_links && S_ISREG(file->mode)) {
|
||||
write_int(f,(int)file->dev);
|
||||
write_int(f,(int)file->inode);
|
||||
if (remote_version < 26) {
|
||||
/* 32-bit dev_t and ino_t */
|
||||
write_int(f,(int)file->dev);
|
||||
write_int(f,(int)file->inode);
|
||||
} else {
|
||||
/* 64-bit dev_t and ino_t */
|
||||
write_longint(f, file->dev);
|
||||
write_longint(f, file->inode);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -335,7 +375,7 @@ static void receive_file_entry(struct file_struct **fptr,
|
||||
static gid_t last_gid;
|
||||
static char lastname[MAXPATHLEN];
|
||||
char thisname[MAXPATHLEN];
|
||||
int l1=0,l2=0;
|
||||
unsigned int l1=0,l2=0;
|
||||
char *p;
|
||||
struct file_struct *file;
|
||||
|
||||
@@ -402,6 +442,10 @@ static void receive_file_entry(struct file_struct **fptr,
|
||||
|
||||
if (preserve_links && S_ISLNK(file->mode)) {
|
||||
int l = read_int(f);
|
||||
if (l < 0) {
|
||||
rprintf(FERROR,"overflow: l=%d\n", l);
|
||||
overflow("receive_file_entry");
|
||||
}
|
||||
file->link = (char *)malloc(l+1);
|
||||
if (!file->link) out_of_memory("receive_file_entry 2");
|
||||
read_sbuf(f,file->link,l);
|
||||
@@ -412,8 +456,13 @@ static void receive_file_entry(struct file_struct **fptr,
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
if (preserve_hard_links && S_ISREG(file->mode)) {
|
||||
file->dev = read_int(f);
|
||||
file->inode = read_int(f);
|
||||
if (remote_version < 26) {
|
||||
file->dev = read_int(f);
|
||||
file->inode = read_int(f);
|
||||
} else {
|
||||
file->dev = read_longint(f);
|
||||
file->inode = read_longint(f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -467,7 +516,8 @@ static int skip_filesystem(char *fname, STRUCT_STAT *st)
|
||||
}
|
||||
|
||||
#define STRDUP(ap, p) (ap ? string_area_strdup(ap, p) : strdup(p))
|
||||
#define MALLOC(ap, i) (ap ? string_area_malloc(ap, i) : malloc(i))
|
||||
/* IRIX cc cares that the operands to the ternary have the same type. */
|
||||
#define MALLOC(ap, i) (ap ? (void*) string_area_malloc(ap, i) : malloc(i))
|
||||
|
||||
/* create a file_struct for a named file */
|
||||
struct file_struct *make_file(int f, char *fname, struct string_area **ap,
|
||||
@@ -479,7 +529,6 @@ struct file_struct *make_file(int f, char *fname, struct string_area **ap,
|
||||
char *p;
|
||||
char cleaned_name[MAXPATHLEN];
|
||||
char linkbuf[MAXPATHLEN];
|
||||
extern int delete_excluded;
|
||||
extern int module_id;
|
||||
|
||||
strlcpy(cleaned_name, fname, MAXPATHLEN);
|
||||
@@ -490,17 +539,21 @@ struct file_struct *make_file(int f, char *fname, struct string_area **ap,
|
||||
}
|
||||
fname = cleaned_name;
|
||||
|
||||
/* f is set to -1 when calculating deletion file list */
|
||||
if (((f != -1) || !delete_excluded) && !noexcludes && !match_file_name(fname,&st))
|
||||
return NULL;
|
||||
|
||||
|
||||
memset(sum,0,SUM_LENGTH);
|
||||
|
||||
if (readlink_stat(fname,&st,linkbuf) != 0) {
|
||||
int save_errno = errno;
|
||||
if ((errno == ENOENT) && copy_links && !noexcludes) {
|
||||
/* symlink pointing nowhere, see if excluded */
|
||||
memset((char *)&st, 0, sizeof(st));
|
||||
if (check_exclude_file(f,fname,&st)) {
|
||||
/* file is excluded anyway, ignore silently */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
io_error = 1;
|
||||
rprintf(FERROR,"readlink %s: %s\n",
|
||||
fname,strerror(errno));
|
||||
fname,strerror(save_errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -517,6 +570,9 @@ struct file_struct *make_file(int f, char *fname, struct string_area **ap,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (check_exclude_file(f,fname,&st))
|
||||
return NULL;
|
||||
|
||||
|
||||
if (lp_ignore_nonreadable(module_id) && access(fname, R_OK) != 0)
|
||||
return NULL;
|
||||
@@ -603,7 +659,10 @@ void send_file_name(int f,struct file_list *flist,char *fname,
|
||||
|
||||
file = make_file(f,fname, &flist->string_area, 0);
|
||||
|
||||
if (!file) return;
|
||||
if (!file) return;
|
||||
|
||||
if (show_build_progress_p() & !(flist->count % 100))
|
||||
emit_build_progress(flist);
|
||||
|
||||
if (flist->count >= flist->malloced) {
|
||||
if (flist->malloced < 1000)
|
||||
@@ -694,6 +753,11 @@ static void send_directory(int f,struct file_list *flist,char *dir)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* I *think* f==-1 means that the list should just be built in memory
|
||||
* and not transmitted. But who can tell? -- mbp
|
||||
*/
|
||||
struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
{
|
||||
int i,l;
|
||||
@@ -704,7 +768,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
int64 start_write;
|
||||
|
||||
if (verbose && recurse && !am_server && f != -1) {
|
||||
rprintf(FINFO,"building file list ... ");
|
||||
rprintf(FINFO, RSYNC_NAME ": building file list...\n");
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO, "\n");
|
||||
rflush(FINFO);
|
||||
@@ -827,8 +891,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
|
||||
send_file_entry(NULL,f,0);
|
||||
}
|
||||
|
||||
if (verbose && recurse && !am_server && f != -1)
|
||||
rprintf(FINFO,"done\n");
|
||||
finish_build_progress(flist);
|
||||
|
||||
clean_flist(flist, 0);
|
||||
|
||||
@@ -959,6 +1022,10 @@ oom:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* XXX: This is currently the hottest function while building the file
|
||||
* list, because building f_name()s every time is expensive.
|
||||
**/
|
||||
int file_compare(struct file_struct **f1,struct file_struct **f2)
|
||||
{
|
||||
if (!(*f1)->basename && !(*f2)->basename) return 0;
|
||||
@@ -1081,6 +1148,10 @@ static void clean_flist(struct file_list *flist, int strip_root)
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: There is a bug here when filenames are repeated more
|
||||
* than once, because we don't handle freed files when doing
|
||||
* the comparison. */
|
||||
|
||||
if (strip_root) {
|
||||
/* we need to strip off the root directory in the case
|
||||
of relative paths, but this must be done _after_
|
||||
@@ -1116,6 +1187,10 @@ static void clean_flist(struct file_list *flist, int strip_root)
|
||||
|
||||
/*
|
||||
* return the full filename of a flist entry
|
||||
*
|
||||
* This function is too expensive at the moment, because it copies
|
||||
* strings when often we only want to compare them. In any case,
|
||||
* using strlcat is silly because it will walk the string repeatedly.
|
||||
*/
|
||||
char *f_name(struct file_struct *f)
|
||||
{
|
||||
@@ -1128,9 +1203,11 @@ char *f_name(struct file_struct *f)
|
||||
n = (n+1)%10;
|
||||
|
||||
if (f->dirname) {
|
||||
strlcpy(p, f->dirname, MAXPATHLEN);
|
||||
strlcat(p, "/", MAXPATHLEN);
|
||||
strlcat(p, f->basename, MAXPATHLEN);
|
||||
int off;
|
||||
|
||||
off = strlcpy(p, f->dirname, MAXPATHLEN);
|
||||
off += strlcpy(p+off, "/", MAXPATHLEN-off);
|
||||
off += strlcpy(p+off, f->basename, MAXPATHLEN-off);
|
||||
} else {
|
||||
strlcpy(p, f->basename, MAXPATHLEN);
|
||||
}
|
||||
|
||||
74
generator.c
74
generator.c
@@ -1,7 +1,10 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
rsync -- fast file replication program
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -99,25 +102,30 @@ static int adapt_block_size(struct file_struct *file, int bsize)
|
||||
/*
|
||||
send a sums struct down a fd
|
||||
*/
|
||||
static void send_sums(struct sum_struct *s,int f_out)
|
||||
static void send_sums(struct sum_struct *s, int f_out)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* tell the other guy how many we are going to be doing and how many
|
||||
bytes there are in the last chunk */
|
||||
write_int(f_out,s?s->count:0);
|
||||
write_int(f_out,s?s->n:block_size);
|
||||
write_int(f_out,s?s->remainder:0);
|
||||
if (s) {
|
||||
size_t i;
|
||||
|
||||
if (!s) return;
|
||||
/* tell the other guy how many we are going to be
|
||||
doing and how many bytes there are in the last
|
||||
chunk */
|
||||
write_int(f_out, s->count);
|
||||
write_int(f_out, s->n);
|
||||
write_int(f_out, s->remainder);
|
||||
|
||||
for (i=0;i<s->count;i++) {
|
||||
write_int(f_out,s->sums[i].sum1);
|
||||
write_buf(f_out,s->sums[i].sum2,csum_length);
|
||||
for (i = 0; i < s->count; i++) {
|
||||
write_int(f_out, s->sums[i].sum1);
|
||||
write_buf(f_out, s->sums[i].sum2, csum_length);
|
||||
}
|
||||
} else {
|
||||
/* we don't have checksums */
|
||||
write_int(f_out, 0);
|
||||
write_int(f_out, block_size);
|
||||
write_int(f_out, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
generate a stream of signatures/checksums that describe a buffer
|
||||
|
||||
@@ -210,7 +218,8 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
if (only_existing && statret == -1 && errno == ENOENT) {
|
||||
/* we only want to update existing files */
|
||||
if (verbose > 1) rprintf(FINFO,"not creating %s\n",fname);
|
||||
if (verbose > 1) rprintf(FINFO, RSYNC_NAME
|
||||
": not creating new file \"%s\"\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -230,10 +239,11 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
* we need to delete it. If it doesn't exist, then
|
||||
* recursively create it. */
|
||||
|
||||
if (dry_run) return;
|
||||
if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
|
||||
if (statret == 0 && !S_ISDIR(st.st_mode)) {
|
||||
if (robust_unlink(fname) != 0) {
|
||||
rprintf(FERROR,"recv_generator: unlink %s: %s\n",
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": recv_generator: unlink \"%s\" to make room for directory: %s\n",
|
||||
fname,strerror(errno));
|
||||
return;
|
||||
}
|
||||
@@ -243,11 +253,13 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
if (!(relative_paths && errno==ENOENT &&
|
||||
create_directory_path(fname)==0 &&
|
||||
do_mkdir(fname,file->mode)==0)) {
|
||||
rprintf(FERROR,"recv_generator: mkdir %s: %s (2)\n",
|
||||
rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
|
||||
fname,strerror(errno));
|
||||
}
|
||||
}
|
||||
if (set_perms(fname,file,NULL,0) && verbose)
|
||||
/* f_out is set to -1 when doing final directory
|
||||
permission and modification time repair */
|
||||
if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
|
||||
rprintf(FINFO,"%s/\n",fname);
|
||||
return;
|
||||
}
|
||||
@@ -260,7 +272,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
if (safe_symlinks && unsafe_symlink(file->link, fname)) {
|
||||
if (verbose) {
|
||||
rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n",
|
||||
rprintf(FINFO,RSYNC_NAME ": ignoring unsafe symlink \"%s\" -> \"%s\"\n",
|
||||
fname,file->link);
|
||||
}
|
||||
return;
|
||||
@@ -269,20 +281,26 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
l = readlink(fname,lnk,MAXPATHLEN-1);
|
||||
if (l > 0) {
|
||||
lnk[l] = 0;
|
||||
/* A link already pointing to the
|
||||
* right place -- no further action
|
||||
* required. */
|
||||
if (strcmp(lnk,file->link) == 0) {
|
||||
set_perms(fname,file,&st,1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Not a symlink, so delete whatever's
|
||||
* already there and put a new symlink
|
||||
* in place. */
|
||||
delete_file(fname);
|
||||
}
|
||||
if (do_symlink(file->link,fname) != 0) {
|
||||
rprintf(FERROR,"symlink %s -> %s : %s\n",
|
||||
rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
|
||||
fname,file->link,strerror(errno));
|
||||
} else {
|
||||
set_perms(fname,file,NULL,0);
|
||||
if (verbose) {
|
||||
rprintf(FINFO,"%s -> %s\n",
|
||||
rprintf(FINFO,RSYNC_NAME": %s -> %s\n",
|
||||
fname,file->link);
|
||||
}
|
||||
}
|
||||
@@ -315,12 +333,14 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
if (preserve_hard_links && check_hard_link(file)) {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO,"%s is a hard link\n",f_name(file));
|
||||
rprintf(FINFO, RSYNC_NAME
|
||||
": \"%s\" is a hard link\n",f_name(file));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!S_ISREG(file->mode)) {
|
||||
rprintf(FINFO,"skipping non-regular file %s\n",fname);
|
||||
rprintf(FINFO, RSYNC_NAME
|
||||
": skipping non-regular file \"%s\"\n",fname);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -345,7 +365,9 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
if (!dry_run) send_sums(NULL,f_out);
|
||||
} else {
|
||||
if (verbose > 1)
|
||||
rprintf(FERROR,"recv_generator failed to open %s\n",fname);
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": recv_generator failed to open \"%s\": %s\n",
|
||||
fname, strerror(errno));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -388,7 +410,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
fd = do_open(fnamecmp, O_RDONLY, 0);
|
||||
|
||||
if (fd == -1) {
|
||||
rprintf(FERROR,"failed to open %s, continuing : %s\n",fnamecmp,strerror(errno));
|
||||
rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
|
||||
/* pretend the file didn't exist */
|
||||
write_int(f_out,i);
|
||||
send_sums(NULL,f_out);
|
||||
|
||||
151
hlink.c
151
hlink.c
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -23,19 +24,22 @@ extern int dry_run;
|
||||
extern int verbose;
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
static int hlink_compare(struct file_struct *f1,struct file_struct *f2)
|
||||
static int hlink_compare(struct file_struct *f1, struct file_struct *f2)
|
||||
{
|
||||
if (!S_ISREG(f1->mode) && !S_ISREG(f2->mode)) return 0;
|
||||
if (!S_ISREG(f1->mode)) return -1;
|
||||
if (!S_ISREG(f2->mode)) return 1;
|
||||
if (!S_ISREG(f1->mode) && !S_ISREG(f2->mode))
|
||||
return 0;
|
||||
if (!S_ISREG(f1->mode))
|
||||
return -1;
|
||||
if (!S_ISREG(f2->mode))
|
||||
return 1;
|
||||
|
||||
if (f1->dev != f2->dev)
|
||||
return (int)(f1->dev>f2->dev?1:-1);
|
||||
if (f1->dev != f2->dev)
|
||||
return (int) (f1->dev > f2->dev ? 1 : -1);
|
||||
|
||||
if (f1->inode != f2->inode)
|
||||
return (int)(f1->inode>f2->inode?1:-1);
|
||||
if (f1->inode != f2->inode)
|
||||
return (int) (f1->inode > f2->inode ? 1 : -1);
|
||||
|
||||
return file_compare(&f1,&f2);
|
||||
return file_compare(&f1, &f2);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,22 +51,25 @@ void init_hard_links(struct file_list *flist)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int i;
|
||||
if (flist->count < 2) return;
|
||||
if (flist->count < 2)
|
||||
return;
|
||||
|
||||
if (hlink_list) free(hlink_list);
|
||||
|
||||
if (!(hlink_list =
|
||||
(struct file_struct *)malloc(sizeof(hlink_list[0])*flist->count)))
|
||||
if (hlink_list)
|
||||
free(hlink_list);
|
||||
|
||||
if (!(hlink_list =
|
||||
(struct file_struct *) malloc(sizeof(hlink_list[0]) *
|
||||
flist->count)))
|
||||
out_of_memory("init_hard_links");
|
||||
|
||||
for (i = 0; i < flist->count; i++)
|
||||
memcpy(&hlink_list[i], flist->files[i], sizeof(hlink_list[0]));
|
||||
memcpy(&hlink_list[i], flist->files[i],
|
||||
sizeof(hlink_list[0]));
|
||||
|
||||
qsort(hlink_list,flist->count,
|
||||
sizeof(hlink_list[0]),
|
||||
(int (*)())hlink_compare);
|
||||
qsort(hlink_list, flist->count,
|
||||
sizeof(hlink_list[0]), (int (*)()) hlink_compare);
|
||||
|
||||
hlink_count=flist->count;
|
||||
hlink_count = flist->count;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -71,86 +78,102 @@ void init_hard_links(struct file_list *flist)
|
||||
int check_hard_link(struct file_struct *file)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int low=0,high=hlink_count-1;
|
||||
int ret=0;
|
||||
int low = 0, high = hlink_count - 1;
|
||||
int ret = 0;
|
||||
|
||||
if (!hlink_list || !S_ISREG(file->mode)) return 0;
|
||||
if (!hlink_list || !S_ISREG(file->mode))
|
||||
return 0;
|
||||
|
||||
while (low != high) {
|
||||
int mid = (low+high)/2;
|
||||
ret = hlink_compare(&hlink_list[mid],file);
|
||||
if (ret == 0) {
|
||||
low = mid;
|
||||
break;
|
||||
}
|
||||
if (ret > 0)
|
||||
high=mid;
|
||||
else
|
||||
low=mid+1;
|
||||
}
|
||||
while (low != high) {
|
||||
int mid = (low + high) / 2;
|
||||
ret = hlink_compare(&hlink_list[mid], file);
|
||||
if (ret == 0) {
|
||||
low = mid;
|
||||
break;
|
||||
}
|
||||
if (ret > 0)
|
||||
high = mid;
|
||||
else
|
||||
low = mid + 1;
|
||||
}
|
||||
|
||||
if (hlink_compare(&hlink_list[low],file) != 0) return 0;
|
||||
if (hlink_compare(&hlink_list[low], file) != 0)
|
||||
return 0;
|
||||
|
||||
if (low > 0 &&
|
||||
S_ISREG(hlink_list[low-1].mode) &&
|
||||
file->dev == hlink_list[low-1].dev &&
|
||||
file->inode == hlink_list[low-1].inode)
|
||||
return 1;
|
||||
if (low > 0 &&
|
||||
S_ISREG(hlink_list[low - 1].mode) &&
|
||||
file->dev == hlink_list[low - 1].dev &&
|
||||
file->inode == hlink_list[low - 1].inode)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
static void hard_link_one(int i)
|
||||
{
|
||||
STRUCT_STAT st1,st2;
|
||||
STRUCT_STAT st1, st2;
|
||||
|
||||
if (link_stat(f_name(&hlink_list[i-1]),&st1) != 0) return;
|
||||
if (link_stat(f_name(&hlink_list[i - 1]), &st1) != 0)
|
||||
return;
|
||||
|
||||
if (link_stat(f_name(&hlink_list[i]),&st2) != 0) {
|
||||
if (do_link(f_name(&hlink_list[i-1]),f_name(&hlink_list[i])) != 0) {
|
||||
if (link_stat(f_name(&hlink_list[i]), &st2) != 0) {
|
||||
if (do_link
|
||||
(f_name(&hlink_list[i - 1]),
|
||||
f_name(&hlink_list[i])) != 0) {
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO,"link %s => %s : %s\n",
|
||||
rprintf(FINFO, "link %s => %s : %s\n",
|
||||
f_name(&hlink_list[i]),
|
||||
f_name(&hlink_list[i-1]),strerror(errno));
|
||||
f_name(&hlink_list[i - 1]),
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino) return;
|
||||
|
||||
if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino)
|
||||
return;
|
||||
|
||||
if (robust_unlink(f_name(&hlink_list[i])) != 0 ||
|
||||
do_link(f_name(&hlink_list[i-1]),f_name(&hlink_list[i])) != 0) {
|
||||
do_link(f_name(&hlink_list[i - 1]),
|
||||
f_name(&hlink_list[i])) != 0) {
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO,"link %s => %s : %s\n",
|
||||
rprintf(FINFO, "link %s => %s : %s\n",
|
||||
f_name(&hlink_list[i]),
|
||||
f_name(&hlink_list[i-1]),strerror(errno));
|
||||
f_name(&hlink_list[i - 1]),
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO,"%s => %s\n",
|
||||
f_name(&hlink_list[i]),f_name(&hlink_list[i-1]));
|
||||
rprintf(FINFO, "%s => %s\n",
|
||||
f_name(&hlink_list[i]),
|
||||
f_name(&hlink_list[i - 1]));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* create any hard links in the flist */
|
||||
void do_hard_links(struct file_list *flist)
|
||||
|
||||
|
||||
/**
|
||||
* Create any hard links in the global hlink_list. They were put
|
||||
* there by running init_hard_links on the filelist.
|
||||
**/
|
||||
void do_hard_links(void)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int i;
|
||||
|
||||
if (!hlink_list) return;
|
||||
|
||||
for (i=1;i<hlink_count;i++) {
|
||||
if (!hlink_list)
|
||||
return;
|
||||
|
||||
for (i = 1; i < hlink_count; i++) {
|
||||
if (S_ISREG(hlink_list[i].mode) &&
|
||||
S_ISREG(hlink_list[i-1].mode) &&
|
||||
hlink_list[i].basename && hlink_list[i-1].basename &&
|
||||
hlink_list[i].dev == hlink_list[i-1].dev &&
|
||||
hlink_list[i].inode == hlink_list[i-1].inode) {
|
||||
S_ISREG(hlink_list[i - 1].mode) &&
|
||||
hlink_list[i].basename && hlink_list[i - 1].basename &&
|
||||
hlink_list[i].dev == hlink_list[i - 1].dev &&
|
||||
hlink_list[i].inode == hlink_list[i - 1].inode) {
|
||||
hard_link_one(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
58
io.c
58
io.c
@@ -49,7 +49,7 @@ int kludge_around_eof = False;
|
||||
|
||||
static int io_error_fd = -1;
|
||||
|
||||
static void read_loop(int fd, char *buf, int len);
|
||||
static void read_loop(int fd, char *buf, size_t len);
|
||||
|
||||
static void check_timeout(void)
|
||||
{
|
||||
@@ -86,7 +86,7 @@ void io_set_error_fd(int fd)
|
||||
static void read_error_fd(void)
|
||||
{
|
||||
char buf[200];
|
||||
int n;
|
||||
size_t n;
|
||||
int fd = io_error_fd;
|
||||
int tag, len;
|
||||
|
||||
@@ -103,7 +103,8 @@ static void read_error_fd(void)
|
||||
|
||||
while (len) {
|
||||
n = len;
|
||||
if (n > (sizeof(buf)-1)) n = sizeof(buf)-1;
|
||||
if (n > (sizeof(buf)-1))
|
||||
n = sizeof(buf)-1;
|
||||
read_loop(fd, buf, n);
|
||||
rwrite((enum logcode)tag, buf, n);
|
||||
len -= n;
|
||||
@@ -163,7 +164,7 @@ static void die_from_readerr (int err)
|
||||
* give a better explanation. We can tell whether the connection has
|
||||
* started by looking e.g. at whether the remote version is known yet.
|
||||
*/
|
||||
static int read_timeout (int fd, char *buf, int len)
|
||||
static int read_timeout (int fd, char *buf, size_t len)
|
||||
{
|
||||
int n, ret=0;
|
||||
|
||||
@@ -236,7 +237,7 @@ static int read_timeout (int fd, char *buf, int len)
|
||||
|
||||
/*! Continue trying to read len bytes - don't return until len has
|
||||
been read. */
|
||||
static void read_loop (int fd, char *buf, int len)
|
||||
static void read_loop (int fd, char *buf, size_t len)
|
||||
{
|
||||
while (len) {
|
||||
int n = read_timeout(fd, buf, len);
|
||||
@@ -253,10 +254,10 @@ static void read_loop (int fd, char *buf, int len)
|
||||
*
|
||||
* Never returns <= 0.
|
||||
*/
|
||||
static int read_unbuffered(int fd, char *buf, int len)
|
||||
static int read_unbuffered(int fd, char *buf, size_t len)
|
||||
{
|
||||
static int remaining;
|
||||
int tag, ret=0;
|
||||
static size_t remaining;
|
||||
int tag, ret = 0;
|
||||
char line[1024];
|
||||
|
||||
if (!io_multiplexing_in || fd != multiplex_in_fd)
|
||||
@@ -271,23 +272,24 @@ static int read_unbuffered(int fd, char *buf, int len)
|
||||
continue;
|
||||
}
|
||||
|
||||
read_loop (fd, line, 4);
|
||||
read_loop(fd, line, 4);
|
||||
tag = IVAL(line, 0);
|
||||
|
||||
remaining = tag & 0xFFFFFF;
|
||||
tag = tag >> 24;
|
||||
|
||||
if (tag == MPLEX_BASE) continue;
|
||||
if (tag == MPLEX_BASE)
|
||||
continue;
|
||||
|
||||
tag -= MPLEX_BASE;
|
||||
|
||||
if (tag != FERROR && tag != FINFO) {
|
||||
rprintf(FERROR,"unexpected tag %d\n", tag);
|
||||
rprintf(FERROR, "unexpected tag %d\n", tag);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
if (remaining > sizeof(line)-1) {
|
||||
rprintf(FERROR,"multiplexing overflow %d\n\n",
|
||||
if (remaining > sizeof(line) - 1) {
|
||||
rprintf(FERROR, "multiplexing overflow %d\n\n",
|
||||
remaining);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
@@ -295,7 +297,7 @@ static int read_unbuffered(int fd, char *buf, int len)
|
||||
read_loop(fd, line, remaining);
|
||||
line[remaining] = 0;
|
||||
|
||||
rprintf((enum logcode)tag,"%s", line);
|
||||
rprintf((enum logcode) tag, "%s", line);
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
@@ -303,12 +305,13 @@ static int read_unbuffered(int fd, char *buf, int len)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* do a buffered read from fd. don't return until all N bytes
|
||||
have been read. If all N can't be read then exit with an error */
|
||||
static void readfd (int fd, char *buffer, int N)
|
||||
static void readfd (int fd, char *buffer, size_t N)
|
||||
{
|
||||
int ret;
|
||||
int total=0;
|
||||
size_t total=0;
|
||||
|
||||
while (total < N) {
|
||||
io_flush();
|
||||
@@ -356,12 +359,12 @@ int64 read_longint(int f)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void read_buf(int f,char *buf,int len)
|
||||
void read_buf(int f,char *buf,size_t len)
|
||||
{
|
||||
readfd(f,buf,len);
|
||||
}
|
||||
|
||||
void read_sbuf(int f,char *buf,int len)
|
||||
void read_sbuf(int f,char *buf,size_t len)
|
||||
{
|
||||
read_buf (f,buf,len);
|
||||
buf[len] = 0;
|
||||
@@ -375,9 +378,9 @@ unsigned char read_byte(int f)
|
||||
}
|
||||
|
||||
/* write len bytes to fd */
|
||||
static void writefd_unbuffered(int fd,char *buf,int len)
|
||||
static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
{
|
||||
int total = 0;
|
||||
size_t total = 0;
|
||||
fd_set w_fds, r_fds;
|
||||
int fd_count, count;
|
||||
struct timeval tv;
|
||||
@@ -424,7 +427,8 @@ static void writefd_unbuffered(int fd,char *buf,int len)
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &w_fds)) {
|
||||
int ret, n = len-total;
|
||||
int ret;
|
||||
size_t n = len-total;
|
||||
ret = write(fd,buf+total,n);
|
||||
|
||||
if (ret == -1 && errno == EINTR) {
|
||||
@@ -483,10 +487,10 @@ void io_start_buffering(int fd)
|
||||
|
||||
/* write an message to a multiplexed stream. If this fails then rsync
|
||||
exits */
|
||||
static void mplex_write(int fd, enum logcode code, char *buf, int len)
|
||||
static void mplex_write(int fd, enum logcode code, char *buf, size_t len)
|
||||
{
|
||||
char buffer[4096];
|
||||
int n = len;
|
||||
size_t n = len;
|
||||
|
||||
SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
|
||||
|
||||
@@ -533,7 +537,7 @@ void io_end_buffering(int fd)
|
||||
}
|
||||
}
|
||||
|
||||
static void writefd(int fd,char *buf,int len)
|
||||
static void writefd(int fd,char *buf,size_t len)
|
||||
{
|
||||
stats.total_written += len;
|
||||
|
||||
@@ -587,7 +591,7 @@ void write_longint(int f, int64 x)
|
||||
writefd(f,b,8);
|
||||
}
|
||||
|
||||
void write_buf(int f,char *buf,int len)
|
||||
void write_buf(int f,char *buf,size_t len)
|
||||
{
|
||||
writefd(f,buf,len);
|
||||
}
|
||||
@@ -606,7 +610,7 @@ void write_byte(int f,unsigned char c)
|
||||
|
||||
|
||||
|
||||
int read_line(int f, char *buf, int maxlen)
|
||||
int read_line(int f, char *buf, size_t maxlen)
|
||||
{
|
||||
while (maxlen) {
|
||||
buf[0] = 0;
|
||||
@@ -664,7 +668,7 @@ void io_start_multiplex_in(int fd)
|
||||
}
|
||||
|
||||
/* write an message to the multiplexed error stream */
|
||||
int io_multiplex_write(enum logcode code, char *buf, int len)
|
||||
int io_multiplex_write(enum logcode code, char *buf, size_t len)
|
||||
{
|
||||
if (!io_multiplexing_out) return 0;
|
||||
|
||||
|
||||
@@ -97,8 +97,10 @@
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/* like strncpy but does not 0 fill the buffer and always null
|
||||
terminates. bufsize is the size of the destination buffer */
|
||||
/* Like strncpy but does not 0 fill the buffer and always null
|
||||
* terminates. bufsize is the size of the destination buffer.
|
||||
*
|
||||
* Returns the index of the terminating byte. */
|
||||
size_t strlcpy(char *d, const char *s, size_t bufsize)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
|
||||
184
lib/inet_ntop.c
Normal file
184
lib/inet_ntop.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (C) 1996-2001 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#define NS_INT16SZ 2
|
||||
#define NS_IN6ADDRSZ 16
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4(const unsigned char *src, char *dst,
|
||||
size_t size);
|
||||
|
||||
#ifdef AF_INET6
|
||||
static const char *inet_ntop6(const unsigned char *src, char *dst,
|
||||
size_t size);
|
||||
#endif
|
||||
|
||||
/* char *
|
||||
* isc_net_ntop(af, src, dst, size)
|
||||
* convert a network format address to presentation format.
|
||||
* return:
|
||||
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
#ifdef AF_INET6
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
* (1) uses no statics
|
||||
* (2) takes a unsigned char* not an in_addr as input
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop4(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
static const char *fmt = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
|
||||
if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
|
||||
{
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* isc_inet_ntop6(src, dst, size)
|
||||
* convert IPv6 binary address into presentation (printable) format
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
#ifdef AF_INET6
|
||||
static const char *
|
||||
inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof words);
|
||||
for (i = 0; i < NS_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/*
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp,
|
||||
sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += sprintf(tp, "%x", words[i]);
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
#endif /* AF_INET6 */
|
||||
210
lib/inet_pton.c
Normal file
210
lib/inet_pton.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 1996-2001 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#define NS_INT16SZ 2
|
||||
#define NS_INADDRSZ 4
|
||||
#define NS_IN6ADDRSZ 16
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4(const char *src, unsigned char *dst);
|
||||
static int inet_pton6(const char *src, unsigned char *dst);
|
||||
|
||||
/* int
|
||||
* isc_net_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid (`dst' is untouched in this case)
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
inet_pton(int af,
|
||||
const char *src,
|
||||
void *dst)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(src, dst)
|
||||
const char *src;
|
||||
unsigned char *dst;
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
unsigned char tmp[NS_INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
unsigned int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (! saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
#ifdef INET6
|
||||
static int
|
||||
inet_pton6(src, dst)
|
||||
const char *src;
|
||||
unsigned char *dst;
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
unsigned int val;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
61
lib/permstring.c
Normal file
61
lib/permstring.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/**
|
||||
* Produce a string representation of Unix mode bits like that used by
|
||||
* ls(1).
|
||||
*
|
||||
* @param buf buffer of at least 11 characters
|
||||
**/
|
||||
void permstring(char *perms,
|
||||
int mode)
|
||||
{
|
||||
static const char *perm_map = "rwxrwxrwx";
|
||||
int i;
|
||||
|
||||
strcpy(perms, "----------");
|
||||
|
||||
for (i=0;i<9;i++) {
|
||||
if (mode & (1<<i)) perms[9-i] = perm_map[8-i];
|
||||
}
|
||||
|
||||
/* Handle setuid/sticky bits. You might think the indices are
|
||||
* off by one, but remember there's a type char at the
|
||||
* start. */
|
||||
if (mode & S_ISUID)
|
||||
perms[3] = (mode & S_IXUSR) ? 's' : 'S';
|
||||
|
||||
if (mode & S_ISGID)
|
||||
perms[6] = (mode & S_IXGRP) ? 's' : 'S';
|
||||
|
||||
if (mode & S_ISVTX)
|
||||
perms[9] = (mode & S_IXOTH) ? 't' : 'T';
|
||||
|
||||
if (S_ISLNK(mode)) perms[0] = 'l';
|
||||
if (S_ISDIR(mode)) perms[0] = 'd';
|
||||
if (S_ISBLK(mode)) perms[0] = 'b';
|
||||
if (S_ISCHR(mode)) perms[0] = 'c';
|
||||
if (S_ISSOCK(mode)) perms[0] = 's';
|
||||
if (S_ISFIFO(mode)) perms[0] = 'p';
|
||||
}
|
||||
|
||||
|
||||
3
lib/permstring.h
Normal file
3
lib/permstring.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#define PERMSTRING_SIZE 11
|
||||
|
||||
void permstring(char *perms, int mode);
|
||||
23
loadparm.c
23
loadparm.c
@@ -1,6 +1,11 @@
|
||||
/* This is based on loadparm.c from Samba, written by Andrew Tridgell
|
||||
and Karl Auer */
|
||||
|
||||
/* some fixes
|
||||
*
|
||||
* Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -379,14 +384,28 @@ static void init_service(service *pservice)
|
||||
copy_service(pservice,&sDefault);
|
||||
}
|
||||
|
||||
static void string_set(char **s, char *v)
|
||||
|
||||
/**
|
||||
* Assign a copy of @p v to @p *s. Handles NULL strings. @p *v must
|
||||
* be initialized when this is called, either to NULL or a malloc'd
|
||||
* string.
|
||||
*
|
||||
* @fixme There is a small leak here in that sometimes the existing
|
||||
* value will be dynamically allocated, and the old copy is lost.
|
||||
* However, we can't always deallocate the old value, because in the
|
||||
* case of sDefault, it points to a static string. It would be nice
|
||||
* to have either all-strdup'd values, or to never need to free
|
||||
* memory.
|
||||
**/
|
||||
static void string_set(char **s, const char *v)
|
||||
{
|
||||
if (!v) {
|
||||
*s = NULL;
|
||||
return;
|
||||
}
|
||||
*s = strdup(v);
|
||||
if (!*s) exit_cleanup(RERR_MALLOC);
|
||||
if (!*s)
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
|
||||
|
||||
|
||||
16
log.c
16
log.c
@@ -286,13 +286,14 @@ void rprintf(enum logcode code, const char *format, ...)
|
||||
int len;
|
||||
|
||||
va_start(ap, format);
|
||||
/* Note: might return -1 */
|
||||
len = vsnprintf(buf, sizeof(buf), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* Deal with buffer overruns. Instead of panicking, just
|
||||
* truncate the resulting string. Note that some vsnprintf()s
|
||||
* return -1 on truncation, e.g., glibc 2.0.6 and earlier. */
|
||||
if (len > sizeof(buf)-1 || len < 0) {
|
||||
if ((size_t) len > sizeof(buf)-1 || len < 0) {
|
||||
const char ellipsis[] = "[...]";
|
||||
|
||||
/* Reset length, and zero-terminate the end of our buffer */
|
||||
@@ -331,18 +332,21 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[1024];
|
||||
int len, sys_len;
|
||||
int len;
|
||||
size_t sys_len;
|
||||
char *sysmsg;
|
||||
|
||||
va_start(ap, format);
|
||||
/* Note: might return <0 */
|
||||
len = vsnprintf(buf, sizeof(buf), format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len > sizeof(buf)-1) exit_cleanup(RERR_MESSAGEIO);
|
||||
if ((size_t) len > sizeof(buf)-1)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
|
||||
sysmsg = strerror(errcode);
|
||||
sys_len = strlen(sysmsg);
|
||||
if (len + 3 + sys_len > sizeof(buf) - 1)
|
||||
if ((size_t) len + 3 + sys_len > sizeof(buf) - 1)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
|
||||
strcpy(buf + len, ": ");
|
||||
@@ -399,7 +403,7 @@ static void log_formatted(enum logcode code,
|
||||
char buf[1024];
|
||||
char buf2[1024];
|
||||
char *p, *s, *n;
|
||||
int l;
|
||||
size_t l;
|
||||
extern struct stats stats;
|
||||
extern int am_sender;
|
||||
extern int am_daemon;
|
||||
@@ -466,7 +470,7 @@ static void log_formatted(enum logcode code,
|
||||
|
||||
l = strlen(n);
|
||||
|
||||
if ((l-1) + ((int)(s - &buf[0])) > sizeof(buf)) {
|
||||
if (l + ((int)(s - &buf[0])) >= sizeof(buf)) {
|
||||
rprintf(FERROR,"buffer overflow expanding %%%c - exiting\n",
|
||||
p[0]);
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
|
||||
44
main.c
44
main.c
@@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,7 @@ struct stats stats;
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static void show_malloc_stats(void);
|
||||
|
||||
/****************************************************************************
|
||||
wait for a process to exit, calling io_flush while waiting
|
||||
@@ -56,6 +57,11 @@ static void report(int f)
|
||||
extern int remote_version;
|
||||
int send_stats;
|
||||
|
||||
if (do_stats) {
|
||||
/* These come out from every process */
|
||||
show_malloc_stats();
|
||||
}
|
||||
|
||||
if (am_daemon) {
|
||||
log_exit(0, __FILE__, __LINE__);
|
||||
if (f == -1 || !am_sender) return;
|
||||
@@ -126,6 +132,38 @@ static void report(int f)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If our C library can get malloc statistics, then show them to FINFO
|
||||
**/
|
||||
static void show_malloc_stats(void)
|
||||
{
|
||||
#ifdef HAVE_MALLINFO
|
||||
struct mallinfo mi;
|
||||
extern int am_server;
|
||||
extern int am_sender;
|
||||
extern int am_daemon;
|
||||
|
||||
mi = mallinfo();
|
||||
|
||||
rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
|
||||
getpid(),
|
||||
am_server ? "server " : "",
|
||||
am_daemon ? "daemon " : "",
|
||||
am_sender ? "sender" : "receiver");
|
||||
rprintf(FINFO, " arena: %10d (bytes from sbrk)\n", mi.arena);
|
||||
rprintf(FINFO, " ordblks: %10d (chunks not in use)\n", mi.ordblks);
|
||||
rprintf(FINFO, " smblks: %10d\n", mi.smblks);
|
||||
rprintf(FINFO, " hblks: %10d (chunks from mmap)\n", mi.hblks);
|
||||
rprintf(FINFO, " hblkhd: %10d (bytes from mmap)\n", mi.hblkhd);
|
||||
rprintf(FINFO, " usmblks: %10d\n", mi.usmblks);
|
||||
rprintf(FINFO, " fsmblks: %10d\n", mi.fsmblks);
|
||||
rprintf(FINFO, " uordblks: %10d (bytes used)\n", mi.uordblks);
|
||||
rprintf(FINFO, " fordblks: %10d (bytes free)\n", mi.fordblks);
|
||||
rprintf(FINFO, " keepcost: %10d (bytes in releasable chunk)\n", mi.keepcost);
|
||||
#endif /* HAVE_MALLINFO */
|
||||
}
|
||||
|
||||
|
||||
/* Start the remote shell. cmd may be NULL to use the default. */
|
||||
static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
|
||||
{
|
||||
@@ -765,8 +803,10 @@ int main(int argc,char *argv[])
|
||||
extern int write_batch; /* dw */
|
||||
extern char *batch_ext; /* dw */
|
||||
int orig_argc; /* dw */
|
||||
char **orig_argv;
|
||||
|
||||
orig_argc = argc; /* dw */
|
||||
orig_argv = argv;
|
||||
|
||||
signal(SIGUSR1, sigusr1_handler);
|
||||
signal(SIGUSR2, sigusr2_handler);
|
||||
@@ -806,7 +846,7 @@ int main(int argc,char *argv[])
|
||||
|
||||
if (write_batch) { /* dw */
|
||||
create_batch_file_ext();
|
||||
write_batch_argvs_file(orig_argc, argc, argv);
|
||||
write_batch_argvs_file(orig_argc, orig_argv);
|
||||
}
|
||||
|
||||
if (read_batch) { /* dw */
|
||||
|
||||
73
options.c
73
options.c
@@ -1,7 +1,7 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2000-2001 by Martin Pool <mbp@samba.org>
|
||||
Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -75,10 +75,20 @@ int modify_window=0;
|
||||
int blocking_io=0;
|
||||
|
||||
/** Network address family. **/
|
||||
int af = AF_INET;
|
||||
#ifdef INET6
|
||||
int default_af_hint = 0; /* Any protocol */
|
||||
#else
|
||||
int default_af_hint = AF_INET; /* Must use IPv4 */
|
||||
#endif
|
||||
|
||||
int read_batch=0; /* dw */
|
||||
int write_batch=0; /* dw */
|
||||
/** Do not go into the background when run as --daemon. Good
|
||||
* for debugging and required for running as a service on W32,
|
||||
* or under Unix process-monitors. **/
|
||||
int no_detach = 0;
|
||||
|
||||
|
||||
int read_batch=0;
|
||||
int write_batch=0;
|
||||
|
||||
char *backup_suffix = BACKUP_SUFFIX;
|
||||
char *tmpdir = NULL;
|
||||
@@ -106,12 +116,13 @@ static int modify_window_set;
|
||||
char *bind_address;
|
||||
|
||||
|
||||
static void print_rsync_version(int f)
|
||||
static void print_rsync_version(enum logcode f)
|
||||
{
|
||||
char const *got_socketpair = "no ";
|
||||
char const *hardlinks = "no ";
|
||||
char const *links = "no ";
|
||||
char const *ipv6 = "no ";
|
||||
STRUCT_STAT *dumstat;
|
||||
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
got_socketpair = "";
|
||||
@@ -132,13 +143,20 @@ static void print_rsync_version(int f)
|
||||
rprintf(f, "%s version %s protocol version %d\n",
|
||||
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
|
||||
rprintf(f,
|
||||
"Copyright (C) 1996-2001 by Andrew Tridgell and others\n");
|
||||
"Copyright (C) 1996-2002 by Andrew Tridgell and others\n");
|
||||
rprintf(f, "<http://rsync.samba.org/>\n");
|
||||
rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
|
||||
"%shard links, %ssymlinks, batchfiles, %sIPv6\n\n",
|
||||
"%shard links, %ssymlinks, batchfiles, %sIPv6,\n",
|
||||
(int) (sizeof(OFF_T) * 8),
|
||||
got_socketpair, hardlinks, links, ipv6);
|
||||
|
||||
/* Note that this field may not have type ino_t. It depends
|
||||
* on the complicated interaction between largefile feature
|
||||
* macros. */
|
||||
rprintf(f, " %d-bit system inums, %d-bit internal inums\n",
|
||||
(int) (sizeof(dumstat->st_ino) * 8),
|
||||
(int) (sizeof(INO64_T) * 8));
|
||||
|
||||
#ifdef NO_INT64
|
||||
rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
|
||||
#endif
|
||||
@@ -171,8 +189,8 @@ void usage(enum logcode F)
|
||||
rprintf(F," --backup-dir make backups into this directory\n");
|
||||
rprintf(F," --suffix=SUFFIX override backup suffix\n");
|
||||
rprintf(F," -u, --update update only (don't overwrite newer files)\n");
|
||||
rprintf(F," -l, --links preserve soft links\n");
|
||||
rprintf(F," -L, --copy-links treat soft links like regular files\n");
|
||||
rprintf(F," -l, --links copy symlinks as symlinks\n");
|
||||
rprintf(F," -L, --copy-links copy the referent of symlinks\n");
|
||||
rprintf(F," --copy-unsafe-links copy links outside the source tree\n");
|
||||
rprintf(F," --safe-links ignore links outside the destination tree\n");
|
||||
rprintf(F," -H, --hard-links preserve hard links\n");
|
||||
@@ -212,7 +230,8 @@ void usage(enum logcode F)
|
||||
rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n");
|
||||
rprintf(F," --version print version number\n");
|
||||
rprintf(F," --daemon run as a rsync daemon\n");
|
||||
rprintf(F," --address bind to the specified address\n");
|
||||
rprintf(F," --no-detach do not detach from the parent\n");
|
||||
rprintf(F," --address=ADDRESS bind to the specified address\n");
|
||||
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
|
||||
rprintf(F," --port=PORT specify alternate rsyncd port number\n");
|
||||
rprintf(F," --blocking-io use blocking IO for the remote shell\n");
|
||||
@@ -221,8 +240,8 @@ void usage(enum logcode F)
|
||||
rprintf(F," --log-format=FORMAT log file transfers using specified format\n");
|
||||
rprintf(F," --password-file=FILE get password from FILE\n");
|
||||
rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
|
||||
rprintf(F," -f --read-batch=EXT read batch file\n");
|
||||
rprintf(F," -F --write-batch write batch file\n");
|
||||
rprintf(F," --read-batch=EXT read batch file\n");
|
||||
rprintf(F," --write-batch write batch file\n");
|
||||
rprintf(F," -h, --help show this help screen\n");
|
||||
#ifdef INET6
|
||||
rprintf(F," -4 prefer IPv4\n");
|
||||
@@ -243,7 +262,7 @@ enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
|
||||
OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
|
||||
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR,
|
||||
OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO,
|
||||
OPT_MODIFY_WINDOW};
|
||||
OPT_MODIFY_WINDOW, OPT_READ_BATCH, OPT_WRITE_BATCH};
|
||||
|
||||
static struct poptOption long_options[] = {
|
||||
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
|
||||
@@ -274,7 +293,7 @@ static struct poptOption long_options[] = {
|
||||
{"update", 'u', POPT_ARG_NONE, &update_only},
|
||||
{"links", 'l', POPT_ARG_NONE, &preserve_links},
|
||||
{"copy-links", 'L', POPT_ARG_NONE, ©_links},
|
||||
{"whole", 'W', POPT_ARG_NONE, &whole_file},
|
||||
{"whole-file", 'W', POPT_ARG_NONE, &whole_file},
|
||||
{"copy-unsafe-links", 0, POPT_ARG_NONE, ©_unsafe_links},
|
||||
{"perms", 'p', POPT_ARG_NONE, &preserve_perms},
|
||||
{"owner", 'o', POPT_ARG_NONE, &preserve_uid},
|
||||
@@ -298,6 +317,7 @@ static struct poptOption long_options[] = {
|
||||
/* TODO: Should this take an optional int giving the compression level? */
|
||||
{"compress", 'z', POPT_ARG_NONE, &do_compression},
|
||||
{"daemon", 0, POPT_ARG_NONE, &am_daemon},
|
||||
{"no-detach", 0, POPT_ARG_NONE, &no_detach},
|
||||
{"stats", 0, POPT_ARG_NONE, &do_stats},
|
||||
{"progress", 0, POPT_ARG_NONE, &do_progress},
|
||||
{"partial", 0, POPT_ARG_NONE, &keep_partial},
|
||||
@@ -311,11 +331,11 @@ static struct poptOption long_options[] = {
|
||||
{"address", 0, POPT_ARG_STRING, &bind_address, 0},
|
||||
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir},
|
||||
{"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links},
|
||||
{"read-batch", 'f', POPT_ARG_STRING, &batch_ext, 'f'},
|
||||
{"write-batch", 'F', POPT_ARG_NONE, &write_batch, 0},
|
||||
{"read-batch", 0, POPT_ARG_STRING, &batch_ext, OPT_READ_BATCH},
|
||||
{"write-batch", 0, POPT_ARG_NONE, &write_batch},
|
||||
#ifdef INET6
|
||||
{0, '4', POPT_ARG_VAL, &af, AF_INET },
|
||||
{0, '6', POPT_ARG_VAL, &af, AF_INET6 },
|
||||
{0, '4', POPT_ARG_VAL, &default_af_hint, AF_INET },
|
||||
{0, '6', POPT_ARG_VAL, &default_af_hint, AF_INET6 },
|
||||
#endif
|
||||
{0,0,0,0}
|
||||
};
|
||||
@@ -491,9 +511,8 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
keep_partial = 1;
|
||||
break;
|
||||
|
||||
|
||||
case 'f':
|
||||
/* The filename is stored for us by popt */
|
||||
case OPT_READ_BATCH:
|
||||
/* The filename is stored in batch_ext for us by popt */
|
||||
read_batch = 1;
|
||||
break;
|
||||
|
||||
@@ -530,7 +549,8 @@ void server_options(char **args,int *argc)
|
||||
static char mdelete[30];
|
||||
static char mwindow[30];
|
||||
static char bw[50];
|
||||
static char fext[20]; /* dw */
|
||||
static char fext[20];
|
||||
static char wbatch[14];
|
||||
|
||||
int i, x;
|
||||
|
||||
@@ -585,8 +605,6 @@ void server_options(char **args,int *argc)
|
||||
argstr[x++] = 'S';
|
||||
if (do_compression)
|
||||
argstr[x++] = 'z';
|
||||
if (write_batch)
|
||||
argstr[x++] = 'F'; /* dw */
|
||||
|
||||
/* this is a complete hack - blame Rusty
|
||||
|
||||
@@ -609,8 +627,13 @@ void server_options(char **args,int *argc)
|
||||
args[ac++] = mdelete;
|
||||
}
|
||||
|
||||
if (write_batch) {
|
||||
snprintf(wbatch,sizeof(wbatch),"--write-batch");
|
||||
args[ac++] = wbatch;
|
||||
}
|
||||
|
||||
if (batch_ext != NULL) {
|
||||
sprintf(fext,"-f%s",batch_ext);
|
||||
snprintf(fext,sizeof(fext),"--read-batch=%s",batch_ext);
|
||||
args[ac++] = fext;
|
||||
}
|
||||
|
||||
|
||||
84
packaging/lsb/rsync.spec
Normal file
84
packaging/lsb/rsync.spec
Normal file
@@ -0,0 +1,84 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.5.1
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
|
||||
Changed target paths to be Linux Standards Base compliant
|
||||
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr --mandir=/usr/share/man
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
|
||||
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/share/man/man1/rsync.1
|
||||
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.4.6
|
||||
Version: 2.5.1
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.4.6.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.4.7pre1
|
||||
Version: 2.5.1
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.4.7pre1.tar.bz2
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
81
packaging/redhat/7.1/rsync.spec.tmpl
Normal file
81
packaging/redhat/7.1/rsync.spec.tmpl
Normal file
@@ -0,0 +1,81 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: PVERSION
|
||||
Release: PRELEASE
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
|
||||
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/man/man1/rsync.1*
|
||||
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
@@ -38,8 +38,8 @@ extern int make_backups;
|
||||
extern char *backup_suffix;
|
||||
|
||||
static struct delete_list {
|
||||
dev_t dev;
|
||||
INO_T inode;
|
||||
DEV64_T dev;
|
||||
INO64_T inode;
|
||||
} *delete_list;
|
||||
static int dlist_len, dlist_alloc_len;
|
||||
|
||||
@@ -206,7 +206,8 @@ static int get_tmpname(char *fnametmp, char *fname)
|
||||
static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
|
||||
OFF_T total_size)
|
||||
{
|
||||
int i,n,remainder,len,count;
|
||||
int i;
|
||||
unsigned int n,remainder,len,count;
|
||||
OFF_T offset = 0;
|
||||
OFF_T offset2;
|
||||
char *data;
|
||||
@@ -488,7 +489,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
}
|
||||
|
||||
if (preserve_hard_links)
|
||||
do_hard_links(flist);
|
||||
do_hard_links();
|
||||
|
||||
/* now we need to fix any directory permissions that were
|
||||
modified during the transfer */
|
||||
|
||||
1
rsync.c
1
rsync.c
@@ -226,7 +226,6 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
|
||||
|
||||
void sig_int(void)
|
||||
{
|
||||
rprintf(FINFO,"\nrsync.c:sig_int() called.\n");
|
||||
exit_cleanup(RERR_SIGNAL);
|
||||
}
|
||||
|
||||
|
||||
81
rsync.h
81
rsync.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Copyright (C) by Andrew Tridgell 1996, 2000
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -49,7 +49,7 @@
|
||||
#define SAME_TIME (1<<7)
|
||||
|
||||
/* update this if you make incompatible changes */
|
||||
#define PROTOCOL_VERSION 25
|
||||
#define PROTOCOL_VERSION 26
|
||||
|
||||
/* We refuse to interoperate with versions that are not in this range.
|
||||
* Note that we assume we'll work with later versions: the onus is on
|
||||
@@ -185,6 +185,10 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
|
||||
#include <glob.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
/* these are needed for the uid/gid mapping code */
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
@@ -263,17 +267,44 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
|
||||
#elif HAVE_LONGLONG
|
||||
#define int64 long long
|
||||
#else
|
||||
/* As long as it gets... */
|
||||
#define int64 off_t
|
||||
#define NO_INT64
|
||||
#endif
|
||||
|
||||
#if HAVE_SHORT_INO_T
|
||||
# define INO_T uint32
|
||||
#elif HAVE_INO_T
|
||||
# define INO_T ino_t
|
||||
#else
|
||||
# define INO_T unsigned
|
||||
#endif
|
||||
/* Starting from protocol version 26, we always use 64-bit
|
||||
* ino_t and dev_t internally, even if this platform does not
|
||||
* allow files to have 64-bit inums. That's because the
|
||||
* receiver needs to find duplicate (dev,ino) tuples to detect
|
||||
* hardlinks, and it might have files coming from a platform
|
||||
* that has 64-bit inums.
|
||||
*
|
||||
* The only exception is if we're on a platform with no 64-bit type at
|
||||
* all.
|
||||
*
|
||||
* Because we use read_longint() to get these off the wire, if you
|
||||
* transfer devices or hardlinks with dev or inum > 2**32 to a machine
|
||||
* with no 64-bit types then you will get an overflow error. Probably
|
||||
* not many people have that combination of machines, and you can
|
||||
* avoid it by not preserving hardlinks or not transferring device
|
||||
* nodes. It's not clear that any other behaviour is better.
|
||||
*
|
||||
* Note that if you transfer devices from a 64-bit-devt machine (say,
|
||||
* Solaris) to a 32-bit-devt machine (say, Linux-2.2/x86) then the
|
||||
* device numbers will be truncated. But it's a kind of silly thing
|
||||
* to do anyhow.
|
||||
*
|
||||
* FIXME: In future, we should probable split the device number into
|
||||
* major/minor, and transfer the two parts as 32-bit ints. That gives
|
||||
* you somewhat more of a chance that they'll come from a big machine
|
||||
* to a little one in a useful way.
|
||||
*
|
||||
* FIXME: Really we need an unsigned type, and we perhaps ought to
|
||||
* cope with platforms on which this is an unsigned int or even a
|
||||
* struct. Later.
|
||||
*/
|
||||
#define INO64_T int64
|
||||
#define DEV64_T int64
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
@@ -304,9 +335,13 @@ struct file_struct {
|
||||
time_t modtime;
|
||||
OFF_T length;
|
||||
mode_t mode;
|
||||
INO_T inode;
|
||||
dev_t dev;
|
||||
dev_t rdev;
|
||||
|
||||
INO64_T inode;
|
||||
/** Device this file lives upon */
|
||||
DEV64_T dev;
|
||||
|
||||
/** If this is a device node, the device number. */
|
||||
DEV64_T rdev;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char *basename;
|
||||
@@ -342,11 +377,11 @@ struct sum_buf {
|
||||
};
|
||||
|
||||
struct sum_struct {
|
||||
OFF_T flength; /* total file length */
|
||||
int count; /* how many chunks */
|
||||
int remainder; /* flength % block_length */
|
||||
int n; /* block_length */
|
||||
struct sum_buf *sums; /* points to info for each chunk */
|
||||
OFF_T flength; /* total file length */
|
||||
size_t count; /* how many chunks */
|
||||
size_t remainder; /* flength % block_length */
|
||||
size_t n; /* block_length */
|
||||
struct sum_buf *sums; /* points to info for each chunk */
|
||||
};
|
||||
|
||||
struct map_struct {
|
||||
@@ -389,7 +424,8 @@ static inline int flist_up(struct file_list *flist, int i)
|
||||
#include "byteorder.h"
|
||||
#include "proto.h"
|
||||
#include "lib/mdfour.h"
|
||||
|
||||
#include "lib/permstring.h"
|
||||
#include "lib/addrinfo.h"
|
||||
|
||||
/* We have replacement versions of these if they're missing. */
|
||||
#ifndef HAVE_ASPRINTF
|
||||
@@ -562,3 +598,12 @@ size_t strlcat(char *d, const char *s, size_t bufsize);
|
||||
|
||||
|
||||
extern int verbose;
|
||||
|
||||
#ifndef HAVE_INET_NTOP
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif /* !HAVE_INET_NTOP */
|
||||
|
||||
#ifndef HAVE_INET_PTON
|
||||
int isc_net_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
|
||||
155
rsync.yo
155
rsync.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsync)(1)(29 May 2001)()()
|
||||
manpage(rsync)(1)(14 Dec 2001)()()
|
||||
manpagename(rsync)(faster, flexible replacement for rcp)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -19,7 +19,7 @@ manpagedescription()
|
||||
|
||||
rsync is a program that behaves in much the same way that rcp does,
|
||||
but has many more options and uses the rsync remote-update protocol to
|
||||
greatly speedup file transfers when the destination file already
|
||||
greatly speed up file transfers when the destination file already
|
||||
exists.
|
||||
|
||||
The rsync remote-update protocol allows rsync to transfer just the
|
||||
@@ -81,7 +81,7 @@ Once installed you can use rsync to any machine that you can use rsh
|
||||
to. rsync uses rsh for its communications, unless both the source and
|
||||
destination are local.
|
||||
|
||||
You can also specify an alternative to rsh, by either using the -e
|
||||
You can also specify an alternative to rsh, either by using the -e
|
||||
command line option, or by setting the RSYNC_RSH environment variable.
|
||||
|
||||
One common substitute is to use ssh, which offers a high degree of
|
||||
@@ -139,10 +139,10 @@ It is also possible to use rsync without using rsh or ssh as the
|
||||
transport. In this case you will connect to a remote rsync server
|
||||
running on TCP port 873.
|
||||
|
||||
You may establish the connetcion via a web proxy by setting the
|
||||
You may establish the connection via a web proxy by setting the
|
||||
environment variable RSYNC_PROXY to a hostname:port pair pointing to
|
||||
your web proxy. Note that your web proxy must allow proxying to port
|
||||
873, this must be configured in your proxy servers ruleset.
|
||||
your web proxy. Note that your web proxy's configuration must allow
|
||||
proxying to port 873.
|
||||
|
||||
Using rsync in this way is the same as using it with rsh or ssh except
|
||||
that:
|
||||
@@ -226,8 +226,8 @@ verb(
|
||||
--backup-dir make backups into this directory
|
||||
--suffix=SUFFIX override backup suffix
|
||||
-u, --update update only (don't overwrite newer files)
|
||||
-l, --links preserve soft links
|
||||
-L, --copy-links treat soft links like regular files
|
||||
-l, --links copy symlinks as symlinks
|
||||
-L, --copy-links copy the referent of symlinks
|
||||
--copy-unsafe-links copy links outside the source tree
|
||||
--safe-links ignore links outside the destination tree
|
||||
-H, --hard-links preserve hard links
|
||||
@@ -267,7 +267,8 @@ verb(
|
||||
--include-from=FILE don't exclude patterns listed in FILE
|
||||
--version print version number
|
||||
--daemon run as a rsync daemon
|
||||
--address bind to the specified address
|
||||
--no-detach do not detach from the parent
|
||||
--address=ADDRESS bind to the specified address
|
||||
--config=FILE specify alternate rsyncd.conf file
|
||||
--port=PORT specify alternate rsyncd port number
|
||||
--blocking-io use blocking IO for the remote shell
|
||||
@@ -276,8 +277,8 @@ verb(
|
||||
--log-format=FORMAT log file transfers using specified format
|
||||
--password-file=FILE get password from FILE
|
||||
--bwlimit=KBPS limit I/O bandwidth, KBytes per second
|
||||
-f, --read-batch=FILE read batch file
|
||||
-F, --write-batch write batch file
|
||||
--read-batch=FILE read batch file
|
||||
--write-batch write batch file
|
||||
-h, --help show this help screen
|
||||
|
||||
|
||||
@@ -334,8 +335,13 @@ explicitly checked on the receiver and any files of the same name
|
||||
which already exist and have the same checksum and size on the
|
||||
receiver are skipped. This option can be quite slow.
|
||||
|
||||
dit(bf(-a, --archive)) This is equivalent to -rlptgoD. It is a quick way
|
||||
of saying you want recursion and want to preserve everything.
|
||||
dit(bf(-a, --archive)) This is equivalent to -rlptgoD. It is a quick
|
||||
way of saying you want recursion and want to preserve almost
|
||||
everything.
|
||||
|
||||
Note however that bf(-a) bf(does not preserve hardlinks), because
|
||||
finding multiply-linked files is expensive. You must separately
|
||||
specify bf(-H).
|
||||
|
||||
dit(bf(-r, --recursive)) This tells rsync to copy directories
|
||||
recursively. If you don't specify this then rsync won't copy
|
||||
@@ -372,17 +378,16 @@ dit(bf(-u, --update)) This forces rsync to skip any files for which the
|
||||
destination file already exists and has a date later than the source
|
||||
file.
|
||||
|
||||
dit(bf(-l, --links)) This tells rsync to recreate symbolic links on the
|
||||
remote system to be the same as the local system. Without this
|
||||
option, all symbolic links are skipped.
|
||||
dit(bf(-l, --links)) When symlinks are encountered, recreate the
|
||||
symlink on the destination.
|
||||
|
||||
dit(bf(-L, --copy-links)) This tells rsync to treat symbolic links just
|
||||
like ordinary files.
|
||||
dit(bf(-L, --copy-links)) When symlinks are encountered, the file that
|
||||
they point to is copied, rather than the symlink.
|
||||
|
||||
dit(bf(--copy-unsafe-links)) This tells rsync to treat symbolic links that
|
||||
point outside the source tree like ordinary files. Absolute symlinks are
|
||||
also treated like ordinary files, and so are any symlinks in the source
|
||||
path itself when --relative is used.
|
||||
dit(bf(--copy-unsafe-links)) This tells rsync to copy the referent of
|
||||
symbolic links that point outside the source tree. Absolute symlinks
|
||||
are also treated like ordinary files, and so are any symlinks in the
|
||||
source path itself when --relative is used.
|
||||
|
||||
dit(bf(--safe-links)) This tells rsync to ignore any symbolic links
|
||||
which point outside the destination tree. All absolute symlinks are
|
||||
@@ -408,16 +413,15 @@ the source and target are on the local machine.
|
||||
dit(bf(-p, --perms)) This option causes rsync to update the remote
|
||||
permissions to be the same as the local permissions.
|
||||
|
||||
dit(bf(-o, --owner)) This option causes rsync to update the remote owner
|
||||
of the file to be the same as the local owner. This is only available
|
||||
to the super-user. Note that if the source system is a daemon using chroot,
|
||||
the --numeric-ids option is implied because the source system cannot get
|
||||
access to the usernames.
|
||||
dit(bf(-o, --owner)) This option causes rsync to set the owner of the
|
||||
destination file to be the same as the source file. On most systems,
|
||||
only the super-user can set file ownership.
|
||||
|
||||
dit(bf(-g, --group)) This option causes rsync to update the remote group
|
||||
of the file to be the same as the local group. If the receving system is
|
||||
not running as the super-user, only groups that the receiver is a member of
|
||||
will be preserved (by group name, not group id number).
|
||||
dit(bf(-g, --group)) This option causes rsync to set the group of the
|
||||
destination file to be the same as the source file. If the receiving
|
||||
program is not running as the super-user, only groups that the
|
||||
receiver is a member of will be preserved (by group name, not group id
|
||||
number).
|
||||
|
||||
dit(bf(-D, --devices)) This option causes rsync to transfer character and
|
||||
block device information to the remote system to recreate these
|
||||
@@ -488,7 +492,7 @@ contains a directory of the same name.
|
||||
Since this option was added, deletions were reordered to be done depth-first
|
||||
so it is hardly ever needed anymore except in very obscure cases.
|
||||
|
||||
dit(bf(-B , --block_size=BLOCKSIZE)) This controls the block size used in
|
||||
dit(bf(-B , --block-size=BLOCKSIZE)) This controls the block size used in
|
||||
the rsync algorithm. See the technical report for details.
|
||||
|
||||
dit(bf(-e, --rsh=COMMAND)) This option allows you to choose an alternative
|
||||
@@ -545,8 +549,9 @@ quote(RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state
|
||||
then files listed in a $HOME/.cvsignore are added to the list and any
|
||||
files listed in the CVSIGNORE environment variable (space delimited).
|
||||
|
||||
Finally in each directory any files listed in the .cvsignore file in
|
||||
that directory are added to the list.
|
||||
Finally, any file is ignored if it is in the same directory as a
|
||||
.cvsignore file and matches one of the patterns listed therein. See
|
||||
the bf(cvs(1)) manual for more information.
|
||||
|
||||
dit(bf(--csum-length=LENGTH)) By default the primary checksum used in
|
||||
rsync is a very strong 16 byte MD4 checksum. In most cases you will
|
||||
@@ -603,21 +608,33 @@ what ownership to give files. The special uid 0 and the special group
|
||||
0 are never mapped via user/group names even if the --numeric-ids
|
||||
option is not specified.
|
||||
|
||||
If the source system is a daemon using chroot, or if a user or group name
|
||||
does not exist on the destination system, then the numeric id from the
|
||||
source system is used instead.
|
||||
If the source system is a daemon using chroot, or if a user or group
|
||||
name does not exist on the destination system, then the numeric id
|
||||
from the source system is used instead.
|
||||
|
||||
dit(bf(--timeout=TIMEOUT)) This option allows you to set a maximum IO
|
||||
timeout in seconds. If no data is transferred for the specified time
|
||||
then rsync will exit. The default is 0, which means no timeout.
|
||||
|
||||
dit(bf(--daemon)) This tells rsync that it is to run as a rsync
|
||||
daemon. If standard input is a socket then rsync will assume that it
|
||||
is being run via inetd, otherwise it will detach from the current
|
||||
terminal and become a background daemon. The daemon will read the
|
||||
config file (/etc/rsyncd.conf) on each connect made by a client and
|
||||
respond to requests accordingly. See the rsyncd.conf(5) man page for more
|
||||
details.
|
||||
dit(bf(--daemon)) This tells rsync that it is to run as a daemon. The
|
||||
daemon may be accessed using the bf(host::module) or
|
||||
bf(rsync://host/module/) syntax.
|
||||
|
||||
If standard input is a socket then rsync will assume that it is being
|
||||
run via inetd, otherwise it will detach from the current terminal and
|
||||
become a background daemon. The daemon will read the config file
|
||||
(/etc/rsyncd.conf) on each connect made by a client and respond to
|
||||
requests accordingly. See the rsyncd.conf(5) man page for more
|
||||
details.
|
||||
|
||||
dit(bf(--no-detach)) When running as a daemon, this option instructs
|
||||
rsync to not detach itself and become a background process. This
|
||||
option is required when running as a service on Cygwin, and may also
|
||||
be useful when rsync is supervised by a program such as
|
||||
bf(daemontools) or AIX's bf(System Resource Controller).
|
||||
bf(--no-detach) is also recommended when rsync is run under a
|
||||
debugger. This option has no effect if rsync is run from inetd or
|
||||
sshd.
|
||||
|
||||
dit(bf(--address)) By default rsync will bind to the wildcard address
|
||||
when run as a daemon with the --daemon option or when connecting to a
|
||||
@@ -691,7 +708,7 @@ manpagesection(EXCLUDE PATTERNS)
|
||||
The exclude and include patterns specified to rsync allow for flexible
|
||||
selection of which files to transfer and which files to skip.
|
||||
|
||||
rsync builds a ordered list of include/exclude options as specified on
|
||||
rsync builds an ordered list of include/exclude options as specified on
|
||||
the command line. When a filename is encountered, rsync checks the
|
||||
name against each exclude/include pattern in turn. The first matching
|
||||
pattern is acted on. If it is an exclude pattern, then that file is
|
||||
@@ -744,7 +761,7 @@ itemize(
|
||||
part of an include option. The "- " part is discarded before matching.
|
||||
|
||||
it() if the pattern is a single exclamation mark ! then the current
|
||||
exclude list is reset, removing all previous exclude patterns.
|
||||
include/exclude list is reset, removing all previously defined patterns.
|
||||
)
|
||||
|
||||
The +/- rules are most useful in exclude lists, allowing you to have a
|
||||
@@ -776,12 +793,15 @@ itemize(
|
||||
|
||||
manpagesection(BATCH MODE)
|
||||
|
||||
bf(Note:) Batch mode should be considered experimental in this version
|
||||
of rsync. The interface or behaviour may change before it stabilizes.
|
||||
|
||||
The following call generates 4 files that encapsulate the information
|
||||
for synchronizing the contents of bf(target_dir) with the updates found in
|
||||
bf(src_dir)
|
||||
|
||||
quote(
|
||||
$ rsync -F [other rsync options here] \nl()
|
||||
$ rsync --write-batch [other rsync options here] \nl()
|
||||
/somewhere/src_dir /somewhere/target_dir
|
||||
)
|
||||
|
||||
@@ -797,6 +817,29 @@ it() bf(rsync_delta.<timestamp>) data blocks for file update & change
|
||||
See bf(http://www.ils.unc.edu/i2dsi/unc_rsync+.html) for papers and technical
|
||||
reports.
|
||||
|
||||
manpagesection(SYMBOLIC LINKS)
|
||||
|
||||
Three basic behaviours are possible when rsync encounters a symbolic
|
||||
link in the source directory.
|
||||
|
||||
By default, symbolic links are not transferred at all. A message
|
||||
"skipping non-regular" file is emitted for any symlinks that exist.
|
||||
|
||||
If bf(--links) is specified, then symlinks are recreated with the same
|
||||
target on the destination. Note that bf(--archive) implies
|
||||
bf(--links).
|
||||
|
||||
If bf(--copy-links) is specified, then symlinks are "collapsed" by
|
||||
copying their referent, rather than the symlink.
|
||||
|
||||
rsync also distinguishes "safe" and "unsafe" symbolic links. An
|
||||
example where this might be used is a web site mirror that wishes
|
||||
ensure the rsync module they copy does not include symbolic links to
|
||||
bf(/etc/passwd) in the public section of the site. Using
|
||||
bf(--copy-unsafe-links) will cause any links to be copied as the file
|
||||
they point to on the destination. Using bf(--safe-links) will cause
|
||||
unsafe links to be ommitted altogether.
|
||||
|
||||
manpagesection(DIAGNOSTICS)
|
||||
|
||||
rsync occasionally produces error messages that may seem a little
|
||||
@@ -922,16 +965,22 @@ Jean-loup Gailly and Mark Adler.
|
||||
manpagesection(THANKS)
|
||||
|
||||
Thanks to Richard Brent, Brendan Mackay, Bill Waite, Stephen Rothwell
|
||||
and David Bell for helpful suggestions and testing of rsync. I've
|
||||
probably missed some people, my apologies if I have.
|
||||
and David Bell for helpful suggestions, patches and testing of rsync.
|
||||
I've probably missed some people, my apologies if I have.
|
||||
|
||||
Especial thanks also to: David Dykstra, Jos Backus, Sebastian Krahmer.
|
||||
|
||||
|
||||
manpageauthor()
|
||||
|
||||
rsync was written by Andrew Tridgell and Paul Mackerras. They may be
|
||||
contacted via email at tridge@samba.org and
|
||||
Paul.Mackerras@cs.anu.edu.au
|
||||
rsync was written by Andrew Tridgell <tridge@samba.org> and Paul
|
||||
Mackerras.
|
||||
|
||||
rsync is now also maintained by Martin Pool <mbp@samba.org>
|
||||
rsync is now maintained by Martin Pool <mbp@samba.org>.
|
||||
|
||||
Mailing lists for support and development are available at
|
||||
url(http://lists.samba.org)(lists.samba.org)
|
||||
|
||||
If you suspect you have found a security vulnerability in rsync,
|
||||
please send it directly to Martin Pool and Andrew Tridgell. For other
|
||||
enquiries, please use the mailing list.
|
||||
|
||||
79
runtests.sh
79
runtests.sh
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
# Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version
|
||||
@@ -160,16 +160,27 @@ missing=0
|
||||
passed=0
|
||||
failed=0
|
||||
|
||||
scratchdir=./testtmp
|
||||
[ -d "$scratchdir" ] && rm -r "$scratchdir"
|
||||
mkdir "$scratchdir"
|
||||
scratchdir=`cd $scratchdir && pwd`
|
||||
echo " scratchdir=$scratchdir"
|
||||
# Prefix for scratch directory. We create separate directories for
|
||||
# each test case, so that they can be left behind in case of failure
|
||||
# to aid investigation.
|
||||
scratchbase="`pwd`"/testtmp
|
||||
echo " scratchbase=$scratchbase"
|
||||
|
||||
suitedir="$srcdir/testsuite"
|
||||
|
||||
export scratchdir suitedir
|
||||
|
||||
prep_scratch() {
|
||||
[ -d "$scratchdir" ] && rm -rf "$scratchdir"
|
||||
mkdir "$scratchdir"
|
||||
return 0
|
||||
}
|
||||
|
||||
discard_scratch() {
|
||||
[ -d "$scratchdir" ] && rm -rf "$scratchdir"
|
||||
return 0
|
||||
}
|
||||
|
||||
if [ "x$whichtests" = x ]
|
||||
then
|
||||
whichtests="*.test"
|
||||
@@ -177,29 +188,45 @@ fi
|
||||
|
||||
for testscript in $suitedir/$whichtests
|
||||
do
|
||||
testbase=`echo $testscript | sed 's!.*/!!'`
|
||||
testbase=`echo $testscript | sed 's!.*/!!' | sed -e 's/.test\$//'`
|
||||
scratchdir="$scratchbase.$testbase"
|
||||
|
||||
echo "----- $testbase starting"
|
||||
prep_scratch
|
||||
|
||||
if sh $RUNSHFLAGS "$testscript"
|
||||
then
|
||||
echo "----- $testbase completed succesfully"
|
||||
set +e
|
||||
sh $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1
|
||||
result=$?
|
||||
set -e
|
||||
|
||||
case $result in
|
||||
0)
|
||||
echo "PASS $testbase"
|
||||
passed=`expr $passed + 1`
|
||||
else
|
||||
case $? in
|
||||
77)
|
||||
echo "----- $testbase skipped"
|
||||
skipped=`expr $skipped + 1`
|
||||
;;
|
||||
*)
|
||||
echo "----- $testbase failed!"
|
||||
failed=`expr $failed + 1`
|
||||
if [ "x$nopersist" = "xyes" ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
esac
|
||||
fi
|
||||
discard_scratch
|
||||
;;
|
||||
77)
|
||||
echo "SKIP $testbase"
|
||||
skipped=`expr $skipped + 1`
|
||||
discard_scratch
|
||||
;;
|
||||
78)
|
||||
# It failed, but we expected that. don't dump out error logs,
|
||||
# because most users won't want to see them. But do leave
|
||||
# the working directory around.
|
||||
echo "XFAIL $testbase"
|
||||
failed=`expr $failed + 1`
|
||||
;;
|
||||
*)
|
||||
echo "FAIL $testbase"
|
||||
echo "----- $testbase failed: log follows"
|
||||
cat "$scratchdir/test.log"
|
||||
echo "----- $testbase log ends"
|
||||
failed=`expr $failed + 1`
|
||||
if [ "x$nopersist" = "xyes" ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
esac
|
||||
done
|
||||
|
||||
echo '------------------------------------------------------------'
|
||||
|
||||
5
sender.c
5
sender.c
@@ -159,13 +159,14 @@ void send_files(struct file_list *flist,int f_out,int f_in)
|
||||
initial_stats = stats;
|
||||
|
||||
s = receive_sums(f_in);
|
||||
if (write_batch) /* dw */
|
||||
write_batch_csum_info(&i,flist->count,s);
|
||||
if (!s) {
|
||||
io_error = 1;
|
||||
rprintf(FERROR,"receive_sums failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (write_batch)
|
||||
write_batch_csum_info(&i,flist->count,s);
|
||||
|
||||
if (!read_batch) {
|
||||
fd = do_open(fname, O_RDONLY, 0);
|
||||
|
||||
314
socket.c
314
socket.c
@@ -1,7 +1,9 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
rsync -- fast file replication program
|
||||
|
||||
Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -18,19 +20,19 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
socket functions used in rsync
|
||||
|
||||
*/
|
||||
/**
|
||||
* @file socket.c
|
||||
*
|
||||
* Socket functions used in rsync.
|
||||
*
|
||||
* This file is now converted to use the new-style getaddrinfo()
|
||||
* interface, which supports IPv6 but is also supported on recent
|
||||
* IPv4-only machines. On systems that don't have that interface, we
|
||||
* emulate it using the KAME implementation.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
#include "lib/addrinfo.h"
|
||||
#endif
|
||||
|
||||
extern int af;
|
||||
|
||||
/* Establish a proxy connection on an open socket to a web roxy by
|
||||
* using the CONNECT method. */
|
||||
static int establish_proxy_connection(int fd, char *host, int port)
|
||||
@@ -95,20 +97,66 @@ static int establish_proxy_connection(int fd, char *host, int port)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Open a socket to a tcp remote host with the specified port .
|
||||
*
|
||||
* Based on code from Warren. Proxy support by Stephen Rothwell
|
||||
*
|
||||
*
|
||||
* @param bind_address Local address to use. Normally NULL to get the stack default.
|
||||
/**
|
||||
* Try to set the local address for a newly-created socket. Return -1
|
||||
* if this fails.
|
||||
**/
|
||||
int open_socket_out(char *host, int port, const char *bind_address)
|
||||
int try_bind_local(int s,
|
||||
int ai_family, int ai_socktype,
|
||||
const char *bind_address)
|
||||
{
|
||||
int error;
|
||||
struct addrinfo bhints, *bres_all, *r;
|
||||
|
||||
memset(&bhints, 0, sizeof(bhints));
|
||||
bhints.ai_family = ai_family;
|
||||
bhints.ai_socktype = ai_socktype;
|
||||
bhints.ai_flags = AI_PASSIVE;
|
||||
if ((error = getaddrinfo(bind_address, NULL, &bhints, &bres_all))) {
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo %s: %s\n",
|
||||
bind_address, gai_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (r = bres_all; r; r = r->ai_next) {
|
||||
if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
|
||||
continue;
|
||||
return s;
|
||||
}
|
||||
|
||||
/* no error message; there might be some problem that allows
|
||||
* creation of the socket but not binding, perhaps if the
|
||||
* machine has no ipv6 address of this name. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open a socket to a tcp remote host with the specified port .
|
||||
*
|
||||
* Based on code from Warren. Proxy support by Stephen Rothwell.
|
||||
* getaddrinfo() rewrite contributed by KAME.net.
|
||||
*
|
||||
* Now that we support IPv6 we need to look up the remote machine's
|
||||
* address first, using @p af_hint to set a preference for the type
|
||||
* of address. Then depending on whether it has v4 or v6 addresses we
|
||||
* try to open a connection.
|
||||
*
|
||||
* The loop allows for machines with some addresses which may not be
|
||||
* reachable, perhaps because we can't e.g. route ipv6 to that network
|
||||
* but we can get ip4 packets through.
|
||||
*
|
||||
* @param bind_address Local address to use. Normally NULL to bind
|
||||
* the wildcard address.
|
||||
*
|
||||
* @param af_hint Address family, e.g. AF_INET or AF_INET6.
|
||||
**/
|
||||
int open_socket_out(char *host, int port, const char *bind_address,
|
||||
int af_hint)
|
||||
{
|
||||
int type = SOCK_STREAM;
|
||||
int error;
|
||||
int s;
|
||||
int result;
|
||||
struct addrinfo hints, *res0, *res;
|
||||
char portbuf[10];
|
||||
char *h;
|
||||
@@ -139,41 +187,32 @@ int open_socket_out(char *host, int port, const char *bind_address)
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = af;
|
||||
hints.ai_family = af_hint;
|
||||
hints.ai_socktype = type;
|
||||
error = getaddrinfo(h, portbuf, &hints, &res0);
|
||||
if (error) {
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s: %s\n", portbuf, gai_strerror(error));
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
|
||||
h, portbuf, gai_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
s = -1;
|
||||
/* Try to connect to all addresses for this machine until we get
|
||||
* through. It might e.g. be multi-homed, or have both IPv4 and IPv6
|
||||
* addresses. We need to create a socket for each record, since the
|
||||
* address record tells us what protocol to use to try to connect. */
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (s < 0)
|
||||
continue;
|
||||
|
||||
if (bind_address) {
|
||||
struct addrinfo bhints, *bres;
|
||||
|
||||
memset(&bhints, 0, sizeof(bhints));
|
||||
bhints.ai_family = res->ai_family;
|
||||
bhints.ai_socktype = type;
|
||||
bhints.ai_flags = AI_PASSIVE;
|
||||
error = getaddrinfo(bind_address, NULL, &bhints, &bres);
|
||||
if (error) {
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
|
||||
bind_address, gai_strerror(error));
|
||||
if (bind_address)
|
||||
if (try_bind_local(s, res->ai_family, type,
|
||||
bind_address) == -1) {
|
||||
close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
if (bres->ai_next) {
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s resolved to multiple hosts\n",
|
||||
bind_address);
|
||||
freeaddrinfo(bres);
|
||||
continue;
|
||||
}
|
||||
bind(s, bres->ai_addr, bres->ai_addrlen);
|
||||
}
|
||||
|
||||
if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
|
||||
close(s);
|
||||
@@ -212,14 +251,16 @@ int open_socket_out(char *host, int port, const char *bind_address)
|
||||
**/
|
||||
int open_socket_out_wrapped (char *host,
|
||||
int port,
|
||||
const char *bind_address)
|
||||
const char *bind_address,
|
||||
int af_hint)
|
||||
{
|
||||
char *prog;
|
||||
|
||||
if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
|
||||
return sock_exec (prog);
|
||||
else
|
||||
return open_socket_out (host, port, bind_address);
|
||||
return open_socket_out (host, port, bind_address,
|
||||
af_hint);
|
||||
}
|
||||
|
||||
|
||||
@@ -227,55 +268,73 @@ int open_socket_out_wrapped (char *host,
|
||||
/**
|
||||
* Open a socket of the specified type, port and address for incoming data
|
||||
*
|
||||
* Try to be better about handling the results of getaddrinfo(): when
|
||||
* opening an inbound socket, we might get several address results,
|
||||
* e.g. for the machine's ipv4 and ipv6 name.
|
||||
*
|
||||
* If binding a wildcard, then any one of them should do. If an address
|
||||
* was specified but it's insufficiently specific then that's not our
|
||||
* fault.
|
||||
*
|
||||
* However, some of the advertized addresses may not work because e.g. we
|
||||
* don't have IPv6 support in the kernel. In that case go on and try all
|
||||
* addresses until one succeeds.
|
||||
*
|
||||
* @param bind_address Local address to bind, or NULL to allow it to
|
||||
* default.
|
||||
**/
|
||||
static int open_socket_in(int type, int port, const char *bind_address)
|
||||
static int open_socket_in(int type, int port, const char *bind_address,
|
||||
int af_hint)
|
||||
{
|
||||
int one=1;
|
||||
int s;
|
||||
struct addrinfo hints, *res;
|
||||
struct addrinfo hints, *all_ai, *resp;
|
||||
char portbuf[10];
|
||||
int error;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = af;
|
||||
hints.ai_family = af_hint;
|
||||
hints.ai_socktype = type;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
snprintf(portbuf, sizeof(portbuf), "%d", port);
|
||||
error = getaddrinfo(bind_address, portbuf, &hints, &res);
|
||||
error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
|
||||
if (error) {
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
|
||||
bind_address, gai_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
if (res->ai_next) {
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: "
|
||||
"resolved to multiple hosts\n",
|
||||
bind_address);
|
||||
freeaddrinfo(res);
|
||||
return -1;
|
||||
|
||||
/* We may not be able to create the socket, if for example the
|
||||
* machine knows about IPv6 in the C library, but not in the
|
||||
* kernel. */
|
||||
for (resp = all_ai; resp; resp = resp->ai_next) {
|
||||
s = socket(resp->ai_family, resp->ai_socktype,
|
||||
resp->ai_protocol);
|
||||
|
||||
if (s == -1)
|
||||
/* See if there's another address that will work... */
|
||||
continue;
|
||||
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *)&one, sizeof one);
|
||||
|
||||
/* now we've got a socket - we need to bind it */
|
||||
if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
|
||||
/* Nope, try another */
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (s < 0) {
|
||||
rprintf(FERROR, RSYNC_NAME ": open socket in failed: %s\n",
|
||||
strerror(errno));
|
||||
freeaddrinfo(res);
|
||||
return -1;
|
||||
}
|
||||
rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
|
||||
"%s\n",
|
||||
port,
|
||||
strerror(errno));
|
||||
|
||||
setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
|
||||
|
||||
/* now we've got a socket - we need to bind it */
|
||||
if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
|
||||
rprintf(FERROR, RSYNC_NAME ": bind failed on port %d\n", port);
|
||||
freeaddrinfo(res);
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return s;
|
||||
freeaddrinfo(all_ai);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -309,9 +368,10 @@ void start_accept_loop(int port, int (*fn)(int ))
|
||||
{
|
||||
int s;
|
||||
extern char *bind_address;
|
||||
extern int default_af_hint;
|
||||
|
||||
/* open an incoming socket */
|
||||
s = open_socket_in(SOCK_STREAM, port, bind_address);
|
||||
s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
|
||||
if (s == -1)
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
|
||||
@@ -328,7 +388,7 @@ void start_accept_loop(int port, int (*fn)(int ))
|
||||
fd_set fds;
|
||||
int fd;
|
||||
struct sockaddr_storage addr;
|
||||
int in_addrlen = sizeof(addr);
|
||||
socklen_t addrlen = sizeof addr;
|
||||
|
||||
/* close log file before the potentially very long select so
|
||||
file can be trimmed by another process instead of growing
|
||||
@@ -344,7 +404,7 @@ void start_accept_loop(int port, int (*fn)(int ))
|
||||
|
||||
if(!FD_ISSET(s, &fds)) continue;
|
||||
|
||||
fd = accept(s,(struct sockaddr *)&addr,&in_addrlen);
|
||||
fd = accept(s,(struct sockaddr *)&addr,&addrlen);
|
||||
|
||||
if (fd == -1) continue;
|
||||
|
||||
@@ -505,13 +565,13 @@ void become_daemon(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
return the IP addr of the client as a string
|
||||
******************************************************************/
|
||||
/**
|
||||
* Return the IP addr of the client as a string
|
||||
**/
|
||||
char *client_addr(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
int length = sizeof(ss);
|
||||
socklen_t length = sizeof ss;
|
||||
static char addr_buf[100];
|
||||
static int initialised;
|
||||
|
||||
@@ -529,13 +589,19 @@ char *client_addr(int fd)
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
return the DNS name of the client
|
||||
******************************************************************/
|
||||
static int get_sockaddr_family(const struct sockaddr_storage *ss)
|
||||
{
|
||||
return ((struct sockaddr *) ss)->sa_family;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the DNS name of the client
|
||||
**/
|
||||
char *client_name(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
int length = sizeof(ss);
|
||||
socklen_t length = sizeof ss;
|
||||
static char name_buf[100];
|
||||
static char port_buf[100];
|
||||
char *def = "UNKNOWN";
|
||||
@@ -550,12 +616,21 @@ char *client_name(int fd)
|
||||
strcpy(name_buf,def);
|
||||
|
||||
if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
|
||||
/* FIXME: Can we really not continue? */
|
||||
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
|
||||
fd, strerror(errno));
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
if (ss.ss_family == AF_INET6 &&
|
||||
if (get_sockaddr_family(&ss) == AF_INET6 &&
|
||||
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&ss)->sin6_addr)) {
|
||||
/* OK, so ss is in the IPv6 family, but it is really
|
||||
* an IPv4 address: something like
|
||||
* "::ffff:10.130.1.2". If we use it as-is, then the
|
||||
* reverse lookup might fail or perhaps something else
|
||||
* bad might happen. So instead we convert it to an
|
||||
* equivalent address in the IPv4 address family. */
|
||||
struct sockaddr_in6 sin6;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
@@ -568,6 +643,9 @@ char *client_name(int fd)
|
||||
sin->sin_len = length;
|
||||
#endif
|
||||
sin->sin_port = sin6.sin6_port;
|
||||
/* FIXME: Isn't there a macro we can use here rather
|
||||
* than grovelling through the struct? It might be
|
||||
* wrong on some systems. */
|
||||
memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
|
||||
sizeof(sin->sin_addr));
|
||||
}
|
||||
@@ -598,7 +676,7 @@ char *client_name(int fd)
|
||||
|
||||
/* XXX sin6_flowinfo and other fields */
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
if (res->ai_family != ss.ss_family)
|
||||
if (res->ai_family != get_sockaddr_family(&ss))
|
||||
continue;
|
||||
if (res->ai_addrlen != length)
|
||||
continue;
|
||||
@@ -606,79 +684,17 @@ char *client_name(int fd)
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: Do a forward lookup as well to prevent spoofing */
|
||||
|
||||
if (res == NULL) {
|
||||
strcpy(name_buf, def);
|
||||
rprintf(FERROR,
|
||||
"reverse name lookup mismatch - spoofed address?\n");
|
||||
rprintf(FERROR, RSYNC_NAME ": "
|
||||
"reverse name lookup for \"%s\" failed on fd%d - spoofed address? \n",
|
||||
name_buf, fd);
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
return name_buf;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a string to an IP address. The string can be a name or
|
||||
dotted decimal number.
|
||||
|
||||
Returns a pointer to a static in_addr struct -- if you call this
|
||||
more than once then you should copy it.
|
||||
*/
|
||||
struct in_addr *ip_address(const char *str)
|
||||
{
|
||||
static struct in_addr ret;
|
||||
struct hostent *hp;
|
||||
|
||||
if (!str) {
|
||||
rprintf (FERROR, "ip_address received NULL name\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* try as an IP address */
|
||||
if (inet_aton(str, &ret) != 0) {
|
||||
return &ret;
|
||||
}
|
||||
|
||||
/* otherwise assume it's a network name of some sort and use
|
||||
gethostbyname */
|
||||
if ((hp = gethostbyname (str)) == 0) {
|
||||
rprintf(FERROR, "gethostbyname failed for \"%s\": unknown host?\n",str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hp->h_addr == NULL) {
|
||||
rprintf(FERROR, "gethostbyname: host address is invalid for host \"%s\"\n",str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hp->h_length > sizeof ret) {
|
||||
rprintf(FERROR, "gethostbyname: host address for \"%s\" is too large\n",
|
||||
str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hp->h_addrtype != AF_INET) {
|
||||
rprintf (FERROR, "gethostname: host address for \"%s\" is not IPv4\n",
|
||||
str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is kind of difficult. The only field in ret is
|
||||
s_addr, which is the IP address as a 32-bit int. On
|
||||
UNICOS, s_addr is in fact a *bitfield* for reasons best
|
||||
know to Cray. This means we can't memcpy in to it. On the
|
||||
other hand, h_addr is a char*, so we can't just assign.
|
||||
|
||||
Since there's meant to be only one field inside the in_addr
|
||||
structure we will try just copying over the top and see how
|
||||
that goes. */
|
||||
memcpy (&ret, hp->h_addr, hp->h_length);
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
this is like socketpair but uses tcp. It is used by the Samba
|
||||
|
||||
@@ -132,7 +132,7 @@ int do_mkstemp(char *template, mode_t perms)
|
||||
}
|
||||
#else
|
||||
if (!mktemp(template)) return -1;
|
||||
return open(template, O_RDWR|O_EXCL|O_CREAT, perms);
|
||||
return do_open(template, O_RDWR|O_EXCL|O_CREAT, perms);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
57
testsuite/duplicates.test
Normal file
57
testsuite/duplicates.test
Normal file
@@ -0,0 +1,57 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync handling of duplicate filenames.
|
||||
|
||||
# It's quite possible that the user might specify the same source file
|
||||
# more than once on the command line, perhaps through shell variables
|
||||
# or wildcard expansions. It might cause problems for rsync if the
|
||||
# same name occurred more than once in the file list, because we might
|
||||
# be trying to update the first copy and generate checksums for the
|
||||
# second copy at the same time. See clean_flist() for the implementation.
|
||||
|
||||
# We don't need to worry about hardlinks or symlinks. Because we
|
||||
# always rename-and-replace the new copy, they can't affect us.
|
||||
|
||||
# This test is not great, because it is a timing-dependent bug.
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
echo "SKIP THIS FOR NOW; It's a known bug"
|
||||
exit 77
|
||||
|
||||
set -x
|
||||
|
||||
# Build some hardlinks
|
||||
|
||||
fromdir="$scratchdir/from"
|
||||
todir="$scratchdir/to"
|
||||
|
||||
mkdir "$fromdir"
|
||||
name1="$fromdir/name1"
|
||||
name2="$fromdir/name2"
|
||||
echo "This is the file" > "$name1"
|
||||
ln -s "$name1" "$name2" || fail "can't create symlink"
|
||||
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
checkit "rsync -avv \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
|
||||
| tee "$outfile"
|
||||
|
||||
# Make sure each file was only copied once...
|
||||
if [ `grep -c '^name1$' "$outfile"` != 1 ]
|
||||
then
|
||||
test_xfail "name1 was not copied exactly once"
|
||||
fi
|
||||
if [ `grep -c '^name2$' "$outfile"` != 1 ]
|
||||
then
|
||||
test_xfail "name2 was not copied exactly once"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
@@ -26,3 +26,5 @@ cp ${FROM}/text ${TO}/ThisShouldGo
|
||||
runtest " --delete" 'checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
|
||||
|
||||
checkforlogs ${LOG}.?
|
||||
|
||||
hands_cleanup
|
||||
38
testsuite/hardlinks.test
Normal file
38
testsuite/hardlinks.test
Normal file
@@ -0,0 +1,38 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync handling of hardlinks. By default (in 2.5.1) rsync does
|
||||
# not detect symlinks and they get split into different files. If you
|
||||
# specify -H, then hard links are detected and recreated as hardlinks
|
||||
# on the other end.
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
set -x
|
||||
|
||||
# Build some hardlinks
|
||||
|
||||
fromdir="$scratchdir/from"
|
||||
todir="$scratchdir/to"
|
||||
|
||||
# TODO: Need to test whether hardlinks are possible on this OS/filesystem
|
||||
|
||||
mkdir "$fromdir"
|
||||
name1="$fromdir/name1"
|
||||
name2="$fromdir/name2"
|
||||
name3="$fromdir/name3"
|
||||
name4="$fromdir/name4"
|
||||
echo "This is the file" > "$name1"
|
||||
ln "$name1" "$name2" || fail "Can't create hardlink"
|
||||
ln "$name2" "$name3" || fail "Can't create hardlink"
|
||||
cp "$name2" "$name4" || fail "Can't copy file"
|
||||
|
||||
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
#
|
||||
# This program is distributable under the terms of the GNU GPL (see COPYING)
|
||||
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
# set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
LONGDIR=${FROM}/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job
|
||||
|
||||
@@ -41,6 +41,11 @@ printmsg() {
|
||||
}
|
||||
|
||||
|
||||
rsync_ls_lR() {
|
||||
find "$@" -print | sort | xargs $TLS
|
||||
}
|
||||
|
||||
|
||||
####################
|
||||
# Build test directories TO and FROM, with FROM full of files.
|
||||
|
||||
@@ -48,7 +53,8 @@ hands_setup() {
|
||||
# Clean before creation
|
||||
rm -rf $FROM
|
||||
rm -rf $TO
|
||||
|
||||
|
||||
[ -d $TMP ] || mkdir $TMP
|
||||
[ -d $FROM ] || mkdir $FROM
|
||||
[ -d $TO ] || mkdir $TO
|
||||
|
||||
@@ -67,7 +73,7 @@ hands_setup() {
|
||||
mkdir ${FROM}/emptydir
|
||||
|
||||
# a hundred lines of text or so
|
||||
ls -lR ${srcdir} > ${FROM}/filelist
|
||||
rsync_ls_lR "${srcdir}" > ${FROM}/filelist
|
||||
|
||||
# This might fail on systems that don't have -n
|
||||
echo $ECHO_N "This file has no trailing lf$ECHO_C" > ${FROM}/nolf
|
||||
@@ -89,12 +95,18 @@ hands_setup() {
|
||||
}
|
||||
|
||||
|
||||
hands_cleanup() {
|
||||
rm -r "$TMP"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
####################
|
||||
# Many machines do not have "mkdir -p", so we have to build up long paths.
|
||||
# How boring.
|
||||
makepath () {
|
||||
echo " makepath $1"
|
||||
p="$1"
|
||||
(
|
||||
# Absolut Unix.
|
||||
@@ -106,8 +118,12 @@ makepath () {
|
||||
# This will break if $1 contains a space.
|
||||
for c in `echo $p | tr '/' ' '`
|
||||
do
|
||||
[ -d "$c" ] || mkdir "$c" || return $?
|
||||
cd "$c" || return $?
|
||||
if [ -d "$c" ] || mkdir "$c"
|
||||
then
|
||||
cd "$c" || return $?
|
||||
else
|
||||
echo "failed to create $c" >&2; return $?
|
||||
fi
|
||||
done
|
||||
)
|
||||
}
|
||||
@@ -119,35 +135,31 @@ makepath () {
|
||||
# there are any difference. If there are, explain them.
|
||||
|
||||
checkit() {
|
||||
log=${LOG}
|
||||
failed=
|
||||
# the log accumulates all output; we only display it if there
|
||||
# is a problem.
|
||||
|
||||
echo "Running: \"$1\"" >${log}
|
||||
echo "">>${log}
|
||||
eval "$1" >>${log} 2>&1
|
||||
# We can just write everything to stdout/stderr, because the
|
||||
# wrapper hides it unless there is a problem.
|
||||
|
||||
echo "Running: \"$1\""
|
||||
eval "$1"
|
||||
status=$?
|
||||
if [ $status != 0 ]; then
|
||||
failed="YES";
|
||||
fi
|
||||
|
||||
echo "-------------">>${log}
|
||||
echo "check how the files compare with diff:">>${log}
|
||||
echo "">>${log}
|
||||
diff -cr $2 $3 >>${log} 2>&1 || failed=YES
|
||||
echo "-------------">>${log}
|
||||
echo "check how the directory listings compare with diff:">>${log}
|
||||
echo "">>${log}
|
||||
( cd $2 ; ls -laR ) > ${TMP}/ls-from 2>>${log}
|
||||
( cd $3 ; ls -laR ) > ${TMP}/ls-to 2>>${log}
|
||||
diff -c ${TMP}/ls-from ${TMP}/ls-to >>${log} 2>&1 || failed=YES
|
||||
echo "-------------"
|
||||
echo "check how the files compare with diff:"
|
||||
echo ""
|
||||
diff -cr $2 $3 || failed=YES
|
||||
echo "-------------"
|
||||
echo "check how the directory listings compare with diff:"
|
||||
echo ""
|
||||
( cd "$2" && rsync_ls_lR . ) > ${TMP}/ls-from
|
||||
( cd "$3" && rsync_ls_lR . ) > ${TMP}/ls-to
|
||||
diff -c ${TMP}/ls-from ${TMP}/ls-to || failed=YES
|
||||
if [ -z "${failed}" ] ; then
|
||||
rm $log
|
||||
return 0
|
||||
else
|
||||
cat ${log}
|
||||
rm ${log}
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -194,3 +206,29 @@ EOF
|
||||
}
|
||||
|
||||
|
||||
build_symlinks() {
|
||||
fromdir="$scratchdir/from"
|
||||
todir="$scratchdir/to"
|
||||
mkdir "$fromdir"
|
||||
date >"$fromdir/referent"
|
||||
ln -s referent "$fromdir/relative"
|
||||
ln -s "$fromdir/referent" "$fromdir/absolute"
|
||||
ln -s nonexistent "$fromdir/dangling"
|
||||
ln -s "$srcdir/rsync.c" "$fromdir/unsafe"
|
||||
}
|
||||
|
||||
test_fail() {
|
||||
echo "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# It failed, but we expected that. don't dump out error logs,
|
||||
# because most users won't want to see them. But do leave
|
||||
# the working directory around.
|
||||
test_xfail() {
|
||||
echo "$@" >&2
|
||||
exit 78
|
||||
}
|
||||
|
||||
# be reproducible
|
||||
umask 077
|
||||
29
testsuite/symlink-ignore.test
Normal file
29
testsuite/symlink-ignore.test
Normal file
@@ -0,0 +1,29 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync's somewhat over-featured symlink control: the default
|
||||
# behaviour is that symlinks should not be copied at all.
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
set -x
|
||||
|
||||
build_symlinks || test_fail "failed to build symlinks"
|
||||
|
||||
# Copy recursively, but without -l or -L or -a, and all the symlinks
|
||||
# should be missing.
|
||||
"$rsync_bin" -r "$fromdir/" "$todir" || test_fail "rsync returned $?"
|
||||
|
||||
[ -f "$todir/referent" ] || test_fail "referent was not copied"
|
||||
[ -d "$todir/from" ] && test_fail "extra level of directories"
|
||||
[ -L "$todir/dangling" ] && test_fail "dangling symlink was copied"
|
||||
[ -L "$todir/relative" ] && test_fail "relative symlink was copied"
|
||||
[ -L "$todir/absolute" ] && test_fail "absolute symlink was copied"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've one
|
||||
|
||||
91
tls.c
91
tls.c
@@ -1,6 +1,6 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 2001 by Martin Pool
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
@@ -27,18 +27,16 @@
|
||||
* our purposes they're the same -- for example, the BSD braindamage
|
||||
* about setting the mode on symlinks based on your current umask.
|
||||
*
|
||||
* There are some restrictions compared to regular ls: all the names
|
||||
* on the command line must be directories rather than files; you
|
||||
* can't give wildcards either.
|
||||
* All the filenames must be given on the command line -- tls does not
|
||||
* even read directories, let alone recurse. The typical usage is
|
||||
* "find|sort|xargs tls".
|
||||
*
|
||||
* We need to recurse downwards and show all the interesting
|
||||
* information and no more.
|
||||
* The format is not exactly the same as any particular Unix ls(1).
|
||||
*
|
||||
* \todo Use readdir64 if available?
|
||||
*
|
||||
* \todo Sort directory entries. Either that, or output file listing
|
||||
* in such a format that we can just pipe the whole lot through sort.
|
||||
*/
|
||||
* A key requirement for this program is that the output be "very
|
||||
* reproducible." So we mask away information that can accidentally
|
||||
* change.
|
||||
**/
|
||||
|
||||
|
||||
|
||||
@@ -62,23 +60,68 @@ static void failed (char const *what,
|
||||
|
||||
|
||||
|
||||
static void list_dir (char const *dn)
|
||||
static void list_file (const char *fname)
|
||||
{
|
||||
DIR *d;
|
||||
struct dirent *de;
|
||||
struct stat buf;
|
||||
char permbuf[PERMSTRING_SIZE];
|
||||
struct tm *mt;
|
||||
char datebuf[50];
|
||||
char linkbuf[4096];
|
||||
|
||||
if (!(d = opendir (dn)))
|
||||
failed ("opendir", dn);
|
||||
if (do_lstat(fname, &buf) == -1)
|
||||
failed ("stat", fname);
|
||||
|
||||
while ((de = readdir (d))) {
|
||||
char *dname = d_name (de);
|
||||
if (!strcmp (dname, ".") || !strcmp (dname, ".."))
|
||||
continue;
|
||||
printf ("%s\n", dname);
|
||||
/* The size of anything but a regular file is probably not
|
||||
* worth thinking about. */
|
||||
if (!S_ISREG(buf.st_mode))
|
||||
buf.st_size = 0;
|
||||
|
||||
/* On some BSD platforms the mode bits of a symlink are
|
||||
* undefined. Also it tends not to be possible to reset a
|
||||
* symlink's mtime, so we have to ignore it too. */
|
||||
if (S_ISLNK(buf.st_mode)) {
|
||||
int len;
|
||||
buf.st_mode &= ~0777;
|
||||
buf.st_mtime = (time_t)0;
|
||||
buf.st_uid = buf.st_gid = 0;
|
||||
strcpy(linkbuf, " -> ");
|
||||
/* const-cast required for silly UNICOS headers */
|
||||
len = readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
|
||||
if (len == -1)
|
||||
failed("readlink", fname);
|
||||
else
|
||||
/* it's not nul-terminated */
|
||||
linkbuf[4+len] = 0;
|
||||
} else {
|
||||
linkbuf[0] = 0;
|
||||
}
|
||||
|
||||
permstring(permbuf, buf.st_mode);
|
||||
|
||||
if (buf.st_mtime) {
|
||||
mt = gmtime(&buf.st_mtime);
|
||||
|
||||
sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
mt->tm_year + 1900,
|
||||
mt->tm_mon + 1,
|
||||
mt->tm_mday,
|
||||
mt->tm_hour,
|
||||
mt->tm_min,
|
||||
mt->tm_sec);
|
||||
} else {
|
||||
strcpy(datebuf, " ");
|
||||
}
|
||||
|
||||
if (closedir (d) == -1)
|
||||
failed ("closedir", dn);
|
||||
/* TODO: Perhaps escape special characters in fname? */
|
||||
|
||||
|
||||
/* NB: need to pass size as a double because it might be be
|
||||
* too large for a long. */
|
||||
printf("%s %12.0f %6d.%-6d %6d %s %s%s\n",
|
||||
permbuf, (double) buf.st_size,
|
||||
buf.st_uid, buf.st_gid,
|
||||
buf.st_nlink,
|
||||
datebuf, fname, linkbuf);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +134,7 @@ int main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
for (argv++; *argv; argv++) {
|
||||
list_dir (*argv);
|
||||
list_file (*argv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
94
util.c
94
util.c
@@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -173,10 +173,7 @@ pid_t local_child(int argc, char **argv,int *f_in,int *f_out)
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
|
||||
if (read_batch)
|
||||
am_sender = 0;
|
||||
else
|
||||
am_sender = !am_sender;
|
||||
am_sender = read_batch ? 0 : !am_sender;
|
||||
am_server = 1;
|
||||
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
@@ -275,7 +272,7 @@ int create_directory_path(char *fname)
|
||||
|
||||
derived from GNU C's cccp.c.
|
||||
*/
|
||||
static int full_write(int desc, char *ptr, int len)
|
||||
static int full_write(int desc, char *ptr, size_t len)
|
||||
{
|
||||
int total_written;
|
||||
|
||||
@@ -301,11 +298,11 @@ static int full_write(int desc, char *ptr, int len)
|
||||
for an error.
|
||||
|
||||
derived from GNU C's cccp.c. */
|
||||
static int safe_read(int desc, char *ptr, int len)
|
||||
static int safe_read(int desc, char *ptr, size_t len)
|
||||
{
|
||||
int n_chars;
|
||||
|
||||
if (len <= 0)
|
||||
if (len == 0)
|
||||
return len;
|
||||
|
||||
#ifdef EINTR
|
||||
@@ -811,28 +808,91 @@ int u_strcmp(const char *cs1, const char *cs2)
|
||||
return (int)*s1 - (int)*s2;
|
||||
}
|
||||
|
||||
static OFF_T last_ofs;
|
||||
static OFF_T last_ofs;
|
||||
static struct timeval print_time;
|
||||
static struct timeval start_time;
|
||||
static OFF_T start_ofs;
|
||||
|
||||
static unsigned long msdiff(struct timeval *t1, struct timeval *t2)
|
||||
{
|
||||
return (t2->tv_sec - t1->tv_sec) * 1000
|
||||
+ (t2->tv_usec - t1->tv_usec) / 1000;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ofs Current position in file
|
||||
* @param size Total size of file
|
||||
* @param is_last True if this is the last time progress will be
|
||||
* printed for this file, so we should output a newline. (Not
|
||||
* necessarily the same as all bytes being received.)
|
||||
**/
|
||||
static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
int is_last)
|
||||
{
|
||||
int pct = (ofs == size) ? 100 : (int)((100.0*ofs)/size);
|
||||
unsigned long diff = msdiff(&start_time, now);
|
||||
double rate = diff ? (double) (ofs-start_ofs) * 1000.0 / diff / 1024.0 : 0;
|
||||
const char *units;
|
||||
double remain = rate ? (double) (size-ofs) / rate / 1000.0: 0.0;
|
||||
int remain_h, remain_m, remain_s;
|
||||
|
||||
if (rate > 1024*1024) {
|
||||
rate /= 1024.0 * 1024.0;
|
||||
units = "GB/s";
|
||||
} else if (rate > 1024) {
|
||||
rate /= 1024.0;
|
||||
units = "MB/s";
|
||||
} else {
|
||||
units = "kB/s";
|
||||
}
|
||||
|
||||
remain_s = (int) remain % 60;
|
||||
remain_m = (int) (remain / 60.0) % 60;
|
||||
remain_h = (int) (remain / 3600.0);
|
||||
|
||||
rprintf(FINFO, "%12.0f %3d%% %7.2f%s %4d:%02d:%02d%s",
|
||||
(double) ofs, pct, rate, units,
|
||||
remain_h, remain_m, remain_s,
|
||||
is_last ? "\n" : "\r");
|
||||
}
|
||||
|
||||
void end_progress(OFF_T size)
|
||||
{
|
||||
extern int do_progress, am_server;
|
||||
|
||||
if (do_progress && !am_server) {
|
||||
rprintf(FINFO,"%.0f (100%%)\n", (double)size);
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
rprint_progress(size, size, &now, True);
|
||||
}
|
||||
last_ofs = 0;
|
||||
last_ofs = 0;
|
||||
start_ofs = 0;
|
||||
print_time.tv_sec = print_time.tv_usec = 0;
|
||||
start_time.tv_sec = start_time.tv_usec = 0;
|
||||
}
|
||||
|
||||
void show_progress(OFF_T ofs, OFF_T size)
|
||||
{
|
||||
extern int do_progress, am_server;
|
||||
struct timeval now;
|
||||
|
||||
if (do_progress && !am_server) {
|
||||
if (ofs > last_ofs + 1000) {
|
||||
int pct = (int)((100.0*ofs)/size);
|
||||
rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
|
||||
last_ofs = ofs;
|
||||
}
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
if (!start_time.tv_sec && !start_time.tv_usec) {
|
||||
start_time.tv_sec = now.tv_sec;
|
||||
start_time.tv_usec = now.tv_usec;
|
||||
start_ofs = ofs;
|
||||
}
|
||||
|
||||
if (do_progress
|
||||
&& !am_server
|
||||
&& ofs > last_ofs + 1000
|
||||
&& msdiff(&print_time, &now) > 250) {
|
||||
rprint_progress(ofs, size, &now, False);
|
||||
last_ofs = ofs;
|
||||
print_time.tv_sec = now.tv_sec;
|
||||
print_time.tv_usec = now.tv_usec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user