mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-25 15:25:30 -04:00
Compare commits
251 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ddcdaf3f6 | ||
|
|
93562b1941 | ||
|
|
959bd70820 | ||
|
|
a7271fb30f | ||
|
|
277036153a | ||
|
|
bc6363f9ab | ||
|
|
e71130fd77 | ||
|
|
38c9f1becf | ||
|
|
779663fc6c | ||
|
|
9562cc8925 | ||
|
|
a945aa19d9 | ||
|
|
2a1d251750 | ||
|
|
8750f64ec7 | ||
|
|
922895d9a3 | ||
|
|
72193c82a6 | ||
|
|
b178eb04d3 | ||
|
|
3158b8df6c | ||
|
|
aa3640c09b | ||
|
|
07b5c770db | ||
|
|
8b7f20b6d3 | ||
|
|
1dabd5dc9a | ||
|
|
58d657c98f | ||
|
|
e46262f36d | ||
|
|
4d92246a54 | ||
|
|
8f48ba03b5 | ||
|
|
eb8058577d | ||
|
|
3c624bba85 | ||
|
|
24e76f840e | ||
|
|
b62ea517f6 | ||
|
|
a6b3c2b512 | ||
|
|
4e95f91f27 | ||
|
|
fad4ab9d0b | ||
|
|
f91b15fbd6 | ||
|
|
83b94efa6b | ||
|
|
2064c28d6d | ||
|
|
c499002e51 | ||
|
|
c8255147b0 | ||
|
|
eee85e3c36 | ||
|
|
0c0219fe84 | ||
|
|
a92edcbf5c | ||
|
|
17549c95de | ||
|
|
9d6fe1a6f0 | ||
|
|
c43624c575 | ||
|
|
4baef8d663 | ||
|
|
c3ee6ac369 | ||
|
|
63c5ac38a2 | ||
|
|
ce41e68995 | ||
|
|
8538db7829 | ||
|
|
559bd2ff31 | ||
|
|
485a40318c | ||
|
|
ede8cae34b | ||
|
|
58ab32037d | ||
|
|
00cde6582c | ||
|
|
e6ba6e1107 | ||
|
|
efad2e85ea | ||
|
|
c463617443 | ||
|
|
6abb59adf6 | ||
|
|
d79bc5c791 | ||
|
|
10cd07c225 | ||
|
|
62e9eb7bc2 | ||
|
|
de20d72541 | ||
|
|
f8cd1c4730 | ||
|
|
5de3fe19b6 | ||
|
|
0ac2d243bf | ||
|
|
14556a30b3 | ||
|
|
8c1f2d53ec | ||
|
|
f532cede11 | ||
|
|
05022e00a2 | ||
|
|
24a743b565 | ||
|
|
e36f5c9f6c | ||
|
|
c9c3215698 | ||
|
|
dbfde9e50a | ||
|
|
1cdb5e1c86 | ||
|
|
24afdc500a | ||
|
|
303759b803 | ||
|
|
a699f7c6af | ||
|
|
a250fa251b | ||
|
|
e44aa644c2 | ||
|
|
ef67c238b5 | ||
|
|
111599be2b | ||
|
|
8e918e1861 | ||
|
|
0874fc4872 | ||
|
|
55dbbdeafe | ||
|
|
cbd27d5e18 | ||
|
|
178ccdde7d | ||
|
|
e51bb8f330 | ||
|
|
6d9207bd38 | ||
|
|
6b87566744 | ||
|
|
b384d71e53 | ||
|
|
11f4f34ed9 | ||
|
|
fe2c582af8 | ||
|
|
2ecd8b7cd2 | ||
|
|
54f00c3f89 | ||
|
|
1fc8c51705 | ||
|
|
b04604945d | ||
|
|
808b1d61c0 | ||
|
|
2f01fb1152 | ||
|
|
ae358c1960 | ||
|
|
212dfdb960 | ||
|
|
c11a77894b | ||
|
|
96cce18ce6 | ||
|
|
a21264a8b9 | ||
|
|
96486cc534 | ||
|
|
e0b1b82d84 | ||
|
|
d94b958400 | ||
|
|
79731940bb | ||
|
|
bdc038fce0 | ||
|
|
2eacba9c41 | ||
|
|
0c5853c32e | ||
|
|
3baa4d2b31 | ||
|
|
018dc6f998 | ||
|
|
523dad4bb3 | ||
|
|
e0c17aa3b7 | ||
|
|
79870bd269 | ||
|
|
e4368e37fe | ||
|
|
eee529f571 | ||
|
|
ff4715a7c2 | ||
|
|
855983b434 | ||
|
|
2455140b04 | ||
|
|
ae4d4205e3 | ||
|
|
9523670032 | ||
|
|
01e57e926c | ||
|
|
ebbab3788f | ||
|
|
d041c17c40 | ||
|
|
b2b1af40c2 | ||
|
|
c5759a2817 | ||
|
|
5ef08b8c39 | ||
|
|
03f907e386 | ||
|
|
573e24346c | ||
|
|
a415379037 | ||
|
|
cc4edc2d78 | ||
|
|
07bd6618b9 | ||
|
|
2daed024b1 | ||
|
|
6622816eff | ||
|
|
3f137ce0e2 | ||
|
|
d616bff57f | ||
|
|
40b3a59fc8 | ||
|
|
4640ae85fe | ||
|
|
24f739c118 | ||
|
|
996824825f | ||
|
|
bbef6566cd | ||
|
|
9be5093726 | ||
|
|
feb8dacc14 | ||
|
|
ff908116ef | ||
|
|
ea53d161be | ||
|
|
7875e6fe63 | ||
|
|
8e2771aa6e | ||
|
|
386f22cec6 | ||
|
|
272adea36b | ||
|
|
a69b165524 | ||
|
|
bf350d7b31 | ||
|
|
70a9cd5752 | ||
|
|
42560e2e53 | ||
|
|
d058d0aecd | ||
|
|
af00666a40 | ||
|
|
2517f5440d | ||
|
|
f2522e3f53 | ||
|
|
8fba76d5c3 | ||
|
|
782b96d3e2 | ||
|
|
1f6b697f28 | ||
|
|
919491948e | ||
|
|
0ea6f486d9 | ||
|
|
9493048c10 | ||
|
|
4dea1a9492 | ||
|
|
650bca3770 | ||
|
|
794f38099a | ||
|
|
8250d8a1c6 | ||
|
|
1fb6163c51 | ||
|
|
7f51d0e849 | ||
|
|
ece2d0e415 | ||
|
|
445640e803 | ||
|
|
5ea7c8aae3 | ||
|
|
7221063019 | ||
|
|
b64ae8b3b4 | ||
|
|
9938bad34a | ||
|
|
1ff3e90507 | ||
|
|
b292021e45 | ||
|
|
13e40ca0c6 | ||
|
|
8e85627fb3 | ||
|
|
d552250fbb | ||
|
|
5436b64557 | ||
|
|
b325dd0326 | ||
|
|
49818a8378 | ||
|
|
af03a7049c | ||
|
|
e401b30403 | ||
|
|
e512826786 | ||
|
|
ccdc2efd67 | ||
|
|
b8a1fd6404 | ||
|
|
3082dffbe2 | ||
|
|
42130f9cb0 | ||
|
|
c6c339cd18 | ||
|
|
6767ca617b | ||
|
|
7d9e30d383 | ||
|
|
3f81ad6060 | ||
|
|
723e9f856d | ||
|
|
9189e41f6e | ||
|
|
6f6f9d1020 | ||
|
|
a76ba8b425 | ||
|
|
b8fd528794 | ||
|
|
0ea5d30479 | ||
|
|
cf1b292201 | ||
|
|
f3721ed133 | ||
|
|
b1220d62f4 | ||
|
|
5df89a1a44 | ||
|
|
d47ac91209 | ||
|
|
7c573428a9 | ||
|
|
f7e65c7b61 | ||
|
|
fe62d30de8 | ||
|
|
494895fb4b | ||
|
|
ac68345a34 | ||
|
|
6a9ade2ded | ||
|
|
d596d389fe | ||
|
|
bc2337717e | ||
|
|
3df40f044a | ||
|
|
d11a5b80c1 | ||
|
|
deea1f70bd | ||
|
|
a91e678324 | ||
|
|
25a22d8501 | ||
|
|
fac9e234ae | ||
|
|
f3d87ee972 | ||
|
|
9bed85542c | ||
|
|
5b979530a7 | ||
|
|
7ec8baaa7e | ||
|
|
8c2c008984 | ||
|
|
719a29e1cf | ||
|
|
4a95d61251 | ||
|
|
fc088e30c8 | ||
|
|
aef51b4c68 | ||
|
|
7790ee3684 | ||
|
|
ed12c8eb21 | ||
|
|
91dd3d0d48 | ||
|
|
95d1d2a9a4 | ||
|
|
a808346dbe | ||
|
|
fa181223d8 | ||
|
|
9ed569486f | ||
|
|
2fa069d85f | ||
|
|
a25aed50e6 | ||
|
|
302e4346c2 | ||
|
|
8e5eafccdf | ||
|
|
e88b92bade | ||
|
|
f8722dba56 | ||
|
|
ee03cb99d9 | ||
|
|
92d706a274 | ||
|
|
581c830c56 | ||
|
|
9e58ef45f3 | ||
|
|
05bd05a7a1 | ||
|
|
89b6b4ce4b | ||
|
|
68cdc3b791 | ||
|
|
209371b891 | ||
|
|
6fd2662982 | ||
|
|
1fdf0302c0 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -23,15 +23,11 @@ config.status
|
||||
/getgroups
|
||||
/gmon.out
|
||||
/rsync
|
||||
/rsync-ssl
|
||||
/stunnel-rsync
|
||||
/stunnel-rsyncd.conf
|
||||
/shconfig
|
||||
/testdir
|
||||
/tests-dont-exist
|
||||
/testtmp
|
||||
/tls
|
||||
/testrun
|
||||
/trimslash
|
||||
/t_unsafe
|
||||
/wildtest
|
||||
|
||||
67
Makefile.in
67
Makefile.in
@@ -4,7 +4,6 @@
|
||||
prefix=@prefix@
|
||||
datarootdir=@datarootdir@
|
||||
exec_prefix=@exec_prefix@
|
||||
stunnel4=@STUNNEL4@
|
||||
bindir=@bindir@
|
||||
mandir=@mandir@
|
||||
|
||||
@@ -19,42 +18,40 @@ INSTALLCMD=@INSTALL@
|
||||
INSTALLMAN=@INSTALL@
|
||||
|
||||
srcdir=@srcdir@
|
||||
MKDIR_P=@MKDIR_P@
|
||||
VPATH=$(srcdir)
|
||||
SHELL=/bin/sh
|
||||
|
||||
VERSION=@RSYNC_VERSION@
|
||||
VERSION=@VERSION@
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
GENFILES=configure.sh config.h.in proto.h proto.h-tstamp rsync.1 rsyncd.conf.5
|
||||
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h itypes.h inums.h \
|
||||
lib/pool_alloc.h
|
||||
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h lib/pool_alloc.h
|
||||
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o lib/md5.o \
|
||||
lib/permstring.o lib/pool_alloc.o lib/sysacls.o lib/sysxattrs.o @LIBOBJS@
|
||||
zlib_OBJS=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
|
||||
ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
|
||||
zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
|
||||
OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \
|
||||
util.o util2.o main.o checksum.o match.o syscall.o log.o backup.o delete.o
|
||||
util.o main.o checksum.o match.o syscall.o log.o backup.o
|
||||
OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o \
|
||||
fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
|
||||
OBJS3=progress.o pipe.o
|
||||
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
|
||||
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
|
||||
popt/popthelp.o popt/poptparse.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
|
||||
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
|
||||
|
||||
TLS_OBJ = tls.o syscall.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
|
||||
|
||||
# Programs we must have to run the test cases
|
||||
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
|
||||
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
|
||||
trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
|
||||
|
||||
CHECK_SYMLINKS = testsuite/chown-fake.test testsuite/devices-fake.test testsuite/xattrs-hlink.test
|
||||
|
||||
# Objects for CHECK_PROGS to clean
|
||||
CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o
|
||||
CHECK_OBJS=tls.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o
|
||||
|
||||
# note that the -I. is needed to handle config.h when using VPATH
|
||||
.c.o:
|
||||
@@ -62,30 +59,16 @@ CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
|
||||
@OBJ_RESTORE@
|
||||
|
||||
all: Makefile rsync$(EXEEXT) rsync-ssl stunnel-rsync stunnel-rsyncd.conf @MAKE_MAN@
|
||||
all: Makefile rsync$(EXEEXT) @MAKE_MAN@
|
||||
|
||||
install: all
|
||||
-${MKDIR_P} ${DESTDIR}${bindir}
|
||||
-mkdir -p ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
|
||||
-${MKDIR_P} ${DESTDIR}${mandir}/man1
|
||||
-${MKDIR_P} ${DESTDIR}${mandir}/man5
|
||||
-mkdir -p ${DESTDIR}${mandir}/man1
|
||||
-mkdir -p ${DESTDIR}${mandir}/man5
|
||||
if test -f rsync.1; then ${INSTALLMAN} -m 644 rsync.1 ${DESTDIR}${mandir}/man1; fi
|
||||
if test -f rsyncd.conf.5; then ${INSTALLMAN} -m 644 rsyncd.conf.5 ${DESTDIR}${mandir}/man5; fi
|
||||
|
||||
install-ssl-client: rsync-ssl stunnel-rsync
|
||||
-${MKDIR_P} ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync-ssl ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} ${INSTALL_STRIP} -m 755 stunnel-rsync ${DESTDIR}${bindir}
|
||||
|
||||
install-ssl-daemon: stunnel-rsyncd.conf
|
||||
-${MKDIR_P} ${DESTDIR}/etc/stunnel
|
||||
${INSTALLCMD} ${INSTALL_STRIP} -m 644 stunnel-rsyncd.conf ${DESTDIR}/etc/stunnel/rsyncd.conf
|
||||
@if ! ls /etc/rsync-ssl/certs/server.* >/dev/null 2>/dev/null; then \
|
||||
echo "Note that you'll need to install the certificate used by /etc/stunnel/rsyncd.conf"; \
|
||||
fi
|
||||
|
||||
install-all: install install-ssl-client install-ssl-daemon
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_STRIP='-s' install
|
||||
|
||||
@@ -118,9 +101,6 @@ rounding.h: rounding.c rsync.h
|
||||
tls$(EXEEXT): $(TLS_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
|
||||
|
||||
testrun$(EXEEXT): testrun.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ testrun.o
|
||||
|
||||
getgroups$(EXEEXT): getgroups.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getgroups.o $(LIBS)
|
||||
|
||||
@@ -131,7 +111,7 @@ TRIMSLASH_OBJ = trimslash.o syscall.o lib/compat.o lib/snprintf.o
|
||||
trimslash$(EXEEXT): $(TRIMSLASH_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)
|
||||
|
||||
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
|
||||
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
|
||||
t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
|
||||
|
||||
@@ -189,17 +169,6 @@ Makefile: Makefile.in config.status configure.sh config.h.in
|
||||
fi \
|
||||
fi
|
||||
|
||||
rsync-ssl: $(srcdir)/rsync-ssl.in Makefile
|
||||
sed 's;\@bindir\@;$(bindir);g' <$(srcdir)/rsync-ssl.in >rsync-ssl
|
||||
@chmod +x rsync-ssl
|
||||
|
||||
stunnel-rsync: $(srcdir)/stunnel-rsync.in Makefile
|
||||
sed 's;\@stunnel4\@;$(stunnel4);g' <$(srcdir)/stunnel-rsync.in >stunnel-rsync
|
||||
@chmod +x stunnel-rsync
|
||||
|
||||
stunnel-rsyncd.conf: $(srcdir)/stunnel-rsyncd.conf.in Makefile
|
||||
sed 's;\@bindir\@;$(bindir);g' <$(srcdir)/stunnel-rsyncd.conf.in >stunnel-rsyncd.conf
|
||||
|
||||
proto: proto.h-tstamp
|
||||
|
||||
proto.h: proto.h-tstamp
|
||||
@@ -208,11 +177,9 @@ proto.h: proto.h-tstamp
|
||||
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c config.h
|
||||
perl $(srcdir)/mkproto.pl $(srcdir)/*.c $(srcdir)/lib/compat.c
|
||||
|
||||
man: rsync.1 rsyncd.conf.5 man-copy
|
||||
|
||||
man-copy:
|
||||
@-if test -f rsync.1; then :; else echo 'Copying srcdir rsync.1'; cp -p $(srcdir)/rsync.1 .; fi
|
||||
@-if test -f rsyncd.conf.5; then :; else echo 'Copying srcdir rsyncd.conf.5'; cp -p $(srcdir)/rsyncd.conf.5 .; fi
|
||||
man: rsync.1 rsyncd.conf.5
|
||||
@if test -f rsync.1; then :; else cp -p $(srcdir)/rsync.1 .; fi
|
||||
@if test -f rsyncd.conf.5; then :; else cp -p $(srcdir)/rsyncd.conf.5 .; fi
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man -o rsync.1 $(srcdir)/rsync.yo
|
||||
@@ -234,7 +201,6 @@ cleantests:
|
||||
# the source directory.
|
||||
distclean: clean
|
||||
rm -f Makefile config.h config.status
|
||||
rm -f rsync-ssl stunnel-rsync stunnel-rsyncd.conf
|
||||
rm -f lib/dummy popt/dummy zlib/dummy
|
||||
rm -f $(srcdir)/Makefile $(srcdir)/config.h $(srcdir)/config.status
|
||||
rm -f $(srcdir)/lib/dummy $(srcdir)/popt/dummy $(srcdir)/zlib/dummy
|
||||
@@ -273,9 +239,6 @@ check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=29
|
||||
|
||||
check30: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=30
|
||||
|
||||
wildtest.o: wildtest.c lib/wildmatch.c rsync.h config.h
|
||||
wildtest$(EXEEXT): wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@ $(LIBS)
|
||||
|
||||
337
NEWS
337
NEWS
@@ -1,243 +1,138 @@
|
||||
NEWS for rsync 3.1.0 (28 Sep 2013)
|
||||
Protocol: 31 (changed)
|
||||
Changes since 3.0.9:
|
||||
|
||||
OUTPUT CHANGES:
|
||||
|
||||
- Output numbers in 3-digit groups by default (e.g. 1,234,567). See the
|
||||
--human-readable option for a way to turn it off. See also the daemon's
|
||||
"log format" parameter and related command-line options (including
|
||||
--out-format) for a modifier that can be used to request digit-grouping
|
||||
or human-readable output in log escapes. (Note that log output is
|
||||
unchanged by default.)
|
||||
|
||||
- The --list-only option is now affected by the --human-readable setting.
|
||||
It will display digit groupings by default, and unit suffixes if higher
|
||||
levels of readability are requested. Also, the column width for the size
|
||||
output has increased from 11 to 14 characters when human readability is
|
||||
enabled. Use --no-h to get the old-style output and column size.
|
||||
|
||||
- The output of the --progress option has changed: the string "xfer" was
|
||||
shortened to "xfr", and the string "to-check" was shortened to "to-chk",
|
||||
both designed to make room for the (by default) wider display of file
|
||||
size numbers without making the total line-length longer. Also, when
|
||||
incremental recursion is enabled, the string "ir-chk" will be used
|
||||
instead of "to-chk" up until the incremental-recursion scan is done,
|
||||
letting you know that the value to check and the total value will still
|
||||
be increasing as new files are found.
|
||||
|
||||
- Enhanced the --stats output: 1) to mention how many files were created
|
||||
(protocol >= 28), 2) to mention how many files were deleted (a new line
|
||||
for protocol 31, but only output when --delete is in effect), and 3) to
|
||||
follow the file-count, created-count, and deleted-count with a subcount
|
||||
list that shows the counts by type. The wording of the transferred count
|
||||
has also changed so that it is clearer that it is only a count of regular
|
||||
files.
|
||||
NEWS for rsync 3.0.8 (26 Mar 2011)
|
||||
Protocol: 30 (unchanged)
|
||||
Changes since 3.0.7:
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- Fixed a bug in the iconv code when EINVAL or EILSEQ is returned with a
|
||||
full output buffer.
|
||||
- Fixed two buffer-overflow issues: one where a directory path that is
|
||||
exactly MAXPATHLEN was not handled correctly, and one handling a
|
||||
--backup-dir that is extra extra large.
|
||||
|
||||
- Fixed some rare bugs in --iconv processing that might cause a multibyte
|
||||
character to get translated incorrectly.
|
||||
- Fixed a data-corruption issue when preserving hard-links without
|
||||
preserving file ownership, and doing deletions either before or during
|
||||
the transfer (CVE-2011-1097). This fixes some assert errors in the
|
||||
hard-linking code, and some potential failed checksums (via -c) that
|
||||
should have matched.
|
||||
|
||||
- Fixed a bogus "vanished file" error if some files were specified with
|
||||
"./" prefixes and others were not.
|
||||
- Fixed a potential crash when an rsync daemon has a filter/exclude list
|
||||
and the transfer is using ACLs or xattrs.
|
||||
|
||||
- Fixed a bug in --sparse where an extra gap could get inserted after a
|
||||
partial write.
|
||||
- Fixed a hang if a really large file is being processed by an rsync that
|
||||
can't handle 64-bit numbers. Rsync will now complain about the file
|
||||
being too big and skip it.
|
||||
|
||||
- Changed the way --progress overwrites its prior output in order to make
|
||||
it nearly impossible for the progress to get overwritten by an error.
|
||||
- For devices and special files, we now avoid gathering useless ACL and/or
|
||||
xattr information for files that aren't being copied. (The un-copied
|
||||
files are still put into the file list, but there's no need to gather
|
||||
data that is not going to be used.) This ensures that if the user uses
|
||||
--no-D, that rsync can't possibly complain about being unable to gather
|
||||
extended information from special files that are in the file list (but
|
||||
not in the transfer).
|
||||
|
||||
- Improved the propagation of abnormal-exit error messages. This should
|
||||
help the client side to receive errors from the server when it is exiting
|
||||
abnormally, and should also avoid dying with an "connection unexpectedly
|
||||
closed" exit when the closed connection is really expected.
|
||||
- Properly handle requesting remote filenames that start with a dash. This
|
||||
avoids a potential error where a filename could be interpreted as a
|
||||
(usually invalid) option.
|
||||
|
||||
- The sender now checks each file it plans to remove to ensure that it
|
||||
hasn't changed from the first stat's info. This helps to avoid losing
|
||||
file data when the user is not using the option in a safe manner.
|
||||
- Fixed a bug in the comparing of upper-case letters in file suffixes for
|
||||
--skip-compress.
|
||||
|
||||
- Fixed a data-duplication bug in the compress option that made compression
|
||||
less efficient. This improves protocol 31 onward, while behaving in a
|
||||
compatible (buggy) manner with older rsync protocols.
|
||||
- If an rsync daemon has a module configured without a path setting, rsync
|
||||
will now disallow access to that module.
|
||||
|
||||
- When creating a temp-file, rsync is now a bit smarter about it dot-char
|
||||
choices, which can fix a problem on OS X with names that start with "..".
|
||||
- If the destination arg is an empty string, it will be treated as a
|
||||
reference to the current directory (as 2.x used to do).
|
||||
|
||||
- Rsync now sets a cleanup flag for --inplace and --append transfers that
|
||||
will flush the write buffer if the transfer aborts. This ensures that
|
||||
more received data gets written out to the disk on an aborted transfer
|
||||
(which is quite helpful on a slow, flaky connection).
|
||||
- If rsync was compiled with a newer time-setting function (such as
|
||||
lutimes), rsync will fall-back to an older function (such as utimes) on a
|
||||
system where the newer function is not around. This helps to make the
|
||||
rsync binary more portable in mixed-OS-release situations.
|
||||
|
||||
- The reads that map_ptr() now does are aligned on 1K boundaries. This
|
||||
helps some filesystems and/or files that don't like unaligned reads.
|
||||
- Fixed a batch-file writing bug that would not write out the full set of
|
||||
compatibility flags that the transfer was using. This fixes a potential
|
||||
protocol problem for a batch file that contains a sender-side I/O error:
|
||||
it would have been sent in a way that the batch-reader wasn't expecting.
|
||||
|
||||
- Fix an issue in the msleep() function if time jumps backwards.
|
||||
- Some improvements to the hard-linking code to ensure that device-number
|
||||
hashing is working right, and to supply more information if the hard-link
|
||||
code fails.
|
||||
|
||||
- Fix daemon-server module-name splitting bug where an arg would get split
|
||||
even if --protect-args was used.
|
||||
- The --inplace code was improved to not search for an impossible checksum
|
||||
position. The quadruple-verbose chunk[N] message will now mention when
|
||||
an inplace chunk was handled by a seek rather than a read+write.
|
||||
|
||||
- Improved ACL mask handling, e.g. for Solaris.
|
||||
|
||||
- Fixed a bug that prevented --numeric-ids from disabling the translation
|
||||
of user/group IDs for ACLs.
|
||||
|
||||
- Fixed an issue where an xattr and/or ACL transfer that used an alt-dest
|
||||
option (e.g. --link-dest) could output an error trying to itemize the
|
||||
changes against the alt-dest directory's xattr/ACL info but was instead
|
||||
trying to access the not-yet-existing new destination directory.
|
||||
|
||||
- Improved xattr system-error messages to mention the full path to the
|
||||
file.
|
||||
|
||||
- The --link-dest checking for identical symlinks now avoids considering
|
||||
attribute differences that cannot be changed on the receiver.
|
||||
|
||||
- Avoid trying to read/write xattrs on certain file types for certain OSes.
|
||||
Improved configure to set NO_SYMLINK_XATTRS, NO_DEVICE_XATTRS, and/or
|
||||
NO_SPECIAL_XATTRS defines in config.h.
|
||||
|
||||
- Improved the unsafe-symlink errors messages.
|
||||
|
||||
- Fixed a bug setting xattrs on new files that aren't user writable.
|
||||
|
||||
- Avoid re-setting xattrs on a hard-linked file w/the same xattrs.
|
||||
|
||||
- Fixed a bug with --fake-super when copying files and dirs that aren't
|
||||
user writable.
|
||||
|
||||
- Fixed a bug where a sparse file could have its last sparse block turned
|
||||
into a real block when rsync sets the file size (requires ftruncate).
|
||||
|
||||
- If a temp-file name is too long, rsync now avoids truncating the name in
|
||||
the middle of adjacent high-bit characters. This prevents a potential
|
||||
filename error if the filesystem doesn't allow a name to contain an
|
||||
invalid multi-byte sequence.
|
||||
|
||||
- If a muli-protocol socket connection fails (i.e., when contacting a
|
||||
daemon), we now report all the failures, not just the last one. This
|
||||
avoids losing a relevant error (e.g. an IPv4 connection-refused error)
|
||||
that happened before the final error (e.g. an IPv6 protocol-not-supported
|
||||
error).
|
||||
|
||||
- Generate a transfer error if we try to call chown with a -1 for a uid or
|
||||
a gid (which is not settable).
|
||||
|
||||
- Fixed the working of --force when used with --one-file-system.
|
||||
|
||||
- Fix the popt arg parsing so that an option that doesn't take an arg will
|
||||
reject an attempt to supply one (can configure --with-included-popt if
|
||||
your system's popt library doesn't yet have this fix).
|
||||
|
||||
- A couple minor option tweaks to the support/rrsync script, and also some
|
||||
regex changes that make vim highlighting happier.
|
||||
|
||||
- Fixed some issues in the support/mnt-excl script.
|
||||
|
||||
- Various manpage improvements.
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
- Added the --remote-option=OPT (-M OPT) command-line option that is useful
|
||||
for things like sending a remote --log-file=FILE or --fake-super option.
|
||||
|
||||
- Added the --info=FLAGS and --debug=FLAGS options to allow finer-grained
|
||||
control over what is output. Added an extra type of --progress output
|
||||
using --info=progress2.
|
||||
|
||||
- The --msgs2stderr option can help with debugging rsync by allowing the
|
||||
debug messages to get output to stderr rather than travel via the socket
|
||||
protocol.
|
||||
|
||||
- Added the --delete-missing-args and --ignore-missing-args options to
|
||||
either delete or ignore user-specified files on the receiver that are
|
||||
missing on the sender (normally the absence of user-specified files
|
||||
generates an error).
|
||||
|
||||
- Added a "T" (terabyte) category to the --human-readable size suffixes.
|
||||
|
||||
- Added the --usermap/--groupmap/--chown options for manipulating file
|
||||
ownership during the copy.
|
||||
|
||||
- Added the "%C" escape to the log-output handling, which will output the
|
||||
MD5 checksum of any transferred file, or all files if --checksum was
|
||||
specified (when protocol 30 or above is in effect).
|
||||
|
||||
- Added the "reverse lookup" parameter to the rsync daemon config file to
|
||||
allow reverse-DNS lookups to be disabled.
|
||||
|
||||
- Added a forward-DNS lookup for the daemon's hosts allow/deny config. Can
|
||||
be disabled via "forward lookup" parameter (defaults to enabled).
|
||||
|
||||
- Added a way for more than one group to be specified in the daemon's
|
||||
config file, including a way to specify that you want all of the
|
||||
specified user's groups without having to name them. Also changed the
|
||||
daemon to complain about an inability to set explicitly-specified uid/gid
|
||||
values, even when not run by a super-user.
|
||||
|
||||
- The daemon now tries to send the user the error messages from the
|
||||
pre-xfer exec script when it fails.
|
||||
|
||||
- Improved the use of alt-dest options into an existing hierarchy of files:
|
||||
If a match is found in an alt-dir, it takes precedence over an existing
|
||||
file. (We'll need to wait for a future version before attribute-changes
|
||||
on otherwise unchanged files are safe when using an existing hierarchy.)
|
||||
|
||||
- Added per-user authorization options and group-authorization support to
|
||||
the daemon's "auth users" parameter.
|
||||
|
||||
- Added a way to reference environment variables in a daemon's config file
|
||||
(using %VAR% references).
|
||||
|
||||
- When replacing a non-dir with a symlink/hard-link/device/special-file,
|
||||
the update should now be done in an atomic manner.
|
||||
|
||||
- Avoid re-sending xattr info for hard-linked files w/the same xattrs
|
||||
(protocol 31).
|
||||
|
||||
- The backup code was improved to use better logic maintaining the backup
|
||||
directory hierarchy. Also, when a file is being backed up, rsync tries
|
||||
to hard-link it into place so that the upcoming replacement of the
|
||||
destination file will be atomic (for the normal, non-inplace logic).
|
||||
|
||||
- Added the ability to synchronize nano-second modified times.
|
||||
|
||||
- Added a few more default suffixes for the "dont compress" settings.
|
||||
|
||||
- Added the checking of the RSYNC_PROTECT_ARGS environment variable to allow
|
||||
the default for the --protect-args command-line option to be overridden.
|
||||
|
||||
- Added the --preallocate command-line option.
|
||||
|
||||
- Allow --password-file=- to read the password from stdin (filename "-").
|
||||
|
||||
- Rsync now comes packaged with an rsync-ssl helper script that can be
|
||||
used to contact a remote rsync daemon using a piped-stunnel command.
|
||||
It also includes an stunnel config file to run the server side to
|
||||
support ssl daemon connections. See the packaging/lsb/rsync.spec
|
||||
file for one way to package the resulting files. (Suggestions for
|
||||
how to make this even easier to install & use are welcomed.)
|
||||
|
||||
- Improved the speed of some --inplace updates when there are lots of
|
||||
identical checksum blocks that end up being unusable.
|
||||
|
||||
- Added the --outbuf=N|L|B option for choosing the output buffering.
|
||||
|
||||
- Repeating the --fuzzy option now causes the code to look for fuzzy
|
||||
matches inside alt-dest directories too.
|
||||
|
||||
- The --chmod option now supports numeric modes, e.g. --chmod=644,D755
|
||||
|
||||
- Added some Solaris xattr code.
|
||||
|
||||
- Made an rsync daemon (the listening process) exit with a 0 status when
|
||||
it was signaled to die. This helps launchd.
|
||||
|
||||
- Improved the RSYNC_* environment variables for the pre-xfer exec script:
|
||||
when a daemon is sent multiple request args, they are now joined into a
|
||||
single return value (separated by spaces) so that the RSYNC_REQUEST
|
||||
environment variable is accurate for any "pre-xfer exec". The values in
|
||||
RSYNC_ARG# vars are no longer truncated at the "." arg (prior to the
|
||||
request dirs/files), so that all the requested values are also listed
|
||||
(separately) in RSYNC_ARG# variables.
|
||||
|
||||
EXTRAS:
|
||||
|
||||
- Added an "instant-rsyncd" script to the support directory, which makes
|
||||
it easy to configure a simple rsync daemon in the current directory.
|
||||
|
||||
- Added the "mapfrom" and "mapto" scripts to the support directory, which
|
||||
makes it easier to do user/group mapping in a local transfer based on
|
||||
passwd/group files from another machine.
|
||||
|
||||
- There's a new, improved version of the lsh script in the support dir:
|
||||
it's written in perl and supports -u without resorting to using sudo
|
||||
(when run as root). The old shell version is now named lsh.sh.
|
||||
|
||||
- There is a helper script named rsync-slash-strip in the support directory
|
||||
for anyone that wants to change the way rsync handles args with trailing
|
||||
slashes. (e.g. arg/ would get stripped to arg while arg/. would turn into
|
||||
arg/).
|
||||
|
||||
INTERNAL:
|
||||
|
||||
- The I/O code was rewritten to be simpler and do bigger buffered reads
|
||||
over the socket. The I/O between the receiver and the generator was
|
||||
changed to be standard multiplexed-I/O (like that over the socket).
|
||||
|
||||
- The sender tries to use any dead time while the generator is looking for
|
||||
files to transfer in order to do sender-side directory scanning in a more
|
||||
parallel manner.
|
||||
|
||||
- A daemon can now inform a client about a daemon-configured timeout value
|
||||
so that the client can assist in the keep-alive activity (protocol 31).
|
||||
|
||||
- The filter code received some refactoring to make it more extendible, to
|
||||
read better, and do better sanity checking.
|
||||
|
||||
- Really big numbers are now output using our own big-num routine rather
|
||||
than casting them to a double and using a %.0f conversion.
|
||||
|
||||
- The pool_alloc library has received some minor improvements in alignment
|
||||
handling.
|
||||
|
||||
- Added init_stat_x() function to avoid duplication of acl/xattr init code.
|
||||
|
||||
- The included zlib was upgraded from 1.2.3 to 1.2.8.
|
||||
|
||||
- Rsync can now be compiled to use an unmodified zlib library instead of
|
||||
the tweaked one that is included with rsync. This will eventually
|
||||
become the default, at which point we'll start the countdown to removing
|
||||
the included zlib. Until then, feel free to configure using:
|
||||
|
||||
./configure --with-included-zlib=no
|
||||
- Added ".hg/" to the default cvs excludes (see -C & --cvs-exclude).
|
||||
|
||||
DEVELOPER RELATED:
|
||||
|
||||
- Added more conditional debug output.
|
||||
- Use lchmod() whenever it is available (not just on symlinks).
|
||||
|
||||
- Fixed some build issues for android and minix.
|
||||
- A couple fixes to the socketpair_tcp() routine.
|
||||
|
||||
- Updated the helper scripts in the packaging subdirectory.
|
||||
|
||||
- Renamed configure.in to configure.ac.
|
||||
|
||||
- Fixed configure's checking for iconv routines for newer OS X versions.
|
||||
|
||||
- Fixed the testsuite/xattrs.test script on OS X.
|
||||
|
||||
198
OLDNEWS
198
OLDNEWS
@@ -1,199 +1,3 @@
|
||||
NEWS for rsync 3.0.9 (23 Sep 2011)
|
||||
Protocol: 30 (unchanged)
|
||||
Changes since 3.0.8:
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- Fix a crash bug in checksum scanning when --inplace is used.
|
||||
|
||||
- Fix a hang if a hard-linked file cannot be opened by the sender (e.g.
|
||||
if it has no read permission).
|
||||
|
||||
- Fix preservation of a symlink's system xattrs (e.g. selinux) on Linux.
|
||||
|
||||
- Fix a memory leak in the xattr code.
|
||||
|
||||
- Fixed a bug with --delete-excluded when a filter merge file has a rule
|
||||
that specifies a receiver-only side restriction.
|
||||
|
||||
- Fix a bug with the modifying of unwritable directories.
|
||||
|
||||
- Fix --fake-super's interaction with --link-dest same-file comparisons.
|
||||
|
||||
- Fix the updating of the curr_dir buffer to avoid a duplicate slash.
|
||||
|
||||
- Fix the directory permissions on an implied dot-dir when using --relative
|
||||
(e.g. /outside/path/././send/path).
|
||||
|
||||
- Fixed some too-long sleeping instances when using --bwlimit.
|
||||
|
||||
- Fixed when symlink ownership difference-checking gets compiled into
|
||||
unchanged_attrs().
|
||||
|
||||
- Improved the socket-error reporting when multiple protocols fail.
|
||||
|
||||
- Fixed a case where a socket error could reference just-freed memory.
|
||||
|
||||
- Failing to use a password file that was specified on the command-line is
|
||||
now a fatal error.
|
||||
|
||||
- Fix the non-root updating of directories that don't have the read and/or
|
||||
execute permission.
|
||||
|
||||
- Make daemon-excluded file errors more error-like.
|
||||
|
||||
- Fix a compilation issue on older C compilers (due to a misplaced var
|
||||
declaration).
|
||||
|
||||
- Make configure avoid finding socketpair on cygwin.
|
||||
|
||||
- Avoid trying to reference SO_BROADCAST if the OS doesn't support it.
|
||||
|
||||
- Fix some issues with the post-processing of the man pages.
|
||||
|
||||
- Fixed the user home-dir handling in the support/lsh script.
|
||||
|
||||
- Some minor manpage improvements.
|
||||
|
||||
NEWS for rsync 3.0.8 (26 Mar 2011)
|
||||
Protocol: 30 (unchanged)
|
||||
Changes since 3.0.7:
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- Fixed two buffer-overflow issues: one where a directory path that is
|
||||
exactly MAXPATHLEN was not handled correctly, and one handling a
|
||||
--backup-dir that is extra extra large.
|
||||
|
||||
- Fixed a data-corruption issue when preserving hard-links without
|
||||
preserving file ownership, and doing deletions either before or during
|
||||
the transfer (CVE-2011-1097). This fixes some assert errors in the
|
||||
hard-linking code, and some potential failed checksums (via -c) that
|
||||
should have matched.
|
||||
|
||||
- Fixed a potential crash when an rsync daemon has a filter/exclude list
|
||||
and the transfer is using ACLs or xattrs.
|
||||
|
||||
- Fixed a hang if a really large file is being processed by an rsync that
|
||||
can't handle 64-bit numbers. Rsync will now complain about the file
|
||||
being too big and skip it.
|
||||
|
||||
- For devices and special files, we now avoid gathering useless ACL and/or
|
||||
xattr information for files that aren't being copied. (The un-copied
|
||||
files are still put into the file list, but there's no need to gather
|
||||
data that is not going to be used.) This ensures that if the user uses
|
||||
--no-D, that rsync can't possibly complain about being unable to gather
|
||||
extended information from special files that are in the file list (but
|
||||
not in the transfer).
|
||||
|
||||
- Properly handle requesting remote filenames that start with a dash. This
|
||||
avoids a potential error where a filename could be interpreted as a
|
||||
(usually invalid) option.
|
||||
|
||||
- Fixed a bug in the comparing of upper-case letters in file suffixes for
|
||||
--skip-compress.
|
||||
|
||||
- If an rsync daemon has a module configured without a path setting, rsync
|
||||
will now disallow access to that module.
|
||||
|
||||
- If the destination arg is an empty string, it will be treated as a
|
||||
reference to the current directory (as 2.x used to do).
|
||||
|
||||
- If rsync was compiled with a newer time-setting function (such as
|
||||
lutimes), rsync will fall-back to an older function (such as utimes) on a
|
||||
system where the newer function is not around. This helps to make the
|
||||
rsync binary more portable in mixed-OS-release situations.
|
||||
|
||||
- Fixed a batch-file writing bug that would not write out the full set of
|
||||
compatibility flags that the transfer was using. This fixes a potential
|
||||
protocol problem for a batch file that contains a sender-side I/O error:
|
||||
it would have been sent in a way that the batch-reader wasn't expecting.
|
||||
|
||||
- Some improvements to the hard-linking code to ensure that device-number
|
||||
hashing is working right, and to supply more information if the hard-link
|
||||
code fails.
|
||||
|
||||
- The --inplace code was improved to not search for an impossible checksum
|
||||
position. The quadruple-verbose chunk[N] message will now mention when
|
||||
an inplace chunk was handled by a seek rather than a read+write.
|
||||
|
||||
- Improved ACL mask handling, e.g. for Solaris.
|
||||
|
||||
- Fixed a bug that prevented --numeric-ids from disabling the translation
|
||||
of user/group IDs for ACLs.
|
||||
|
||||
- Fixed an issue where an xattr and/or ACL transfer that used an alt-dest
|
||||
option (e.g. --link-dest) could output an error trying to itemize the
|
||||
changes against the alt-dest directory's xattr/ACL info but was instead
|
||||
trying to access the not-yet-existing new destination directory.
|
||||
|
||||
- Improved xattr system-error messages to mention the full path to the
|
||||
file.
|
||||
|
||||
- The --link-dest checking for identical symlinks now avoids considering
|
||||
attribute differences that cannot be changed on the receiver.
|
||||
|
||||
- Avoid trying to read/write xattrs on certain file types for certain OSes.
|
||||
Improved configure to set NO_SYMLINK_XATTRS, NO_DEVICE_XATTRS, and/or
|
||||
NO_SPECIAL_XATTRS defines in config.h.
|
||||
|
||||
- Improved the unsafe-symlink errors messages.
|
||||
|
||||
- Fixed a bug setting xattrs on new files that aren't user writable.
|
||||
|
||||
- Avoid re-setting xattrs on a hard-linked file w/the same xattrs.
|
||||
|
||||
- Fixed a bug with --fake-super when copying files and dirs that aren't
|
||||
user writable.
|
||||
|
||||
- Fixed a bug where a sparse file could have its last sparse block turned
|
||||
into a real block when rsync sets the file size (requires ftruncate).
|
||||
|
||||
- If a temp-file name is too long, rsync now avoids truncating the name in
|
||||
the middle of adjacent high-bit characters. This prevents a potential
|
||||
filename error if the filesystem doesn't allow a name to contain an
|
||||
invalid multi-byte sequence.
|
||||
|
||||
- If a muli-protocol socket connection fails (i.e., when contacting a
|
||||
daemon), we now report all the failures, not just the last one. This
|
||||
avoids losing a relevant error (e.g. an IPv4 connection-refused error)
|
||||
that happened before the final error (e.g. an IPv6 protocol-not-supported
|
||||
error).
|
||||
|
||||
- Generate a transfer error if we try to call chown with a -1 for a uid or
|
||||
a gid (which is not settable).
|
||||
|
||||
- Fixed the working of --force when used with --one-file-system.
|
||||
|
||||
- Fix the popt arg parsing so that an option that doesn't take an arg will
|
||||
reject an attempt to supply one (can configure --with-included-popt if
|
||||
your system's popt library doesn't yet have this fix).
|
||||
|
||||
- A couple minor option tweaks to the support/rrsync script, and also some
|
||||
regex changes that make vim highlighting happier.
|
||||
|
||||
- Fixed some issues in the support/mnt-excl script.
|
||||
|
||||
- Various manpage improvements.
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
- Added ".hg/" to the default cvs excludes (see -C & --cvs-exclude).
|
||||
|
||||
DEVELOPER RELATED:
|
||||
|
||||
- Use lchmod() whenever it is available (not just on symlinks).
|
||||
|
||||
- A couple fixes to the socketpair_tcp() routine.
|
||||
|
||||
- Updated the helper scripts in the packaging subdirectory.
|
||||
|
||||
- Renamed configure.in to configure.ac.
|
||||
|
||||
- Fixed configure's checking for iconv routines for newer OS X versions.
|
||||
|
||||
- Fixed the testsuite/xattrs.test script on OS X.
|
||||
|
||||
NEWS for rsync 3.0.7 (31 Dec 2009)
|
||||
Protocol: 30 (unchanged)
|
||||
Changes since 3.0.6:
|
||||
@@ -3290,8 +3094,6 @@ Changes since 2.4.6:
|
||||
|
||||
Partial Protocol History
|
||||
RELEASE DATE VER. DATE OF COMMIT* PROTOCOL
|
||||
28 Sep 2013 3.1.0 31 Aug 2008 31
|
||||
23 Sep 2011 3.0.9 30
|
||||
26 Mar 2011 3.0.8 30
|
||||
31 Dec 2009 3.0.7 30
|
||||
08 May 2009 3.0.6 30
|
||||
|
||||
77
access.c
77
access.c
@@ -2,7 +2,7 @@
|
||||
* Routines to authenticate access to a daemon (hosts allow/deny).
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2004-2013 Wayne Davison
|
||||
* Copyright (C) 2004-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,50 +20,14 @@
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
static int allow_forward_dns;
|
||||
|
||||
extern const char undetermined_hostname[];
|
||||
|
||||
static int match_hostname(const char **host_ptr, const char *addr, const char *tok)
|
||||
static int match_hostname(char *host, char *tok)
|
||||
{
|
||||
struct hostent *hp;
|
||||
unsigned int i;
|
||||
const char *host = *host_ptr;
|
||||
|
||||
if (!host || !*host)
|
||||
return 0;
|
||||
|
||||
/* First check if the reverse-DNS-determined hostname matches. */
|
||||
if (iwildmatch(tok, host))
|
||||
return 1;
|
||||
|
||||
if (!allow_forward_dns)
|
||||
return 0;
|
||||
|
||||
/* Fail quietly if tok is an address or wildcarded entry, not a simple hostname. */
|
||||
if (!tok[strspn(tok, ".0123456789")] || tok[strcspn(tok, ":/*?[")])
|
||||
return 0;
|
||||
|
||||
/* Now try forward-DNS on the token (config-specified hostname) and see if the IP matches. */
|
||||
if (!(hp = gethostbyname(tok)))
|
||||
return 0;
|
||||
|
||||
for (i = 0; hp->h_addr_list[i] != NULL; i++) {
|
||||
if (strcmp(addr, inet_ntoa(*(struct in_addr*)(hp->h_addr_list[i]))) == 0) {
|
||||
/* If reverse lookups are off, we'll use the conf-specified
|
||||
* hostname in preference to UNDETERMINED. */
|
||||
if (host == undetermined_hostname) {
|
||||
if (!(*host_ptr = strdup(tok)))
|
||||
*host_ptr = undetermined_hostname;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return wildmatch(tok, host);
|
||||
}
|
||||
|
||||
static int match_binary(const char *b1, const char *b2, const char *mask, int addrlen)
|
||||
static int match_binary(char *b1, char *b2, char *mask, int addrlen)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -92,7 +56,7 @@ static void make_mask(char *mask, int plen, int addrlen)
|
||||
return;
|
||||
}
|
||||
|
||||
static int match_address(const char *addr, const char *tok)
|
||||
static int match_address(char *addr, char *tok)
|
||||
{
|
||||
char *p;
|
||||
struct addrinfo hints, *resa, *rest;
|
||||
@@ -106,16 +70,24 @@ static int match_address(const char *addr, const char *tok)
|
||||
#endif
|
||||
char mask[16];
|
||||
char *a = NULL, *t = NULL;
|
||||
unsigned int len;
|
||||
|
||||
if (!addr || !*addr)
|
||||
return 0;
|
||||
|
||||
p = strchr(tok,'/');
|
||||
if (p)
|
||||
if (p) {
|
||||
*p = '\0';
|
||||
len = p - tok;
|
||||
} else
|
||||
len = strlen(tok);
|
||||
|
||||
/* Fail quietly if tok is a hostname, not an address. */
|
||||
if (tok[strspn(tok, ".0123456789")] && strchr(tok, ':') == NULL) {
|
||||
/* Fail quietly if tok is a hostname (not an address) */
|
||||
if (strspn(tok, ".0123456789") != len
|
||||
#ifdef INET6
|
||||
&& strchr(tok, ':') == NULL
|
||||
#endif
|
||||
) {
|
||||
if (p)
|
||||
*p = '/';
|
||||
return 0;
|
||||
@@ -238,7 +210,7 @@ static int match_address(const char *addr, const char *tok)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int access_match(const char *list, const char *addr, const char **host_ptr)
|
||||
static int access_match(char *list, char *addr, char *host)
|
||||
{
|
||||
char *tok;
|
||||
char *list2 = strdup(list);
|
||||
@@ -247,9 +219,11 @@ static int access_match(const char *list, const char *addr, const char **host_pt
|
||||
out_of_memory("access_match");
|
||||
|
||||
strlower(list2);
|
||||
if (host)
|
||||
strlower(host);
|
||||
|
||||
for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
|
||||
if (match_hostname(host_ptr, addr, tok) || match_address(addr, tok)) {
|
||||
if (match_hostname(host, tok) || match_address(addr, tok)) {
|
||||
free(list2);
|
||||
return 1;
|
||||
}
|
||||
@@ -259,21 +233,16 @@ static int access_match(const char *list, const char *addr, const char **host_pt
|
||||
return 0;
|
||||
}
|
||||
|
||||
int allow_access(const char *addr, const char **host_ptr, int i)
|
||||
int allow_access(char *addr, char *host, char *allow_list, char *deny_list)
|
||||
{
|
||||
const char *allow_list = lp_hosts_allow(i);
|
||||
const char *deny_list = lp_hosts_deny(i);
|
||||
|
||||
if (allow_list && !*allow_list)
|
||||
allow_list = NULL;
|
||||
if (deny_list && !*deny_list)
|
||||
deny_list = NULL;
|
||||
|
||||
allow_forward_dns = lp_forward_lookup(i);
|
||||
|
||||
/* If we match an allow-list item, we always allow access. */
|
||||
if (allow_list) {
|
||||
if (access_match(allow_list, addr, host_ptr))
|
||||
if (access_match(allow_list, addr, host))
|
||||
return 1;
|
||||
/* For an allow-list w/o a deny-list, disallow non-matches. */
|
||||
if (!deny_list)
|
||||
@@ -282,7 +251,7 @@ int allow_access(const char *addr, const char **host_ptr, int i)
|
||||
|
||||
/* If we match a deny-list item (and got past any allow-list
|
||||
* items), we always disallow access. */
|
||||
if (deny_list && access_match(deny_list, addr, host_ptr))
|
||||
if (deny_list && access_match(deny_list, addr, host))
|
||||
return 0;
|
||||
|
||||
/* Allow all other access. */
|
||||
|
||||
10
acls.c
10
acls.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2006-2013 Wayne Davison
|
||||
* Copyright (C) 2006-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -495,15 +495,9 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl,
|
||||
}
|
||||
|
||||
racl->user_obj = IVAL(buf, 0);
|
||||
if (racl->user_obj == NO_ENTRY)
|
||||
racl->user_obj = (mode >> 6) & 7;
|
||||
racl->group_obj = IVAL(buf, 4);
|
||||
if (racl->group_obj == NO_ENTRY)
|
||||
racl->group_obj = (mode >> 3) & 7;
|
||||
racl->mask_obj = IVAL(buf, 8);
|
||||
racl->other_obj = IVAL(buf, 12);
|
||||
if (racl->other_obj == NO_ENTRY)
|
||||
racl->other_obj = mode & 7;
|
||||
|
||||
if (cnt) {
|
||||
char *bp = buf + 4*4;
|
||||
@@ -1143,7 +1137,7 @@ int default_perms_for_dir(const char *dir)
|
||||
/* Apply the permission-bit entries of the default ACL, if any. */
|
||||
if (racl.user_obj != NO_ENTRY) {
|
||||
perms = rsync_acl_get_perms(&racl);
|
||||
if (DEBUG_GTE(ACL, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "got ACL-based default perms %o for directory %s\n", perms, dir);
|
||||
}
|
||||
|
||||
|
||||
358
authenticate.c
358
authenticate.c
@@ -2,7 +2,7 @@
|
||||
* Support rsync daemon authentication.
|
||||
*
|
||||
* Copyright (C) 1998-2000 Andrew Tridgell
|
||||
* Copyright (C) 2002-2013 Wayne Davison
|
||||
* Copyright (C) 2002-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,9 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
|
||||
extern int read_only;
|
||||
extern char *password_file;
|
||||
|
||||
/***************************************************************************
|
||||
@@ -78,6 +76,129 @@ static void gen_challenge(const char *addr, char *challenge)
|
||||
base64_encode(digest, len, challenge, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Return the secret for a user from the secret file, null terminated.
|
||||
* Maximum length is len (not counting the null). */
|
||||
static int get_secret(int module, const char *user, char *secret, int len)
|
||||
{
|
||||
const char *fname = lp_secrets_file(module);
|
||||
STRUCT_STAT st;
|
||||
int fd, ok = 1;
|
||||
const char *p;
|
||||
char ch, *s;
|
||||
|
||||
if (!fname || !*fname)
|
||||
return 0;
|
||||
|
||||
if ((fd = open(fname, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
|
||||
if (do_stat(fname, &st) == -1) {
|
||||
rsyserr(FLOG, errno, "stat(%s)", fname);
|
||||
ok = 0;
|
||||
} else if (lp_strict_modes(module)) {
|
||||
if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
|
||||
ok = 0;
|
||||
} else if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
rprintf(FLOG, "continuing without secrets file\n");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*user == '#') {
|
||||
/* Reject attempt to match a comment. */
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to find a line that starts with the user name and a ':'. */
|
||||
p = user;
|
||||
while (1) {
|
||||
if (read(fd, &ch, 1) != 1) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (ch == '\n')
|
||||
p = user;
|
||||
else if (p) {
|
||||
if (*p == ch)
|
||||
p++;
|
||||
else if (!*p && ch == ':')
|
||||
break;
|
||||
else
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Slurp the secret into the "secret" buffer. */
|
||||
s = secret;
|
||||
while (len > 0) {
|
||||
if (read(fd, s, 1) != 1 || *s == '\n')
|
||||
break;
|
||||
if (*s == '\r')
|
||||
continue;
|
||||
s++;
|
||||
len--;
|
||||
}
|
||||
*s = '\0';
|
||||
close(fd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *getpassf(const char *filename)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
char buffer[512], *p;
|
||||
int fd, n, ok = 1;
|
||||
const char *envpw = getenv("RSYNC_PASSWORD");
|
||||
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
if ((fd = open(filename,O_RDONLY)) < 0) {
|
||||
rsyserr(FWARNING, errno, "could not open password file \"%s\"",
|
||||
filename);
|
||||
if (envpw)
|
||||
rprintf(FINFO, "falling back to RSYNC_PASSWORD environment variable.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (do_stat(filename, &st) == -1) {
|
||||
rsyserr(FWARNING, errno, "stat(%s)", filename);
|
||||
ok = 0;
|
||||
} else if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FWARNING, "password file must not be other-accessible\n");
|
||||
ok = 0;
|
||||
} else if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
rprintf(FWARNING, "password file must be owned by root when running as root\n");
|
||||
ok = 0;
|
||||
}
|
||||
if (!ok) {
|
||||
close(fd);
|
||||
rprintf(FWARNING, "continuing without password file\n");
|
||||
if (envpw)
|
||||
rprintf(FINFO, "falling back to RSYNC_PASSWORD environment variable.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n = read(fd, buffer, sizeof buffer - 1);
|
||||
close(fd);
|
||||
if (n > 0) {
|
||||
buffer[n] = '\0';
|
||||
if ((p = strtok(buffer, "\n\r")) != NULL)
|
||||
return strdup(p);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Generate an MD4 hash created from the combination of the password
|
||||
* and the challenge string and return it base64-encoded. */
|
||||
static void generate_hash(const char *in, const char *challenge, char *out)
|
||||
@@ -93,125 +214,6 @@ static void generate_hash(const char *in, const char *challenge, char *out)
|
||||
base64_encode(buf, len, out, 0);
|
||||
}
|
||||
|
||||
/* Return the secret for a user from the secret file, null terminated.
|
||||
* Maximum length is len (not counting the null). */
|
||||
static const char *check_secret(int module, const char *user, const char *group,
|
||||
const char *challenge, const char *pass)
|
||||
{
|
||||
char line[1024];
|
||||
char pass2[MAX_DIGEST_LEN*2];
|
||||
const char *fname = lp_secrets_file(module);
|
||||
STRUCT_STAT st;
|
||||
int fd, ok = 1;
|
||||
int user_len = strlen(user);
|
||||
int group_len = group ? strlen(group) : 0;
|
||||
char *err;
|
||||
|
||||
if (!fname || !*fname || (fd = open(fname, O_RDONLY)) < 0)
|
||||
return "no secrets file";
|
||||
|
||||
if (do_fstat(fd, &st) == -1) {
|
||||
rsyserr(FLOG, errno, "fstat(%s)", fname);
|
||||
ok = 0;
|
||||
} else if (lp_strict_modes(module)) {
|
||||
if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
|
||||
ok = 0;
|
||||
} else if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
close(fd);
|
||||
return "ignoring secrets file";
|
||||
}
|
||||
|
||||
if (*user == '#') {
|
||||
/* Reject attempt to match a comment. */
|
||||
close(fd);
|
||||
return "invalid username";
|
||||
}
|
||||
|
||||
/* Try to find a line that starts with the user (or @group) name and a ':'. */
|
||||
err = "secret not found";
|
||||
while ((user || group) && read_line_old(fd, line, sizeof line, 1)) {
|
||||
const char **ptr, *s;
|
||||
int len;
|
||||
if (*line == '@') {
|
||||
ptr = &group;
|
||||
len = group_len;
|
||||
s = line+1;
|
||||
} else {
|
||||
ptr = &user;
|
||||
len = user_len;
|
||||
s = line;
|
||||
}
|
||||
if (!*ptr || strncmp(s, *ptr, len) != 0 || s[len] != ':')
|
||||
continue;
|
||||
generate_hash(s+len+1, challenge, pass2);
|
||||
if (strcmp(pass, pass2) == 0) {
|
||||
err = NULL;
|
||||
break;
|
||||
}
|
||||
err = "password mismatch";
|
||||
*ptr = NULL; /* Don't look for name again. */
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
memset(line, 0, sizeof line);
|
||||
memset(pass2, 0, sizeof pass2);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const char *getpassf(const char *filename)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
char buffer[512], *p;
|
||||
int n;
|
||||
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
if (strcmp(filename, "-") == 0) {
|
||||
n = fgets(buffer, sizeof buffer, stdin) == NULL ? -1 : (int)strlen(buffer);
|
||||
} else {
|
||||
int fd;
|
||||
|
||||
if ((fd = open(filename,O_RDONLY)) < 0) {
|
||||
rsyserr(FERROR, errno, "could not open password file %s", filename);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
if (do_stat(filename, &st) == -1) {
|
||||
rsyserr(FERROR, errno, "stat(%s)", filename);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FERROR, "ERROR: password file must not be other-accessible\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
rprintf(FERROR, "ERROR: password file must be owned by root when running as root\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
n = read(fd, buffer, sizeof buffer - 1);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
buffer[n] = '\0';
|
||||
if ((p = strtok(buffer, "\n\r")) != NULL)
|
||||
return strdup(p);
|
||||
}
|
||||
|
||||
rprintf(FERROR, "ERROR: failed to read a password from %s\n", filename);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
/* Possibly negotiate authentication with the client. Use "leader" to
|
||||
* start off the auth if necessary.
|
||||
*
|
||||
@@ -224,12 +226,9 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
|
||||
char *users = lp_auth_users(module);
|
||||
char challenge[MAX_DIGEST_LEN*2];
|
||||
char line[BIGPATHBUFLEN];
|
||||
char **auth_uid_groups = NULL;
|
||||
int auth_uid_groups_cnt = -1;
|
||||
const char *err = NULL;
|
||||
int group_match = -1;
|
||||
char secret[512];
|
||||
char pass2[MAX_DIGEST_LEN*2];
|
||||
char *tok, *pass;
|
||||
char opt_ch = '\0';
|
||||
|
||||
/* if no auth list then allow anyone in! */
|
||||
if (!users || !*users)
|
||||
@@ -239,7 +238,7 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
|
||||
|
||||
io_printf(f_out, "%s%s\n", leader, challenge);
|
||||
|
||||
if (!read_line_old(f_in, line, sizeof line, 0)
|
||||
if (!read_line_old(f_in, line, sizeof line)
|
||||
|| (pass = strchr(line, ' ')) == NULL) {
|
||||
rprintf(FLOG, "auth failed on module %s from %s (%s): "
|
||||
"invalid challenge response\n",
|
||||
@@ -252,91 +251,36 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
|
||||
out_of_memory("auth_server");
|
||||
|
||||
for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
|
||||
char *opts;
|
||||
/* See if the user appended :deny, :ro, or :rw. */
|
||||
if ((opts = strchr(tok, ':')) != NULL) {
|
||||
*opts++ = '\0';
|
||||
opt_ch = isUpper(opts) ? toLower(opts) : *opts;
|
||||
if (opt_ch == 'r') { /* handle ro and rw */
|
||||
opt_ch = isUpper(opts+1) ? toLower(opts+1) : opts[1];
|
||||
if (opt_ch == 'o')
|
||||
opt_ch = 'r';
|
||||
else if (opt_ch != 'w')
|
||||
opt_ch = '\0';
|
||||
} else if (opt_ch != 'd') /* if it's not deny, ignore it */
|
||||
opt_ch = '\0';
|
||||
} else
|
||||
opt_ch = '\0';
|
||||
if (*tok != '@') {
|
||||
/* Match the username */
|
||||
if (wildmatch(tok, line))
|
||||
break;
|
||||
} else {
|
||||
#ifdef HAVE_GETGROUPLIST
|
||||
int j;
|
||||
/* See if authorizing user is a real user, and if so, see
|
||||
* if it is in a group that matches tok+1 wildmat. */
|
||||
if (auth_uid_groups_cnt < 0) {
|
||||
gid_t gid_list[64];
|
||||
uid_t auth_uid;
|
||||
auth_uid_groups_cnt = sizeof gid_list / sizeof (gid_t);
|
||||
if (!user_to_uid(line, &auth_uid, False)
|
||||
|| getallgroups(auth_uid, gid_list, &auth_uid_groups_cnt) != NULL)
|
||||
auth_uid_groups_cnt = 0;
|
||||
else {
|
||||
if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
|
||||
out_of_memory("auth_server");
|
||||
for (j = 0; j < auth_uid_groups_cnt; j++)
|
||||
auth_uid_groups[j] = gid_to_group(gid_list[j]);
|
||||
}
|
||||
}
|
||||
for (j = 0; j < auth_uid_groups_cnt; j++) {
|
||||
if (auth_uid_groups[j] && wildmatch(tok+1, auth_uid_groups[j])) {
|
||||
group_match = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (group_match >= 0)
|
||||
break;
|
||||
#else
|
||||
rprintf(FLOG, "your computer doesn't support getgrouplist(), so no @group authorization is possible.\n");
|
||||
#endif
|
||||
}
|
||||
if (wildmatch(tok, line))
|
||||
break;
|
||||
}
|
||||
|
||||
free(users);
|
||||
|
||||
if (!tok)
|
||||
err = "no matching rule";
|
||||
else if (opt_ch == 'd')
|
||||
err = "denied by rule";
|
||||
else {
|
||||
char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
|
||||
err = check_secret(module, line, group, challenge, pass);
|
||||
}
|
||||
|
||||
memset(challenge, 0, sizeof challenge);
|
||||
memset(pass, 0, strlen(pass));
|
||||
|
||||
if (auth_uid_groups) {
|
||||
int j;
|
||||
for (j = 0; j < auth_uid_groups_cnt; j++) {
|
||||
if (auth_uid_groups[j])
|
||||
free(auth_uid_groups[j]);
|
||||
}
|
||||
free(auth_uid_groups);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
rprintf(FLOG, "auth failed on module %s from %s (%s) for %s: %s\n",
|
||||
lp_name(module), host, addr, line, err);
|
||||
if (!tok) {
|
||||
rprintf(FLOG, "auth failed on module %s from %s (%s): "
|
||||
"unauthorized user\n",
|
||||
lp_name(module), host, addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (opt_ch == 'r')
|
||||
read_only = 1;
|
||||
else if (opt_ch == 'w')
|
||||
read_only = 0;
|
||||
memset(secret, 0, sizeof secret);
|
||||
if (!get_secret(module, line, secret, sizeof secret - 1)) {
|
||||
memset(secret, 0, sizeof secret);
|
||||
rprintf(FLOG, "auth failed on module %s from %s (%s): "
|
||||
"missing secret for user \"%s\"\n",
|
||||
lp_name(module), host, addr, line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
generate_hash(secret, challenge, pass2);
|
||||
memset(secret, 0, sizeof secret);
|
||||
|
||||
if (strcmp(pass, pass2) != 0) {
|
||||
rprintf(FLOG, "auth failed on module %s from %s (%s): "
|
||||
"password mismatch\n",
|
||||
lp_name(module), host, addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return strdup(line);
|
||||
}
|
||||
|
||||
493
backup.c
493
backup.c
@@ -2,7 +2,7 @@
|
||||
* Backup handling code.
|
||||
*
|
||||
* Copyright (C) 1999 Andrew Tridgell
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,8 +19,8 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int am_root;
|
||||
extern int preserve_acls;
|
||||
extern int preserve_xattrs;
|
||||
@@ -34,218 +34,210 @@ extern char backup_dir_buf[MAXPATHLEN];
|
||||
extern char *backup_suffix;
|
||||
extern char *backup_dir;
|
||||
|
||||
/* Returns -1 on error, 0 on missing dir, and 1 on present dir. */
|
||||
static int validate_backup_dir(void)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
|
||||
if (do_lstat(backup_dir_buf, &st) < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
rsyserr(FERROR, errno, "backup lstat %s failed", backup_dir_buf);
|
||||
return -1;
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
int flags = get_del_for_flag(st.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
|
||||
if (delete_item(backup_dir_buf, st.st_mode, flags) == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create a backup path from the given fname, putting the result into
|
||||
* backup_dir_buf. Any new directories (compared to the prior backup
|
||||
* path) are ensured to exist as directories, replacing anything else
|
||||
* that may be in the way (e.g. a symlink). */
|
||||
static BOOL copy_valid_path(const char *fname)
|
||||
{
|
||||
const char *f;
|
||||
int val;
|
||||
BOOL ret = True;
|
||||
stat_x sx;
|
||||
char *b, *rel = backup_dir_buf + backup_dir_len, *name = rel;
|
||||
|
||||
for (f = fname, b = rel; *f && *f == *b; f++, b++) {
|
||||
if (*b == '/')
|
||||
name = b + 1;
|
||||
}
|
||||
|
||||
if (stringjoin(rel, backup_dir_remainder, fname, backup_suffix, NULL) >= backup_dir_remainder) {
|
||||
rprintf(FERROR, "backup filename too long\n");
|
||||
*name = '\0';
|
||||
return False;
|
||||
}
|
||||
|
||||
for ( ; ; name = b + 1) {
|
||||
if ((b = strchr(name, '/')) == NULL)
|
||||
return True;
|
||||
*b = '\0';
|
||||
|
||||
val = validate_backup_dir();
|
||||
if (val == 0)
|
||||
break;
|
||||
if (val < 0) {
|
||||
*name = '\0';
|
||||
return False;
|
||||
}
|
||||
|
||||
*b = '/';
|
||||
}
|
||||
|
||||
init_stat_x(&sx);
|
||||
|
||||
for ( ; b; name = b + 1, b = strchr(name, '/')) {
|
||||
*b = '\0';
|
||||
|
||||
while (do_mkdir(backup_dir_buf, ACCESSPERMS) < 0) {
|
||||
if (errno == EEXIST) {
|
||||
val = validate_backup_dir();
|
||||
if (val > 0)
|
||||
break;
|
||||
if (val == 0)
|
||||
continue;
|
||||
} else
|
||||
rsyserr(FERROR, errno, "backup mkdir %s failed", backup_dir_buf);
|
||||
*name = '\0';
|
||||
ret = False;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Try to transfer the directory settings of the actual dir
|
||||
* that the files are coming from. */
|
||||
if (x_stat(rel, &sx.st, NULL) < 0)
|
||||
rsyserr(FERROR, errno, "backup stat %s failed", full_fname(rel));
|
||||
else {
|
||||
struct file_struct *file;
|
||||
if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS)))
|
||||
continue;
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
get_acl(rel, &sx);
|
||||
cache_tmp_acl(file, &sx);
|
||||
free_acl(&sx);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
get_xattr(rel, &sx);
|
||||
cache_tmp_xattr(file, &sx);
|
||||
free_xattr(&sx);
|
||||
}
|
||||
#endif
|
||||
set_file_attrs(backup_dir_buf, file, NULL, NULL, 0);
|
||||
unmake_file(file);
|
||||
}
|
||||
|
||||
*b = '/';
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Make a complete pathname for backup file and verify any new path elements. */
|
||||
/* make a complete pathname for backup file */
|
||||
char *get_backup_name(const char *fname)
|
||||
{
|
||||
if (backup_dir) {
|
||||
/* copy fname into backup_dir_buf while validating the dirs. */
|
||||
if (copy_valid_path(fname))
|
||||
if (stringjoin(backup_dir_buf + backup_dir_len, backup_dir_remainder,
|
||||
fname, backup_suffix, NULL) < backup_dir_remainder)
|
||||
return backup_dir_buf;
|
||||
} else {
|
||||
if (stringjoin(backup_dir_buf, MAXPATHLEN,
|
||||
fname, backup_suffix, NULL) < MAXPATHLEN)
|
||||
return backup_dir_buf;
|
||||
/* copy_valid_path() has printed an error message. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (stringjoin(backup_dir_buf, MAXPATHLEN, fname, backup_suffix, NULL) < MAXPATHLEN)
|
||||
return backup_dir_buf;
|
||||
|
||||
rprintf(FERROR, "backup filename too long\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Has same return codes as make_backup(). */
|
||||
static inline int link_or_rename(const char *from, const char *to,
|
||||
BOOL prefer_rename, STRUCT_STAT *stp)
|
||||
/* simple backup creates a backup with a suffix in the same directory */
|
||||
static int make_simple_backup(const char *fname)
|
||||
{
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
if (!prefer_rename) {
|
||||
#ifndef CAN_HARDLINK_SYMLINK
|
||||
if (S_ISLNK(stp->st_mode))
|
||||
return 0; /* Use copy code. */
|
||||
#endif
|
||||
#ifndef CAN_HARDLINK_SPECIAL
|
||||
if (IS_SPECIAL(stp->st_mode) || IS_DEVICE(stp->st_mode))
|
||||
return 0; /* Use copy code. */
|
||||
#endif
|
||||
if (do_link(from, to) == 0) {
|
||||
if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: HLINK %s successful.\n", from);
|
||||
return 2;
|
||||
int rename_errno;
|
||||
const char *fnamebak = get_backup_name(fname);
|
||||
|
||||
if (!fnamebak)
|
||||
return 0;
|
||||
|
||||
while (1) {
|
||||
if (do_rename(fname, fnamebak) == 0) {
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO, "backed up %s to %s\n",
|
||||
fname, fnamebak);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* We prefer to rename a regular file rather than copy it. */
|
||||
if (!S_ISREG(stp->st_mode) || errno == EEXIST || errno == EISDIR)
|
||||
return 0;
|
||||
/* cygwin (at least version b19) reports EINVAL */
|
||||
if (errno == ENOENT || errno == EINVAL)
|
||||
break;
|
||||
|
||||
rename_errno = errno;
|
||||
if (errno == EISDIR && do_rmdir(fnamebak) == 0)
|
||||
continue;
|
||||
if (errno == ENOTDIR && do_unlink(fnamebak) == 0)
|
||||
continue;
|
||||
|
||||
rsyserr(FERROR, rename_errno, "rename %s to backup %s",
|
||||
fname, fnamebak);
|
||||
errno = rename_errno;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (do_rename(from, to) == 0) {
|
||||
if (stp->st_nlink > 1 && !S_ISDIR(stp->st_mode)) {
|
||||
/* If someone has hard-linked the file into the backup
|
||||
* dir, rename() might return success but do nothing! */
|
||||
robust_unlink(from); /* Just in case... */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Create a directory given an absolute path, perms based upon another directory
|
||||
path
|
||||
****************************************************************************/
|
||||
int make_bak_dir(const char *fullpath)
|
||||
{
|
||||
char fbuf[MAXPATHLEN], *rel, *end, *p;
|
||||
struct file_struct *file;
|
||||
int len = backup_dir_len;
|
||||
stat_x sx;
|
||||
|
||||
while (*fullpath == '.' && fullpath[1] == '/') {
|
||||
fullpath += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (strlcpy(fbuf, fullpath, sizeof fbuf) >= sizeof fbuf)
|
||||
return -1;
|
||||
|
||||
rel = fbuf + len;
|
||||
end = p = rel + strlen(rel);
|
||||
|
||||
/* Try to find an existing dir, starting from the deepest dir. */
|
||||
while (1) {
|
||||
if (--p == fbuf)
|
||||
return -1;
|
||||
if (*p == '/') {
|
||||
*p = '\0';
|
||||
if (mkdir_defmode(fbuf) == 0)
|
||||
break;
|
||||
if (errno != ENOENT) {
|
||||
rsyserr(FERROR, errno,
|
||||
"make_bak_dir mkdir %s failed",
|
||||
full_fname(fbuf));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make all the dirs that we didn't find on the way here. */
|
||||
while (1) {
|
||||
if (p >= rel) {
|
||||
/* Try to transfer the directory settings of the
|
||||
* actual dir that the files are coming from. */
|
||||
if (x_stat(rel, &sx.st, NULL) < 0) {
|
||||
rsyserr(FERROR, errno,
|
||||
"make_bak_dir stat %s failed",
|
||||
full_fname(rel));
|
||||
} else {
|
||||
#ifdef SUPPORT_ACLS
|
||||
sx.acc_acl = sx.def_acl = NULL;
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
sx.xattr = NULL;
|
||||
#endif
|
||||
if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS)))
|
||||
continue;
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
get_acl(rel, &sx);
|
||||
cache_tmp_acl(file, &sx);
|
||||
free_acl(&sx);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
get_xattr(rel, &sx);
|
||||
cache_tmp_xattr(file, &sx);
|
||||
free_xattr(&sx);
|
||||
}
|
||||
#endif
|
||||
set_file_attrs(fbuf, file, NULL, NULL, 0);
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
*p = '/';
|
||||
p += strlen(p);
|
||||
if (p == end)
|
||||
break;
|
||||
if (mkdir_defmode(fbuf) < 0) {
|
||||
rsyserr(FERROR, errno, "make_bak_dir mkdir %s failed",
|
||||
full_fname(fbuf));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* robustly move a file, creating new directory structures if necessary */
|
||||
static int robust_move(const char *src, char *dst)
|
||||
{
|
||||
if (robust_rename(src, dst, NULL, 0755) < 0) {
|
||||
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
|
||||
if (errno == ENOENT && make_bak_dir(dst) == 0) {
|
||||
if (robust_rename(src, dst, NULL, 0755) < 0)
|
||||
save_errno = errno ? errno : save_errno;
|
||||
else
|
||||
save_errno = 0;
|
||||
}
|
||||
if (save_errno) {
|
||||
errno = save_errno;
|
||||
return -1;
|
||||
}
|
||||
if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: RENAME %s successful.\n", from);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hard-link, rename, or copy an item to the backup name. Returns 2 if item
|
||||
* was duplicated into backup area, 1 if item was moved, or 0 for failure.*/
|
||||
int make_backup(const char *fname, BOOL prefer_rename)
|
||||
|
||||
/* If we have a --backup-dir, then we get here from make_backup().
|
||||
* We will move the file to be deleted into a parallel directory tree. */
|
||||
static int keep_backup(const char *fname)
|
||||
{
|
||||
stat_x sx;
|
||||
struct file_struct *file;
|
||||
int save_preserve_xattrs;
|
||||
char *buf = get_backup_name(fname);
|
||||
int ret = 0;
|
||||
char *buf;
|
||||
int save_preserve_xattrs = preserve_xattrs;
|
||||
int kept = 0;
|
||||
int ret_code;
|
||||
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
init_stat_x(&sx);
|
||||
/* Return success if no file to keep. */
|
||||
/* return if no file to keep */
|
||||
if (x_lstat(fname, &sx.st, NULL) < 0)
|
||||
return 1;
|
||||
#ifdef SUPPORT_ACLS
|
||||
sx.acc_acl = sx.def_acl = NULL;
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
sx.xattr = NULL;
|
||||
#endif
|
||||
|
||||
/* Try a hard-link or a rename first. Using rename is not atomic, but
|
||||
* is more efficient than forcing a copy for larger files when no hard-
|
||||
* linking is possible. */
|
||||
if ((ret = link_or_rename(fname, buf, prefer_rename, &sx.st)) != 0)
|
||||
goto success;
|
||||
if (errno == EEXIST || errno == EISDIR) {
|
||||
STRUCT_STAT bakst;
|
||||
if (do_lstat(buf, &bakst) == 0) {
|
||||
int flags = get_del_for_flag(bakst.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
|
||||
if (delete_item(buf, bakst.st_mode, flags) != 0)
|
||||
return 0;
|
||||
}
|
||||
if ((ret = link_or_rename(fname, buf, prefer_rename, &sx.st)) != 0)
|
||||
goto success;
|
||||
}
|
||||
|
||||
/* Fall back to making a copy. */
|
||||
if (!(file = make_file(fname, NULL, &sx.st, 0, NO_FILTERS)))
|
||||
if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
|
||||
return 1; /* the file could have disappeared */
|
||||
|
||||
if (!(buf = get_backup_name(fname))) {
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
get_acl(fname, &sx);
|
||||
@@ -264,34 +256,87 @@ int make_backup(const char *fname, BOOL prefer_rename)
|
||||
/* Check to see if this is a device file, or link */
|
||||
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|
||||
|| (preserve_specials && IS_SPECIAL(file->mode))) {
|
||||
if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0)
|
||||
rsyserr(FERROR, errno, "mknod %s failed", full_fname(buf));
|
||||
else if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: DEVICE %s successful.\n", fname);
|
||||
ret = 2;
|
||||
int save_errno;
|
||||
do_unlink(buf);
|
||||
if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0) {
|
||||
save_errno = errno ? errno : EINVAL; /* 0 paranoia */
|
||||
if (errno == ENOENT && make_bak_dir(buf) == 0) {
|
||||
if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0)
|
||||
save_errno = errno ? errno : save_errno;
|
||||
else
|
||||
save_errno = 0;
|
||||
}
|
||||
if (save_errno) {
|
||||
rsyserr(FERROR, save_errno, "mknod %s failed",
|
||||
full_fname(buf));
|
||||
}
|
||||
} else
|
||||
save_errno = 0;
|
||||
if (verbose > 2 && save_errno == 0) {
|
||||
rprintf(FINFO, "make_backup: DEVICE %s successful.\n",
|
||||
fname);
|
||||
}
|
||||
kept = 1;
|
||||
do_unlink(fname);
|
||||
}
|
||||
|
||||
if (!kept && S_ISDIR(file->mode)) {
|
||||
/* make an empty directory */
|
||||
if (do_mkdir(buf, file->mode) < 0) {
|
||||
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
|
||||
if (errno == ENOENT && make_bak_dir(buf) == 0) {
|
||||
if (do_mkdir(buf, file->mode) < 0)
|
||||
save_errno = errno ? errno : save_errno;
|
||||
else
|
||||
save_errno = 0;
|
||||
}
|
||||
if (save_errno) {
|
||||
rsyserr(FINFO, save_errno, "mkdir %s failed",
|
||||
full_fname(buf));
|
||||
}
|
||||
}
|
||||
|
||||
ret_code = do_rmdir(fname);
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "make_backup: RMDIR %s returns %i\n",
|
||||
full_fname(fname), ret_code);
|
||||
}
|
||||
kept = 1;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
if (!ret && preserve_links && S_ISLNK(file->mode)) {
|
||||
if (!kept && preserve_links && S_ISLNK(file->mode)) {
|
||||
const char *sl = F_SYMLINK(file);
|
||||
if (safe_symlinks && unsafe_symlink(sl, fname)) {
|
||||
if (INFO_GTE(SYMSAFE, 1)) {
|
||||
if (verbose) {
|
||||
rprintf(FINFO, "not backing up unsafe symlink \"%s\" -> \"%s\"\n",
|
||||
fname, sl);
|
||||
}
|
||||
ret = 2;
|
||||
kept = 1;
|
||||
} else {
|
||||
if (do_symlink(sl, buf) < 0)
|
||||
rsyserr(FERROR, errno, "link %s -> \"%s\"", full_fname(buf), sl);
|
||||
else if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: SYMLINK %s successful.\n", fname);
|
||||
ret = 2;
|
||||
do_unlink(buf);
|
||||
if (do_symlink(sl, buf) < 0) {
|
||||
int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
|
||||
if (errno == ENOENT && make_bak_dir(buf) == 0) {
|
||||
if (do_symlink(sl, buf) < 0)
|
||||
save_errno = errno ? errno : save_errno;
|
||||
else
|
||||
save_errno = 0;
|
||||
}
|
||||
if (save_errno) {
|
||||
rsyserr(FERROR, save_errno, "link %s -> \"%s\"",
|
||||
full_fname(buf), sl);
|
||||
}
|
||||
}
|
||||
do_unlink(fname);
|
||||
kept = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ret && !S_ISREG(file->mode)) {
|
||||
rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname);
|
||||
if (!kept && !S_ISREG(file->mode)) {
|
||||
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
|
||||
fname);
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
@@ -299,33 +344,23 @@ int make_backup(const char *fname, BOOL prefer_rename)
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Copy to backup tree if a file. */
|
||||
if (!ret) {
|
||||
if (copy_file(fname, buf, -1, file->mode) < 0) {
|
||||
/* move to keep tree if a file */
|
||||
if (!kept) {
|
||||
if (robust_move(fname, buf) != 0) {
|
||||
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
|
||||
full_fname(fname), buf);
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
return 0;
|
||||
} else if (sx.st.st_nlink > 1) {
|
||||
/* If someone has hard-linked the file into the backup
|
||||
* dir, rename() might return success but do nothing! */
|
||||
robust_unlink(fname); /* Just in case... */
|
||||
}
|
||||
if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: COPY %s successful.\n", fname);
|
||||
ret = 2;
|
||||
}
|
||||
|
||||
save_preserve_xattrs = preserve_xattrs;
|
||||
preserve_xattrs = 0;
|
||||
set_file_attrs(buf, file, NULL, fname, 0);
|
||||
preserve_xattrs = save_preserve_xattrs;
|
||||
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
@@ -334,8 +369,18 @@ int make_backup(const char *fname, BOOL prefer_rename)
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
|
||||
success:
|
||||
if (INFO_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "backed up %s to %s\n", fname, buf);
|
||||
return ret;
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO, "backed up %s to %s\n",
|
||||
fname, buf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* main backup switch routine */
|
||||
int make_backup(const char *fname)
|
||||
{
|
||||
if (backup_dir)
|
||||
return keep_backup(fname);
|
||||
return make_simple_backup(fname);
|
||||
}
|
||||
|
||||
16
batch.c
16
batch.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1999 Weiss
|
||||
* Copyright (C) 2004 Chris Shoemaker
|
||||
* Copyright (C) 2004-2013 Wayne Davison
|
||||
* Copyright (C) 2004-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include <zlib.h>
|
||||
#include "zlib/zlib.h"
|
||||
#include <time.h>
|
||||
|
||||
extern int eol_nulls;
|
||||
@@ -43,7 +43,7 @@ extern char *batch_name;
|
||||
extern char *iconv_opt;
|
||||
#endif
|
||||
|
||||
extern filter_rule_list filter_list;
|
||||
extern struct filter_list_struct filter_list;
|
||||
|
||||
int batch_stream_flags;
|
||||
|
||||
@@ -135,7 +135,7 @@ void check_batch_flags(void)
|
||||
set ? "Please" : "Do not");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if (INFO_GTE(MISC, 1)) {
|
||||
if (verbose) {
|
||||
rprintf(FINFO,
|
||||
"%sing the %s option to match the batchfile.\n",
|
||||
set ? "Sett" : "Clear", flag_name[i]);
|
||||
@@ -191,15 +191,15 @@ static int write_arg(int fd, char *arg)
|
||||
|
||||
static void write_filter_rules(int fd)
|
||||
{
|
||||
filter_rule *ent;
|
||||
struct filter_struct *ent;
|
||||
|
||||
write_sbuf(fd, " <<'#E#'\n");
|
||||
for (ent = filter_list.head; ent; ent = ent->next) {
|
||||
unsigned int plen;
|
||||
char *p = get_rule_prefix(ent, "- ", 0, &plen);
|
||||
char *p = get_rule_prefix(ent->match_flags, "- ", 0, &plen);
|
||||
write_buf(fd, p, plen);
|
||||
write_sbuf(fd, ent->pattern);
|
||||
if (ent->rflags & FILTRULE_DIRECTORY)
|
||||
if (ent->match_flags & MATCHFLG_DIRECTORY)
|
||||
write_byte(fd, '/');
|
||||
write_byte(fd, eol_nulls ? 0 : '\n');
|
||||
}
|
||||
@@ -221,7 +221,7 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
|
||||
stringjoin(filename, sizeof filename,
|
||||
batch_name, ".sh", NULL);
|
||||
fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
S_IRUSR | S_IWUSR | S_IEXEC);
|
||||
if (fd < 0) {
|
||||
rsyserr(FERROR, errno, "Batch file %s open error",
|
||||
filename);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Simple byteorder handling.
|
||||
*
|
||||
* Copyright (C) 1992-1995 Andrew Tridgell
|
||||
* Copyright (C) 2007-2013 Wayne Davison
|
||||
* Copyright (C) 2007-2008 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
2
case_N.h
2
case_N.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Allow an arbitrary sequence of case labels.
|
||||
*
|
||||
* Copyright (C) 2006-2013 Wayne Davison
|
||||
* Copyright (C) 2006-2010 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2004-2013 Wayne Davison
|
||||
* Copyright (C) 2004-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
32
chmod.c
32
chmod.c
@@ -2,7 +2,7 @@
|
||||
* Implement the core of the --chmod option.
|
||||
*
|
||||
* Copyright (C) 2002 Scott Howard
|
||||
* Copyright (C) 2005-2013 Wayne Davison
|
||||
* Copyright (C) 2005-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
|
||||
extern mode_t orig_umask;
|
||||
|
||||
@@ -36,12 +35,10 @@ struct chmod_mode_struct {
|
||||
#define CHMOD_ADD 1
|
||||
#define CHMOD_SUB 2
|
||||
#define CHMOD_EQ 3
|
||||
#define CHMOD_SET 4
|
||||
|
||||
#define STATE_ERROR 0
|
||||
#define STATE_1ST_HALF 1
|
||||
#define STATE_2ND_HALF 2
|
||||
#define STATE_OCTAL_NUM 3
|
||||
|
||||
/* Parse a chmod-style argument, and break it down into one or more AND/OR
|
||||
* pairs in a linked list. We return a pointer to new items on succcess
|
||||
@@ -90,10 +87,6 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
|
||||
curr_mode->ModeAND = CHMOD_BITS - (where * 7) - (topoct ? topbits : 0);
|
||||
curr_mode->ModeOR = bits + topoct;
|
||||
break;
|
||||
case CHMOD_SET:
|
||||
curr_mode->ModeAND = 0;
|
||||
curr_mode->ModeOR = bits;
|
||||
break;
|
||||
}
|
||||
|
||||
curr_mode->flags = flags;
|
||||
@@ -106,8 +99,7 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
|
||||
where = what = op = topoct = topbits = flags = 0;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case STATE_1ST_HALF:
|
||||
if (state != STATE_2ND_HALF) {
|
||||
switch (*modestr) {
|
||||
case 'D':
|
||||
if (flags & FLAG_FILES_ONLY)
|
||||
@@ -146,17 +138,10 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
|
||||
state = STATE_2ND_HALF;
|
||||
break;
|
||||
default:
|
||||
if (isDigit(modestr) && *modestr < '8' && !where) {
|
||||
op = CHMOD_SET;
|
||||
state = STATE_OCTAL_NUM;
|
||||
where = 1;
|
||||
what = *modestr - '0';
|
||||
} else
|
||||
state = STATE_ERROR;
|
||||
state = STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case STATE_2ND_HALF:
|
||||
} else {
|
||||
switch (*modestr) {
|
||||
case 'r':
|
||||
what |= 4;
|
||||
@@ -183,15 +168,6 @@ struct chmod_mode_struct *parse_chmod(const char *modestr,
|
||||
state = STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case STATE_OCTAL_NUM:
|
||||
if (isDigit(modestr) && *modestr < '8') {
|
||||
what = what*8 + *modestr - '0';
|
||||
if (what > CHMOD_BITS)
|
||||
state = STATE_ERROR;
|
||||
} else
|
||||
state = STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
modestr++;
|
||||
}
|
||||
|
||||
108
cleanup.c
108
cleanup.c
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -28,14 +28,9 @@ extern int am_receiver;
|
||||
extern int io_error;
|
||||
extern int keep_partial;
|
||||
extern int got_xfer_error;
|
||||
extern int protocol_version;
|
||||
extern int output_needs_newline;
|
||||
extern char *partial_dir;
|
||||
extern char *logfile_name;
|
||||
|
||||
BOOL shutting_down = False;
|
||||
BOOL flush_ok_after_signal = False;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
static struct sigaction sigact;
|
||||
#endif
|
||||
@@ -87,7 +82,7 @@ int cleanup_got_literal = 0;
|
||||
static const char *cleanup_fname;
|
||||
static const char *cleanup_new_fname;
|
||||
static struct file_struct *cleanup_file;
|
||||
static int cleanup_fd_r = -1, cleanup_fd_w = -1;
|
||||
static int cleanup_fd_r, cleanup_fd_w;
|
||||
static pid_t cleanup_pid = 0;
|
||||
|
||||
pid_t cleanup_child_pid = -1;
|
||||
@@ -102,15 +97,15 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
static int switch_step = 0;
|
||||
static int exit_code = 0, exit_line = 0;
|
||||
static const char *exit_file = NULL;
|
||||
static int first_code = 0;
|
||||
static int unmodified_code = 0;
|
||||
|
||||
SIGACTION(SIGUSR1, SIG_IGN);
|
||||
SIGACTION(SIGUSR2, SIG_IGN);
|
||||
|
||||
if (!exit_code) { /* Preserve first error exit info when recursing. */
|
||||
exit_code = code;
|
||||
exit_file = file;
|
||||
exit_line = line < 0 ? -line : line;
|
||||
if (exit_code) { /* Preserve first exit info when recursing. */
|
||||
code = exit_code;
|
||||
file = exit_file;
|
||||
line = exit_line;
|
||||
}
|
||||
|
||||
/* If this is the exit at the end of the run, the server side
|
||||
@@ -124,14 +119,11 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
#include "case_N.h" /* case 0: */
|
||||
switch_step++;
|
||||
|
||||
first_code = code;
|
||||
exit_code = unmodified_code = code;
|
||||
exit_file = file;
|
||||
exit_line = line;
|
||||
|
||||
if (output_needs_newline) {
|
||||
fputc('\n', stdout);
|
||||
output_needs_newline = 0;
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(EXIT, 2)) {
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,
|
||||
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
who_am_i(), code, file, line);
|
||||
@@ -146,8 +138,8 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
int pid = wait_process(cleanup_child_pid, &status, WNOHANG);
|
||||
if (pid == cleanup_child_pid) {
|
||||
status = WEXITSTATUS(status);
|
||||
if (status > exit_code)
|
||||
exit_code = status;
|
||||
if (status > code)
|
||||
code = exit_code = status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,43 +147,25 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (cleanup_got_literal && (cleanup_fname || cleanup_fd_w != -1)) {
|
||||
if (cleanup_got_literal && cleanup_fname && cleanup_new_fname
|
||||
&& keep_partial && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
|
||||
const char *fname = cleanup_fname;
|
||||
cleanup_fname = NULL;
|
||||
if (cleanup_fd_r != -1) {
|
||||
if (cleanup_fd_r != -1)
|
||||
close(cleanup_fd_r);
|
||||
cleanup_fd_r = -1;
|
||||
}
|
||||
if (cleanup_fd_w != -1) {
|
||||
flush_write_file(cleanup_fd_w);
|
||||
close(cleanup_fd_w);
|
||||
cleanup_fd_w = -1;
|
||||
}
|
||||
if (fname && cleanup_new_fname && keep_partial
|
||||
&& handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
|
||||
int tweak_modtime = 0;
|
||||
if (!partial_dir) {
|
||||
/* We don't want to leave a partial file with a modern time or it
|
||||
* could be skipped via --update. Setting the time to something
|
||||
* really old also helps it to stand out as unfinished in an ls. */
|
||||
tweak_modtime = 1;
|
||||
cleanup_file->modtime = 0;
|
||||
}
|
||||
finish_transfer(cleanup_new_fname, fname, NULL, NULL,
|
||||
cleanup_file, tweak_modtime, !partial_dir);
|
||||
}
|
||||
finish_transfer(cleanup_new_fname, fname, NULL, NULL,
|
||||
cleanup_file, 0, !partial_dir);
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (flush_ok_after_signal) {
|
||||
flush_ok_after_signal = False;
|
||||
if (code == RERR_SIGNAL)
|
||||
io_flush(FULL_FLUSH);
|
||||
}
|
||||
if (!exit_code && !code)
|
||||
if (!code || am_server || am_receiver)
|
||||
io_flush(FULL_FLUSH);
|
||||
|
||||
/* FALLTHROUGH */
|
||||
@@ -200,7 +174,7 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
|
||||
if (cleanup_fname)
|
||||
do_unlink(cleanup_fname);
|
||||
if (exit_code)
|
||||
if (code)
|
||||
kill_all(SIGUSR1);
|
||||
if (cleanup_pid && cleanup_pid == getpid()) {
|
||||
char *pidf = lp_pid_file();
|
||||
@@ -208,55 +182,34 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
unlink(lp_pid_file());
|
||||
}
|
||||
|
||||
if (exit_code == 0) {
|
||||
if (code)
|
||||
exit_code = code;
|
||||
if (code == 0) {
|
||||
if (io_error & IOERR_DEL_LIMIT)
|
||||
exit_code = RERR_DEL_LIMIT;
|
||||
code = exit_code = RERR_DEL_LIMIT;
|
||||
if (io_error & IOERR_VANISHED)
|
||||
exit_code = RERR_VANISHED;
|
||||
code = exit_code = RERR_VANISHED;
|
||||
if (io_error & IOERR_GENERAL || got_xfer_error)
|
||||
exit_code = RERR_PARTIAL;
|
||||
code = exit_code = RERR_PARTIAL;
|
||||
}
|
||||
|
||||
/* If line < 0, this exit is after a MSG_ERROR_EXIT event, so
|
||||
* we don't want to output a duplicate error. */
|
||||
if ((exit_code && line > 0)
|
||||
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1))))
|
||||
log_exit(exit_code, exit_file, exit_line);
|
||||
if (code || am_daemon || (logfile_name && (am_server || !verbose)))
|
||||
log_exit(code, file, line);
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (DEBUG_GTE(EXIT, 1)) {
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO,
|
||||
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): "
|
||||
"about to call exit(%d)\n",
|
||||
who_am_i(), first_code, exit_file, exit_line, exit_code);
|
||||
who_am_i(), unmodified_code, file, line, code);
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (exit_code && exit_code != RERR_SOCKETIO && exit_code != RERR_STREAMIO && exit_code != RERR_SIGNAL1
|
||||
&& exit_code != RERR_TIMEOUT && !shutting_down && (protocol_version >= 31 || am_receiver)) {
|
||||
if (line > 0) {
|
||||
if (DEBUG_GTE(EXIT, 3)) {
|
||||
rprintf(FINFO, "[%s] sending MSG_ERROR_EXIT with exit_code %d\n",
|
||||
who_am_i(), exit_code);
|
||||
}
|
||||
send_msg_int(MSG_ERROR_EXIT, exit_code);
|
||||
}
|
||||
noop_io_until_death();
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (am_server && exit_code)
|
||||
if (am_server && code)
|
||||
msleep(100);
|
||||
close_all();
|
||||
|
||||
@@ -265,13 +218,12 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
break;
|
||||
}
|
||||
|
||||
exit(exit_code);
|
||||
exit(code);
|
||||
}
|
||||
|
||||
void cleanup_disable(void)
|
||||
{
|
||||
cleanup_fname = cleanup_new_fname = NULL;
|
||||
cleanup_fd_r = cleanup_fd_w = -1;
|
||||
cleanup_got_literal = 0;
|
||||
}
|
||||
|
||||
|
||||
14
clientname.c
14
clientname.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2002-2013 Wayne Davison
|
||||
* Copyright (C) 2002-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -41,6 +41,7 @@ char *client_addr(int fd)
|
||||
static int initialised;
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t length = sizeof ss;
|
||||
char *ssh_info, *p;
|
||||
|
||||
if (initialised)
|
||||
return addr_buf;
|
||||
@@ -48,14 +49,11 @@ char *client_addr(int fd)
|
||||
initialised = 1;
|
||||
|
||||
if (am_server) { /* daemon over --rsh mode */
|
||||
char *env_str;
|
||||
strlcpy(addr_buf, "0.0.0.0", sizeof addr_buf);
|
||||
if ((env_str = getenv("REMOTE_HOST")) != NULL
|
||||
|| (env_str = getenv("SSH_CONNECTION")) != NULL
|
||||
|| (env_str = getenv("SSH_CLIENT")) != NULL
|
||||
|| (env_str = getenv("SSH2_CLIENT")) != NULL) {
|
||||
char *p;
|
||||
strlcpy(addr_buf, env_str, sizeof addr_buf);
|
||||
if ((ssh_info = getenv("SSH_CONNECTION")) != NULL
|
||||
|| (ssh_info = getenv("SSH_CLIENT")) != NULL
|
||||
|| (ssh_info = getenv("SSH2_CLIENT")) != NULL) {
|
||||
strlcpy(addr_buf, ssh_info, sizeof addr_buf);
|
||||
/* Truncate the value to just the IP address. */
|
||||
if ((p = strchr(addr_buf, ' ')) != NULL)
|
||||
*p = '\0';
|
||||
|
||||
415
clientserver.c
415
clientserver.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001-2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2002-2013 Wayne Davison
|
||||
* Copyright (C) 2002-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,9 +20,10 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int quiet;
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int output_motd;
|
||||
extern int list_only;
|
||||
@@ -36,7 +37,6 @@ extern int ignore_errors;
|
||||
extern int preserve_xattrs;
|
||||
extern int kluge_around_eof;
|
||||
extern int daemon_over_rsh;
|
||||
extern int munge_symlinks;
|
||||
extern int sanitize_paths;
|
||||
extern int numeric_ids;
|
||||
extern int filesfrom_fd;
|
||||
@@ -48,23 +48,23 @@ extern int write_batch;
|
||||
extern int default_af_hint;
|
||||
extern int logfile_format_has_i;
|
||||
extern int logfile_format_has_o_or_i;
|
||||
extern mode_t orig_umask;
|
||||
extern char *bind_address;
|
||||
extern char *config_file;
|
||||
extern char *logfile_format;
|
||||
extern char *files_from;
|
||||
extern char *tmpdir;
|
||||
extern struct chmod_mode_struct *chmod_modes;
|
||||
extern filter_rule_list daemon_filter_list;
|
||||
extern struct filter_list_struct daemon_filter_list;
|
||||
#ifdef ICONV_OPTION
|
||||
extern char *iconv_opt;
|
||||
extern iconv_t ic_send, ic_recv;
|
||||
#endif
|
||||
|
||||
#define MAX_GID_LIST 32
|
||||
|
||||
char *auth_user;
|
||||
int read_only = 0;
|
||||
int module_id = -1;
|
||||
int munge_symlinks = 0;
|
||||
struct chmod_mode_struct *daemon_chmod_modes;
|
||||
|
||||
/* module_dirlen is the length of the module_dir string when in daemon
|
||||
@@ -81,12 +81,6 @@ static int rl_nulls = 0;
|
||||
static struct sigaction sigact;
|
||||
#endif
|
||||
|
||||
static gid_t gid_list[MAX_GID_LIST];
|
||||
static int gid_count = 0;
|
||||
|
||||
/* Used when "reverse lookup" is off. */
|
||||
const char undetermined_hostname[] = "UNDETERMINED";
|
||||
|
||||
/**
|
||||
* Run a client connected to an rsyncd. The alternative to this
|
||||
* function for remote-shell connections is do_cmd().
|
||||
@@ -164,7 +158,7 @@ static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int
|
||||
}
|
||||
|
||||
/* This strips the \n. */
|
||||
if (!read_line_old(f_in, buf, bufsiz, 0)) {
|
||||
if (!read_line_old(f_in, buf, bufsiz)) {
|
||||
if (am_client)
|
||||
rprintf(FERROR, "rsync: did not see server greeting\n");
|
||||
return -1;
|
||||
@@ -276,7 +270,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
|
||||
|
||||
sargs[sargc] = NULL;
|
||||
|
||||
if (DEBUG_GTE(CMD, 1))
|
||||
if (verbose > 1)
|
||||
print_child_argv("sending daemon args:", sargs);
|
||||
|
||||
io_printf(f_out, "%.*s\n", modlen, modname);
|
||||
@@ -286,7 +280,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
|
||||
kluge_around_eof = list_only && protocol_version < 25 ? 1 : 0;
|
||||
|
||||
while (1) {
|
||||
if (!read_line_old(f_in, line, sizeof line, 0)) {
|
||||
if (!read_line_old(f_in, line, sizeof line)) {
|
||||
rprintf(FERROR, "rsync: didn't get server startup line\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -340,7 +334,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
|
||||
|
||||
if (protocol_version < 23) {
|
||||
if (protocol_version == 22 || !am_sender)
|
||||
io_start_multiplex_in(f_in);
|
||||
io_start_multiplex_in();
|
||||
}
|
||||
|
||||
free(modname);
|
||||
@@ -348,83 +342,61 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *finish_pre_exec(pid_t pid, int write_fd, int read_fd, char *request,
|
||||
static char *finish_pre_exec(pid_t pid, int fd, char *request,
|
||||
char **early_argv, char **argv)
|
||||
{
|
||||
char buf[BIGPATHBUFLEN], *bp;
|
||||
int j = 0, status = -1, msglen = sizeof buf - 1;
|
||||
int j = 0, status = -1;
|
||||
|
||||
if (!request)
|
||||
request = "(NONE)";
|
||||
|
||||
write_buf(write_fd, request, strlen(request)+1);
|
||||
write_buf(fd, request, strlen(request)+1);
|
||||
if (early_argv) {
|
||||
for ( ; *early_argv; early_argv++)
|
||||
write_buf(write_fd, *early_argv, strlen(*early_argv)+1);
|
||||
write_buf(fd, *early_argv, strlen(*early_argv)+1);
|
||||
j = 1; /* Skip arg0 name in argv. */
|
||||
}
|
||||
for ( ; argv[j]; j++)
|
||||
write_buf(write_fd, argv[j], strlen(argv[j])+1);
|
||||
write_byte(write_fd, 0);
|
||||
|
||||
close(write_fd);
|
||||
|
||||
/* Read the stdout from the pre-xfer exec program. This it is only
|
||||
* displayed to the user if the script also returns an error status. */
|
||||
for (bp = buf; msglen > 0; msglen -= j) {
|
||||
if ((j = read(read_fd, bp, msglen)) <= 0) {
|
||||
if (j == 0)
|
||||
break;
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
break; /* Just ignore the read error for now... */
|
||||
}
|
||||
bp += j;
|
||||
if (j > 1 && bp[-1] == '\n' && bp[-2] == '\r') {
|
||||
bp--;
|
||||
j--;
|
||||
bp[-1] = '\n';
|
||||
}
|
||||
for ( ; argv[j]; j++) {
|
||||
write_buf(fd, argv[j], strlen(argv[j])+1);
|
||||
if (argv[j][0] == '.' && argv[j][1] == '\0')
|
||||
break;
|
||||
}
|
||||
*bp = '\0';
|
||||
write_byte(fd, 0);
|
||||
|
||||
close(read_fd);
|
||||
close(fd);
|
||||
|
||||
if (wait_process(pid, &status, 0) < 0
|
||||
|| !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
char *e;
|
||||
if (asprintf(&e, "pre-xfer exec returned failure (%d)%s%s%s\n%s",
|
||||
if (asprintf(&e, "pre-xfer exec returned failure (%d)%s%s\n",
|
||||
status, status < 0 ? ": " : "",
|
||||
status < 0 ? strerror(errno) : "",
|
||||
*buf ? ":" : "", buf) < 0)
|
||||
return "out_of_memory in finish_pre_exec\n";
|
||||
status < 0 ? strerror(errno) : "") < 0)
|
||||
out_of_memory("finish_pre_exec");
|
||||
return e;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PUTENV
|
||||
static int read_arg_from_pipe(int fd, char *buf, int limit)
|
||||
{
|
||||
char *bp = buf, *eob = buf + limit - 1;
|
||||
|
||||
while (1) {
|
||||
int got = read(fd, bp, 1);
|
||||
if (got != 1) {
|
||||
if (got < 0 && errno == EINTR)
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
if (*bp == '\0')
|
||||
break;
|
||||
if (bp < eob)
|
||||
bp++;
|
||||
int got = read(fd, bp, 1);
|
||||
if (got != 1) {
|
||||
if (got < 0 && errno == EINTR)
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
if (*bp == '\0')
|
||||
break;
|
||||
if (bp < eob)
|
||||
bp++;
|
||||
}
|
||||
*bp = '\0';
|
||||
|
||||
return bp - buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int path_failure(int f_out, const char *dir, BOOL was_chdir)
|
||||
{
|
||||
@@ -436,91 +408,20 @@ static int path_failure(int f_out, const char *dir, BOOL was_chdir)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int add_a_group(int f_out, const char *gname)
|
||||
{
|
||||
gid_t gid;
|
||||
if (!group_to_gid(gname, &gid, True)) {
|
||||
rprintf(FLOG, "Invalid gid %s\n", gname);
|
||||
io_printf(f_out, "@ERROR: invalid gid %s\n", gname);
|
||||
return -1;
|
||||
}
|
||||
if (gid_count == MAX_GID_LIST) {
|
||||
rprintf(FLOG, "Too many groups specified via gid parameter.\n");
|
||||
io_printf(f_out, "@ERROR: too many groups\n");
|
||||
return -1;
|
||||
}
|
||||
gid_list[gid_count++] = gid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETGROUPLIST
|
||||
static int want_all_groups(int f_out, uid_t uid)
|
||||
{
|
||||
const char *err;
|
||||
gid_count = MAX_GID_LIST;
|
||||
if ((err = getallgroups(uid, gid_list, &gid_count)) != NULL) {
|
||||
rsyserr(FLOG, errno, "%s", err);
|
||||
io_printf(f_out, "@ERROR: %s\n", err);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#elif defined HAVE_INITGROUPS
|
||||
static struct passwd *want_all_groups(int f_out, uid_t uid)
|
||||
{
|
||||
struct passwd *pw;
|
||||
if ((pw = getpwuid(uid)) == NULL) {
|
||||
rsyserr(FLOG, errno, "getpwuid failed");
|
||||
io_printf(f_out, "@ERROR: getpwuid failed\n");
|
||||
return NULL;
|
||||
}
|
||||
/* Start with the default group and initgroups() will add the reset. */
|
||||
gid_count = 1;
|
||||
gid_list[0] = pw->pw_gid;
|
||||
return pw;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void set_env_str(const char *var, const char *str)
|
||||
{
|
||||
#ifdef HAVE_PUTENV
|
||||
char *mem;
|
||||
if (asprintf(&mem, "%s=%s", var, str) < 0)
|
||||
out_of_memory("set_env_str");
|
||||
putenv(mem);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_PUTENV
|
||||
static void set_env_num(const char *var, long num)
|
||||
{
|
||||
char *mem;
|
||||
if (asprintf(&mem, "%s=%ld", var, num) < 0)
|
||||
out_of_memory("set_env_num");
|
||||
putenv(mem);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rsync_module(int f_in, int f_out, int i, const char *addr, const char *host)
|
||||
static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
|
||||
{
|
||||
int argc;
|
||||
char **argv, **orig_argv, **orig_early_argv, *module_chdir;
|
||||
char line[BIGPATHBUFLEN];
|
||||
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
|
||||
struct passwd *pw = NULL;
|
||||
#endif
|
||||
uid_t uid;
|
||||
int set_uid;
|
||||
uid_t uid = (uid_t)-2; /* canonically "nobody" */
|
||||
gid_t gid = (gid_t)-2;
|
||||
char *p, *err_msg = NULL;
|
||||
char *name = lp_name(i);
|
||||
int use_chroot = lp_use_chroot(i);
|
||||
int ret, pre_exec_arg_fd = -1, pre_exec_error_fd = -1;
|
||||
int save_munge_symlinks;
|
||||
int ret, pre_exec_fd = -1;
|
||||
pid_t pre_exec_pid = 0;
|
||||
char *request = NULL;
|
||||
|
||||
set_env_str("RSYNC_MODULE_NAME", name);
|
||||
|
||||
#ifdef ICONV_OPTION
|
||||
iconv_opt = lp_charset(i);
|
||||
if (*iconv_opt)
|
||||
@@ -528,14 +429,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
iconv_opt = NULL;
|
||||
#endif
|
||||
|
||||
/* If reverse lookup is disabled globally but enabled for this module,
|
||||
* we need to do it now before the access check. */
|
||||
if (host == undetermined_hostname && lp_reverse_lookup(i))
|
||||
host = client_name(f_in);
|
||||
set_env_str("RSYNC_HOST_NAME", host);
|
||||
set_env_str("RSYNC_HOST_ADDR", addr);
|
||||
|
||||
if (!allow_access(addr, &host, i)) {
|
||||
if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
|
||||
rprintf(FLOG, "rsync denied on module %s from %s (%s)\n",
|
||||
name, host, addr);
|
||||
if (!lp_list(i))
|
||||
@@ -567,17 +461,18 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
return -1;
|
||||
}
|
||||
|
||||
read_only = lp_read_only(i); /* may also be overridden by auth_server() */
|
||||
auth_user = auth_server(f_in, f_out, i, host, addr, "@RSYNCD: AUTHREQD ");
|
||||
|
||||
if (!auth_user) {
|
||||
io_printf(f_out, "@ERROR: auth failed on module %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
set_env_str("RSYNC_USER_NAME", auth_user);
|
||||
|
||||
module_id = i;
|
||||
|
||||
if (lp_read_only(i))
|
||||
read_only = 1;
|
||||
|
||||
if (lp_transfer_logging(i) && !logfile_format)
|
||||
logfile_format = lp_log_format(i);
|
||||
if (log_format_has(logfile_format, 'i'))
|
||||
@@ -585,53 +480,37 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
if (logfile_format_has_i || log_format_has(logfile_format, 'o'))
|
||||
logfile_format_has_o_or_i = 1;
|
||||
|
||||
uid = MY_UID();
|
||||
am_root = (uid == 0);
|
||||
am_root = (MY_UID() == 0);
|
||||
|
||||
p = *lp_uid(i) ? lp_uid(i) : am_root ? NOBODY_USER : NULL;
|
||||
if (p) {
|
||||
if (!user_to_uid(p, &uid, True)) {
|
||||
rprintf(FLOG, "Invalid uid %s\n", p);
|
||||
io_printf(f_out, "@ERROR: invalid uid %s\n", p);
|
||||
return -1;
|
||||
}
|
||||
set_uid = 1;
|
||||
} else
|
||||
set_uid = 0;
|
||||
|
||||
p = *lp_gid(i) ? strtok(lp_gid(i), ", ") : NULL;
|
||||
if (p) {
|
||||
/* The "*" gid must be the first item in the list. */
|
||||
if (strcmp(p, "*") == 0) {
|
||||
#ifdef HAVE_GETGROUPLIST
|
||||
if (want_all_groups(f_out, uid) < 0)
|
||||
return -1;
|
||||
#elif defined HAVE_INITGROUPS
|
||||
if ((pw = want_all_groups(f_out, uid)) == NULL)
|
||||
return -1;
|
||||
#else
|
||||
rprintf(FLOG, "This rsync does not support a gid of \"*\"\n");
|
||||
io_printf(f_out, "@ERROR: invalid gid setting.\n");
|
||||
return -1;
|
||||
#endif
|
||||
} else if (add_a_group(f_out, p) < 0)
|
||||
return -1;
|
||||
while ((p = strtok(NULL, ", ")) != NULL) {
|
||||
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
|
||||
if (pw) {
|
||||
rprintf(FLOG, "This rsync cannot add groups after \"*\".\n");
|
||||
io_printf(f_out, "@ERROR: invalid gid setting.\n");
|
||||
if (am_root) {
|
||||
p = lp_uid(i);
|
||||
if (!name_to_uid(p, &uid)) {
|
||||
if (!isDigit(p)) {
|
||||
rprintf(FLOG, "Invalid uid %s\n", p);
|
||||
io_printf(f_out, "@ERROR: invalid uid %s\n", p);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (add_a_group(f_out, p) < 0)
|
||||
return -1;
|
||||
uid = atoi(p);
|
||||
}
|
||||
|
||||
p = lp_gid(i);
|
||||
if (!name_to_gid(p, &gid)) {
|
||||
if (!isDigit(p)) {
|
||||
rprintf(FLOG, "Invalid gid %s\n", p);
|
||||
io_printf(f_out, "@ERROR: invalid gid %s\n", p);
|
||||
return -1;
|
||||
}
|
||||
gid = atoi(p);
|
||||
}
|
||||
} else if (am_root) {
|
||||
if (add_a_group(f_out, NOBODY_GROUP) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: If we're not root, but the configuration requests
|
||||
* that we change to some uid other than the current one, then
|
||||
* log a warning. */
|
||||
|
||||
/* TODO: Perhaps take a list of gids, and make them into the
|
||||
* supplementary groups. */
|
||||
|
||||
module_dir = lp_path(i);
|
||||
if (*module_dir == '\0') {
|
||||
rprintf(FLOG, "No path specified for module %s\n", name);
|
||||
@@ -661,7 +540,6 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
return path_failure(f_out, module_dir, False);
|
||||
full_module_path = module_dir = module_chdir;
|
||||
}
|
||||
set_env_str("RSYNC_MODULE_PATH", full_module_path);
|
||||
|
||||
if (module_dirlen == 1) {
|
||||
module_dirlen = 0;
|
||||
@@ -670,32 +548,45 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
set_filter_dir(module_dir, module_dirlen);
|
||||
|
||||
p = lp_filter(i);
|
||||
parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
|
||||
parse_rule(&daemon_filter_list, p, MATCHFLG_WORD_SPLIT,
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3);
|
||||
|
||||
p = lp_include_from(i);
|
||||
parse_filter_file(&daemon_filter_list, p, rule_template(FILTRULE_INCLUDE),
|
||||
parse_filter_file(&daemon_filter_list, p, MATCHFLG_INCLUDE,
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
|
||||
|
||||
p = lp_include(i);
|
||||
parse_filter_str(&daemon_filter_list, p,
|
||||
rule_template(FILTRULE_INCLUDE | FILTRULE_WORD_SPLIT),
|
||||
parse_rule(&daemon_filter_list, p,
|
||||
MATCHFLG_INCLUDE | MATCHFLG_WORD_SPLIT,
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES);
|
||||
|
||||
p = lp_exclude_from(i);
|
||||
parse_filter_file(&daemon_filter_list, p, rule_template(0),
|
||||
parse_filter_file(&daemon_filter_list, p, 0,
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
|
||||
|
||||
p = lp_exclude(i);
|
||||
parse_filter_str(&daemon_filter_list, p, rule_template(FILTRULE_WORD_SPLIT),
|
||||
parse_rule(&daemon_filter_list, p, MATCHFLG_WORD_SPLIT,
|
||||
XFLG_ABS_IF_SLASH | XFLG_DIR2WILD3 | XFLG_OLD_PREFIXES);
|
||||
|
||||
log_init(1);
|
||||
|
||||
#ifdef HAVE_PUTENV
|
||||
if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
|
||||
char *modname, *modpath, *hostaddr, *hostname, *username;
|
||||
int status;
|
||||
|
||||
if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
|
||||
|| asprintf(&modpath, "RSYNC_MODULE_PATH=%s", full_module_path) < 0
|
||||
|| asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0
|
||||
|| asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0
|
||||
|| asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0)
|
||||
out_of_memory("rsync_module");
|
||||
putenv(modname);
|
||||
putenv(modpath);
|
||||
putenv(hostaddr);
|
||||
putenv(hostname);
|
||||
putenv(username);
|
||||
umask(orig_umask);
|
||||
/* For post-xfer exec, fork a new process to run the rsync
|
||||
* daemon while this process waits for the exit status and
|
||||
* runs the indicated command at that point. */
|
||||
@@ -707,18 +598,18 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
return -1;
|
||||
}
|
||||
if (pid) {
|
||||
close(f_in);
|
||||
if (f_out != f_in)
|
||||
close(f_out);
|
||||
set_env_num("RSYNC_PID", (long)pid);
|
||||
if (asprintf(&p, "RSYNC_PID=%ld", (long)pid) > 0)
|
||||
putenv(p);
|
||||
if (wait_process(pid, &status, 0) < 0)
|
||||
status = -1;
|
||||
set_env_num("RSYNC_RAW_STATUS", status);
|
||||
if (asprintf(&p, "RSYNC_RAW_STATUS=%d", status) > 0)
|
||||
putenv(p);
|
||||
if (WIFEXITED(status))
|
||||
status = WEXITSTATUS(status);
|
||||
else
|
||||
status = -1;
|
||||
set_env_num("RSYNC_EXIT_STATUS", status);
|
||||
if (asprintf(&p, "RSYNC_EXIT_STATUS=%d", status) > 0)
|
||||
putenv(p);
|
||||
if (system(lp_postxfer_exec(i)) < 0)
|
||||
status = -1;
|
||||
_exit(status);
|
||||
@@ -728,9 +619,10 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
* command, though it first waits for the parent process to
|
||||
* send us the user's request via a pipe. */
|
||||
if (*lp_prexfer_exec(i)) {
|
||||
int arg_fds[2], error_fds[2];
|
||||
set_env_num("RSYNC_PID", (long)getpid());
|
||||
if (pipe(arg_fds) < 0 || pipe(error_fds) < 0 || (pre_exec_pid = fork()) < 0) {
|
||||
int fds[2];
|
||||
if (asprintf(&p, "RSYNC_PID=%ld", (long)getpid()) > 0)
|
||||
putenv(p);
|
||||
if (pipe(fds) < 0 || (pre_exec_pid = fork()) < 0) {
|
||||
rsyserr(FLOG, errno, "pre-xfer exec preparation failed");
|
||||
io_printf(f_out, "@ERROR: pre-xfer exec preparation failed\n");
|
||||
return -1;
|
||||
@@ -738,43 +630,37 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
if (pre_exec_pid == 0) {
|
||||
char buf[BIGPATHBUFLEN];
|
||||
int j, len;
|
||||
close(arg_fds[1]);
|
||||
close(error_fds[0]);
|
||||
pre_exec_arg_fd = arg_fds[0];
|
||||
pre_exec_error_fd = error_fds[1];
|
||||
set_blocking(pre_exec_arg_fd);
|
||||
set_blocking(pre_exec_error_fd);
|
||||
len = read_arg_from_pipe(pre_exec_arg_fd, buf, BIGPATHBUFLEN);
|
||||
close(fds[1]);
|
||||
set_blocking(fds[0]);
|
||||
len = read_arg_from_pipe(fds[0], buf, BIGPATHBUFLEN);
|
||||
if (len <= 0)
|
||||
_exit(1);
|
||||
set_env_str("RSYNC_REQUEST", buf);
|
||||
if (asprintf(&p, "RSYNC_REQUEST=%s", buf) > 0)
|
||||
putenv(p);
|
||||
for (j = 0; ; j++) {
|
||||
len = read_arg_from_pipe(pre_exec_arg_fd, buf,
|
||||
len = read_arg_from_pipe(fds[0], buf,
|
||||
BIGPATHBUFLEN);
|
||||
if (len <= 0) {
|
||||
if (!len)
|
||||
break;
|
||||
_exit(1);
|
||||
}
|
||||
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) >= 0)
|
||||
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) > 0)
|
||||
putenv(p);
|
||||
}
|
||||
close(pre_exec_arg_fd);
|
||||
close(fds[0]);
|
||||
close(STDIN_FILENO);
|
||||
dup2(pre_exec_error_fd, STDOUT_FILENO);
|
||||
close(pre_exec_error_fd);
|
||||
close(STDOUT_FILENO);
|
||||
status = system(lp_prexfer_exec(i));
|
||||
if (!WIFEXITED(status))
|
||||
_exit(1);
|
||||
_exit(WEXITSTATUS(status));
|
||||
}
|
||||
close(arg_fds[0]);
|
||||
close(error_fds[1]);
|
||||
pre_exec_arg_fd = arg_fds[1];
|
||||
pre_exec_error_fd = error_fds[0];
|
||||
set_blocking(pre_exec_arg_fd);
|
||||
set_blocking(pre_exec_error_fd);
|
||||
close(fds[0]);
|
||||
set_blocking(fds[1]);
|
||||
pre_exec_fd = fds[1];
|
||||
}
|
||||
umask(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -808,47 +694,46 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
munge_symlinks = !use_chroot || module_dirlen;
|
||||
if (munge_symlinks) {
|
||||
STRUCT_STAT st;
|
||||
char prefix[SYMLINK_PREFIX_LEN]; /* NOT +1 ! */
|
||||
strlcpy(prefix, SYMLINK_PREFIX, sizeof prefix); /* trim the trailing slash */
|
||||
if (do_stat(prefix, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
rprintf(FLOG, "Symlink munging is unsafe when a %s directory exists.\n",
|
||||
prefix);
|
||||
if (do_stat(SYMLINK_PREFIX, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
rprintf(FLOG, "Symlink munging is unsupported when a %s directory exists.\n",
|
||||
SYMLINK_PREFIX);
|
||||
io_printf(f_out, "@ERROR: daemon security issue -- contact admin\n", name);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
if (gid_count) {
|
||||
if (setgid(gid_list[0])) {
|
||||
rsyserr(FLOG, errno, "setgid %ld failed", (long)gid_list[0]);
|
||||
if (am_root) {
|
||||
/* XXXX: You could argue that if the daemon is started
|
||||
* by a non-root user and they explicitly specify a
|
||||
* gid, then we should try to change to that gid --
|
||||
* this could be possible if it's already in their
|
||||
* supplementary groups. */
|
||||
|
||||
/* TODO: Perhaps we need to document that if rsyncd is
|
||||
* started by somebody other than root it will inherit
|
||||
* all their supplementary groups. */
|
||||
|
||||
if (setgid(gid)) {
|
||||
rsyserr(FLOG, errno, "setgid %d failed", (int)gid);
|
||||
io_printf(f_out, "@ERROR: setgid failed\n");
|
||||
return -1;
|
||||
}
|
||||
#ifdef HAVE_SETGROUPS
|
||||
/* Set the group(s) we want to be active. */
|
||||
if (setgroups(gid_count, gid_list)) {
|
||||
/* Get rid of any supplementary groups this process
|
||||
* might have inheristed. */
|
||||
if (setgroups(1, &gid)) {
|
||||
rsyserr(FLOG, errno, "setgroups failed");
|
||||
io_printf(f_out, "@ERROR: setgroups failed\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
|
||||
/* pw is set if the user wants all the user's groups. */
|
||||
if (pw && initgroups(pw->pw_name, pw->pw_gid) < 0) {
|
||||
rsyserr(FLOG, errno, "initgroups failed");
|
||||
io_printf(f_out, "@ERROR: initgroups failed\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (set_uid) {
|
||||
if (setuid(uid) < 0
|
||||
#ifdef HAVE_SETEUID
|
||||
|| seteuid(uid) < 0
|
||||
#endif
|
||||
) {
|
||||
rsyserr(FLOG, errno, "setuid %ld failed", (long)uid);
|
||||
rsyserr(FLOG, errno, "setuid %d failed", (int)uid);
|
||||
io_printf(f_out, "@ERROR: setuid failed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -871,9 +756,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
read_args(f_in, name, line, sizeof line, rl_nulls, &argv, &argc, &request);
|
||||
orig_argv = argv;
|
||||
|
||||
save_munge_symlinks = munge_symlinks;
|
||||
|
||||
reset_output_levels(); /* future verbosity is controlled by client options */
|
||||
verbose = 0; /* future verbosity is controlled by client options */
|
||||
ret = parse_arguments(&argc, (const char ***) &argv);
|
||||
if (protect_args && ret) {
|
||||
orig_early_argv = orig_argv;
|
||||
@@ -884,11 +767,9 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
} else
|
||||
orig_early_argv = NULL;
|
||||
|
||||
munge_symlinks = save_munge_symlinks; /* The client mustn't control this. */
|
||||
|
||||
if (pre_exec_pid) {
|
||||
err_msg = finish_pre_exec(pre_exec_pid, pre_exec_arg_fd, pre_exec_error_fd,
|
||||
request, orig_early_argv, orig_argv);
|
||||
err_msg = finish_pre_exec(pre_exec_pid, pre_exec_fd, request,
|
||||
orig_early_argv, orig_argv);
|
||||
}
|
||||
|
||||
if (orig_early_argv)
|
||||
@@ -926,12 +807,13 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
|
||||
#ifndef DEBUG
|
||||
/* don't allow the logs to be flooded too fast */
|
||||
limit_output_verbosity(lp_max_verbosity(i));
|
||||
if (verbose > lp_max_verbosity(i))
|
||||
verbose = lp_max_verbosity(i);
|
||||
#endif
|
||||
|
||||
if (protocol_version < 23
|
||||
&& (protocol_version == 22 || am_sender))
|
||||
io_start_multiplex_out(f_out);
|
||||
io_start_multiplex_out();
|
||||
else if (!ret || err_msg) {
|
||||
/* We have to get I/O multiplexing started so that we can
|
||||
* get the error back to the client. This means getting
|
||||
@@ -955,19 +837,13 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
if (files_from)
|
||||
write_byte(f_out, 0);
|
||||
}
|
||||
io_start_multiplex_out(f_out);
|
||||
io_start_multiplex_out();
|
||||
}
|
||||
|
||||
if (!ret || err_msg) {
|
||||
if (err_msg) {
|
||||
while ((p = strchr(err_msg, '\n')) != NULL) {
|
||||
int len = p - err_msg + 1;
|
||||
rwrite(FERROR, err_msg, len, 0);
|
||||
err_msg += len;
|
||||
}
|
||||
if (*err_msg)
|
||||
rprintf(FERROR, "%s\n", err_msg);
|
||||
} else
|
||||
if (err_msg)
|
||||
rwrite(FERROR, err_msg, strlen(err_msg), 0);
|
||||
else
|
||||
option_error();
|
||||
msleep(400);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
@@ -1015,7 +891,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
|
||||
with "list = False". */
|
||||
static void send_listing(int fd)
|
||||
{
|
||||
int n = lp_num_modules();
|
||||
int n = lp_numservices();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
@@ -1044,7 +920,7 @@ static int load_config(int globals_only)
|
||||
int start_daemon(int f_in, int f_out)
|
||||
{
|
||||
char line[1024];
|
||||
const char *addr, *host;
|
||||
char *addr, *host;
|
||||
int i;
|
||||
|
||||
io_set_sock_fds(f_in, f_out);
|
||||
@@ -1057,7 +933,7 @@ int start_daemon(int f_in, int f_out)
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
|
||||
addr = client_addr(f_in);
|
||||
host = lp_reverse_lookup(-1) ? client_name(f_in) : undetermined_hostname;
|
||||
host = client_name(f_in);
|
||||
rprintf(FLOG, "connect from %s (%s)\n", host, addr);
|
||||
|
||||
if (!am_server) {
|
||||
@@ -1069,7 +945,7 @@ int start_daemon(int f_in, int f_out)
|
||||
return -1;
|
||||
|
||||
line[0] = 0;
|
||||
if (!read_line_old(f_in, line, sizeof line, 0))
|
||||
if (!read_line_old(f_in, line, sizeof line))
|
||||
return -1;
|
||||
|
||||
if (!*line || strcmp(line, "#list") == 0) {
|
||||
@@ -1111,14 +987,14 @@ static void create_pid_file(void)
|
||||
return;
|
||||
|
||||
cleanup_set_pid(pid);
|
||||
if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666)) == -1) {
|
||||
if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666 & ~orig_umask)) == -1) {
|
||||
failure:
|
||||
cleanup_set_pid(0);
|
||||
fprintf(stderr, "failed to create pid file %s: %s\n", pid_file, strerror(errno));
|
||||
rsyserr(FLOG, errno, "failed to create pid file %s", pid_file);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
snprintf(pidbuf, sizeof pidbuf, "%d\n", (int)pid);
|
||||
snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
|
||||
len = strlen(pidbuf);
|
||||
if (write(fd, pidbuf, len) != len)
|
||||
goto failure;
|
||||
@@ -1179,7 +1055,6 @@ int daemon_main(void)
|
||||
fprintf(stderr, "Failed to parse config file: %s\n", config_file);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
set_dparams(0);
|
||||
|
||||
if (no_detach)
|
||||
create_pid_file();
|
||||
@@ -1196,7 +1071,7 @@ int daemon_main(void)
|
||||
rprintf(FLOG, "rsyncd version %s starting, listening on port %d\n",
|
||||
RSYNC_VERSION, rsync_port);
|
||||
/* TODO: If listening on a particular address, then show that
|
||||
* address too. In fact, why not just do getnameinfo on the
|
||||
* address too. In fact, why not just do inet_ntop on the
|
||||
* local address??? */
|
||||
|
||||
start_accept_loop(rsync_port, start_daemon);
|
||||
|
||||
24
compat.c
24
compat.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) Andrew Tridgell 1996
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2004-2013 Wayne Davison
|
||||
* Copyright (C) 2004-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,7 @@ int inc_recurse = 0;
|
||||
int compat_flags = 0;
|
||||
int use_safe_inc_flist = 0;
|
||||
|
||||
extern int verbose;
|
||||
extern int am_server;
|
||||
extern int am_sender;
|
||||
extern int local_server;
|
||||
@@ -34,7 +35,6 @@ extern int inplace;
|
||||
extern int recurse;
|
||||
extern int use_qsort;
|
||||
extern int allow_inc_recurse;
|
||||
extern int preallocate_files;
|
||||
extern int append_mode;
|
||||
extern int fuzzy_basis;
|
||||
extern int read_batch;
|
||||
@@ -55,7 +55,7 @@ extern char *partial_dir;
|
||||
extern char *dest_option;
|
||||
extern char *files_from;
|
||||
extern char *filesfrom_host;
|
||||
extern filter_rule_list filter_list;
|
||||
extern struct filter_list_struct filter_list;
|
||||
extern int need_unsorted_flist;
|
||||
#ifdef ICONV_OPTION
|
||||
extern iconv_t ic_send, ic_recv;
|
||||
@@ -163,7 +163,7 @@ void setup_protocol(int f_out,int f_in)
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(PROTO, 1)) {
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
|
||||
am_server? "Server" : "Client", remote_protocol, protocol_version);
|
||||
}
|
||||
@@ -190,14 +190,6 @@ void setup_protocol(int f_out,int f_in)
|
||||
if (read_batch)
|
||||
check_batch_flags();
|
||||
|
||||
#ifndef SUPPORT_PREALLOCATION
|
||||
if (preallocate_files && !am_sender) {
|
||||
rprintf(FERROR, "preallocation is not supported on this %s\n",
|
||||
am_server ? "Server" : "Client");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (protocol_version < 30) {
|
||||
if (append_mode == 1)
|
||||
append_mode = 2;
|
||||
@@ -293,7 +285,7 @@ void setup_protocol(int f_out,int f_in)
|
||||
read_batch ? "batch file" : "connection");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
use_safe_inc_flist = (compat_flags & CF_SAFE_FLIST) || protocol_version >= 31;
|
||||
use_safe_inc_flist = !!(compat_flags & CF_SAFE_FLIST);
|
||||
need_messages_from_generator = 1;
|
||||
#ifdef CAN_SET_SYMLINK_TIMES
|
||||
} else if (!am_sender) {
|
||||
@@ -305,10 +297,10 @@ void setup_protocol(int f_out,int f_in)
|
||||
unsort_ndx = ++file_extra_cnt;
|
||||
|
||||
if (partial_dir && *partial_dir != '/' && (!am_server || local_server)) {
|
||||
int rflags = FILTRULE_NO_PREFIXES | FILTRULE_DIRECTORY;
|
||||
int flags = MATCHFLG_NO_PREFIXES | MATCHFLG_DIRECTORY;
|
||||
if (!am_sender || protocol_version >= 30)
|
||||
rflags |= FILTRULE_PERISHABLE;
|
||||
parse_filter_str(&filter_list, partial_dir, rule_template(rflags), 0);
|
||||
flags |= MATCHFLG_PERISHABLE;
|
||||
parse_rule(&filter_list, partial_dir, flags, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
652
config.guess
vendored
Normal file → Executable file
652
config.guess
vendored
Normal file → Executable file
@@ -1,12 +1,14 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2013 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2013-05-16'
|
||||
timestamp='2006-07-02'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
@@ -15,23 +17,27 @@ timestamp='2013-05-16'
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that
|
||||
# program. This Exception is an additional permission under section 7
|
||||
# of the GNU General Public License, version 3 ("GPLv3").
|
||||
#
|
||||
# Originally written by Per Bothner.
|
||||
#
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
#
|
||||
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
|
||||
# Originally written by Per Bothner <per@bothner.com>.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
# exits with 0. Otherwise, it exits with 1.
|
||||
#
|
||||
# The plan is that this can be called by configure scripts if you
|
||||
# don't specify an explicit build system type.
|
||||
|
||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||
|
||||
usage="\
|
||||
@@ -50,7 +56,8 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright 1992-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -132,33 +139,12 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
|
||||
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
case "${UNAME_SYSTEM}" in
|
||||
Linux|GNU|GNU/*)
|
||||
# If the system lacks a compiler, then just pick glibc.
|
||||
# We could probably try harder.
|
||||
LIBC=gnu
|
||||
|
||||
eval $set_cc_for_build
|
||||
cat <<-EOF > $dummy.c
|
||||
#include <features.h>
|
||||
#if defined(__UCLIBC__)
|
||||
LIBC=uclibc
|
||||
#elif defined(__dietlibc__)
|
||||
LIBC=dietlibc
|
||||
#else
|
||||
LIBC=gnu
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
|
||||
;;
|
||||
esac
|
||||
|
||||
# Note: order is significant - the case branches are not exclusive.
|
||||
|
||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:NetBSD:*:*)
|
||||
# NetBSD (nbsd) targets should (where applicable) match one or
|
||||
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
|
||||
# switched to ELF, *-*-netbsd* would select the old
|
||||
# object file format. This provides both forward
|
||||
@@ -175,7 +161,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
arm*) machine=arm-unknown ;;
|
||||
sh3el) machine=shl-unknown ;;
|
||||
sh3eb) machine=sh-unknown ;;
|
||||
sh5el) machine=sh5le-unknown ;;
|
||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format, if it has switched
|
||||
@@ -184,7 +169,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
eval $set_cc_for_build
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ELF__
|
||||
| grep __ELF__ >/dev/null
|
||||
then
|
||||
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
|
||||
# Return netbsd for either. FIX?
|
||||
@@ -194,7 +179,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
os=netbsd
|
||||
os=netbsd
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
@@ -215,10 +200,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
exit ;;
|
||||
*:Bitrig:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
|
||||
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:OpenBSD:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
||||
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
|
||||
@@ -241,7 +222,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
;;
|
||||
*5.*)
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
;;
|
||||
esac
|
||||
# According to Compaq, /usr/sbin/psrinfo has been available on
|
||||
@@ -287,10 +268,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
|
||||
exitcode=$?
|
||||
trap '' 0
|
||||
exit $exitcode ;;
|
||||
exit ;;
|
||||
Alpha\ *:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# Should we change UNAME_MACHINE based on the output of uname instead
|
||||
@@ -316,12 +294,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
echo s390-ibm-zvmoe
|
||||
exit ;;
|
||||
*:OS400:*:*)
|
||||
echo powerpc-ibm-os400
|
||||
echo powerpc-ibm-os400
|
||||
exit ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
arm*:riscos:*:*|arm*:RISCOS:*:*)
|
||||
arm:riscos:*:*|arm:RISCOS:*:*)
|
||||
echo arm-unknown-riscos
|
||||
exit ;;
|
||||
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
|
||||
@@ -345,33 +323,14 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
case `/usr/bin/uname -p` in
|
||||
sparc) echo sparc-icl-nx7; exit ;;
|
||||
esac ;;
|
||||
s390x:SunOS:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4H:SunOS:5.*:*)
|
||||
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
|
||||
echo i386-pc-auroraux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||
eval $set_cc_for_build
|
||||
SUN_ARCH="i386"
|
||||
# If there is a compiler, see if it is configured for 64-bit objects.
|
||||
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
||||
# This test works for both compilers.
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
SUN_ARCH="x86_64"
|
||||
fi
|
||||
fi
|
||||
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
i86pc:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
# According to config.sub, this is the proper way to canonicalize
|
||||
@@ -415,23 +374,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# MiNT. But MiNT is downward compatible to TOS, so this should
|
||||
# be no problem.
|
||||
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
exit ;;
|
||||
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
m68k:machten:*:*)
|
||||
echo m68k-apple-machten${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -501,8 +460,8 @@ EOF
|
||||
echo m88k-motorola-sysv3
|
||||
exit ;;
|
||||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
|
||||
then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
|
||||
@@ -515,7 +474,7 @@ EOF
|
||||
else
|
||||
echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||
echo m88k-dolphin-sysv3
|
||||
exit ;;
|
||||
@@ -572,7 +531,7 @@ EOF
|
||||
echo rs6000-ibm-aix3.2
|
||||
fi
|
||||
exit ;;
|
||||
*:AIX:*:[4567])
|
||||
*:AIX:*:[45])
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
@@ -615,52 +574,52 @@ EOF
|
||||
9000/[678][0-9][0-9])
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
||||
esac ;;
|
||||
esac
|
||||
esac ;;
|
||||
esac
|
||||
fi
|
||||
if [ "${HP_ARCH}" = "" ]; then
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
long bits = sysconf(_SC_KERNEL_BITS);
|
||||
#endif
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
int main ()
|
||||
{
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
long bits = sysconf(_SC_KERNEL_BITS);
|
||||
#endif
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||
case CPU_PA_RISC2_0:
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
switch (bits)
|
||||
{
|
||||
case 64: puts ("hppa2.0w"); break;
|
||||
case 32: puts ("hppa2.0n"); break;
|
||||
default: puts ("hppa2.0"); break;
|
||||
} break;
|
||||
#else /* !defined(_SC_KERNEL_BITS) */
|
||||
puts ("hppa2.0"); break;
|
||||
#endif
|
||||
default: puts ("hppa1.0"); break;
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||
case CPU_PA_RISC2_0:
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
switch (bits)
|
||||
{
|
||||
case 64: puts ("hppa2.0w"); break;
|
||||
case 32: puts ("hppa2.0n"); break;
|
||||
default: puts ("hppa2.0"); break;
|
||||
} break;
|
||||
#else /* !defined(_SC_KERNEL_BITS) */
|
||||
puts ("hppa2.0"); break;
|
||||
#endif
|
||||
default: puts ("hppa1.0"); break;
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||
@@ -680,7 +639,7 @@ EOF
|
||||
# => hppa64-hp-hpux11.23
|
||||
|
||||
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
|
||||
grep -q __LP64__
|
||||
grep __LP64__ >/dev/null
|
||||
then
|
||||
HP_ARCH="hppa2.0w"
|
||||
else
|
||||
@@ -751,22 +710,22 @@ EOF
|
||||
exit ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||
echo c34-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||
echo c38-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit ;;
|
||||
@@ -790,14 +749,14 @@ EOF
|
||||
exit ;;
|
||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
5000:UNIX_System_V:4.*:*)
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
@@ -809,51 +768,37 @@ EOF
|
||||
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:FreeBSD:*:*)
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
case ${UNAME_PROCESSOR} in
|
||||
case ${UNAME_MACHINE} in
|
||||
pc98)
|
||||
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
amd64)
|
||||
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
*)
|
||||
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
esac
|
||||
exit ;;
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
exit ;;
|
||||
*:MINGW64*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw64
|
||||
exit ;;
|
||||
*:MINGW*:*)
|
||||
i*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
i*:MSYS*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msys
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
exit ;;
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit ;;
|
||||
*:Interix*:*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
authenticamd | genuineintel | EM64T)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
IA64)
|
||||
echo ia64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
esac ;;
|
||||
x86:Interix*:[3456]*)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T:Interix*:[3456]*)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
exit ;;
|
||||
8664:Windows_NT:*)
|
||||
echo x86_64-pc-mks
|
||||
exit ;;
|
||||
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
|
||||
@@ -874,21 +819,93 @@ EOF
|
||||
exit ;;
|
||||
*:GNU:*:*)
|
||||
# the GNU system
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
exit ;;
|
||||
*:GNU/*:*:*)
|
||||
# other systems with GNU libc and userland
|
||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
|
||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
|
||||
exit ;;
|
||||
i*86:Minix:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-minix
|
||||
exit ;;
|
||||
aarch64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
arm*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
aarch64_be:Linux:*:*)
|
||||
UNAME_MACHINE=aarch64_be
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
cris:Linux:*:*)
|
||||
echo cris-axis-linux-gnu
|
||||
exit ;;
|
||||
crisv32:Linux:*:*)
|
||||
echo crisv32-axis-linux-gnu
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo frv-unknown-linux-gnu
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
mips:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips
|
||||
#undef mipsel
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mipsel
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips64
|
||||
#undef mips64el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mips64el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips64
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
or32:Linux:*:*)
|
||||
echo or32-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
exit ;;
|
||||
alpha:Linux:*:*)
|
||||
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
||||
@@ -899,126 +916,103 @@ EOF
|
||||
EV6) UNAME_MACHINE=alphaev6 ;;
|
||||
EV67) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||||
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
arc:Linux:*:* | arceb:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
else
|
||||
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_PCS_VFP
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
|
||||
fi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
cris:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||
exit ;;
|
||||
crisv32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
hexagon:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
mips:Linux:*:* | mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef ${UNAME_MACHINE}
|
||||
#undef ${UNAME_MACHINE}el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=${UNAME_MACHINE}el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=${UNAME_MACHINE}
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
|
||||
;;
|
||||
or1k:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
or32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
padre:Linux:*:*)
|
||||
echo sparc-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||
echo hppa64-unknown-linux-${LIBC}
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||||
exit ;;
|
||||
parisc:Linux:*:* | hppa:Linux:*:*)
|
||||
# Look for CPU level
|
||||
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
||||
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
|
||||
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
|
||||
*) echo hppa-unknown-linux-${LIBC} ;;
|
||||
PA7*) echo hppa1.1-unknown-linux-gnu ;;
|
||||
PA8*) echo hppa2.0-unknown-linux-gnu ;;
|
||||
*) echo hppa-unknown-linux-gnu ;;
|
||||
esac
|
||||
exit ;;
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-${LIBC}
|
||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||
echo hppa64-unknown-linux-gnu
|
||||
exit ;;
|
||||
s390:Linux:*:* | s390x:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-ibm-linux
|
||||
exit ;;
|
||||
sh64*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
sh*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
tile*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
vax:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-dec-linux-gnu
|
||||
exit ;;
|
||||
x86_64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
echo x86_64-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
# problems with other programs or directories called `ld' in the path.
|
||||
# Set LC_ALL=C to ensure ld outputs messages in English.
|
||||
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
|
||||
| sed -ne '/supported targets:/!d
|
||||
s/[ ][ ]*/ /g
|
||||
s/.*supported targets: *//
|
||||
s/ .*//
|
||||
p'`
|
||||
case "$ld_supported_targets" in
|
||||
elf32-i386)
|
||||
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
|
||||
;;
|
||||
a.out-i386-linux)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||
exit ;;
|
||||
coff-i386)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||
exit ;;
|
||||
"")
|
||||
# Either a pre-BFD a.out linker (linux-gnuoldld) or
|
||||
# one that does not give us useful --help.
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
|
||||
exit ;;
|
||||
esac
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <features.h>
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
LIBC=gnu
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
#else
|
||||
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
LIBC=gnu
|
||||
#else
|
||||
LIBC=gnuaout
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __dietlibc__
|
||||
LIBC=dietlibc
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^LIBC/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${LIBC}" != x && {
|
||||
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||||
exit
|
||||
}
|
||||
test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
|
||||
;;
|
||||
i*86:DYNIX/ptx:4*:*)
|
||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
||||
# earlier versions are messed up and put the nodename in both
|
||||
@@ -1026,11 +1020,11 @@ EOF
|
||||
echo i386-sequent-sysv4
|
||||
exit ;;
|
||||
i*86:UNIX_SV:4.2MP:2.*)
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# I just have to hope. -- rms.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit ;;
|
||||
i*86:OS/2:*:*)
|
||||
@@ -1047,7 +1041,7 @@ EOF
|
||||
i*86:syllable:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-syllable
|
||||
exit ;;
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
i*86:*DOS:*:*)
|
||||
@@ -1062,7 +1056,7 @@ EOF
|
||||
fi
|
||||
exit ;;
|
||||
i*86:*:5:[678]*)
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
case `/bin/uname -X | grep "^Machine"` in
|
||||
*486*) UNAME_MACHINE=i486 ;;
|
||||
*Pentium) UNAME_MACHINE=i586 ;;
|
||||
@@ -1090,13 +1084,10 @@ EOF
|
||||
exit ;;
|
||||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# Note: whatever this is, it MUST be the same as what config.sub
|
||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
||||
# this is a cross-build.
|
||||
echo i586-pc-msdosdjgpp
|
||||
exit ;;
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
echo i386-pc-msdosdjgpp
|
||||
exit ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-pc-mach3
|
||||
exit ;;
|
||||
@@ -1131,18 +1122,8 @@ EOF
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
|
||||
OS_REL='.3'
|
||||
test -r /etc/.relid \
|
||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
|
||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1155,7 +1136,7 @@ EOF
|
||||
rs6000:LynxOS:2.*:*)
|
||||
echo rs6000-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
|
||||
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
|
||||
echo powerpc-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SM[BE]S:UNIX_SV:*:*)
|
||||
@@ -1175,10 +1156,10 @@ EOF
|
||||
echo ns32k-sni-sysv
|
||||
fi
|
||||
exit ;;
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
# From Gerald Hewes <hewes@openmarket.com>.
|
||||
# How about differentiating between stratus architectures? -djm
|
||||
@@ -1204,11 +1185,11 @@ EOF
|
||||
exit ;;
|
||||
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
|
||||
if [ -d /usr/nec ]; then
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
|
||||
echo powerpc-be-beos
|
||||
exit ;;
|
||||
@@ -1218,12 +1199,6 @@ EOF
|
||||
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
|
||||
echo i586-pc-beos
|
||||
exit ;;
|
||||
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
|
||||
echo i586-pc-haiku
|
||||
exit ;;
|
||||
x86_64:Haiku:*:*)
|
||||
echo x86_64-unknown-haiku
|
||||
exit ;;
|
||||
SX-4:SUPER-UX:*:*)
|
||||
echo sx4-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1233,15 +1208,6 @@ EOF
|
||||
SX-6:SUPER-UX:*:*)
|
||||
echo sx6-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-7:SUPER-UX:*:*)
|
||||
echo sx7-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-8:SUPER-UX:*:*)
|
||||
echo sx8-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-8R:SUPER-UX:*:*)
|
||||
echo sx8r-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
Power*:Rhapsody:*:*)
|
||||
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1250,21 +1216,9 @@ EOF
|
||||
exit ;;
|
||||
*:Darwin:*:*)
|
||||
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
||||
eval $set_cc_for_build
|
||||
if test "$UNAME_PROCESSOR" = unknown ; then
|
||||
UNAME_PROCESSOR=powerpc
|
||||
fi
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
case $UNAME_PROCESSOR in
|
||||
i386) UNAME_PROCESSOR=x86_64 ;;
|
||||
powerpc) UNAME_PROCESSOR=powerpc64 ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
case $UNAME_PROCESSOR in
|
||||
unknown) UNAME_PROCESSOR=powerpc ;;
|
||||
esac
|
||||
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||
@@ -1278,10 +1232,7 @@ EOF
|
||||
*:QNX:*:4*)
|
||||
echo i386-pc-qnx
|
||||
exit ;;
|
||||
NEO-?:NONSTOP_KERNEL:*:*)
|
||||
echo neo-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSE-*:NONSTOP_KERNEL:*:*)
|
||||
NSE-?:NONSTOP_KERNEL:*:*)
|
||||
echo nse-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSR-?:NONSTOP_KERNEL:*:*)
|
||||
@@ -1326,13 +1277,13 @@ EOF
|
||||
echo pdp10-unknown-its
|
||||
exit ;;
|
||||
SEI:*:*:SEIUX)
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:DragonFly:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit ;;
|
||||
*:*VMS:*:*)
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
case "${UNAME_MACHINE}" in
|
||||
A*) echo alpha-dec-vms ; exit ;;
|
||||
I*) echo ia64-dec-vms ; exit ;;
|
||||
@@ -1347,14 +1298,11 @@ EOF
|
||||
i*86:rdos:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-rdos
|
||||
exit ;;
|
||||
i*86:AROS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-aros
|
||||
exit ;;
|
||||
x86_64:VMkernel:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-esx
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||
|
||||
eval $set_cc_for_build
|
||||
cat >$dummy.c <<EOF
|
||||
#ifdef _SEQUENT_
|
||||
@@ -1372,11 +1320,11 @@ main ()
|
||||
#include <sys/param.h>
|
||||
printf ("m68k-sony-newsos%s\n",
|
||||
#ifdef NEWSOS4
|
||||
"4"
|
||||
"4"
|
||||
#else
|
||||
""
|
||||
""
|
||||
#endif
|
||||
); exit (0);
|
||||
); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1510,9 +1458,9 @@ This script, last modified $timestamp, has failed to recognize
|
||||
the operating system you are using. It is advised that you
|
||||
download the most up to date version of the config scripts from
|
||||
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
|
||||
and
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
|
||||
|
||||
If the version you run ($0) is already up to date, please
|
||||
send the following data and any information you think might be
|
||||
|
||||
382
config.sub
vendored
Normal file → Executable file
382
config.sub
vendored
Normal file → Executable file
@@ -1,40 +1,44 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2013 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2013-04-24'
|
||||
timestamp='2006-07-02'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
# can handle that machine. It does not imply ALL GNU software can.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that
|
||||
# program. This Exception is an additional permission under section 7
|
||||
# of the GNU General Public License, version 3 ("GPLv3").
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
|
||||
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
|
||||
# This file is supposed to be the same for all GNU packages
|
||||
# and recognize all the CPU types, system types and aliases
|
||||
# that are meaningful with *any* GNU software.
|
||||
@@ -68,7 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright 1992-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -115,18 +120,12 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
kopensolaris*-gnu* | \
|
||||
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
|
||||
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
android-linux)
|
||||
os=-linux-android
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
|
||||
;;
|
||||
*)
|
||||
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
||||
if [ $basic_machine != $1 ]
|
||||
@@ -149,13 +148,10 @@ case $os in
|
||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple | -axis | -knuth | -cray | -microblaze*)
|
||||
-apple | -axis | -knuth | -cray)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
-bluegene*)
|
||||
os=-cnk
|
||||
;;
|
||||
-sim | -cisco | -oki | -wec | -winbond)
|
||||
os=
|
||||
basic_machine=$1
|
||||
@@ -170,10 +166,10 @@ case $os in
|
||||
os=-chorusos
|
||||
basic_machine=$1
|
||||
;;
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
basic_machine=$1
|
||||
;;
|
||||
;;
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
@@ -218,12 +214,6 @@ case $os in
|
||||
-isc*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-lynx*178)
|
||||
os=-lynxos178
|
||||
;;
|
||||
-lynx*5)
|
||||
os=-lynxos5
|
||||
;;
|
||||
-lynx*)
|
||||
os=-lynxos
|
||||
;;
|
||||
@@ -248,34 +238,24 @@ case $basic_machine in
|
||||
# Some are omitted here because they have special meanings below.
|
||||
1750a | 580 \
|
||||
| a29k \
|
||||
| aarch64 | aarch64_be \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| am33_2.0 \
|
||||
| arc | arceb \
|
||||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
||||
| avr | avr32 \
|
||||
| be32 | be64 \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| epiphany \
|
||||
| fido | fr30 | frv \
|
||||
| fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| hexagon \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| le32 | le64 \
|
||||
| lm32 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
|
||||
| maxq | mb | microblaze | mcore \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
| mips64octeon | mips64octeonel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64r5900 | mips64r5900el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
@@ -286,45 +266,30 @@ case $basic_machine in
|
||||
| mipsisa64r2 | mipsisa64r2el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipsr5900 | mipsr5900el \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| moxie \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nds32 | nds32le | nds32be \
|
||||
| nios | nios2 | nios2eb | nios2el \
|
||||
| nios | nios2 \
|
||||
| ns16k | ns32k \
|
||||
| open8 \
|
||||
| or1k | or32 \
|
||||
| or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| rl78 | rx \
|
||||
| score \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
| spu \
|
||||
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
|
||||
| ubicom32 \
|
||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||
| spu | strongarm \
|
||||
| tahoe | thumb | tic4x | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| we32k \
|
||||
| x86 | xc16x | xstormy16 | xtensa \
|
||||
| z8k | z80)
|
||||
| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
c54x)
|
||||
basic_machine=tic54x-unknown
|
||||
;;
|
||||
c55x)
|
||||
basic_machine=tic55x-unknown
|
||||
;;
|
||||
c6x)
|
||||
basic_machine=tic6x-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
# Motorola 68HC11/12.
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
@@ -334,21 +299,6 @@ case $basic_machine in
|
||||
basic_machine=mt-unknown
|
||||
;;
|
||||
|
||||
strongarm | thumb | xscale)
|
||||
basic_machine=arm-unknown
|
||||
;;
|
||||
xgate)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
xscaleeb)
|
||||
basic_machine=armeb-unknown
|
||||
;;
|
||||
|
||||
xscaleel)
|
||||
basic_machine=armel-unknown
|
||||
;;
|
||||
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
# (2) the word "unknown" tends to confuse beginning users.
|
||||
@@ -363,37 +313,29 @@ case $basic_machine in
|
||||
# Recognize the basic CPU types with company name.
|
||||
580-* \
|
||||
| a29k-* \
|
||||
| aarch64-* | aarch64_be-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* | avr32-* \
|
||||
| be32-* | be64-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| hexagon-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| le32-* | le64-* \
|
||||
| lm32-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
|
||||
| microblaze-* | microblazeel-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
| mips64octeon-* | mips64octeonel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64r5900-* | mips64r5900el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
@@ -404,41 +346,31 @@ case $basic_machine in
|
||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipsr5900-* | mipsr5900el-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| mmix-* \
|
||||
| mt-* \
|
||||
| msp430-* \
|
||||
| nds32-* | nds32le-* | nds32be-* \
|
||||
| nios-* | nios2-* | nios2eb-* | nios2el-* \
|
||||
| nios-* | nios2-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| open8-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| rl78-* | romp-* | rs6000-* | rx-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
|
||||
| tahoe-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tile*-* \
|
||||
| tron-* \
|
||||
| ubicom32-* \
|
||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||
| vax-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| xstormy16-* | xtensa-* \
|
||||
| ymp-* \
|
||||
| z8k-* | z80-*)
|
||||
;;
|
||||
# Recognize the basic CPU types without company name, with glob match.
|
||||
xtensa*)
|
||||
basic_machine=$basic_machine-unknown
|
||||
| z8k-*)
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
@@ -456,7 +388,7 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
@@ -502,10 +434,6 @@ case $basic_machine in
|
||||
basic_machine=m68k-apollo
|
||||
os=-bsd
|
||||
;;
|
||||
aros)
|
||||
basic_machine=i386-pc
|
||||
os=-aros
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
@@ -514,35 +442,10 @@ case $basic_machine in
|
||||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
blackfin)
|
||||
basic_machine=bfin-unknown
|
||||
os=-linux
|
||||
;;
|
||||
blackfin-*)
|
||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
bluegene*)
|
||||
basic_machine=powerpc-ibm
|
||||
os=-cnk
|
||||
;;
|
||||
c54x-*)
|
||||
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c55x-*)
|
||||
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c6x-*)
|
||||
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cegcc)
|
||||
basic_machine=arm-unknown
|
||||
os=-cegcc
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
@@ -571,8 +474,8 @@ case $basic_machine in
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16 | cr16-*)
|
||||
basic_machine=cr16-unknown
|
||||
cr16c)
|
||||
basic_machine=cr16c-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
@@ -610,10 +513,6 @@ case $basic_machine in
|
||||
basic_machine=m88k-motorola
|
||||
os=-sysv3
|
||||
;;
|
||||
dicos)
|
||||
basic_machine=i686-pc
|
||||
os=-dicos
|
||||
;;
|
||||
djgpp)
|
||||
basic_machine=i586-pc
|
||||
os=-msdosdjgpp
|
||||
@@ -729,6 +628,7 @@ case $basic_machine in
|
||||
i370-ibm* | ibm*)
|
||||
basic_machine=i370-ibm
|
||||
;;
|
||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||
i*86v32)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv32
|
||||
@@ -767,14 +667,6 @@ case $basic_machine in
|
||||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
m68knommu)
|
||||
basic_machine=m68k-unknown
|
||||
os=-linux
|
||||
;;
|
||||
m68knommu-*)
|
||||
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
m88k-omron*)
|
||||
basic_machine=m88k-omron
|
||||
;;
|
||||
@@ -786,21 +678,10 @@ case $basic_machine in
|
||||
basic_machine=ns32k-utek
|
||||
os=-sysv
|
||||
;;
|
||||
microblaze*)
|
||||
basic_machine=microblaze-xilinx
|
||||
;;
|
||||
mingw64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-mingw64
|
||||
;;
|
||||
mingw32)
|
||||
basic_machine=i386-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
mingw32ce)
|
||||
basic_machine=arm-unknown
|
||||
os=-mingw32ce
|
||||
;;
|
||||
miniframe)
|
||||
basic_machine=m68000-convergent
|
||||
;;
|
||||
@@ -829,18 +710,10 @@ case $basic_machine in
|
||||
ms1-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||
;;
|
||||
msys)
|
||||
basic_machine=i386-pc
|
||||
os=-msys
|
||||
;;
|
||||
mvs)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
;;
|
||||
nacl)
|
||||
basic_machine=le32-unknown
|
||||
os=-nacl
|
||||
;;
|
||||
ncr3000)
|
||||
basic_machine=i486-ncr
|
||||
os=-sysv4
|
||||
@@ -905,12 +778,6 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
neo-tandem)
|
||||
basic_machine=neo-tandem
|
||||
;;
|
||||
nse-tandem)
|
||||
basic_machine=nse-tandem
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@@ -941,14 +808,6 @@ case $basic_machine in
|
||||
basic_machine=i860-intel
|
||||
os=-osf
|
||||
;;
|
||||
parisc)
|
||||
basic_machine=hppa-unknown
|
||||
os=-linux
|
||||
;;
|
||||
parisc-*)
|
||||
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
pbd)
|
||||
basic_machine=sparc-tti
|
||||
;;
|
||||
@@ -993,10 +852,9 @@ case $basic_machine in
|
||||
;;
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc | ppcbe) basic_machine=powerpc-unknown
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
;;
|
||||
ppc-* | ppcbe-*)
|
||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
@@ -1021,11 +879,7 @@ case $basic_machine in
|
||||
basic_machine=i586-unknown
|
||||
os=-pw32
|
||||
;;
|
||||
rdos | rdos64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-rdos
|
||||
;;
|
||||
rdos32)
|
||||
rdos)
|
||||
basic_machine=i386-pc
|
||||
os=-rdos
|
||||
;;
|
||||
@@ -1055,10 +909,6 @@ case $basic_machine in
|
||||
sb1el)
|
||||
basic_machine=mipsisa64sb1el-unknown
|
||||
;;
|
||||
sde)
|
||||
basic_machine=mipsisa32-sde
|
||||
os=-elf
|
||||
;;
|
||||
sei)
|
||||
basic_machine=mips-sei
|
||||
os=-seiux
|
||||
@@ -1070,9 +920,6 @@ case $basic_machine in
|
||||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sh5el)
|
||||
basic_machine=sh5le-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
@@ -1094,9 +941,6 @@ case $basic_machine in
|
||||
basic_machine=i860-stratus
|
||||
os=-sysv4
|
||||
;;
|
||||
strongarm-* | thumb-*)
|
||||
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
sun2)
|
||||
basic_machine=m68000-sun
|
||||
;;
|
||||
@@ -1153,9 +997,17 @@ case $basic_machine in
|
||||
basic_machine=t90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tile*)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-linux-gnu
|
||||
tic54x | c54x*)
|
||||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic55x | c55x*)
|
||||
basic_machine=tic55x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic6x | c6x*)
|
||||
basic_machine=tic6x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tx39)
|
||||
basic_machine=mipstx39-unknown
|
||||
@@ -1224,9 +1076,6 @@ case $basic_machine in
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
xscale-* | xscalee[bl]-*)
|
||||
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
|
||||
;;
|
||||
ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
@@ -1235,10 +1084,6 @@ case $basic_machine in
|
||||
basic_machine=z8k-unknown
|
||||
os=-sim
|
||||
;;
|
||||
z80-*-coff)
|
||||
basic_machine=z80-unknown
|
||||
os=-sim
|
||||
;;
|
||||
none)
|
||||
basic_machine=none-none
|
||||
os=-none
|
||||
@@ -1277,7 +1122,7 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
||||
@@ -1324,12 +1169,9 @@ esac
|
||||
if [ x"$os" != x"" ]
|
||||
then
|
||||
case $os in
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# -solaris* is a basic system type, with this one exception.
|
||||
-auroraux)
|
||||
os=-auroraux
|
||||
;;
|
||||
-solaris1 | -solaris1.*)
|
||||
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||
;;
|
||||
@@ -1350,23 +1192,21 @@ case $os in
|
||||
# Each alternative MUST END IN A *, to match a version number.
|
||||
# -sysv* is not here because it comes later, after sysvr4.
|
||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||
| -sym* | -kopensolaris* | -plan9* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* | -aros* \
|
||||
| -aos* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* \
|
||||
| -openbsd* | -solidbsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
@@ -1374,7 +1214,7 @@ case $os in
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1413,7 +1253,7 @@ case $os in
|
||||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-os400*)
|
||||
-os400*)
|
||||
os=-os400
|
||||
;;
|
||||
-wince*)
|
||||
@@ -1462,7 +1302,7 @@ case $os in
|
||||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-tpf*)
|
||||
-tpf*)
|
||||
os=-tpf
|
||||
;;
|
||||
-triton*)
|
||||
@@ -1498,14 +1338,12 @@ case $os in
|
||||
-aros*)
|
||||
os=-aros
|
||||
;;
|
||||
-kaos*)
|
||||
os=-kaos
|
||||
;;
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-dicos*)
|
||||
os=-dicos
|
||||
;;
|
||||
-nacl*)
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@@ -1528,10 +1366,7 @@ else
|
||||
# system, and we'll never get to this point.
|
||||
|
||||
case $basic_machine in
|
||||
score-*)
|
||||
os=-elf
|
||||
;;
|
||||
spu-*)
|
||||
spu-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-acorn)
|
||||
@@ -1543,20 +1378,8 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
hexagon-*)
|
||||
os=-elf
|
||||
;;
|
||||
tic54x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic55x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic6x-*)
|
||||
os=-coff
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
@@ -1576,22 +1399,19 @@ case $basic_machine in
|
||||
;;
|
||||
m68000-sun)
|
||||
os=-sunos3
|
||||
# This also exists in the configure program, but was not the
|
||||
# default.
|
||||
# os=-sunos4
|
||||
;;
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-*)
|
||||
os=-elf
|
||||
;;
|
||||
or1k-*)
|
||||
os=-elf
|
||||
;;
|
||||
or32-*)
|
||||
os=-coff
|
||||
;;
|
||||
@@ -1610,7 +1430,7 @@ case $basic_machine in
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-knuth)
|
||||
*-knuth)
|
||||
os=-mmixware
|
||||
;;
|
||||
*-wec)
|
||||
@@ -1715,7 +1535,7 @@ case $basic_machine in
|
||||
-sunos*)
|
||||
vendor=sun
|
||||
;;
|
||||
-cnk*|-aix*)
|
||||
-aix*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-beos*)
|
||||
|
||||
2
configure
vendored
2
configure
vendored
@@ -8,8 +8,6 @@ realconfigure="$dir/configure.sh"
|
||||
|
||||
if test ! -f "$realconfigure"; then
|
||||
if test -f "$HOME/build_farm/build_test.fns"; then
|
||||
# Test the included popt
|
||||
set -- --with-included-popt "${@}"
|
||||
# Allow the build farm to grab latest files via rsync.
|
||||
actions='build fetch'
|
||||
else
|
||||
|
||||
115
configure.ac
115
configure.ac
@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PREREQ(2.59)
|
||||
|
||||
RSYNC_VERSION=3.1.0
|
||||
RSYNC_VERSION=3.0.8
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
|
||||
|
||||
@@ -39,7 +39,6 @@ AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_EGREP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_MKDIR_P
|
||||
AC_PROG_CC_STDC
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
@@ -79,15 +78,6 @@ fi
|
||||
AC_ARG_WITH(included-popt,
|
||||
AC_HELP_STRING([--with-included-popt], [use bundled popt library, not from system]))
|
||||
|
||||
AC_ARG_WITH(included-zlib,
|
||||
AC_HELP_STRING([--with-included-zlib], [use bundled zlib library, not from system]))
|
||||
|
||||
AC_ARG_WITH(protected-args,
|
||||
AC_HELP_STRING([--with-protected-args], [make --protected-args option the default]))
|
||||
if test x"$with_protected_args" = x"yes"; then
|
||||
AC_DEFINE_UNQUOTED(RSYNC_USE_PROTECTED_ARGS, 1, [Define to 1 if --protected-args should be the default])
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(rsync-path,
|
||||
AC_HELP_STRING([--with-rsync-path=PATH], [set default --rsync-path to PATH (default: rsync)]),
|
||||
[ RSYNC_PATH="$with_rsync_path" ],
|
||||
@@ -134,14 +124,8 @@ AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
|
||||
AC_CHECK_PROG(HAVE_YODL2MAN, yodl2man, 1, 0)
|
||||
if test x$HAVE_YODL2MAN = x1; then
|
||||
MAKE_MAN=man
|
||||
else
|
||||
MAKE_MAN=man-copy
|
||||
fi
|
||||
|
||||
# Some programs on solaris are only found in /usr/xpg4/bin (or work better than others versions).
|
||||
AC_PATH_PROG(SHELL_PATH, sh, /bin/sh, [/usr/xpg4/bin$PATH_SEPARATOR$PATH])
|
||||
AC_PATH_PROG(FAKEROOT_PATH, fakeroot, /usr/bin/fakeroot, [/usr/xpg4/bin$PATH_SEPARATOR$PATH])
|
||||
|
||||
AC_ARG_WITH(nobody-group,
|
||||
AC_HELP_STRING([--with-nobody-group=GROUP],
|
||||
[set the default unprivileged group (default nobody or nogroup)]),
|
||||
@@ -347,8 +331,7 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
|
||||
sys/un.h sys/attr.h mcheck.h arpa/inet.h arpa/nameser.h locale.h \
|
||||
netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h \
|
||||
sys/acl.h acl/libacl.h attr/xattr.h sys/xattr.h sys/extattr.h \
|
||||
popt.h popt/popt.h linux/falloc.h netinet/in_systm.h netinet/ip.h \
|
||||
zlib.h)
|
||||
popt.h popt/popt.h)
|
||||
AC_HEADER_MAJOR
|
||||
|
||||
AC_CACHE_CHECK([if makedev takes 3 args],rsync_cv_MAKEDEV_TAKES_3_ARGS,[
|
||||
@@ -396,18 +379,7 @@ AC_TYPE_SIGNAL
|
||||
AC_TYPE_UID_T
|
||||
AC_CHECK_TYPES([mode_t,off_t,size_t,pid_t,id_t])
|
||||
AC_TYPE_GETGROUPS
|
||||
AC_CHECK_MEMBERS([struct stat.st_rdev,
|
||||
struct stat.st_mtimensec,
|
||||
struct stat.st_mtim.tv_nsec],,,[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif])
|
||||
AC_CHECK_MEMBERS([struct stat.st_rdev])
|
||||
|
||||
TYPE_SOCKLEN_T
|
||||
|
||||
@@ -601,50 +573,14 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
|
||||
strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
|
||||
setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
|
||||
seteuid strerror putenv iconv_open locale_charset nl_langinfo getxattr \
|
||||
extattr_get_link sigaction sigprocmask setattrlist getgrouplist \
|
||||
initgroups utimensat posix_fallocate attropen setvbuf)
|
||||
extattr_get_link sigaction sigprocmask setattrlist \
|
||||
utimensat)
|
||||
|
||||
dnl cygwin iconv.h defines iconv_open as libiconv_open
|
||||
if test x"$ac_cv_func_iconv_open" != x"yes"; then
|
||||
AC_CHECK_FUNC(libiconv_open, [ac_cv_func_iconv_open=yes; AC_DEFINE(HAVE_ICONV_OPEN, 1)])
|
||||
fi
|
||||
|
||||
dnl Preallocation stuff (also fallocate, posix_fallocate function tests above):
|
||||
|
||||
AC_CACHE_CHECK([for useable fallocate],rsync_cv_have_fallocate,[
|
||||
AC_TRY_LINK([#include <fcntl.h>
|
||||
#include <sys/types.h>],
|
||||
[fallocate(0, 0, 0, 0);],
|
||||
rsync_cv_have_fallocate=yes,rsync_cv_have_fallocate=no)])
|
||||
if test x"$rsync_cv_have_fallocate" = x"yes"; then
|
||||
AC_DEFINE(HAVE_FALLOCATE, 1, [Define to 1 if you have the fallocate function and it compiles and links without error])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for SYS_fallocate],rsync_cv_have_sys_fallocate,[
|
||||
AC_TRY_COMPILE([#include <sys/syscall.h>
|
||||
#include <sys/types.h>],
|
||||
[syscall(SYS_fallocate, 0, 0, (loff_t)0, (loff_t)0);],
|
||||
rsync_cv_have_sys_fallocate=yes,rsync_cv_have_sys_fallocate=no)])
|
||||
if test x"$rsync_cv_have_sys_fallocate" = x"yes"; then
|
||||
AC_DEFINE(HAVE_SYS_FALLOCATE, 1, [Define to 1 if you have the SYS_fallocate syscall number])
|
||||
fi
|
||||
|
||||
if test x"$ac_cv_func_posix_fallocate" = x"yes"; then
|
||||
AC_MSG_CHECKING([whether posix_fallocate is efficient])
|
||||
case $host_os in
|
||||
*cygwin*)
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_EFFICIENT_POSIX_FALLOCATE, 1,
|
||||
[Define if posix_fallocate is efficient (Cygwin)])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
dnl End of preallocation stuff
|
||||
|
||||
AC_CHECK_FUNCS(getpgrp tcgetpgrp)
|
||||
if test $ac_cv_func_getpgrp = yes; then
|
||||
AC_FUNC_GETPGRP
|
||||
@@ -739,19 +675,13 @@ AC_TRY_RUN([
|
||||
|
||||
main() {
|
||||
int fd[2];
|
||||
#ifdef __CYGWIN__
|
||||
exit(1);
|
||||
#else
|
||||
exit((socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1);
|
||||
#endif
|
||||
}],
|
||||
rsync_cv_HAVE_SOCKETPAIR=yes,rsync_cv_HAVE_SOCKETPAIR=no,rsync_cv_HAVE_SOCKETPAIR=cross)])
|
||||
if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
|
||||
AC_DEFINE(HAVE_SOCKETPAIR, 1, [Define to 1 if you have the "socketpair" function])
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNCS(getpass, , [AC_LIBOBJ(lib/getpass)])
|
||||
|
||||
if test x"$with_included_popt" != x"yes"; then
|
||||
AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
|
||||
fi
|
||||
@@ -780,25 +710,6 @@ else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
# We default to using our zlib unless --with-included-zlib=no is given.
|
||||
if test x"$with_included_zlib" != x"no"; then
|
||||
with_included_zlib=yes
|
||||
elif test x"$ac_cv_header_zlib_h" != x"yes"; then
|
||||
with_included_zlib=yes
|
||||
fi
|
||||
if test x"$with_included_zlib" != x"yes"; then
|
||||
AC_CHECK_LIB(z, deflateParams, , [with_included_zlib=yes])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to use included zlib])
|
||||
if test x"$with_included_zlib" = x"yes"; then
|
||||
AC_MSG_RESULT($srcdir/zlib)
|
||||
BUILD_ZLIB='$(zlib_OBJS)'
|
||||
CFLAGS="$CFLAGS -I$srcdir/zlib"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for unsigned char],rsync_cv_SIGNED_CHAR_OK,[
|
||||
AC_TRY_COMPILE([],[signed char *s = ""],
|
||||
rsync_cv_SIGNED_CHAR_OK=yes,rsync_cv_SIGNED_CHAR_OK=no)])
|
||||
@@ -952,12 +863,8 @@ AC_SUBST(OBJ_SAVE)
|
||||
AC_SUBST(OBJ_RESTORE)
|
||||
AC_SUBST(CC_SHOBJ_FLAG)
|
||||
AC_SUBST(BUILD_POPT)
|
||||
AC_SUBST(BUILD_ZLIB)
|
||||
AC_SUBST(MAKE_MAN)
|
||||
|
||||
AC_PATH_PROG([STUNNEL], [stunnel], [stunnel], [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin])
|
||||
AC_PATH_PROG([STUNNEL4], [stunnel4], [$STUNNEL], [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin])
|
||||
|
||||
AC_CHECK_FUNCS(_acl __acl _facl __facl)
|
||||
#################################################
|
||||
# check for ACL support
|
||||
@@ -976,7 +883,7 @@ else
|
||||
AC_DEFINE(HAVE_UNIXWARE_ACLS, 1, [true if you have UnixWare ACLs])
|
||||
AC_DEFINE(SUPPORT_ACLS, 1, [Define to 1 to add support for ACLs])
|
||||
;;
|
||||
solaris*|*cygwin*)
|
||||
*solaris*|*cygwin*)
|
||||
AC_MSG_RESULT(Using solaris ACLs)
|
||||
AC_DEFINE(HAVE_SOLARIS_ACLS, 1, [true if you have solaris ACLs])
|
||||
AC_DEFINE(SUPPORT_ACLS, 1)
|
||||
@@ -1045,7 +952,7 @@ AC_MSG_CHECKING(whether to support extended attributes)
|
||||
AC_ARG_ENABLE(xattr-support,
|
||||
AC_HELP_STRING([--disable-xattr-support],
|
||||
[disable extended attributes]),
|
||||
[], [case "$ac_cv_func_getxattr$ac_cv_func_extattr_get_link$ac_cv_func_attropen" in
|
||||
[], [case "$ac_cv_func_getxattr$ac_cv_func_extattr_get_link" in
|
||||
*yes*) enable_xattr_support=maybe ;;
|
||||
*) enable_xattr_support=no ;;
|
||||
esac])
|
||||
@@ -1059,7 +966,7 @@ else
|
||||
AC_MSG_RESULT(Using Linux xattrs)
|
||||
AC_DEFINE(HAVE_LINUX_XATTRS, 1, [True if you have Linux xattrs])
|
||||
AC_DEFINE(SUPPORT_XATTRS, 1)
|
||||
AC_DEFINE(NO_SYMLINK_USER_XATTRS, 1, [True if symlinks do not support user xattrs])
|
||||
AC_DEFINE(NO_SYMLINK_XATTRS, 1, [True if symlinks do not support xattrs])
|
||||
;;
|
||||
darwin*)
|
||||
AC_MSG_RESULT(Using OS X xattrs)
|
||||
@@ -1073,12 +980,6 @@ else
|
||||
AC_DEFINE(HAVE_FREEBSD_XATTRS, 1, [True if you have FreeBSD xattrs])
|
||||
AC_DEFINE(SUPPORT_XATTRS, 1)
|
||||
;;
|
||||
solaris*)
|
||||
AC_MSG_RESULT(Using Solaris xattrs)
|
||||
AC_DEFINE(HAVE_SOLARIS_XATTRS, 1, [True if you have Solaris xattrs])
|
||||
AC_DEFINE(SUPPORT_XATTRS, 1)
|
||||
AC_DEFINE(NO_SYMLINK_XATTRS, 1, [True if symlinks do not support xattrs])
|
||||
;;
|
||||
*)
|
||||
if test x"$enable_xattr_support" = x"yes"; then
|
||||
AC_MSG_ERROR(Failed to find extended attribute support)
|
||||
|
||||
240
delete.c
240
delete.c
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Deletion routines used in rsync.
|
||||
*
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int am_root;
|
||||
extern int make_backups;
|
||||
extern int max_delete;
|
||||
extern char *backup_dir;
|
||||
extern char *backup_suffix;
|
||||
extern int backup_suffix_len;
|
||||
extern struct stats stats;
|
||||
|
||||
int ignore_perishable = 0;
|
||||
int non_perishable_cnt = 0;
|
||||
int skipped_deletes = 0;
|
||||
|
||||
static inline int is_backup_file(char *fn)
|
||||
{
|
||||
int k = strlen(fn) - backup_suffix_len;
|
||||
return k > 0 && strcmp(fn+k, backup_suffix) == 0;
|
||||
}
|
||||
|
||||
/* The directory is about to be deleted: if DEL_RECURSE is given, delete all
|
||||
* its contents, otherwise just checks for content. Returns DR_SUCCESS or
|
||||
* DR_NOT_EMPTY. Note that fname must point to a MAXPATHLEN buffer! (The
|
||||
* buffer is used for recursion, but returned unchanged.)
|
||||
*/
|
||||
static enum delret delete_dir_contents(char *fname, uint16 flags)
|
||||
{
|
||||
struct file_list *dirlist;
|
||||
enum delret ret;
|
||||
unsigned remainder;
|
||||
void *save_filters;
|
||||
int j, dlen;
|
||||
char *p;
|
||||
|
||||
if (DEBUG_GTE(DEL, 3)) {
|
||||
rprintf(FINFO, "delete_dir_contents(%s) flags=%d\n",
|
||||
fname, flags);
|
||||
}
|
||||
|
||||
dlen = strlen(fname);
|
||||
save_filters = push_local_filters(fname, dlen);
|
||||
|
||||
non_perishable_cnt = 0;
|
||||
dirlist = get_dirlist(fname, dlen, 0);
|
||||
ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS;
|
||||
|
||||
if (!dirlist->used)
|
||||
goto done;
|
||||
|
||||
if (!(flags & DEL_RECURSE)) {
|
||||
ret = DR_NOT_EMPTY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p = fname + dlen;
|
||||
if (dlen != 1 || *fname != '/')
|
||||
*p++ = '/';
|
||||
remainder = MAXPATHLEN - (p - fname);
|
||||
|
||||
/* We do our own recursion, so make delete_item() non-recursive. */
|
||||
flags = (flags & ~(DEL_RECURSE|DEL_MAKE_ROOM|DEL_NO_UID_WRITE))
|
||||
| DEL_DIR_IS_EMPTY;
|
||||
|
||||
for (j = dirlist->used; j--; ) {
|
||||
struct file_struct *fp = dirlist->files[j];
|
||||
|
||||
if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) {
|
||||
if (DEBUG_GTE(DEL, 1)) {
|
||||
rprintf(FINFO,
|
||||
"mount point, %s, pins parent directory\n",
|
||||
f_name(fp, NULL));
|
||||
}
|
||||
ret = DR_NOT_EMPTY;
|
||||
continue;
|
||||
}
|
||||
|
||||
strlcpy(p, fp->basename, remainder);
|
||||
if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
|
||||
do_chmod(fname, fp->mode | S_IWUSR);
|
||||
/* Save stack by recursing to ourself directly. */
|
||||
if (S_ISDIR(fp->mode)) {
|
||||
if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS)
|
||||
ret = DR_NOT_EMPTY;
|
||||
}
|
||||
if (delete_item(fname, fp->mode, flags) != DR_SUCCESS)
|
||||
ret = DR_NOT_EMPTY;
|
||||
}
|
||||
|
||||
fname[dlen] = '\0';
|
||||
|
||||
done:
|
||||
flist_free(dirlist);
|
||||
pop_local_filters(save_filters);
|
||||
|
||||
if (ret == DR_NOT_EMPTY) {
|
||||
rprintf(FINFO, "cannot delete non-empty directory: %s\n",
|
||||
fname);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Delete a file or directory. If DEL_RECURSE is set in the flags, this will
|
||||
* delete recursively.
|
||||
*
|
||||
* Note that fbuf must point to a MAXPATHLEN buffer if the mode indicates it's
|
||||
* a directory! (The buffer is used for recursion, but returned unchanged.)
|
||||
*/
|
||||
enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
|
||||
{
|
||||
enum delret ret;
|
||||
char *what;
|
||||
int ok;
|
||||
|
||||
if (DEBUG_GTE(DEL, 2)) {
|
||||
rprintf(FINFO, "delete_item(%s) mode=%o flags=%d\n",
|
||||
fbuf, (int)mode, (int)flags);
|
||||
}
|
||||
|
||||
if (flags & DEL_NO_UID_WRITE)
|
||||
do_chmod(fbuf, mode | S_IWUSR);
|
||||
|
||||
if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
|
||||
/* This only happens on the first call to delete_item() since
|
||||
* delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */
|
||||
ignore_perishable = 1;
|
||||
/* If DEL_RECURSE is not set, this just reports emptiness. */
|
||||
ret = delete_dir_contents(fbuf, flags);
|
||||
ignore_perishable = 0;
|
||||
if (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT)
|
||||
goto check_ret;
|
||||
/* OK: try to delete the directory. */
|
||||
}
|
||||
|
||||
if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && stats.deleted_files >= max_delete) {
|
||||
skipped_deletes++;
|
||||
return DR_AT_LIMIT;
|
||||
}
|
||||
|
||||
if (S_ISDIR(mode)) {
|
||||
what = "rmdir";
|
||||
ok = do_rmdir(fbuf) == 0;
|
||||
} else {
|
||||
if (make_backups > 0 && !(flags & DEL_FOR_BACKUP) && (backup_dir || !is_backup_file(fbuf))) {
|
||||
what = "make_backup";
|
||||
ok = make_backup(fbuf, True);
|
||||
if (ok == 2) {
|
||||
what = "unlink";
|
||||
ok = robust_unlink(fbuf) == 0;
|
||||
}
|
||||
} else {
|
||||
what = "unlink";
|
||||
ok = robust_unlink(fbuf) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (!(flags & DEL_MAKE_ROOM)) {
|
||||
log_delete(fbuf, mode);
|
||||
stats.deleted_files++;
|
||||
if (S_ISREG(mode)) {
|
||||
/* Nothing more to count */
|
||||
} else if (S_ISDIR(mode))
|
||||
stats.deleted_dirs++;
|
||||
#ifdef SUPPORT_LINKS
|
||||
else if (S_ISLNK(mode))
|
||||
stats.deleted_symlinks++;
|
||||
#endif
|
||||
else if (IS_DEVICE(mode))
|
||||
stats.deleted_symlinks++;
|
||||
else
|
||||
stats.deleted_specials++;
|
||||
}
|
||||
ret = DR_SUCCESS;
|
||||
} else {
|
||||
if (S_ISDIR(mode) && errno == ENOTEMPTY) {
|
||||
rprintf(FINFO, "cannot delete non-empty directory: %s\n",
|
||||
fbuf);
|
||||
ret = DR_NOT_EMPTY;
|
||||
} else if (errno != ENOENT) {
|
||||
rsyserr(FERROR, errno, "delete_file: %s(%s) failed",
|
||||
what, fbuf);
|
||||
ret = DR_FAILURE;
|
||||
} else
|
||||
ret = DR_SUCCESS;
|
||||
}
|
||||
|
||||
check_ret:
|
||||
if (ret != DR_SUCCESS && flags & DEL_MAKE_ROOM) {
|
||||
const char *desc;
|
||||
switch (flags & DEL_MAKE_ROOM) {
|
||||
case DEL_FOR_FILE: desc = "regular file"; break;
|
||||
case DEL_FOR_DIR: desc = "directory"; break;
|
||||
case DEL_FOR_SYMLINK: desc = "symlink"; break;
|
||||
case DEL_FOR_DEVICE: desc = "device file"; break;
|
||||
case DEL_FOR_SPECIAL: desc = "special file"; break;
|
||||
default: exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */
|
||||
}
|
||||
rprintf(FERROR_XFER, "could not make way for %s %s: %s\n",
|
||||
flags & DEL_FOR_BACKUP ? "backup" : "new",
|
||||
desc, fbuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16 get_del_for_flag(uint16 mode)
|
||||
{
|
||||
if (S_ISREG(mode))
|
||||
return DEL_FOR_FILE;
|
||||
if (S_ISDIR(mode))
|
||||
return DEL_FOR_DIR;
|
||||
if (S_ISLNK(mode))
|
||||
return DEL_FOR_SYMLINK;
|
||||
if (IS_DEVICE(mode))
|
||||
return DEL_FOR_DEVICE;
|
||||
if (IS_SPECIAL(mode))
|
||||
return DEL_FOR_SPECIAL;
|
||||
exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* Error codes returned by rsync.
|
||||
*
|
||||
* Copyright (C) 1998-2000 Andrew Tridgell
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2008 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
46
fileio.c
46
fileio.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2004-2013 Wayne Davison
|
||||
* Copyright (C) 2004-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,19 +20,11 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
|
||||
#ifndef ENODATA
|
||||
#define ENODATA EAGAIN
|
||||
#endif
|
||||
|
||||
/* We want all reads to be aligned on 1K boundries. */
|
||||
#define ALIGN_BOUNDRY 1024
|
||||
/* How far past the boundary is an offset? */
|
||||
#define ALIGNED_OVERSHOOT(oft) ((oft) & (ALIGN_BOUNDRY-1))
|
||||
/* Round up a length to the next boundary */
|
||||
#define ALIGNED_LENGTH(len) ((((len) - 1) | (ALIGN_BOUNDRY-1)) + 1)
|
||||
|
||||
extern int sparse_files;
|
||||
|
||||
static OFF_T sparse_seek = 0;
|
||||
@@ -84,14 +76,11 @@ static int write_sparse(int f, char *buf, int len)
|
||||
while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) {
|
||||
if (ret < 0 && errno == EINTR)
|
||||
continue;
|
||||
sparse_seek = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret != (int)(len - (l1+l2))) {
|
||||
sparse_seek = 0;
|
||||
if (ret != (int)(len - (l1+l2)))
|
||||
return l1+ret;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
@@ -169,7 +158,8 @@ int write_file(int f, char *buf, int len)
|
||||
* It gives sliding window access to a file. mmap() is not used because of
|
||||
* the possibility of another program (such as a mailer) truncating the
|
||||
* file thus giving us a SIGBUS. */
|
||||
struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
|
||||
struct map_struct *map_file(int fd, OFF_T len, int32 read_size,
|
||||
int32 blk_size)
|
||||
{
|
||||
struct map_struct *map;
|
||||
|
||||
@@ -181,7 +171,7 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
|
||||
|
||||
map->fd = fd;
|
||||
map->file_size = len;
|
||||
map->def_window_size = ALIGNED_LENGTH(read_size);
|
||||
map->def_window_size = read_size;
|
||||
|
||||
return map;
|
||||
}
|
||||
@@ -190,8 +180,9 @@ struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
|
||||
/* slide the read window in the file */
|
||||
char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
{
|
||||
int32 nread;
|
||||
OFF_T window_start, read_start;
|
||||
int32 window_size, read_size, read_offset, align_fudge;
|
||||
int32 window_size, read_size, read_offset;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
@@ -206,13 +197,12 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
return map->p + (offset - map->p_offset);
|
||||
|
||||
/* nope, we are going to have to do a read. Work out our desired window */
|
||||
align_fudge = (int32)ALIGNED_OVERSHOOT(offset);
|
||||
window_start = offset - align_fudge;
|
||||
window_start = offset;
|
||||
window_size = map->def_window_size;
|
||||
if (window_start + window_size > map->file_size)
|
||||
window_size = (int32)(map->file_size - window_start);
|
||||
if (window_size < len + align_fudge)
|
||||
window_size = ALIGNED_LENGTH(len + align_fudge);
|
||||
if (len > window_size)
|
||||
window_size = len;
|
||||
|
||||
/* make sure we have allocated enough memory for the window */
|
||||
if (window_size > map->p_size) {
|
||||
@@ -222,9 +212,11 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
map->p_size = window_size;
|
||||
}
|
||||
|
||||
/* Now try to avoid re-reading any bytes by reusing any bytes from the previous buffer. */
|
||||
if (window_start >= map->p_offset && window_start < map->p_offset + map->p_len
|
||||
&& window_start + window_size >= map->p_offset + map->p_len) {
|
||||
/* Now try to avoid re-reading any bytes by reusing any bytes
|
||||
* from the previous buffer. */
|
||||
if (window_start >= map->p_offset &&
|
||||
window_start < map->p_offset + map->p_len &&
|
||||
window_start + window_size >= map->p_offset + map->p_len) {
|
||||
read_start = map->p_offset + map->p_len;
|
||||
read_offset = (int32)(read_start - window_start);
|
||||
read_size = window_size - read_offset;
|
||||
@@ -244,8 +236,8 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
if (map->p_fd_offset != read_start) {
|
||||
OFF_T ret = do_lseek(map->fd, read_start, SEEK_SET);
|
||||
if (ret != read_start) {
|
||||
rsyserr(FERROR, errno, "lseek returned %s, not %s",
|
||||
big_num(ret), big_num(read_start));
|
||||
rsyserr(FERROR, errno, "lseek returned %.0f, not %.0f",
|
||||
(double)ret, (double)read_start);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
map->p_fd_offset = read_start;
|
||||
@@ -254,7 +246,7 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
map->p_len = window_size;
|
||||
|
||||
while (read_size > 0) {
|
||||
int32 nread = read(map->fd, map->p + read_offset, read_size);
|
||||
nread = read(map->fd, map->p + read_offset, read_size);
|
||||
if (nread <= 0) {
|
||||
if (!map->status)
|
||||
map->status = nread ? errno : ENODATA;
|
||||
@@ -268,7 +260,7 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
read_size -= nread;
|
||||
}
|
||||
|
||||
return map->p + align_fudge;
|
||||
return map->p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
375
flist.c
375
flist.c
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2002-2013 Wayne Davison
|
||||
* Copyright (C) 2002-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,15 +23,16 @@
|
||||
#include "rsync.h"
|
||||
#include "ifuncs.h"
|
||||
#include "rounding.h"
|
||||
#include "inums.h"
|
||||
#include "io.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int am_root;
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int am_sender;
|
||||
extern int am_generator;
|
||||
extern int inc_recurse;
|
||||
extern int do_progress;
|
||||
extern int always_checksum;
|
||||
extern int module_id;
|
||||
extern int ignore_errors;
|
||||
@@ -51,7 +52,6 @@ extern int preserve_hard_links;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_specials;
|
||||
extern int delete_during;
|
||||
extern int missing_args;
|
||||
extern int eol_nulls;
|
||||
extern int relative_paths;
|
||||
extern int implied_dirs;
|
||||
@@ -66,20 +66,17 @@ extern int munge_symlinks;
|
||||
extern int use_safe_inc_flist;
|
||||
extern int need_unsorted_flist;
|
||||
extern int sender_symlink_iconv;
|
||||
extern int output_needs_newline;
|
||||
extern int sender_keeps_checksum;
|
||||
extern int unsort_ndx;
|
||||
extern uid_t our_uid;
|
||||
extern struct stats stats;
|
||||
extern char *filesfrom_host;
|
||||
extern char *usermap, *groupmap;
|
||||
|
||||
extern char curr_dir[MAXPATHLEN];
|
||||
|
||||
extern struct chmod_mode_struct *chmod_modes;
|
||||
|
||||
extern filter_rule_list filter_list;
|
||||
extern filter_rule_list daemon_filter_list;
|
||||
extern struct filter_list_struct filter_list;
|
||||
extern struct filter_list_struct daemon_filter_list;
|
||||
|
||||
#ifdef ICONV_OPTION
|
||||
extern int filesfrom_convert;
|
||||
@@ -96,13 +93,11 @@ struct file_list *cur_flist, *first_flist, *dir_flist;
|
||||
int send_dir_ndx = -1, send_dir_depth = -1;
|
||||
int flist_cnt = 0; /* how many (non-tmp) file list objects exist */
|
||||
int file_total = 0; /* total of all active items over all file-lists */
|
||||
int file_old_total = 0; /* total of active items that will soon be gone */
|
||||
int flist_eof = 0; /* all the file-lists are now known */
|
||||
|
||||
#define NORMAL_NAME 0
|
||||
#define SLASH_ENDING_NAME 1
|
||||
#define DOTDIR_NAME 2
|
||||
#define MISSING_NAME 3
|
||||
|
||||
/* Starting from protocol version 26, we always use 64-bit ino_t and dev_t
|
||||
* internally, even if this platform does not allow files to have 64-bit inums.
|
||||
@@ -127,13 +122,14 @@ static char tmp_sum[MAX_DIGEST_LEN];
|
||||
|
||||
static char empty_sum[MAX_DIGEST_LEN];
|
||||
static int flist_count_offset; /* for --delete --progress */
|
||||
static int dir_count = 0;
|
||||
|
||||
static void flist_sort_and_clean(struct file_list *flist, int strip_root);
|
||||
static void output_flist(struct file_list *flist);
|
||||
|
||||
void init_flist(void)
|
||||
{
|
||||
if (DEBUG_GTE(FLIST, 4)) {
|
||||
if (verbose > 4) {
|
||||
rprintf(FINFO, "FILE_STRUCT_LEN=%d, EXTRA_LEN=%d\n",
|
||||
(int)FILE_STRUCT_LEN, (int)EXTRA_LEN);
|
||||
}
|
||||
@@ -144,13 +140,14 @@ void init_flist(void)
|
||||
|
||||
static int show_filelist_p(void)
|
||||
{
|
||||
return INFO_GTE(FLIST, 1) && xfer_dirs && !am_server && !inc_recurse;
|
||||
return verbose && xfer_dirs && !am_server && !inc_recurse;
|
||||
}
|
||||
|
||||
static void start_filelist_progress(char *kind)
|
||||
{
|
||||
rprintf(FCLIENT, "%s ... ", kind);
|
||||
output_needs_newline = 1;
|
||||
if (verbose > 1 || do_progress)
|
||||
rprintf(FCLIENT, "\n");
|
||||
rflush(FINFO);
|
||||
}
|
||||
|
||||
@@ -161,20 +158,18 @@ static void emit_filelist_progress(int count)
|
||||
|
||||
static void maybe_emit_filelist_progress(int count)
|
||||
{
|
||||
if (INFO_GTE(FLIST, 2) && show_filelist_p() && (count % 100) == 0)
|
||||
if (do_progress && show_filelist_p() && (count % 100) == 0)
|
||||
emit_filelist_progress(count);
|
||||
}
|
||||
|
||||
static void finish_filelist_progress(const struct file_list *flist)
|
||||
{
|
||||
if (INFO_GTE(FLIST, 2)) {
|
||||
if (do_progress) {
|
||||
/* This overwrites the progress line */
|
||||
rprintf(FINFO, "%d file%sto consider\n",
|
||||
flist->used, flist->used == 1 ? " " : "s ");
|
||||
} else {
|
||||
output_needs_newline = 0;
|
||||
} else
|
||||
rprintf(FINFO, "done\n");
|
||||
}
|
||||
}
|
||||
|
||||
void show_flist_stats(void)
|
||||
@@ -196,12 +191,12 @@ static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf)
|
||||
if (link_stat(path, stp, copy_dirlinks) < 0)
|
||||
return -1;
|
||||
if (S_ISLNK(stp->st_mode)) {
|
||||
int llen = do_readlink(path, linkbuf, MAXPATHLEN - 1);
|
||||
int llen = readlink(path, linkbuf, MAXPATHLEN - 1);
|
||||
if (llen < 0)
|
||||
return -1;
|
||||
linkbuf[llen] = '\0';
|
||||
if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) {
|
||||
if (INFO_GTE(SYMSAFE, 1)) {
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
|
||||
path, linkbuf);
|
||||
}
|
||||
@@ -321,10 +316,10 @@ static void flist_expand(struct file_list *flist, int extra)
|
||||
new_ptr = realloc_array(flist->files, struct file_struct *,
|
||||
flist->malloced);
|
||||
|
||||
if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
|
||||
rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
|
||||
if (verbose >= 2 && flist->malloced != FLIST_START) {
|
||||
rprintf(FCLIENT, "[%s] expand file_list pointer array to %.0f bytes, did%s move\n",
|
||||
who_am_i(),
|
||||
big_num(sizeof flist->files[0] * flist->malloced),
|
||||
(double)sizeof flist->files[0] * flist->malloced,
|
||||
(new_ptr == flist->files) ? " not" : "");
|
||||
}
|
||||
|
||||
@@ -408,35 +403,21 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
static gid_t gid;
|
||||
static const char *user_name, *group_name;
|
||||
static char lastname[MAXPATHLEN];
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
int first_hlink_ndx = -1;
|
||||
#endif
|
||||
int l1, l2;
|
||||
int xflags;
|
||||
|
||||
/* Initialize starting value of xflags and adjust counts. */
|
||||
if (S_ISREG(file->mode))
|
||||
xflags = 0;
|
||||
else if (S_ISDIR(file->mode)) {
|
||||
stats.num_dirs++;
|
||||
if (protocol_version >= 30) {
|
||||
if (file->flags & FLAG_CONTENT_DIR)
|
||||
xflags = file->flags & FLAG_TOP_DIR;
|
||||
else if (file->flags & FLAG_IMPLIED_DIR)
|
||||
xflags = XMIT_TOP_DIR | XMIT_NO_CONTENT_DIR;
|
||||
else
|
||||
xflags = XMIT_NO_CONTENT_DIR;
|
||||
} else
|
||||
xflags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
|
||||
} else {
|
||||
if (S_ISLNK(file->mode))
|
||||
stats.num_symlinks++;
|
||||
else if (IS_DEVICE(file->mode))
|
||||
stats.num_devices++;
|
||||
else if (IS_SPECIAL(file->mode))
|
||||
stats.num_specials++;
|
||||
xflags = 0;
|
||||
}
|
||||
/* Initialize starting value of xflags. */
|
||||
if (protocol_version >= 30 && S_ISDIR(file->mode)) {
|
||||
dir_count++;
|
||||
if (file->flags & FLAG_CONTENT_DIR)
|
||||
xflags = file->flags & FLAG_TOP_DIR;
|
||||
else if (file->flags & FLAG_IMPLIED_DIR)
|
||||
xflags = XMIT_TOP_DIR | XMIT_NO_CONTENT_DIR;
|
||||
else
|
||||
xflags = XMIT_NO_CONTENT_DIR;
|
||||
} else
|
||||
xflags = file->flags & FLAG_TOP_DIR; /* FLAG_TOP_DIR == XMIT_TOP_DIR */
|
||||
|
||||
if (file->mode == mode)
|
||||
xflags |= XMIT_SAME_MODE;
|
||||
@@ -458,7 +439,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
if (protocol_version < 30 && (uint32)minor(rdev) <= 0xFFu)
|
||||
xflags |= XMIT_RDEV_MINOR_8_pre30;
|
||||
}
|
||||
} else if (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31) {
|
||||
} else if (preserve_specials && IS_SPECIAL(mode)) {
|
||||
/* Special files don't need an rdev number, so just make
|
||||
* the historical transmission of the value efficient. */
|
||||
if (protocol_version < 28)
|
||||
@@ -495,8 +476,6 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
xflags |= XMIT_SAME_TIME;
|
||||
else
|
||||
modtime = file->modtime;
|
||||
if (NSEC_BUMP(file) && protocol_version >= 31)
|
||||
xflags |= XMIT_MOD_NSEC;
|
||||
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
if (tmp_dev != -1) {
|
||||
@@ -507,17 +486,6 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
np->data = (void*)(long)(first_ndx + ndx + 1);
|
||||
xflags |= XMIT_HLINK_FIRST;
|
||||
}
|
||||
if (DEBUG_GTE(HLINK, 1)) {
|
||||
if (first_hlink_ndx >= 0) {
|
||||
rprintf(FINFO, "[%s] #%d hard-links #%d (%sabbrev)\n",
|
||||
who_am_i(), first_ndx + ndx, first_hlink_ndx,
|
||||
first_hlink_ndx >= first_ndx ? "" : "un");
|
||||
} else if (DEBUG_GTE(HLINK, 3)) {
|
||||
rprintf(FINFO, "[%s] dev:inode for #%d is %s:%s\n",
|
||||
who_am_i(), first_ndx + ndx,
|
||||
big_num(tmp_dev), big_num(tmp_ino));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tmp_dev == dev) {
|
||||
if (protocol_version >= 28)
|
||||
@@ -564,13 +532,11 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
write_byte(f, l2);
|
||||
write_buf(f, fname + l1, l2);
|
||||
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
if (first_hlink_ndx >= 0) {
|
||||
write_varint(f, first_hlink_ndx);
|
||||
if (first_hlink_ndx >= first_ndx)
|
||||
goto the_end;
|
||||
}
|
||||
#endif
|
||||
|
||||
write_varlong30(f, F_LENGTH(file), 3);
|
||||
if (!(xflags & XMIT_SAME_TIME)) {
|
||||
@@ -579,8 +545,6 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
else
|
||||
write_int(f, modtime);
|
||||
}
|
||||
if (xflags & XMIT_MOD_NSEC)
|
||||
write_varint(f, F_MOD_NSEC(file));
|
||||
if (!(xflags & XMIT_SAME_MODE))
|
||||
write_int(f, to_wire_mode(mode));
|
||||
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
|
||||
@@ -608,7 +572,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
}
|
||||
}
|
||||
if ((preserve_devices && IS_DEVICE(mode))
|
||||
|| (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31)) {
|
||||
|| (preserve_specials && IS_SPECIAL(mode))) {
|
||||
if (protocol_version < 28) {
|
||||
if (!(xflags & XMIT_SAME_RDEV_pre28))
|
||||
write_int(f, (int)rdev);
|
||||
@@ -659,9 +623,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
|
||||
write_buf(f, sum, checksum_len);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
the_end:
|
||||
#endif
|
||||
strlcpy(lastname, fname, MAXPATHLEN);
|
||||
|
||||
if (S_ISREG(mode) || S_ISLNK(mode))
|
||||
@@ -690,7 +652,6 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
int extra_len = file_extra_cnt * EXTRA_LEN;
|
||||
int first_hlink_ndx = -1;
|
||||
int64 file_length;
|
||||
uint32 modtime_nsec;
|
||||
const char *basename;
|
||||
struct file_struct *file;
|
||||
alloc_pool_t *pool;
|
||||
@@ -723,9 +684,9 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
xbuf outbuf, inbuf;
|
||||
|
||||
INIT_CONST_XBUF(outbuf, thisname);
|
||||
INIT_XBUF(inbuf, lastname, basename_len, (size_t)-1);
|
||||
INIT_XBUF(inbuf, lastname, basename_len, -1);
|
||||
|
||||
if (iconvbufs(ic_recv, &inbuf, &outbuf, ICB_INIT) < 0) {
|
||||
if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
rprintf(FERROR_UTF8,
|
||||
"[%s] cannot convert filename: %s (%s)\n",
|
||||
@@ -765,16 +726,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
first_hlink_ndx, flist->ndx_start + flist->used);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if (DEBUG_GTE(HLINK, 1)) {
|
||||
rprintf(FINFO, "[%s] #%d hard-links #%d (%sabbrev)\n",
|
||||
who_am_i(), flist->used+flist->ndx_start, first_hlink_ndx,
|
||||
first_hlink_ndx >= flist->ndx_start ? "" : "un");
|
||||
}
|
||||
if (first_hlink_ndx >= flist->ndx_start) {
|
||||
struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];
|
||||
file_length = F_LENGTH(first);
|
||||
modtime = first->modtime;
|
||||
modtime_nsec = F_MOD_NSEC(first);
|
||||
mode = first->mode;
|
||||
if (preserve_uid)
|
||||
uid = F_OWNER(first);
|
||||
@@ -808,14 +763,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
} else
|
||||
modtime = read_int(f);
|
||||
}
|
||||
if (xflags & XMIT_MOD_NSEC)
|
||||
modtime_nsec = read_varint(f);
|
||||
else
|
||||
modtime_nsec = 0;
|
||||
if (!(xflags & XMIT_SAME_MODE))
|
||||
mode = from_wire_mode(read_int(f));
|
||||
|
||||
if (chmod_modes && !S_ISLNK(mode) && mode)
|
||||
if (chmod_modes && !S_ISLNK(mode))
|
||||
mode = tweak_mode(mode, chmod_modes);
|
||||
|
||||
if (preserve_uid && !(xflags & XMIT_SAME_UID)) {
|
||||
@@ -825,7 +776,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
uid = (uid_t)read_varint(f);
|
||||
if (xflags & XMIT_USER_NAME_FOLLOWS)
|
||||
uid = recv_user_name(f, uid);
|
||||
else if (inc_recurse && am_root && (!numeric_ids || usermap))
|
||||
else if (inc_recurse && am_root && !numeric_ids)
|
||||
uid = match_uid(uid);
|
||||
}
|
||||
}
|
||||
@@ -837,13 +788,13 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
gid_flags = 0;
|
||||
if (xflags & XMIT_GROUP_NAME_FOLLOWS)
|
||||
gid = recv_group_name(f, gid, &gid_flags);
|
||||
else if (inc_recurse && (!am_root || !numeric_ids || groupmap))
|
||||
else if (inc_recurse && (!am_root || !numeric_ids))
|
||||
gid = match_gid(gid, &gid_flags);
|
||||
}
|
||||
}
|
||||
|
||||
if ((preserve_devices && IS_DEVICE(mode))
|
||||
|| (preserve_specials && IS_SPECIAL(mode) && protocol_version < 31)) {
|
||||
|| (preserve_specials && IS_SPECIAL(mode))) {
|
||||
if (protocol_version < 28) {
|
||||
if (!(xflags & XMIT_SAME_RDEV_pre28))
|
||||
rdev = (dev_t)read_int(f);
|
||||
@@ -909,10 +860,6 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
#if SIZEOF_INT64 >= 8
|
||||
if (file_length > 0xFFFFFFFFu && S_ISREG(mode))
|
||||
extra_len += EXTRA_LEN;
|
||||
#endif
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
if (modtime_nsec)
|
||||
extra_len += EXTRA_LEN;
|
||||
#endif
|
||||
if (file_length < 0) {
|
||||
rprintf(FERROR, "Offset underflow: file-length is negative\n");
|
||||
@@ -949,12 +896,6 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
file->flags |= FLAG_HLINKED;
|
||||
#endif
|
||||
file->modtime = (time_t)modtime;
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
if (modtime_nsec) {
|
||||
file->flags |= FLAG_MOD_NSEC;
|
||||
OPT_EXTRA(file, 0)->unum = modtime_nsec;
|
||||
}
|
||||
#endif
|
||||
file->len32 = (uint32)file_length;
|
||||
#if SIZEOF_INT64 >= 8
|
||||
if (file_length > 0xFFFFFFFFu && S_ISREG(mode)) {
|
||||
@@ -963,7 +904,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
#else
|
||||
file->flags |= FLAG_LENGTH64;
|
||||
OPT_EXTRA(file, NSEC_BUMP(file))->unum = (uint32)(file_length >> 32);
|
||||
OPT_EXTRA(file, 0)->unum = (uint32)(file_length >> 32);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -1043,7 +984,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
|
||||
read_sbuf(f, inbuf.buf, inbuf.len);
|
||||
INIT_XBUF(outbuf, bp, 0, alloc_len);
|
||||
|
||||
if (iconvbufs(ic_recv, &inbuf, &outbuf, ICB_INIT) < 0) {
|
||||
if (iconvbufs(ic_recv, &inbuf, &outbuf, 0) < 0) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
rprintf(FERROR_XFER,
|
||||
"[%s] cannot convert symlink data for: %s (%s)\n",
|
||||
@@ -1156,10 +1097,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
if (sanitize_paths)
|
||||
sanitize_path(thisname, thisname, "", 0, SP_DEFAULT);
|
||||
|
||||
if (stp && (S_ISDIR(stp->st_mode) || stp->st_mode == 0)) {
|
||||
/* This is needed to handle a "symlink/." with a --relative
|
||||
* dir, or a request to delete a specific file. */
|
||||
st = *stp;
|
||||
if (stp && S_ISDIR(stp->st_mode)) {
|
||||
st = *stp; /* Needed for "symlink/." with --relative. */
|
||||
*linkname = '\0'; /* make IBM code checker happy */
|
||||
} else if (readlink_stat(thisname, &st, linkname) != 0) {
|
||||
int save_errno = errno;
|
||||
@@ -1200,11 +1139,6 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
full_fname(thisname));
|
||||
}
|
||||
return NULL;
|
||||
} else if (st.st_mode == 0) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
rprintf(FINFO, "skipping file with bogus (zero) st_mode: %s\n",
|
||||
full_fname(thisname));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (filter_level == NO_FILTERS)
|
||||
@@ -1221,7 +1155,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
if (one_file_system && st.st_dev != filesystem_dev
|
||||
&& BITS_SETnUNSET(flags, FLAG_CONTENT_DIR, FLAG_TOP_DIR)) {
|
||||
if (one_file_system > 1) {
|
||||
if (INFO_GTE(MOUNT, 1)) {
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO,
|
||||
"[%s] skipping mount-point dir %s\n",
|
||||
who_am_i(), thisname);
|
||||
@@ -1270,7 +1204,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
pool = NULL;
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(FLIST, 2)) {
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "[%s] make_file(%s,*,%d)\n",
|
||||
who_am_i(), thisname, filter_level);
|
||||
}
|
||||
@@ -1293,21 +1227,11 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
linkname_len = 0;
|
||||
#endif
|
||||
|
||||
#ifdef ST_MTIME_NSEC
|
||||
if (st.ST_MTIME_NSEC && protocol_version >= 31)
|
||||
extra_len += EXTRA_LEN;
|
||||
#endif
|
||||
#if SIZEOF_CAPITAL_OFF_T >= 8
|
||||
if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode))
|
||||
extra_len += EXTRA_LEN;
|
||||
#endif
|
||||
|
||||
if (always_checksum && am_sender && S_ISREG(st.st_mode)) {
|
||||
file_checksum(thisname, tmp_sum, st.st_size);
|
||||
if (sender_keeps_checksum)
|
||||
extra_len += SUM_EXTRA_CNT * EXTRA_LEN;
|
||||
}
|
||||
|
||||
#if EXTRA_ROUNDING > 0
|
||||
if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
|
||||
extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;
|
||||
@@ -1351,17 +1275,11 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
|
||||
file->flags = flags;
|
||||
file->modtime = st.st_mtime;
|
||||
#ifdef ST_MTIME_NSEC
|
||||
if (st.ST_MTIME_NSEC && protocol_version >= 31) {
|
||||
file->flags |= FLAG_MOD_NSEC;
|
||||
OPT_EXTRA(file, 0)->unum = st.ST_MTIME_NSEC;
|
||||
}
|
||||
#endif
|
||||
file->len32 = (uint32)st.st_size;
|
||||
#if SIZEOF_CAPITAL_OFF_T >= 8
|
||||
if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode)) {
|
||||
file->flags |= FLAG_LENGTH64;
|
||||
OPT_EXTRA(file, NSEC_BUMP(file))->unum = (uint32)(st.st_size >> 32);
|
||||
OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32);
|
||||
}
|
||||
#endif
|
||||
file->mode = st.st_mode;
|
||||
@@ -1380,6 +1298,9 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
memcpy(bp + basename_len, linkname, linkname_len);
|
||||
#endif
|
||||
|
||||
if (always_checksum && am_sender && S_ISREG(st.st_mode))
|
||||
file_checksum(thisname, tmp_sum, st.st_size);
|
||||
|
||||
if (am_sender)
|
||||
F_PATHNAME(file) = pathname;
|
||||
else if (!pool)
|
||||
@@ -1391,11 +1312,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sender_keeps_checksum && S_ISREG(st.st_mode))
|
||||
memcpy(F_SUM(file), tmp_sum, checksum_len);
|
||||
|
||||
if (unsort_ndx)
|
||||
F_NDX(file) = stats.num_dirs;
|
||||
F_NDX(file) = dir_count;
|
||||
|
||||
return file;
|
||||
}
|
||||
@@ -1416,7 +1334,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
if (chmod_modes && !S_ISLNK(file->mode) && file->mode)
|
||||
if (chmod_modes && !S_ISLNK(file->mode))
|
||||
file->mode = tweak_mode(file->mode, chmod_modes);
|
||||
|
||||
if (f >= 0) {
|
||||
@@ -1430,7 +1348,6 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
|
||||
#endif
|
||||
#if defined SUPPORT_ACLS || defined SUPPORT_XATTRS
|
||||
stat_x sx;
|
||||
init_stat_x(&sx);
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
@@ -1460,14 +1377,14 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
|
||||
if (file->dirname) {
|
||||
INIT_XBUF_STRLEN(inbuf, (char*)file->dirname);
|
||||
outbuf.size -= 2; /* Reserve room for '/' & 1 more char. */
|
||||
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0)
|
||||
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0)
|
||||
goto convert_error;
|
||||
outbuf.size += 2;
|
||||
fbuf[outbuf.len++] = '/';
|
||||
}
|
||||
|
||||
INIT_XBUF_STRLEN(inbuf, (char*)file->basename);
|
||||
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) {
|
||||
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {
|
||||
convert_error:
|
||||
io_error |= IOERR_GENERAL;
|
||||
rprintf(FERROR_XFER,
|
||||
@@ -1481,7 +1398,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
|
||||
if (symlink_len && sender_symlink_iconv) {
|
||||
INIT_XBUF(inbuf, (char*)symlink_name, symlink_len, (size_t)-1);
|
||||
INIT_CONST_XBUF(outbuf, symlink_buf);
|
||||
if (iconvbufs(ic_send, &inbuf, &outbuf, ICB_INIT) < 0) {
|
||||
if (iconvbufs(ic_send, &inbuf, &outbuf, 0) < 0) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
f_name(file, fbuf);
|
||||
rprintf(FERROR_XFER,
|
||||
@@ -1502,6 +1419,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
sx.st.st_mode = file->mode;
|
||||
sx.acc_acl = sx.def_acl = NULL;
|
||||
if (get_acl(fname, &sx) < 0) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
return NULL;
|
||||
@@ -1511,6 +1429,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist,
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
sx.st.st_mode = file->mode;
|
||||
sx.xattr = NULL;
|
||||
if (get_xattr(fname, &sx) < 0) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
return NULL;
|
||||
@@ -1727,12 +1646,11 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len,
|
||||
remainder = 0;
|
||||
|
||||
for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
|
||||
unsigned name_len;
|
||||
char *dname = d_name(di);
|
||||
if (dname[0] == '.' && (dname[1] == '\0'
|
||||
|| (dname[1] == '.' && dname[2] == '\0')))
|
||||
continue;
|
||||
name_len = strlcpy(p, dname, remainder);
|
||||
unsigned name_len = strlcpy(p, dname, remainder);
|
||||
if (name_len >= remainder) {
|
||||
char save = fbuf[len];
|
||||
fbuf[len] = '\0';
|
||||
@@ -1781,7 +1699,7 @@ static void send_implied_dirs(int f, struct file_list *flist, char *fname,
|
||||
item_list *relname_list;
|
||||
relnamecache **rnpp;
|
||||
int len, need_new_dir, depth = 0;
|
||||
filter_rule_list save_filter_list = filter_list;
|
||||
struct filter_list_struct save_filter_list = filter_list;
|
||||
|
||||
flags = (flags | FLAG_IMPLIED_DIR) & ~(FLAG_TOP_DIR | FLAG_CONTENT_DIR);
|
||||
filter_list.head = filter_list.tail = NULL; /* Don't filter implied dirs. */
|
||||
@@ -1877,8 +1795,7 @@ static NORETURN void fatal_unsafe_io_error(void)
|
||||
/* This (sadly) can only happen when pushing data because
|
||||
* the sender does not know about what kind of delete
|
||||
* is in effect on the receiving side when pulling. */
|
||||
rprintf(FERROR_XFER, "FATAL I/O ERROR: dying to avoid a --delete-%s issue with a pre-3.0.7 receiver.\n",
|
||||
delete_during == 2 ? "delay" : "during");
|
||||
rprintf(FERROR_XFER, "FATAL I/O ERROR: dying to avoid a --delete-during issue with a pre-3.0.7 receiver.\n");
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
@@ -1935,9 +1852,7 @@ static void send1extra(int f, struct file_struct *file, struct file_list *flist)
|
||||
|
||||
if (name_type != NORMAL_NAME) {
|
||||
STRUCT_STAT st;
|
||||
if (name_type == MISSING_NAME)
|
||||
memset(&st, 0, sizeof st);
|
||||
else if (link_stat(fbuf, &st, 1) != 0) {
|
||||
if (link_stat(fbuf, &st, 1) != 0) {
|
||||
interpret_stat_error(fbuf, True);
|
||||
continue;
|
||||
}
|
||||
@@ -1954,19 +1869,19 @@ void send_extra_file_list(int f, int at_least)
|
||||
struct file_list *flist;
|
||||
int64 start_write;
|
||||
uint16 prev_flags;
|
||||
int save_io_error = io_error;
|
||||
int old_cnt, save_io_error = io_error;
|
||||
|
||||
if (flist_eof)
|
||||
return;
|
||||
|
||||
if (at_least < 0)
|
||||
at_least = file_total - file_old_total + 1;
|
||||
|
||||
/* Keep sending data until we have the requested number of
|
||||
* files in the upcoming file-lists. */
|
||||
while (file_total - file_old_total < at_least) {
|
||||
old_cnt = cur_flist->used;
|
||||
for (flist = first_flist; flist != cur_flist; flist = flist->next)
|
||||
old_cnt += flist->used;
|
||||
while (file_total - old_cnt < at_least) {
|
||||
struct file_struct *file = dir_flist->sorted[send_dir_ndx];
|
||||
int dir_ndx, dstart = stats.num_dirs;
|
||||
int dir_ndx, dstart = dir_count;
|
||||
const char *pathname = F_PATHNAME(file);
|
||||
int32 *dp;
|
||||
|
||||
@@ -2020,13 +1935,13 @@ void send_extra_file_list(int f, int at_least)
|
||||
|
||||
flist_sort_and_clean(flist, 0);
|
||||
|
||||
add_dirs_to_tree(send_dir_ndx, flist, stats.num_dirs - dstart);
|
||||
add_dirs_to_tree(send_dir_ndx, flist, dir_count - dstart);
|
||||
flist_done_allocating(flist);
|
||||
|
||||
file_total += flist->used;
|
||||
stats.flist_size += stats.total_written - start_write;
|
||||
stats.num_files += flist->used;
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
if (verbose > 3)
|
||||
output_flist(flist);
|
||||
|
||||
if (DIR_FIRST_CHILD(dp) >= 0) {
|
||||
@@ -2037,8 +1952,6 @@ void send_extra_file_list(int f, int at_least)
|
||||
if ((send_dir_ndx = DIR_PARENT(dp)) < 0) {
|
||||
write_ndx(f, NDX_FLIST_EOF);
|
||||
flist_eof = 1;
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
|
||||
change_local_filter_dir(NULL, 0, 0);
|
||||
goto finish;
|
||||
}
|
||||
@@ -2051,7 +1964,7 @@ void send_extra_file_list(int f, int at_least)
|
||||
}
|
||||
|
||||
finish:
|
||||
if (io_error != save_io_error && protocol_version == 30 && !ignore_errors)
|
||||
if (io_error != save_io_error && !ignore_errors)
|
||||
send_msg_int(MSG_IO_ERROR, io_error);
|
||||
}
|
||||
|
||||
@@ -2066,7 +1979,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
struct timeval start_tv, end_tv;
|
||||
int64 start_write;
|
||||
int use_ff_fd = 0;
|
||||
int disable_buffering, reenable_multiplex = -1;
|
||||
int disable_buffering;
|
||||
int flags = recurse ? FLAG_CONTENT_DIR : 0;
|
||||
int reading_remotely = filesfrom_host != NULL;
|
||||
int rl_flags = (reading_remotely ? 0 : RL_DUMP_COMMENTS)
|
||||
@@ -2079,7 +1992,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
rprintf(FLOG, "building file list\n");
|
||||
if (show_filelist_p())
|
||||
start_filelist_progress("building file list");
|
||||
else if (inc_recurse && INFO_GTE(FLIST, 1) && !am_server)
|
||||
else if (inc_recurse && verbose && !am_server)
|
||||
rprintf(FCLIENT, "sending incremental file list\n");
|
||||
|
||||
start_write = stats.total_written;
|
||||
@@ -2107,12 +2020,6 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
full_fname(argv[0]));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
if (protocol_version < 31) {
|
||||
/* Older protocols send the files-from data w/o packaging
|
||||
* it in multiplexed I/O packets, so temporarily switch
|
||||
* to buffered I/O to match this behavior. */
|
||||
reenable_multiplex = io_end_multiplex_in(MPLX_TO_BUFFERED);
|
||||
}
|
||||
use_ff_fd = 1;
|
||||
}
|
||||
|
||||
@@ -2194,8 +2101,12 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
fn = fbuf;
|
||||
/* A leading ./ can be used in relative mode to affect
|
||||
* the dest dir without its name being in the path. */
|
||||
if (*fn == '.' && fn[1] == '/' && fn[2] && !implied_dot_dir)
|
||||
implied_dot_dir = -1;
|
||||
if (*fn == '.' && fn[1] == '/' && !implied_dot_dir) {
|
||||
send_file_name(f, flist, ".", NULL,
|
||||
(flags | FLAG_IMPLIED_DIR) & ~FLAG_CONTENT_DIR,
|
||||
ALL_FILTERS);
|
||||
implied_dot_dir = 1;
|
||||
}
|
||||
len = clean_fname(fn, CFN_KEEP_TRAILING_SLASH
|
||||
| CFN_DROP_TRAILING_DOT_DIR);
|
||||
if (len == 1) {
|
||||
@@ -2233,20 +2144,11 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
dirlen = dir ? strlen(dir) : 0;
|
||||
if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
|
||||
if (!change_pathname(NULL, dir, -dirlen))
|
||||
goto bad_path;
|
||||
continue;
|
||||
lastdir = pathname;
|
||||
lastdir_len = pathname_len;
|
||||
} else if (!change_pathname(NULL, lastdir, lastdir_len)) {
|
||||
bad_path:
|
||||
if (implied_dot_dir < 0)
|
||||
implied_dot_dir = 0;
|
||||
} else if (!change_pathname(NULL, lastdir, lastdir_len))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (implied_dot_dir < 0) {
|
||||
implied_dot_dir = 1;
|
||||
send_file_name(f, flist, ".", NULL, (flags | FLAG_IMPLIED_DIR) & ~FLAG_CONTENT_DIR, ALL_FILTERS);
|
||||
}
|
||||
|
||||
if (fn != fbuf)
|
||||
memmove(fbuf, fn, len + 1);
|
||||
@@ -2254,26 +2156,14 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
if (link_stat(fbuf, &st, copy_dirlinks || name_type != NORMAL_NAME) != 0
|
||||
|| (name_type != DOTDIR_NAME && is_daemon_excluded(fbuf, S_ISDIR(st.st_mode)))
|
||||
|| (relative_paths && path_is_daemon_excluded(fbuf, 1))) {
|
||||
if (errno != ENOENT || missing_args == 0) {
|
||||
/* This is a transfer error, but inhibit deletion
|
||||
* only if we might be omitting an existing file. */
|
||||
if (errno != ENOENT)
|
||||
io_error |= IOERR_GENERAL;
|
||||
rsyserr(FERROR_XFER, errno, "link_stat %s failed",
|
||||
full_fname(fbuf));
|
||||
continue;
|
||||
} else if (missing_args == 1) {
|
||||
/* Just ignore the arg. */
|
||||
continue;
|
||||
} else /* (missing_args == 2) */ {
|
||||
/* Send the arg as a "missing" entry with
|
||||
* mode 0, which tells the generator to delete it. */
|
||||
memset(&st, 0, sizeof st);
|
||||
}
|
||||
io_error |= IOERR_GENERAL;
|
||||
rsyserr(FERROR_XFER, errno, "link_stat %s failed",
|
||||
full_fname(fbuf));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* A dot-dir should not be excluded! */
|
||||
if (name_type != DOTDIR_NAME && st.st_mode != 0
|
||||
if (name_type != DOTDIR_NAME
|
||||
&& is_excluded(fbuf, S_ISDIR(st.st_mode) != 0, ALL_FILTERS))
|
||||
continue;
|
||||
|
||||
@@ -2289,8 +2179,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
p = fn;
|
||||
} else
|
||||
fn = p;
|
||||
send_implied_dirs(f, flist, fbuf, fbuf, p, flags,
|
||||
st.st_mode == 0 ? MISSING_NAME : name_type);
|
||||
send_implied_dirs(f, flist, fbuf, fbuf, p, flags, name_type);
|
||||
if (fn == p)
|
||||
continue;
|
||||
}
|
||||
@@ -2324,9 +2213,6 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
send_file_name(f, flist, fbuf, &st, flags, NO_FILTERS);
|
||||
}
|
||||
|
||||
if (reenable_multiplex >= 0)
|
||||
io_start_multiplex_in(reenable_multiplex);
|
||||
|
||||
gettimeofday(&end_tv, NULL);
|
||||
stats.flist_buildtime = (int64)(end_tv.tv_sec - start_tv.tv_sec) * 1000
|
||||
+ (end_tv.tv_usec - start_tv.tv_usec) / 1000;
|
||||
@@ -2375,11 +2261,12 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
flist->sorted = flist->files;
|
||||
flist_sort_and_clean(flist, 0);
|
||||
file_total += flist->used;
|
||||
file_old_total += flist->used;
|
||||
|
||||
if (numeric_ids <= 0 && !inc_recurse)
|
||||
send_id_list(f);
|
||||
|
||||
set_msg_fd_in(-1);
|
||||
|
||||
/* send the io_error flag */
|
||||
if (protocol_version < 30)
|
||||
write_int(f, ignore_errors ? 0 : io_error);
|
||||
@@ -2387,28 +2274,26 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
send_msg_int(MSG_IO_ERROR, io_error);
|
||||
|
||||
if (disable_buffering)
|
||||
io_end_buffering_out(IOBUF_FREE_BUFS);
|
||||
io_end_buffering_out();
|
||||
|
||||
stats.flist_size = stats.total_written - start_write;
|
||||
stats.num_files = flist->used;
|
||||
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
if (verbose > 3)
|
||||
output_flist(flist);
|
||||
|
||||
if (DEBUG_GTE(FLIST, 2))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "send_file_list done\n");
|
||||
|
||||
if (inc_recurse) {
|
||||
send_dir_depth = 1;
|
||||
add_dirs_to_tree(-1, flist, stats.num_dirs);
|
||||
add_dirs_to_tree(-1, flist, dir_count);
|
||||
if (!file_total || strcmp(flist->sorted[flist->low]->basename, ".") != 0)
|
||||
flist->parent_ndx = -1;
|
||||
flist_done_allocating(flist);
|
||||
if (send_dir_ndx < 0) {
|
||||
write_ndx(f, NDX_FLIST_EOF);
|
||||
flist_eof = 1;
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
|
||||
}
|
||||
else if (file_total == 1) {
|
||||
/* If we're creating incremental file-lists and there
|
||||
@@ -2416,10 +2301,6 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
* file-list to check if this is a 1-file xfer. */
|
||||
send_extra_file_list(f, 1);
|
||||
}
|
||||
} else {
|
||||
flist_eof = 1;
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
|
||||
}
|
||||
|
||||
return flist;
|
||||
@@ -2430,18 +2311,14 @@ struct file_list *recv_file_list(int f)
|
||||
struct file_list *flist;
|
||||
int dstart, flags;
|
||||
int64 start_read;
|
||||
int save_verbose = verbose;
|
||||
|
||||
if (!first_flist) {
|
||||
if (show_filelist_p())
|
||||
start_filelist_progress("receiving file list");
|
||||
else if (inc_recurse && INFO_GTE(FLIST, 1) && !am_server)
|
||||
rprintf(FCLIENT, "receiving incremental file list\n");
|
||||
if (!first_flist)
|
||||
rprintf(FLOG, "receiving file list\n");
|
||||
if (usermap)
|
||||
parse_name_map(usermap, True);
|
||||
if (groupmap)
|
||||
parse_name_map(groupmap, False);
|
||||
}
|
||||
if (show_filelist_p())
|
||||
start_filelist_progress("receiving file list");
|
||||
else if (inc_recurse && verbose && !am_server && !first_flist)
|
||||
rprintf(FCLIENT, "receiving incremental file list\n");
|
||||
|
||||
start_read = stats.total_read;
|
||||
|
||||
@@ -2461,6 +2338,8 @@ struct file_list *recv_file_list(int f)
|
||||
dstart = 0;
|
||||
}
|
||||
|
||||
if (am_server && verbose > 2)
|
||||
verbose = 2;
|
||||
while ((flags = read_byte(f)) != 0) {
|
||||
struct file_struct *file;
|
||||
|
||||
@@ -2482,33 +2361,24 @@ struct file_list *recv_file_list(int f)
|
||||
flist_expand(flist, 1);
|
||||
file = recv_file_entry(f, flist, flags);
|
||||
|
||||
if (S_ISREG(file->mode)) {
|
||||
/* Already counted */
|
||||
} else if (S_ISDIR(file->mode)) {
|
||||
if (inc_recurse) {
|
||||
flist_expand(dir_flist, 1);
|
||||
dir_flist->files[dir_flist->used++] = file;
|
||||
}
|
||||
stats.num_dirs++;
|
||||
} else if (S_ISLNK(file->mode))
|
||||
stats.num_symlinks++;
|
||||
else if (IS_DEVICE(file->mode))
|
||||
stats.num_symlinks++;
|
||||
else
|
||||
stats.num_specials++;
|
||||
if (inc_recurse && S_ISDIR(file->mode)) {
|
||||
flist_expand(dir_flist, 1);
|
||||
dir_flist->files[dir_flist->used++] = file;
|
||||
}
|
||||
|
||||
flist->files[flist->used++] = file;
|
||||
|
||||
maybe_emit_filelist_progress(flist->used);
|
||||
|
||||
if (DEBUG_GTE(FLIST, 2)) {
|
||||
if (verbose > 2) {
|
||||
char *name = f_name(file, NULL);
|
||||
rprintf(FINFO, "recv_file_name(%s)\n", NS(name));
|
||||
}
|
||||
}
|
||||
file_total += flist->used;
|
||||
verbose = save_verbose;
|
||||
|
||||
if (DEBUG_GTE(FLIST, 2))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "received %d names\n", flist->used);
|
||||
|
||||
if (show_filelist_p())
|
||||
@@ -2546,29 +2416,26 @@ struct file_list *recv_file_list(int f)
|
||||
|
||||
if (inc_recurse)
|
||||
flist_done_allocating(flist);
|
||||
else if (f >= 0) {
|
||||
else if (f >= 0)
|
||||
recv_id_list(f, flist);
|
||||
flist_eof = 1;
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
|
||||
}
|
||||
|
||||
flist_sort_and_clean(flist, relative_paths);
|
||||
|
||||
if (protocol_version < 30) {
|
||||
/* Recv the io_error flag */
|
||||
int err = read_int(f);
|
||||
if (!ignore_errors)
|
||||
io_error |= err;
|
||||
if (ignore_errors)
|
||||
read_int(f);
|
||||
else
|
||||
io_error |= read_int(f);
|
||||
} else if (inc_recurse && flist->ndx_start == 1) {
|
||||
if (!file_total || strcmp(flist->sorted[flist->low]->basename, ".") != 0)
|
||||
flist->parent_ndx = -1;
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
if (verbose > 3)
|
||||
output_flist(flist);
|
||||
|
||||
if (DEBUG_GTE(FLIST, 2))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "recv_file_list done\n");
|
||||
|
||||
stats.flist_size += stats.total_read - start_read;
|
||||
@@ -2585,8 +2452,6 @@ void recv_additional_file_list(int f)
|
||||
int ndx = read_ndx(f);
|
||||
if (ndx == NDX_FLIST_EOF) {
|
||||
flist_eof = 1;
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
|
||||
change_local_filter_dir(NULL, 0, 0);
|
||||
} else {
|
||||
ndx = NDX_FLIST_OFFSET - ndx;
|
||||
@@ -2598,7 +2463,7 @@ void recv_additional_file_list(int f)
|
||||
NDX_FLIST_OFFSET - dir_flist->used + 1);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if (DEBUG_GTE(FLIST, 3)) {
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO, "[%s] receiving flist for dir %d\n",
|
||||
who_am_i(), ndx);
|
||||
}
|
||||
@@ -2705,16 +2570,14 @@ struct file_list *flist_new(int flags, char *msg)
|
||||
|
||||
if (flags & FLIST_TEMP) {
|
||||
if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0,
|
||||
out_of_memory,
|
||||
POOL_INTERN)))
|
||||
out_of_memory, POOL_INTERN)))
|
||||
out_of_memory(msg);
|
||||
} else {
|
||||
/* This is a doubly linked list with prev looping back to
|
||||
* the end of the list, but the last next pointer is NULL. */
|
||||
if (!first_flist) {
|
||||
flist->file_pool = pool_create(NORMAL_EXTENT, 0,
|
||||
out_of_memory,
|
||||
POOL_INTERN);
|
||||
out_of_memory, POOL_INTERN);
|
||||
if (!flist->file_pool)
|
||||
out_of_memory(msg);
|
||||
|
||||
@@ -2844,7 +2707,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root)
|
||||
keep = j, drop = i;
|
||||
|
||||
if (!am_sender) {
|
||||
if (DEBUG_GTE(DUP, 1)) {
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO,
|
||||
"removing duplicate name %s from file list (%d)\n",
|
||||
f_name(file, fbuf), drop + flist->ndx_start);
|
||||
@@ -2985,10 +2848,10 @@ static void output_flist(struct file_list *flist)
|
||||
} else
|
||||
root = dir = slash = name = trail = "";
|
||||
rprintf(FINFO,
|
||||
"[%s] i=%d %s %s%s%s%s mode=0%o len=%s%s%s flags=%x\n",
|
||||
"[%s] i=%d %s %s%s%s%s mode=0%o len=%.0f%s%s flags=%x\n",
|
||||
who, i + flist->ndx_start,
|
||||
root, dir, slash, name, trail,
|
||||
(int)file->mode, comma_num(F_LENGTH(file)),
|
||||
(int)file->mode, (double)F_LENGTH(file),
|
||||
uidbuf, gidbuf, file->flags);
|
||||
}
|
||||
}
|
||||
@@ -3203,7 +3066,7 @@ struct file_list *get_dirlist(char *dirname, int dlen, int flags)
|
||||
send_directory(senddir_fd, dirlist, dirname, dlen, FLAG_CONTENT_DIR);
|
||||
xfer_dirs = save_xfer_dirs;
|
||||
recurse = save_recurse;
|
||||
if (INFO_GTE(PROGRESS, 1))
|
||||
if (do_progress)
|
||||
flist_count_offset += dirlist->used;
|
||||
|
||||
prune_empty_dirs = 0;
|
||||
@@ -3211,7 +3074,7 @@ struct file_list *get_dirlist(char *dirname, int dlen, int flags)
|
||||
flist_sort_and_clean(dirlist, 0);
|
||||
prune_empty_dirs = save_prune_empty_dirs;
|
||||
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
if (verbose > 3)
|
||||
output_flist(dirlist);
|
||||
|
||||
return dirlist;
|
||||
|
||||
823
generator.c
823
generator.c
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
* `id -G` on Linux, but it's too hard to find a portable equivalent.
|
||||
*
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2008 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 3 as
|
||||
|
||||
23
hashtable.c
23
hashtable.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Routines to provide a memory-efficient hashtable.
|
||||
*
|
||||
* Copyright (C) 2007-2013 Wayne Davison
|
||||
* Copyright (C) 2007-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,13 +23,13 @@
|
||||
|
||||
struct hashtable *hashtable_create(int size, int key64)
|
||||
{
|
||||
int req = size;
|
||||
struct hashtable *tbl;
|
||||
int node_size = key64 ? sizeof (struct ht_int64_node)
|
||||
: sizeof (struct ht_int32_node);
|
||||
|
||||
/* Pick a power of 2 that can hold the requested size. */
|
||||
if (size & (size-1) || size < 16) {
|
||||
int req = size;
|
||||
size = 16;
|
||||
while (size < req)
|
||||
size *= 2;
|
||||
@@ -43,25 +43,11 @@ struct hashtable *hashtable_create(int size, int key64)
|
||||
tbl->node_size = node_size;
|
||||
tbl->key64 = key64 ? 1 : 0;
|
||||
|
||||
if (DEBUG_GTE(HASH, 1)) {
|
||||
char buf[32];
|
||||
if (req != size)
|
||||
snprintf(buf, sizeof buf, "req: %d, ", req);
|
||||
else
|
||||
*buf = '\0';
|
||||
rprintf(FINFO, "[%s] created hashtable %lx (%ssize: %d, keys: %d-bit)\n",
|
||||
who_am_i(), (long)tbl, buf, size, key64 ? 64 : 32);
|
||||
}
|
||||
|
||||
return tbl;
|
||||
}
|
||||
|
||||
void hashtable_destroy(struct hashtable *tbl)
|
||||
{
|
||||
if (DEBUG_GTE(HASH, 1)) {
|
||||
rprintf(FINFO, "[%s] destroyed hashtable %lx (size: %d, keys: %d-bit)\n",
|
||||
who_am_i(), (long)tbl, tbl->size, tbl->key64 ? 64 : 32);
|
||||
}
|
||||
free(tbl->nodes);
|
||||
free(tbl);
|
||||
}
|
||||
@@ -89,11 +75,6 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
|
||||
tbl->size = size;
|
||||
tbl->entries = 0;
|
||||
|
||||
if (DEBUG_GTE(HASH, 1)) {
|
||||
rprintf(FINFO, "[%s] growing hashtable %lx (size: %d, keys: %d-bit)\n",
|
||||
who_am_i(), (long)tbl, size, key64 ? 64 : 32);
|
||||
}
|
||||
|
||||
for (i = size / 2; i-- > 0; ) {
|
||||
struct ht_int32_node *move_node = HT_NODE(tbl, old_nodes, i);
|
||||
int64 move_key = HT_KEY(move_node, key64);
|
||||
|
||||
99
hlink.c
99
hlink.c
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2004-2013 Wayne Davison
|
||||
* Copyright (C) 2004-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -21,9 +21,8 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int list_only;
|
||||
extern int am_sender;
|
||||
@@ -32,6 +31,7 @@ extern int do_xfers;
|
||||
extern int link_dest;
|
||||
extern int preserve_acls;
|
||||
extern int preserve_xattrs;
|
||||
extern int make_backups;
|
||||
extern int protocol_version;
|
||||
extern int remove_source_files;
|
||||
extern int stdout_format_has_i;
|
||||
@@ -71,14 +71,8 @@ struct ht_int64_node *idev_find(int64 dev, int64 ino)
|
||||
if (!dev_node || dev_node->key != dev+1) {
|
||||
/* We keep a separate hash table of inodes for every device. */
|
||||
dev_node = hashtable_find(dev_tbl, dev+1, 1);
|
||||
if (!(tbl = dev_node->data)) {
|
||||
if (!(tbl = dev_node->data))
|
||||
tbl = dev_node->data = hashtable_create(512, 1);
|
||||
if (DEBUG_GTE(HLINK, 3)) {
|
||||
rprintf(FINFO,
|
||||
"[%s] created hashtable for dev %s\n",
|
||||
who_am_i(), big_num(dev));
|
||||
}
|
||||
}
|
||||
} else
|
||||
tbl = dev_node->data;
|
||||
|
||||
@@ -212,7 +206,7 @@ void match_hard_links(struct file_list *flist)
|
||||
}
|
||||
|
||||
static int maybe_hard_link(struct file_struct *file, int ndx,
|
||||
char *fname, int statret, stat_x *sxp,
|
||||
const char *fname, int statret, stat_x *sxp,
|
||||
const char *oldname, STRUCT_STAT *old_stp,
|
||||
const char *realname, int itemizing, enum logcode code)
|
||||
{
|
||||
@@ -224,24 +218,31 @@ static int maybe_hard_link(struct file_struct *file, int ndx,
|
||||
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
|
||||
0, "");
|
||||
}
|
||||
if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
|
||||
if (verbose > 1 && maybe_ATTRS_REPORT)
|
||||
rprintf(FCLIENT, "%s is uptodate\n", fname);
|
||||
file->flags |= FLAG_HLINK_DONE;
|
||||
return 0;
|
||||
}
|
||||
if (make_backups > 0) {
|
||||
if (!make_backup(fname))
|
||||
return -1;
|
||||
} else if (robust_unlink(fname)) {
|
||||
rsyserr(FERROR_XFER, errno, "unlink %s failed",
|
||||
full_fname(fname));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (atomic_create(file, fname, oldname, MAKEDEV(0, 0), sxp, statret == 0 ? DEL_FOR_FILE : 0)) {
|
||||
if (hard_link_one(file, fname, oldname, 0)) {
|
||||
if (itemizing) {
|
||||
itemize(fname, file, ndx, statret, sxp,
|
||||
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
|
||||
realname);
|
||||
}
|
||||
if (code != FNONE && INFO_GTE(NAME, 1))
|
||||
if (code != FNONE && verbose)
|
||||
rprintf(code, "%s => %s\n", fname, realname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -287,7 +288,7 @@ static char *check_prior(struct file_struct *file, int gnum,
|
||||
|
||||
/* Only called if FLAG_HLINKED is set and FLAG_HLINK_FIRST is not. Returns:
|
||||
* 0 = process the file, 1 = skip the file, -1 = error occurred. */
|
||||
int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
int hard_link_check(struct file_struct *file, int ndx, const char *fname,
|
||||
int statret, stat_x *sxp, int itemizing,
|
||||
enum logcode code)
|
||||
{
|
||||
@@ -306,10 +307,6 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
if (!flist) {
|
||||
/* The previous file was skipped, so this one is
|
||||
* treated as if it were the first in its group. */
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): virtual first\n",
|
||||
ndx, f_name(file, NULL), gnum);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -326,16 +323,8 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
F_HL_PREV(prev_file) = ndx;
|
||||
file->flags |= FLAG_FILE_SENT;
|
||||
cur_flist->in_progress++;
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): waiting for %d\n",
|
||||
ndx, f_name(file, NULL), gnum, F_HL_PREV(file));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): looking for a leader\n",
|
||||
ndx, f_name(file, NULL), gnum);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -343,6 +332,7 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
if (!(prev_file->flags & FLAG_HLINK_FIRST)) {
|
||||
/* The previous previous is FIRST when prev is not. */
|
||||
prev_name = realname = check_prior(prev_file, gnum, &prev_ndx, &flist);
|
||||
assert(prev_name != NULL || flist != NULL);
|
||||
/* Update our previous pointer to point to the FIRST. */
|
||||
F_HL_PREV(file) = prev_ndx;
|
||||
}
|
||||
@@ -350,14 +340,9 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
if (!prev_name) {
|
||||
int alt_dest;
|
||||
|
||||
assert(flist != NULL);
|
||||
prev_file = flist->files[prev_ndx - flist->ndx_start];
|
||||
/* F_HL_PREV() is alt_dest value when DONE && FIRST. */
|
||||
alt_dest = F_HL_PREV(prev_file);
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): found flist match (alt %d)\n",
|
||||
ndx, f_name(file, NULL), gnum, alt_dest);
|
||||
}
|
||||
|
||||
if (alt_dest >= 0 && dry_run) {
|
||||
pathjoin(namebuf, MAXPATHLEN, basis_dir[alt_dest],
|
||||
@@ -371,11 +356,6 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): leader is %d (%s)\n",
|
||||
ndx, f_name(file, NULL), gnum, prev_ndx, prev_name);
|
||||
}
|
||||
|
||||
if (link_stat(prev_name, &prev_st, 0) < 0) {
|
||||
if (!dry_run || errno != ENOENT) {
|
||||
rsyserr(FERROR_XFER, errno, "stat %s failed", full_fname(prev_name));
|
||||
@@ -391,7 +371,12 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
char cmpbuf[MAXPATHLEN];
|
||||
stat_x alt_sx;
|
||||
int j = 0;
|
||||
init_stat_x(&alt_sx);
|
||||
#ifdef SUPPORT_ACLS
|
||||
alt_sx.acc_acl = alt_sx.def_acl = NULL;
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
alt_sx.xattr = NULL;
|
||||
#endif
|
||||
do {
|
||||
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
|
||||
if (link_stat(cmpbuf, &alt_sx.st, 0) < 0)
|
||||
@@ -402,10 +387,10 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
continue;
|
||||
statret = 1;
|
||||
if (stdout_format_has_i == 0
|
||||
|| (!INFO_GTE(NAME, 2) && stdout_format_has_i < 2)) {
|
||||
|| (verbose < 2 && stdout_format_has_i < 2)) {
|
||||
itemizing = 0;
|
||||
code = FNONE;
|
||||
if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
|
||||
if (verbose > 1 && maybe_ATTRS_REPORT)
|
||||
rprintf(FCLIENT, "%s is uptodate\n", fname);
|
||||
}
|
||||
break;
|
||||
@@ -441,8 +426,16 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
free_stat_x(&alt_sx);
|
||||
} else {
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls)
|
||||
free_acl(&alt_sx);
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs)
|
||||
free_xattr(&alt_sx);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (maybe_hard_link(file, ndx, fname, statret, sxp, prev_name, &prev_st,
|
||||
@@ -461,7 +454,7 @@ int hard_link_one(struct file_struct *file, const char *fname,
|
||||
if (do_link(oldname, fname) < 0) {
|
||||
enum logcode code;
|
||||
if (terse) {
|
||||
if (!INFO_GTE(NAME, 1))
|
||||
if (!verbose)
|
||||
return 0;
|
||||
code = FINFO;
|
||||
} else
|
||||
@@ -488,7 +481,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
|
||||
int prev_statret, ndx, prev_ndx = F_HL_PREV(file);
|
||||
|
||||
if (stp == NULL && prev_ndx >= 0) {
|
||||
if (link_stat(fname, &st, 0) < 0 && !dry_run) {
|
||||
if (link_stat(fname, &st, 0) < 0) {
|
||||
rsyserr(FERROR_XFER, errno, "stat %s failed",
|
||||
full_fname(fname));
|
||||
return;
|
||||
@@ -506,7 +499,12 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
|
||||
} else
|
||||
our_name = fname;
|
||||
|
||||
init_stat_x(&prev_sx);
|
||||
#ifdef SUPPORT_ACLS
|
||||
prev_sx.acc_acl = prev_sx.def_acl = NULL;
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
prev_sx.xattr = NULL;
|
||||
#endif
|
||||
|
||||
while ((ndx = prev_ndx) >= 0) {
|
||||
int val;
|
||||
@@ -519,7 +517,14 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
|
||||
val = maybe_hard_link(file, ndx, prev_name, prev_statret, &prev_sx,
|
||||
our_name, stp, fname, itemizing, code);
|
||||
flist->in_progress--;
|
||||
free_stat_x(&prev_sx);
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls)
|
||||
free_acl(&prev_sx);
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs)
|
||||
free_xattr(&prev_sx);
|
||||
#endif
|
||||
if (val < 0)
|
||||
continue;
|
||||
if (remove_source_files == 1 && do_xfers)
|
||||
|
||||
70
ifuncs.h
70
ifuncs.h
@@ -1,6 +1,6 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2007-2013 Wayne Davison
|
||||
* Copyright (C) 2007-2008 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -35,14 +35,6 @@ realloc_xbuf(xbuf *xb, size_t sz)
|
||||
xb->size = sz;
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_xbuf(xbuf *xb)
|
||||
{
|
||||
if (xb->buf)
|
||||
free(xb->buf);
|
||||
memset(xb, 0, sizeof (xbuf));
|
||||
}
|
||||
|
||||
static inline int
|
||||
to_wire_mode(mode_t mode)
|
||||
{
|
||||
@@ -75,32 +67,44 @@ d_name(struct dirent *di)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
init_stat_x(stat_x *sx_p)
|
||||
static inline int
|
||||
isDigit(const char *ptr)
|
||||
{
|
||||
#ifdef SUPPORT_ACLS
|
||||
sx_p->acc_acl = sx_p->def_acl = NULL;
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
sx_p->xattr = NULL;
|
||||
#endif
|
||||
return isdigit(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_stat_x(stat_x *sx_p)
|
||||
static inline int
|
||||
isPrint(const char *ptr)
|
||||
{
|
||||
#ifdef SUPPORT_ACLS
|
||||
{
|
||||
extern int preserve_acls;
|
||||
if (preserve_acls)
|
||||
free_acl(sx_p);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
{
|
||||
extern int preserve_xattrs;
|
||||
if (preserve_xattrs)
|
||||
free_xattr(sx_p);
|
||||
}
|
||||
#endif
|
||||
return isprint(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isSpace(const char *ptr)
|
||||
{
|
||||
return isspace(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isLower(const char *ptr)
|
||||
{
|
||||
return islower(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isUpper(const char *ptr)
|
||||
{
|
||||
return isupper(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
toLower(const char *ptr)
|
||||
{
|
||||
return tolower(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
toUpper(const char *ptr)
|
||||
{
|
||||
return toupper(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
57
inums.h
57
inums.h
@@ -1,57 +0,0 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2008 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
static inline char *
|
||||
big_num(int64 num)
|
||||
{
|
||||
return do_big_num(num, 0, NULL);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
comma_num(int64 num)
|
||||
{
|
||||
extern int human_readable;
|
||||
return do_big_num(num, human_readable != 0, NULL);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
human_num(int64 num)
|
||||
{
|
||||
extern int human_readable;
|
||||
return do_big_num(num, human_readable, NULL);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
big_dnum(double dnum, int decimal_digits)
|
||||
{
|
||||
return do_big_dnum(dnum, 0, decimal_digits);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
comma_dnum(double dnum, int decimal_digits)
|
||||
{
|
||||
extern int human_readable;
|
||||
return do_big_dnum(dnum, human_readable != 0, decimal_digits);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
human_dnum(double dnum, int decimal_digits)
|
||||
{
|
||||
extern int human_readable;
|
||||
return do_big_dnum(dnum, human_readable, decimal_digits);
|
||||
}
|
||||
2
io.h
2
io.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2013 Wayne Davison
|
||||
* Copyright (C) 2007-2008 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
59
itypes.h
59
itypes.h
@@ -1,59 +0,0 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2007-2013 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
static inline int
|
||||
isDigit(const char *ptr)
|
||||
{
|
||||
return isdigit(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isPrint(const char *ptr)
|
||||
{
|
||||
return isprint(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isSpace(const char *ptr)
|
||||
{
|
||||
return isspace(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isLower(const char *ptr)
|
||||
{
|
||||
return islower(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isUpper(const char *ptr)
|
||||
{
|
||||
return isupper(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
toLower(const char *ptr)
|
||||
{
|
||||
return tolower(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
toUpper(const char *ptr)
|
||||
{
|
||||
return toupper(*(unsigned char *)ptr);
|
||||
}
|
||||
122
lib/compat.c
122
lib/compat.c
@@ -20,9 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
|
||||
static char number_separator;
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
char *strdup(char *s)
|
||||
@@ -154,122 +151,3 @@ int sys_gettimeofday(struct timeval *tv)
|
||||
return gettimeofday(tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define HUMANIFY(mult) \
|
||||
do { \
|
||||
if (num >= mult || num <= -mult) { \
|
||||
double dnum = (double)num / mult; \
|
||||
char units; \
|
||||
if (num < 0) \
|
||||
dnum = -dnum; \
|
||||
if (dnum < mult) \
|
||||
units = 'K'; \
|
||||
else if ((dnum /= mult) < mult) \
|
||||
units = 'M'; \
|
||||
else if ((dnum /= mult) < mult) \
|
||||
units = 'G'; \
|
||||
else { \
|
||||
dnum /= mult; \
|
||||
units = 'T'; \
|
||||
} \
|
||||
if (num < 0) \
|
||||
dnum = -dnum; \
|
||||
snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units); \
|
||||
return bufs[n]; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Return the int64 number as a string. If the human_flag arg is non-zero,
|
||||
* we may output the number in K, M, G, or T units. If we don't add a unit
|
||||
* suffix, we will append the fract string, if it is non-NULL. We can
|
||||
* return up to 4 buffers at a time. */
|
||||
char *do_big_num(int64 num, int human_flag, const char *fract)
|
||||
{
|
||||
static char bufs[4][128]; /* more than enough room */
|
||||
static unsigned int n;
|
||||
char *s;
|
||||
int len, negated;
|
||||
|
||||
if (human_flag && !number_separator) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof buf, "%f", 3.14);
|
||||
if (strchr(buf, '.') != NULL)
|
||||
number_separator = ',';
|
||||
else
|
||||
number_separator = '.';
|
||||
}
|
||||
|
||||
n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
|
||||
|
||||
if (human_flag > 1) {
|
||||
if (human_flag == 2)
|
||||
HUMANIFY(1000);
|
||||
else
|
||||
HUMANIFY(1024);
|
||||
}
|
||||
|
||||
s = bufs[n] + sizeof bufs[0] - 1;
|
||||
if (fract) {
|
||||
len = strlen(fract);
|
||||
s -= len;
|
||||
strlcpy(s, fract, len + 1);
|
||||
} else
|
||||
*s = '\0';
|
||||
|
||||
len = 0;
|
||||
|
||||
if (!num)
|
||||
*--s = '0';
|
||||
if (num < 0) {
|
||||
/* A maximum-size negated number can't fit as a positive,
|
||||
* so do one digit in negated form to start us off. */
|
||||
*--s = (char)(-(num % 10)) + '0';
|
||||
num = -(num / 10);
|
||||
len++;
|
||||
negated = 1;
|
||||
} else
|
||||
negated = 0;
|
||||
|
||||
while (num) {
|
||||
if (human_flag) {
|
||||
if (len == 3) {
|
||||
*--s = number_separator;
|
||||
len = 1;
|
||||
} else
|
||||
len++;
|
||||
}
|
||||
*--s = (char)(num % 10) + '0';
|
||||
num /= 10;
|
||||
}
|
||||
|
||||
if (negated)
|
||||
*--s = '-';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return the double number as a string. If the human_flag option is > 1,
|
||||
* we may output the number in K, M, G, or T units. The buffer we use for
|
||||
* our result is either a single static buffer defined here, or a buffer
|
||||
* we get from do_big_num(). */
|
||||
char *do_big_dnum(double dnum, int human_flag, int decimal_digits)
|
||||
{
|
||||
static char tmp_buf[128];
|
||||
#if SIZEOF_INT64 >= 8
|
||||
char *fract;
|
||||
|
||||
snprintf(tmp_buf, sizeof tmp_buf, "%.*f", decimal_digits, dnum);
|
||||
|
||||
if (!human_flag || (dnum < 1000.0 && dnum > -1000.0))
|
||||
return tmp_buf;
|
||||
|
||||
for (fract = tmp_buf+1; isDigit(fract); fract++) {}
|
||||
|
||||
return do_big_num((int64)dnum, human_flag, fract);
|
||||
#else
|
||||
/* A big number might lose digits converting to a too-short int64,
|
||||
* so let's just return the raw double conversion. */
|
||||
snprintf(tmp_buf, sizeof tmp_buf, "%.*f", decimal_digits, dnum);
|
||||
return tmp_buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* An implementation of getpass for systems that lack one.
|
||||
*
|
||||
* Copyright (C) 2013 Roman Donchenko
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
char *getpass(const char *prompt)
|
||||
{
|
||||
static char password[256];
|
||||
|
||||
BOOL tty_changed = False, read_success;
|
||||
struct termios tty_old, tty_new;
|
||||
FILE *in = stdin, *out = stderr;
|
||||
FILE *tty = fopen("/dev/tty", "w+");
|
||||
|
||||
if (tty)
|
||||
in = out = tty;
|
||||
|
||||
if (tcgetattr(fileno(in), &tty_old) == 0) {
|
||||
tty_new = tty_old;
|
||||
tty_new.c_lflag &= ~(ECHO | ISIG);
|
||||
|
||||
if (tcsetattr(fileno(in), TCSAFLUSH, &tty_new) == 0)
|
||||
tty_changed = True;
|
||||
}
|
||||
|
||||
if (!tty_changed)
|
||||
fputs("(WARNING: will be visible) ", out);
|
||||
fputs(prompt, out);
|
||||
fflush(out);
|
||||
|
||||
read_success = fgets(password, sizeof password, in) != NULL;
|
||||
|
||||
/* Print the newline that hasn't been echoed. */
|
||||
fputc('\n', out);
|
||||
|
||||
if (tty_changed)
|
||||
tcsetattr(fileno(in), TCSAFLUSH, &tty_old);
|
||||
|
||||
if (tty)
|
||||
fclose(tty);
|
||||
|
||||
if (read_success) {
|
||||
/* Remove the trailing newline. */
|
||||
size_t password_len = strlen(password);
|
||||
if (password_len && password[password_len - 1] == '\n')
|
||||
password[password_len - 1] = '\0';
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -95,39 +95,25 @@ for
|
||||
.I quantum
|
||||
will produce a quantum that should meet maximal alignment
|
||||
on most platforms.
|
||||
Unless
|
||||
.B POOL_NO_QALIGN
|
||||
If
|
||||
.B POOL_QALIGN
|
||||
is set in the
|
||||
.IR flags ,
|
||||
allocations will be aligned to addresses that are a
|
||||
multiple of
|
||||
.IR quantum .
|
||||
A
|
||||
.B NULL
|
||||
may be specified for the
|
||||
.I bomb
|
||||
function pointer if it is not needed. (See the
|
||||
.B pool_alloc()
|
||||
function for how it is used.)
|
||||
If
|
||||
.B POOL_CLEAR
|
||||
is set in the
|
||||
.IR flags ,
|
||||
all allocations from the pool will be initialized to zeros.
|
||||
If either
|
||||
.B POOL_PREPEND
|
||||
or
|
||||
.B POOL_INTERN
|
||||
is specified in the
|
||||
.IR flags ,
|
||||
each extent's data structure will be allocated at the start of the
|
||||
.IR size -length
|
||||
buffer (rather than as a separate, non-pool allocation), with the
|
||||
former extending the
|
||||
.I size
|
||||
to hold the structure, and the latter subtracting the structure's
|
||||
length from the indicated
|
||||
.IR size .
|
||||
You may specify a
|
||||
.B NULL
|
||||
for the
|
||||
.I bomb
|
||||
function pointer if you don't wish to use it. (See the
|
||||
.B pool_alloc()
|
||||
function for how it is used.)
|
||||
.P
|
||||
.B pool_destroy()
|
||||
destroys an allocation
|
||||
@@ -145,8 +131,8 @@ is
|
||||
.BR 0 ,
|
||||
.I quantum
|
||||
bytes will be allocated.
|
||||
If the pool has been created without
|
||||
.BR POOL_NO_QALIGN ,
|
||||
If the pool has been created with
|
||||
.BR POOL_QALIGN ,
|
||||
every chunk of memory that is returned will be suitably aligned.
|
||||
You can use this with the default
|
||||
.I quantum
|
||||
@@ -183,7 +169,7 @@ an extent), its memory will be completely freed back to the system.
|
||||
If
|
||||
.I addr
|
||||
is
|
||||
.BR NULL ,
|
||||
.BR 0 ,
|
||||
no memory will be freed, but subsequent allocations will come
|
||||
from a new extent.
|
||||
.P
|
||||
|
||||
155
lib/pool_alloc.c
155
lib/pool_alloc.c
@@ -2,8 +2,6 @@
|
||||
|
||||
#define POOL_DEF_EXTENT (32 * 1024)
|
||||
|
||||
#define POOL_QALIGN_P2 (1<<16) /* power-of-2 qalign */
|
||||
|
||||
struct alloc_pool
|
||||
{
|
||||
size_t size; /* extent size */
|
||||
@@ -15,7 +13,7 @@ struct alloc_pool
|
||||
|
||||
/* statistical data */
|
||||
unsigned long e_created; /* extents created */
|
||||
unsigned long e_freed; /* extents destroyed */
|
||||
unsigned long e_freed; /* extents detroyed */
|
||||
int64 n_allocated; /* calls to alloc */
|
||||
int64 n_freed; /* calls to free */
|
||||
int64 b_allocated; /* cum. bytes allocated */
|
||||
@@ -24,18 +22,16 @@ struct alloc_pool
|
||||
|
||||
struct pool_extent
|
||||
{
|
||||
struct pool_extent *next;
|
||||
void *start; /* starting address */
|
||||
size_t free; /* free bytecount */
|
||||
size_t bound; /* trapped free bytes */
|
||||
size_t bound; /* bytes bound by padding,
|
||||
* overhead and freed */
|
||||
struct pool_extent *next;
|
||||
};
|
||||
|
||||
struct align_test {
|
||||
uchar foo;
|
||||
union {
|
||||
int64 i;
|
||||
void *p;
|
||||
} bar;
|
||||
void *foo;
|
||||
int64 bar;
|
||||
};
|
||||
|
||||
#define MINALIGN offsetof(struct align_test, bar)
|
||||
@@ -47,42 +43,20 @@ struct align_test {
|
||||
alloc_pool_t
|
||||
pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags)
|
||||
{
|
||||
struct alloc_pool *pool;
|
||||
struct alloc_pool *pool;
|
||||
|
||||
if (!(pool = new0(struct alloc_pool)))
|
||||
return NULL;
|
||||
|
||||
if ((MINALIGN & (MINALIGN - 1)) != 0) {
|
||||
if (bomb)
|
||||
(*bomb)("Compiler error: MINALIGN is not a power of 2\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!size)
|
||||
size = POOL_DEF_EXTENT;
|
||||
if (!quantum)
|
||||
quantum = MINALIGN;
|
||||
if (!(pool = new(struct alloc_pool)))
|
||||
return pool;
|
||||
memset(pool, 0, sizeof (struct alloc_pool));
|
||||
|
||||
pool->size = size /* round extent size to min alignment reqs */
|
||||
? (size + MINALIGN - 1) & ~(MINALIGN - 1)
|
||||
: POOL_DEF_EXTENT;
|
||||
if (flags & POOL_INTERN) {
|
||||
if (size <= sizeof (struct pool_extent))
|
||||
size = quantum;
|
||||
else
|
||||
size -= sizeof (struct pool_extent);
|
||||
flags |= POOL_PREPEND;
|
||||
pool->size -= sizeof (struct pool_extent);
|
||||
flags |= POOL_APPEND;
|
||||
}
|
||||
|
||||
if (quantum <= 1)
|
||||
flags = (flags | POOL_NO_QALIGN) & ~POOL_QALIGN_P2;
|
||||
else if (!(flags & POOL_NO_QALIGN)) {
|
||||
if (size % quantum)
|
||||
size += quantum - size % quantum;
|
||||
/* If quantum is a power of 2, we'll avoid using modulus. */
|
||||
if (!(quantum & (quantum - 1)))
|
||||
flags |= POOL_QALIGN_P2;
|
||||
}
|
||||
|
||||
pool->size = size;
|
||||
pool->quantum = quantum;
|
||||
pool->quantum = quantum ? quantum : MINALIGN;
|
||||
pool->bomb = bomb;
|
||||
pool->flags = flags;
|
||||
|
||||
@@ -93,21 +67,17 @@ void
|
||||
pool_destroy(alloc_pool_t p)
|
||||
{
|
||||
struct alloc_pool *pool = (struct alloc_pool *) p;
|
||||
struct pool_extent *cur, *next;
|
||||
struct pool_extent *cur, *next;
|
||||
|
||||
if (!pool)
|
||||
return;
|
||||
|
||||
for (cur = pool->extents; cur; cur = next) {
|
||||
next = cur->next;
|
||||
if (pool->flags & POOL_PREPEND)
|
||||
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
|
||||
else {
|
||||
free(cur->start);
|
||||
free(cur->start);
|
||||
if (!(pool->flags & POOL_APPEND))
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
free(pool);
|
||||
}
|
||||
|
||||
@@ -120,40 +90,45 @@ pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg)
|
||||
|
||||
if (!len)
|
||||
len = pool->quantum;
|
||||
else if (pool->flags & POOL_QALIGN_P2) {
|
||||
if (len & (pool->quantum - 1))
|
||||
len += pool->quantum - (len & (pool->quantum - 1));
|
||||
} else if (!(pool->flags & POOL_NO_QALIGN)) {
|
||||
if (len % pool->quantum)
|
||||
len += pool->quantum - len % pool->quantum;
|
||||
}
|
||||
else if (pool->quantum > 1 && len % pool->quantum)
|
||||
len += pool->quantum - len % pool->quantum;
|
||||
|
||||
if (len > pool->size)
|
||||
goto bomb_out;
|
||||
|
||||
if (!pool->extents || len > pool->extents->free) {
|
||||
void *start;
|
||||
size_t asize;
|
||||
void *start;
|
||||
size_t free;
|
||||
size_t bound;
|
||||
size_t skew;
|
||||
size_t asize;
|
||||
struct pool_extent *ext;
|
||||
|
||||
free = pool->size;
|
||||
bound = 0;
|
||||
|
||||
asize = pool->size;
|
||||
if (pool->flags & POOL_PREPEND)
|
||||
if (pool->flags & POOL_APPEND)
|
||||
asize += sizeof (struct pool_extent);
|
||||
|
||||
if (!(start = new_array(char, asize)))
|
||||
goto bomb_out;
|
||||
|
||||
if (pool->flags & POOL_CLEAR)
|
||||
memset(start, 0, asize);
|
||||
memset(start, 0, free);
|
||||
|
||||
if (pool->flags & POOL_PREPEND) {
|
||||
ext = start;
|
||||
start = PTR_ADD(start, sizeof (struct pool_extent));
|
||||
} else if (!(ext = new(struct pool_extent)))
|
||||
if (pool->flags & POOL_APPEND)
|
||||
ext = PTR_ADD(start, free);
|
||||
else if (!(ext = new(struct pool_extent)))
|
||||
goto bomb_out;
|
||||
if (pool->flags & POOL_QALIGN && pool->quantum > 1
|
||||
&& (skew = (size_t)PTR_ADD(start, free) % pool->quantum)) {
|
||||
bound += skew;
|
||||
free -= skew;
|
||||
}
|
||||
ext->start = start;
|
||||
ext->free = pool->size;
|
||||
ext->bound = 0;
|
||||
ext->free = free;
|
||||
ext->bound = bound;
|
||||
ext->next = pool->extents;
|
||||
pool->extents = ext;
|
||||
|
||||
@@ -185,24 +160,10 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
|
||||
if (!pool)
|
||||
return;
|
||||
|
||||
if (!addr) {
|
||||
/* A NULL addr starts a fresh extent for new allocations. */
|
||||
if ((cur = pool->extents) != NULL && cur->free != pool->size) {
|
||||
cur->bound += cur->free;
|
||||
cur->free = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
len = pool->quantum;
|
||||
else if (pool->flags & POOL_QALIGN_P2) {
|
||||
if (len & (pool->quantum - 1))
|
||||
len += pool->quantum - (len & (pool->quantum - 1));
|
||||
} else if (!(pool->flags & POOL_NO_QALIGN)) {
|
||||
if (len % pool->quantum)
|
||||
len += pool->quantum - len % pool->quantum;
|
||||
}
|
||||
else if (pool->quantum > 1 && len % pool->quantum)
|
||||
len += pool->quantum - len % pool->quantum;
|
||||
|
||||
pool->n_freed++;
|
||||
pool->b_freed += len;
|
||||
@@ -218,12 +179,19 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
|
||||
if (!prev) {
|
||||
/* The "live" extent is kept ready for more allocations. */
|
||||
if (cur->free + cur->bound + len >= pool->size) {
|
||||
size_t skew;
|
||||
|
||||
if (pool->flags & POOL_CLEAR) {
|
||||
memset(PTR_ADD(cur->start, cur->free), 0,
|
||||
pool->size - cur->free);
|
||||
}
|
||||
cur->free = pool->size;
|
||||
cur->bound = 0;
|
||||
if (pool->flags & POOL_QALIGN && pool->quantum > 1
|
||||
&& (skew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum)) {
|
||||
cur->bound += skew;
|
||||
cur->free -= skew;
|
||||
}
|
||||
} else if (addr == PTR_ADD(cur->start, cur->free)) {
|
||||
if (pool->flags & POOL_CLEAR)
|
||||
memset(addr, 0, len);
|
||||
@@ -235,12 +203,9 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
|
||||
|
||||
if (cur->free + cur->bound >= pool->size) {
|
||||
prev->next = cur->next;
|
||||
if (pool->flags & POOL_PREPEND)
|
||||
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
|
||||
else {
|
||||
free(cur->start);
|
||||
free(cur->start);
|
||||
if (!(pool->flags & POOL_APPEND))
|
||||
free(cur);
|
||||
}
|
||||
pool->e_freed++;
|
||||
} else if (prev != pool->extents) {
|
||||
/* Move the extent to be the first non-live extent. */
|
||||
@@ -277,11 +242,18 @@ pool_free_old(alloc_pool_t p, void *addr)
|
||||
prev->next = NULL;
|
||||
next = cur;
|
||||
} else {
|
||||
size_t skew;
|
||||
|
||||
/* The most recent live extent can just be reset. */
|
||||
if (pool->flags & POOL_CLEAR)
|
||||
memset(addr, 0, pool->size - cur->free);
|
||||
cur->free = pool->size;
|
||||
cur->bound = 0;
|
||||
if (pool->flags & POOL_QALIGN && pool->quantum > 1
|
||||
&& (skew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum)) {
|
||||
cur->bound += skew;
|
||||
cur->free -= skew;
|
||||
}
|
||||
next = cur->next;
|
||||
cur->next = NULL;
|
||||
}
|
||||
@@ -292,12 +264,9 @@ pool_free_old(alloc_pool_t p, void *addr)
|
||||
|
||||
while ((cur = next) != NULL) {
|
||||
next = cur->next;
|
||||
if (pool->flags & POOL_PREPEND)
|
||||
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
|
||||
else {
|
||||
free(cur->start);
|
||||
free(cur->start);
|
||||
if (!(pool->flags & POOL_APPEND))
|
||||
free(cur);
|
||||
}
|
||||
pool->e_freed++;
|
||||
}
|
||||
}
|
||||
@@ -344,7 +313,7 @@ int
|
||||
pool_stats(alloc_pool_t p, int fd, int summarize)
|
||||
{
|
||||
struct alloc_pool *pool = (struct alloc_pool *) p;
|
||||
struct pool_extent *cur;
|
||||
struct pool_extent *cur;
|
||||
char buf[BUFSIZ];
|
||||
int ret = 0;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#define POOL_CLEAR (1<<0) /* zero fill allocations */
|
||||
#define POOL_NO_QALIGN (1<<1) /* don't align data to quanta */
|
||||
#define POOL_QALIGN (1<<1) /* align data to quanta */
|
||||
#define POOL_INTERN (1<<2) /* Allocate extent structures */
|
||||
#define POOL_PREPEND (1<<3) /* or prepend to extent data */
|
||||
#define POOL_APPEND (1<<3) /* or appended to extent data */
|
||||
|
||||
typedef void *alloc_pool_t;
|
||||
|
||||
|
||||
921
lib/snprintf.c
921
lib/snprintf.c
File diff suppressed because it is too large
Load Diff
144
lib/sysxattrs.c
144
lib/sysxattrs.c
@@ -126,150 +126,6 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size)
|
||||
return len;
|
||||
}
|
||||
|
||||
#elif HAVE_SOLARIS_XATTRS
|
||||
|
||||
static ssize_t read_xattr(int attrfd, void *buf, size_t buflen)
|
||||
{
|
||||
STRUCT_STAT sb;
|
||||
ssize_t ret;
|
||||
|
||||
if (fstat(attrfd, &sb) < 0)
|
||||
ret = -1;
|
||||
else if (sb.st_size > SSIZE_MAX) {
|
||||
errno = ERANGE;
|
||||
ret = -1;
|
||||
} else if (buflen == 0)
|
||||
ret = sb.st_size;
|
||||
else if (sb.st_size > buflen) {
|
||||
errno = ERANGE;
|
||||
ret = -1;
|
||||
} else {
|
||||
size_t bufpos;
|
||||
for (bufpos = 0; bufpos < sb.st_size; ) {
|
||||
ssize_t cnt = read(attrfd, buf + bufpos, sb.st_size - bufpos);
|
||||
if (cnt <= 0) {
|
||||
if (cnt < 0 && errno == EINTR)
|
||||
continue;
|
||||
bufpos = -1;
|
||||
break;
|
||||
}
|
||||
bufpos += cnt;
|
||||
}
|
||||
ret = bufpos;
|
||||
}
|
||||
|
||||
close(attrfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
|
||||
{
|
||||
int attrfd;
|
||||
|
||||
if ((attrfd = attropen(path, name, O_RDONLY)) < 0) {
|
||||
errno = ENOATTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read_xattr(attrfd, value, size);
|
||||
}
|
||||
|
||||
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
|
||||
{
|
||||
int attrfd;
|
||||
|
||||
if ((attrfd = openat(filedes, name, O_RDONLY|O_XATTR, 0)) < 0) {
|
||||
errno = ENOATTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read_xattr(attrfd, value, size);
|
||||
}
|
||||
|
||||
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
|
||||
{
|
||||
int attrfd;
|
||||
size_t bufpos;
|
||||
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
|
||||
|
||||
if ((attrfd = attropen(path, name, O_CREAT|O_TRUNC|O_WRONLY, mode)) < 0)
|
||||
return -1;
|
||||
|
||||
for (bufpos = 0; bufpos < size; ) {
|
||||
ssize_t cnt = write(attrfd, value+bufpos, size);
|
||||
if (cnt <= 0) {
|
||||
if (cnt < 0 && errno == EINTR)
|
||||
continue;
|
||||
bufpos = -1;
|
||||
break;
|
||||
}
|
||||
bufpos += cnt;
|
||||
}
|
||||
|
||||
close(attrfd);
|
||||
|
||||
return bufpos > 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
int sys_lremovexattr(const char *path, const char *name)
|
||||
{
|
||||
int attrdirfd;
|
||||
int ret;
|
||||
|
||||
if ((attrdirfd = attropen(path, ".", O_RDONLY)) < 0)
|
||||
return -1;
|
||||
|
||||
ret = unlinkat(attrdirfd, name, 0);
|
||||
|
||||
close(attrdirfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
|
||||
{
|
||||
int attrdirfd;
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
ssize_t ret = 0;
|
||||
|
||||
if ((attrdirfd = attropen(path, ".", O_RDONLY)) < 0) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((dirp = fdopendir(attrdirfd)) == NULL) {
|
||||
close(attrdirfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((dp = readdir(dirp))) {
|
||||
int len = strlen(dp->d_name);
|
||||
|
||||
if (dp->d_name[0] == '.' && (len == 1 || (len == 2 && dp->d_name[1] == '.')))
|
||||
continue;
|
||||
if (len == 11 && dp->d_name[0] == 'S' && strncmp(dp->d_name, "SUNWattr_r", 10) == 0
|
||||
&& (dp->d_name[10] == 'o' || dp->d_name[10] == 'w'))
|
||||
continue;
|
||||
|
||||
if ((ret += len+1) > size) {
|
||||
if (size == 0)
|
||||
continue;
|
||||
ret = -1;
|
||||
errno = ERANGE;
|
||||
break;
|
||||
}
|
||||
memcpy(list, dp->d_name, len+1);
|
||||
list += len+1;
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
close(attrdirfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error You need to create xattr compatibility functions.
|
||||
|
||||
1014
loadparm.c
1014
loadparm.c
File diff suppressed because it is too large
Load Diff
190
log.c
190
log.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2000-2001 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,9 +20,9 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#include "inums.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int am_daemon;
|
||||
extern int am_server;
|
||||
@@ -31,19 +31,16 @@ extern int am_generator;
|
||||
extern int local_server;
|
||||
extern int quiet;
|
||||
extern int module_id;
|
||||
extern int checksum_len;
|
||||
extern int msg_fd_out;
|
||||
extern int allow_8bit_chars;
|
||||
extern int protocol_version;
|
||||
extern int always_checksum;
|
||||
extern int preserve_times;
|
||||
extern int msgs2stderr;
|
||||
extern int progress_is_active;
|
||||
extern int stdout_format_has_i;
|
||||
extern int stdout_format_has_o_or_i;
|
||||
extern int logfile_format_has_i;
|
||||
extern int logfile_format_has_o_or_i;
|
||||
extern int receiver_symlink_times;
|
||||
extern int64 total_data_written;
|
||||
extern int64 total_data_read;
|
||||
extern mode_t orig_umask;
|
||||
extern char *auth_user;
|
||||
extern char *stdout_format;
|
||||
@@ -58,8 +55,6 @@ extern iconv_t ic_recv;
|
||||
extern char curr_dir[MAXPATHLEN];
|
||||
extern char *full_module_path;
|
||||
extern unsigned int module_dirlen;
|
||||
extern char sender_file_sum[MAX_DIGEST_LEN];
|
||||
extern const char undetermined_hostname[];
|
||||
|
||||
static int log_initialised;
|
||||
static int logfile_was_closed;
|
||||
@@ -67,11 +62,6 @@ static FILE *logfile_fp;
|
||||
struct stats stats;
|
||||
|
||||
int got_xfer_error = 0;
|
||||
int output_needs_newline = 0;
|
||||
int send_msgs_to_gen = 0;
|
||||
|
||||
static int64 initial_data_written;
|
||||
static int64 initial_data_read;
|
||||
|
||||
struct {
|
||||
int code;
|
||||
@@ -95,13 +85,13 @@ struct {
|
||||
{ RERR_MALLOC , "error allocating core memory buffers" },
|
||||
{ RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" },
|
||||
{ RERR_VANISHED , "some files vanished before they could be transferred" },
|
||||
{ RERR_DEL_LIMIT , "the --max-delete limit stopped deletions" },
|
||||
{ RERR_TIMEOUT , "timeout in data send/receive" },
|
||||
{ RERR_CONTIMEOUT , "timeout waiting for daemon connection" },
|
||||
{ RERR_CMD_FAILED , "remote shell failed" },
|
||||
{ RERR_CMD_KILLED , "remote shell killed" },
|
||||
{ RERR_CMD_RUN , "remote command could not be run" },
|
||||
{ RERR_CMD_NOTFOUND,"remote command not found" },
|
||||
{ RERR_DEL_LIMIT , "the --max-delete limit stopped deletions" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
@@ -123,7 +113,8 @@ static void logit(int priority, const char *buf)
|
||||
if (logfile_was_closed)
|
||||
logfile_reopen();
|
||||
if (logfile_fp) {
|
||||
fprintf(logfile_fp, "%s [%d] %s", timestring(time(NULL)), (int)getpid(), buf);
|
||||
fprintf(logfile_fp, "%s [%d] %s",
|
||||
timestring(time(NULL)), (int)getpid(), buf);
|
||||
fflush(logfile_fp);
|
||||
} else {
|
||||
syslog(priority, "%s", buf);
|
||||
@@ -250,7 +241,7 @@ static void filtered_fwrite(FILE *f, const char *buf, int len, int use_isprint)
|
||||
void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||
{
|
||||
int trailing_CR_or_NL;
|
||||
FILE *f = msgs2stderr ? stderr : stdout;
|
||||
FILE *f = NULL;
|
||||
#ifdef ICONV_OPTION
|
||||
iconv_t ic = is_utf8 && ic_recv != (iconv_t)-1 ? ic_recv : ic_chck;
|
||||
#else
|
||||
@@ -262,16 +253,7 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||
if (len < 0)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
|
||||
if (msgs2stderr) {
|
||||
if (!am_daemon) {
|
||||
if (code == FLOG)
|
||||
return;
|
||||
goto output_msg;
|
||||
}
|
||||
if (code == FCLIENT)
|
||||
return;
|
||||
code = FLOG;
|
||||
} else if (send_msgs_to_gen) {
|
||||
if (am_server && msg_fd_out >= 0) {
|
||||
assert(!is_utf8);
|
||||
/* Pass the message to our sibling in native charset. */
|
||||
send_msg((enum msgcode)code, buf, len, 0);
|
||||
@@ -324,43 +306,31 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
|
||||
/* TODO: can we send the error to the user somehow? */
|
||||
return;
|
||||
}
|
||||
f = stderr;
|
||||
}
|
||||
|
||||
output_msg:
|
||||
switch (code) {
|
||||
case FERROR_XFER:
|
||||
got_xfer_error = 1;
|
||||
/* FALL THROUGH */
|
||||
case FERROR:
|
||||
case FERROR_UTF8:
|
||||
case FERROR_SOCKET:
|
||||
case FWARNING:
|
||||
f = stderr;
|
||||
break;
|
||||
case FLOG:
|
||||
case FINFO:
|
||||
case FCLIENT:
|
||||
f = am_server ? stderr : stdout;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown logcode in rwrite(): %d [%s]\n", (int)code, who_am_i());
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
|
||||
if (output_needs_newline) {
|
||||
if (progress_is_active && !am_server) {
|
||||
fputc('\n', f);
|
||||
output_needs_newline = 0;
|
||||
progress_is_active = 0;
|
||||
}
|
||||
|
||||
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
|
||||
? buf[--len] : 0;
|
||||
|
||||
if (len && buf[0] == '\r') {
|
||||
fputc('\r', f);
|
||||
buf++;
|
||||
len--;
|
||||
}
|
||||
|
||||
#ifdef ICONV_CONST
|
||||
if (ic != (iconv_t)-1) {
|
||||
xbuf outbuf, inbuf;
|
||||
@@ -368,10 +338,10 @@ output_msg:
|
||||
int ierrno;
|
||||
|
||||
INIT_CONST_XBUF(outbuf, convbuf);
|
||||
INIT_XBUF(inbuf, (char*)buf, len, (size_t)-1);
|
||||
INIT_XBUF(inbuf, (char*)buf, len, -1);
|
||||
|
||||
while (inbuf.len) {
|
||||
iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT);
|
||||
iconvbufs(ic, &inbuf, &outbuf, 0);
|
||||
ierrno = errno;
|
||||
if (outbuf.len) {
|
||||
filtered_fwrite(f, convbuf, outbuf.len, 0);
|
||||
@@ -466,12 +436,12 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
|
||||
|
||||
void rflush(enum logcode code)
|
||||
{
|
||||
FILE *f;
|
||||
FILE *f = NULL;
|
||||
|
||||
if (am_daemon || code == FLOG)
|
||||
return;
|
||||
|
||||
if (!am_server && (code == FINFO || code == FCLIENT))
|
||||
if (code == FINFO && !am_server)
|
||||
f = stdout;
|
||||
else
|
||||
f = stderr;
|
||||
@@ -479,15 +449,10 @@ void rflush(enum logcode code)
|
||||
fflush(f);
|
||||
}
|
||||
|
||||
void remember_initial_stats(void)
|
||||
{
|
||||
initial_data_read = total_data_read;
|
||||
initial_data_written = total_data_written;
|
||||
}
|
||||
|
||||
/* A generic logging routine for send/recv, with parameter substitiution. */
|
||||
static void log_formatted(enum logcode code, const char *format, const char *op,
|
||||
struct file_struct *file, const char *fname, int iflags,
|
||||
struct file_struct *file, const char *fname,
|
||||
struct stats *initial_stats, int iflags,
|
||||
const char *hlink)
|
||||
{
|
||||
char buf[MAXPATHLEN+1024], buf2[MAXPATHLEN], fmt[32];
|
||||
@@ -510,45 +475,30 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
|
||||
buf[total] = '\0';
|
||||
|
||||
for (p = buf; (p = strchr(p, '%')) != NULL; ) {
|
||||
int humanize = 0;
|
||||
s = p++;
|
||||
c = fmt + 1;
|
||||
while (*p == '\'') {
|
||||
humanize++;
|
||||
p++;
|
||||
}
|
||||
if (*p == '-')
|
||||
*c++ = *p++;
|
||||
while (isDigit(p) && c - fmt < (int)(sizeof fmt) - 8)
|
||||
*c++ = *p++;
|
||||
while (*p == '\'') {
|
||||
humanize++;
|
||||
p++;
|
||||
}
|
||||
if (!*p)
|
||||
break;
|
||||
*c = '\0';
|
||||
n = NULL;
|
||||
|
||||
/* Note for %h and %a: it doesn't matter what fd we pass to
|
||||
* client_{name,addr} because rsync_module will already have
|
||||
* forced the answer to be cached (assuming, of course, for %h
|
||||
* that lp_reverse_lookup(module_id) is true). */
|
||||
switch (*p) {
|
||||
case 'h':
|
||||
if (am_daemon) {
|
||||
n = lp_reverse_lookup(module_id)
|
||||
? client_name(0) : undetermined_hostname;
|
||||
}
|
||||
if (am_daemon)
|
||||
n = client_name(0);
|
||||
break;
|
||||
case 'a':
|
||||
if (am_daemon)
|
||||
n = client_addr(0);
|
||||
break;
|
||||
case 'l':
|
||||
strlcat(fmt, "s", sizeof fmt);
|
||||
strlcat(fmt, ".0f", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt,
|
||||
do_big_num(F_LENGTH(file), humanize, NULL));
|
||||
(double)F_LENGTH(file));
|
||||
n = buf2;
|
||||
break;
|
||||
case 'U':
|
||||
@@ -568,8 +518,9 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
strlcat(fmt, "d", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt, (int)getpid());
|
||||
strlcat(fmt, "ld", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt,
|
||||
(long)getpid());
|
||||
n = buf2;
|
||||
break;
|
||||
case 'M':
|
||||
@@ -656,41 +607,28 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
|
||||
n = auth_user;
|
||||
break;
|
||||
case 'b':
|
||||
if (!(iflags & ITEM_TRANSFER))
|
||||
b = 0;
|
||||
else if (am_sender)
|
||||
b = total_data_written - initial_data_written;
|
||||
else
|
||||
b = total_data_read - initial_data_read;
|
||||
strlcat(fmt, "s", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt,
|
||||
do_big_num(b, humanize, NULL));
|
||||
if (am_sender) {
|
||||
b = stats.total_written -
|
||||
initial_stats->total_written;
|
||||
} else {
|
||||
b = stats.total_read -
|
||||
initial_stats->total_read;
|
||||
}
|
||||
strlcat(fmt, ".0f", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt, (double)b);
|
||||
n = buf2;
|
||||
break;
|
||||
case 'c':
|
||||
if (!(iflags & ITEM_TRANSFER))
|
||||
b = 0;
|
||||
else if (!am_sender)
|
||||
b = total_data_written - initial_data_written;
|
||||
else
|
||||
b = total_data_read - initial_data_read;
|
||||
strlcat(fmt, "s", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt,
|
||||
do_big_num(b, humanize, NULL));
|
||||
n = buf2;
|
||||
break;
|
||||
case 'C':
|
||||
if (protocol_version >= 30
|
||||
&& (iflags & ITEM_TRANSFER
|
||||
|| (always_checksum && S_ISREG(file->mode)))) {
|
||||
const char *sum = iflags & ITEM_TRANSFER
|
||||
? sender_file_sum : F_SUM(file);
|
||||
n = sum_as_hex(sum);
|
||||
if (!am_sender) {
|
||||
b = stats.total_written -
|
||||
initial_stats->total_written;
|
||||
} else {
|
||||
memset(buf2, ' ', checksum_len*2);
|
||||
buf2[checksum_len*2] = '\0';
|
||||
n = buf2;
|
||||
b = stats.total_read -
|
||||
initial_stats->total_read;
|
||||
}
|
||||
strlcat(fmt, ".0f", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt, (double)b);
|
||||
n = buf2;
|
||||
break;
|
||||
case 'i':
|
||||
if (iflags & ITEM_DELETED) {
|
||||
@@ -790,12 +728,10 @@ int log_format_has(const char *format, char esc)
|
||||
return 0;
|
||||
|
||||
for (p = format; (p = strchr(p, '%')) != NULL; ) {
|
||||
for (p++; *p == '\''; p++) {} /*SHARED ITERATOR*/
|
||||
if (*p == '-')
|
||||
if (*++p == '-')
|
||||
p++;
|
||||
while (isDigit(p))
|
||||
p++;
|
||||
while (*p == '\'') p++;
|
||||
if (!*p)
|
||||
break;
|
||||
if (*p == esc)
|
||||
@@ -807,14 +743,19 @@ int log_format_has(const char *format, char esc)
|
||||
/* Log the transfer of a file. If the code is FCLIENT, the output just goes
|
||||
* to stdout. If it is FLOG, it just goes to the log file. Otherwise we
|
||||
* output to both. */
|
||||
void log_item(enum logcode code, struct file_struct *file, int iflags, const char *hlink)
|
||||
void log_item(enum logcode code, struct file_struct *file,
|
||||
struct stats *initial_stats, int iflags, const char *hlink)
|
||||
{
|
||||
const char *s_or_r = am_sender ? "send" : "recv";
|
||||
|
||||
if (code != FLOG && stdout_format && !am_server)
|
||||
log_formatted(FCLIENT, stdout_format, s_or_r, file, NULL, iflags, hlink);
|
||||
if (code != FCLIENT && logfile_format && *logfile_format)
|
||||
log_formatted(FLOG, logfile_format, s_or_r, file, NULL, iflags, hlink);
|
||||
if (code != FLOG && stdout_format && !am_server) {
|
||||
log_formatted(FCLIENT, stdout_format, s_or_r,
|
||||
file, NULL, initial_stats, iflags, hlink);
|
||||
}
|
||||
if (code != FCLIENT && logfile_format && *logfile_format) {
|
||||
log_formatted(FLOG, logfile_format, s_or_r,
|
||||
file, NULL, initial_stats, iflags, hlink);
|
||||
}
|
||||
}
|
||||
|
||||
void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
|
||||
@@ -822,16 +763,16 @@ void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
|
||||
{
|
||||
int significant_flags = iflags & SIGNIFICANT_ITEM_FLAGS;
|
||||
int see_item = itemizing && (significant_flags || *buf
|
||||
|| stdout_format_has_i > 1 || (INFO_GTE(NAME, 2) && stdout_format_has_i));
|
||||
|| stdout_format_has_i > 1 || (verbose > 1 && stdout_format_has_i));
|
||||
int local_change = iflags & ITEM_LOCAL_CHANGE && significant_flags;
|
||||
if (am_server) {
|
||||
if (logfile_name && !dry_run && see_item
|
||||
&& (significant_flags || logfile_format_has_i))
|
||||
log_item(FLOG, file, iflags, buf);
|
||||
log_item(FLOG, file, &stats, iflags, buf);
|
||||
} else if (see_item || local_change || *buf
|
||||
|| (S_ISDIR(file->mode) && significant_flags)) {
|
||||
enum logcode code = significant_flags || logfile_format_has_i ? FINFO : FCLIENT;
|
||||
log_item(code, file, iflags, buf);
|
||||
log_item(code, file, &stats, iflags, buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -840,13 +781,13 @@ void log_delete(const char *fname, int mode)
|
||||
static struct {
|
||||
union file_extras ex[4]; /* just in case... */
|
||||
struct file_struct file;
|
||||
} x; /* Zero-initialized due to static declaration. */
|
||||
} x;
|
||||
int len = strlen(fname);
|
||||
const char *fmt;
|
||||
|
||||
x.file.mode = mode;
|
||||
|
||||
if (!INFO_GTE(DEL, 1) && !stdout_format)
|
||||
if (!verbose && !stdout_format)
|
||||
;
|
||||
else if (am_server && protocol_version >= 29 && len < MAXPATHLEN) {
|
||||
if (S_ISDIR(mode))
|
||||
@@ -854,14 +795,15 @@ void log_delete(const char *fname, int mode)
|
||||
send_msg(MSG_DELETED, fname, len, am_generator);
|
||||
} else {
|
||||
fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n";
|
||||
log_formatted(FCLIENT, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
|
||||
log_formatted(FCLIENT, fmt, "del.", &x.file, fname, &stats,
|
||||
ITEM_DELETED, NULL);
|
||||
}
|
||||
|
||||
if (!logfile_name || dry_run || !logfile_format)
|
||||
return;
|
||||
|
||||
fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n";
|
||||
log_formatted(FLOG, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL);
|
||||
log_formatted(FLOG, fmt, "del.", &x.file, fname, &stats, ITEM_DELETED, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -873,10 +815,10 @@ void log_delete(const char *fname, int mode)
|
||||
void log_exit(int code, const char *file, int line)
|
||||
{
|
||||
if (code == 0) {
|
||||
rprintf(FLOG,"sent %s bytes received %s bytes total size %s\n",
|
||||
comma_num(stats.total_written),
|
||||
comma_num(stats.total_read),
|
||||
comma_num(stats.total_size));
|
||||
rprintf(FLOG,"sent %.0f bytes received %.0f bytes total size %.0f\n",
|
||||
(double)stats.total_written,
|
||||
(double)stats.total_read,
|
||||
(double)stats.total_size);
|
||||
} else if (am_server != 2) {
|
||||
const char *name;
|
||||
|
||||
|
||||
353
main.c
353
main.c
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -21,30 +21,27 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
#include "ifuncs.h"
|
||||
#include "io.h"
|
||||
#if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int list_only;
|
||||
extern int io_timeout;
|
||||
extern int am_root;
|
||||
extern int am_server;
|
||||
extern int am_sender;
|
||||
extern int am_daemon;
|
||||
extern int inc_recurse;
|
||||
extern int blocking_io;
|
||||
extern int always_checksum;
|
||||
extern int remove_source_files;
|
||||
extern int output_needs_newline;
|
||||
extern int need_messages_from_generator;
|
||||
extern int kluge_around_eof;
|
||||
extern int do_stats;
|
||||
extern int got_xfer_error;
|
||||
extern int msgs2stderr;
|
||||
extern int module_id;
|
||||
extern int read_only;
|
||||
extern int copy_links;
|
||||
extern int copy_dirlinks;
|
||||
extern int copy_unsafe_links;
|
||||
@@ -65,44 +62,31 @@ extern int whole_file;
|
||||
extern int read_batch;
|
||||
extern int write_batch;
|
||||
extern int batch_fd;
|
||||
extern int sock_f_in;
|
||||
extern int sock_f_out;
|
||||
extern int filesfrom_fd;
|
||||
extern int connect_timeout;
|
||||
extern int send_msgs_to_gen;
|
||||
extern dev_t filesystem_dev;
|
||||
extern pid_t cleanup_child_pid;
|
||||
extern size_t bwlimit_writemax;
|
||||
extern unsigned int module_dirlen;
|
||||
extern BOOL flist_receiving_enabled;
|
||||
extern BOOL shutting_down;
|
||||
extern int basis_dir_cnt;
|
||||
extern struct stats stats;
|
||||
extern char *stdout_format;
|
||||
extern char *logfile_format;
|
||||
extern char *filesfrom_host;
|
||||
extern char *partial_dir;
|
||||
extern char *dest_option;
|
||||
extern char *basis_dir[MAX_BASIS_DIRS+1];
|
||||
extern char *rsync_path;
|
||||
extern char *shell_cmd;
|
||||
extern char *batch_name;
|
||||
extern char *password_file;
|
||||
extern char *backup_dir;
|
||||
extern char curr_dir[MAXPATHLEN];
|
||||
extern char backup_dir_buf[MAXPATHLEN];
|
||||
extern char *basis_dir[MAX_BASIS_DIRS+1];
|
||||
extern struct file_list *first_flist;
|
||||
extern filter_rule_list daemon_filter_list;
|
||||
extern struct filter_list_struct daemon_filter_list;
|
||||
|
||||
uid_t our_uid;
|
||||
gid_t our_gid;
|
||||
int am_receiver = 0; /* Only set to 1 after the receiver/generator fork. */
|
||||
int am_generator = 0; /* Only set to 1 after the receiver/generator fork. */
|
||||
int local_server = 0;
|
||||
int daemon_over_rsh = 0;
|
||||
mode_t orig_umask = 0;
|
||||
int batch_gen_fd = -1;
|
||||
int sender_keeps_checksum = 0;
|
||||
|
||||
/* There's probably never more than at most 2 outstanding child processes,
|
||||
* but set it higher, just in case. */
|
||||
@@ -132,7 +116,7 @@ static void show_malloc_stats(void);
|
||||
pid_t wait_process(pid_t pid, int *status_ptr, int flags)
|
||||
{
|
||||
pid_t waited_pid;
|
||||
|
||||
|
||||
do {
|
||||
waited_pid = waitpid(pid, status_ptr, flags);
|
||||
} while (waited_pid == -1 && errno == EINTR);
|
||||
@@ -185,30 +169,6 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
|
||||
*exit_code_ptr = WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
void write_del_stats(int f)
|
||||
{
|
||||
if (read_batch)
|
||||
write_int(f, NDX_DEL_STATS);
|
||||
else
|
||||
write_ndx(f, NDX_DEL_STATS);
|
||||
write_varint(f, stats.deleted_files - stats.deleted_dirs
|
||||
- stats.deleted_symlinks - stats.deleted_devices
|
||||
- stats.deleted_specials);
|
||||
write_varint(f, stats.deleted_dirs);
|
||||
write_varint(f, stats.deleted_symlinks);
|
||||
write_varint(f, stats.deleted_devices);
|
||||
write_varint(f, stats.deleted_specials);
|
||||
}
|
||||
|
||||
void read_del_stats(int f)
|
||||
{
|
||||
stats.deleted_files = read_varint(f);
|
||||
stats.deleted_files += stats.deleted_dirs = read_varint(f);
|
||||
stats.deleted_files += stats.deleted_symlinks = read_varint(f);
|
||||
stats.deleted_files += stats.deleted_devices = read_varint(f);
|
||||
stats.deleted_files += stats.deleted_specials = read_varint(f);
|
||||
}
|
||||
|
||||
/* This function gets called from all 3 processes. We want the client side
|
||||
* to actually output the text, but the sender is the only process that has
|
||||
* all the stats we need. So, if we're a client sender, we do the report.
|
||||
@@ -225,7 +185,7 @@ static void handle_stats(int f)
|
||||
total_read = stats.total_read;
|
||||
total_written = stats.total_written;
|
||||
|
||||
if (INFO_GTE(STATS, 3)) {
|
||||
if (do_stats && verbose > 1) {
|
||||
/* These come out from every process */
|
||||
show_malloc_stats();
|
||||
show_flist_stats();
|
||||
@@ -279,39 +239,13 @@ static void handle_stats(int f)
|
||||
}
|
||||
}
|
||||
|
||||
static void output_itemized_counts(const char *prefix, int *counts)
|
||||
{
|
||||
static char *labels[] = { "reg", "dir", "link", "dev", "special" };
|
||||
char buf[1024], *pre = " (";
|
||||
int j, len = 0;
|
||||
int total = counts[0];
|
||||
if (total) {
|
||||
counts[0] -= counts[1] + counts[2] + counts[3] + counts[4];
|
||||
for (j = 0; j < 5; j++) {
|
||||
if (counts[j]) {
|
||||
len += snprintf(buf+len, sizeof buf - len - 2,
|
||||
"%s%s: %s",
|
||||
pre, labels[j], comma_num(counts[j]));
|
||||
pre = ", ";
|
||||
}
|
||||
}
|
||||
buf[len++] = ')';
|
||||
}
|
||||
buf[len] = '\0';
|
||||
rprintf(FINFO, "%s: %s%s\n", prefix, comma_num(total), buf);
|
||||
}
|
||||
|
||||
static void output_summary(void)
|
||||
{
|
||||
if (INFO_GTE(STATS, 2)) {
|
||||
if (do_stats) {
|
||||
rprintf(FCLIENT, "\n");
|
||||
output_itemized_counts("Number of files", &stats.num_files);
|
||||
if (protocol_version >= 29)
|
||||
output_itemized_counts("Number of created files", &stats.created_files);
|
||||
if (protocol_version >= 31)
|
||||
output_itemized_counts("Number of deleted files", &stats.deleted_files);
|
||||
rprintf(FINFO,"Number of regular files transferred: %s\n",
|
||||
comma_num(stats.xferred_files));
|
||||
rprintf(FINFO,"Number of files: %d\n", stats.num_files);
|
||||
rprintf(FINFO,"Number of files transferred: %d\n",
|
||||
stats.num_transferred_files);
|
||||
rprintf(FINFO,"Total file size: %s bytes\n",
|
||||
human_num(stats.total_size));
|
||||
rprintf(FINFO,"Total transferred file size: %s bytes\n",
|
||||
@@ -324,11 +258,11 @@ static void output_summary(void)
|
||||
human_num(stats.flist_size));
|
||||
if (stats.flist_buildtime) {
|
||||
rprintf(FINFO,
|
||||
"File list generation time: %s seconds\n",
|
||||
comma_dnum((double)stats.flist_buildtime / 1000, 3));
|
||||
"File list generation time: %.3f seconds\n",
|
||||
(double)stats.flist_buildtime / 1000);
|
||||
rprintf(FINFO,
|
||||
"File list transfer time: %s seconds\n",
|
||||
comma_dnum((double)stats.flist_xfertime / 1000, 3));
|
||||
"File list transfer time: %.3f seconds\n",
|
||||
(double)stats.flist_xfertime / 1000);
|
||||
}
|
||||
rprintf(FINFO,"Total bytes sent: %s\n",
|
||||
human_num(total_written));
|
||||
@@ -336,15 +270,15 @@ static void output_summary(void)
|
||||
human_num(total_read));
|
||||
}
|
||||
|
||||
if (INFO_GTE(STATS, 1)) {
|
||||
if (verbose || do_stats) {
|
||||
rprintf(FCLIENT, "\n");
|
||||
rprintf(FINFO,
|
||||
"sent %s bytes received %s bytes %s bytes/sec\n",
|
||||
human_num(total_written), human_num(total_read),
|
||||
human_dnum((total_written + total_read)/(0.5 + (endtime - starttime)), 2));
|
||||
rprintf(FINFO, "total size is %s speedup is %s%s\n",
|
||||
rprintf(FINFO, "total size is %s speedup is %.2f%s\n",
|
||||
human_num(stats.total_size),
|
||||
comma_dnum((double)stats.total_size / (total_written+total_read), 2),
|
||||
(double)stats.total_size / (total_written+total_read),
|
||||
write_batch < 0 ? " (BATCH ONLY)" : dry_run ? " (DRY RUN)" : "");
|
||||
}
|
||||
|
||||
@@ -365,7 +299,7 @@ static void show_malloc_stats(void)
|
||||
|
||||
rprintf(FCLIENT, "\n");
|
||||
rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
|
||||
(int)getpid(), am_server ? "server " : "",
|
||||
getpid(), am_server ? "server " : "",
|
||||
am_daemon ? "daemon " : "", who_am_i());
|
||||
rprintf(FINFO, " arena: %10ld (bytes from sbrk)\n",
|
||||
(long)mi.arena);
|
||||
@@ -398,7 +332,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
int *f_in_p, int *f_out_p)
|
||||
{
|
||||
int i, argc = 0;
|
||||
char *args[MAX_ARGS], *need_to_free = NULL;
|
||||
char *args[MAX_ARGS];
|
||||
pid_t pid;
|
||||
int dash_l_set = 0;
|
||||
|
||||
@@ -409,7 +343,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
cmd = rsh_env;
|
||||
if (!cmd)
|
||||
cmd = RSYNC_RSH;
|
||||
cmd = need_to_free = strdup(cmd);
|
||||
cmd = strdup(cmd); /* MEMORY LEAK */
|
||||
if (!cmd)
|
||||
goto oom;
|
||||
|
||||
@@ -506,7 +440,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
|
||||
args[argc] = NULL;
|
||||
|
||||
if (DEBUG_GTE(CMD, 2)) {
|
||||
if (verbose > 3) {
|
||||
for (i = 0; i < argc; i++)
|
||||
rprintf(FCLIENT, "cmd[%d]=%s ", i, args[i]);
|
||||
rprintf(FCLIENT, "\n");
|
||||
@@ -545,9 +479,6 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
|
||||
send_protected_args(*f_out_p, args);
|
||||
}
|
||||
|
||||
if (need_to_free)
|
||||
free(need_to_free);
|
||||
|
||||
return pid;
|
||||
|
||||
oom:
|
||||
@@ -574,7 +505,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
int statret;
|
||||
char *cp;
|
||||
|
||||
if (DEBUG_GTE(RECV, 1)) {
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "get_local_name count=%d %s\n",
|
||||
file_total, NS(dest_path));
|
||||
}
|
||||
@@ -595,7 +526,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
if ((*dest_path != '.' || dest_path[1] != '\0')
|
||||
&& (check_filter(&daemon_filter_list, FLOG, dest_path, 0) < 0
|
||||
|| check_filter(&daemon_filter_list, FLOG, dest_path, 1) < 0)) {
|
||||
rprintf(FERROR, "ERROR: daemon has excluded destination \"%s\"\n",
|
||||
rprintf(FERROR, "skipping daemon-excluded destination \"%s\"\n",
|
||||
dest_path);
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
@@ -650,7 +581,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
if (do_mkdir(dest_path, ACCESSPERMS) != 0) {
|
||||
if (mkdir_defmode(dest_path) != 0) {
|
||||
rsyserr(FERROR, errno, "mkdir %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
@@ -660,7 +591,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
&& strcmp(flist->files[flist->low]->basename, ".") == 0)
|
||||
flist->files[0]->flags |= FLAG_DIR_CREATED;
|
||||
|
||||
if (INFO_GTE(NAME, 1))
|
||||
if (verbose)
|
||||
rprintf(FINFO, "created directory %s\n", dest_path);
|
||||
|
||||
if (dry_run) {
|
||||
@@ -706,63 +637,48 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
static void check_alt_basis_dirs(void)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
char *slash = strrchr(curr_dir, '/');
|
||||
int j;
|
||||
char **dir_p, *slash = strrchr(curr_dir, '/');
|
||||
|
||||
for (j = 0; j < basis_dir_cnt; j++) {
|
||||
char *bdir = basis_dir[j];
|
||||
int bd_len = strlen(bdir);
|
||||
if (bd_len > 1 && bdir[bd_len-1] == '/')
|
||||
bdir[--bd_len] = '\0';
|
||||
if (dry_run > 1 && *bdir != '/') {
|
||||
int len = curr_dir_len + 1 + bd_len + 1;
|
||||
for (dir_p = basis_dir; *dir_p; dir_p++) {
|
||||
if (dry_run > 1 && **dir_p != '/') {
|
||||
int len = curr_dir_len + 1 + strlen(*dir_p) + 1;
|
||||
char *new = new_array(char, len);
|
||||
if (!new)
|
||||
out_of_memory("check_alt_basis_dirs");
|
||||
if (slash && strncmp(bdir, "../", 3) == 0) {
|
||||
if (slash && strncmp(*dir_p, "../", 3) == 0) {
|
||||
/* We want to remove only one leading "../" prefix for
|
||||
* the directory we couldn't create in dry-run mode:
|
||||
* this ensures that any other ".." references get
|
||||
* evaluated the same as they would for a live copy. */
|
||||
*slash = '\0';
|
||||
pathjoin(new, len, curr_dir, bdir + 3);
|
||||
pathjoin(new, len, curr_dir, *dir_p + 3);
|
||||
*slash = '/';
|
||||
} else
|
||||
pathjoin(new, len, curr_dir, bdir);
|
||||
basis_dir[j] = bdir = new;
|
||||
pathjoin(new, len, curr_dir, *dir_p);
|
||||
*dir_p = new;
|
||||
}
|
||||
if (do_stat(*dir_p, &st) < 0) {
|
||||
rprintf(FWARNING, "%s arg does not exist: %s\n",
|
||||
dest_option, *dir_p);
|
||||
} else if (!S_ISDIR(st.st_mode)) {
|
||||
rprintf(FWARNING, "%s arg is not a dir: %s\n",
|
||||
dest_option, *dir_p);
|
||||
}
|
||||
if (do_stat(bdir, &st) < 0)
|
||||
rprintf(FWARNING, "%s arg does not exist: %s\n", dest_option, bdir);
|
||||
else if (!S_ISDIR(st.st_mode))
|
||||
rprintf(FWARNING, "%s arg is not a dir: %s\n", dest_option, bdir);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is only called by the sender. */
|
||||
static void read_final_goodbye(int f_in, int f_out)
|
||||
static void read_final_goodbye(int f_in)
|
||||
{
|
||||
int i, iflags, xlen;
|
||||
uchar fnamecmp_type;
|
||||
char xname[MAXPATHLEN];
|
||||
|
||||
shutting_down = True;
|
||||
|
||||
if (protocol_version < 29)
|
||||
i = read_int(f_in);
|
||||
else {
|
||||
i = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type, xname, &xlen);
|
||||
if (protocol_version >= 31 && i == NDX_DONE) {
|
||||
if (am_sender)
|
||||
write_ndx(f_out, NDX_DONE);
|
||||
else {
|
||||
if (batch_gen_fd >= 0) {
|
||||
while (read_int(batch_gen_fd) != NDX_DEL_STATS) {}
|
||||
read_del_stats(batch_gen_fd);
|
||||
}
|
||||
write_int(f_out, NDX_DONE);
|
||||
}
|
||||
i = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type, xname, &xlen);
|
||||
}
|
||||
i = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
|
||||
xname, &xlen);
|
||||
}
|
||||
|
||||
if (i != NDX_DONE) {
|
||||
@@ -777,15 +693,17 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
|
||||
struct file_list *flist;
|
||||
char *dir = argv[0];
|
||||
|
||||
if (DEBUG_GTE(SEND, 1))
|
||||
rprintf(FINFO, "server_sender starting pid=%d\n", (int)getpid());
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "server_sender starting pid=%ld\n",
|
||||
(long)getpid());
|
||||
}
|
||||
|
||||
if (am_daemon && lp_write_only(module_id)) {
|
||||
rprintf(FERROR, "ERROR: module is write only\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
return;
|
||||
}
|
||||
if (am_daemon && read_only && remove_source_files) {
|
||||
if (am_daemon && lp_read_only(module_id) && remove_source_files) {
|
||||
rprintf(FERROR,
|
||||
"ERROR: --remove-%s-files cannot be used with a read-only module\n",
|
||||
remove_source_files == 1 ? "source" : "sent");
|
||||
@@ -810,12 +728,8 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
|
||||
}
|
||||
|
||||
flist = send_file_list(f_out,argc,argv);
|
||||
if (!flist || flist->used == 0) {
|
||||
/* Make sure input buffering is off so we can't hang in noop_io_until_death(). */
|
||||
io_end_buffering_in(0);
|
||||
/* TODO: we should really exit in a more controlled manner. */
|
||||
if (!flist || flist->used == 0)
|
||||
exit_cleanup(0);
|
||||
}
|
||||
|
||||
io_start_buffering_in(f_in);
|
||||
|
||||
@@ -823,7 +737,7 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
|
||||
io_flush(FULL_FLUSH);
|
||||
handle_stats(f_out);
|
||||
if (protocol_version >= 24)
|
||||
read_final_goodbye(f_in, f_out);
|
||||
read_final_goodbye(f_in);
|
||||
io_flush(FULL_FLUSH);
|
||||
exit_cleanup(0);
|
||||
}
|
||||
@@ -849,17 +763,7 @@ static int do_recv(int f_in, int f_out, char *local_name)
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (backup_dir) {
|
||||
int ret = make_path(backup_dir_buf, MKP_DROP_NAME); /* drops trailing slash */
|
||||
if (ret < 0)
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
if (ret)
|
||||
rprintf(FINFO, "Created backup_dir %s\n", backup_dir_buf);
|
||||
else if (INFO_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
|
||||
}
|
||||
|
||||
io_flush(FULL_FLUSH);
|
||||
io_flush(NORMAL_FLUSH);
|
||||
|
||||
if ((pid = do_fork()) == -1) {
|
||||
rsyserr(FERROR, errno, "fork failed in do_recv");
|
||||
@@ -868,43 +772,38 @@ static int do_recv(int f_in, int f_out, char *local_name)
|
||||
|
||||
if (pid == 0) {
|
||||
am_receiver = 1;
|
||||
send_msgs_to_gen = am_server;
|
||||
|
||||
close(error_pipe[0]);
|
||||
|
||||
/* We can't let two processes write to the socket at one time. */
|
||||
io_end_multiplex_out(MPLX_SWITCHING);
|
||||
if (f_in != f_out)
|
||||
close(f_out);
|
||||
sock_f_out = -1;
|
||||
f_out = error_pipe[1];
|
||||
|
||||
bwlimit_writemax = 0; /* receiver doesn't need to do this */
|
||||
/* we can't let two processes write to the socket at one time */
|
||||
io_end_multiplex_out();
|
||||
|
||||
if (read_batch)
|
||||
io_start_buffering_in(f_in);
|
||||
io_start_multiplex_out(f_out);
|
||||
/* set place to send errors */
|
||||
set_msg_fd_out(error_pipe[1]);
|
||||
io_start_buffering_out(error_pipe[1]);
|
||||
|
||||
recv_files(f_in, f_out, local_name);
|
||||
recv_files(f_in, local_name);
|
||||
io_flush(FULL_FLUSH);
|
||||
handle_stats(f_in);
|
||||
|
||||
if (output_needs_newline) {
|
||||
fputc('\n', stdout);
|
||||
output_needs_newline = 0;
|
||||
}
|
||||
|
||||
write_int(f_out, NDX_DONE);
|
||||
send_msg(MSG_STATS, (char*)&stats.total_read, sizeof stats.total_read, 0);
|
||||
send_msg(MSG_DONE, "", 1, 0);
|
||||
write_varlong(error_pipe[1], stats.total_read, 3);
|
||||
io_flush(FULL_FLUSH);
|
||||
|
||||
/* Handle any keep-alive packets from the post-processing work
|
||||
* that the generator does. */
|
||||
if (protocol_version >= 29) {
|
||||
int iflags, xlen;
|
||||
uchar fnamecmp_type;
|
||||
char xname[MAXPATHLEN];
|
||||
|
||||
kluge_around_eof = -1;
|
||||
|
||||
/* This should only get stopped via a USR2 signal. */
|
||||
read_final_goodbye(f_in, f_out);
|
||||
read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
|
||||
xname, &xlen);
|
||||
|
||||
rprintf(FERROR, "Invalid packet at end of run [%s]\n",
|
||||
who_am_i());
|
||||
@@ -919,20 +818,19 @@ static int do_recv(int f_in, int f_out, char *local_name)
|
||||
}
|
||||
|
||||
am_generator = 1;
|
||||
flist_receiving_enabled = True;
|
||||
|
||||
io_end_multiplex_in(MPLX_SWITCHING);
|
||||
io_end_multiplex_in();
|
||||
if (write_batch && !am_server)
|
||||
stop_write_batch();
|
||||
|
||||
close(error_pipe[1]);
|
||||
if (f_in != f_out)
|
||||
close(f_in);
|
||||
sock_f_in = -1;
|
||||
f_in = error_pipe[0];
|
||||
|
||||
io_start_buffering_out(f_out);
|
||||
io_start_multiplex_in(f_in);
|
||||
|
||||
set_msg_fd_in(error_pipe[0]);
|
||||
io_start_buffering_in(error_pipe[0]);
|
||||
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
if (preserve_hard_links && inc_recurse) {
|
||||
@@ -946,13 +844,13 @@ static int do_recv(int f_in, int f_out, char *local_name)
|
||||
|
||||
handle_stats(-1);
|
||||
io_flush(FULL_FLUSH);
|
||||
shutting_down = True;
|
||||
if (protocol_version >= 24) {
|
||||
/* send a final goodbye message */
|
||||
write_ndx(f_out, NDX_DONE);
|
||||
}
|
||||
io_flush(FULL_FLUSH);
|
||||
|
||||
set_msg_fd_in(-1);
|
||||
kill(pid, SIGUSR2);
|
||||
wait_process_with_flush(pid, &exit_code);
|
||||
return exit_code;
|
||||
@@ -963,20 +861,20 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
|
||||
int exit_code;
|
||||
struct file_list *flist;
|
||||
char *local_name = NULL;
|
||||
int negated_levels;
|
||||
int save_verbose = verbose;
|
||||
|
||||
if (filesfrom_fd >= 0 && !msgs2stderr && protocol_version < 31) {
|
||||
if (filesfrom_fd >= 0) {
|
||||
/* We can't mix messages with files-from data on the socket,
|
||||
* so temporarily turn off info/debug messages. */
|
||||
negate_output_levels();
|
||||
negated_levels = 1;
|
||||
} else
|
||||
negated_levels = 0;
|
||||
* so temporarily turn off verbose messages. */
|
||||
verbose = 0;
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(RECV, 1))
|
||||
rprintf(FINFO, "server_recv(%d) starting pid=%d\n", argc, (int)getpid());
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
|
||||
argc, (long)getpid());
|
||||
}
|
||||
|
||||
if (am_daemon && read_only) {
|
||||
if (am_daemon && lp_read_only(module_id)) {
|
||||
rprintf(FERROR,"ERROR: module is read only\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
return;
|
||||
@@ -994,7 +892,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (protocol_version >= 30)
|
||||
io_start_multiplex_in(f_in);
|
||||
io_start_multiplex_in();
|
||||
else
|
||||
io_start_buffering_in(f_in);
|
||||
recv_filter_list(f_in);
|
||||
@@ -1005,7 +903,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
|
||||
* need the IO routines to automatically write out the names
|
||||
* onto our f_out socket as we read the file-list. This
|
||||
* avoids both deadlock and extra delays/buffers. */
|
||||
start_filesfrom_forwarding(filesfrom_fd);
|
||||
io_set_filesfrom_fds(filesfrom_fd, f_out);
|
||||
filesfrom_fd = -1;
|
||||
}
|
||||
|
||||
@@ -1016,9 +914,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
|
||||
}
|
||||
if (inc_recurse && file_total == 1)
|
||||
recv_additional_file_list(f_in);
|
||||
|
||||
if (negated_levels)
|
||||
negate_output_levels();
|
||||
verbose = save_verbose;
|
||||
|
||||
if (argc > 0)
|
||||
local_name = get_local_name(flist,argv[0]);
|
||||
@@ -1036,7 +932,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[])
|
||||
|
||||
if (daemon_filter_list.head) {
|
||||
char **dir_p;
|
||||
filter_rule_list *elp = &daemon_filter_list;
|
||||
struct filter_list_struct *elp = &daemon_filter_list;
|
||||
|
||||
for (dir_p = basis_dir; *dir_p; dir_p++) {
|
||||
char *dir = *dir_p;
|
||||
@@ -1075,16 +971,12 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
|
||||
setup_protocol(f_out, f_in);
|
||||
|
||||
if (protocol_version >= 23)
|
||||
io_start_multiplex_out(f_out);
|
||||
if (am_daemon && io_timeout && protocol_version >= 31)
|
||||
send_msg_int(MSG_IO_TIMEOUT, io_timeout);
|
||||
io_start_multiplex_out();
|
||||
|
||||
if (am_sender) {
|
||||
keep_dirlinks = 0; /* Must be disabled on the sender. */
|
||||
if (need_messages_from_generator)
|
||||
io_start_multiplex_in(f_in);
|
||||
else
|
||||
io_start_buffering_in(f_in);
|
||||
io_start_multiplex_in();
|
||||
recv_filter_list(f_in);
|
||||
do_server_sender(f_in, f_out, argc, argv);
|
||||
} else
|
||||
@@ -1092,8 +984,11 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
|
||||
exit_cleanup(0);
|
||||
}
|
||||
|
||||
/* This is called once the connection has been negotiated. It is used
|
||||
* for rsyncd, remote-shell, and local connections. */
|
||||
|
||||
/*
|
||||
* This is called once the connection has been negotiated. It is used
|
||||
* for rsyncd, remote-shell, and local connections.
|
||||
*/
|
||||
int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
{
|
||||
struct file_list *flist = NULL;
|
||||
@@ -1121,20 +1016,12 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
|
||||
if (am_sender) {
|
||||
keep_dirlinks = 0; /* Must be disabled on the sender. */
|
||||
|
||||
if (always_checksum
|
||||
&& (log_format_has(stdout_format, 'C')
|
||||
|| log_format_has(logfile_format, 'C')))
|
||||
sender_keeps_checksum = 1;
|
||||
|
||||
if (protocol_version >= 30)
|
||||
io_start_multiplex_out(f_out);
|
||||
io_start_multiplex_out();
|
||||
else
|
||||
io_start_buffering_out(f_out);
|
||||
if (protocol_version >= 31 || (!filesfrom_host && protocol_version >= 23))
|
||||
io_start_multiplex_in(f_in);
|
||||
else
|
||||
io_start_buffering_in(f_in);
|
||||
if (!filesfrom_host)
|
||||
set_msg_fd_in(f_in);
|
||||
send_filter_list(f_out);
|
||||
if (filesfrom_host)
|
||||
filesfrom_fd = f_in;
|
||||
@@ -1142,20 +1029,20 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
if (write_batch && !am_server)
|
||||
start_write_batch(f_out);
|
||||
flist = send_file_list(f_out, argc, argv);
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"file list sent\n");
|
||||
|
||||
if (protocol_version < 31 && filesfrom_host && protocol_version >= 23)
|
||||
io_start_multiplex_in(f_in);
|
||||
if (protocol_version >= 23)
|
||||
io_start_multiplex_in();
|
||||
|
||||
io_flush(NORMAL_FLUSH);
|
||||
send_files(f_in, f_out);
|
||||
io_flush(FULL_FLUSH);
|
||||
handle_stats(-1);
|
||||
if (protocol_version >= 24)
|
||||
read_final_goodbye(f_in, f_out);
|
||||
read_final_goodbye(f_in);
|
||||
if (pid != -1) {
|
||||
if (DEBUG_GTE(EXIT, 2))
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
|
||||
io_flush(FULL_FLUSH);
|
||||
wait_process_with_flush(pid, &exit_code);
|
||||
@@ -1167,17 +1054,15 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
|
||||
if (!read_batch) {
|
||||
if (protocol_version >= 23)
|
||||
io_start_multiplex_in(f_in);
|
||||
io_start_multiplex_in();
|
||||
if (need_messages_from_generator)
|
||||
io_start_multiplex_out(f_out);
|
||||
else
|
||||
io_start_buffering_out(f_out);
|
||||
io_start_multiplex_out();
|
||||
}
|
||||
|
||||
send_filter_list(read_batch ? -1 : f_out);
|
||||
|
||||
if (filesfrom_fd >= 0) {
|
||||
start_filesfrom_forwarding(filesfrom_fd);
|
||||
io_set_filesfrom_fds(filesfrom_fd, f_out);
|
||||
filesfrom_fd = -1;
|
||||
}
|
||||
|
||||
@@ -1199,7 +1084,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (pid != -1) {
|
||||
if (DEBUG_GTE(RECV, 1))
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
|
||||
io_flush(FULL_FLUSH);
|
||||
wait_process_with_flush(pid, &exit_code);
|
||||
@@ -1224,12 +1109,14 @@ static int copy_argv(char *argv[])
|
||||
}
|
||||
|
||||
|
||||
/* Start a client for either type of remote connection. Work out
|
||||
/**
|
||||
* Start a client for either type of remote connection. Work out
|
||||
* whether the arguments request a remote shell or rsyncd connection,
|
||||
* and call the appropriate connection function, then run_client.
|
||||
*
|
||||
* Calls either start_socket_client (for sockets) or do_cmd and
|
||||
* client_run (for ssh). */
|
||||
* client_run (for ssh).
|
||||
**/
|
||||
static int start_client(int argc, char *argv[])
|
||||
{
|
||||
char *p, *shell_machine = NULL, *shell_user = NULL;
|
||||
@@ -1316,9 +1203,6 @@ static int start_client(int argc, char *argv[])
|
||||
remote_argc = argc = 1;
|
||||
}
|
||||
|
||||
if (!rsync_port && remote_argc && !**remote_argv) /* Turn an empty arg into a dot dir. */
|
||||
*remote_argv = ".";
|
||||
|
||||
if (am_sender) {
|
||||
char *dummy_host;
|
||||
int dummy_port = rsync_port;
|
||||
@@ -1354,8 +1238,6 @@ static int start_client(int argc, char *argv[])
|
||||
rprintf(FERROR, "All source args must use the same port number.\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if (!rsync_port && !*arg) /* Turn an empty arg into a dot dir. */
|
||||
arg = ".";
|
||||
remote_argv[i] = arg;
|
||||
}
|
||||
}
|
||||
@@ -1384,10 +1266,10 @@ static int start_client(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(CMD, 2)) {
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
|
||||
NS(shell_cmd), NS(shell_machine), NS(shell_user),
|
||||
NS(remote_argv[0]));
|
||||
remote_argv ? NS(remote_argv[0]) : "");
|
||||
}
|
||||
|
||||
pid = do_cmd(shell_cmd, shell_machine, shell_user, remote_argv, remote_argc,
|
||||
@@ -1490,9 +1372,10 @@ const char *get_panic_action(void)
|
||||
static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
|
||||
{
|
||||
char cmd_buf[300];
|
||||
int ret, pid_int = getpid();
|
||||
int ret;
|
||||
|
||||
snprintf(cmd_buf, sizeof cmd_buf, get_panic_action(), pid_int, pid_int);
|
||||
snprintf(cmd_buf, sizeof cmd_buf, get_panic_action(),
|
||||
getpid(), getpid());
|
||||
|
||||
/* Unless we failed to execute gdb, we allow the process to
|
||||
* continue. I'm not sure if that's right. */
|
||||
@@ -1528,7 +1411,6 @@ int main(int argc,char *argv[])
|
||||
|
||||
starttime = time(NULL);
|
||||
our_uid = MY_UID();
|
||||
our_gid = MY_GID();
|
||||
am_root = our_uid == 0;
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
@@ -1538,10 +1420,9 @@ int main(int argc,char *argv[])
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
/* Get the umask for use in permission calculations. We no longer set
|
||||
* it to zero; that is ugly and pointless now that all the callers that
|
||||
* relied on it have been reeducated to work with default ACLs. */
|
||||
umask(orig_umask = umask(0));
|
||||
/* we set a 0 umask so that correct file permissions can be
|
||||
* carried across */
|
||||
orig_umask = umask(0);
|
||||
|
||||
#if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
133
match.c
133
match.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,14 +20,13 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int do_progress;
|
||||
extern int checksum_seed;
|
||||
extern int append_mode;
|
||||
extern int checksum_len;
|
||||
|
||||
int updating_basis_file;
|
||||
char sender_file_sum[MAX_DIGEST_LEN];
|
||||
|
||||
static int false_alarms;
|
||||
static int hash_hits;
|
||||
@@ -108,10 +107,10 @@ static void matched(int f, struct sum_struct *s, struct map_struct *buf,
|
||||
int32 n = (int32)(offset - last_match); /* max value: block_size (int32) */
|
||||
int32 j;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2) && i >= 0) {
|
||||
if (verbose > 2 && i >= 0) {
|
||||
rprintf(FINFO,
|
||||
"match at %s last_match=%s j=%d len=%ld n=%ld\n",
|
||||
big_num(offset), big_num(last_match), i,
|
||||
"match at %.0f last_match=%.0f j=%d len=%ld n=%ld\n",
|
||||
(double)offset, (double)last_match, i,
|
||||
(long)s->sums[i].len, (long)n);
|
||||
}
|
||||
|
||||
@@ -133,7 +132,7 @@ static void matched(int f, struct sum_struct *s, struct map_struct *buf,
|
||||
else
|
||||
last_match = offset;
|
||||
|
||||
if (buf && INFO_GTE(PROGRESS, 1))
|
||||
if (buf && do_progress)
|
||||
show_progress(last_match, buf->file_size);
|
||||
}
|
||||
|
||||
@@ -152,9 +151,9 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
* coding of the output to work more efficiently. */
|
||||
want_i = 0;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2)) {
|
||||
rprintf(FINFO, "hash search b=%ld len=%s\n",
|
||||
(long)s->blength, big_num(len));
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "hash search b=%ld len=%.0f\n",
|
||||
(long)s->blength, (double)len);
|
||||
}
|
||||
|
||||
k = (int32)MIN(len, (OFF_T)s->blength);
|
||||
@@ -164,55 +163,41 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
sum = get_checksum1((char *)map, k);
|
||||
s1 = sum & 0xFFFF;
|
||||
s2 = sum >> 16;
|
||||
if (DEBUG_GTE(DELTASUM, 3))
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO, "sum=%.8x k=%ld\n", sum, (long)k);
|
||||
|
||||
offset = aligned_offset = aligned_i = 0;
|
||||
|
||||
end = len + 1 - s->sums[s->count-1].len;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 3)) {
|
||||
rprintf(FINFO, "hash search s->blength=%ld len=%s count=%s\n",
|
||||
(long)s->blength, big_num(len), big_num(s->count));
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO, "hash search s->blength=%ld len=%.0f count=%.0f\n",
|
||||
(long)s->blength, (double)len, (double)s->count);
|
||||
}
|
||||
|
||||
do {
|
||||
int done_csum2 = 0;
|
||||
uint32 hash_entry;
|
||||
int32 i, *prev;
|
||||
int32 i;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 4)) {
|
||||
rprintf(FINFO, "offset=%s sum=%04x%04x\n",
|
||||
big_num(offset), s2 & 0xFFFF, s1 & 0xFFFF);
|
||||
if (verbose > 4) {
|
||||
rprintf(FINFO, "offset=%.0f sum=%04x%04x\n",
|
||||
(double)offset, s2 & 0xFFFF, s1 & 0xFFFF);
|
||||
}
|
||||
|
||||
if (tablesize == TRADITIONAL_TABLESIZE) {
|
||||
hash_entry = SUM2HASH2(s1,s2);
|
||||
if ((i = hash_table[hash_entry]) < 0)
|
||||
if ((i = hash_table[SUM2HASH2(s1,s2)]) < 0)
|
||||
goto null_hash;
|
||||
sum = (s1 & 0xffff) | (s2 << 16);
|
||||
} else {
|
||||
sum = (s1 & 0xffff) | (s2 << 16);
|
||||
hash_entry = BIG_SUM2HASH(sum);
|
||||
if ((i = hash_table[hash_entry]) < 0)
|
||||
if ((i = hash_table[BIG_SUM2HASH(sum)]) < 0)
|
||||
goto null_hash;
|
||||
}
|
||||
prev = &hash_table[hash_entry];
|
||||
|
||||
hash_hits++;
|
||||
do {
|
||||
int32 l;
|
||||
|
||||
/* When updating in-place, the chunk's offset must be
|
||||
* either >= our offset or identical data at that offset.
|
||||
* Remove any bypassed entries that we can never use. */
|
||||
if (updating_basis_file && s->sums[i].offset < offset
|
||||
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET)) {
|
||||
*prev = s->sums[i].chain;
|
||||
continue;
|
||||
}
|
||||
prev = &s->sums[i].chain;
|
||||
|
||||
if (sum != s->sums[i].sum1)
|
||||
continue;
|
||||
|
||||
@@ -221,10 +206,16 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
if (l != s->sums[i].len)
|
||||
continue;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 3)) {
|
||||
/* in-place: ensure chunk's offset is either >= our
|
||||
* offset or that the data didn't move. */
|
||||
if (updating_basis_file && s->sums[i].offset < offset
|
||||
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET))
|
||||
continue;
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,
|
||||
"potential match at %s i=%ld sum=%08x\n",
|
||||
big_num(offset), (long)i, sum);
|
||||
"potential match at %.0f i=%ld sum=%08x\n",
|
||||
(double)offset, (long)i, sum);
|
||||
}
|
||||
|
||||
if (!done_csum2) {
|
||||
@@ -247,9 +238,7 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
aligned_offset += s->blength;
|
||||
aligned_i++;
|
||||
}
|
||||
if ((offset == aligned_offset
|
||||
|| (sum == 0 && l == s->blength && aligned_offset + l <= len))
|
||||
&& aligned_i < s->count) {
|
||||
if (offset == aligned_offset) {
|
||||
if (i != aligned_i) {
|
||||
if (sum != s->sums[aligned_i].sum1
|
||||
|| l != s->sums[aligned_i].len
|
||||
@@ -257,27 +246,6 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
goto check_want_i;
|
||||
i = aligned_i;
|
||||
}
|
||||
if (offset != aligned_offset) {
|
||||
/* We've matched some zeros in a spot that is also zeros
|
||||
* further along in the basis file, if we find zeros ahead
|
||||
* in the sender's file, we'll output enough literal data
|
||||
* to re-align with the basis file, and get back to seeking
|
||||
* instead of writing. */
|
||||
backup = (int32)(aligned_offset - last_match);
|
||||
if (backup < 0)
|
||||
backup = 0;
|
||||
map = (schar *)map_ptr(buf, aligned_offset - backup, l + backup)
|
||||
+ backup;
|
||||
sum = get_checksum1((char *)map, l);
|
||||
if (sum != s->sums[i].sum1)
|
||||
goto check_want_i;
|
||||
get_checksum2((char *)map, l, sum2);
|
||||
if (memcmp(sum2, s->sums[i].sum2, s->s2length) != 0)
|
||||
goto check_want_i;
|
||||
/* OK, we have a re-alignment match. Bump the offset
|
||||
* forward to the new match point. */
|
||||
offset = aligned_offset;
|
||||
}
|
||||
/* This identical chunk is in the same spot in the old and new file. */
|
||||
s->sums[i].flags |= SUMFLG_SAME_OFFSET;
|
||||
want_i = i;
|
||||
@@ -360,6 +328,9 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
**/
|
||||
void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
{
|
||||
char file_sum[MAX_DIGEST_LEN];
|
||||
int sum_len;
|
||||
|
||||
last_match = 0;
|
||||
false_alarms = 0;
|
||||
hash_hits = 0;
|
||||
@@ -372,7 +343,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
if (append_mode == 2) {
|
||||
OFF_T j = 0;
|
||||
for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
|
||||
if (buf && INFO_GTE(PROGRESS, 1))
|
||||
if (buf && do_progress)
|
||||
show_progress(last_match, buf->file_size);
|
||||
sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
|
||||
CHUNK_SIZE);
|
||||
@@ -380,7 +351,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
}
|
||||
if (last_match < s->flength) {
|
||||
int32 n = (int32)(s->flength - last_match);
|
||||
if (buf && INFO_GTE(PROGRESS, 1))
|
||||
if (buf && do_progress)
|
||||
show_progress(last_match, buf->file_size);
|
||||
sum_update(map_ptr(buf, last_match, n), n);
|
||||
}
|
||||
@@ -392,12 +363,12 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
if (len > 0 && s->count > 0) {
|
||||
build_hash_table(s);
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"built hash table\n");
|
||||
|
||||
hash_search(f, s, buf, len);
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"done hash search\n");
|
||||
} else {
|
||||
OFF_T j;
|
||||
@@ -407,28 +378,18 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
matched(f, s, buf, len, -1);
|
||||
}
|
||||
|
||||
if (sum_end(sender_file_sum) != checksum_len)
|
||||
overflow_exit("checksum_len"); /* Impossible... */
|
||||
sum_len = sum_end(file_sum);
|
||||
/* If we had a read error, send a bad checksum. */
|
||||
if (buf && buf->status != 0)
|
||||
file_sum[0]++;
|
||||
|
||||
/* If we had a read error, send a bad checksum. We use all bits
|
||||
* off as long as the checksum doesn't happen to be that, in
|
||||
* which case we turn the last 0 bit into a 1. */
|
||||
if (buf && buf->status != 0) {
|
||||
int i;
|
||||
for (i = 0; i < checksum_len && sender_file_sum[i] == 0; i++) {}
|
||||
memset(sender_file_sum, 0, checksum_len);
|
||||
if (i == checksum_len)
|
||||
sender_file_sum[i-1]++;
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"sending file_sum\n");
|
||||
write_buf(f, sender_file_sum, checksum_len);
|
||||
write_buf(f, file_sum, sum_len);
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2)) {
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
|
||||
false_alarms, hash_hits, matches);
|
||||
}
|
||||
|
||||
total_hash_hits += hash_hits;
|
||||
total_false_alarms += false_alarms;
|
||||
@@ -438,11 +399,11 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
|
||||
void match_report(void)
|
||||
{
|
||||
if (!DEBUG_GTE(DELTASUM, 1))
|
||||
if (verbose <= 1)
|
||||
return;
|
||||
|
||||
rprintf(FINFO,
|
||||
"total: matches=%d hash_hits=%d false_alarms=%d data=%s\n",
|
||||
"total: matches=%d hash_hits=%d false_alarms=%d data=%.0f\n",
|
||||
total_matches, total_hash_hits, total_false_alarms,
|
||||
big_num(stats.literal_data));
|
||||
(double)stats.literal_data);
|
||||
}
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
||||
&Getopt::Long::Configure('bundling');
|
||||
&usage if !&GetOptions(
|
||||
'branch|b=s' => \( my $master_branch = 'master' ),
|
||||
'skip-check' => \( my $skip_branch_check ),
|
||||
'delete' => \( my $delete_local_branches ),
|
||||
'help|h' => \( my $help_opt ),
|
||||
);
|
||||
&usage if $help_opt;
|
||||
|
||||
require 'packaging/git-status.pl';
|
||||
check_git_state($master_branch, !$skip_branch_check, 1);
|
||||
|
||||
my %local_branch;
|
||||
open PIPE, '-|', 'git branch -l' or die "Unable to fork: $!\n";
|
||||
while (<PIPE>) {
|
||||
if (m# patch/\Q$master_branch\E/(.*)#o) {
|
||||
$local_branch{$1} = 1;
|
||||
}
|
||||
}
|
||||
close PIPE;
|
||||
|
||||
if ($delete_local_branches) {
|
||||
foreach my $name (sort keys %local_branch) {
|
||||
my $branch = "patch/$master_branch/$name";
|
||||
system 'git', 'branch', '-D', $branch and exit 1;
|
||||
}
|
||||
%local_branch = ( );
|
||||
}
|
||||
|
||||
my @patch_list;
|
||||
foreach (@ARGV) {
|
||||
if (!-f $_) {
|
||||
die "File not found: $_\n";
|
||||
}
|
||||
die "Filename is not a .diff file: $_\n" unless /\.diff$/;
|
||||
push @patch_list, $_;
|
||||
}
|
||||
|
||||
exit unless @patch_list;
|
||||
|
||||
my(%scanned, %created, %info);
|
||||
|
||||
foreach my $patch (@patch_list) {
|
||||
my($where, $name) = $patch =~ m{^(.*?)([^/]+)\.diff$};
|
||||
next if $scanned{$name}++;
|
||||
|
||||
open IN, '<', $patch or die "Unable to open $patch: $!\n";
|
||||
|
||||
my $info = '';
|
||||
my $commit;
|
||||
while (<IN>) {
|
||||
if (m#^based-on: (\S+)#) {
|
||||
$commit = $1;
|
||||
last;
|
||||
}
|
||||
last if m#^index .*\.\..* \d#;
|
||||
last if m#^diff --git #;
|
||||
last if m#^--- (old|a)/#;
|
||||
$info .= $_;
|
||||
}
|
||||
close IN;
|
||||
|
||||
$info =~ s/\s+\Z/\n/;
|
||||
|
||||
my $parent = $master_branch;
|
||||
my @patches = $info =~ m#patch -p1 <patches/(\S+)\.diff#g;
|
||||
if (@patches) {
|
||||
if ($patches[-1] eq $name) {
|
||||
pop @patches;
|
||||
} else {
|
||||
warn "No identity patch line in $patch\n";
|
||||
}
|
||||
if (@patches) {
|
||||
$parent = pop @patches;
|
||||
if (!$scanned{$parent}) {
|
||||
unless (-f "$where$parent.diff") {
|
||||
die "Unknown parent of $patch: $parent\n";
|
||||
}
|
||||
# Add parent to @patch_list so that we will look for the
|
||||
# parent's parent. Any duplicates will just be ignored.
|
||||
push @patch_list, "$where$parent.diff";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn "No patch lines found in $patch\n";
|
||||
}
|
||||
|
||||
$info{$name} = [ $parent, $info, $commit ];
|
||||
}
|
||||
|
||||
foreach my $patch (@patch_list) {
|
||||
create_branch($patch);
|
||||
}
|
||||
|
||||
system 'git', 'checkout', $master_branch and exit 1;
|
||||
|
||||
exit;
|
||||
|
||||
sub create_branch
|
||||
{
|
||||
my($patch) = @_;
|
||||
my($where, $name) = $patch =~ m{^(.*?)([^/]+)\.diff$};
|
||||
|
||||
return if $created{$name}++;
|
||||
|
||||
my $ref = $info{$name};
|
||||
my($parent, $info, $commit) = @$ref;
|
||||
|
||||
my $parent_branch;
|
||||
if ($parent eq $master_branch) {
|
||||
$parent_branch = $master_branch;
|
||||
$parent_branch = $commit if defined $commit;
|
||||
} else {
|
||||
create_branch("$where/$parent.diff");
|
||||
$parent_branch = "patch/$master_branch/$parent";
|
||||
}
|
||||
|
||||
my $branch = "patch/$master_branch/$name";
|
||||
print "\n", '=' x 64, "\nProcessing $branch ($parent_branch)\n";
|
||||
|
||||
if ($local_branch{$name}) {
|
||||
system 'git', 'branch', '-D', $branch and exit 1;
|
||||
}
|
||||
|
||||
system 'git', 'checkout', '-b', $branch, $parent_branch and exit 1;
|
||||
|
||||
open OUT, '>', "PATCH.$name" or die $!;
|
||||
print OUT $info;
|
||||
close OUT;
|
||||
system 'git', 'add', "PATCH.$name" and exit 1;
|
||||
|
||||
open IN, '<', $patch or die "Unable to open $patch: $!\n";
|
||||
$_ = join('', <IN>);
|
||||
close IN;
|
||||
|
||||
open PIPE, '|-', 'patch -p1' or die $!;
|
||||
print PIPE $_;
|
||||
close PIPE;
|
||||
|
||||
system 'rm -f *.orig */*.orig';
|
||||
|
||||
while (m#\nnew file mode (\d+)\s+--- /dev/null\s+\Q+++\E b/(.*)#g) {
|
||||
chmod oct($1), $2;
|
||||
system 'git', 'add', $2;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
system 'git status';
|
||||
print 'Press Enter to commit, Ctrl-C to abort, or type a wild-name to add a new file: ';
|
||||
$_ = <STDIN>;
|
||||
last if /^$/;
|
||||
chomp;
|
||||
system "git add $_";
|
||||
}
|
||||
|
||||
while (system 'git', 'commit', '-a', '-m', "Creating branch from $name.diff.") {
|
||||
exit 1 if system '/bin/zsh';
|
||||
}
|
||||
}
|
||||
|
||||
sub usage
|
||||
{
|
||||
die <<EOT;
|
||||
Usage branch-from-patch [OPTIONS] patches/DIFF...
|
||||
|
||||
Options:
|
||||
-b, --branch=BRANCH Create branches relative to BRANCH if no "based-on"
|
||||
header was found in the patch file.
|
||||
--skip-check Skip the check that ensures starting with a clean branch.
|
||||
--delete Delete all the local patch/BASE/* branches, not just the ones
|
||||
that are being recreated.
|
||||
-h, --help Output this help message.
|
||||
EOT
|
||||
}
|
||||
@@ -6,28 +6,25 @@ sub check_git_state
|
||||
my($master_branch, $fatal_unless_clean, $check_patches_dir) = @_;
|
||||
|
||||
my($cur_branch) = check_git_status($fatal_unless_clean);
|
||||
(my $branch = $cur_branch) =~ s{^patch/([^/]+)/[^/]+$}{$1}; # change patch/BRANCH/PATCH_NAME into BRANCH
|
||||
if ($branch ne $master_branch) {
|
||||
if ($cur_branch ne $master_branch) {
|
||||
print "The checkout is not on the $master_branch branch.\n";
|
||||
exit 1 if $master_branch ne 'master';
|
||||
print "Do you want me to continue with --branch=$branch? [n] ";
|
||||
print "Do you want me to continue with --branch=$cur_branch? [n] ";
|
||||
$_ = <STDIN>;
|
||||
exit 1 unless /^y/i;
|
||||
$_[0] = $master_branch = $branch; # Updates caller's $master_branch too.
|
||||
$_[0] = $master_branch = $cur_branch; # Updates caller's $master_branch too.
|
||||
}
|
||||
|
||||
if ($check_patches_dir && -d 'patches/.git') {
|
||||
($branch) = check_git_status($fatal_unless_clean, 'patches');
|
||||
if ($branch ne $master_branch) {
|
||||
print "The *patches* checkout is on branch $branch, not branch $master_branch.\n";
|
||||
($cur_branch) = check_git_status($fatal_unless_clean, 'patches');
|
||||
if ($cur_branch ne $master_branch) {
|
||||
print "The *patches* checkout is on branch $cur_branch, not branch $master_branch.\n";
|
||||
print "Do you want to change it to branch $master_branch? [n] ";
|
||||
$_ = <STDIN>;
|
||||
exit 1 unless /^y/i;
|
||||
system "cd patches && git checkout '$master_branch'";
|
||||
}
|
||||
}
|
||||
|
||||
return $cur_branch;
|
||||
}
|
||||
|
||||
sub check_git_status
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Summary: A fast, versatile, remote (and local) file-copying tool
|
||||
Name: rsync
|
||||
Version: 3.1.0
|
||||
Version: 3.0.8
|
||||
%define fullversion %{version}
|
||||
Release: 1
|
||||
%define srcdir src
|
||||
@@ -13,14 +13,6 @@ Prefix: %{_prefix}
|
||||
BuildRoot: /var/tmp/%{name}-root
|
||||
License: GPL
|
||||
|
||||
%package ssl-client
|
||||
Summary: Provides rsync-ssl
|
||||
Requires: stunnel >= 4
|
||||
|
||||
%package ssl-daemon
|
||||
Summary: An stunnel config file to support ssl rsync daemon connections.
|
||||
Requires: stunnel >= 4
|
||||
|
||||
%description
|
||||
Rsync is a fast and extraordinarily versatile file copying tool. It can
|
||||
copy locally, to/from another host over any remote shell, or to/from a
|
||||
@@ -32,22 +24,12 @@ differences between the source files and the existing files in the
|
||||
destination. Rsync is widely used for backups and mirroring and as an
|
||||
improved copy command for everyday use.
|
||||
|
||||
%description ssl-client
|
||||
Provides the rsync-ssl script that makes use of stunnel 4 to open an ssl
|
||||
connection to an rsync daemon (on port 874). This setup does NOT require
|
||||
any local stunnel daemon to be running to connect to the remote ssl rsyncd.
|
||||
|
||||
%description ssl-daemon
|
||||
Provides a config file for stunnel that will (if you start your stunnel
|
||||
service) cause stunnel to listen for ssl rsync-daemon connections and run
|
||||
"rsync --daemon" to handle them.
|
||||
|
||||
%prep
|
||||
# Choose one -- setup source only, or setup source + rsync-patches:
|
||||
%setup -q -n rsync-%{fullversion}
|
||||
#%setup -q -b1 -n rsync-%{fullversion}
|
||||
|
||||
# If you you used "%setup -q -b1 ...", choose the patches you wish to apply:
|
||||
# If you you used "%setup -q -b1", choose the patches you wish to apply:
|
||||
#patch -p1 <patches/acls.diff
|
||||
#patch -p1 <patches/xattrs.diff
|
||||
#patch -p1 <patches/remote-option.diff
|
||||
@@ -64,11 +46,14 @@ make
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make install install-ssl-client install-ssl-daemon DESTDIR=$RPM_BUILD_ROOT
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d $RPM_BUILD_ROOT/etc/rsync-ssl/certs
|
||||
%makeinstall
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d
|
||||
install -m 644 packaging/lsb/rsync.xinetd $RPM_BUILD_ROOT/etc/xinetd.d/rsync
|
||||
|
||||
#install -p -m 755 support/rsyncdb $RPM_BUILD_ROOT/usr/bin/rsyncdb
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
@@ -76,21 +61,13 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%defattr(-,root,root)
|
||||
%doc COPYING NEWS OLDNEWS README support/ tech_report.tex
|
||||
%config(noreplace) /etc/xinetd.d/rsync
|
||||
%{_prefix}/bin/rsync
|
||||
%{_prefix}/bin/rsync*
|
||||
%{_mandir}/man1/rsync.1*
|
||||
%{_mandir}/man5/rsyncd.conf.5*
|
||||
|
||||
%files ssl-client
|
||||
%{_prefix}/bin/rsync-ssl
|
||||
%{_prefix}/bin/stunnel-rsync
|
||||
|
||||
%files ssl-daemon
|
||||
%config(noreplace) /etc/stunnel/rsyncd.conf
|
||||
%dir /etc/rsync-ssl/certs
|
||||
|
||||
%changelog
|
||||
* Sat Sep 28 2013 Wayne Davison <wayned@samba.org>
|
||||
Released 3.1.0.
|
||||
* Sat Mar 26 2011 Wayne Davison <wayned@samba.org>
|
||||
Released 3.0.8.
|
||||
|
||||
* Fri Mar 21 2008 Wayne Davison <wayned@samba.org>
|
||||
Added installation of /etc/xinetd.d/rsync file and some commented-out
|
||||
|
||||
@@ -32,7 +32,7 @@ die "No '$patches_dir' directory was found.\n" unless -d $patches_dir;
|
||||
die "No '.git' directory present in the current dir.\n" unless -d '.git';
|
||||
|
||||
require 'packaging/git-status.pl';
|
||||
my $starting_branch = check_git_state($master_branch, !$skip_branch_check, 1);
|
||||
check_git_state($master_branch, !$skip_branch_check, 1);
|
||||
|
||||
my $master_commit;
|
||||
open PIPE, '-|', "git log -1 --no-color $master_branch" or die $!;
|
||||
@@ -124,7 +124,7 @@ if ($incl_generated_files) {
|
||||
}
|
||||
|
||||
sleep 1 while $last_touch >= time;
|
||||
system "git checkout $starting_branch" and exit 1;
|
||||
system "git checkout $master_branch" and exit 1;
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ system "packaging/patch-update --branch=$master_branch";
|
||||
|
||||
if ($ans =~ /^y/i) {
|
||||
print "\nVisiting all \"patch/$master_branch/*\" branches ...\n";
|
||||
system "packaging/patch-update --branch=$master_branch --skip-check --shell";
|
||||
system "packaging/patch-update --branch=$master_branch --shell";
|
||||
}
|
||||
|
||||
if (-d 'patches/.git') {
|
||||
|
||||
159
params.c
159
params.c
@@ -75,7 +75,6 @@
|
||||
|
||||
#include "rsync.h"
|
||||
#include "ifuncs.h"
|
||||
#include "itypes.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
* Constants...
|
||||
@@ -94,8 +93,6 @@
|
||||
|
||||
static char *bufr = NULL;
|
||||
static int bSize = 0;
|
||||
static BOOL (*the_sfunc)(char *);
|
||||
static BOOL (*the_pfunc)(char *, char *);
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
* Functions...
|
||||
@@ -226,7 +223,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
|
||||
bufr[end] = '\0';
|
||||
if( 0 == end ) /* Don't allow an empty name. */
|
||||
{
|
||||
rprintf(FLOG, "%s Empty section name in config file.\n", func );
|
||||
rprintf(FLOG, "%s Empty section name in configuration file.\n", func );
|
||||
return( False );
|
||||
}
|
||||
if( !sfunc( bufr ) ) /* Got a valid name. Deal with it. */
|
||||
@@ -239,7 +236,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
|
||||
if( i < 0 )
|
||||
{
|
||||
bufr[end] = '\0';
|
||||
rprintf(FLOG, "%s Badly formed line in config file: %s\n",
|
||||
rprintf(FLOG, "%s Badly formed line in configuration file: %s\n",
|
||||
func, bufr );
|
||||
return( False );
|
||||
}
|
||||
@@ -264,7 +261,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
|
||||
}
|
||||
|
||||
/* We arrive here if we've met the EOF before the closing bracket. */
|
||||
rprintf(FLOG, "%s Unexpected EOF in the config file: %s\n", func, bufr );
|
||||
rprintf(FLOG, "%s Unexpected EOF in the configuration file: %s\n", func, bufr );
|
||||
return( False );
|
||||
} /* Section */
|
||||
|
||||
@@ -318,12 +315,13 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
case '=': /* Equal sign marks end of param name. */
|
||||
if( 0 == end ) /* Don't allow an empty name. */
|
||||
{
|
||||
rprintf(FLOG, "%s Invalid parameter name in config file.\n", func );
|
||||
rprintf(FLOG, "%s Invalid parameter name in config. file.\n", func );
|
||||
return( False );
|
||||
}
|
||||
bufr[end++] = '\0'; /* Mark end of string & advance. */
|
||||
i = vstart = end; /* New string starts here. */
|
||||
c = EatWhitespace(InFile);
|
||||
i = end; /* New string starts here. */
|
||||
vstart = end; /* New string is parameter value. */
|
||||
bufr[i] = '\0'; /* New string is nul, for now. */
|
||||
break;
|
||||
|
||||
case '\n': /* Find continuation char, else error. */
|
||||
@@ -331,7 +329,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
if( i < 0 )
|
||||
{
|
||||
bufr[end] = '\0';
|
||||
rprintf(FLOG, "%s Ignoring badly formed line in config file: %s\n",
|
||||
rprintf(FLOG, "%s Ignoring badly formed line in configuration file: %s\n",
|
||||
func, bufr );
|
||||
return( True );
|
||||
}
|
||||
@@ -345,19 +343,6 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
rprintf(FLOG, "%s Unexpected end-of-file at: %s\n", func, bufr );
|
||||
return( True );
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
/* A directive divides at the first space or tab. */
|
||||
if (*bufr == '&') {
|
||||
bufr[end++] = '\0';
|
||||
i = vstart = end;
|
||||
c = EatWhitespace(InFile);
|
||||
if (c == '=')
|
||||
c = EatWhitespace(InFile);
|
||||
break;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
|
||||
default:
|
||||
if( isspace( c ) ) /* One ' ' per whitespace region. */
|
||||
{
|
||||
@@ -375,6 +360,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
}
|
||||
|
||||
/* Now parse the value. */
|
||||
c = EatWhitespace( InFile ); /* Again, trim leading whitespace. */
|
||||
while( (EOF !=c) && (c > 0) )
|
||||
{
|
||||
|
||||
@@ -420,88 +406,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
return( pfunc( bufr, &bufr[vstart] ) ); /* Pass name & value to pfunc(). */
|
||||
} /* Parameter */
|
||||
|
||||
static int name_cmp(const void *n1, const void *n2)
|
||||
{
|
||||
return strcmp(*(char * const *)n1, *(char * const *)n2);
|
||||
}
|
||||
|
||||
static int include_config(char *include, int manage_globals)
|
||||
{
|
||||
STRUCT_STAT sb;
|
||||
char *match = manage_globals ? "*.conf" : "*.inc";
|
||||
int ret;
|
||||
|
||||
if (do_stat(include, &sb) < 0) {
|
||||
rsyserr(FLOG, errno, "unable to stat config file \"%s\"", include);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S_ISREG(sb.st_mode)) {
|
||||
if (manage_globals && the_sfunc)
|
||||
the_sfunc("]push");
|
||||
ret = pm_process(include, the_sfunc, the_pfunc);
|
||||
if (manage_globals && the_sfunc)
|
||||
the_sfunc("]pop");
|
||||
} else if (S_ISDIR(sb.st_mode)) {
|
||||
char buf[MAXPATHLEN], **bpp;
|
||||
item_list conf_list;
|
||||
struct dirent *di;
|
||||
size_t j;
|
||||
DIR *d;
|
||||
|
||||
if (!(d = opendir(include))) {
|
||||
rsyserr(FLOG, errno, "unable to open config dir \"%s\"", include);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&conf_list, 0, sizeof conf_list);
|
||||
|
||||
while ((di = readdir(d)) != NULL) {
|
||||
char *dname = d_name(di);
|
||||
if (!wildmatch(match, dname))
|
||||
continue;
|
||||
bpp = EXPAND_ITEM_LIST(&conf_list, char *, 32);
|
||||
pathjoin(buf, sizeof buf, include, dname);
|
||||
*bpp = strdup(buf);
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
if (!(bpp = conf_list.items))
|
||||
return 1;
|
||||
|
||||
if (conf_list.count > 1)
|
||||
qsort(bpp, conf_list.count, sizeof (char *), name_cmp);
|
||||
|
||||
for (j = 0, ret = 1; j < conf_list.count; j++) {
|
||||
if (manage_globals && the_sfunc)
|
||||
the_sfunc(j == 0 ? "]push" : "]reset");
|
||||
if ((ret = pm_process(bpp[j], the_sfunc, the_pfunc)) != 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (manage_globals && the_sfunc)
|
||||
the_sfunc("]pop");
|
||||
|
||||
for (j = 0; j < conf_list.count; j++)
|
||||
free(bpp[j]);
|
||||
free(bpp);
|
||||
} else
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int parse_directives(char *name, char *val)
|
||||
{
|
||||
if (strcasecmp(name, "&include") == 0)
|
||||
return include_config(val, 1);
|
||||
if (strcasecmp(name, "&merge") == 0)
|
||||
return include_config(val, 0);
|
||||
rprintf(FLOG, "Unknown directive: %s.\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Parse( FILE *InFile,
|
||||
static BOOL Parse( FILE *InFile,
|
||||
BOOL (*sfunc)(char *),
|
||||
BOOL (*pfunc)(char *, char *) )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
@@ -513,8 +418,7 @@ static int Parse( FILE *InFile,
|
||||
* pfunc - Function to be called when a parameter is scanned.
|
||||
* See Parameter().
|
||||
*
|
||||
* Output: 1 if the file was successfully scanned, 2 if the file was
|
||||
* scanned until a section header with no section function, else 0.
|
||||
* Output: True if the file was successfully scanned, else False.
|
||||
*
|
||||
* Notes: The input can be viewed in terms of 'lines'. There are four
|
||||
* types of lines:
|
||||
@@ -523,7 +427,7 @@ static int Parse( FILE *InFile,
|
||||
* The remainder of the line is ignored.
|
||||
* Section - First non-whitespace character is a '['.
|
||||
* Parameter - The default case.
|
||||
*
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
{
|
||||
@@ -544,39 +448,29 @@ static int Parse( FILE *InFile,
|
||||
break;
|
||||
|
||||
case '[': /* Section Header. */
|
||||
if (!sfunc)
|
||||
return 2;
|
||||
if( !Section( InFile, sfunc ) )
|
||||
return 0;
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
if (!sfunc) return True;
|
||||
if( !Section( InFile, sfunc ) )
|
||||
return( False );
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
case '\\': /* Bogus backslash. */
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
case '&': /* Handle directives */
|
||||
the_sfunc = sfunc;
|
||||
the_pfunc = pfunc;
|
||||
c = Parameter( InFile, parse_directives, c );
|
||||
if (c != 1)
|
||||
return c;
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
default: /* Parameter line. */
|
||||
if( !Parameter( InFile, pfunc, c ) )
|
||||
return 0;
|
||||
return( False );
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return( True );
|
||||
} /* Parse */
|
||||
|
||||
static FILE *OpenConfFile( char *FileName )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
* Open a config file.
|
||||
* Open a configuration file.
|
||||
*
|
||||
* Input: FileName - The pathname of the config file to be opened.
|
||||
*
|
||||
@@ -591,21 +485,21 @@ static FILE *OpenConfFile( char *FileName )
|
||||
|
||||
if( NULL == FileName || 0 == *FileName )
|
||||
{
|
||||
rprintf(FLOG, "%s No config filename specified.\n", func);
|
||||
rprintf(FLOG, "%s No configuration filename specified.\n", func);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
OpenedFile = fopen( FileName, "r" );
|
||||
if( NULL == OpenedFile )
|
||||
{
|
||||
rsyserr(FLOG, errno, "unable to open config file \"%s\"",
|
||||
rsyserr(FLOG, errno, "unable to open configuration file \"%s\"",
|
||||
FileName);
|
||||
}
|
||||
|
||||
return( OpenedFile );
|
||||
} /* OpenConfFile */
|
||||
|
||||
int pm_process( char *FileName,
|
||||
BOOL pm_process( char *FileName,
|
||||
BOOL (*sfunc)(char *),
|
||||
BOOL (*pfunc)(char *, char *) )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
@@ -617,8 +511,7 @@ int pm_process( char *FileName,
|
||||
* pfunc - A pointer to a function that will be called when
|
||||
* a parameter name and value are discovered.
|
||||
*
|
||||
* Output: 1 if the file was successfully parsed, 2 if parsing ended at a
|
||||
* section header w/o a section function, else 0.
|
||||
* Output: TRUE if the file was successfully parsed, else FALSE.
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
@@ -656,10 +549,10 @@ int pm_process( char *FileName,
|
||||
if( !result ) /* Generic failure. */
|
||||
{
|
||||
rprintf(FLOG, "%s Failed. Error returned from params.c:parse().\n", func);
|
||||
return 0;
|
||||
return( False );
|
||||
}
|
||||
|
||||
return result;
|
||||
return( True ); /* Generic success. */
|
||||
} /* pm_process */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
19
pipe.c
19
pipe.c
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2004-2013 Wayne Davison
|
||||
* Copyright (C) 2004-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -26,10 +26,8 @@ extern int am_sender;
|
||||
extern int am_server;
|
||||
extern int blocking_io;
|
||||
extern int filesfrom_fd;
|
||||
extern int munge_symlinks;
|
||||
extern mode_t orig_umask;
|
||||
extern char *logfile_name;
|
||||
extern int remote_option_cnt;
|
||||
extern const char **remote_options;
|
||||
extern struct chmod_mode_struct *chmod_modes;
|
||||
|
||||
/**
|
||||
@@ -51,7 +49,7 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
|
||||
if (DEBUG_GTE(CMD, 1))
|
||||
if (verbose >= 2)
|
||||
print_child_argv("opening connection using:", command);
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
|
||||
@@ -77,6 +75,7 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
|
||||
close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO)
|
||||
close(from_child_pipe[1]);
|
||||
umask(orig_umask);
|
||||
set_blocking(STDIN_FILENO);
|
||||
if (blocking_io > 0)
|
||||
set_blocking(STDOUT_FILENO);
|
||||
@@ -132,7 +131,6 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
|
||||
am_sender = 0;
|
||||
am_server = 1;
|
||||
filesfrom_fd = -1;
|
||||
munge_symlinks = 0; /* Each side needs its own option. */
|
||||
chmod_modes = NULL; /* Let the sending side handle this. */
|
||||
|
||||
/* Let the client side handle this. */
|
||||
@@ -141,15 +139,6 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
|
||||
logfile_close();
|
||||
}
|
||||
|
||||
if (remote_option_cnt) {
|
||||
int rc = remote_option_cnt + 1;
|
||||
const char **rv = remote_options;
|
||||
if (!parse_arguments(&rc, &rv)) {
|
||||
option_error();
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
}
|
||||
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
|
||||
62
progress.c
62
progress.c
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -21,12 +21,9 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
|
||||
extern int am_server;
|
||||
extern int flist_eof;
|
||||
extern int need_unsorted_flist;
|
||||
extern int output_needs_newline;
|
||||
extern struct stats stats;
|
||||
extern struct file_list *cur_flist;
|
||||
|
||||
@@ -43,6 +40,8 @@ struct progress_history {
|
||||
OFF_T ofs;
|
||||
};
|
||||
|
||||
int progress_is_active = 0;
|
||||
|
||||
static struct progress_history ph_start;
|
||||
static struct progress_history ph_list[PROGRESS_HISTORY_SECS];
|
||||
static int newest_hpos, oldest_hpos;
|
||||
@@ -67,26 +66,11 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
{
|
||||
char rembuf[64], eol[128];
|
||||
const char *units;
|
||||
int pct = ofs == size ? 100 : (int) (100.0 * ofs / size);
|
||||
unsigned long diff;
|
||||
double rate, remain;
|
||||
int pct;
|
||||
|
||||
if (is_last) {
|
||||
int len = snprintf(eol, sizeof eol,
|
||||
" (xfr#%d, %s-chk=%d/%d)\n",
|
||||
stats.xferred_files, flist_eof ? "to" : "ir",
|
||||
stats.num_files - current_file_index - 1,
|
||||
stats.num_files);
|
||||
if (INFO_GTE(PROGRESS, 2)) {
|
||||
static int last_len = 0;
|
||||
/* Drop \n and pad with spaces if line got shorter. */
|
||||
if (last_len < --len)
|
||||
last_len = len;
|
||||
eol[last_len] = '\0';
|
||||
while (last_len > len)
|
||||
eol[--last_len] = ' ';
|
||||
is_last = 0;
|
||||
}
|
||||
/* Compute stats based on the starting info. */
|
||||
if (!ph_start.time.tv_sec
|
||||
|| !(diff = msdiff(&ph_start.time, now)))
|
||||
@@ -95,7 +79,6 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
/* Switch to total time taken for our last update. */
|
||||
remain = (double) diff / 1000.0;
|
||||
} else {
|
||||
strlcpy(eol, " ", sizeof eol);
|
||||
/* Compute stats based on recent progress. */
|
||||
if (!(diff = msdiff(&ph_list[oldest_hpos].time, now)))
|
||||
diff = 1;
|
||||
@@ -123,21 +106,23 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
(int) remain % 60);
|
||||
}
|
||||
|
||||
output_needs_newline = 0;
|
||||
pct = ofs == size ? 100 : (int) (100.0 * ofs / size);
|
||||
rprintf(FCLIENT, "\r%15s %3d%% %7.2f%s %s%s",
|
||||
if (is_last) {
|
||||
snprintf(eol, sizeof eol, " (xfer#%d, to-check=%d/%d)\n",
|
||||
stats.num_transferred_files,
|
||||
stats.num_files - current_file_index - 1,
|
||||
stats.num_files);
|
||||
} else
|
||||
strlcpy(eol, "\r", sizeof eol);
|
||||
progress_is_active = 0;
|
||||
rprintf(FCLIENT, "%12s %3d%% %7.2f%s %s%s",
|
||||
human_num(ofs), pct, rate, units, rembuf, eol);
|
||||
if (!is_last) {
|
||||
output_needs_newline = 1;
|
||||
rflush(FCLIENT);
|
||||
}
|
||||
if (!is_last)
|
||||
progress_is_active = 1;
|
||||
}
|
||||
|
||||
void set_current_file_index(struct file_struct *file, int ndx)
|
||||
{
|
||||
if (!file)
|
||||
current_file_index = cur_flist->used + cur_flist->ndx_start - 1;
|
||||
else if (need_unsorted_flist)
|
||||
if (need_unsorted_flist)
|
||||
current_file_index = flist_find(cur_flist, file) + cur_flist->ndx_start;
|
||||
else
|
||||
current_file_index = ndx;
|
||||
@@ -149,14 +134,9 @@ void end_progress(OFF_T size)
|
||||
if (!am_server) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if (INFO_GTE(PROGRESS, 2)) {
|
||||
rprint_progress(stats.total_transferred_size,
|
||||
stats.total_size, &now, True);
|
||||
} else {
|
||||
rprint_progress(size, size, &now, True);
|
||||
memset(&ph_start, 0, sizeof ph_start);
|
||||
}
|
||||
rprint_progress(size, size, &now, True);
|
||||
}
|
||||
memset(&ph_start, 0, sizeof ph_start);
|
||||
}
|
||||
|
||||
void show_progress(OFF_T ofs, OFF_T size)
|
||||
@@ -212,9 +192,5 @@ void show_progress(OFF_T ofs, OFF_T size)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (INFO_GTE(PROGRESS, 2)) {
|
||||
rprint_progress(stats.total_transferred_size,
|
||||
stats.total_size, &now, False);
|
||||
} else
|
||||
rprint_progress(ofs, size, &now, False);
|
||||
rprint_progress(ofs, size, &now, False);
|
||||
}
|
||||
|
||||
266
receiver.c
266
receiver.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,12 +20,13 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int do_xfers;
|
||||
extern int am_root;
|
||||
extern int am_server;
|
||||
extern int do_progress;
|
||||
extern int inc_recurse;
|
||||
extern int log_before_transfer;
|
||||
extern int stdout_format_has_i;
|
||||
@@ -45,21 +46,17 @@ extern int cleanup_got_literal;
|
||||
extern int remove_source_files;
|
||||
extern int append_mode;
|
||||
extern int sparse_files;
|
||||
extern int preallocate_files;
|
||||
extern int keep_partial;
|
||||
extern int checksum_len;
|
||||
extern int checksum_seed;
|
||||
extern int inplace;
|
||||
extern int allowed_lull;
|
||||
extern int delay_updates;
|
||||
extern mode_t orig_umask;
|
||||
extern struct stats stats;
|
||||
extern char *tmpdir;
|
||||
extern char *partial_dir;
|
||||
extern char *basis_dir[MAX_BASIS_DIRS+1];
|
||||
extern char sender_file_sum[MAX_DIGEST_LEN];
|
||||
extern struct file_list *cur_flist, *first_flist, *dir_flist;
|
||||
extern filter_rule_list daemon_filter_list;
|
||||
extern struct filter_list_struct daemon_filter_list;
|
||||
|
||||
static struct bitbag *delayed_bits = NULL;
|
||||
static int phase = 0, redoing = 0;
|
||||
@@ -69,8 +66,6 @@ static int updating_basis_or_equiv;
|
||||
|
||||
#define TMPNAME_SUFFIX ".XXXXXX"
|
||||
#define TMPNAME_SUFFIX_LEN ((int)sizeof TMPNAME_SUFFIX - 1)
|
||||
#define MAX_UNIQUE_NUMBER 999999
|
||||
#define MAX_UNIQUE_LOOP 100
|
||||
|
||||
/* get_tmpname() - create a tmp filename for a given filename
|
||||
*
|
||||
@@ -84,17 +79,12 @@ static int updating_basis_or_equiv;
|
||||
* the basename basically becomes 8 characters longer. In such a case, the
|
||||
* original name is shortened sufficiently to make it all fit.
|
||||
*
|
||||
* If the make_unique arg is True, the XXXXXX string is replaced with a unique
|
||||
* string that doesn't exist at the time of the check. This is intended to be
|
||||
* used for creating hard links, symlinks, devices, and special files, since
|
||||
* normal files should be handled by mkstemp() for safety.
|
||||
*
|
||||
* Of course, the only reason the file is based on the original name is to
|
||||
* make it easier to figure out what purpose a temp file is serving when a
|
||||
* transfer is in progress. */
|
||||
int get_tmpname(char *fnametmp, const char *fname, BOOL make_unique)
|
||||
int get_tmpname(char *fnametmp, const char *fname)
|
||||
{
|
||||
int maxname, length = 0;
|
||||
int maxname, added, length = 0;
|
||||
const char *f;
|
||||
char *suf;
|
||||
|
||||
@@ -113,8 +103,6 @@ int get_tmpname(char *fnametmp, const char *fname, BOOL make_unique)
|
||||
}
|
||||
} else
|
||||
f = fname;
|
||||
if (*f == '.') /* avoid an extra leading dot for OS X's sake */
|
||||
f++;
|
||||
fnametmp[length++] = '.';
|
||||
|
||||
/* The maxname value is bufsize, and includes space for the '\0'.
|
||||
@@ -122,56 +110,26 @@ int get_tmpname(char *fnametmp, const char *fname, BOOL make_unique)
|
||||
maxname = MIN(MAXPATHLEN - length - TMPNAME_SUFFIX_LEN,
|
||||
NAME_MAX - 1 - TMPNAME_SUFFIX_LEN);
|
||||
|
||||
if (maxname < 0) {
|
||||
if (maxname < 1) {
|
||||
rprintf(FERROR_XFER, "temporary filename too long: %s\n", fname);
|
||||
fnametmp[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (maxname) {
|
||||
int added = strlcpy(fnametmp + length, f, maxname);
|
||||
if (added >= maxname)
|
||||
added = maxname - 1;
|
||||
suf = fnametmp + length + added;
|
||||
added = strlcpy(fnametmp + length, f, maxname);
|
||||
if (added >= maxname)
|
||||
added = maxname - 1;
|
||||
suf = fnametmp + length + added;
|
||||
|
||||
/* Trim any dangling high-bit chars if the first-trimmed char (if any) is
|
||||
* also a high-bit char, just in case we cut into a multi-byte sequence.
|
||||
* We are guaranteed to stop because of the leading '.' we added. */
|
||||
if ((int)f[added] & 0x80) {
|
||||
while ((int)suf[-1] & 0x80)
|
||||
suf--;
|
||||
}
|
||||
/* trim one trailing dot before our suffix's dot */
|
||||
if (suf[-1] == '.')
|
||||
/* Trim any dangling high-bit chars if the first-trimmed char (if any) is
|
||||
* also a high-bit char, just in case we cut into a multi-byte sequence.
|
||||
* We are guaranteed to stop because of the leading '.' we added. */
|
||||
if ((int)f[added] & 0x80) {
|
||||
while ((int)suf[-1] & 0x80)
|
||||
suf--;
|
||||
} else
|
||||
suf = fnametmp + length - 1; /* overwrite the leading dot with suffix's dot */
|
||||
}
|
||||
|
||||
if (make_unique) {
|
||||
static unsigned counter_limit;
|
||||
unsigned counter;
|
||||
|
||||
if (!counter_limit) {
|
||||
counter_limit = (unsigned)getpid() + MAX_UNIQUE_LOOP;
|
||||
if (counter_limit > MAX_UNIQUE_NUMBER || counter_limit < MAX_UNIQUE_LOOP)
|
||||
counter_limit = MAX_UNIQUE_LOOP;
|
||||
}
|
||||
counter = counter_limit - MAX_UNIQUE_LOOP;
|
||||
|
||||
/* This doesn't have to be very good because we don't need
|
||||
* to worry about someone trying to guess the values: all
|
||||
* a conflict will do is cause a device, special file, hard
|
||||
* link, or symlink to fail to be created. Also: avoid
|
||||
* using mktemp() due to gcc's annoying warning. */
|
||||
while (1) {
|
||||
snprintf(suf, TMPNAME_SUFFIX_LEN+1, ".%d", counter);
|
||||
if (access(fnametmp, 0) < 0)
|
||||
break;
|
||||
if (++counter >= counter_limit)
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
memcpy(suf, TMPNAME_SUFFIX, TMPNAME_SUFFIX_LEN+1);
|
||||
memcpy(suf, TMPNAME_SUFFIX, TMPNAME_SUFFIX_LEN+1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -185,7 +143,7 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
|
||||
int fd;
|
||||
mode_t added_perms;
|
||||
|
||||
if (!get_tmpname(fnametmp, fname, False))
|
||||
if (!get_tmpname(fnametmp, fname))
|
||||
return -1;
|
||||
|
||||
if (am_root < 0) {
|
||||
@@ -208,9 +166,9 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
|
||||
* information should have been previously transferred, but that may
|
||||
* not be the case with -R */
|
||||
if (fd == -1 && relative_paths && errno == ENOENT
|
||||
&& make_path(fnametmp, MKP_SKIP_SLASH | MKP_DROP_NAME) == 0) {
|
||||
&& create_directory_path(fnametmp) == 0) {
|
||||
/* Get back to name with XXXXXX in it. */
|
||||
get_tmpname(fnametmp, fname, False);
|
||||
get_tmpname(fnametmp, fname);
|
||||
fd = do_mkstemp(fnametmp, (file->mode|added_perms) & INITACCESSPERMS);
|
||||
}
|
||||
#endif
|
||||
@@ -228,39 +186,24 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
const char *fname, int fd, OFF_T total_size)
|
||||
{
|
||||
static char file_sum1[MAX_DIGEST_LEN];
|
||||
static char file_sum2[MAX_DIGEST_LEN];
|
||||
struct map_struct *mapbuf;
|
||||
struct sum_struct sum;
|
||||
int32 len;
|
||||
int32 len, sum_len;
|
||||
OFF_T offset = 0;
|
||||
OFF_T offset2;
|
||||
char *data;
|
||||
int32 i;
|
||||
char *map = NULL;
|
||||
#ifdef SUPPORT_PREALLOCATION
|
||||
#ifdef PREALLOCATE_NEEDS_TRUNCATE
|
||||
OFF_T preallocated_len = 0;
|
||||
#endif
|
||||
|
||||
if (preallocate_files && fd != -1 && total_size > 0 && (!inplace || total_size > size_r)) {
|
||||
/* Try to preallocate enough space for file's eventual length. Can
|
||||
* reduce fragmentation on filesystems like ext4, xfs, and NTFS. */
|
||||
if (do_fallocate(fd, 0, total_size) == 0) {
|
||||
#ifdef PREALLOCATE_NEEDS_TRUNCATE
|
||||
preallocated_len = total_size;
|
||||
#endif
|
||||
} else
|
||||
rsyserr(FWARNING, errno, "do_fallocate %s", full_fname(fname));
|
||||
}
|
||||
#endif
|
||||
|
||||
read_sum_head(f_in, &sum);
|
||||
|
||||
if (fd_r >= 0 && size_r > 0) {
|
||||
int32 read_size = MAX(sum.blength * 2, 16*1024);
|
||||
mapbuf = map_file(fd_r, size_r, read_size, sum.blength);
|
||||
if (DEBUG_GTE(DELTASUM, 2)) {
|
||||
rprintf(FINFO, "recv mapped %s of size %s\n",
|
||||
fname_r, big_num(size_r));
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "recv mapped %s of size %.0f\n",
|
||||
fname_r, (double)size_r);
|
||||
}
|
||||
} else
|
||||
mapbuf = NULL;
|
||||
@@ -272,9 +215,9 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
sum.flength = (OFF_T)sum.count * sum.blength;
|
||||
if (sum.remainder)
|
||||
sum.flength -= sum.blength - sum.remainder;
|
||||
if (append_mode == 2 && mapbuf) {
|
||||
if (append_mode == 2) {
|
||||
for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
|
||||
if (INFO_GTE(PROGRESS, 1))
|
||||
if (do_progress)
|
||||
show_progress(offset, total_size);
|
||||
sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
|
||||
CHUNK_SIZE);
|
||||
@@ -282,30 +225,27 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
}
|
||||
if (offset < sum.flength) {
|
||||
int32 len = (int32)(sum.flength - offset);
|
||||
if (INFO_GTE(PROGRESS, 1))
|
||||
if (do_progress)
|
||||
show_progress(offset, total_size);
|
||||
sum_update(map_ptr(mapbuf, offset, len), len);
|
||||
}
|
||||
}
|
||||
offset = sum.flength;
|
||||
if (fd != -1 && (j = do_lseek(fd, offset, SEEK_SET)) != offset) {
|
||||
rsyserr(FERROR_XFER, errno, "lseek of %s returned %s, not %s",
|
||||
full_fname(fname), big_num(j), big_num(offset));
|
||||
rsyserr(FERROR_XFER, errno, "lseek of %s returned %.0f, not %.0f",
|
||||
full_fname(fname), (double)j, (double)offset);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
}
|
||||
|
||||
while ((i = recv_token(f_in, &data)) != 0) {
|
||||
if (INFO_GTE(PROGRESS, 1))
|
||||
if (do_progress)
|
||||
show_progress(offset, total_size);
|
||||
|
||||
if (allowed_lull)
|
||||
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH | MSK_ACTIVE_RECEIVER);
|
||||
|
||||
if (i > 0) {
|
||||
if (DEBUG_GTE(DELTASUM, 3)) {
|
||||
rprintf(FINFO,"data recv %d at %s\n",
|
||||
i, big_num(offset));
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,"data recv %d at %.0f\n",
|
||||
i,(double)offset);
|
||||
}
|
||||
|
||||
stats.literal_data += i;
|
||||
@@ -327,10 +267,10 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
|
||||
stats.matched_data += len;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 3)) {
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,
|
||||
"chunk[%d] of size %ld at %s offset=%s%s\n",
|
||||
i, (long)len, big_num(offset2), big_num(offset),
|
||||
"chunk[%d] of size %ld at %.0f offset=%.0f%s\n",
|
||||
i, (long)len, (double)offset2, (double)offset,
|
||||
updating_basis_or_equiv && offset == offset2 ? " (seek)" : "");
|
||||
}
|
||||
|
||||
@@ -349,9 +289,9 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
offset += len;
|
||||
if ((pos = do_lseek(fd, len, SEEK_CUR)) != offset) {
|
||||
rsyserr(FERROR_XFER, errno,
|
||||
"lseek of %s returned %s, not %s",
|
||||
"lseek of %s returned %.0f, not %.0f",
|
||||
full_fname(fname),
|
||||
big_num(pos), big_num(offset));
|
||||
(double)pos, (double)offset);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
continue;
|
||||
@@ -366,20 +306,13 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
goto report_write_error;
|
||||
|
||||
#ifdef HAVE_FTRUNCATE
|
||||
/* inplace: New data could be shorter than old data.
|
||||
* preallocate_files: total_size could have been an overestimate.
|
||||
* Cut off any extra preallocated zeros from dest file. */
|
||||
if ((inplace
|
||||
#ifdef PREALLOCATE_NEEDS_TRUNCATE
|
||||
|| preallocated_len > offset
|
||||
#endif
|
||||
) && fd != -1 && do_ftruncate(fd, offset) < 0) {
|
||||
if (inplace && fd != -1 && do_ftruncate(fd, offset) < 0) {
|
||||
rsyserr(FERROR_XFER, errno, "ftruncate failed on %s",
|
||||
full_fname(fname));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (INFO_GTE(PROGRESS, 1))
|
||||
if (do_progress)
|
||||
end_progress(total_size);
|
||||
|
||||
if (fd != -1 && offset > 0 && sparse_end(fd, offset) != 0) {
|
||||
@@ -389,16 +322,15 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
|
||||
if (sum_end(file_sum1) != checksum_len)
|
||||
overflow_exit("checksum_len"); /* Impossible... */
|
||||
sum_len = sum_end(file_sum1);
|
||||
|
||||
if (mapbuf)
|
||||
unmap_file(mapbuf);
|
||||
|
||||
read_buf(f_in, sender_file_sum, checksum_len);
|
||||
if (DEBUG_GTE(DELTASUM, 2))
|
||||
read_buf(f_in, file_sum2, sum_len);
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"got file_sum\n");
|
||||
if (fd != -1 && memcmp(file_sum1, sender_file_sum, checksum_len) != 0)
|
||||
if (fd != -1 && memcmp(file_sum1, file_sum2, sum_len) != 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -418,9 +350,9 @@ static void handle_delayed_updates(char *local_name)
|
||||
struct file_struct *file = cur_flist->files[ndx];
|
||||
fname = local_name ? local_name : f_name(file, NULL);
|
||||
if ((partialptr = partial_dir_fname(fname)) != NULL) {
|
||||
if (make_backups > 0 && !make_backup(fname, False))
|
||||
if (make_backups > 0 && !make_backup(fname))
|
||||
continue;
|
||||
if (DEBUG_GTE(RECV, 1)) {
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "renaming %s to %s\n",
|
||||
partialptr, fname);
|
||||
}
|
||||
@@ -471,18 +403,16 @@ static int we_want_redo(int desired_ndx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gen_wants_ndx(int desired_ndx, int flist_num)
|
||||
static int gen_wants_ndx(int desired_ndx)
|
||||
{
|
||||
static int next_ndx = -1;
|
||||
static int done_cnt = 0;
|
||||
static BOOL got_eof = False;
|
||||
int flist_num = first_flist->flist_num;
|
||||
|
||||
if (got_eof)
|
||||
return 0;
|
||||
|
||||
/* TODO: integrate gen-reading I/O into perform_io() so this is not needed? */
|
||||
io_flush(FULL_FLUSH);
|
||||
|
||||
while (next_ndx < desired_ndx) {
|
||||
if (inc_recurse && flist_num <= done_cnt)
|
||||
return 0;
|
||||
@@ -510,7 +440,7 @@ static int gen_wants_ndx(int desired_ndx, int flist_num)
|
||||
* main routine for receiver process.
|
||||
*
|
||||
* Receiver process runs on the same host as the generator process. */
|
||||
int recv_files(int f_in, int f_out, char *local_name)
|
||||
int recv_files(int f_in, char *local_name)
|
||||
{
|
||||
int fd1,fd2;
|
||||
STRUCT_STAT st;
|
||||
@@ -522,6 +452,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
char fnamecmpbuf[MAXPATHLEN];
|
||||
uchar fnamecmp_type;
|
||||
struct file_struct *file;
|
||||
struct stats initial_stats;
|
||||
int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i;
|
||||
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
|
||||
int max_phase = protocol_version >= 29 ? 2 : 1;
|
||||
@@ -531,7 +462,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
#endif
|
||||
int ndx, recv_ok;
|
||||
|
||||
if (DEBUG_GTE(RECV, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "recv_files(%d) starting\n", cur_flist->used);
|
||||
|
||||
if (delay_updates)
|
||||
@@ -541,32 +472,24 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
cleanup_disable();
|
||||
|
||||
/* This call also sets cur_flist. */
|
||||
ndx = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type,
|
||||
ndx = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
|
||||
xname, &xlen);
|
||||
if (ndx == NDX_DONE) {
|
||||
if (!am_server && INFO_GTE(PROGRESS, 2) && cur_flist) {
|
||||
set_current_file_index(NULL, 0);
|
||||
end_progress(0);
|
||||
}
|
||||
if (inc_recurse && first_flist) {
|
||||
if (read_batch) {
|
||||
ndx = first_flist->used + first_flist->ndx_start;
|
||||
gen_wants_ndx(ndx, first_flist->flist_num);
|
||||
}
|
||||
if (read_batch)
|
||||
gen_wants_ndx(first_flist->used + first_flist->ndx_start);
|
||||
flist_free(first_flist);
|
||||
if (first_flist)
|
||||
continue;
|
||||
} else if (read_batch && first_flist) {
|
||||
ndx = first_flist->used;
|
||||
gen_wants_ndx(ndx, first_flist->flist_num);
|
||||
}
|
||||
} else if (read_batch && first_flist)
|
||||
gen_wants_ndx(first_flist->used);
|
||||
if (++phase > max_phase)
|
||||
break;
|
||||
if (DEBUG_GTE(RECV, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "recv_files phase=%d\n", phase);
|
||||
if (phase == 2 && delay_updates)
|
||||
handle_delayed_updates(local_name);
|
||||
write_int(f_out, NDX_DONE);
|
||||
send_msg(MSG_DONE, "", 0, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -576,12 +499,11 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
file = dir_flist->files[cur_flist->parent_ndx];
|
||||
fname = local_name ? local_name : f_name(file, fbuf);
|
||||
|
||||
if (DEBUG_GTE(RECV, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "recv_files(%s)\n", fname);
|
||||
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
|
||||
&& (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
|
||||
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
|
||||
recv_xattr_request(file, f_in);
|
||||
#endif
|
||||
|
||||
@@ -592,21 +514,6 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
&& !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))
|
||||
set_file_attrs(fname, file, NULL, fname, 0);
|
||||
#endif
|
||||
if (iflags & ITEM_IS_NEW) {
|
||||
stats.created_files++;
|
||||
if (S_ISREG(file->mode)) {
|
||||
/* Nothing further to count. */
|
||||
} else if (S_ISDIR(file->mode))
|
||||
stats.created_dirs++;
|
||||
#ifdef SUPPORT_LINKS
|
||||
else if (S_ISLNK(file->mode))
|
||||
stats.created_symlinks++;
|
||||
#endif
|
||||
else if (IS_DEVICE(file->mode))
|
||||
stats.created_devices++;
|
||||
else
|
||||
stats.created_specials++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (phase == 2) {
|
||||
@@ -636,13 +543,11 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
csum_length = SHORT_SUM_LENGTH;
|
||||
redoing = 0;
|
||||
}
|
||||
if (iflags & ITEM_IS_NEW)
|
||||
stats.created_files++;
|
||||
}
|
||||
|
||||
if (!am_server && INFO_GTE(PROGRESS, 1))
|
||||
if (!am_server && do_progress)
|
||||
set_current_file_index(file, ndx);
|
||||
stats.xferred_files++;
|
||||
stats.num_transferred_files++;
|
||||
stats.total_transferred_size += F_LENGTH(file);
|
||||
|
||||
cleanup_got_literal = 0;
|
||||
@@ -656,7 +561,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
if (read_batch) {
|
||||
int wanted = redoing
|
||||
? we_want_redo(ndx)
|
||||
: gen_wants_ndx(ndx, cur_flist->flist_num);
|
||||
: gen_wants_ndx(ndx);
|
||||
if (!wanted) {
|
||||
rprintf(FINFO,
|
||||
"(Skipping batched update for%s \"%s\")\n",
|
||||
@@ -668,21 +573,16 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
}
|
||||
}
|
||||
|
||||
if (!log_before_transfer)
|
||||
remember_initial_stats();
|
||||
|
||||
if (!do_xfers) { /* log the transfer */
|
||||
log_item(FCLIENT, file, iflags, NULL);
|
||||
log_item(FCLIENT, file, &stats, iflags, NULL);
|
||||
if (read_batch)
|
||||
discard_receive_data(f_in, F_LENGTH(file));
|
||||
continue;
|
||||
}
|
||||
if (write_batch < 0) {
|
||||
log_item(FCLIENT, file, iflags, NULL);
|
||||
log_item(FCLIENT, file, &stats, iflags, NULL);
|
||||
if (!am_server)
|
||||
discard_receive_data(f_in, F_LENGTH(file));
|
||||
if (inc_recurse)
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -701,26 +601,21 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
break;
|
||||
case FNAMECMP_FUZZY:
|
||||
if (file->dirname) {
|
||||
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, file->dirname, xname);
|
||||
pathjoin(fnamecmpbuf, MAXPATHLEN,
|
||||
file->dirname, xname);
|
||||
fnamecmp = fnamecmpbuf;
|
||||
} else
|
||||
fnamecmp = xname;
|
||||
break;
|
||||
default:
|
||||
if (fnamecmp_type > FNAMECMP_FUZZY && fnamecmp_type-FNAMECMP_FUZZY <= basis_dir_cnt) {
|
||||
fnamecmp_type -= FNAMECMP_FUZZY + 1;
|
||||
if (file->dirname) {
|
||||
stringjoin(fnamecmpbuf, sizeof fnamecmpbuf,
|
||||
basis_dir[fnamecmp_type], "/", file->dirname, "/", xname, NULL);
|
||||
} else
|
||||
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], xname);
|
||||
} else if (fnamecmp_type >= basis_dir_cnt) {
|
||||
if (fnamecmp_type >= basis_dir_cnt) {
|
||||
rprintf(FERROR,
|
||||
"invalid basis_dir index: %d.\n",
|
||||
fnamecmp_type);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
} else
|
||||
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], fname);
|
||||
}
|
||||
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
|
||||
basis_dir[fnamecmp_type], fname);
|
||||
fnamecmp = fnamecmpbuf;
|
||||
break;
|
||||
}
|
||||
@@ -743,6 +638,8 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
fnamecmp = fname;
|
||||
}
|
||||
|
||||
initial_stats = stats;
|
||||
|
||||
/* open the file */
|
||||
fd1 = do_open(fnamecmp, O_RDONLY, 0);
|
||||
|
||||
@@ -819,8 +716,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
if (fd2 == -1) {
|
||||
rsyserr(FERROR_XFER, errno, "open %s failed",
|
||||
full_fname(fname));
|
||||
} else if (updating_basis_or_equiv)
|
||||
cleanup_set(NULL, NULL, file, fd1, fd2);
|
||||
}
|
||||
} else {
|
||||
fd2 = open_tmpfile(fnametmp, fname, file);
|
||||
if (fd2 != -1)
|
||||
@@ -838,15 +734,15 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
|
||||
/* log the transfer */
|
||||
if (log_before_transfer)
|
||||
log_item(FCLIENT, file, iflags, NULL);
|
||||
else if (!am_server && INFO_GTE(NAME, 1) && INFO_EQ(PROGRESS, 1))
|
||||
log_item(FCLIENT, file, &initial_stats, iflags, NULL);
|
||||
else if (!am_server && verbose && do_progress)
|
||||
rprintf(FINFO, "%s\n", fname);
|
||||
|
||||
/* recv file data */
|
||||
recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
|
||||
fname, fd2, F_LENGTH(file));
|
||||
|
||||
log_item(log_code, file, iflags, NULL);
|
||||
log_item(log_code, file, &initial_stats, iflags, NULL);
|
||||
|
||||
if (fd1 != -1)
|
||||
close(fd1);
|
||||
@@ -900,7 +796,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
break;
|
||||
case 0: {
|
||||
enum logcode msgtype = redoing ? FERROR_XFER : FWARNING;
|
||||
if (msgtype == FERROR_XFER || INFO_GTE(NAME, 1)) {
|
||||
if (msgtype == FERROR_XFER || verbose) {
|
||||
char *errstr, *redostr, *keptstr;
|
||||
if (!(keep_partial && partialptr) && !inplace)
|
||||
keptstr = "discarded";
|
||||
@@ -942,7 +838,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
||||
if (phase == 2 && delay_updates) /* for protocol_version < 29 */
|
||||
handle_delayed_updates(local_name);
|
||||
|
||||
if (DEBUG_GTE(RECV, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"recv_files finished\n");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* A pre-compilation helper program to aid in the creation of rounding.h.
|
||||
*
|
||||
* Copyright (C) 2007-2013 Wayne Davison
|
||||
* Copyright (C) 2007-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
12
rsync-ssl.in
12
rsync-ssl.in
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This script supports using stunnel to secure an rsync daemon connection.
|
||||
# Note that this requires at least version 4.x of stunnel.
|
||||
case "$@" in
|
||||
*rsync://*) ;;
|
||||
*::*) ;;
|
||||
*)
|
||||
echo "You must use rsync-ssl with a daemon-style hostname." 0>&1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
exec @bindir@/rsync --rsh=@bindir@/stunnel-rsync "${@}"
|
||||
240
rsync.c
240
rsync.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int preserve_acls;
|
||||
extern int preserve_xattrs;
|
||||
@@ -35,18 +36,15 @@ extern int preserve_executability;
|
||||
extern int preserve_times;
|
||||
extern int am_root;
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int am_sender;
|
||||
extern int am_receiver;
|
||||
extern int am_generator;
|
||||
extern int am_starting_up;
|
||||
extern int allow_8bit_chars;
|
||||
extern int protocol_version;
|
||||
extern int got_kill_signal;
|
||||
extern int inc_recurse;
|
||||
extern int inplace;
|
||||
extern int flist_eof;
|
||||
extern int file_old_total;
|
||||
extern int keep_dirlinks;
|
||||
extern int make_backups;
|
||||
extern struct file_list *cur_flist, *first_flist, *dir_flist;
|
||||
@@ -84,20 +82,19 @@ void setup_iconv(void)
|
||||
/* It's OK if this fails... */
|
||||
ic_chck = iconv_open(defset, defset);
|
||||
|
||||
if (DEBUG_GTE(ICONV, 2)) {
|
||||
if (verbose > 3) {
|
||||
if (ic_chck == (iconv_t)-1) {
|
||||
rprintf(FINFO,
|
||||
"msg checking via isprint()"
|
||||
" (iconv_open(\"%s\", \"%s\") errno: %d)\n",
|
||||
"note: iconv_open(\"%s\", \"%s\") failed (%d)"
|
||||
" -- using isprint() instead of iconv().\n",
|
||||
defset, defset, errno);
|
||||
} else {
|
||||
rprintf(FINFO,
|
||||
"msg checking charset: %s\n",
|
||||
defset);
|
||||
"note: iconv_open(\"%s\", \"%s\") succeeded.\n",
|
||||
defset, defset);
|
||||
}
|
||||
}
|
||||
} else
|
||||
ic_chck = (iconv_t)-1;
|
||||
}
|
||||
|
||||
# ifdef ICONV_OPTION
|
||||
if (!iconv_opt)
|
||||
@@ -127,82 +124,47 @@ void setup_iconv(void)
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(ICONV, 1)) {
|
||||
rprintf(FINFO, "[%s] charset: %s\n",
|
||||
who_am_i(), *charset ? charset : "[LOCALE]");
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO, "%s charset: %s\n",
|
||||
am_server ? "server" : "client",
|
||||
*charset ? charset : "[LOCALE]");
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/* This function converts the chars in the "in" xbuf into characters in the
|
||||
* "out" xbuf. The ".len" chars of the "in" xbuf is used starting from its
|
||||
* ".pos". The ".size" of the "out" xbuf restricts how many characters can
|
||||
* be stored, starting at its ".pos+.len" position. Note that the last byte
|
||||
* of the "out" xbuf is not used, which reserves space for a trailing '\0'
|
||||
* (though it is up to the caller to store a trailing '\0', as needed).
|
||||
*
|
||||
/* This function converts the characters in the "in" xbuf into characters
|
||||
* in the "out" xbuf. The "len" of the "in" xbuf is used starting from its
|
||||
* "pos". The "size" of the "out" xbuf restricts how many characters can be
|
||||
* stored, starting at its "pos+len" position. Note that the last byte of
|
||||
* the buffer is never used, which reserves space for a terminating '\0'.
|
||||
* We return a 0 on success or a -1 on error. An error also sets errno to
|
||||
* E2BIG, EILSEQ, or EINVAL (see below); otherwise errno will be set to 0.
|
||||
* The "in" xbuf is altered to update ".pos" and ".len". The "out" xbuf has
|
||||
* data appended, and its ".len" incremented (see below for a ".size" note).
|
||||
*
|
||||
* If ICB_CIRCULAR_OUT is set in "flags", the chars going into the "out" xbuf
|
||||
* can wrap around to the start, and the xbuf may have its ".size" reduced
|
||||
* (presumably by 1 byte) if the iconv code doesn't have space to store a
|
||||
* multi-byte character at the physical end of the ".buf" (though no reducing
|
||||
* happens if ".pos" is <= 1, since there is no room to wrap around).
|
||||
*
|
||||
* If ICB_EXPAND_OUT is set in "flags", the "out" xbuf will be allocated if
|
||||
* empty, and (as long as ICB_CIRCULAR_OUT is not set) expanded if too small.
|
||||
* This prevents the return of E2BIG (except for a circular xbuf).
|
||||
*
|
||||
* If ICB_INCLUDE_BAD is set in "flags", any badly-encoded chars are included
|
||||
* verbatim in the "out" xbuf, so EILSEQ will not be returned.
|
||||
*
|
||||
* If ICB_INCLUDE_INCOMPLETE is set in "flags", any incomplete multi-byte
|
||||
* chars are included, which ensures that EINVAL is not returned.
|
||||
*
|
||||
* If ICB_INIT is set, the iconv() conversion state is initialized prior to
|
||||
* processing the characters. */
|
||||
* The "in" xbuf is altered to update "pos" and "len". The "out" xbuf has
|
||||
* data appended, and its "len" incremented. If ICB_EXPAND_OUT is set in
|
||||
* "flags", the "out" xbuf will also be allocated if empty, and expanded if
|
||||
* too small (so E2BIG will not be returned). If ICB_INCLUDE_BAD is set in
|
||||
* "flags", any badly-encoded chars are included verbatim in the "out" xbuf,
|
||||
* so EILSEQ will not be returned. Likewise for ICB_INCLUDE_INCOMPLETE with
|
||||
* respect to an incomplete multi-byte char at the end, which ensures that
|
||||
* EINVAL is not returned. Anytime "in.pos" is 0 we will reset the iconv()
|
||||
* state prior to processing the characters. */
|
||||
int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags)
|
||||
{
|
||||
ICONV_CONST char *ibuf;
|
||||
size_t icnt, ocnt, opos;
|
||||
size_t icnt, ocnt;
|
||||
char *obuf;
|
||||
|
||||
if (!out->size && flags & ICB_EXPAND_OUT) {
|
||||
size_t siz = ROUND_UP_1024(in->len * 2);
|
||||
alloc_xbuf(out, siz);
|
||||
} else if (out->len+1 >= out->size) {
|
||||
/* There is no room to even start storing data. */
|
||||
if (!(flags & ICB_EXPAND_OUT) || flags & ICB_CIRCULAR_OUT) {
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
realloc_xbuf(out, out->size + ROUND_UP_1024(in->len * 2));
|
||||
}
|
||||
if (!out->size && flags & ICB_EXPAND_OUT)
|
||||
alloc_xbuf(out, 1024);
|
||||
|
||||
if (flags & ICB_INIT)
|
||||
if (!in->pos)
|
||||
iconv(ic, NULL, 0, NULL, 0);
|
||||
|
||||
ibuf = in->buf + in->pos;
|
||||
icnt = in->len;
|
||||
|
||||
opos = out->pos + out->len;
|
||||
if (flags & ICB_CIRCULAR_OUT) {
|
||||
if (opos >= out->size) {
|
||||
opos -= out->size;
|
||||
/* We know that out->pos is not 0 due to the "no room" check
|
||||
* above, so this can't go "negative". */
|
||||
ocnt = out->pos - opos - 1;
|
||||
} else {
|
||||
/* Allow the use of all bytes to the physical end of the buffer
|
||||
* unless pos is 0, in which case we reserve our trailing '\0'. */
|
||||
ocnt = out->size - opos - (out->pos ? 0 : 1);
|
||||
}
|
||||
} else
|
||||
ocnt = out->size - opos - 1;
|
||||
obuf = out->buf + opos;
|
||||
obuf = out->buf + (out->pos + out->len);
|
||||
ocnt = out->size - (out->pos + out->len) - 1;
|
||||
|
||||
while (icnt) {
|
||||
while (iconv(ic, &ibuf, &icnt, &obuf, &ocnt) == (size_t)-1) {
|
||||
@@ -211,58 +173,31 @@ int iconvbufs(iconv_t ic, xbuf *in, xbuf *out, int flags)
|
||||
if (errno == EINVAL) {
|
||||
if (!(flags & ICB_INCLUDE_INCOMPLETE))
|
||||
goto finish;
|
||||
if (!ocnt)
|
||||
goto e2big;
|
||||
} else if (errno == EILSEQ) {
|
||||
if (!(flags & ICB_INCLUDE_BAD))
|
||||
goto finish;
|
||||
if (!ocnt)
|
||||
goto e2big;
|
||||
} else if (errno == E2BIG) {
|
||||
size_t siz;
|
||||
e2big:
|
||||
opos = obuf - out->buf;
|
||||
if (flags & ICB_CIRCULAR_OUT && out->pos > 1 && opos > out->pos) {
|
||||
/* We are in a divided circular buffer at the physical
|
||||
* end with room to wrap to the start. If iconv() refused
|
||||
* to use one or more trailing bytes in the buffer, we
|
||||
* set the size to ignore the unused bytes. */
|
||||
if (opos < out->size)
|
||||
reduce_iobuf_size(out, opos);
|
||||
obuf = out->buf;
|
||||
ocnt = out->pos - 1;
|
||||
continue;
|
||||
}
|
||||
if (!(flags & ICB_EXPAND_OUT) || flags & ICB_CIRCULAR_OUT) {
|
||||
} else {
|
||||
size_t opos = obuf - out->buf;
|
||||
if (!(flags & ICB_EXPAND_OUT)) {
|
||||
errno = E2BIG;
|
||||
goto finish;
|
||||
}
|
||||
siz = ROUND_UP_1024(in->len * 2);
|
||||
realloc_xbuf(out, out->size + siz);
|
||||
realloc_xbuf(out, out->size + 1024);
|
||||
obuf = out->buf + opos;
|
||||
ocnt += siz;
|
||||
ocnt += 1024;
|
||||
continue;
|
||||
} else {
|
||||
rsyserr(FERROR, errno, "unexpected error from iconv()");
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
*obuf++ = *ibuf++;
|
||||
ocnt--, icnt--;
|
||||
if (!icnt)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
finish:
|
||||
opos = obuf - out->buf;
|
||||
if (flags & ICB_CIRCULAR_OUT && opos < out->pos)
|
||||
opos += out->size;
|
||||
out->len = opos - out->pos;
|
||||
|
||||
in->len = icnt;
|
||||
in->pos = ibuf - in->buf;
|
||||
out->len = obuf - out->buf - out->pos;
|
||||
|
||||
return errno ? -1 : 0;
|
||||
}
|
||||
@@ -281,7 +216,7 @@ void send_protected_args(int fd, char *args[])
|
||||
|
||||
for (i = 0; args[i]; i++) {} /* find first NULL */
|
||||
args[i] = "rsync"; /* set a new arg0 */
|
||||
if (DEBUG_GTE(CMD, 1))
|
||||
if (verbose > 1)
|
||||
print_child_argv("protected args:", args + i + 1);
|
||||
do {
|
||||
if (!args[i][0])
|
||||
@@ -290,7 +225,7 @@ void send_protected_args(int fd, char *args[])
|
||||
else if (convert) {
|
||||
INIT_XBUF_STRLEN(inbuf, args[i]);
|
||||
iconvbufs(ic_send, &inbuf, &outbuf,
|
||||
ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_INIT);
|
||||
ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE);
|
||||
outbuf.buf[outbuf.len] = '\0';
|
||||
write_buf(fd, outbuf.buf, outbuf.len + 1);
|
||||
outbuf.len = 0;
|
||||
@@ -307,13 +242,13 @@ void send_protected_args(int fd, char *args[])
|
||||
#endif
|
||||
}
|
||||
|
||||
int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
|
||||
int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
|
||||
char *buf, int *len_ptr)
|
||||
{
|
||||
int len, iflags = 0;
|
||||
struct file_list *flist;
|
||||
uchar fnamecmp_type = FNAMECMP_FNAME;
|
||||
int ndx;
|
||||
int ndx, save_verbose = verbose;
|
||||
|
||||
read_loop:
|
||||
while (1) {
|
||||
@@ -323,12 +258,6 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
|
||||
break;
|
||||
if (ndx == NDX_DONE)
|
||||
return ndx;
|
||||
if (ndx == NDX_DEL_STATS) {
|
||||
read_del_stats(f_in);
|
||||
if (am_sender && am_server)
|
||||
write_del_stats(f_out);
|
||||
continue;
|
||||
}
|
||||
if (!inc_recurse || am_sender) {
|
||||
int last;
|
||||
if (first_flist)
|
||||
@@ -342,9 +271,7 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
|
||||
}
|
||||
if (ndx == NDX_FLIST_EOF) {
|
||||
flist_eof = 1;
|
||||
if (DEBUG_GTE(FLIST, 3))
|
||||
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i());
|
||||
write_int(f_out, NDX_FLIST_EOF);
|
||||
send_msg(MSG_FLIST_EOF, "", 0, 0);
|
||||
continue;
|
||||
}
|
||||
ndx = NDX_FLIST_OFFSET - ndx;
|
||||
@@ -358,15 +285,18 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(FLIST, 2)) {
|
||||
/* Send everything read from f_in to msg_fd_out. */
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO, "[%s] receiving flist for dir %d\n",
|
||||
who_am_i(), ndx);
|
||||
}
|
||||
/* Send all the data we read for this flist to the generator. */
|
||||
start_flist_forward(ndx);
|
||||
verbose = 0;
|
||||
send_msg_int(MSG_FLIST, ndx);
|
||||
start_flist_forward(f_in);
|
||||
flist = recv_file_list(f_in);
|
||||
flist->parent_ndx = ndx;
|
||||
stop_flist_forward();
|
||||
verbose = save_verbose;
|
||||
}
|
||||
|
||||
iflags = protocol_version >= 29 ? read_shortint(f_in)
|
||||
@@ -375,19 +305,11 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag_ptr, uchar *type_ptr,
|
||||
/* Support the protocol-29 keep-alive style. */
|
||||
if (protocol_version < 30 && ndx == cur_flist->used && iflags == ITEM_IS_NEW) {
|
||||
if (am_sender)
|
||||
maybe_send_keepalive(time(NULL), MSK_ALLOW_FLUSH);
|
||||
maybe_send_keepalive();
|
||||
goto read_loop;
|
||||
}
|
||||
|
||||
flist = flist_for_ndx(ndx, "read_ndx_and_attrs");
|
||||
if (flist != cur_flist) {
|
||||
cur_flist = flist;
|
||||
if (am_sender) {
|
||||
file_old_total = cur_flist->used;
|
||||
for (flist = first_flist; flist != cur_flist; flist = flist->next)
|
||||
file_old_total += flist->used;
|
||||
}
|
||||
}
|
||||
cur_flist = flist_for_ndx(ndx, "read_ndx_and_attrs");
|
||||
|
||||
if (iflags & ITEM_BASIS_TYPE_FOLLOWS)
|
||||
fnamecmp_type = read_byte(f_in);
|
||||
@@ -469,7 +391,12 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
|
||||
full_fname(fname));
|
||||
return 0;
|
||||
}
|
||||
init_stat_x(&sx2);
|
||||
#ifdef SUPPORT_ACLS
|
||||
sx2.acc_acl = sx2.def_acl = NULL;
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
sx2.xattr = NULL;
|
||||
#endif
|
||||
sxp = &sx2;
|
||||
inherit = !preserve_perms;
|
||||
} else
|
||||
@@ -502,7 +429,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
|
||||
flags |= ATTRS_SKIP_MTIME;
|
||||
if (!(flags & ATTRS_SKIP_MTIME)
|
||||
&& cmp_time(sxp->st.st_mtime, file->modtime) != 0) {
|
||||
int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode);
|
||||
int ret = set_modtime(fname, file->modtime, sxp->st.st_mode);
|
||||
if (ret < 0) {
|
||||
rsyserr(FERROR_XFER, errno, "failed to set times on %s",
|
||||
full_fname(fname));
|
||||
@@ -523,7 +450,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
|
||||
} else
|
||||
#endif
|
||||
if (change_uid || change_gid) {
|
||||
if (DEBUG_GTE(OWN, 1)) {
|
||||
if (verbose > 2) {
|
||||
if (change_uid) {
|
||||
rprintf(FINFO,
|
||||
"set uid of %s from %u to %u\n",
|
||||
@@ -588,20 +515,27 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (INFO_GTE(NAME, 2) && flags & ATTRS_REPORT) {
|
||||
if (verbose > 1 && flags & ATTRS_REPORT) {
|
||||
if (updated)
|
||||
rprintf(FCLIENT, "%s\n", fname);
|
||||
else
|
||||
rprintf(FCLIENT, "%s is uptodate\n", fname);
|
||||
}
|
||||
cleanup:
|
||||
if (sxp == &sx2)
|
||||
free_stat_x(&sx2);
|
||||
if (sxp == &sx2) {
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls)
|
||||
free_acl(&sx2);
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs)
|
||||
free_xattr(&sx2);
|
||||
#endif
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/* This is only called for SIGINT, SIGHUP, and SIGTERM. */
|
||||
RETSIGTYPE sig_int(int sig_num)
|
||||
RETSIGTYPE sig_int(UNUSED(int val))
|
||||
{
|
||||
/* KLUGE: if the user hits Ctrl-C while ssh is prompting
|
||||
* for a password, then our cleanup's sending of a SIGUSR1
|
||||
@@ -612,23 +546,6 @@ RETSIGTYPE sig_int(int sig_num)
|
||||
* not ssh waiting for a password, then this tiny delay
|
||||
* shouldn't hurt anything. */
|
||||
msleep(400);
|
||||
|
||||
/* If we're an rsync daemon listener (not a daemon server),
|
||||
* we'll exit with status 0 if we received SIGTERM. */
|
||||
if (am_daemon && !am_server && sig_num == SIGTERM)
|
||||
exit_cleanup(0);
|
||||
|
||||
/* If the signal arrived on the server side (or for the receiver
|
||||
* process on the client), we want to try to do a controlled shutdown
|
||||
* that lets the client side (generator process) know what happened.
|
||||
* To do this, we set a flag and let the normal process handle the
|
||||
* shutdown. We only attempt this if multiplexed IO is in effect and
|
||||
* we didn't already set the flag. */
|
||||
if (!got_kill_signal && (am_server || am_receiver)) {
|
||||
got_kill_signal = sig_num;
|
||||
return;
|
||||
}
|
||||
|
||||
exit_cleanup(RERR_SIGNAL);
|
||||
}
|
||||
|
||||
@@ -646,17 +563,16 @@ int finish_transfer(const char *fname, const char *fnametmp,
|
||||
const char *temp_copy_name = partialptr && *partialptr != '/' ? partialptr : NULL;
|
||||
|
||||
if (inplace) {
|
||||
if (DEBUG_GTE(RECV, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "finishing %s\n", fname);
|
||||
fnametmp = fname;
|
||||
goto do_set_file_attrs;
|
||||
}
|
||||
|
||||
if (make_backups > 0 && overwriting_basis) {
|
||||
int ok = make_backup(fname, False);
|
||||
if (!ok)
|
||||
if (!make_backup(fname))
|
||||
return 1;
|
||||
if (ok == 1 && fnamecmp == fname)
|
||||
if (fnamecmp == fname)
|
||||
fnamecmp = get_backup_name(fname);
|
||||
}
|
||||
|
||||
@@ -665,15 +581,17 @@ int finish_transfer(const char *fname, const char *fnametmp,
|
||||
ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
|
||||
|
||||
/* move tmp file over real file */
|
||||
if (DEBUG_GTE(RECV, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
|
||||
ret = robust_rename(fnametmp, fname, temp_copy_name, file->mode);
|
||||
ret = robust_rename(fnametmp, fname, temp_copy_name,
|
||||
file->mode & INITACCESSPERMS);
|
||||
if (ret < 0) {
|
||||
rsyserr(FERROR_XFER, errno, "%s %s -> \"%s\"",
|
||||
ret == -2 ? "copy" : "rename",
|
||||
full_fname(fnametmp), fname);
|
||||
if (!partialptr || (ret == -2 && temp_copy_name)
|
||||
|| robust_rename(fnametmp, partialptr, NULL, file->mode) < 0)
|
||||
|| robust_rename(fnametmp, partialptr, NULL,
|
||||
file->mode & INITACCESSPERMS) < 0)
|
||||
do_unlink(fnametmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
233
rsync.h
233
rsync.h
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) 1996, 2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2008 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -61,7 +61,6 @@
|
||||
#define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - now */
|
||||
#define XMIT_HLINK_FIRST (1<<12) /* protocols 30 - now (HLINKED files only) */
|
||||
#define XMIT_IO_ERROR_ENDLIST (1<<12) /* protocols 31*- now (w/XMIT_EXTENDED_FLAGS) (also protocol 30 w/'f' compat flag) */
|
||||
#define XMIT_MOD_NSEC (1<<13) /* protocols 31 - now */
|
||||
|
||||
/* These flags are used in the live flist data. */
|
||||
|
||||
@@ -82,7 +81,6 @@
|
||||
#define FLAG_LENGTH64 (1<<9) /* sender/receiver/generator */
|
||||
#define FLAG_SKIP_GROUP (1<<10) /* receiver/generator */
|
||||
#define FLAG_TIME_FAILED (1<<11)/* generator */
|
||||
#define FLAG_MOD_NSEC (1<<12) /* sender/receiver/generator */
|
||||
|
||||
/* These flags are passed to functions but not stored. */
|
||||
|
||||
@@ -98,7 +96,7 @@
|
||||
== ((unsigned)(b2) & (unsigned)(mask)))
|
||||
|
||||
/* update this if you make incompatible changes */
|
||||
#define PROTOCOL_VERSION 31
|
||||
#define PROTOCOL_VERSION 30
|
||||
|
||||
/* This is used when working on a new protocol version in CVS, and should
|
||||
* be a new non-zero value for each CVS change that affects the protocol.
|
||||
@@ -126,8 +124,7 @@
|
||||
#define OLD_PROTOCOL_VERSION 25
|
||||
#define MAX_PROTOCOL_VERSION 40
|
||||
|
||||
#define MIN_FILECNT_LOOKAHEAD 1000
|
||||
#define MAX_FILECNT_LOOKAHEAD 10000
|
||||
#define FILECNT_LOOKAHEAD 1000
|
||||
|
||||
#define RSYNC_PORT 873
|
||||
|
||||
@@ -135,14 +132,12 @@
|
||||
#define WRITE_SIZE (32*1024)
|
||||
#define CHUNK_SIZE (32*1024)
|
||||
#define MAX_MAP_SIZE (256*1024)
|
||||
#define IO_BUFFER_SIZE (32*1024)
|
||||
#define IO_BUFFER_SIZE (4092)
|
||||
#define MAX_BLOCK_SIZE ((int32)1 << 17)
|
||||
|
||||
/* For compatibility with older rsyncs */
|
||||
#define OLD_MAX_BLOCK_SIZE ((int32)1 << 29)
|
||||
|
||||
#define ROUND_UP_1024(siz) ((siz) & (1024-1) ? ((siz) | (1024-1)) + 1 : (siz))
|
||||
|
||||
#define IOERR_GENERAL (1<<0) /* For backward compatibility, this must == 1 */
|
||||
#define IOERR_VANISHED (1<<1)
|
||||
#define IOERR_DEL_LIMIT (1<<2)
|
||||
@@ -236,46 +231,20 @@ enum msgcode {
|
||||
MSG_ERROR_UTF8=FERROR_UTF8, /* sibling logging */
|
||||
MSG_LOG=FLOG, MSG_CLIENT=FCLIENT, /* sibling logging */
|
||||
MSG_REDO=9, /* reprocess indicated flist index */
|
||||
MSG_STATS=10, /* message has stats data for generator */
|
||||
MSG_FLIST=20, /* extra file list over sibling socket */
|
||||
MSG_FLIST_EOF=21,/* we've transmitted all the file lists */
|
||||
MSG_IO_ERROR=22,/* the sending side had an I/O error */
|
||||
MSG_IO_TIMEOUT=33,/* tell client about a daemon's timeout value */
|
||||
MSG_NOOP=42, /* a do-nothing message (legacy protocol-30 only) */
|
||||
MSG_ERROR_EXIT=86, /* synchronize an error exit (siblings and protocol >= 31) */
|
||||
MSG_NOOP=42, /* a do-nothing message */
|
||||
MSG_SUCCESS=100,/* successfully updated indicated flist index */
|
||||
MSG_DELETED=101,/* successfully deleted a file on receiving side */
|
||||
MSG_NO_SEND=102,/* sender failed to open a file we wanted */
|
||||
MSG_DONE=86 /* current phase is done */
|
||||
};
|
||||
|
||||
#define NDX_DONE -1
|
||||
#define NDX_FLIST_EOF -2
|
||||
#define NDX_DEL_STATS -3
|
||||
#define NDX_FLIST_OFFSET -101
|
||||
|
||||
/* For calling delete_item() and delete_dir_contents(). */
|
||||
#define DEL_NO_UID_WRITE (1<<0) /* file/dir has our uid w/o write perm */
|
||||
#define DEL_RECURSE (1<<1) /* if dir, delete all contents */
|
||||
#define DEL_DIR_IS_EMPTY (1<<2) /* internal delete_FUNCTIONS use only */
|
||||
#define DEL_FOR_FILE (1<<3) /* making room for a replacement file */
|
||||
#define DEL_FOR_DIR (1<<4) /* making room for a replacement dir */
|
||||
#define DEL_FOR_SYMLINK (1<<5) /* making room for a replacement symlink */
|
||||
#define DEL_FOR_DEVICE (1<<6) /* making room for a replacement device */
|
||||
#define DEL_FOR_SPECIAL (1<<7) /* making room for a replacement special */
|
||||
#define DEL_FOR_BACKUP (1<<8) /* the delete is for a backup operation */
|
||||
|
||||
#define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL)
|
||||
|
||||
enum delret {
|
||||
DR_SUCCESS = 0, DR_FAILURE, DR_AT_LIMIT, DR_NOT_EMPTY
|
||||
};
|
||||
|
||||
/* Defines for make_path() */
|
||||
#define MKP_DROP_NAME (1<<0) /* drop trailing filename or trailing slash */
|
||||
#define MKP_SKIP_SLASH (1<<1) /* skip one or more leading slashes */
|
||||
|
||||
/* Defines for maybe_send_keepalive() */
|
||||
#define MSK_ALLOW_FLUSH (1<<0)
|
||||
#define MSK_ACTIVE_RECEIVER (1<<1)
|
||||
|
||||
#include "errcode.h"
|
||||
|
||||
#include "config.h"
|
||||
@@ -371,7 +340,7 @@ enum delret {
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
#if defined HAVE_UTIMENSAT || defined HAVE_LUTIMES
|
||||
#if defined HAVE_LUTIMES || defined HAVE_UTIMENSAT
|
||||
#define CAN_SET_SYMLINK_TIMES 1
|
||||
#endif
|
||||
|
||||
@@ -383,14 +352,6 @@ enum delret {
|
||||
#define CAN_CHMOD_SYMLINK 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
#define ST_MTIME_NSEC st_mtim.tv_nsec
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
|
||||
#define ST_MTIME_NSEC st_mtimensec
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
@@ -612,7 +573,7 @@ struct hashtable {
|
||||
void *nodes;
|
||||
int32 size, entries;
|
||||
uint32 node_size;
|
||||
short key64;
|
||||
int key64;
|
||||
};
|
||||
|
||||
struct ht_int32_node {
|
||||
@@ -673,23 +634,6 @@ struct ht_int64_node {
|
||||
#define ACLS_NEED_MASK 1
|
||||
#endif
|
||||
|
||||
#if defined HAVE_FALLOCATE || HAVE_SYS_FALLOCATE
|
||||
#ifdef HAVE_LINUX_FALLOC_H
|
||||
#include <linux/falloc.h>
|
||||
#endif
|
||||
#ifdef FALLOC_FL_KEEP_SIZE
|
||||
#define SUPPORT_PREALLOCATION 1
|
||||
#elif defined HAVE_FTRUNCATE
|
||||
#define SUPPORT_PREALLOCATION 1
|
||||
#define PREALLOCATE_NEEDS_TRUNCATE 1
|
||||
#endif
|
||||
#else /* !fallocate */
|
||||
#if defined HAVE_EFFICIENT_POSIX_FALLOCATE && defined HAVE_FTRUNCATE
|
||||
#define SUPPORT_PREALLOCATION 1
|
||||
#define PREALLOCATE_NEEDS_TRUNCATE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
union file_extras {
|
||||
int32 num;
|
||||
uint32 unum;
|
||||
@@ -721,9 +665,7 @@ extern int xattrs_ndx;
|
||||
#define REQ_EXTRA(f,ndx) ((union file_extras*)(f) - (ndx))
|
||||
#define OPT_EXTRA(f,bump) ((union file_extras*)(f) - file_extra_cnt - 1 - (bump))
|
||||
|
||||
#define NSEC_BUMP(f) ((f)->flags & FLAG_MOD_NSEC ? 1 : 0)
|
||||
#define LEN64_BUMP(f) ((f)->flags & FLAG_LENGTH64 ? 1 : 0)
|
||||
#define START_BUMP(f) (NSEC_BUMP(f) + LEN64_BUMP(f))
|
||||
#define HLINK_BUMP(f) ((f)->flags & (FLAG_HLINKED|FLAG_HLINK_DONE) ? inc_recurse+1 : 0)
|
||||
#define ACL_BUMP(f) (acls_ndx ? 1 : 0)
|
||||
|
||||
@@ -732,11 +674,9 @@ extern int xattrs_ndx;
|
||||
#define F_LENGTH(f) ((int64)(f)->len32)
|
||||
#else
|
||||
#define F_LENGTH(f) ((int64)(f)->len32 + ((f)->flags & FLAG_LENGTH64 \
|
||||
? (int64)OPT_EXTRA(f, NSEC_BUMP(f))->unum << 32 : 0))
|
||||
? (int64)OPT_EXTRA(f, 0)->unum << 32 : 0))
|
||||
#endif
|
||||
|
||||
#define F_MOD_NSEC(f) ((f)->flags & FLAG_MOD_NSEC ? OPT_EXTRA(f, 0)->unum : 0)
|
||||
|
||||
/* If there is a symlink string, it is always right after the basename */
|
||||
#define F_SYMLINK(f) ((f)->basename + strlen((f)->basename) + 1)
|
||||
|
||||
@@ -754,21 +694,22 @@ extern int xattrs_ndx;
|
||||
#define F_NDX(f) REQ_EXTRA(f, unsort_ndx)->num
|
||||
|
||||
/* These items are per-entry optional: */
|
||||
#define F_HL_GNUM(f) OPT_EXTRA(f, START_BUMP(f))->num /* non-dirs */
|
||||
#define F_HL_PREV(f) OPT_EXTRA(f, START_BUMP(f)+inc_recurse)->num /* non-dirs */
|
||||
#define F_DIR_NODE_P(f) (&OPT_EXTRA(f, START_BUMP(f) \
|
||||
#define F_HL_GNUM(f) OPT_EXTRA(f, LEN64_BUMP(f))->num /* non-dirs */
|
||||
#define F_HL_PREV(f) OPT_EXTRA(f, LEN64_BUMP(f)+inc_recurse)->num /* non-dirs */
|
||||
#define F_DIR_NODE_P(f) (&OPT_EXTRA(f, LEN64_BUMP(f) \
|
||||
+ DIRNODE_EXTRA_CNT - 1)->num) /* sender dirs */
|
||||
#define F_DIR_RELNAMES_P(f) (&OPT_EXTRA(f, START_BUMP(f) + DIRNODE_EXTRA_CNT \
|
||||
#define F_DIR_RELNAMES_P(f) (&OPT_EXTRA(f, LEN64_BUMP(f) + DIRNODE_EXTRA_CNT \
|
||||
+ PTR_EXTRA_CNT - 1)->num) /* sender dirs */
|
||||
#define F_DIR_DEFACL(f) OPT_EXTRA(f, START_BUMP(f))->unum /* receiver dirs */
|
||||
#define F_DIR_DEV_P(f) (&OPT_EXTRA(f, START_BUMP(f) + ACL_BUMP(f) \
|
||||
#define F_DIR_DEFACL(f) OPT_EXTRA(f, LEN64_BUMP(f))->unum /* receiver dirs */
|
||||
#define F_DIR_DEV_P(f) (&OPT_EXTRA(f, LEN64_BUMP(f) + ACL_BUMP(f) \
|
||||
+ DEV_EXTRA_CNT - 1)->unum) /* receiver dirs */
|
||||
|
||||
/* This optional item might follow an F_HL_*() item. */
|
||||
#define F_RDEV_P(f) (&OPT_EXTRA(f, START_BUMP(f) + HLINK_BUMP(f) + DEV_EXTRA_CNT - 1)->unum)
|
||||
/* This optional item might follow an F_HL_*() item.
|
||||
* (Note: a device doesn't need to check LEN64_BUMP(f).) */
|
||||
#define F_RDEV_P(f) (&OPT_EXTRA(f, HLINK_BUMP(f) + DEV_EXTRA_CNT - 1)->unum)
|
||||
|
||||
/* The sum is only present on regular files. */
|
||||
#define F_SUM(f) ((char*)OPT_EXTRA(f, START_BUMP(f) + HLINK_BUMP(f) \
|
||||
#define F_SUM(f) ((char*)OPT_EXTRA(f, LEN64_BUMP(f) + HLINK_BUMP(f) \
|
||||
+ SUM_EXTRA_CNT - 1))
|
||||
|
||||
/* Some utility defines: */
|
||||
@@ -853,45 +794,47 @@ struct map_struct {
|
||||
int status; /* first errno from read errors */
|
||||
};
|
||||
|
||||
#define FILTRULE_WILD (1<<0) /* pattern has '*', '[', and/or '?' */
|
||||
#define FILTRULE_WILD2 (1<<1) /* pattern has '**' */
|
||||
#define FILTRULE_WILD2_PREFIX (1<<2) /* pattern starts with "**" */
|
||||
#define FILTRULE_WILD3_SUFFIX (1<<3) /* pattern ends with "***" */
|
||||
#define FILTRULE_ABS_PATH (1<<4) /* path-match on absolute path */
|
||||
#define FILTRULE_INCLUDE (1<<5) /* this is an include, not an exclude */
|
||||
#define FILTRULE_DIRECTORY (1<<6) /* this matches only directories */
|
||||
#define FILTRULE_WORD_SPLIT (1<<7) /* split rules on whitespace */
|
||||
#define FILTRULE_NO_INHERIT (1<<8) /* don't inherit these rules */
|
||||
#define FILTRULE_NO_PREFIXES (1<<9) /* parse no prefixes from patterns */
|
||||
#define FILTRULE_MERGE_FILE (1<<10)/* specifies a file to merge */
|
||||
#define FILTRULE_PERDIR_MERGE (1<<11)/* merge-file is searched per-dir */
|
||||
#define FILTRULE_EXCLUDE_SELF (1<<12)/* merge-file name should be excluded */
|
||||
#define FILTRULE_FINISH_SETUP (1<<13)/* per-dir merge file needs setup */
|
||||
#define FILTRULE_NEGATE (1<<14)/* rule matches when pattern does not */
|
||||
#define FILTRULE_CVS_IGNORE (1<<15)/* rule was -C or :C */
|
||||
#define FILTRULE_SENDER_SIDE (1<<16)/* rule applies to the sending side */
|
||||
#define FILTRULE_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */
|
||||
#define FILTRULE_CLEAR_LIST (1<<18)/* this item is the "!" token */
|
||||
#define FILTRULE_PERISHABLE (1<<19)/* perishable if parent dir goes away */
|
||||
#define MATCHFLG_WILD (1<<0) /* pattern has '*', '[', and/or '?' */
|
||||
#define MATCHFLG_WILD2 (1<<1) /* pattern has '**' */
|
||||
#define MATCHFLG_WILD2_PREFIX (1<<2) /* pattern starts with "**" */
|
||||
#define MATCHFLG_WILD3_SUFFIX (1<<3) /* pattern ends with "***" */
|
||||
#define MATCHFLG_ABS_PATH (1<<4) /* path-match on absolute path */
|
||||
#define MATCHFLG_INCLUDE (1<<5) /* this is an include, not an exclude */
|
||||
#define MATCHFLG_DIRECTORY (1<<6) /* this matches only directories */
|
||||
#define MATCHFLG_WORD_SPLIT (1<<7) /* split rules on whitespace */
|
||||
#define MATCHFLG_NO_INHERIT (1<<8) /* don't inherit these rules */
|
||||
#define MATCHFLG_NO_PREFIXES (1<<9) /* parse no prefixes from patterns */
|
||||
#define MATCHFLG_MERGE_FILE (1<<10)/* specifies a file to merge */
|
||||
#define MATCHFLG_PERDIR_MERGE (1<<11)/* merge-file is searched per-dir */
|
||||
#define MATCHFLG_EXCLUDE_SELF (1<<12)/* merge-file name should be excluded */
|
||||
#define MATCHFLG_FINISH_SETUP (1<<13)/* per-dir merge file needs setup */
|
||||
#define MATCHFLG_NEGATE (1<<14)/* rule matches when pattern does not */
|
||||
#define MATCHFLG_CVS_IGNORE (1<<15)/* rule was -C or :C */
|
||||
#define MATCHFLG_SENDER_SIDE (1<<16)/* rule applies to the sending side */
|
||||
#define MATCHFLG_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */
|
||||
#define MATCHFLG_CLEAR_LIST (1<<18)/* this item is the "!" token */
|
||||
#define MATCHFLG_PERISHABLE (1<<19)/* perishable if parent dir goes away */
|
||||
|
||||
#define FILTRULES_SIDES (FILTRULE_SENDER_SIDE | FILTRULE_RECEIVER_SIDE)
|
||||
#define MATCHFLGS_FROM_CONTAINER (MATCHFLG_ABS_PATH | MATCHFLG_INCLUDE \
|
||||
| MATCHFLG_DIRECTORY | MATCHFLG_SENDER_SIDE \
|
||||
| MATCHFLG_NEGATE | MATCHFLG_RECEIVER_SIDE \
|
||||
| MATCHFLG_PERISHABLE)
|
||||
|
||||
typedef struct filter_struct {
|
||||
struct filter_struct {
|
||||
struct filter_struct *next;
|
||||
char *pattern;
|
||||
uint32 rflags;
|
||||
uint32 match_flags;
|
||||
union {
|
||||
int slash_cnt;
|
||||
struct filter_list_struct *mergelist;
|
||||
} u;
|
||||
} filter_rule;
|
||||
};
|
||||
|
||||
typedef struct filter_list_struct {
|
||||
filter_rule *head;
|
||||
filter_rule *tail;
|
||||
filter_rule *parent_dirscan_head;
|
||||
struct filter_list_struct {
|
||||
struct filter_struct *head;
|
||||
struct filter_struct *tail;
|
||||
char *debug_type;
|
||||
} filter_rule_list;
|
||||
};
|
||||
|
||||
struct stats {
|
||||
int64 total_size;
|
||||
@@ -903,10 +846,8 @@ struct stats {
|
||||
int64 flist_buildtime;
|
||||
int64 flist_xfertime;
|
||||
int64 flist_size;
|
||||
int num_files, num_dirs, num_symlinks, num_devices, num_specials;
|
||||
int created_files, created_dirs, created_symlinks, created_devices, created_specials;
|
||||
int deleted_files, deleted_dirs, deleted_symlinks, deleted_devices, deleted_specials;
|
||||
int xferred_files;
|
||||
int num_files;
|
||||
int num_transferred_files;
|
||||
};
|
||||
|
||||
struct chmod_mode_struct;
|
||||
@@ -941,22 +882,13 @@ typedef struct {
|
||||
} xbuf;
|
||||
|
||||
#define INIT_XBUF(xb, str, ln, sz) (xb).buf = (str), (xb).len = (ln), (xb).size = (sz), (xb).pos = 0
|
||||
#define INIT_XBUF_STRLEN(xb, str) (xb).buf = (str), (xb).len = strlen((xb).buf), (xb).size = (size_t)-1, (xb).pos = 0
|
||||
#define INIT_XBUF_STRLEN(xb, str) (xb).buf = (str), (xb).len = strlen((xb).buf), (xb).size = (-1), (xb).pos = 0
|
||||
/* This one is used to make an output xbuf based on a char[] buffer: */
|
||||
#define INIT_CONST_XBUF(xb, bf) (xb).buf = (bf), (xb).size = sizeof (bf), (xb).len = (xb).pos = 0
|
||||
|
||||
#define ICB_EXPAND_OUT (1<<0)
|
||||
#define ICB_INCLUDE_BAD (1<<1)
|
||||
#define ICB_INCLUDE_INCOMPLETE (1<<2)
|
||||
#define ICB_CIRCULAR_OUT (1<<3)
|
||||
#define ICB_INIT (1<<4)
|
||||
|
||||
#define IOBUF_KEEP_BUFS 0
|
||||
#define IOBUF_FREE_BUFS 1
|
||||
|
||||
#define MPLX_SWITCHING IOBUF_KEEP_BUFS
|
||||
#define MPLX_ALL_DONE IOBUF_FREE_BUFS
|
||||
#define MPLX_TO_BUFFERED 2
|
||||
|
||||
#define RL_EOL_NULLS (1<<0)
|
||||
#define RL_DUMP_COMMENTS (1<<1)
|
||||
@@ -1044,9 +976,6 @@ extern int errno;
|
||||
|
||||
#ifdef HAVE_READLINK
|
||||
#define SUPPORT_LINKS 1
|
||||
#if !defined NO_SYMLINK_XATTRS && !defined NO_SYMLINK_USER_XATTRS
|
||||
#define do_readlink(path, buf, bufsiz) readlink(path, buf, bufsiz)
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_LINK
|
||||
#define SUPPORT_HARD_LINKS 1
|
||||
@@ -1226,53 +1155,7 @@ size_t strlcat(char *d, const char *s, size_t bufsize);
|
||||
#define FD_ZERO(fdsetp) memset(fdsetp, 0, sizeof (fd_set))
|
||||
#endif
|
||||
|
||||
extern short info_levels[], debug_levels[];
|
||||
|
||||
#define INFO_GTE(flag, lvl) (info_levels[INFO_##flag] >= (lvl))
|
||||
#define INFO_EQ(flag, lvl) (info_levels[INFO_##flag] == (lvl))
|
||||
#define DEBUG_GTE(flag, lvl) (debug_levels[DEBUG_##flag] >= (lvl))
|
||||
#define DEBUG_EQ(flag, lvl) (debug_levels[DEBUG_##flag] == (lvl))
|
||||
|
||||
#define INFO_BACKUP 0
|
||||
#define INFO_COPY (INFO_BACKUP+1)
|
||||
#define INFO_DEL (INFO_COPY+1)
|
||||
#define INFO_FLIST (INFO_DEL+1)
|
||||
#define INFO_MISC (INFO_FLIST+1)
|
||||
#define INFO_MOUNT (INFO_MISC+1)
|
||||
#define INFO_NAME (INFO_MOUNT+1)
|
||||
#define INFO_PROGRESS (INFO_NAME+1)
|
||||
#define INFO_REMOVE (INFO_PROGRESS+1)
|
||||
#define INFO_SKIP (INFO_REMOVE+1)
|
||||
#define INFO_STATS (INFO_SKIP+1)
|
||||
#define INFO_SYMSAFE (INFO_STATS+1)
|
||||
|
||||
#define COUNT_INFO (INFO_SYMSAFE+1)
|
||||
|
||||
#define DEBUG_ACL 0
|
||||
#define DEBUG_BACKUP (DEBUG_ACL+1)
|
||||
#define DEBUG_BIND (DEBUG_BACKUP+1)
|
||||
#define DEBUG_CHDIR (DEBUG_BIND+1)
|
||||
#define DEBUG_CONNECT (DEBUG_CHDIR+1)
|
||||
#define DEBUG_CMD (DEBUG_CONNECT+1)
|
||||
#define DEBUG_DEL (DEBUG_CMD+1)
|
||||
#define DEBUG_DELTASUM (DEBUG_DEL+1)
|
||||
#define DEBUG_DUP (DEBUG_DELTASUM+1)
|
||||
#define DEBUG_EXIT (DEBUG_DUP+1)
|
||||
#define DEBUG_FILTER (DEBUG_EXIT+1)
|
||||
#define DEBUG_FLIST (DEBUG_FILTER+1)
|
||||
#define DEBUG_FUZZY (DEBUG_FLIST+1)
|
||||
#define DEBUG_GENR (DEBUG_FUZZY+1)
|
||||
#define DEBUG_HASH (DEBUG_GENR+1)
|
||||
#define DEBUG_HLINK (DEBUG_HASH+1)
|
||||
#define DEBUG_ICONV (DEBUG_HLINK+1)
|
||||
#define DEBUG_IO (DEBUG_ICONV+1)
|
||||
#define DEBUG_OWN (DEBUG_IO+1)
|
||||
#define DEBUG_PROTO (DEBUG_OWN+1)
|
||||
#define DEBUG_RECV (DEBUG_PROTO+1)
|
||||
#define DEBUG_SEND (DEBUG_RECV+1)
|
||||
#define DEBUG_TIME (DEBUG_SEND+1)
|
||||
|
||||
#define COUNT_DEBUG (DEBUG_TIME+1)
|
||||
extern int verbose;
|
||||
|
||||
#ifndef HAVE_INET_NTOP
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
@@ -1282,10 +1165,6 @@ const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
int inet_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETPASS
|
||||
char *getpass(const char *prompt);
|
||||
#endif
|
||||
|
||||
#ifdef MAINTAINER_MODE
|
||||
const char *get_panic_action(void);
|
||||
#endif
|
||||
|
||||
523
rsync.yo
523
rsync.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsync)(1)(28 Sep 2013)()()
|
||||
manpage(rsync)(1)(26 Mar 2011)()()
|
||||
manpagename(rsync)(a fast, versatile, remote (and local) file-copying tool)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -281,19 +281,6 @@ daemon (including stand-alone and inetd configurations).
|
||||
If you're using one of the remote-shell transports for the transfer, there is
|
||||
no need to manually start an rsync daemon.
|
||||
|
||||
manpagesection(SORTED TRANSFER ORDER)
|
||||
|
||||
Rsync always sorts the specified filenames into its internal transfer list.
|
||||
This handles the merging together of the contents of identically named
|
||||
directories, makes it easy to remove duplicate filenames, and may confuse
|
||||
someone when the files are transferred in a different order than what was
|
||||
given on the command-line.
|
||||
|
||||
If you need a particular file to be transferred prior to another, either
|
||||
separate the files into different rsync calls, or consider using
|
||||
bf(--delay-updates) (which doesn't affect the sorted transfer order, but
|
||||
does make the final file-updating phase happen much more rapidly).
|
||||
|
||||
manpagesection(EXAMPLES)
|
||||
|
||||
Here are some examples of how I use rsync.
|
||||
@@ -331,9 +318,6 @@ manpagesection(OPTIONS SUMMARY)
|
||||
Here is a short summary of the options available in rsync. Please refer
|
||||
to the detailed description below for a complete description. verb(
|
||||
-v, --verbose increase verbosity
|
||||
--info=FLAGS fine-grained informational verbosity
|
||||
--debug=FLAGS fine-grained debug verbosity
|
||||
--msgs2stderr special output handling for debugging
|
||||
-q, --quiet suppress non-error messages
|
||||
--no-motd suppress daemon-mode MOTD (see caveat)
|
||||
-c, --checksum skip based on checksum, not mod-time & size
|
||||
@@ -354,7 +338,6 @@ to the detailed description below for a complete description. verb(
|
||||
-L, --copy-links transform symlink into referent file/dir
|
||||
--copy-unsafe-links only "unsafe" symlinks are transformed
|
||||
--safe-links ignore symlinks that point outside the tree
|
||||
--munge-links munge symlinks to make them safer
|
||||
-k, --copy-dirlinks transform symlink to dir into referent dir
|
||||
-K, --keep-dirlinks treat symlinked dir on receiver as dir
|
||||
-H, --hard-links preserve hard links
|
||||
@@ -370,11 +353,9 @@ to the detailed description below for a complete description. verb(
|
||||
-D same as --devices --specials
|
||||
-t, --times preserve modification times
|
||||
-O, --omit-dir-times omit directories from --times
|
||||
-J, --omit-link-times omit symlinks from --times
|
||||
--super receiver attempts super-user activities
|
||||
--fake-super store/recover privileged attrs using xattrs
|
||||
-S, --sparse handle sparse files efficiently
|
||||
--preallocate allocate dest files before writing
|
||||
-n, --dry-run perform a trial run with no changes made
|
||||
-W, --whole-file copy files whole (w/o delta-xfer algorithm)
|
||||
-x, --one-file-system don't cross filesystem boundaries
|
||||
@@ -386,13 +367,11 @@ to the detailed description below for a complete description. verb(
|
||||
--remove-source-files sender removes synchronized files (non-dir)
|
||||
--del an alias for --delete-during
|
||||
--delete delete extraneous files from dest dirs
|
||||
--delete-before receiver deletes before xfer, not during
|
||||
--delete-during receiver deletes during the transfer
|
||||
--delete-before receiver deletes before transfer (default)
|
||||
--delete-during receiver deletes during xfer, not before
|
||||
--delete-delay find deletions during, delete after
|
||||
--delete-after receiver deletes after transfer, not during
|
||||
--delete-after receiver deletes after transfer, not before
|
||||
--delete-excluded also delete excluded files from dest dirs
|
||||
--ignore-missing-args ignore missing source args without error
|
||||
--delete-missing-args delete missing source args from destination
|
||||
--ignore-errors delete even if there are I/O errors
|
||||
--force force deletion of dirs even if not empty
|
||||
--max-delete=NUM don't delete more than NUM files
|
||||
@@ -403,9 +382,6 @@ to the detailed description below for a complete description. verb(
|
||||
--delay-updates put all updated files into place at end
|
||||
-m, --prune-empty-dirs prune empty directory chains from file-list
|
||||
--numeric-ids don't map uid/gid values by user/group name
|
||||
--usermap=STRING custom username mapping
|
||||
--groupmap=STRING custom groupname mapping
|
||||
--chown=USER:GROUP simple username/groupname mapping
|
||||
--timeout=SECONDS set I/O timeout in seconds
|
||||
--contimeout=SECONDS set daemon connection timeout in seconds
|
||||
-I, --ignore-times don't skip files that match size and time
|
||||
@@ -434,20 +410,18 @@ to the detailed description below for a complete description. verb(
|
||||
--port=PORT specify double-colon alternate port number
|
||||
--sockopts=OPTIONS specify custom TCP options
|
||||
--blocking-io use blocking I/O for the remote shell
|
||||
--outbuf=N|L|B set out buffering to None, Line, or Block
|
||||
--stats give some file-transfer stats
|
||||
-8, --8-bit-output leave high-bit chars unescaped in output
|
||||
-h, --human-readable output numbers in a human-readable format
|
||||
--progress show progress during transfer
|
||||
-P same as --partial --progress
|
||||
-i, --itemize-changes output a change-summary for all updates
|
||||
-M, --remote-option=OPTION send OPTION to the remote side only
|
||||
--out-format=FORMAT output updates using the specified FORMAT
|
||||
--log-file=FILE log what we're doing to the specified FILE
|
||||
--log-file-format=FMT log updates using the specified FMT
|
||||
--password-file=FILE read daemon-access password from FILE
|
||||
--list-only list the files instead of copying them
|
||||
--bwlimit=RATE limit socket I/O bandwidth
|
||||
--bwlimit=KBPS limit I/O bandwidth; KBytes per second
|
||||
--write-batch=FILE write a batched update to FILE
|
||||
--only-write-batch=FILE like --write-batch but w/o updating dest
|
||||
--read-batch=FILE read a batched update from FILE
|
||||
@@ -463,9 +437,8 @@ Rsync can also be run as a daemon, in which case the following options are
|
||||
accepted: verb(
|
||||
--daemon run as an rsync daemon
|
||||
--address=ADDRESS bind to the specified address
|
||||
--bwlimit=RATE limit socket I/O bandwidth
|
||||
--bwlimit=KBPS limit I/O bandwidth; KBytes per second
|
||||
--config=FILE specify alternate rsyncd.conf file
|
||||
-M, --dparam=OVERRIDE override global daemon config parameter
|
||||
--no-detach do not detach from the parent
|
||||
--port=PORT listen on alternate port number
|
||||
--log-file=FILE override the "log file" setting
|
||||
@@ -478,17 +451,11 @@ accepted: verb(
|
||||
|
||||
manpageoptions()
|
||||
|
||||
Rsync accepts both long (double-dash + word) and short (single-dash + letter)
|
||||
options. The full list of the available options are described below. If an
|
||||
option can be specified in more than one way, the choices are comma-separated.
|
||||
Some options only have a long variant, not a short. If the option takes a
|
||||
parameter, the parameter is only listed after the long variant, even though it
|
||||
must also be specified for the short. When specifying a parameter, you can
|
||||
either use the form --option=param or replace the '=' with whitespace. The
|
||||
parameter may need to be quoted in some manner for it to survive the shell's
|
||||
command-line parsing. Keep in mind that a leading tilde (~) in a filename is
|
||||
substituted by your shell, so --option=~/foo will not change the tilde into
|
||||
your home directory (remove the '=' for that).
|
||||
rsync uses the GNU long options package. Many of the command line
|
||||
options have two variants, one short and one long. These are shown
|
||||
below, separated by commas. Some options only have a long variant.
|
||||
The '=' for options that take a parameter is optional; whitespace
|
||||
can be used instead.
|
||||
|
||||
startdit()
|
||||
dit(bf(--help)) Print a short help page describing the options
|
||||
@@ -506,67 +473,14 @@ information on what files are being skipped and slightly more
|
||||
information at the end. More than two bf(-v) options should only be used if
|
||||
you are debugging rsync.
|
||||
|
||||
In a modern rsync, the bf(-v) option is equivalent to the setting of groups
|
||||
of bf(--info) and bf(--debug) options. You can choose to use these newer
|
||||
options in addition to, or in place of using bf(--verbose), as any
|
||||
fine-grained settings override the implied settings of bf(-v). Both
|
||||
bf(--info) and bf(--debug) have a way to ask for help that tells you
|
||||
exactly what flags are set for each increase in verbosity.
|
||||
|
||||
dit(bf(--info=FLAGS))
|
||||
This option lets you have fine-grained control over the
|
||||
information
|
||||
output you want to see. An individual flag name may be followed by a level
|
||||
number, with 0 meaning to silence that output, 1 being the default output
|
||||
level, and higher numbers increasing the output of that flag (for those
|
||||
that support higher levels). Use
|
||||
bf(--info=help)
|
||||
to see all the available flag names, what they output, and what flag names
|
||||
are added for each increase in the verbose level. Some examples:
|
||||
|
||||
verb( rsync -a --info=progress2 src/ dest/
|
||||
rsync -avv --info=stats2,misc1,flist0 src/ dest/ )
|
||||
|
||||
Note that bf(--info=name)'s output is affected by the bf(--out-format) and
|
||||
bf(--itemize-changes) (bf(-i)) options. See those options for more
|
||||
information on what is output and when.
|
||||
|
||||
This option was added to 3.1.0, so an older rsync on the server side might
|
||||
reject your attempts at fine-grained control (if one or more flags needed
|
||||
to be send to the server and the server was too old to understand them).
|
||||
|
||||
dit(bf(--debug=FLAGS))
|
||||
This option lets you have fine-grained control over the debug
|
||||
output you want to see. An individual flag name may be followed by a level
|
||||
number, with 0 meaning to silence that output, 1 being the default output
|
||||
level, and higher numbers increasing the output of that flag (for those
|
||||
that support higher levels). Use
|
||||
bf(--debug=help)
|
||||
to see all the available flag names, what they output, and what flag names
|
||||
are added for each increase in the verbose level. Some examples:
|
||||
|
||||
verb( rsync -avvv --debug=none src/ dest/
|
||||
rsync -avA --del --debug=del2,acl src/ dest/ )
|
||||
|
||||
Note that some debug messages will only be output when bf(--msgs2stderr) is
|
||||
specified, especially those pertaining to I/O and buffer debugging.
|
||||
|
||||
This option was added to 3.1.0, so an older rsync on the server side might
|
||||
reject your attempts at fine-grained control (if one or more flags needed
|
||||
to be send to the server and the server was too old to understand them).
|
||||
|
||||
dit(bf(--msgs2stderr)) This option changes rsync to send all its output
|
||||
directly to stderr rather than to send messages to the client side via the
|
||||
protocol (which normally outputs info messages via stdout). This is mainly
|
||||
intended for debugging in order to avoid changing the data sent via the
|
||||
protocol, since the extra protocol data can change what is being tested.
|
||||
Keep in mind that a daemon connection does not have a stderr channel to send
|
||||
messages back to the client side, so if you are doing any daemon-transfer
|
||||
debugging using this option, you should start up a daemon using bf(--no-detach)
|
||||
so that you can see the stderr output on the daemon side.
|
||||
|
||||
This option has the side-effect of making stderr output get line-buffered so
|
||||
that the merging of the output of 3 programs happens in a more readable manner.
|
||||
Note that the names of the transferred files that are output are done using
|
||||
a default bf(--out-format) of "%n%L", which tells you just the name of the
|
||||
file and, if the item is a link, where it points. At the single bf(-v)
|
||||
level of verbosity, this does not mention when a file gets its attributes
|
||||
changed. If you ask for an itemized list of changed attributes (either
|
||||
bf(--itemize-changes) or adding "%i" to the bf(--out-format) setting), the
|
||||
output (on the client) increases to mention all items that are changed in
|
||||
any way. See the bf(--out-format) option for more details.
|
||||
|
||||
dit(bf(-q, --quiet)) This option decreases the amount of information you
|
||||
are given during the transfer, notably suppressing information messages
|
||||
@@ -905,25 +819,6 @@ which point outside the copied tree. All absolute symlinks are
|
||||
also ignored. Using this option in conjunction with bf(--relative) may
|
||||
give unexpected results.
|
||||
|
||||
dit(bf(--munge-links)) This option tells rsync to (1) modify all symlinks on
|
||||
the receiving side in a way that makes them unusable but recoverable (see
|
||||
below), or (2) to unmunge symlinks on the sending side that had been stored in
|
||||
a munged state. This is useful if you don't quite trust the source of the data
|
||||
to not try to slip in a symlink to a unexpected place.
|
||||
|
||||
The way rsync disables the use of symlinks is to prefix each one with the
|
||||
string "/rsyncd-munged/". This prevents the links from being used as long as
|
||||
that directory does not exist. When this option is enabled, rsync will refuse
|
||||
to run if that path is a directory or a symlink to a directory.
|
||||
|
||||
The option only affects the client side of the transfer, so if you need it to
|
||||
affect the server, specify it via bf(--remote-option). (Note that in a local
|
||||
transfer, the client side is the sender.)
|
||||
|
||||
This option has no affect on a daemon, since the daemon configures whether it
|
||||
wants munged symlinks via its "munge symlinks" parameter. See also the
|
||||
"munge-symlinks" perl script in the support directory of the source code.
|
||||
|
||||
dit(bf(-k, --copy-dirlinks)) This option causes the sending side to treat
|
||||
a symlink to a directory as though it were a real directory. This is
|
||||
useful if you don't want symlinks to non-directories to be affected, as
|
||||
@@ -1096,7 +991,7 @@ used by bf(--fake-super)) unless you repeat the option (e.g. -XX). This
|
||||
"copy all xattrs" mode cannot be used with bf(--fake-super).
|
||||
|
||||
dit(bf(--chmod)) This option tells rsync to apply one or more
|
||||
comma-separated "chmod" modes to the permission of the files in the
|
||||
comma-separated "chmod" strings to the permission of the files in the
|
||||
transfer. The resulting value is treated as though it were the permissions
|
||||
that the sending side supplied for the file, which means that this option
|
||||
can seem to have no effect on existing files if bf(--perms) is not enabled.
|
||||
@@ -1111,10 +1006,6 @@ consistent executability across all bits:
|
||||
|
||||
quote(--chmod=Dg+s,ug+w,Fo-w,+X)
|
||||
|
||||
Using octal mode numbers is also allowed:
|
||||
|
||||
quote(--chmod=D2775,F664)
|
||||
|
||||
It is also legal to specify multiple bf(--chmod) options, as each
|
||||
additional option is just appended to the list of changes to make.
|
||||
|
||||
@@ -1167,9 +1058,6 @@ it is preserving modification times (see bf(--times)). If NFS is sharing
|
||||
the directories on the receiving side, it is a good idea to use bf(-O).
|
||||
This option is inferred if you use bf(--backup) without bf(--backup-dir).
|
||||
|
||||
dit(bf(-J, --omit-link-times)) This tells rsync to omit symlinks when
|
||||
it is preserving modification times (see bf(--times)).
|
||||
|
||||
dit(bf(--super)) This tells the receiving side to attempt super-user
|
||||
activities even if the receiving rsync wasn't run by the super-user. These
|
||||
activities include: preserving users via the bf(--owner) option, preserving
|
||||
@@ -1196,16 +1084,16 @@ This is a good way to backup data without using a super-user, and to store
|
||||
ACLs from incompatible systems.
|
||||
|
||||
The bf(--fake-super) option only affects the side where the option is used.
|
||||
To affect the remote side of a remote-shell connection, use the
|
||||
bf(--remote-option) (bf(-M)) option:
|
||||
To affect the remote side of a remote-shell connection, specify an rsync
|
||||
path:
|
||||
|
||||
quote(tt( rsync -av -M--fake-super /src/ host:/dest/))
|
||||
quote(tt( rsync -av --rsync-path="rsync --fake-super" /src/ host:/dest/))
|
||||
|
||||
For a local copy, this option affects both the source and the destination.
|
||||
If you wish a local copy to enable this option just for the destination
|
||||
files, specify bf(-M--fake-super). If you wish a local copy to enable
|
||||
this option just for the source files, combine bf(--fake-super) with
|
||||
bf(-M--super).
|
||||
Since there is only one "side" in a local copy, this option affects both
|
||||
the sending and receiving of files. You'll need to specify a copy using
|
||||
"localhost" if you need to avoid this, possibly using the "lsh" shell
|
||||
script (from the support directory) as a substitute for an actual remote
|
||||
shell (see bf(--rsh)).
|
||||
|
||||
This option is overridden by both bf(--super) and bf(--no-super).
|
||||
|
||||
@@ -1215,17 +1103,6 @@ dit(bf(-S, --sparse)) Try to handle sparse files efficiently so they take
|
||||
up less space on the destination. Conflicts with bf(--inplace) because it's
|
||||
not possible to overwrite data in a sparse fashion.
|
||||
|
||||
dit(bf(--preallocate)) This tells the receiver to allocate each destination
|
||||
file to its eventual size before writing data to the file. Rsync will only use
|
||||
the real filesystem-level preallocation support provided by Linux's
|
||||
bf(fallocate)(2) system call or Cygwin's bf(posix_fallocate)(3), not the slow
|
||||
glibc implementation that writes a zero byte into each block.
|
||||
|
||||
Without this option, larger files may not be entirely contiguous on the
|
||||
filesystem, but with this option rsync will probably copy more slowly. If the
|
||||
destination is not an extent-supporting filesystem (such as ext4, xfs, NTFS,
|
||||
etc.), this option may have no positive effect at all.
|
||||
|
||||
dit(bf(-n, --dry-run)) This makes rsync perform a trial run that doesn't
|
||||
make any changes (and produces mostly the same output as a real run). It
|
||||
is most commonly used in combination with the bf(-v, --verbose) and/or
|
||||
@@ -1297,19 +1174,6 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending
|
||||
side the files (meaning non-directories) that are a part of the transfer
|
||||
and have been successfully duplicated on the receiving side.
|
||||
|
||||
Note that you should only use this option on source files that are quiescent.
|
||||
If you are using this to move files that show up in a particular directory over
|
||||
to another host, make sure that the finished files get renamed into the source
|
||||
directory, not directly written into it, so that rsync can't possibly transfer
|
||||
a file that is not yet fully written. If you can't first write the files into
|
||||
a different directory, you should use a naming idiom that lets rsync avoid
|
||||
transferring files that are not yet finished (e.g. name the file "foo.new" when
|
||||
it is written, rename it to "foo" when it is done, and then use the option
|
||||
bf(--exclude='*.new') for the rsync transfer).
|
||||
|
||||
Starting with 3.1.0, rsync will skip the sender-side removal (and output an
|
||||
error) if the file's size or modify time has not stayed unchanged.
|
||||
|
||||
dit(bf(--delete)) This tells rsync to delete extraneous files from the
|
||||
receiving side (ones that aren't on the sending side), but only for the
|
||||
directories that are being synchronized. You must have asked rsync to
|
||||
@@ -1393,23 +1257,6 @@ this way on the receiver, and for a way to protect files from
|
||||
bf(--delete-excluded).
|
||||
See bf(--delete) (which is implied) for more details on file-deletion.
|
||||
|
||||
dit(bf(--ignore-missing-args)) When rsync is first processing the explicitly
|
||||
requested source files (e.g. command-line arguments or bf(--files-from)
|
||||
entries), it is normally an error if the file cannot be found. This option
|
||||
suppresses that error, and does not try to transfer the file. This does not
|
||||
affect subsequent vanished-file errors if a file was initially found to be
|
||||
present and later is no longer there.
|
||||
|
||||
dit(bf(--delete-missing-args)) This option takes the behavior of (the implied)
|
||||
bf(--ignore-missing-args) option a step farther: each missing arg will become
|
||||
a deletion request of the corresponding destination file on the receiving side
|
||||
(should it exist). If the destination file is a non-empty directory, it will
|
||||
only be successfully deleted if --force or --delete are in effect. Other than
|
||||
that, this option is independent of any other type of delete processing.
|
||||
|
||||
The missing source files are represented by special file-list entries which
|
||||
display as a "*missing" entry in the bf(--list-only) output.
|
||||
|
||||
dit(bf(--ignore-errors)) Tells bf(--delete) to go ahead and delete files
|
||||
even when there are I/O errors.
|
||||
|
||||
@@ -1422,17 +1269,15 @@ using bf(--delete-after), and it used to be non-functional unless the
|
||||
bf(--recursive) option was also enabled.
|
||||
|
||||
dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM
|
||||
files or directories. If that limit is exceeded, all further deletions are
|
||||
skipped through the end of the transfer. At the end, rsync outputs a warning
|
||||
(including a count of the skipped deletions) and exits with an error code
|
||||
of 25 (unless some more important error condition also occurred).
|
||||
files or directories. If that limit is exceeded, a warning is output
|
||||
and rsync exits with an error code of 25 (new for 3.0.0).
|
||||
|
||||
Beginning with version 3.0.0, you may specify bf(--max-delete=0) to be warned
|
||||
Also new for version 3.0.0, you may specify bf(--max-delete=0) to be warned
|
||||
about any extraneous files in the destination without removing any of them.
|
||||
Older clients interpreted this as "unlimited", so if you don't know what
|
||||
version the client is, you can use the less obvious bf(--max-delete=-1) as
|
||||
a backward-compatible way to specify that no deletions be allowed (though
|
||||
really old versions didn't warn when the limit was exceeded).
|
||||
older versions didn't warn when the limit was exceeded).
|
||||
|
||||
dit(bf(--max-size=SIZE)) This tells rsync to avoid transferring any
|
||||
file that is larger than the specified SIZE. The SIZE value can be
|
||||
@@ -1454,15 +1299,11 @@ be offset by one byte in the indicated direction.
|
||||
Examples: --max-size=1.5mb-1 is 1499999 bytes, and --max-size=2g+1 is
|
||||
2147483649 bytes.
|
||||
|
||||
Note that rsync versions prior to 3.1.0 did not allow bf(--max-size=0).
|
||||
|
||||
dit(bf(--min-size=SIZE)) This tells rsync to avoid transferring any
|
||||
file that is smaller than the specified SIZE, which can help in not
|
||||
transferring small, junk files.
|
||||
See the bf(--max-size) option for a description of SIZE and other information.
|
||||
|
||||
Note that rsync versions prior to 3.1.0 did not allow bf(--min-size=0).
|
||||
|
||||
dit(bf(-B, --block-size=BLOCKSIZE)) This forces the block size used in
|
||||
rsync's delta-transfer algorithm to a fixed value. It is normally selected based on
|
||||
the size of each file being updated. See the technical report for details.
|
||||
@@ -1514,36 +1355,6 @@ machine for use with the bf(--relative) option. For instance:
|
||||
|
||||
quote(tt( rsync -avR --rsync-path="cd /a/b && rsync" host:c/d /e/))
|
||||
|
||||
dit(bf(-M, --remote-option=OPTION)) This option is used for more advanced
|
||||
situations where you want certain effects to be limited to one side of the
|
||||
transfer only. For instance, if you want to pass bf(--log-file=FILE) and
|
||||
bf(--fake-super) to the remote system, specify it like this:
|
||||
|
||||
quote(tt( rsync -av -M --log-file=foo -M--fake-super src/ dest/))
|
||||
|
||||
If you want to have an option affect only the local side of a transfer when
|
||||
it normally affects both sides, send its negation to the remote side. Like
|
||||
this:
|
||||
|
||||
quote(tt( rsync -av -x -M--no-x src/ dest/))
|
||||
|
||||
Be cautious using this, as it is possible to toggle an option that will cause
|
||||
rsync to have a different idea about what data to expect next over the socket,
|
||||
and that will make it fail in a cryptic fashion.
|
||||
|
||||
Note that it is best to use a separate bf(--remote-option) for each option you
|
||||
want to pass. This makes your useage compatible with the bf(--protect-args)
|
||||
option. If that option is off, any spaces in your remote options will be split
|
||||
by the remote shell unless you take steps to protect them.
|
||||
|
||||
When performing a local transfer, the "local" side is the sender and the
|
||||
"remote" side is the receiver.
|
||||
|
||||
Note some versions of the popt option-parsing library have a bug in them that
|
||||
prevents you from using an adjacent arg with an equal in it next to a short
|
||||
option letter (e.g. tt(-M--log-file=/tmp/foo). If this bug affects your
|
||||
version of popt, you can use the version of popt that is included with rsync.
|
||||
|
||||
dit(bf(-C, --cvs-exclude)) This is a useful shorthand for excluding a
|
||||
broad range of files that you often don't want to transfer between
|
||||
systems. It uses a similar algorithm to CVS to determine if
|
||||
@@ -1708,20 +1519,6 @@ side will also be translated
|
||||
from the local to the remote character-set. The translation happens before
|
||||
wild-cards are expanded. See also the bf(--files-from) option.
|
||||
|
||||
You may also control this option via the RSYNC_PROTECT_ARGS environment
|
||||
variable. If this variable has a non-zero value, this option will be enabled
|
||||
by default, otherwise it will be disabled by default. Either state is
|
||||
overridden by a manually specified positive or negative version of this option
|
||||
(note that bf(--no-s) and bf(--no-protect-args) are the negative versions).
|
||||
Since this option was first introduced in 3.0.0, you'll need to make sure it's
|
||||
disabled if you ever need to interact with a remote rsync that is older than
|
||||
that.
|
||||
|
||||
Rsync can also be configured (at build time) to have this option enabled by
|
||||
default (with is overridden by both the environment and the command-line).
|
||||
This option will eventually become a new default setting at some
|
||||
as-yet-undetermined point in the future.
|
||||
|
||||
dit(bf(-T, --temp-dir=DIR)) This option instructs rsync to use DIR as a
|
||||
scratch directory when creating temporary copies of the files transferred
|
||||
on the receiving side. The default behavior is to create each temporary
|
||||
@@ -1760,10 +1557,6 @@ looks in the same directory as the destination file for either a file that
|
||||
has an identical size and modified-time, or a similarly-named file. If
|
||||
found, rsync uses the fuzzy basis file to try to speed up the transfer.
|
||||
|
||||
If the option is repeated, the fuzzy scan will also be done in any matching
|
||||
alternate destination directories that are specified via bf(--compare-dest),
|
||||
bf(--copy-dest), or bf(--link-dest).
|
||||
|
||||
Note that the use of the bf(--delete) option might get rid of any potential
|
||||
fuzzy-match files, so either use bf(--delete-after) or specify some
|
||||
filename exclusions if you need to prevent this.
|
||||
@@ -1775,8 +1568,6 @@ directory). If a file is found in em(DIR) that is identical to the
|
||||
sender's file, the file will NOT be transferred to the destination
|
||||
directory. This is useful for creating a sparse backup of just files that
|
||||
have changed from an earlier backup.
|
||||
This option is typically used to copy into an empty (or newly created)
|
||||
directory.
|
||||
|
||||
Beginning in version 2.6.4, multiple bf(--compare-dest) directories may be
|
||||
provided, which will cause rsync to search the list in the order specified
|
||||
@@ -1789,10 +1580,6 @@ selected to try to speed up the transfer.
|
||||
If em(DIR) is a relative path, it is relative to the destination directory.
|
||||
See also bf(--copy-dest) and bf(--link-dest).
|
||||
|
||||
NOTE: beginning with version 3.1.0, rsync will remove a file from a non-empty
|
||||
destination hierarchy if an exact match is found in one of the compare-dest
|
||||
hierarchies (making the end result more closely match a fresh copy).
|
||||
|
||||
dit(bf(--copy-dest=DIR)) This option behaves like bf(--compare-dest), but
|
||||
rsync will also copy unchanged files found in em(DIR) to the destination
|
||||
directory using a local copy.
|
||||
@@ -1830,11 +1617,10 @@ If a match is not found, a basis file from one of the em(DIR)s will be
|
||||
selected to try to speed up the transfer.
|
||||
|
||||
This option works best when copying into an empty destination hierarchy, as
|
||||
existing files may get their attributes tweaked, and that can affect alternate
|
||||
destination files via hard-links. Also, itemizing of changes can get a bit
|
||||
muddled. Note that prior to version 3.1.0, an alternate-directory exact match
|
||||
would never be found (nor linked into the destination) when a destination file
|
||||
already exists.
|
||||
rsync treats existing files as definitive (so it never looks in the link-dest
|
||||
dirs when a destination file already exists), and as malleable (so it might
|
||||
change the attributes of a destination file, which affects all the hard-linked
|
||||
versions).
|
||||
|
||||
Note that if you combine this option with bf(--ignore-times), rsync will not
|
||||
link any files together because it only links identical files together as a
|
||||
@@ -1886,31 +1672,20 @@ The default list of suffixes that will not be compressed is this (in this
|
||||
version of rsync):
|
||||
|
||||
bf(7z)
|
||||
bf(ace)
|
||||
bf(avi)
|
||||
bf(bz2)
|
||||
bf(deb)
|
||||
bf(gpg)
|
||||
bf(gz)
|
||||
bf(iso)
|
||||
bf(jpeg)
|
||||
bf(jpg)
|
||||
bf(lz)
|
||||
bf(lzma)
|
||||
bf(lzo)
|
||||
bf(mov)
|
||||
bf(mp3)
|
||||
bf(mp4)
|
||||
bf(ogg)
|
||||
bf(png)
|
||||
bf(rar)
|
||||
bf(rpm)
|
||||
bf(rzip)
|
||||
bf(tbz)
|
||||
bf(tgz)
|
||||
bf(tlz)
|
||||
bf(txz)
|
||||
bf(xz)
|
||||
bf(z)
|
||||
bf(zip)
|
||||
|
||||
@@ -1935,57 +1710,6 @@ from the source system is used instead. See also the comments on the
|
||||
the chroot setting affects rsync's ability to look up the names of the
|
||||
users and groups and what you can do about it.
|
||||
|
||||
dit(bf(--usermap=STRING, --groupmap=STRING)) These options allow you to
|
||||
specify users and groups that should be mapped to other values by the
|
||||
receiving side. The bf(STRING) is one or more bf(FROM):bf(TO) pairs of
|
||||
values separated by commas. Any matching bf(FROM) value from the sender is
|
||||
replaced with a bf(TO) value from the receiver. You may specify usernames
|
||||
or user IDs for the bf(FROM) and bf(TO) values, and the bf(FROM) value may
|
||||
also be a wild-card string, which will be matched against the sender's
|
||||
names (wild-cards do NOT match against ID numbers, though see below for
|
||||
why a '*' matches everything). You may instead specify a range of ID
|
||||
numbers via an inclusive range: LOW-HIGH. For example:
|
||||
|
||||
verb( --usermap=0-99:nobody,wayne:admin,*:normal --groupmap=usr:1,1:usr)
|
||||
|
||||
The first match in the list is the one that is used. You should specify
|
||||
all your user mappings using a single bf(--usermap) option, and/or all
|
||||
your group mappings using a single bf(--groupmap) option.
|
||||
|
||||
Note that the sender's name for the 0 user and group are not transmitted
|
||||
to the receiver, so you should either match these values using a 0, or use
|
||||
the names in effect on the receiving side (typically "root"). All other
|
||||
bf(FROM) names match those in use on the sending side. All bf(TO) names
|
||||
match those in use on the receiving side.
|
||||
|
||||
Any IDs that do not have a name on the sending side are treated as having an
|
||||
empty name for the purpose of matching. This allows them to be matched via
|
||||
a "*" or using an empty name. For instance:
|
||||
|
||||
verb( --usermap=:nobody --groupmap=*:nobody)
|
||||
|
||||
When the bf(--numeric-ids) option is used, the sender does not send any
|
||||
names, so all the IDs are treated as having an empty name. This means that
|
||||
you will need to specify numeric bf(FROM) values if you want to map these
|
||||
nameless IDs to different values.
|
||||
|
||||
For the bf(--usermap) option to have any effect, the bf(-o) (bf(--owner))
|
||||
option must be used (or implied), and the receiver will need to be running
|
||||
as a super-user (see also the bf(--fake-super) option). For the bf(--groupmap)
|
||||
option to have any effect, the bf(-g) (bf(--groups)) option must be used
|
||||
(or implied), and the receiver will need to have permissions to set that
|
||||
group.
|
||||
|
||||
dit(bf(--chown=USER:GROUP)) This option forces all files to be owned by USER
|
||||
with group GROUP. This is a simpler interface than using bf(--usermap) and
|
||||
bf(--groupmap) directly, but it is implemented using those options internally,
|
||||
so you cannot mix them. If either the USER or GROUP is empty, no mapping for
|
||||
the omitted user/group will occur. If GROUP is empty, the trailing colon may
|
||||
be omitted, but if USER is empty, a leading colon must be supplied.
|
||||
|
||||
If you specify "--chown=foo:bar, this is exactly the same as specifying
|
||||
"--usermap=*:foo --groupmap=*:bar", only easier.
|
||||
|
||||
dit(bf(--timeout=TIMEOUT)) This option allows you to set a maximum I/O
|
||||
timeout in seconds. If no data is transferred for the specified time
|
||||
then rsync will exit. The default is 0, which means no timeout.
|
||||
@@ -2020,13 +1744,6 @@ rsync defaults to using
|
||||
blocking I/O, otherwise it defaults to using non-blocking I/O. (Note that
|
||||
ssh prefers non-blocking I/O.)
|
||||
|
||||
dit(bf(--outbuf=MODE)) This sets the output buffering mode. The mode can be
|
||||
None (aka Unbuffered), Line, or Block (aka Full). You may specify as little
|
||||
as a single letter for the mode, and use upper or lower case.
|
||||
|
||||
The main use of this option is to change Full buffering to Line buffering
|
||||
when rsync's output is going to a file or pipe.
|
||||
|
||||
dit(bf(-i, --itemize-changes)) Requests a simple itemized list of the
|
||||
changes that are being made to each file, including attribute changes.
|
||||
This is exactly the same as specifying bf(--out-format='%i %n%L').
|
||||
@@ -2106,13 +1823,13 @@ dit(bf(--out-format=FORMAT)) This allows you to specify exactly what the
|
||||
rsync client outputs to the user on a per-update basis. The format is a
|
||||
text string containing embedded single-character escape sequences prefixed
|
||||
with a percent (%) character. A default format of "%n%L" is assumed if
|
||||
either bf(--info=name) or bf(-v) is specified (this tells you just the name
|
||||
bf(-v) is specified (which reports the name
|
||||
of the file and, if the item is a link, where it points). For a full list
|
||||
of the possible escape characters, see the "log format" setting in the
|
||||
rsyncd.conf manpage.
|
||||
|
||||
Specifying the bf(--out-format) option implies the bf(--info=name) option,
|
||||
which will mention each file, dir, etc. that gets updated in a significant
|
||||
Specifying the bf(--out-format) option
|
||||
will mention each file, dir, etc. that gets updated in a significant
|
||||
way (a transferred file, a recreated symlink/device, or a touched
|
||||
directory). In addition, if the itemize-changes escape (%i) is included in
|
||||
the string (e.g. if the bf(--itemize-changes) option was used), the logging
|
||||
@@ -2137,7 +1854,7 @@ option if you wish to override this.
|
||||
Here's a example command that requests the remote side to log what is
|
||||
happening:
|
||||
|
||||
verb( rsync -av --remote-option=--log-file=/tmp/rlog src/ dest/)
|
||||
verb( rsync -av --rsync-path="rsync --log-file=/tmp/rlog" src/ dest/)
|
||||
|
||||
This is very useful if you need to debug why a connection is closing
|
||||
unexpectedly.
|
||||
@@ -2154,29 +1871,14 @@ is '%i %n%L'.
|
||||
|
||||
dit(bf(--stats)) This tells rsync to print a verbose set of statistics
|
||||
on the file transfer, allowing you to tell how effective rsync's delta-transfer
|
||||
algorithm is for your data. This option is equivalent to bf(--info=stats2)
|
||||
if combined with 0 or 1 bf(-v) options, or bf(--info=stats3) if combined
|
||||
with 2 or more bf(-v) options.
|
||||
algorithm is for your data.
|
||||
|
||||
The current statistics are as follows: quote(itemization(
|
||||
it() bf(Number of files) is the count of all "files" (in the generic
|
||||
sense), which includes directories, symlinks, etc. The total count will
|
||||
be followed by a list of counts by filetype (if the total is non-zero).
|
||||
For example: "(reg: 5, dir: 3, link: 2, dev: 1, special: 1)" lists the
|
||||
totals for regular files, directories, symlinks, devices, and special
|
||||
files. If any of value is 0, it is completely omitted from the list.
|
||||
it() bf(Number of created files) is the count of how many "files" (generic
|
||||
sense) were created (as opposed to updated). The total count will be
|
||||
followed by a list of counts by filetype (if the total is non-zero).
|
||||
it() bf(Number of deleted files) is the count of how many "files" (generic
|
||||
sense) were created (as opposed to updated). The total count will be
|
||||
followed by a list of counts by filetype (if the total is non-zero).
|
||||
Note that this line is only output if deletions are in effect, and only
|
||||
if protocol 31 is being used (the default for rsync 3.1.x).
|
||||
it() bf(Number of regular files transferred) is the count of normal files
|
||||
that were updated via rsync's delta-transfer algorithm, which does not
|
||||
include dirs, symlinks, etc. Note that rsync 3.1.0 added the word
|
||||
"regular" into this heading.
|
||||
sense), which includes directories, symlinks, etc.
|
||||
it() bf(Number of files transferred) is the count of normal files that
|
||||
were updated via rsync's delta-transfer algorithm, which does not include created
|
||||
dirs, symlinks, etc.
|
||||
it() bf(Total file size) is the total sum of all file sizes in the transfer.
|
||||
This does not count any size for directories or special files, but does
|
||||
include the size of symlinks.
|
||||
@@ -2215,25 +1917,10 @@ would output as "\#012". A literal backslash that is in a filename is not
|
||||
escaped unless it is followed by a hash and 3 digits (0-9).
|
||||
|
||||
dit(bf(-h, --human-readable)) Output numbers in a more human-readable format.
|
||||
There are 3 possible levels: (1) output numbers with a separator between each
|
||||
set of 3 digits (either a comma or a period, depending on if the decimal point
|
||||
is represented by a period or a comma); (2) output numbers in units of 1000
|
||||
(with a character suffix for larger units -- see below); (3) output numbers in
|
||||
units of 1024.
|
||||
|
||||
The default is human-readable level 1. Each bf(-h) option increases the level
|
||||
by one. You can take the level down to 0 (to output numbers as pure digits) by
|
||||
specifing the bf(--no-human-readable) (bf(--no-h)) option.
|
||||
|
||||
The unit letters that are appended in levels 2 and 3 are: K (kilo), M (mega),
|
||||
G (giga), or T (tera). For example, a 1234567-byte file would output as 1.23M
|
||||
in level-2 (assuming that a period is your local decimal point).
|
||||
|
||||
Backward compatibility note: versions of rsync prior to 3.1.0 do not support
|
||||
human-readable level 1, and they default to level 0. Thus, specifying one or
|
||||
two bf(-h) options will behave in a comparable manner in old and new versions
|
||||
as long as you didn't specify a bf(--no-h) option prior to one or more bf(-h)
|
||||
options. See the bf(--list-only) option for one difference.
|
||||
This makes big numbers output using larger units, with a K, M, or G suffix. If
|
||||
this option was specified once, these units are K (1000), M (1000*1000), and
|
||||
G (1000*1000*1000); if the option is repeated, the units are powers of 1024
|
||||
instead of 1000.
|
||||
|
||||
dit(bf(--partial)) By default, rsync will delete any partially
|
||||
transferred file if the transfer is interrupted. In some circumstances
|
||||
@@ -2362,9 +2049,7 @@ in place of the hide-filter (if that is more natural to you).
|
||||
dit(bf(--progress)) This option tells rsync to print information
|
||||
showing the progress of the transfer. This gives a bored user
|
||||
something to watch.
|
||||
With a modern rsync this is the same as specifying
|
||||
bf(--info=flist2,name,progress), but any user-supplied settings for those
|
||||
info flags takes precedence (e.g. "--info=flist0 --progress").
|
||||
Implies bf(--verbose) if it wasn't already specified.
|
||||
|
||||
While rsync is transferring a regular file, it updates a progress line that
|
||||
looks like this:
|
||||
@@ -2386,41 +2071,23 @@ was finishing the matched part of the file.
|
||||
When the file transfer finishes, rsync replaces the progress line with a
|
||||
summary line that looks like this:
|
||||
|
||||
verb( 1,238,099 100% 146.38kB/s 0:00:08 (xfr#5, to-chk=169/396))
|
||||
verb( 1238099 100% 146.38kB/s 0:00:08 (xfer#5, to-check=169/396))
|
||||
|
||||
In this example, the file was 1,238,099 bytes long in total, the average rate
|
||||
In this example, the file was 1238099 bytes long in total, the average rate
|
||||
of transfer for the whole file was 146.38 kilobytes per second over the 8
|
||||
seconds that it took to complete, it was the 5th transfer of a regular file
|
||||
during the current rsync session, and there are 169 more files for the
|
||||
receiver to check (to see if they are up-to-date or not) remaining out of
|
||||
the 396 total files in the file-list.
|
||||
|
||||
In an incremental recursion scan, rsync won't know the total number of files
|
||||
in the file-list until it reaches the ends of the scan, but since it starts to
|
||||
transfer files during the scan, it will display a line with the text "ir-chk"
|
||||
(for incremental recursion check) instead of "to-chk" until the point that it
|
||||
knows the full size of the list, at which point it will switch to using
|
||||
"to-chk". Thus, seeing "ir-chk" lets you know that the total count of files
|
||||
in the file list is still going to increase (and each time it does, the count
|
||||
of files left to check will increase by the number of the files added to the
|
||||
list).
|
||||
|
||||
dit(bf(-P)) The bf(-P) option is equivalent to bf(--partial) bf(--progress). Its
|
||||
purpose is to make it much easier to specify these two options for a long
|
||||
transfer that may be interrupted.
|
||||
|
||||
There is also a bf(--info=progress2) option that outputs statistics based
|
||||
on the whole transfer, rather than individual files. Use this flag without
|
||||
outputting a filename (e.g. avoid bf(-v) or specify bf(--info=name0) if you
|
||||
want to see how the transfer is doing without scrolling the screen with a
|
||||
lot of names. (You don't need to specify the bf(--progress) option in
|
||||
order to use bf(--info=progress2).)
|
||||
|
||||
dit(bf(--password-file=FILE)) This option allows you to provide a password for
|
||||
accessing an rsync daemon via a file or via standard input if bf(FILE) is
|
||||
bf(-). The file should contain just the password on the first line (all other
|
||||
lines are ignored). Rsync will exit with an error if bf(FILE) is world
|
||||
readable or if a root-run rsync command finds a non-root-owned file.
|
||||
dit(bf(--password-file)) This option allows you to provide a password in a
|
||||
file for accessing an rsync daemon. The file must not be world readable.
|
||||
It should contain just the password as the first line of the file (all
|
||||
other lines are ignored).
|
||||
|
||||
This option does not supply a password to a remote shell transport such as
|
||||
ssh; to learn how to do that, consult the remote shell's documentation.
|
||||
@@ -2441,14 +2108,6 @@ without using this option. For example:
|
||||
|
||||
verb( rsync -av --list-only foo* dest/)
|
||||
|
||||
Starting with rsync 3.1.0, the sizes output by bf(--list-only) are affected
|
||||
by the bf(--human-readable) option. By default they will contain digit
|
||||
separators, but higher levels of readability will output the sizes with
|
||||
unit suffixes. Note also that the column width for the size output has
|
||||
increased from 11 to 14 characters for all human-readable levels. Use
|
||||
bf(--no-h) if you want just digits in the sizes, and the old column width
|
||||
of 11 characters.
|
||||
|
||||
Compatibility note: when requesting a remote listing of files from an rsync
|
||||
that is version 2.6.3 or older, you may encounter an error if you ask for a
|
||||
non-recursive listing. This is because a file listing implies the bf(--dirs)
|
||||
@@ -2457,27 +2116,13 @@ avoid this problem, either specify the bf(--no-dirs) option (if you don't
|
||||
need to expand a directory's content), or turn on recursion and exclude
|
||||
the content of subdirectories: bf(-r --exclude='/*/*').
|
||||
|
||||
dit(bf(--bwlimit=RATE)) This option allows you to specify the maximum transfer
|
||||
rate for the data sent over the socket, specified in units per second. The
|
||||
RATE value can be suffixed with a string to indicate a size multiplier, and may
|
||||
be a fractional value (e.g. "bf(--bwlimit=1.5m)"). If no suffix is specified,
|
||||
the value will be assumed to be in units of 1024 bytes (as if "K" or "KiB" had
|
||||
been appended). See the bf(--max-size) option for a description of all the
|
||||
available suffixes. A value of zero specifies no limit.
|
||||
|
||||
For backward-compatibility reasons, the rate limit will be rounded to the
|
||||
nearest KiB unit, so no rate smaller than 1024 bytes per second is possible.
|
||||
|
||||
Rsync writes data over the socket in blocks, and this option both limits the
|
||||
size of the blocks that rsync writes, and tries to keep the average transfer
|
||||
rate at the requested limit. Some "burstiness" may be seen where rsync writes
|
||||
out a block of data and then sleeps to bring the average rate into compliance.
|
||||
|
||||
Due to the internal buffering of data, the bf(--progress) option may not be an
|
||||
accurate reflection on how fast the data is being sent. This is because some
|
||||
files can show up as being rapidly sent when the data is quickly buffered,
|
||||
while other can show up as very slow when the flushing of the output buffer
|
||||
occurs. This may be fixed in a future version.
|
||||
dit(bf(--bwlimit=KBPS)) This option allows you to specify a maximum
|
||||
transfer rate in kilobytes per second. This option is most effective when
|
||||
using rsync with large files (several megabytes and up). Due to the nature
|
||||
of rsync transfers, blocks of data are sent, then if rsync determines the
|
||||
transfer was too fast, it will wait before sending the next data block. The
|
||||
result is an average transfer rate equaling the specified limit. A value
|
||||
of zero specifies no limit.
|
||||
|
||||
dit(bf(--write-batch=FILE)) Record a file that can later be applied to
|
||||
another identical destination with bf(--read-batch). See the "BATCH MODE"
|
||||
@@ -2552,15 +2197,15 @@ If rsync was complied without support for IPv6, the bf(--ipv6) option
|
||||
will have no effect. The bf(--version) output will tell you if this
|
||||
is the case.
|
||||
|
||||
dit(bf(--checksum-seed=NUM)) Set the checksum seed to the integer NUM. This 4
|
||||
byte checksum seed is included in each block and MD4 file checksum calculation
|
||||
(the more modern MD5 file checksums don't use a seed). By default the checksum
|
||||
seed is generated by the server and defaults to the current code(time()). This
|
||||
option is used to set a specific checksum seed, which is useful for
|
||||
applications that want repeatable block checksums, or in the case where the
|
||||
user wants a more random checksum seed. Setting NUM to 0 causes rsync to use
|
||||
the default of code(time()) for checksum seed.
|
||||
|
||||
dit(bf(--checksum-seed=NUM)) Set the checksum seed to the integer
|
||||
NUM. This 4 byte checksum seed is included in each block and file
|
||||
checksum calculation. By default the checksum seed is generated
|
||||
by the server and defaults to the current code(time()). This option
|
||||
is used to set a specific checksum seed, which is useful for
|
||||
applications that want repeatable block and file checksums, or
|
||||
in the case where the user wants a more random checksum seed.
|
||||
Setting NUM to 0 causes rsync to use the default of code(time())
|
||||
for checksum seed.
|
||||
enddit()
|
||||
|
||||
manpagesection(DAEMON OPTIONS)
|
||||
@@ -2585,10 +2230,11 @@ allows you to specify a specific IP address (or hostname) to bind to. This
|
||||
makes virtual hosting possible in conjunction with the bf(--config) option.
|
||||
See also the "address" global option in the rsyncd.conf manpage.
|
||||
|
||||
dit(bf(--bwlimit=RATE)) This option allows you to specify the maximum transfer
|
||||
rate for the data the daemon sends over the socket. The client can still
|
||||
specify a smaller bf(--bwlimit) value, but no larger value will be allowed.
|
||||
See the client version of this option (above) for some extra details.
|
||||
dit(bf(--bwlimit=KBPS)) This option allows you to specify a maximum
|
||||
transfer rate in kilobytes per second for the data the daemon sends.
|
||||
The client can still specify a smaller bf(--bwlimit) value, but their
|
||||
requested value will be rounded down if they try to exceed it. See the
|
||||
client version of this option (above) for some extra details.
|
||||
|
||||
dit(bf(--config=FILE)) This specifies an alternate config file than
|
||||
the default. This is only relevant when bf(--daemon) is specified.
|
||||
@@ -2596,14 +2242,6 @@ The default is /etc/rsyncd.conf unless the daemon is running over
|
||||
a remote shell program and the remote user is not the super-user; in that case
|
||||
the default is rsyncd.conf in the current directory (typically $HOME).
|
||||
|
||||
dit(bf(-M, --dparam=OVERRIDE)) This option can be used to set a daemon-config
|
||||
parameter when starting up rsync in daemon mode. It is equivalent to adding
|
||||
the parameter at the end of the global settings prior to the first module's
|
||||
definition. The parameter names can be specified without spaces, if you so
|
||||
desire. For instance:
|
||||
|
||||
verb( rsync --daemon -M pidfile=/path/rsync.pid )
|
||||
|
||||
dit(bf(--no-detach)) When running as a daemon, this option instructs
|
||||
rsync to not detach itself and become a background process. This
|
||||
option is required when running as a service on Cygwin, and may also
|
||||
@@ -3314,9 +2952,6 @@ ignore patterns in .cvsignore files. See the bf(--cvs-exclude) option for
|
||||
more details.
|
||||
dit(bf(RSYNC_ICONV)) Specify a default bf(--iconv) setting using this
|
||||
environment variable. (First supported in 3.0.0.)
|
||||
dit(bf(RSYNC_PROTECT_ARGS)) Specify a non-zero numeric value if you want the
|
||||
bf(--protect-args) option to be enabled by default, or a zero value to make
|
||||
sure that it is disabled by default. (First supported in 3.1.0.)
|
||||
dit(bf(RSYNC_RSH)) The RSYNC_RSH environment variable allows you to
|
||||
override the default shell used as the transport for rsync. Command line
|
||||
options are permitted after the command name, just as in the bf(-e) option.
|
||||
@@ -3361,7 +2996,7 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
|
||||
This man page is current for version 3.1.0 of rsync.
|
||||
This man page is current for version 3.0.8 of rsync.
|
||||
|
||||
manpagesection(INTERNAL OPTIONS)
|
||||
|
||||
@@ -3375,7 +3010,7 @@ ssh login.
|
||||
|
||||
manpagesection(CREDITS)
|
||||
|
||||
rsync is distributed under the GNU General Public License. See the file
|
||||
rsync is distributed under the GNU public license. See the file
|
||||
COPYING for details.
|
||||
|
||||
A WEB site is available at
|
||||
|
||||
280
rsyncd.conf.yo
280
rsyncd.conf.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsyncd.conf)(5)(28 Sep 2013)()()
|
||||
manpage(rsyncd.conf)(5)(26 Mar 2011)()()
|
||||
manpagename(rsyncd.conf)(configuration file for rsync in daemon mode)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -28,9 +28,8 @@ whitespace in module and parameter names is irrelevant. Leading and
|
||||
trailing whitespace in a parameter value is discarded. Internal whitespace
|
||||
within a parameter value is retained verbatim.
|
||||
|
||||
Any line bf(beginning) with a hash (#) is ignored, as are lines containing
|
||||
only whitespace. (If a hash occurs after anything other than leading
|
||||
whitespace, it is considered a part of the line's content.)
|
||||
Any line beginning with a hash (#) is ignored, as are lines containing
|
||||
only whitespace.
|
||||
|
||||
Any line ending in a \ is "continued" on the next line in the
|
||||
customary UNIX fashion.
|
||||
@@ -79,31 +78,15 @@ You may also include any module parameters in the global part of the
|
||||
config file in which case the supplied value will override the
|
||||
default for that parameter.
|
||||
|
||||
You may use references to environment variables in the values of parameters.
|
||||
String parameters will have %VAR% references expanded as late as possible (when
|
||||
the string is used in the program), allowing for the use of variables that
|
||||
rsync sets at connection time, such as RSYNC_USER_NAME. Non-string parameters
|
||||
(such as true/false settings) are expanded when read from the config file. If
|
||||
a variable does not exist in the environment, or if a sequence of characters is
|
||||
not a valid reference (such as an un-paired percent sign), the raw characters
|
||||
are passed through unchanged. This helps with backward compatibility and
|
||||
safety (e.g. expanding a non-existent %VAR% to an empty string in a path could
|
||||
result in a very unsafe path). The safest way to insert a literal % into a
|
||||
value is to use %%.
|
||||
|
||||
startdit()
|
||||
dit(bf(motd file)) This parameter allows you to specify a
|
||||
"message of the day" to display to clients on each connect. This
|
||||
usually contains site information and any legal notices. The default
|
||||
is no motd file.
|
||||
This can be overridden by the bf(--dparam=motdfile=FILE)
|
||||
command-line option when starting the daemon.
|
||||
|
||||
dit(bf(pid file)) This parameter tells the rsync daemon to write
|
||||
its process ID to that file. If the file already exists, the rsync
|
||||
daemon will abort rather than overwrite the file.
|
||||
This can be overridden by the bf(--dparam=pidfile=FILE)
|
||||
command-line option when starting the daemon.
|
||||
|
||||
dit(bf(port)) You can override the default port the daemon will listen on
|
||||
by specifying this value (defaults to 873). This is ignored if the daemon
|
||||
@@ -121,9 +104,6 @@ details on some of the options you may be able to set. By default no
|
||||
special socket options are set. These settings can also be specified
|
||||
via the bf(--sockopts) command-line option.
|
||||
|
||||
dit(bf(listen backlog)) You can override the default backlog value when the
|
||||
daemon listens for connections. It defaults to 5.
|
||||
|
||||
enddit()
|
||||
|
||||
manpagesection(MODULE PARAMETERS)
|
||||
@@ -137,9 +117,6 @@ name contains whitespace, each internal sequence of whitespace will be
|
||||
changed into a single space, while leading or trailing whitespace will be
|
||||
discarded.
|
||||
|
||||
As with GLOBAL PARAMETERS, you may use references to environment variables in
|
||||
the values of parameters. See the GLOBAL PARAMETERS section for more details.
|
||||
|
||||
startdit()
|
||||
|
||||
dit(bf(comment)) This parameter specifies a description string
|
||||
@@ -150,19 +127,6 @@ dit(bf(path)) This parameter specifies the directory in the daemon's
|
||||
filesystem to make available in this module. You must specify this parameter
|
||||
for each module in tt(rsyncd.conf).
|
||||
|
||||
You may base the path's value off of an environment variable by surrounding
|
||||
the variable name with percent signs. You can even reference a variable
|
||||
that is set by rsync when the user connects.
|
||||
For example, this would use the authorizing user's name in the path:
|
||||
|
||||
verb( path = /home/%RSYNC_USER_NAME% )
|
||||
|
||||
It is fine if the path includes internal spaces -- they will be retained
|
||||
verbatim (which means that you shouldn't try to escape them). If your final
|
||||
directory has a trailing space (and this is somehow not something you wish to
|
||||
fix), append a trailing slash to the path to avoid losing the trailing
|
||||
whitespace.
|
||||
|
||||
dit(bf(use chroot)) If "use chroot" is true, the rsync daemon will chroot
|
||||
to the "path" before starting the file transfer with the client. This has
|
||||
the advantage of extra protection against possible implementation security
|
||||
@@ -227,9 +191,8 @@ to translate names, and that it is not possible for a user to change those
|
||||
resources.
|
||||
|
||||
dit(bf(munge symlinks)) This parameter tells rsync to modify
|
||||
all symlinks in the same way as the (non-daemon-affecting)
|
||||
bf(--munge-links) command-line option (using a method described below).
|
||||
This should help protect your files from user trickery when
|
||||
all incoming symlinks in a way that makes them unusable but recoverable
|
||||
(see below). This should help protect your files from user trickery when
|
||||
your daemon module is writable. The default is disabled when "use chroot"
|
||||
is on and the inside-chroot path is "/", otherwise it is enabled.
|
||||
|
||||
@@ -297,12 +260,6 @@ If the daemon fails to open the specified file, it will fall back to
|
||||
using syslog and output an error about the failure. (Note that the
|
||||
failure to open the specified log file used to be a fatal error.)
|
||||
|
||||
This setting can be overridden by using the bf(--log-file=FILE) or
|
||||
bf(--dparam=logfile=FILE) command-line options. The former overrides
|
||||
all the log-file parameters of the daemon and all module settings.
|
||||
The latter sets the daemon's log file and the default for all the
|
||||
modules, which still allows modules to override the default setting.
|
||||
|
||||
dit(bf(syslog facility)) This parameter allows you to
|
||||
specify the syslog facility name to use when logging messages from the
|
||||
rsync daemon. You may use any standard syslog facility name which is
|
||||
@@ -330,46 +287,27 @@ attempted uploads will fail. If "read only" is false then uploads will
|
||||
be possible if file permissions on the daemon side allow them. The default
|
||||
is for all modules to be read only.
|
||||
|
||||
Note that "auth users" can override this setting on a per-user basis.
|
||||
|
||||
dit(bf(write only)) This parameter determines whether clients
|
||||
will be able to download files or not. If "write only" is true then any
|
||||
attempted downloads will fail. If "write only" is false then downloads
|
||||
will be possible if file permissions on the daemon side allow them. The
|
||||
default is for this parameter to be disabled.
|
||||
|
||||
dit(bf(list)) This parameter determines whether this module is
|
||||
listed when the client asks for a listing of available modules. In addition,
|
||||
if this is false, the daemon will pretend the module does not exist
|
||||
when a client denied by "hosts allow" or "hosts deny" attempts to access it.
|
||||
Realize that if "reverse lookup" is disabled globally but enabled for the
|
||||
module, the resulting reverse lookup to a potentially client-controlled DNS
|
||||
server may still reveal to the client that it hit an existing module.
|
||||
The default is for modules to be listable.
|
||||
dit(bf(list)) This parameter determines if this module should be
|
||||
listed when the client asks for a listing of available modules. By
|
||||
setting this to false you can create hidden modules. The default is
|
||||
for modules to be listable.
|
||||
|
||||
dit(bf(uid)) This parameter specifies the user name or user ID that
|
||||
file transfers to and from that module should take place as when the daemon
|
||||
was run as root. In combination with the "gid" parameter this determines what
|
||||
file permissions are available. The default when run by a super-user is to
|
||||
switch to the system's "nobody" user. The default for a non-super-user is to
|
||||
not try to change the user. See also the "gid" parameter.
|
||||
file permissions are available. The default is uid -2, which is normally
|
||||
the user "nobody".
|
||||
|
||||
The RSYNC_USER_NAME environment variable may be used to request that rsync run
|
||||
as the authorizing user. For example, if you want a rsync to run as the same
|
||||
user that was received for the rsync authentication, this setup is useful:
|
||||
|
||||
verb( uid = %RSYNC_USER_NAME%
|
||||
gid = * )
|
||||
|
||||
dit(bf(gid)) This parameter specifies one or more group names/IDs that will be
|
||||
used when accessing the module. The first one will be the default group, and
|
||||
any extra ones be set as supplemental groups. You may also specify a "*" as
|
||||
the first gid in the list, which will be replaced by all the normal groups for
|
||||
the transfer's user (see "uid"). The default when run by a super-user is to
|
||||
switch to your OS's "nobody" (or perhaps "nogroup") group with no other
|
||||
supplementary groups. The default for a non-super-user is to not change any
|
||||
group attributes (and indeed, your OS may not allow a non-super-user to try to
|
||||
change their group settings).
|
||||
dit(bf(gid)) This parameter specifies the group name or group ID that
|
||||
file transfers to and from that module should take place as when the daemon
|
||||
was run as root. This complements the "uid" parameter. The default is gid -2,
|
||||
which is normally the group "nobody".
|
||||
|
||||
dit(bf(fake super)) Setting "fake super = yes" for a module causes the
|
||||
daemon side to behave as if the bf(--fake-super) command-line option had
|
||||
@@ -444,12 +382,10 @@ be on to the clients.
|
||||
See the description of the bf(--chmod) rsync option and the bf(chmod)(1)
|
||||
manpage for information on the format of this string.
|
||||
|
||||
dit(bf(auth users)) This parameter specifies a comma and/or space-separated
|
||||
list of authorization rules. In its simplest form, you list the usernames
|
||||
that will be allowed to connect to
|
||||
dit(bf(auth users)) This parameter specifies a comma and
|
||||
space-separated list of usernames that will be allowed to connect to
|
||||
this module. The usernames do not need to exist on the local
|
||||
system. The rules may contain shell wildcard characters that will be matched
|
||||
against the username provided by the client for authentication. If
|
||||
system. The usernames may also contain shell wildcard characters. If
|
||||
"auth users" is set then the client will be challenged to supply a
|
||||
username and password to connect to the module. A challenge response
|
||||
authentication protocol is used for this exchange. The plain text
|
||||
@@ -457,65 +393,24 @@ usernames and passwords are stored in the file specified by the
|
||||
"secrets file" parameter. The default is for all users to be able to
|
||||
connect without a password (this is called "anonymous rsync").
|
||||
|
||||
In addition to username matching, you can specify groupname matching via a '@'
|
||||
prefix. When using groupname matching, the authenticating username must be a
|
||||
real user on the system, or it will be assumed to be a member of no groups.
|
||||
For example, specifying "@rsync" will match the authenticating user if the
|
||||
named user is a member of the rsync group.
|
||||
|
||||
Finally, options may be specified after a colon (:). The options allow you to
|
||||
"deny" a user or a group, set the access to "ro" (read-only), or set the access
|
||||
to "rw" (read/write). Setting an auth-rule-specific ro/rw setting overrides
|
||||
the module's "read only" setting.
|
||||
|
||||
Be sure to put the rules in the order you want them to be matched, because the
|
||||
checking stops at the first matching user or group, and that is the only auth
|
||||
that is checked. For example:
|
||||
|
||||
verb( auth users = joe:deny @guest:deny admin:rw @rsync:ro susan joe sam )
|
||||
|
||||
In the above rule, user joe will be denied access no matter what. Any user
|
||||
that is in the group "guest" is also denied access. The user "admin" gets
|
||||
access in read/write mode, but only if the admin user is not in group "guest"
|
||||
(because the admin user-matching rule would never be reached if the user is in
|
||||
group "guest"). Any other user who is in group "rsync" will get read-only
|
||||
access. Finally, users susan, joe, and sam get the ro/rw setting of the
|
||||
module, but only if the user didn't match an earlier group-matching rule.
|
||||
|
||||
See the description of the secrets file for how you can have per-user passwords
|
||||
as well as per-group passwords. It also explains how a user can authenticate
|
||||
using their user password or (when applicable) a group password, depending on
|
||||
what rule is being authenticated.
|
||||
|
||||
See also the section entitled "USING RSYNC-DAEMON FEATURES VIA A REMOTE
|
||||
SHELL CONNECTION" in bf(rsync)(1) for information on how handle an
|
||||
rsyncd.conf-level username that differs from the remote-shell-level
|
||||
username when using a remote shell to connect to an rsync daemon.
|
||||
|
||||
dit(bf(secrets file)) This parameter specifies the name of a file that contains
|
||||
the username:password and/or @groupname:password pairs used for authenticating
|
||||
this module. This file is only consulted if the "auth users" parameter is
|
||||
specified. The file is line-based and contains one name:password pair per
|
||||
line. Any line has a hash (#) as the very first character on the line is
|
||||
considered a comment and is skipped. The passwords can contain any characters
|
||||
but be warned that many operating systems limit the length of passwords that
|
||||
can be typed at the client end, so you may find that passwords longer than 8
|
||||
characters don't work.
|
||||
|
||||
The use of group-specific lines are only relevant when the module is being
|
||||
authorized using a matching "@groupname" rule. When that happens, the user
|
||||
can be authorized via either their "username:password" line or the
|
||||
"@groupname:password" line for the group that triggered the authentication.
|
||||
|
||||
It is up to you what kind of password entries you want to include, either
|
||||
users, groups, or both. The use of group rules in "auth users" does not
|
||||
require that you specify a group password if you do not want to use shared
|
||||
passwords.
|
||||
dit(bf(secrets file)) This parameter specifies the name of
|
||||
a file that contains the username:password pairs used for
|
||||
authenticating this module. This file is only consulted if the "auth
|
||||
users" parameter is specified. The file is line based and contains
|
||||
username:password pairs separated by a single colon. Any line starting
|
||||
with a hash (#) is considered a comment and is skipped. The passwords
|
||||
can contain any characters but be warned that many operating systems
|
||||
limit the length of passwords that can be typed at the client end, so
|
||||
you may find that passwords longer than 8 characters don't work.
|
||||
|
||||
There is no default for the "secrets file" parameter, you must choose a name
|
||||
(such as tt(/etc/rsyncd.secrets)). The file must normally not be readable
|
||||
by "other"; see "strict modes". If the file is not found or is rejected, no
|
||||
logins for a "user auth" module will be possible.
|
||||
by "other"; see "strict modes".
|
||||
|
||||
dit(bf(strict modes)) This parameter determines whether or not
|
||||
the permissions on the secrets file will be checked. If "strict modes" is
|
||||
@@ -542,14 +437,12 @@ quote(itemization(
|
||||
IP address and maskaddr is the netmask in dotted decimal notation for IPv4,
|
||||
or similar for IPv6, e.g. ffff:ffff:ffff:ffff:: instead of /64. All IP
|
||||
addresses which match the masked IP address will be allowed in.
|
||||
it() a hostname pattern using wildcards. If the hostname of the connecting IP
|
||||
(as determined by a reverse lookup) matches the wildcarded name (using the
|
||||
same rules as normal unix filename matching), the client is allowed in. This
|
||||
only works if "reverse lookup" is enabled (the default).
|
||||
it() a hostname. A plain hostname is matched against the reverse DNS of the
|
||||
connecting IP (if "reverse lookup" is enabled), and/or the IP of the given
|
||||
hostname is matched against the connecting IP (if "forward lookup" is
|
||||
enabled, as it is by default). Any match will be allowed in.
|
||||
it() a hostname. The hostname as determined by a reverse lookup will
|
||||
be matched (case insensitive) against the pattern. Only an exact
|
||||
match is allowed in.
|
||||
it() a hostname pattern using wildcards. These are matched using the
|
||||
same rules as normal unix filename matching. If the pattern matches
|
||||
then the client is allowed in.
|
||||
))
|
||||
|
||||
Note IPv6 link-local addresses can have a scope in the address specification:
|
||||
@@ -577,23 +470,6 @@ rejected. See the "hosts allow" parameter for more information.
|
||||
|
||||
The default is no "hosts deny" parameter, which means all hosts can connect.
|
||||
|
||||
dit(bf(reverse lookup)) Controls whether the daemon performs a reverse lookup
|
||||
on the client's IP address to determine its hostname, which is used for
|
||||
"hosts allow"/"hosts deny" checks and the "%h" log escape. This is enabled by
|
||||
default, but you may wish to disable it to save time if you know the lookup will
|
||||
not return a useful result, in which case the daemon will use the name
|
||||
"UNDETERMINED" instead.
|
||||
|
||||
If this parameter is enabled globally (even by default), rsync performs the
|
||||
lookup as soon as a client connects, so disabling it for a module will not
|
||||
avoid the lookup. Thus, you probably want to disable it globally and then
|
||||
enable it for modules that need the information.
|
||||
|
||||
dit(bf(forward lookup)) Controls whether the daemon performs a forward lookup
|
||||
on any hostname specified in an hosts allow/deny setting. By default this is
|
||||
enabled, allowing the use of an explicit hostname that would not be returned
|
||||
by reverse DNS of the connecting IP.
|
||||
|
||||
dit(bf(ignore errors)) This parameter tells rsyncd to
|
||||
ignore I/O errors on the daemon when deciding whether to run the delete
|
||||
phase of the transfer. Normally rsync skips the bf(--delete) step if any
|
||||
@@ -620,11 +496,6 @@ The format is a text string containing embedded single-character escape
|
||||
sequences prefixed with a percent (%) character. An optional numeric
|
||||
field width may also be specified between the percent and the escape
|
||||
letter (e.g. "bf(%-50n %8l %07p)").
|
||||
In addition, one or more apostrophes may be specified prior to a numerical
|
||||
escape to indicate that the numerical value should be made more human-readable.
|
||||
The 3 supported levels are the same as for the bf(--human-readable)
|
||||
command-line option, though the default is for human-readability to be off.
|
||||
Each added apostrophe increases the level (e.g. "bf(%''l %'b %f)").
|
||||
|
||||
The default log format is "%o %h [%a] %m (%u) %f %l", and a "%t [%p] "
|
||||
is always prefixed when using the "log file" parameter.
|
||||
@@ -635,14 +506,13 @@ rsyncstats.)
|
||||
The single-character escapes that are understood are as follows:
|
||||
|
||||
quote(itemization(
|
||||
it() %a the remote IP address (only available for a daemon)
|
||||
it() %a the remote IP address
|
||||
it() %b the number of bytes actually transferred
|
||||
it() %B the permission bits of the file (e.g. rwxrwxrwt)
|
||||
it() %c the total size of the block checksums received for the basis file (only when sending)
|
||||
it() %C the full-file MD5 checksum if bf(--checksum) is enabled or a file was transferred (only for protocol 30 or above).
|
||||
it() %f the filename (long form on sender; no trailing "/")
|
||||
it() %G the gid of the file (decimal) or "DEFAULT"
|
||||
it() %h the remote host name (only available for a daemon)
|
||||
it() %h the remote host name
|
||||
it() %i an itemized list of what is being updated
|
||||
it() %l the length of the file in bytes
|
||||
it() %L the string " -> SYMLINK", " => HARDLINK", or "" (where bf(SYMLINK) or bf(HARDLINK) is a filename)
|
||||
@@ -713,12 +583,7 @@ the sender.
|
||||
|
||||
dit(bf(pre-xfer exec), bf(post-xfer exec)) You may specify a command to be run
|
||||
before and/or after the transfer. If the bf(pre-xfer exec) command fails, the
|
||||
transfer is aborted before it begins. Any output from the script on stdout (up
|
||||
to several KB) will be displayed to the user when aborting, but is NOT
|
||||
displayed if the script returns success. Any output from the script on stderr
|
||||
goes to the daemon's stderr, which is typically discarded (though see
|
||||
--no-detatch option for a way to see the stderr output, which can assist with
|
||||
debugging).
|
||||
transfer is aborted before it begins.
|
||||
|
||||
The following environment variables will be set, though some are
|
||||
specific to the pre-xfer or the post-xfer environment:
|
||||
@@ -731,14 +596,11 @@ quote(itemization(
|
||||
it() bf(RSYNC_USER_NAME): The accessing user's name (empty if no user).
|
||||
it() bf(RSYNC_PID): A unique number for this transfer.
|
||||
it() bf(RSYNC_REQUEST): (pre-xfer only) The module/path info specified
|
||||
by the user. Note that the user can specify multiple source files,
|
||||
so the request can be something like "mod/path1 mod/path2", etc.
|
||||
by the user (note that the user can specify multiple source files,
|
||||
so the request can be something like "mod/path1 mod/path2", etc.).
|
||||
it() bf(RSYNC_ARG#): (pre-xfer only) The pre-request arguments are set
|
||||
in these numbered values. RSYNC_ARG0 is always "rsyncd", followed by
|
||||
the options that were used in RSYNC_ARG1, and so on. There will be a
|
||||
value of "." indicating that the options are done and the path args
|
||||
are beginning -- these contain similar information to RSYNC_REQUEST,
|
||||
but with values separated and the module name stripped off.
|
||||
in these numbered values. RSYNC_ARG0 is always "rsyncd", and the last
|
||||
value contains a single period.
|
||||
it() bf(RSYNC_EXIT_STATUS): (post-xfer only) the server side's exit value.
|
||||
This will be 0 for a successful run, a positive value for an error that the
|
||||
server generated, or a -1 if rsync failed to exit properly. Note that an
|
||||
@@ -753,62 +615,6 @@ module's uid/gid setting) without any chroot restrictions.
|
||||
|
||||
enddit()
|
||||
|
||||
manpagesection(CONFIG DIRECTIVES)
|
||||
|
||||
There are currently two config directives available that allow a config file to
|
||||
incorporate the contents of other files: bf(&include) and bf(&merge). Both
|
||||
allow a reference to either a file or a directory. They differ in how
|
||||
segregated the file's contents are considered to be.
|
||||
|
||||
The bf(&include) directive treats each file as more distinct, with each one
|
||||
inheriting the defaults of the parent file, starting the parameter parsing
|
||||
as globals/defaults, and leaving the defaults unchanged for the parsing of
|
||||
the rest of the parent file.
|
||||
|
||||
The bf(&merge) directive, on the other hand, treats the file's contents as
|
||||
if it were simply inserted in place of the directive, and thus it can set
|
||||
parameters in a module started in another file, can affect the defaults for
|
||||
other files, etc.
|
||||
|
||||
When an bf(&include) or bf(&merge) directive refers to a directory, it will read
|
||||
in all the bf(*.conf) or bf(*.inc) files (respectively) that are contained inside
|
||||
that directory (without any
|
||||
recursive scanning), with the files sorted into alpha order. So, if you have a
|
||||
directory named "rsyncd.d" with the files "foo.conf", "bar.conf", and
|
||||
"baz.conf" inside it, this directive:
|
||||
|
||||
verb( &include /path/rsyncd.d )
|
||||
|
||||
would be the same as this set of directives:
|
||||
|
||||
verb( &include /path/rsyncd.d/bar.conf
|
||||
&include /path/rsyncd.d/baz.conf
|
||||
&include /path/rsyncd.d/foo.conf )
|
||||
|
||||
except that it adjusts as files are added and removed from the directory.
|
||||
|
||||
The advantage of the bf(&include) directive is that you can define one or more
|
||||
modules in a separate file without worrying about unintended side-effects
|
||||
between the self-contained module files.
|
||||
|
||||
The advantage of the bf(&merge) directive is that you can load config snippets
|
||||
that can be included into multiple module definitions, and you can also set
|
||||
global values that will affect connections (such as bf(motd file)), or globals
|
||||
that will affect other include files.
|
||||
|
||||
For example, this is a useful /etc/rsyncd.conf file:
|
||||
|
||||
verb( port = 873
|
||||
log file = /var/log/rsync.log
|
||||
pid file = /var/lock/rsync.lock
|
||||
|
||||
&merge /etc/rsyncd.d
|
||||
&include /etc/rsyncd.d )
|
||||
|
||||
This would merge any /etc/rsyncd.d/*.inc files (for global values that should
|
||||
stay in effect), and then include any /etc/rsyncd.d/*.conf files (defining
|
||||
modules without any global-value cross-talk).
|
||||
|
||||
manpagesection(AUTHENTICATION STRENGTH)
|
||||
|
||||
The authentication protocol used in rsync is a 128 bit MD4 based
|
||||
@@ -894,11 +700,11 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
|
||||
This man page is current for version 3.1.0 of rsync.
|
||||
This man page is current for version 3.0.8 of rsync.
|
||||
|
||||
manpagesection(CREDITS)
|
||||
|
||||
rsync is distributed under the GNU General Public License. See the file
|
||||
rsync is distributed under the GNU public license. See the file
|
||||
COPYING for details.
|
||||
|
||||
The primary ftp site for rsync is
|
||||
|
||||
15
runtests.sh
15
runtests.sh
@@ -129,10 +129,7 @@ RUNSHFLAGS='-e'
|
||||
export RUNSHFLAGS
|
||||
|
||||
# for Solaris
|
||||
if [ -d /usr/xpg4/bin ]; then
|
||||
PATH="/usr/xpg4/bin/:$PATH"
|
||||
export PATH
|
||||
fi
|
||||
[ -d /usr/xpg4/bin ] && PATH="/usr/xpg4/bin/:$PATH"
|
||||
|
||||
if [ "x$loglevel" != x ] && [ "$loglevel" -gt 8 ]; then
|
||||
if set -x; then
|
||||
@@ -232,9 +229,8 @@ echo " scratchbase=$scratchbase"
|
||||
[ -d "$scratchbase" ] || mkdir "$scratchbase"
|
||||
|
||||
suitedir="$srcdir/testsuite"
|
||||
TESTRUN_TIMEOUT=300
|
||||
|
||||
export scratchdir suitedir TESTRUN_TIMEOUT
|
||||
export scratchdir suitedir
|
||||
|
||||
prep_scratch() {
|
||||
[ -d "$scratchdir" ] && chmod -R u+rwX "$scratchdir" && rm -rf "$scratchdir"
|
||||
@@ -265,13 +261,8 @@ do
|
||||
|
||||
prep_scratch
|
||||
|
||||
case "$testscript" in
|
||||
*hardlinks*) TESTRUN_TIMEOUT=600 ;;
|
||||
*) TESTRUN_TIMEOUT=300 ;;
|
||||
esac
|
||||
|
||||
set +e
|
||||
"$TOOLDIR/"testrun $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1
|
||||
sh $RUNSHFLAGS "$testscript" >"$scratchdir/test.log" 2>&1
|
||||
result=$?
|
||||
set -e
|
||||
|
||||
|
||||
139
sender.c
139
sender.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int do_xfers;
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
@@ -32,22 +32,19 @@ extern int logfile_format_has_i;
|
||||
extern int csum_length;
|
||||
extern int append_mode;
|
||||
extern int io_error;
|
||||
extern int flist_eof;
|
||||
extern int allowed_lull;
|
||||
extern int preserve_xattrs;
|
||||
extern int protocol_version;
|
||||
extern int remove_source_files;
|
||||
extern int updating_basis_file;
|
||||
extern int make_backups;
|
||||
extern int do_progress;
|
||||
extern int inplace;
|
||||
extern int batch_fd;
|
||||
extern int write_batch;
|
||||
extern int file_old_total;
|
||||
extern struct stats stats;
|
||||
extern struct file_list *cur_flist, *first_flist, *dir_flist;
|
||||
|
||||
BOOL extra_flist_sending_enabled;
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
@@ -63,7 +60,7 @@ static struct sum_struct *receive_sums(int f)
|
||||
{
|
||||
struct sum_struct *s;
|
||||
int32 i;
|
||||
int lull_mod = protocol_version >= 31 ? 0 : allowed_lull * 5;
|
||||
int lull_mod = allowed_lull * 5;
|
||||
OFF_T offset = 0;
|
||||
|
||||
if (!(s = new(struct sum_struct)))
|
||||
@@ -73,9 +70,9 @@ static struct sum_struct *receive_sums(int f)
|
||||
|
||||
s->sums = NULL;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 3)) {
|
||||
rprintf(FINFO, "count=%s n=%ld rem=%ld\n",
|
||||
big_num(s->count), (long)s->blength, (long)s->remainder);
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO, "count=%.0f n=%ld rem=%ld\n",
|
||||
(double)s->count, (long)s->blength, (long)s->remainder);
|
||||
}
|
||||
|
||||
if (append_mode > 0) {
|
||||
@@ -104,13 +101,13 @@ static struct sum_struct *receive_sums(int f)
|
||||
s->sums[i].len = s->blength;
|
||||
offset += s->sums[i].len;
|
||||
|
||||
if (lull_mod && !(i % lull_mod))
|
||||
maybe_send_keepalive(time(NULL), True);
|
||||
if (allowed_lull && !(i % lull_mod))
|
||||
maybe_send_keepalive();
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 3)) {
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,
|
||||
"chunk[%d] len=%d offset=%s sum1=%08x\n",
|
||||
i, s->sums[i].len, big_num(s->sums[i].offset),
|
||||
"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
|
||||
i, s->sums[i].len, (double)s->sums[i].offset,
|
||||
s->sums[i].sum1);
|
||||
}
|
||||
}
|
||||
@@ -123,10 +120,8 @@ static struct sum_struct *receive_sums(int f)
|
||||
void successful_send(int ndx)
|
||||
{
|
||||
char fname[MAXPATHLEN];
|
||||
char *failed_op;
|
||||
struct file_struct *file;
|
||||
struct file_list *flist;
|
||||
STRUCT_STAT st;
|
||||
|
||||
if (!remove_source_files)
|
||||
return;
|
||||
@@ -137,31 +132,11 @@ void successful_send(int ndx)
|
||||
return;
|
||||
f_name(file, fname);
|
||||
|
||||
if (do_lstat(fname, &st) < 0) {
|
||||
failed_op = "re-lstat";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (st.st_size != F_LENGTH(file) || st.st_mtime != file->modtime
|
||||
#ifdef ST_MTIME_NSEC
|
||||
|| (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file))
|
||||
#endif
|
||||
) {
|
||||
rprintf(FERROR, "ERROR: Skipping sender remove for changed file: %s\n", fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (do_unlink(fname) < 0) {
|
||||
failed_op = "remove";
|
||||
failed:
|
||||
if (errno == ENOENT)
|
||||
rprintf(FINFO, "sender file already removed: %s\n", fname);
|
||||
else
|
||||
rsyserr(FERROR, errno, "sender failed to %s %s", failed_op, fname);
|
||||
} else {
|
||||
if (INFO_GTE(REMOVE, 1))
|
||||
if (do_unlink(fname) == 0) {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO, "sender removed %s\n", fname);
|
||||
}
|
||||
} else
|
||||
rsyserr(FERROR, errno, "sender failed to remove %s", fname);
|
||||
}
|
||||
|
||||
static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
|
||||
@@ -177,8 +152,7 @@ static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
|
||||
if (iflags & ITEM_XNAME_FOLLOWS)
|
||||
write_vstring(f_out, buf, len);
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
|
||||
&& (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
|
||||
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
|
||||
send_xattr_request(fname, file, f_out);
|
||||
#endif
|
||||
}
|
||||
@@ -195,51 +169,41 @@ void send_files(int f_in, int f_out)
|
||||
int iflags, xlen;
|
||||
struct file_struct *file;
|
||||
int phase = 0, max_phase = protocol_version >= 29 ? 2 : 1;
|
||||
struct stats initial_stats;
|
||||
int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i;
|
||||
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
|
||||
int f_xfer = write_batch < 0 ? batch_fd : f_out;
|
||||
int save_io_error = io_error;
|
||||
int ndx, j;
|
||||
|
||||
if (DEBUG_GTE(SEND, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "send_files starting\n");
|
||||
|
||||
while (1) {
|
||||
if (inc_recurse) {
|
||||
send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
|
||||
extra_flist_sending_enabled = !flist_eof;
|
||||
}
|
||||
if (inc_recurse)
|
||||
send_extra_file_list(f_out, FILECNT_LOOKAHEAD);
|
||||
|
||||
/* This call also sets cur_flist. */
|
||||
ndx = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type,
|
||||
ndx = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
|
||||
xname, &xlen);
|
||||
extra_flist_sending_enabled = False;
|
||||
|
||||
if (ndx == NDX_DONE) {
|
||||
if (!am_server && INFO_GTE(PROGRESS, 2) && cur_flist) {
|
||||
set_current_file_index(NULL, 0);
|
||||
end_progress(0);
|
||||
}
|
||||
if (inc_recurse && first_flist) {
|
||||
file_old_total -= first_flist->used;
|
||||
flist_free(first_flist);
|
||||
if (first_flist) {
|
||||
if (first_flist == cur_flist)
|
||||
file_old_total = cur_flist->used;
|
||||
write_ndx(f_out, NDX_DONE);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (++phase > max_phase)
|
||||
break;
|
||||
if (DEBUG_GTE(SEND, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "send_files phase=%d\n", phase);
|
||||
write_ndx(f_out, NDX_DONE);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inc_recurse)
|
||||
send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
|
||||
send_extra_file_list(f_out, FILECNT_LOOKAHEAD);
|
||||
|
||||
if (ndx - cur_flist->ndx_start >= 0)
|
||||
file = cur_flist->files[ndx - cur_flist->ndx_start];
|
||||
@@ -255,12 +219,11 @@ void send_files(int f_in, int f_out)
|
||||
continue;
|
||||
f_name(file, fname);
|
||||
|
||||
if (DEBUG_GTE(SEND, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "send_files(%d, %s%s%s)\n", ndx, path,slash,fname);
|
||||
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
|
||||
&& (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
|
||||
if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)
|
||||
recv_xattr_request(file, f_in);
|
||||
#endif
|
||||
|
||||
@@ -268,21 +231,6 @@ void send_files(int f_in, int f_out)
|
||||
maybe_log_item(file, iflags, itemizing, xname);
|
||||
write_ndx_and_attrs(f_out, ndx, iflags, fname, file,
|
||||
fnamecmp_type, xname, xlen);
|
||||
if (iflags & ITEM_IS_NEW) {
|
||||
stats.created_files++;
|
||||
if (S_ISREG(file->mode)) {
|
||||
/* Nothing further to count. */
|
||||
} else if (S_ISDIR(file->mode))
|
||||
stats.created_dirs++;
|
||||
#ifdef SUPPORT_LINKS
|
||||
else if (S_ISLNK(file->mode))
|
||||
stats.created_symlinks++;
|
||||
#endif
|
||||
else if (IS_DEVICE(file->mode))
|
||||
stats.created_devices++;
|
||||
else
|
||||
stats.created_specials++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (phase == 2) {
|
||||
@@ -306,28 +254,25 @@ void send_files(int f_in, int f_out)
|
||||
append_mode = -append_mode;
|
||||
csum_length = SHORT_SUM_LENGTH;
|
||||
}
|
||||
if (iflags & ITEM_IS_NEW)
|
||||
stats.created_files++;
|
||||
}
|
||||
|
||||
updating_basis_file = inplace && (protocol_version >= 29
|
||||
? fnamecmp_type == FNAMECMP_FNAME : make_backups <= 0);
|
||||
|
||||
if (!am_server && INFO_GTE(PROGRESS, 1))
|
||||
if (!am_server && do_progress)
|
||||
set_current_file_index(file, ndx);
|
||||
stats.xferred_files++;
|
||||
stats.num_transferred_files++;
|
||||
stats.total_transferred_size += F_LENGTH(file);
|
||||
|
||||
if (!log_before_transfer)
|
||||
remember_initial_stats();
|
||||
|
||||
if (!do_xfers) { /* log the transfer */
|
||||
log_item(FCLIENT, file, iflags, NULL);
|
||||
log_item(FCLIENT, file, &stats, iflags, NULL);
|
||||
write_ndx_and_attrs(f_out, ndx, iflags, fname, file,
|
||||
fnamecmp_type, xname, xlen);
|
||||
continue;
|
||||
}
|
||||
|
||||
initial_stats = stats;
|
||||
|
||||
if (!(s = receive_sums(f_in))) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
rprintf(FERROR_XFER, "receive_sums failed\n");
|
||||
@@ -361,7 +306,7 @@ void send_files(int f_in, int f_out)
|
||||
rsyserr(FERROR_XFER, errno, "fstat failed");
|
||||
free_sums(s);
|
||||
close(fd);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (st.st_size) {
|
||||
@@ -370,30 +315,30 @@ void send_files(int f_in, int f_out)
|
||||
} else
|
||||
mbuf = NULL;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2)) {
|
||||
rprintf(FINFO, "send_files mapped %s%s%s of size %s\n",
|
||||
path,slash,fname, big_num(st.st_size));
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "send_files mapped %s%s%s of size %.0f\n",
|
||||
path,slash,fname, (double)st.st_size);
|
||||
}
|
||||
|
||||
write_ndx_and_attrs(f_out, ndx, iflags, fname, file,
|
||||
fnamecmp_type, xname, xlen);
|
||||
write_sum_head(f_xfer, s);
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "calling match_sums %s%s%s\n", path,slash,fname);
|
||||
|
||||
if (log_before_transfer)
|
||||
log_item(FCLIENT, file, iflags, NULL);
|
||||
else if (!am_server && INFO_GTE(NAME, 1) && INFO_EQ(PROGRESS, 1))
|
||||
log_item(FCLIENT, file, &initial_stats, iflags, NULL);
|
||||
else if (!am_server && verbose && do_progress)
|
||||
rprintf(FCLIENT, "%s\n", fname);
|
||||
|
||||
set_compression(fname);
|
||||
|
||||
match_sums(f_xfer, s, mbuf, st.st_size);
|
||||
if (INFO_GTE(PROGRESS, 1))
|
||||
if (do_progress)
|
||||
end_progress(st.st_size);
|
||||
|
||||
log_item(log_code, file, iflags, NULL);
|
||||
log_item(log_code, file, &initial_stats, iflags, NULL);
|
||||
|
||||
if (mbuf) {
|
||||
j = unmap_file(mbuf);
|
||||
@@ -408,7 +353,7 @@ void send_files(int f_in, int f_out)
|
||||
|
||||
free_sums(s);
|
||||
|
||||
if (DEBUG_GTE(SEND, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "sender finished %s%s%s\n", path,slash,fname);
|
||||
|
||||
/* Flag that we actually sent this entry. */
|
||||
@@ -420,7 +365,7 @@ void send_files(int f_in, int f_out)
|
||||
if (io_error != save_io_error && protocol_version >= 30)
|
||||
send_msg_int(MSG_IO_ERROR, io_error);
|
||||
|
||||
if (DEBUG_GTE(SEND, 1))
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "send files finished\n");
|
||||
|
||||
match_report();
|
||||
|
||||
@@ -8,8 +8,5 @@
|
||||
ECHO_T="@ECHO_T@"
|
||||
ECHO_N="@ECHO_N@"
|
||||
ECHO_C="@ECHO_C@"
|
||||
HOST_OS="@host_os@"
|
||||
SHELL_PATH="@SHELL_PATH@"
|
||||
FAKEROOT_PATH="@FAKEROOT_PATH@"
|
||||
|
||||
export ECHO_T ECHO_N ECHO_C HOST_OS SHELL_PATH FAKEROOT_PATH
|
||||
export ECHO_T ECHO_N ECHO_C
|
||||
|
||||
37
socket.c
37
socket.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,13 +25,9 @@
|
||||
* emulate it using the KAME implementation. */
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
#ifdef HAVE_NETINET_IN_SYSTM_H
|
||||
#include "ifuncs.h"
|
||||
#include <netinet/in_systm.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IP_H
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
extern char *bind_address;
|
||||
@@ -229,7 +225,7 @@ int open_socket_out(char *host, int port, const char *bind_addr,
|
||||
}
|
||||
*cp++ = '\0';
|
||||
strlcpy(portbuf, cp, sizeof portbuf);
|
||||
if (DEBUG_GTE(CONNECT, 1)) {
|
||||
if (verbose >= 2) {
|
||||
rprintf(FINFO, "connection via http proxy %s port %s\n",
|
||||
h, portbuf);
|
||||
}
|
||||
@@ -301,29 +297,22 @@ int open_socket_out(char *host, int port, const char *bind_addr,
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
if (DEBUG_GTE(CONNECT, 2)) {
|
||||
char buf[2048];
|
||||
if ((error = getnameinfo(res->ai_addr, res->ai_addrlen, buf, sizeof buf, NULL, 0, NI_NUMERICHOST)) != 0)
|
||||
snprintf(buf, sizeof buf, "*getnameinfo failure: %s*", gai_strerror(error));
|
||||
rprintf(FINFO, "Connected to %s (%s)\n", h, buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
freeaddrinfo(res0);
|
||||
|
||||
if (s < 0 || DEBUG_GTE(CONNECT, 2)) {
|
||||
if (s < 0) {
|
||||
char buf[2048];
|
||||
for (res = res0, j = 0; res; res = res->ai_next, j++) {
|
||||
if (errnos[j] == 0)
|
||||
continue;
|
||||
if ((error = getnameinfo(res->ai_addr, res->ai_addrlen, buf, sizeof buf, NULL, 0, NI_NUMERICHOST)) != 0)
|
||||
snprintf(buf, sizeof buf, "*getnameinfo failure: %s*", gai_strerror(error));
|
||||
if (inet_ntop(res->ai_family, res->ai_addr->sa_data + 2, buf, sizeof buf) == NULL)
|
||||
strlcpy(buf, "*inet_ntop failed*", sizeof buf);
|
||||
rsyserr(FERROR, errnos[j], "failed to connect to %s (%s)", h, buf);
|
||||
}
|
||||
if (s < 0)
|
||||
s = -1;
|
||||
s = -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
free(errnos);
|
||||
|
||||
return s;
|
||||
@@ -381,7 +370,7 @@ int open_socket_out_wrapped(char *host, int port, const char *bind_addr,
|
||||
*t = '\0';
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(CONNECT, 1)) {
|
||||
if (verbose >= 2) {
|
||||
rprintf(FINFO, "%sopening tcp connection to %s port %d\n",
|
||||
prog ? "Using RSYNC_CONNECT_PROG instead of " : "",
|
||||
host, port);
|
||||
@@ -489,7 +478,7 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
|
||||
/* Only output the socket()/bind() messages if we were totally
|
||||
* unsuccessful, or if the daemon is being run with -vv. */
|
||||
for (s = 0; s < ecnt; s++) {
|
||||
if (!i || DEBUG_GTE(BIND, 1))
|
||||
if (!i || verbose > 1)
|
||||
rwrite(FLOG, errmsgs[s], strlen(errmsgs[s]), 0);
|
||||
free(errmsgs[s]);
|
||||
}
|
||||
@@ -557,7 +546,7 @@ void start_accept_loop(int port, int (*fn)(int, int))
|
||||
/* ready to listen */
|
||||
FD_ZERO(&deffds);
|
||||
for (i = 0, maxfd = -1; sp[i] >= 0; i++) {
|
||||
if (listen(sp[i], lp_listen_backlog()) < 0) {
|
||||
if (listen(sp[i], 5) < 0) {
|
||||
rsyserr(FERROR, errno, "listen() on socket failed");
|
||||
#ifdef INET6
|
||||
if (errno == EADDRINUSE && i > 0) {
|
||||
@@ -646,9 +635,7 @@ struct
|
||||
} socket_options[] = {
|
||||
{"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
|
||||
{"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
|
||||
#ifdef SO_BROADCAST
|
||||
{"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
|
||||
#endif
|
||||
#ifdef TCP_NODELAY
|
||||
{"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
|
||||
#endif
|
||||
@@ -831,7 +818,7 @@ static int sock_exec(const char *prog)
|
||||
rsyserr(FERROR, errno, "socketpair_tcp failed");
|
||||
return -1;
|
||||
}
|
||||
if (DEBUG_GTE(CMD, 1))
|
||||
if (verbose >= 2)
|
||||
rprintf(FINFO, "Running socket program: \"%s\"\n", prog);
|
||||
|
||||
pid = fork();
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This must be called as (note the trailing dot):
|
||||
#
|
||||
# stunnel-rsync HOSTNAME rsync --server --daemon .
|
||||
#
|
||||
# ... which is typically done via the rsync-ssl script, which results in something like this:
|
||||
#
|
||||
# rsync --rsh=stunnel-rsync -aiv HOSTNAME::module [ARGS]
|
||||
#
|
||||
# This SSL setup based on the files by: http://dozzie.jarowit.net/trac/wiki/RsyncSSL
|
||||
# Note that this requires at least version 4.x of stunnel.
|
||||
|
||||
# The current environment can override using the RSYNC_SSL_* values:
|
||||
if [ x"$RSYNC_SSL_CERT" = x ]; then
|
||||
cert=""
|
||||
else
|
||||
cert="cert = $RSYNC_SSL_CERT"
|
||||
fi
|
||||
if [ x"$RSYNC_SSL_CA_CERT" ]; then
|
||||
cafile=""
|
||||
verify=0
|
||||
else
|
||||
cafile="CAfile = $RSYNC_SSL_CA_CERT"
|
||||
verify=3
|
||||
fi
|
||||
port=${RSYNC_SSL_PORT:-874}
|
||||
|
||||
# If the user specified USER@HOSTNAME::module, then rsync passes us
|
||||
# the -l USER option too, so we must be prepared to ignore it.
|
||||
if [ x"$1" = x"-l" ]; then
|
||||
shift 2
|
||||
fi
|
||||
|
||||
hostname=$1
|
||||
shift
|
||||
|
||||
if [ x"$hostname" = x -o x"$1" != x"rsync" -o x"$2" != x"--server" -o x"$3" != x"--daemon" ]; then
|
||||
echo "Usage: stunnel-rsync HOSTNAME rsync --server --daemon ." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# devzero@web.de came up with this no-tmpfile calling syntax:
|
||||
@stunnel4@ -fd 10 11<&0 <<EOF 10<&0 0<&11 11<&-
|
||||
foreground = yes
|
||||
debug = crit
|
||||
connect = $hostname:$port
|
||||
client = yes
|
||||
TIMEOUTclose = 0
|
||||
verify = $verify
|
||||
$cert
|
||||
$cafile
|
||||
EOF
|
||||
@@ -1,30 +0,0 @@
|
||||
# This config for stunnel will start up rsync for an incoming ssl connection.
|
||||
foreground = no
|
||||
#output = /var/log/stunnel-rsyncd.log
|
||||
pid = /var/run/stunnel-rsyncd.pid
|
||||
socket = l:TCP_NODELAY=1
|
||||
socket = r:TCP_NODELAY=1
|
||||
compression = rle
|
||||
# This must be root for rsync to use chroot -- rsync will drop permissions:
|
||||
setuid = root
|
||||
setgid = root
|
||||
|
||||
[rsync]
|
||||
accept = 874
|
||||
# You can set the cert to a combo *.pem file and omit the key, if you like.
|
||||
cert = /etc/rsync-ssl/certs/server.crt
|
||||
key = /etc/rsync-ssl/certs/server.key
|
||||
client = no
|
||||
|
||||
# To allow anyone to try an ssl connection, use this:
|
||||
verify = 0
|
||||
CAfile = /etc/ssl/ca-bundle.pem
|
||||
|
||||
# To allow only cert-authorized clients, use something like this instead of the above:
|
||||
#verify = 3
|
||||
#CAfile = /etc/rsync-ssl/certs/allowed-clients.cert.pem
|
||||
|
||||
exec = @bindir@/rsync
|
||||
# You can either share the same config as a normal daemon, or specify a separate config:
|
||||
execargs = rsync --server --daemon .
|
||||
#execargs = rsync --server --daemon --config=/etc/rsync-ssl/rsyncd.conf .
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/bin/perl -w
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# Sets mtime and atime of files to the latest commit time in git.
|
||||
#
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# instant-rsyncd lets you quickly set up and start a simple, unprivileged rsync
|
||||
# daemon with a single module in the current directory. I've found it
|
||||
# invaluable for quick testing, and I use it when writing a list of commands
|
||||
# that people can paste into a terminal to reproduce a daemon-related bug.
|
||||
# Sysadmins deploying an rsync daemon for the first time may find it helpful as
|
||||
# a starting point.
|
||||
#
|
||||
# Usage: instant-rsyncd MODULE PORT RSYNCD-USERNAME [RSYNC-PATH]
|
||||
# The script asks for the rsyncd user's password twice on stdin, once to set it
|
||||
# and once to log in to test the daemon.
|
||||
# -- Matt McCutchen <matt@mattmccutchen.net>
|
||||
|
||||
set -e
|
||||
|
||||
dir="$(pwd)"
|
||||
|
||||
echo
|
||||
echo "This will setup an rsync daemon in $dir"
|
||||
|
||||
if [ $# = 0 ]; then
|
||||
IFS='' read -p 'Module name to create (or return to exit): ' module
|
||||
[ ! "$module" ] && exit
|
||||
else
|
||||
module="$1"
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ $# = 0 ]; then
|
||||
IFS='' read -p 'Port number the daemon should listen on [873]: ' port
|
||||
else
|
||||
port="$1"
|
||||
shift
|
||||
fi
|
||||
[ "$port" ] || port=873
|
||||
|
||||
if [ $# = 0 ]; then
|
||||
IFS='' read -p 'User name for authentication (empty for none): ' user
|
||||
else
|
||||
user="$1"
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ "$user" ]; then
|
||||
IFS='' read -s -p 'Desired password: ' password
|
||||
echo
|
||||
fi
|
||||
|
||||
rsync="$1"
|
||||
[ "$rsync" ] || rsync=rsync
|
||||
|
||||
moduledir="${dir%/}/$module"
|
||||
|
||||
mkdir "$module"
|
||||
|
||||
cat >rsyncd.conf <<EOF
|
||||
log file = rsyncd.log
|
||||
pid file = rsyncd.pid
|
||||
port = $port
|
||||
use chroot = no
|
||||
|
||||
[$module]
|
||||
path = $module
|
||||
read only = false
|
||||
EOF
|
||||
|
||||
if [ "$user" ]; then
|
||||
cat >>rsyncd.conf <<-EOF
|
||||
auth users = $user
|
||||
secrets file = $module.secrets
|
||||
EOF
|
||||
touch "$module".secrets
|
||||
chmod go-rwx "$module".secrets
|
||||
echo "$user:$password" >"$module".secrets
|
||||
user="$user@"
|
||||
fi
|
||||
|
||||
cat >start <<EOF
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd \`dirname \$0\`
|
||||
! [ -e rsyncd.pid ] || {
|
||||
echo "Is the daemon already running? If not, delete rsyncd.pid."
|
||||
exit 1
|
||||
}
|
||||
$rsync --daemon --config=rsyncd.conf
|
||||
EOF
|
||||
chmod +x start
|
||||
|
||||
cat >stop <<"EOF"
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd `dirname $0`
|
||||
! [ -e rsyncd.pid ] || kill -s SIGTERM $(< rsyncd.pid)
|
||||
EOF
|
||||
chmod +x stop
|
||||
|
||||
path="rsync://$user$(hostname):$port/$module/"
|
||||
|
||||
if ./start; then
|
||||
sleep .2
|
||||
echo
|
||||
echo "I ran the start command for the daemon. The log file rsyncd.log says:"
|
||||
echo
|
||||
cat rsyncd.log
|
||||
echo
|
||||
echo "You can start and stop it with ./start and ./stop respectively."
|
||||
echo "You can customize the configuration file rsyncd.conf."
|
||||
echo
|
||||
echo "Give rsync the following path to access the module:"
|
||||
echo " $path"
|
||||
echo
|
||||
if [ "$user" ]; then
|
||||
echo "Let's test the daemon now. Enter the password you chose at the prompt."
|
||||
else
|
||||
echo "Let's test the daemon now."
|
||||
fi
|
||||
echo
|
||||
echo '$' $rsync --list-only "$path"
|
||||
$rsync --list-only "$path"
|
||||
echo
|
||||
echo "You should see an empty folder; it's $moduledir."
|
||||
else
|
||||
echo "Something went wrong. Do you see an error message?"
|
||||
fi
|
||||
100
support/lsh
100
support/lsh
@@ -1,81 +1,35 @@
|
||||
#!/usr/bin/perl
|
||||
#!/bin/sh
|
||||
# This script can be used as a "remote shell" command that is only
|
||||
# capable of pretending to connect to "localhost". This is useful
|
||||
# for testing or for running a local copy where the sender and the
|
||||
# receiver needs to use different options (e.g. --fake-super). If
|
||||
# we get -l USER, we try to become the USER, either directly (must
|
||||
# be root) or by using "sudo -H -u USER" (requires --sudo option).
|
||||
# we get a -l USER option, we try to use "sudo -u USER" to run the
|
||||
# command.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use English '-no_match_vars';
|
||||
user=''
|
||||
prefix=''
|
||||
do_cd=y # Default path is user's home dir, just like ssh.
|
||||
|
||||
&Getopt::Long::Configure('bundling');
|
||||
&Getopt::Long::Configure('require_order');
|
||||
GetOptions(
|
||||
'l=s' => \( my $login_name ),
|
||||
'1|2|4|6|A|a|C|f|g|k|M|N|n|q|s|T|t|V|v|X|x|Y' => sub { }, # Ignore
|
||||
'b|c|D|e|F|i|L|m|O|o|p|R|S|w=s' => sub { }, # Ignore
|
||||
'no-cd' => \( my $no_chdir ),
|
||||
'sudo' => \( my $use_sudo ),
|
||||
) or &usage;
|
||||
&usage unless @ARGV > 1;
|
||||
while : ; do
|
||||
case "$1" in
|
||||
-l) user="$2"; shift; shift ;;
|
||||
-l*) user=`echo "$1" | sed 's/^-l//'`; shift ;;
|
||||
--no-cd) do_cd=n; shift ;;
|
||||
-*) shift ;;
|
||||
localhost) shift; break ;;
|
||||
*) echo "lsh: unable to connect to host $1" 1>&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
my $host = shift;
|
||||
if ($host =~ s/^([^@]+)\@//) {
|
||||
$login_name = $1;
|
||||
}
|
||||
if ($host ne 'localhost') {
|
||||
die "lsh: unable to connect to host $host\n";
|
||||
}
|
||||
if [ "$user" ]; then
|
||||
prefix="sudo -H -u '$user'"
|
||||
if [ $do_cd = y ]; then
|
||||
home=`perl -e "print((getpwnam('$user'))[7])"`
|
||||
# Yeah, this may fail, but attempts to get sudo to cd are harder.
|
||||
cd $home
|
||||
fi
|
||||
elif [ $do_cd = y ]; then
|
||||
cd
|
||||
fi
|
||||
|
||||
my ($home_dir, @cmd);
|
||||
if ($login_name) {
|
||||
my ($uid, $gid);
|
||||
if ($login_name =~ /\D/) {
|
||||
$uid = getpwnam($login_name);
|
||||
die "Unknown user: $login_name\n" unless defined $uid;
|
||||
} else {
|
||||
$uid = $login_name;
|
||||
}
|
||||
($login_name, $gid, $home_dir) = (getpwuid($uid))[0,3,7];
|
||||
if ($use_sudo) {
|
||||
unshift @ARGV, "cd '$home_dir' &&" unless $no_chdir;
|
||||
unshift @cmd, qw( sudo -H -u ), $login_name;
|
||||
$no_chdir = 1;
|
||||
} else {
|
||||
my $groups = "$gid $gid";
|
||||
while (my ($grgid, $grmembers) = (getgrent)[2,3]) {
|
||||
if ($grgid != $gid && $grmembers =~ /(^|\s)\Q$login_name\E(\s|$)/o) {
|
||||
$groups .= " $grgid";
|
||||
}
|
||||
}
|
||||
|
||||
my ($ruid, $euid) = ($UID, $EUID);
|
||||
$GID = $EGID = $groups;
|
||||
$UID = $EUID = $uid;
|
||||
die "Cannot set ruid: $! (use --sudo?)\n" if $UID == $ruid && $ruid != $uid;
|
||||
die "Cannot set euid: $! (use --sudo?)\n" if $EUID == $euid && $euid != $uid;
|
||||
|
||||
$ENV{USER} = $ENV{USERNAME} = $login_name;
|
||||
$ENV{HOME} = $home_dir;
|
||||
}
|
||||
} else {
|
||||
$home_dir = (getpwuid($UID))[7];
|
||||
}
|
||||
|
||||
unless ($no_chdir) {
|
||||
chdir $home_dir or die "Unable to chdir to $home_dir: $!\n";
|
||||
}
|
||||
|
||||
push @cmd, '/bin/sh', '-c', "@ARGV";
|
||||
exec @cmd;
|
||||
die "Failed to exec: $!\n";
|
||||
|
||||
sub usage
|
||||
{
|
||||
die <<EOT;
|
||||
Usage: lsh [-l user] [--sudo] [--no-cd] localhost COMMAND [...]
|
||||
EOT
|
||||
}
|
||||
eval $prefix "${@}"
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/bin/sh
|
||||
# This script can be used as a "remote shell" command that is only
|
||||
# capable of pretending to connect to "localhost". This is useful
|
||||
# for testing or for running a local copy where the sender and the
|
||||
# receiver needs to use different options (e.g. --fake-super). If
|
||||
# we get a -l USER option, we try to use "sudo -u USER" to run the
|
||||
# command.
|
||||
|
||||
user=''
|
||||
do_cd=y # Default path is user's home dir, just like ssh.
|
||||
|
||||
while : ; do
|
||||
case "$1" in
|
||||
-l) user="$2"; shift; shift ;;
|
||||
-l*) user=`echo "$1" | sed 's/^-l//'`; shift ;;
|
||||
--no-cd) do_cd=n; shift ;;
|
||||
-*) shift ;;
|
||||
localhost) shift; break ;;
|
||||
*) echo "lsh: unable to connect to host $1" 1>&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$user" ]; then
|
||||
prefix=''
|
||||
if [ $do_cd = y ]; then
|
||||
home=`perl -e "print((getpwnam('$user'))[7])"`
|
||||
prefix="cd '$home' &&"
|
||||
fi
|
||||
sudo -H -u "$user" sh -c "$prefix $*"
|
||||
else
|
||||
if [ $do_cd = y ]; then
|
||||
cd || exit 1
|
||||
fi
|
||||
eval "${@}"
|
||||
fi
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# This helper script makes it easy to use a passwd or group file to map
|
||||
# values in a LOCAL transfer. For instance, if you mount a backup that
|
||||
# does not have the same passwd setup as the local machine, you can do
|
||||
# a copy FROM the backup area as follows and get the differing ID values
|
||||
# mapped just like a remote transfer FROM the backed-up machine would do:
|
||||
#
|
||||
# rsync -av --usermap=`mapfrom /mnt/backup/etc/passwd` \
|
||||
# --groupmap=`mapfrom /mnt/backup/etc/group` \
|
||||
# /mnt/backup/some/src/ /some/dest/
|
||||
|
||||
while (<>) {
|
||||
push @_, "$2:$1" if /^(\w+):[^:]+:(\d+)/;
|
||||
}
|
||||
print join(',', @_), "\n";
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# This helper script makes it easy to use a passwd or group file to map
|
||||
# values in a LOCAL transfer. For instance, if you mount a backup that
|
||||
# does not have the same passwd setup as the local machine, you can do
|
||||
# a copy TO the backup area as follows and get the differing ID values
|
||||
# mapped just like a remote transfer TO the backed-up machine would do:
|
||||
#
|
||||
# rsync -av --usermap=`mapto /mnt/backup/etc/passwd` \
|
||||
# --groupmap=`mapto /mnt/backup/etc/group` \
|
||||
# /some/src/ /mnt/backup/some/dest/
|
||||
|
||||
while (<>) {
|
||||
push @_, "$1:$2" if /^(\w+):[^:]+:(\d+)/;
|
||||
}
|
||||
print join(',', @_), "\n";
|
||||
@@ -18,7 +18,7 @@
|
||||
# easily adapted to read /etc/mtab or similar.
|
||||
#
|
||||
# ADDENDUM: The addition of the --filter option (which has support for
|
||||
# absolute-anchored excludes) can make this script unneeded in some
|
||||
# absolute-anchored excludes) can make this screen unneeded in some
|
||||
# scenarios. If you don't need delete protection on the receiving side
|
||||
# (or if the destination path is identical to the source path), then you
|
||||
# can exclude some absolute paths from the transfer based on the mount
|
||||
|
||||
@@ -74,18 +74,15 @@ our %long_opt = (
|
||||
'delete-delay' => 0,
|
||||
'delete-during' => 0,
|
||||
'delete-excluded' => 0,
|
||||
'delete-missing-args' => 0,
|
||||
'existing' => 0,
|
||||
'fake-super' => 0,
|
||||
'files-from' => 3,
|
||||
'force' => 0,
|
||||
'from0' => 0,
|
||||
'fuzzy' => 0,
|
||||
'groupmap' => 1,
|
||||
'iconv' => 1,
|
||||
'ignore-errors' => 0,
|
||||
'ignore-existing' => 0,
|
||||
'ignore-missing-args' => 0,
|
||||
'inplace' => 0,
|
||||
'link-dest' => 2,
|
||||
'list-only' => 0,
|
||||
@@ -117,7 +114,6 @@ our %long_opt = (
|
||||
'temp-dir' => 2,
|
||||
'timeout' => 1,
|
||||
'use-qsort' => 0,
|
||||
'usermap' => 1,
|
||||
);
|
||||
|
||||
### END of options data produced by the cull_options script. ###
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
# This script can be used as an rsync command-line filter that strips a single
|
||||
# trailing slash from each arg. That treats "src/" the same as "src", thus
|
||||
# you need to use "src/." or "src//" for just the contents of the "src" dir.
|
||||
# (Note that command-line dir-excludes would need to use "excl//" too.)
|
||||
#
|
||||
# To use this, name it something like "rs", put it somewhere in your path, and
|
||||
# then use "rs" in place of "rsync" when you are typing your copy commands.
|
||||
args=()
|
||||
for arg in "${@}"; do
|
||||
if [[ "$arg" == / ]]; then
|
||||
args=("${args[@]}" /)
|
||||
else
|
||||
args=("${args[@]}" "${arg%/}")
|
||||
fi
|
||||
done
|
||||
exec /usr/bin/rsync "${args[@]}"
|
||||
121
syscall.c
121
syscall.c
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -29,13 +29,8 @@
|
||||
#include <sys/attr.h>
|
||||
#endif
|
||||
|
||||
#if defined HAVE_SYS_FALLOCATE && !defined HAVE_FALLOCATE
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
extern int dry_run;
|
||||
extern int am_root;
|
||||
extern int am_sender;
|
||||
extern int read_only;
|
||||
extern int list_only;
|
||||
extern int preserve_perms;
|
||||
@@ -58,55 +53,13 @@ int do_unlink(const char *fname)
|
||||
return unlink(fname);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
int do_symlink(const char *lnk, const char *fname)
|
||||
int do_symlink(const char *fname1, const char *fname2)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
|
||||
#if defined NO_SYMLINK_XATTRS || defined NO_SYMLINK_USER_XATTRS
|
||||
/* For --fake-super, we create a normal file with mode 0600
|
||||
* and write the lnk into it. */
|
||||
if (am_root < 0) {
|
||||
int ok, len = strlen(lnk);
|
||||
int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
ok = write(fd, lnk, len) == len;
|
||||
if (close(fd) < 0)
|
||||
ok = 0;
|
||||
return ok ? 0 : -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return symlink(lnk, fname);
|
||||
return symlink(fname1, fname2);
|
||||
}
|
||||
|
||||
#if defined NO_SYMLINK_XATTRS || defined NO_SYMLINK_USER_XATTRS
|
||||
ssize_t do_readlink(const char *path, char *buf, size_t bufsiz)
|
||||
{
|
||||
/* For --fake-super, we read the link from the file. */
|
||||
if (am_root < 0) {
|
||||
int fd = do_open_nofollow(path, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
int len = read(fd, buf, bufsiz);
|
||||
close(fd);
|
||||
return len;
|
||||
}
|
||||
if (errno != ELOOP)
|
||||
return -1;
|
||||
/* A real symlink needs to be turned into a fake one on the receiving
|
||||
* side, so tell the generator that the link has no length. */
|
||||
if (!am_sender)
|
||||
return 0;
|
||||
/* Otherwise fall through and let the sender report the real length. */
|
||||
}
|
||||
|
||||
return readlink(path, buf, bufsiz);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINK
|
||||
int do_link(const char *fname1, const char *fname2)
|
||||
{
|
||||
@@ -421,71 +374,3 @@ int do_utime(const char *fname, time_t modtime, UNUSED(uint32 mod_nsec))
|
||||
#else
|
||||
#error Need utimes or utime function.
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_PREALLOCATION
|
||||
int do_fallocate(int fd, OFF_T offset, OFF_T length)
|
||||
{
|
||||
#ifdef FALLOC_FL_KEEP_SIZE
|
||||
#define DO_FALLOC_OPTIONS FALLOC_FL_KEEP_SIZE
|
||||
#else
|
||||
#define DO_FALLOC_OPTIONS 0
|
||||
#endif
|
||||
RETURN_ERROR_IF(dry_run, 0);
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
#if defined HAVE_FALLOCATE
|
||||
return fallocate(fd, DO_FALLOC_OPTIONS, offset, length);
|
||||
#elif defined HAVE_SYS_FALLOCATE
|
||||
return syscall(SYS_fallocate, fd, DO_FALLOC_OPTIONS, (loff_t)offset, (loff_t)length);
|
||||
#elif defined HAVE_EFFICIENT_POSIX_FALLOCATE
|
||||
return posix_fallocate(fd, offset, length);
|
||||
#else
|
||||
#error Coding error in SUPPORT_PREALLOCATION logic.
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int do_open_nofollow(const char *pathname, int flags)
|
||||
{
|
||||
#ifndef O_NOFOLLOW
|
||||
STRUCT_STAT f_st, l_st;
|
||||
#endif
|
||||
int fd;
|
||||
|
||||
if (flags != O_RDONLY) {
|
||||
RETURN_ERROR_IF(dry_run, 0);
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
#ifndef O_NOFOLLOW
|
||||
/* This function doesn't support write attempts w/o O_NOFOLLOW. */
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef O_NOFOLLOW
|
||||
fd = open(pathname, flags|O_NOFOLLOW);
|
||||
#else
|
||||
if (do_lstat(pathname, &l_st) < 0)
|
||||
return -1;
|
||||
if (S_ISLNK(l_st.st_mode)) {
|
||||
errno = ELOOP;
|
||||
return -1;
|
||||
}
|
||||
if ((fd = open(pathname, flags)) < 0)
|
||||
return fd;
|
||||
if (do_fstat(fd, &f_st) < 0) {
|
||||
close_and_return_error:
|
||||
{
|
||||
int save_errno = errno;
|
||||
close(fd);
|
||||
errno = save_errno;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (l_st.st_dev != f_st.st_dev || l_st.st_ino != f_st.st_ino) {
|
||||
errno = EINVAL;
|
||||
goto close_and_return_error;
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
23
t_stub.c
23
t_stub.c
@@ -3,7 +3,7 @@
|
||||
* functions, so that module test harnesses can run standalone.
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,18 +22,16 @@
|
||||
#include "rsync.h"
|
||||
|
||||
int modify_window = 0;
|
||||
int preallocate_files = 0;
|
||||
int protect_args = 0;
|
||||
int module_id = -1;
|
||||
int checksum_len = 0;
|
||||
int relative_paths = 0;
|
||||
int human_readable = 0;
|
||||
int module_dirlen = 0;
|
||||
int preserve_acls = 0;
|
||||
int preserve_times = 0;
|
||||
int preserve_xattrs = 0;
|
||||
mode_t orig_umask = 002;
|
||||
char *partial_dir;
|
||||
char *module_dir;
|
||||
filter_rule_list daemon_filter_list;
|
||||
struct filter_list_struct daemon_filter_list;
|
||||
|
||||
void rprintf(UNUSED(enum logcode code), const char *format, ...)
|
||||
{
|
||||
@@ -60,7 +58,7 @@ filter_rule_list daemon_filter_list;
|
||||
exit(code);
|
||||
}
|
||||
|
||||
int check_filter(UNUSED(filter_rule_list *listp), UNUSED(enum logcode code),
|
||||
int check_filter(UNUSED(struct filter_list_struct *listp), UNUSED(enum logcode code),
|
||||
UNUSED(const char *name), UNUSED(int name_is_dir))
|
||||
{
|
||||
/* This function doesn't really get called in this test context, so
|
||||
@@ -68,19 +66,14 @@ filter_rule_list daemon_filter_list;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest))
|
||||
int make_bak_dir(UNUSED(const char *fullpath))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void free_xattr(UNUSED(stat_x *sxp))
|
||||
int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void free_acl(UNUSED(stat_x *sxp))
|
||||
{
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *lp_name(UNUSED(int mod))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Test harness for unsafe_symlink(). Not linked into rsync itself.
|
||||
*
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,13 +25,11 @@
|
||||
|
||||
int dry_run = 0;
|
||||
int am_root = 0;
|
||||
int am_sender = 1;
|
||||
int read_only = 0;
|
||||
int list_only = 0;
|
||||
int human_readable = 0;
|
||||
int verbose = 0;
|
||||
int preserve_perms = 0;
|
||||
int preserve_executability = 0;
|
||||
short info_levels[COUNT_INFO], debug_levels[COUNT_DEBUG];
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
|
||||
61
testrun.c
61
testrun.c
@@ -1,61 +0,0 @@
|
||||
/* Run a testsuite script with a timeout. */
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#define DEFAULT_TIMEOUT_SECS (5*60)
|
||||
#define TIMEOUT_ENV "TESTRUN_TIMEOUT"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
char *timeout_env;
|
||||
int status, timeout_secs, slept = 0;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: testrun [SHELL_OPTIONS] TESTSUITE_SCRIPT [ARGS]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((timeout_env = getenv(TIMEOUT_ENV)) != NULL)
|
||||
timeout_secs = atoi(timeout_env);
|
||||
else
|
||||
timeout_secs = DEFAULT_TIMEOUT_SECS;
|
||||
|
||||
if ((pid = fork()) < 0) {
|
||||
fprintf(stderr, "TESTRUN ERROR: fork failed: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
argv[0] = "sh";
|
||||
execvp(argv[0], argv);
|
||||
fprintf(stderr, "TESTRUN ERROR: failed to exec %s: %s\n", argv[0], strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int ret = waitpid(pid, &status, WNOHANG);
|
||||
if (ret > 0)
|
||||
break;
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
fprintf(stderr, "TESTRUN ERROR: waitpid failed: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (slept++ > timeout_secs) {
|
||||
fprintf(stderr, "TESTRUN TIMEOUT: test took over %d seconds.\n", timeout_secs);
|
||||
if (kill(pid, SIGTERM) < 0)
|
||||
fprintf(stderr, "TESTRUN ERROR: failed to kill pid %d: %s\n", (int)pid, strerror(errno));
|
||||
else
|
||||
fprintf(stderr, "TESTRUN INFO: killed pid %d\n", (int)pid);
|
||||
exit(1);
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
if (!WIFEXITED(status))
|
||||
exit(255);
|
||||
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
@@ -1,14 +1,5 @@
|
||||
#! /bin/sh
|
||||
|
||||
test_fail() {
|
||||
echo "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo $0 running
|
||||
|
||||
$RSYNC --version || test_fail '--version output failed'
|
||||
|
||||
$RSYNC --info=help || test_fail '--info=help output failed'
|
||||
|
||||
$RSYNC --debug=help || test_fail '--debug=help output failed'
|
||||
$RSYNC --version || exit 1
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# Test that rsync handles basic ACL preservation.
|
||||
|
||||
. $suitedir/rsync.fns
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
$RSYNC --version | grep ", ACLs" >/dev/null || test_skipped "Rsync is configured without ACL support"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
bakdir="$tmpdir/bak"
|
||||
|
||||
makepath "$fromdir/deep" "$bakdir/dname"
|
||||
makepath "$fromdir/deep" "$bakdir"
|
||||
name1="$fromdir/deep/name1"
|
||||
name2="$fromdir/deep/name2"
|
||||
|
||||
@@ -20,13 +20,13 @@ outfile="$scratchdir/rsync.out"
|
||||
cat "$srcdir"/[gr]*.[ch] > "$name1"
|
||||
cat "$srcdir"/[et]*.[ch] > "$name2"
|
||||
|
||||
checkit "$RSYNC -ai --info=backup '$fromdir/' '$todir/'" "$fromdir" "$todir"
|
||||
checkit "$RSYNC -avv '$fromdir/' '$todir/'" "$fromdir" "$todir"
|
||||
|
||||
checkit "$RSYNC -ai --info=backup '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
|
||||
checkit "$RSYNC -avv '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
|
||||
cat "$srcdir"/[fgpr]*.[ch] > "$name1"
|
||||
cat "$srcdir"/[etw]*.[ch] > "$name2"
|
||||
|
||||
$RSYNC -ai --info=backup --no-whole-file --backup "$fromdir/" "$todir/" \
|
||||
$RSYNC -avv --no-whole-file --backup "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
for fn in deep/name1 deep/name2; do
|
||||
grep "backed up $fn to $fn~" "$outfile" >/dev/null || test_fail "no backup message output for $fn"
|
||||
@@ -38,7 +38,7 @@ done
|
||||
echo deleted-file >"$todir/dname"
|
||||
cp_touch "$todir/dname" "$chkdir"
|
||||
|
||||
checkit "$RSYNC -ai --info=backup --no-whole-file --delete-delay \
|
||||
checkit "$RSYNC -avv --no-whole-file --delete-delay \
|
||||
--backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \
|
||||
| tee "$outfile"
|
||||
|
||||
@@ -48,11 +48,11 @@ done
|
||||
diff -r $diffopt "$chkdir" "$bakdir" || test_fail "backup dir contents are bogus"
|
||||
rm "$bakdir/dname"
|
||||
|
||||
checkit "$RSYNC -ai --info=backup --del '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
|
||||
checkit "$RSYNC -avv --del '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
|
||||
cat "$srcdir"/[efgr]*.[ch] > "$name1"
|
||||
cat "$srcdir"/[ew]*.[ch] > "$name2"
|
||||
|
||||
checkit "$RSYNC -ai --info=backup --inplace --no-whole-file --backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \
|
||||
checkit "$RSYNC -avv --inplace --no-whole-file --backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \
|
||||
| tee "$outfile"
|
||||
|
||||
for fn in deep/name1 deep/name2; do
|
||||
@@ -60,7 +60,7 @@ for fn in deep/name1 deep/name2; do
|
||||
done
|
||||
diff -r $diffopt "$chkdir" "$bakdir" || test_fail "backup dir contents are bogus"
|
||||
|
||||
checkit "$RSYNC -ai --info=backup --inplace --no-whole-file '$fromdir/' '$bakdir/'" "$fromdir" "$bakdir"
|
||||
checkit "$RSYNC -avv --inplace --no-whole-file '$fromdir/' '$bakdir/'" "$fromdir" "$bakdir"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
# Test that the --chmod option functions correctly.
|
||||
|
||||
. $suitedir/rsync.fns
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
# Build some files
|
||||
|
||||
|
||||
@@ -18,25 +18,14 @@ case $0 in
|
||||
$RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests"
|
||||
RSYNC="$RSYNC --fake-super"
|
||||
TLS_ARGS="$TLS_ARGS --fake-super"
|
||||
case "$HOST_OS" in
|
||||
darwin*)
|
||||
case "`xattr 2>&1`" in
|
||||
*--list:*)
|
||||
chown() {
|
||||
own=$1
|
||||
shift
|
||||
xattr -s 'rsync.%stat' "100644 0,0 $own" "${@}"
|
||||
}
|
||||
;;
|
||||
solaris*)
|
||||
chown() {
|
||||
own=$1
|
||||
shift
|
||||
for fn in "${@}"; do
|
||||
runat "$fn" "$SHELL_PATH" <<EOF
|
||||
echo "100644 0,0 $own" > rsync.%stat
|
||||
EOF
|
||||
done
|
||||
}
|
||||
;;
|
||||
*)
|
||||
chown() {
|
||||
own=$1
|
||||
@@ -51,9 +40,9 @@ EOF
|
||||
case `get_testuid` in
|
||||
'') ;; # If "id" failed, try to continue...
|
||||
0) ;;
|
||||
*) if [ -e "$FAKEROOT_PATH" ]; then
|
||||
*) if [ -f /usr/bin/fakeroot ]; then
|
||||
echo "Let's try re-running the script under fakeroot..."
|
||||
exec "$FAKEROOT_PATH" "$SHELL_PATH" "$0"
|
||||
exec /usr/bin/fakeroot /bin/sh "$0"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
chkfile="$scratchdir/rsync.chk"
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
SSH="src/support/lsh.sh --no-cd"
|
||||
SSH="src/support/lsh --no-cd"
|
||||
FILE_REPL='s/^\([^d][^ ]*\) *\(..........[0-9]\) /\1 \2 /'
|
||||
DIR_REPL='s/^\(d[^ ]*\) *[0-9][.,0-9]* /\1 DIR /'
|
||||
DIR_REPL='s/^\(d[^ ]*\) *[0-9][0-9]* /\1 DIR /'
|
||||
LS_REPL='s;[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9];####/##/## ##:##:##;'
|
||||
|
||||
build_rsyncd_conf
|
||||
@@ -50,22 +50,19 @@ case `get_testuid` in
|
||||
;;
|
||||
esac
|
||||
|
||||
$RSYNC -ve "$SSH" --rsync-path="$RSYNC$confopt" localhost::
|
||||
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
$RSYNC -v localhost:: \
|
||||
| tee "$outfile"
|
||||
# These have a space-padded 15-char name, then a tab, then a comment.
|
||||
sed 's/NOCOMMENT//' <<EOT >"$chkfile"
|
||||
test-from r/o
|
||||
test-to r/w
|
||||
test-scratch NOCOMMENT
|
||||
EOT
|
||||
|
||||
$RSYNC -ve "$SSH" --rsync-path="$RSYNC$confopt" localhost:: | tee "$outfile"
|
||||
echo '===='
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 0 failed"
|
||||
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
$RSYNC -v localhost:: | tee "$outfile"
|
||||
echo '===='
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
|
||||
|
||||
$RSYNC -r localhost::test-hidden \
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# Test that rsync obeys default ACLs. -- Matt McCutchen
|
||||
|
||||
. $suitedir/rsync.fns
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
$RSYNC --version | grep ", ACLs" >/dev/null || test_skipped "Rsync is configured without ACL support"
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ case $0 in
|
||||
$RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests"
|
||||
RSYNC="$RSYNC --fake-super"
|
||||
TLS_ARGS="$TLS_ARGS --fake-super"
|
||||
case "$HOST_OS" in
|
||||
darwin*)
|
||||
case "`xattr 2>&1`" in
|
||||
*--list:*)
|
||||
mknod() {
|
||||
fn="$1"
|
||||
case "$2" in
|
||||
@@ -34,22 +34,6 @@ case $0 in
|
||||
xattr -s 'rsync.%stat' "$mode $maj,$min 0:0" "$fn"
|
||||
}
|
||||
;;
|
||||
solaris*)
|
||||
mknod() {
|
||||
fn="$1"
|
||||
case "$2" in
|
||||
p) mode=10644 ;;
|
||||
c) mode=20644 ;;
|
||||
b) mode=60644 ;;
|
||||
esac
|
||||
maj="${3:-0}"
|
||||
min="${4:-0}"
|
||||
touch "$fn"
|
||||
runat "$fn" "$SHELL_PATH" <<EOF
|
||||
echo "$mode $maj,$min 0:0" > rsync.%stat
|
||||
EOF
|
||||
}
|
||||
;;
|
||||
*)
|
||||
mknod() {
|
||||
fn="$1"
|
||||
@@ -70,9 +54,9 @@ EOF
|
||||
case `get_testuid` in
|
||||
'') ;; # If "id" failed, try to continue...
|
||||
0) ;;
|
||||
*) if [ -e "$FAKEROOT_PATH" ]; then
|
||||
*) if [ -f /usr/bin/fakeroot ]; then
|
||||
echo "Let's try re-running the script under fakeroot..."
|
||||
exec "$FAKEROOT_PATH" "$SHELL_PATH" $RUNSHFLAGS "$0"
|
||||
exec /usr/bin/fakeroot /bin/sh $RUNSHFLAGS "$0"
|
||||
fi
|
||||
test_skipped "Rsync needs root/fakeroot for device tests"
|
||||
;;
|
||||
@@ -90,7 +74,7 @@ mknod "$fromdir/char3" c 42 69 || test_skipped "Can't create char device node"
|
||||
mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node"
|
||||
mknod "$fromdir/block2" b 42 73 || test_skipped "Can't create block device node"
|
||||
mknod "$fromdir/block3" b 105 73 || test_skipped "Can't create block device node"
|
||||
ln "$fromdir/block3" "$fromdir/block3.5" || echo "Skipping hard-linked device test..."
|
||||
ln "$fromdir/block3" "$fromdir/block2.5" || echo "Skipping hard-linked device test..."
|
||||
mkfifo "$fromdir/fifo" || mknod "$fromdir/fifo" p || test_skipped "Can't run mkfifo"
|
||||
# Work around time rounding/truncating issue by touching both files.
|
||||
touch -r "$fromdir/block" "$fromdir/block" "$fromdir/block2"
|
||||
@@ -126,14 +110,14 @@ cat <<EOT >"$chkfile"
|
||||
cDc.t.$dots block
|
||||
cDc...$dots block2
|
||||
cD$all_plus block3
|
||||
hD$all_plus block3.5 => block3
|
||||
hD$all_plus block2.5 => block3
|
||||
cD$all_plus char
|
||||
cD$all_plus char2
|
||||
cD$all_plus char3
|
||||
cS$all_plus fifo
|
||||
EOT
|
||||
if test ! -r "$fromdir/block3.5"; then
|
||||
grep -v block3.5 <"$chkfile" >"$chkfile.new"
|
||||
if test ! -r "$fromdir/block2.5"; then
|
||||
grep -v block2.5 <"$chkfile" >"$chkfile.new"
|
||||
mv "$chkfile.new" "$chkfile"
|
||||
fi
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
|
||||
@@ -144,7 +128,7 @@ echo ""
|
||||
( cd "$todir" && rsync_ls_lR . ) > "$tmpdir/ls-to"
|
||||
diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to"
|
||||
|
||||
if test -r "$fromdir/block3.5"; then
|
||||
if test -r "$fromdir/block2.5"; then
|
||||
set -x
|
||||
$RSYNC -aii --link-dest="$todir" "$fromdir/" "$chkdir/" \
|
||||
| tee "$outfile"
|
||||
@@ -152,8 +136,8 @@ if test -r "$fromdir/block3.5"; then
|
||||
cd$allspace ./
|
||||
hD$allspace block
|
||||
hD$allspace block2
|
||||
hD$allspace block2.5
|
||||
hD$allspace block3
|
||||
hD$allspace block3.5
|
||||
hD$allspace char
|
||||
hD$allspace char2
|
||||
hD$allspace char3
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# Test that rsync obeys directory setgid. -- Matt McCutchen
|
||||
|
||||
. $suitedir/rsync.fns
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
umask 077
|
||||
|
||||
@@ -26,7 +26,7 @@ testit() {
|
||||
echo "File!" >"$scratchdir/file"
|
||||
echo "#!/bin/sh" >"$scratchdir/program"
|
||||
mkdir "$scratchdir/dir"
|
||||
chmod u=rwx,g=rw,g+s,o=r "$scratchdir/dir" || test_skipped "Can't chmod"
|
||||
chmod 2764 "$scratchdir/dir" || test_skipped "Can't chmod"
|
||||
chmod 664 "$scratchdir/file"
|
||||
chmod 775 "$scratchdir/program"
|
||||
[ -g "$scratchdir/dir" ] || test_skipped "The directory setgid bit vanished!"
|
||||
@@ -35,7 +35,7 @@ mkdir "$scratchdir/dir/blah"
|
||||
|
||||
# Test some target directories
|
||||
testit setgid-off 700 rw------- rwx------ rwx------
|
||||
testit setgid-on u=rwx,g=rw,g+s,o-rwx rw------- rwx------ rwx--S---
|
||||
testit setgid-on 2700 rw------- rwx------ rwx--S---
|
||||
|
||||
# Hooray
|
||||
exit 0
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# Test the --executability or -E option. -- Matt McCutchen
|
||||
|
||||
. $suitedir/rsync.fns
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
# Put some files in the From directory
|
||||
mkdir "$fromdir"
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
SSH="$scratchdir/src/support/lsh.sh"
|
||||
|
||||
hands_setup
|
||||
|
||||
# This list of files skips the contents of "subsubdir" but includes
|
||||
@@ -28,18 +26,5 @@ $RSYNC -a --exclude=dir/text --exclude='subsubdir/**' "$fromdir/" "$chkdir/"
|
||||
|
||||
checkit "$RSYNC -av --files-from='$scratchdir/filelist' '$scratchdir' '$todir/'" "$chkdir" "$todir"
|
||||
|
||||
for filehost in '' 'localhost:'; do
|
||||
for srchost in '' 'localhost:'; do
|
||||
if [ -z "$srchost" ]; then
|
||||
desthost='localhost:'
|
||||
else
|
||||
desthost=''
|
||||
fi
|
||||
|
||||
rm -rf "$todir"
|
||||
checkit "$RSYNC -avse '$SSH' --rsync-path='$RSYNC' --files-from='$filehost$scratchdir/filelist' '$srchost$scratchdir' '$desthost$todir/'" "$chkdir" "$todir"
|
||||
done
|
||||
done
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
|
||||
@@ -9,23 +9,21 @@
|
||||
|
||||
hands_setup
|
||||
|
||||
DEBUG_OPTS="--debug=all0,deltasum0"
|
||||
|
||||
# Main script starts here
|
||||
|
||||
runtest "basic operation" 'checkit "$RSYNC -av \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
|
||||
ln "$fromdir/filelist" "$fromdir/dir"
|
||||
runtest "hard links" 'checkit "$RSYNC -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
runtest "hard links" 'checkit "$RSYNC -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
|
||||
rm "$todir/text"
|
||||
runtest "one file" 'checkit "$RSYNC -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
runtest "one file" 'checkit "$RSYNC -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
|
||||
echo "extra line" >> "$todir/text"
|
||||
runtest "extra data" 'checkit "$RSYNC -avH $DEBUG_OPTS --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
runtest "extra data" 'checkit "$RSYNC -avH --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
|
||||
cp "$fromdir/text" "$todir/ThisShouldGo"
|
||||
runtest " --delete" 'checkit "$RSYNC --delete -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
runtest " --delete" 'checkit "$RSYNC --delete -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
|
||||
|
||||
cd "$tmpdir"
|
||||
rm -rf to from/*dir
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
SSH="$scratchdir/src/support/lsh.sh"
|
||||
SSH="$scratchdir/src/support/lsh"
|
||||
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
@@ -33,11 +33,11 @@ ln "$name2" "$name3" || fail "Can't create hardlink"
|
||||
cp "$name2" "$name4" || fail "Can't copy file"
|
||||
cat $srcdir/*.c >"$fromdir/text"
|
||||
|
||||
checkit "$RSYNC -aHivv --debug=HLINK5 '$fromdir/' '$todir/'" "$fromdir" "$todir"
|
||||
checkit "$RSYNC -aHivv '$fromdir/' '$todir/'" "$fromdir" "$todir"
|
||||
|
||||
echo "extra extra" >>"$todir/name1"
|
||||
|
||||
checkit "$RSYNC -aHivv --debug=HLINK5 --no-whole-file '$fromdir/' '$todir/'" "$fromdir" "$todir"
|
||||
checkit "$RSYNC -aHivv --no-whole-file '$fromdir/' '$todir/'" "$fromdir" "$todir"
|
||||
|
||||
# Add a new link in a new subdirectory to test that we don't try to link
|
||||
# the files before the directory gets created. We also create a bunch of
|
||||
@@ -56,27 +56,27 @@ done
|
||||
ln "$name1" "$fromdir/subdir/down/deep/new-file"
|
||||
rm "$todir/text"
|
||||
|
||||
checkit "$RSYNC -aHivve '$SSH' --debug=HLINK5 --rsync-path='$RSYNC' '$fromdir/' localhost:'$todir/'" "$fromdir" "$todir"
|
||||
checkit "$RSYNC -aHivve '$SSH' --rsync-path='$RSYNC' '$fromdir/' localhost:'$todir/'" "$fromdir" "$todir"
|
||||
|
||||
# Do some duplicate copies using --link-dest and --copy-dest to test that
|
||||
# we hard-link all locally-inherited items.
|
||||
checkit "$RSYNC -aHivv --debug=HLINK5 --link-dest='$todir' '$fromdir/' '$chkdir/'" "$todir" "$chkdir"
|
||||
checkit "$RSYNC -aHivv --link-dest='$todir' '$fromdir/' '$chkdir/'" "$todir" "$chkdir"
|
||||
|
||||
rm -rf "$chkdir"
|
||||
checkit "$RSYNC -aHivv --debug=HLINK5 --copy-dest='$todir' '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
|
||||
checkit "$RSYNC -aHivv --copy-dest='$todir' '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir"
|
||||
|
||||
# Create a hard link that has only one part in the hierarchy.
|
||||
echo "This is another file" >"$fromdir/solo"
|
||||
ln "$fromdir/solo" "$chkdir/solo" || fail "Can't create hardlink"
|
||||
|
||||
# Make sure that the checksum data doesn't slide due to an HLINK_BUMP() change.
|
||||
$RSYNC -aHivc --debug=HLINK5 "$fromdir/" "$chkdir/" | tee "$outfile"
|
||||
$RSYNC -aHivc "$fromdir/" "$chkdir/" | tee "$outfile"
|
||||
grep solo "$outfile" && test_fail "Erroneous copy of solo file occurred!"
|
||||
|
||||
# Make sure there's nothing wrong with sending a single file with -H
|
||||
# enabled (this has broken twice so far, so we need this test).
|
||||
rm -rf "$todir"
|
||||
$RSYNC -aHivv --debug=HLINK5 "$name1" "$todir/"
|
||||
$RSYNC -aHivv "$name1" "$todir/"
|
||||
diff $diffopt "$name1" "$todir" || test_fail "solo copy of name1 failed"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
|
||||
@@ -108,9 +108,9 @@ filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
bar/baz/rsync is uptodate
|
||||
foo/config1 is uptodate
|
||||
foo/config2
|
||||
foo/extra is uptodate
|
||||
foo/sym is uptodate
|
||||
foo/config2
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
|
||||
|
||||
@@ -203,8 +203,8 @@ bar/baz/rsync is uptodate
|
||||
foo/ is uptodate
|
||||
foo/config1 is uptodate
|
||||
foo/config2 is uptodate
|
||||
foo/sym $is_uptodate
|
||||
foo/extra => foo/config1
|
||||
foo/sym $is_uptodate
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 10 failed"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
# Test three bugs fixed by my redoing of the missing_below logic.
|
||||
|
||||
. $suitedir/rsync.fns
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
makepath "$fromdir/subdir" "$todir"
|
||||
echo data >"$fromdir/subdir/file"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# License along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
tmpdir="$scratchdir"
|
||||
fromdir="$tmpdir/from"
|
||||
todir="$tmpdir/to"
|
||||
@@ -31,7 +32,7 @@ tab_ch=' ' # a single tab character
|
||||
# Berkley's nice.
|
||||
PATH="$PATH:/usr/ucb"
|
||||
|
||||
if diff -u "$suitedir/rsync.fns" "$suitedir/rsync.fns" >/dev/null 2>&1; then
|
||||
if diff -u "$srcdir/testsuite/rsync.fns" "$srcdir/testsuite/rsync.fns" >/dev/null 2>&1; then
|
||||
diffopt="-u"
|
||||
else
|
||||
diffopt="-c"
|
||||
@@ -262,17 +263,6 @@ build_rsyncd_conf() {
|
||||
logfile="$scratchdir/rsyncd.log"
|
||||
hostname=`uname -n`
|
||||
|
||||
uid_setting='uid = 0'
|
||||
gid_setting='gid = 0'
|
||||
case `get_testuid` in
|
||||
0) ;;
|
||||
*)
|
||||
# Non-root cannot specify uid & gid settings
|
||||
uid_setting="#$uid_setting"
|
||||
gid_setting="#$gid_setting"
|
||||
;;
|
||||
esac
|
||||
|
||||
cat >"$conf" <<EOF
|
||||
# rsyncd configuration file autogenerated by $0
|
||||
|
||||
@@ -284,9 +274,9 @@ log file = $logfile
|
||||
log format = %i %h [%a] %m (%u) %l %f%L
|
||||
transfer logging = yes
|
||||
exclude = ? foobar.baz
|
||||
max verbosity = 4
|
||||
$uid_setting
|
||||
$gid_setting
|
||||
max verbosity = 9
|
||||
uid = 0
|
||||
gid = 0
|
||||
|
||||
[test-from]
|
||||
path = $fromdir
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
SSH="$scratchdir/src/support/lsh.sh"
|
||||
SSH="$scratchdir/src/support/lsh"
|
||||
|
||||
if test x"$rsync_enable_ssh_tests" = xyes; then
|
||||
if type ssh >/dev/null ; then
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
# Test that rsync handles basic xattr preservation.
|
||||
|
||||
. $suitedir/rsync.fns
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
lnkdir="$tmpdir/lnk"
|
||||
|
||||
$RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync is configured without xattr support"
|
||||
|
||||
case "$HOST_OS" in
|
||||
darwin*)
|
||||
case "`xattr 2>&1`" in
|
||||
*--list:*)
|
||||
xset() {
|
||||
xnam="$1"
|
||||
xval="$2"
|
||||
@@ -24,27 +24,6 @@ darwin*)
|
||||
RSYNC_PREFIX='rsync'
|
||||
RUSR='rsync.nonuser'
|
||||
;;
|
||||
solaris*)
|
||||
xset() {
|
||||
xnam="$1"
|
||||
xval="$2"
|
||||
shift 2
|
||||
for fn in "${@}"; do
|
||||
runat "$fn" "$SHELL_PATH" <<EOF
|
||||
echo "${xval}" > "${xnam}"
|
||||
EOF
|
||||
done
|
||||
}
|
||||
xls() {
|
||||
for fn in "${@}"; do
|
||||
runat "$fn" "$SHELL_PATH" <<EOF
|
||||
for x in *; do echo "\$x=\`cat \$x\`"; done
|
||||
EOF
|
||||
done
|
||||
}
|
||||
RSYNC_PREFIX='rsync'
|
||||
RUSR='rsync.nonuser'
|
||||
;;
|
||||
*)
|
||||
xset() {
|
||||
xnam="$1"
|
||||
|
||||
31
tls.c
31
tls.c
@@ -2,7 +2,7 @@
|
||||
* Trivial ls for comparing two directories after running an rsync.
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2013 Wayne Davison
|
||||
* Copyright (C) 2003-2009 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -43,12 +43,10 @@
|
||||
/* These are to make syscall.o shut up. */
|
||||
int dry_run = 0;
|
||||
int am_root = 0;
|
||||
int am_sender = 1;
|
||||
int read_only = 1;
|
||||
int list_only = 0;
|
||||
int link_times = 0;
|
||||
int link_owner = 0;
|
||||
int nsec_times = 0;
|
||||
int preserve_perms = 0;
|
||||
int preserve_executability = 0;
|
||||
|
||||
@@ -148,9 +146,9 @@ static void list_file(const char *fname)
|
||||
buf.st_uid = buf.st_gid = 0;
|
||||
strlcpy(linkbuf, " -> ", sizeof linkbuf);
|
||||
/* const-cast required for silly UNICOS headers */
|
||||
len = do_readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
|
||||
len = readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
|
||||
if (len == -1)
|
||||
failed("do_readlink", fname);
|
||||
failed("readlink", fname);
|
||||
else
|
||||
/* it's not nul-terminated */
|
||||
linkbuf[4+len] = 0;
|
||||
@@ -161,10 +159,9 @@ static void list_file(const char *fname)
|
||||
permstring(permbuf, buf.st_mode);
|
||||
|
||||
if (buf.st_mtime) {
|
||||
int len;
|
||||
mt = gmtime(&buf.st_mtime);
|
||||
|
||||
len = snprintf(datebuf, sizeof datebuf,
|
||||
snprintf(datebuf, sizeof datebuf,
|
||||
"%04d-%02d-%02d %02d:%02d:%02d",
|
||||
(int)mt->tm_year + 1900,
|
||||
(int)mt->tm_mon + 1,
|
||||
@@ -172,17 +169,8 @@ static void list_file(const char *fname)
|
||||
(int)mt->tm_hour,
|
||||
(int)mt->tm_min,
|
||||
(int)mt->tm_sec);
|
||||
#ifdef ST_MTIME_NSEC
|
||||
if (nsec_times) {
|
||||
snprintf(datebuf + len, sizeof datebuf - len,
|
||||
".%09d", (int)buf.ST_MTIME_NSEC);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
int len = MIN(19 + 9*nsec_times, (int)sizeof datebuf - 1);
|
||||
memset(datebuf, ' ', len);
|
||||
datebuf[len] = '\0';
|
||||
}
|
||||
} else
|
||||
strlcpy(datebuf, " ", sizeof datebuf);
|
||||
|
||||
/* TODO: Perhaps escape special characters in fname? */
|
||||
|
||||
@@ -191,8 +179,8 @@ static void list_file(const char *fname)
|
||||
printf("%5ld,%6ld",
|
||||
(long)major(buf.st_rdev),
|
||||
(long)minor(buf.st_rdev));
|
||||
} else
|
||||
printf("%15s", do_big_num(buf.st_size, 1, NULL));
|
||||
} else /* NB: use double for size since it might not fit in a long. */
|
||||
printf("%12.0f", (double)buf.st_size);
|
||||
printf(" %6ld.%-6ld %6ld %s %s%s\n",
|
||||
(long)buf.st_uid, (long)buf.st_gid, (long)buf.st_nlink,
|
||||
datebuf, fname, linkbuf);
|
||||
@@ -204,9 +192,6 @@ static struct poptOption long_options[] = {
|
||||
{"link-owner", 'L', POPT_ARG_NONE, &link_owner, 0, 0, 0 },
|
||||
#ifdef SUPPORT_XATTRS
|
||||
{"fake-super", 'f', POPT_ARG_VAL, &am_root, -1, 0, 0 },
|
||||
#endif
|
||||
#ifdef ST_MTIME_NSEC
|
||||
{"nsec", 's', POPT_ARG_NONE, &nsec_times, 0, 0, 0 },
|
||||
#endif
|
||||
{"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
|
||||
{0,0,0,0,0,0,0}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user