mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-27 00:05:36 -04:00
Compare commits
437 Commits
v2.6.7pre1
...
v2.6.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c6d79528a | ||
|
|
556e03a3c9 | ||
|
|
e4887738bb | ||
|
|
0f5c1c193a | ||
|
|
ab6dcad61c | ||
|
|
b6855ddc9c | ||
|
|
0cbb958f34 | ||
|
|
418da6d952 | ||
|
|
51d133d686 | ||
|
|
cbb95d3d24 | ||
|
|
d9126a861f | ||
|
|
b4768a1397 | ||
|
|
47b032e97f | ||
|
|
50dfd5b4fe | ||
|
|
1de02c273d | ||
|
|
9ce7fc3887 | ||
|
|
dc1f7b9ea3 | ||
|
|
ee7cf95b13 | ||
|
|
492fc3536d | ||
|
|
5e61bdb4d5 | ||
|
|
f964ac5eee | ||
|
|
c55b39afad | ||
|
|
a27463a9a2 | ||
|
|
590eb6c02d | ||
|
|
0d7a6b4906 | ||
|
|
b4f0287197 | ||
|
|
8d6386809e | ||
|
|
230328a30a | ||
|
|
5819d6b14a | ||
|
|
7b4a40ed70 | ||
|
|
f210dcadf4 | ||
|
|
178a1d2048 | ||
|
|
a4b4e0770b | ||
|
|
2a6e35db31 | ||
|
|
e3794138d8 | ||
|
|
fdd10da6f7 | ||
|
|
5f12a07bff | ||
|
|
6a4a1d0cb0 | ||
|
|
434c40986d | ||
|
|
8ee6857702 | ||
|
|
721ddc903f | ||
|
|
154c345db0 | ||
|
|
25f637a334 | ||
|
|
2356d73bb4 | ||
|
|
4968423e71 | ||
|
|
99eba67585 | ||
|
|
5abe03d6e8 | ||
|
|
83078af5b0 | ||
|
|
185aa5b0e5 | ||
|
|
cabd60fdce | ||
|
|
10944395bf | ||
|
|
204f4f4d09 | ||
|
|
c9bce0b8f8 | ||
|
|
deee574b11 | ||
|
|
55410368e5 | ||
|
|
e4fdf1debe | ||
|
|
1580899c1d | ||
|
|
f863b76300 | ||
|
|
5e1ec06f09 | ||
|
|
36e2ea6068 | ||
|
|
f4164b73b4 | ||
|
|
9ef506a2b2 | ||
|
|
b1b54199ef | ||
|
|
33394b769d | ||
|
|
011e85a5e3 | ||
|
|
d5dcb6f775 | ||
|
|
0c25dedf31 | ||
|
|
6105464b79 | ||
|
|
4d51f0db79 | ||
|
|
ff530f04a0 | ||
|
|
e8b21fe406 | ||
|
|
71cb9df386 | ||
|
|
f97c2d4a9b | ||
|
|
b8a6dae038 | ||
|
|
969f7ed5b7 | ||
|
|
e825409a84 | ||
|
|
b8d29fd8e6 | ||
|
|
200f2d98db | ||
|
|
1a7f3d99c5 | ||
|
|
e80876700c | ||
|
|
ec55b4f2fb | ||
|
|
798cde474f | ||
|
|
558d482c47 | ||
|
|
418b6a2703 | ||
|
|
1ef5bf3cfd | ||
|
|
2a94207ad6 | ||
|
|
ddcba3f075 | ||
|
|
db3ae95cac | ||
|
|
1a05de2bff | ||
|
|
d9163a4cf5 | ||
|
|
44885a398f | ||
|
|
dfe1ed5e97 | ||
|
|
242f6052c2 | ||
|
|
519d55a950 | ||
|
|
b6008dc645 | ||
|
|
6f3684ffb5 | ||
|
|
615a5415c9 | ||
|
|
ba081be327 | ||
|
|
3e88414e4e | ||
|
|
0888952768 | ||
|
|
5dcd9a2b70 | ||
|
|
6ce9432d75 | ||
|
|
6c8507724b | ||
|
|
d04e95e968 | ||
|
|
b06050f9ad | ||
|
|
ad75d18d2e | ||
|
|
ed4b8da048 | ||
|
|
2cd421d809 | ||
|
|
ea0ea357f4 | ||
|
|
0480a946f5 | ||
|
|
67f8a41be5 | ||
|
|
5e1f082d0c | ||
|
|
a633351962 | ||
|
|
2edfe52230 | ||
|
|
acee1ad853 | ||
|
|
8f4ae68ca7 | ||
|
|
ff1b9344c9 | ||
|
|
a923437bc0 | ||
|
|
dde698c2e8 | ||
|
|
c2b47e31a5 | ||
|
|
4e0bf97716 | ||
|
|
174e51b5bf | ||
|
|
30cd7ec1cf | ||
|
|
48459ba15c | ||
|
|
48ecccce2d | ||
|
|
a739128df9 | ||
|
|
2c1775620a | ||
|
|
40f910c43a | ||
|
|
503114a782 | ||
|
|
71f9e4673e | ||
|
|
176e8e94c3 | ||
|
|
814b340c27 | ||
|
|
f167879035 | ||
|
|
4187572616 | ||
|
|
ff43d8b449 | ||
|
|
97bf86f8ee | ||
|
|
8c449e6285 | ||
|
|
29930a9fd2 | ||
|
|
c98ad3df96 | ||
|
|
9c3c30e5c7 | ||
|
|
b4a09b72ee | ||
|
|
5a3810b463 | ||
|
|
e8d97006e5 | ||
|
|
8adc22e362 | ||
|
|
dcebf78fe0 | ||
|
|
651c8510e8 | ||
|
|
1ed3f5ed61 | ||
|
|
70c81b0c07 | ||
|
|
47c1197534 | ||
|
|
fb41a3c669 | ||
|
|
2700069d5a | ||
|
|
044ccbaacf | ||
|
|
841d943651 | ||
|
|
04cd8789cb | ||
|
|
9578783a71 | ||
|
|
4cff5fa462 | ||
|
|
cc1b4f776a | ||
|
|
72d1b262ac | ||
|
|
6fb7cc38a2 | ||
|
|
8a7b8400e7 | ||
|
|
d2ab094dec | ||
|
|
ccd2966da9 | ||
|
|
6dc9b74bc6 | ||
|
|
04c841190f | ||
|
|
d20ce6e144 | ||
|
|
a7d461fccd | ||
|
|
4c5a2da65f | ||
|
|
caff33228e | ||
|
|
f38f6f80b7 | ||
|
|
e848e06618 | ||
|
|
eece5fe32c | ||
|
|
8590993185 | ||
|
|
b64ee91a41 | ||
|
|
d0133e6eba | ||
|
|
1925c3448c | ||
|
|
19b8587654 | ||
|
|
051f5df526 | ||
|
|
e525519509 | ||
|
|
4b90820d9f | ||
|
|
2873603ab5 | ||
|
|
ec52c3b9da | ||
|
|
10ae3406ee | ||
|
|
232658d9d3 | ||
|
|
c000002f46 | ||
|
|
2fedf3d596 | ||
|
|
887d745549 | ||
|
|
20f90d5e8a | ||
|
|
17bda2d109 | ||
|
|
b534351058 | ||
|
|
b3e4e7ef2e | ||
|
|
a3f6dbdf5c | ||
|
|
95ae5224b0 | ||
|
|
03dbc0b831 | ||
|
|
ffa8ab8eb5 | ||
|
|
a17e119d8b | ||
|
|
6bfc7b4d79 | ||
|
|
b3e8e7c79e | ||
|
|
bdd3a4fef5 | ||
|
|
a00f5a371e | ||
|
|
55c412630c | ||
|
|
778ee637ee | ||
|
|
80aff93b32 | ||
|
|
6721973e37 | ||
|
|
a2ed5801d3 | ||
|
|
15ce4b24fc | ||
|
|
c5260884d6 | ||
|
|
ea124cb324 | ||
|
|
13b597fa71 | ||
|
|
ecc7623e7f | ||
|
|
87c0f9d6b4 | ||
|
|
1cfcb8af11 | ||
|
|
56aaa4c44c | ||
|
|
4b6a7bd706 | ||
|
|
5bc933a285 | ||
|
|
01d124d9e2 | ||
|
|
58a06312a4 | ||
|
|
c2c8db9195 | ||
|
|
d1e6b0e225 | ||
|
|
8936367695 | ||
|
|
8517e9c10a | ||
|
|
fcecb70b1d | ||
|
|
582c1589f3 | ||
|
|
cb15269eb0 | ||
|
|
f47807900b | ||
|
|
40410a38bc | ||
|
|
6b54a688cf | ||
|
|
b59dc8d5ae | ||
|
|
45ba206a94 | ||
|
|
2220ec0a69 | ||
|
|
5fdbb87df8 | ||
|
|
f1c9bcd0fc | ||
|
|
3723548ded | ||
|
|
12ccc73ae7 | ||
|
|
ee8d9636d1 | ||
|
|
38de2866e5 | ||
|
|
bdac7621ee | ||
|
|
8ac4774675 | ||
|
|
229e1950ed | ||
|
|
93977bca10 | ||
|
|
c2a2147a5b | ||
|
|
73173af955 | ||
|
|
a2248aea2e | ||
|
|
a8167c6611 | ||
|
|
91f4b31fe1 | ||
|
|
cad8f6f980 | ||
|
|
d8bf7ea8e9 | ||
|
|
d8f28a663c | ||
|
|
2ae4126a9e | ||
|
|
6f1c2aab43 | ||
|
|
e71c1c26df | ||
|
|
b24498ec2c | ||
|
|
b2d4639543 | ||
|
|
d3ef985954 | ||
|
|
7c58c99184 | ||
|
|
ad77db8b71 | ||
|
|
e7c67065c0 | ||
|
|
0f78b81511 | ||
|
|
d051056f92 | ||
|
|
a4a38e8df0 | ||
|
|
60ef8ed128 | ||
|
|
8aa0dc7838 | ||
|
|
4177f09b83 | ||
|
|
acaadb55c1 | ||
|
|
b88c2e8ffe | ||
|
|
f4ea5f47dc | ||
|
|
62ae66d43b | ||
|
|
8641d28740 | ||
|
|
de3438407c | ||
|
|
434764269c | ||
|
|
ba212fe0b6 | ||
|
|
5f93b4d35e | ||
|
|
f8db4a8ab4 | ||
|
|
398612ba07 | ||
|
|
77b013afb5 | ||
|
|
08c0cd8a42 | ||
|
|
1c6e9dfabc | ||
|
|
0037bf23fc | ||
|
|
285edc9169 | ||
|
|
c4aa84ad50 | ||
|
|
b635bc92d1 | ||
|
|
146d2228cc | ||
|
|
b2501ccf12 | ||
|
|
e60bba3fbc | ||
|
|
e26cfccf16 | ||
|
|
74f80abce2 | ||
|
|
5899b8cf3e | ||
|
|
08e0a62956 | ||
|
|
2bd17a51ae | ||
|
|
c7b9ebb598 | ||
|
|
e3db43ffe5 | ||
|
|
f61ab01d96 | ||
|
|
ceca8ccac8 | ||
|
|
374c3e1278 | ||
|
|
e09d8a304c | ||
|
|
2a7d9fe9b8 | ||
|
|
e63aeb6d68 | ||
|
|
077d5d4ebc | ||
|
|
e2d774cdd7 | ||
|
|
415b598346 | ||
|
|
69627d66f8 | ||
|
|
ac98cd98e3 | ||
|
|
91d324b4ea | ||
|
|
89fb50263b | ||
|
|
e257c6c20b | ||
|
|
43eae40e45 | ||
|
|
920240a687 | ||
|
|
f8b9da1a2c | ||
|
|
3c987ee956 | ||
|
|
5c6d46329b | ||
|
|
8b3e964d14 | ||
|
|
91a93df049 | ||
|
|
19826af5f0 | ||
|
|
49f4cfdf39 | ||
|
|
b3222792ad | ||
|
|
0640710115 | ||
|
|
fa65989a8b | ||
|
|
4209f079dd | ||
|
|
a7704777ce | ||
|
|
7d51b8374d | ||
|
|
a27042b521 | ||
|
|
5b51c893c5 | ||
|
|
408e69396c | ||
|
|
954bbed84a | ||
|
|
7c329ec72c | ||
|
|
07a8a360a5 | ||
|
|
1618c9e6d1 | ||
|
|
ba0147ac42 | ||
|
|
9e88f057b4 | ||
|
|
f171bf5b8f | ||
|
|
1b1628b90a | ||
|
|
50cf25672e | ||
|
|
b316862831 | ||
|
|
38a4b9c297 | ||
|
|
a058cbc410 | ||
|
|
1ef7913497 | ||
|
|
88a16c8b4f | ||
|
|
8030b28ff8 | ||
|
|
1c598b1db8 | ||
|
|
6854bf69a8 | ||
|
|
293def601d | ||
|
|
651dc65efc | ||
|
|
c2b2bd6a93 | ||
|
|
e32a48d256 | ||
|
|
b5cf121d70 | ||
|
|
44c26bf2a1 | ||
|
|
cc8c5057fe | ||
|
|
b4c7c1ca99 | ||
|
|
16d3b31b2c | ||
|
|
89a8180c5e | ||
|
|
34f961bbf3 | ||
|
|
2384f9e1db | ||
|
|
48cce779a2 | ||
|
|
6820753732 | ||
|
|
fbbe9a016d | ||
|
|
c64ca7ef58 | ||
|
|
900cfcb584 | ||
|
|
beab3078d6 | ||
|
|
530a2199da | ||
|
|
d9bca0c32f | ||
|
|
d733de97f5 | ||
|
|
f06c11ed40 | ||
|
|
c638caa63e | ||
|
|
d775372a34 | ||
|
|
07affc3d93 | ||
|
|
f2ebbebead | ||
|
|
a695b379b5 | ||
|
|
88c2190a7c | ||
|
|
2dbf36ef55 | ||
|
|
cca9208697 | ||
|
|
aa37022ef7 | ||
|
|
85c417579f | ||
|
|
baed67efc4 | ||
|
|
c5b7aa1532 | ||
|
|
904e5af128 | ||
|
|
a41d110647 | ||
|
|
a92d6ff13c | ||
|
|
05278935a3 | ||
|
|
a56cdef9b1 | ||
|
|
e9357a2deb | ||
|
|
8d94d27af0 | ||
|
|
6f2a222c59 | ||
|
|
8470a515ef | ||
|
|
06982ac43b | ||
|
|
865c3b5f92 | ||
|
|
8c9e06d7b9 | ||
|
|
a9cc128308 | ||
|
|
ccb16b467b | ||
|
|
1e44aeb92a | ||
|
|
c897f7119a | ||
|
|
ee8e2b1547 | ||
|
|
5fa38cd679 | ||
|
|
65535b5482 | ||
|
|
439a198d02 | ||
|
|
f041b02557 | ||
|
|
4d8639eb2d | ||
|
|
519c8de16f | ||
|
|
7f20af4674 | ||
|
|
55d24e5fed | ||
|
|
81f654e396 | ||
|
|
8f1dc165e2 | ||
|
|
9a0cfff57f | ||
|
|
d749eb6896 | ||
|
|
6d59ac192b | ||
|
|
94d3725cf2 | ||
|
|
8840ec0f49 | ||
|
|
44a8e86d47 | ||
|
|
73abdda442 | ||
|
|
15b03ab1a8 | ||
|
|
dc5245679a | ||
|
|
60414e5bce | ||
|
|
af40c7d667 | ||
|
|
7eb2ecda0f | ||
|
|
6d12a859bc | ||
|
|
920071e242 | ||
|
|
2a24b4bd0c | ||
|
|
a753502200 | ||
|
|
8958fae362 | ||
|
|
e2d68210d7 | ||
|
|
99534debc8 | ||
|
|
5b98629747 | ||
|
|
42003f6af3 | ||
|
|
434573b226 | ||
|
|
d6081c829c | ||
|
|
58718881ef | ||
|
|
ac669e8b92 | ||
|
|
567f1566a9 | ||
|
|
59a5687105 | ||
|
|
7b13ff9704 | ||
|
|
5e7b826a4f | ||
|
|
cbc63b9b48 | ||
|
|
71a84cbab0 | ||
|
|
55e54e464b | ||
|
|
467688dc06 | ||
|
|
375d8f913b | ||
|
|
021849204a | ||
|
|
b635f2e964 | ||
|
|
1e2b96bbee |
19
.ignore
19
.ignore
@@ -1,19 +0,0 @@
|
||||
.#*
|
||||
*.log
|
||||
Makefile
|
||||
config.h
|
||||
*.o
|
||||
CVS
|
||||
.ignore
|
||||
.cvsignore
|
||||
*~
|
||||
rsync
|
||||
config.status
|
||||
config.cache
|
||||
TAGS
|
||||
config.log
|
||||
test
|
||||
*.gz
|
||||
rsync-*
|
||||
*.dvi
|
||||
*.aux
|
||||
4
COPYING
4
COPYING
@@ -2,7 +2,7 @@
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -313,7 +313,7 @@ Also add information on how to contact you by electronic and paper mail.
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Makefile
|
||||
|
||||
prefix=@prefix@
|
||||
datarootdir=@datarootdir@
|
||||
exec_prefix=@exec_prefix@
|
||||
bindir=@bindir@
|
||||
mandir=@mandir@
|
||||
@@ -91,13 +92,13 @@ t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
|
||||
|
||||
gen:
|
||||
$(MAKE) -C $(srcdir) -f prepare-source.mak gen
|
||||
cd $(srcdir) && $(MAKE) -f prepare-source.mak gen
|
||||
|
||||
man:
|
||||
$(MAKE) -C $(srcdir) -f prepare-source.mak man
|
||||
cd $(srcdir) && $(MAKE) -f prepare-source.mak man
|
||||
|
||||
proto:
|
||||
$(MAKE) -C $(srcdir) -f prepare-source.mak proto.h
|
||||
cd $(srcdir) && $(MAKE) -f prepare-source.mak proto.h
|
||||
|
||||
clean: cleantests
|
||||
rm -f *~ $(OBJS) $(TLS_OBJ) $(CHECK_PROGS) $(CHECK_OBJS)
|
||||
@@ -142,7 +143,7 @@ test: check
|
||||
# might lose in the future where POSIX diverges from old sh.
|
||||
|
||||
check: all $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin=`pwd`/rsync$(EXEEXT) srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh
|
||||
|
||||
wildtest.o: wildtest.c lib/wildmatch.c rsync.h
|
||||
wildtest$(EXEEXT): wildtest.o lib/compat.o
|
||||
|
||||
331
NEWS
331
NEWS
@@ -1,255 +1,158 @@
|
||||
NEWS for rsync 2.6.7 (UNRELEASED)
|
||||
NEWS for rsync 2.6.9 (6 Nov 2006)
|
||||
Protocol: 29 (unchanged)
|
||||
Changes since 2.6.6:
|
||||
|
||||
OUTPUT CHANGES:
|
||||
|
||||
- The itemized output now uses 'S' for a special file instead of
|
||||
clumping them together with the 'D' for devices.
|
||||
|
||||
- The way rsync escapes unreadable characters has changed. First, rsync
|
||||
now has support for recognizing valid multibyte character sequences in
|
||||
your current locale, allowing it to escape fewer characters than before
|
||||
for a locale such as UTF-8. Second, it now uses an escape idiom of
|
||||
"\#123", which is the literal string "\#" followed by exactly 3 octal
|
||||
digits. Rsync no longer doubles a backslash character in a filename
|
||||
(e.g. it used to output "foo\\bar" when copying "foo\bar") -- now it only
|
||||
escapes a backslash that is followed by a hash-sign and 3 digits (0-9)
|
||||
(e.g. it will output "foo\#134#789" when copying "foo\#789"). See also
|
||||
the --8-bit-output (-8) option, mentioned below.
|
||||
|
||||
Script writers: the local rsync is the one that outputs escaped names,
|
||||
so if you need to support unescaping of filenames for older rsyncs, I'd
|
||||
suggest that you parse the output of "rsync --version" and only use the
|
||||
old unescaping rules for 2.6.5 and 2.6.6.
|
||||
Changes since 2.6.8:
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- Fixed a really old bug that caused --checksum (-c) to checksum all the
|
||||
files encountered during the delete scan (ouch).
|
||||
- If rsync is interrupted via a handled signal (such as SIGINT), it will
|
||||
once again clean-up its temp file from the destination dir.
|
||||
|
||||
- Fixed a potential hang in a remote generator: when the receiver gets a
|
||||
read-error on the socket, it now signals the generator about this so that
|
||||
the generator does not try to send any of the terminating error messages
|
||||
to the client (avoiding a potential hang in some setups).
|
||||
- Fixed an overzealous sanitizing bug in the handling of the --link-dest,
|
||||
--copy-dest, and --compare-dest options to a daemon without chroot: if
|
||||
the copy's destination dir is deeper than the top of the module's path,
|
||||
these options now accept a safe number of parent-dir (../) references
|
||||
(since these options are relative to the destination dir). The old code
|
||||
incorrectly chopped off all "../" prefixes for these options, no matter
|
||||
how deep the destination directory was in the module's hierarchy.
|
||||
|
||||
- Made hard-links work with symlinks and devices again.
|
||||
- Fixed a bug where a deferred info/error/log message could get sent
|
||||
directly to the sender instead of being handled by rwrite() in the
|
||||
generator. This fixes an "unexpected tag 3" fatal error, and should
|
||||
also fix a potential problem where a deferred info/error message from
|
||||
the receiver might bypass the log file and get sent only to the client
|
||||
process. (These problems could only affect an rsync daemon that was
|
||||
receiving files.)
|
||||
|
||||
- If the sender gets an early EOF reading a source file, we propagate this
|
||||
error to the receiver so that it can discard the file and try requesting
|
||||
it again (which is the existing behavior for other kinds of read errors).
|
||||
- Fixed a bug when --inplace was combined with a --*-dest option and we
|
||||
update a file's data using an alternate basis file. The code now
|
||||
notices that it needs to copy the matching data from the basis file
|
||||
instead of (wrongly) assuming that it was already present in the file.
|
||||
|
||||
- If a device-file/special-file changes permissions, rsync now updates the
|
||||
permissions without recreating the file.
|
||||
- Fixed a bug where using --dry-run with a --*-dest option with a path
|
||||
relative to a directory that does not yet exist: the affected option
|
||||
gets its proper path value so that the output of the dry-run is right.
|
||||
|
||||
- If the user specifies a remote-host for both the source and destination,
|
||||
we now output a syntax error rather than trying to open the destination
|
||||
hostspec as a filename.
|
||||
- Fixed a bug in the %f logfile escape when receiving files: the
|
||||
destination path is now included in the output (e.g. you can now tell
|
||||
when a user specifies a subdir inside a module).
|
||||
|
||||
- When --inplace creates a new destination file, rsync now creates it with
|
||||
permissions 0600 instead of 0000 -- this makes restarting possible when
|
||||
the transfer gets interrupted in the middle of sending a new file.
|
||||
- If the receiving side fails to create a directory, it will now skip
|
||||
trying to update everything that is inside that directory.
|
||||
|
||||
- Reject the combination of --inplace and --sparse since the sparse-output
|
||||
algorithm doesn't work when overwriting existing data.
|
||||
- If --link-dest is specified with --checksum but without --times, rsync
|
||||
will now allow a hard-link to be created to a matching link-dest file
|
||||
even when the file's modify-time doesn't match the server's file.
|
||||
|
||||
- Fixed the directory name in the error that is output when pop_dir()
|
||||
fails.
|
||||
- The daemon now calls more timezone-using functions prior to doing a
|
||||
chroot. This should help some C libraries to generate proper timestamps
|
||||
from inside a chrooted daemon (and to not try to access /etc/timezone
|
||||
over and over again).
|
||||
|
||||
- Really fixed the parsing of a "!" entry in .cvsignore files this time.
|
||||
- Fixed a bug in the handling of an absolute --partial-dir=ABS_PATH option:
|
||||
it now deletes an alternate basis file from the partial-dir that was used
|
||||
to successfully update a destination file.
|
||||
|
||||
- If the generator gets a stat() error on a file, output it (this used to
|
||||
require at least -vv for the error to be seen).
|
||||
- Fixed a bug in the handling of --delete-excluded when using a per-dir
|
||||
merge file: the merge file is now honored on the receiving side, and
|
||||
only its unqualified include/exclude commands are ignored (just as is
|
||||
done for global include/excludes).
|
||||
|
||||
- If waitpid() fails or the child rsync didn't exit cleanly, we now handle
|
||||
the exit status properly and generate a better error.
|
||||
- Fixed a recent bug where --delete was not working when transferring from
|
||||
the root (/) of the filesystem with --relative enabled.
|
||||
|
||||
- Fixed some glitches in the double-verbose output when using --copy-dest,
|
||||
--link-dest, or --compare-dest.
|
||||
- Fixed a recent bug where an --exclude='*' could affect the root (/) of
|
||||
the filesystem with --relative enabled.
|
||||
|
||||
- Fixed the matching of the dont-compress items (e.g. *.gz) against files
|
||||
that have a path component containing a slash.
|
||||
- When --inplace creates a file, it is now created with owner read/write
|
||||
permissions (0600) instead of no permissions at all. This avoids a
|
||||
problem continuing a transfer that was interrupted (since --inplace
|
||||
will not update a file that has no write permissions).
|
||||
|
||||
- If code reading a filter/exclude file an EINTR error, rsync now clears
|
||||
the error flag on the file handle so it can keep on reading.
|
||||
- If either --remove-source-files or --remove-sent-files is enabled and we
|
||||
are unable to remove the source file, rsync now outputs an error.
|
||||
|
||||
- If --relative is active, the sending side cleans up trailing "/" or "/."
|
||||
suffixes to avoid triggering a bug in older rsync versions. Also, we now
|
||||
reject a ".." dir if it would be sent as a relative dir.
|
||||
- Fixed a bug in the daemon's "incoming chmod" rule: newly-created
|
||||
directories no longer get the 'F' (file) rules applied to them.
|
||||
|
||||
- If a non-directory is in the way of a directory and rsync is run with
|
||||
--dry-run and --delete, rsync no longer complains about not being able
|
||||
to opendir() the not-yet present directory.
|
||||
- Fixed an infinite loop bug when a filter rule was rejected due to being
|
||||
overly long.
|
||||
|
||||
- Got rid of the need for --force to be used in some circumstances with
|
||||
--delete-after (making it consistent with --delete-before/-during).
|
||||
- When the server receives a --partial-dir option from the client, it no
|
||||
longer runs the client-side code that adds an assumed filter rule (since
|
||||
the client will be sending us the rules in the usual manner, and they
|
||||
may have chosen to override the auto-added rule).
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
- Added the --specials option to tell rsync to copy special files (and does
|
||||
not require root). The --devices option now affects just character and
|
||||
block devices (which now matches the documentation). The -D option still
|
||||
requests both --devices and --specials, and -a still implies -D.
|
||||
- Added the --log-file=FILE and --log-file-format=FORMAT options. These
|
||||
can be used to tell any rsync to output what it is doing to a log file.
|
||||
They work with a client rsync, a non-daemon server rsync (see the man
|
||||
page for instructions), and also allows the overriding of rsyncd.conf
|
||||
settings when starting a daemon.
|
||||
|
||||
- Added the --append option that makes rsync append data onto files that
|
||||
are longer on the source than the destination (this includes new files).
|
||||
- The --log-format option was renamed to be --out-format to avoid confusing
|
||||
it with affecting the log-file output. (The old option remains as an
|
||||
alias for the new to preserve backward compatibility.)
|
||||
|
||||
- Added the --min-size=SIZE option to exclude small files from the
|
||||
transfer.
|
||||
- Made "log file" and "syslog facility" settable on a per-module basis in
|
||||
the daemon's config file.
|
||||
|
||||
- Added the --compress-level option to allow you to set how aggressive
|
||||
rsync's compression should be (this option implies --compress).
|
||||
- Added the --remove-source-files option as a replacement for the (now
|
||||
deprecated) --remove-sent-files option. This new option removes all
|
||||
non-dirs from the source directories, even if the file was already
|
||||
up-to-date. This fixes a problem where interrupting an rsync that
|
||||
was using --remove-sent-files and restarting it could leave behind
|
||||
a file that the earlier rsync synchronized, but didn't get to remove.
|
||||
(The deprecated --remove-sent-files is still understood for now, and
|
||||
still behaves in the same way as before.)
|
||||
|
||||
- Enhanced the parsing of the SIZE value for --min-size and --max-size to
|
||||
allow easy entry of multiples of 1000 (instead of just multiples of 1024)
|
||||
and off-by-one values too (e.g. --max-size=8mb-1).
|
||||
- Added the option --no-motd to suppress the message-of-the-day output
|
||||
from a daemon when doing a copy. (See the manpage for a caveat.)
|
||||
|
||||
- Added the --8-bit-output (-8) option, which tells rsync to avoid escaping
|
||||
high-bit characters that it thinks are unreadable in the current locale.
|
||||
|
||||
- The new option --human-readable (-h) changes the output of --progress,
|
||||
--stats, and the end-of-run summary to be easier to read. If repeated,
|
||||
the units become powers of 1024 instead of powers of 1000.
|
||||
|
||||
- If lutimes() and/or lchmod() are around, use them to allow the
|
||||
preservation of attributes on symlinks.
|
||||
|
||||
- The --link-dest option now affects symlinks and devices (when possible).
|
||||
|
||||
- Improved the output of hard-linked and copied files when using
|
||||
--link-dest, --copy-dest, or --compare-dest.
|
||||
|
||||
- Added two config items to the rsyncd.conf parsing: "pre-xfer exec" and
|
||||
"post-xfer exec". These allow a command to be specified on a per-module
|
||||
basis that will be run before and/or after a daemon-mode transfer. (See
|
||||
the manpage for a list of the environment variables that are set with
|
||||
information about the transfer.)
|
||||
|
||||
- When using the --relative option, you can now insert a dot dir in
|
||||
the source path to indicate where the replication of the source dirs
|
||||
should start. For example, if you specify a source path of
|
||||
rsync://host/module/foo/bar/./baz/dir with -R, rsync will now only
|
||||
replicate the "baz/dir" part of the source path (note: a trailing
|
||||
dot dir is unaffected unless it also has a trailing slash).
|
||||
|
||||
- Added some new --no-FOO options that make it easier to override unwanted
|
||||
implied or default options. For example, "-a --no-o" (aka "--archive
|
||||
--no-owner") can be used to turn off the preservation of file ownership
|
||||
that is implied by -a.
|
||||
|
||||
- Added the --chmod=MODE option that allows the destination permissions to
|
||||
be changed from the source permissions. E.g. --chmod=g+w,o-rwx
|
||||
|
||||
- Added the "incoming chmod" and "outgoing chmod" daemon options that allow
|
||||
a module to specify what permissions changes should be applied to all
|
||||
files copied to and from the daemon.
|
||||
|
||||
- Allow the --temp-dir option to be specified when starting a daemon, which
|
||||
sets the default temporary directory for incoming files.
|
||||
|
||||
- If --delete is combined with --dirs without --recursive, rsync will now
|
||||
delete in any directory whose content is being synchronized.
|
||||
|
||||
- If --backup is combined with --delete without --backup-dir (and without
|
||||
--delete-excluded), we add a "protect" filter-rule to ensure that files
|
||||
with the backup suffix are not deleted.
|
||||
|
||||
- The file-count stats that are output by --progress were improved to
|
||||
better indicate what the numbers mean. For instance, the output:
|
||||
"(xfer#5, to-check=8383/9999)" indicates that this was the fifth file
|
||||
to be transferred, and we still need to check 8383 more files out of
|
||||
a total of 9999.
|
||||
|
||||
- The include/exclude code now allows a dir/*** directive (with 3 trailing
|
||||
stars) to match both the dir itself as well as all the content below the
|
||||
dir (dir/** would not match the dir).
|
||||
|
||||
- Added the --prune-empty-dirs (-m) option that makes the receiving rsync
|
||||
discard empty chains of directories from the file-list. This makes it
|
||||
easier to selectively copy files from a source hierarchy and end up with
|
||||
just the directories needed to hold the resulting files.
|
||||
|
||||
- If the --itemize-changes (-i) option is repeated, rsync now includes
|
||||
unchanged files in the itemized output (similar to -vv, but without all
|
||||
the other verbose messages that can get in the way). Of course, the
|
||||
client must be version 2.6.7 for this to work, but the remote rsync only
|
||||
needs to be 2.6.7 if you're pushing files.
|
||||
|
||||
- Added the --super option to make the receiver always attempt super- user
|
||||
activities. This is useful for systems that allow things such as devices
|
||||
to be created or ownership to be set without being UID 0, and is also
|
||||
useful for someone who wants to ensure that errors will be output if the
|
||||
receiving rsync isn't being run as root.
|
||||
|
||||
- Added the --sockopts option for those few who want to customize the TCP
|
||||
options used to contact a daemon rsync.
|
||||
|
||||
- Added a way for the --temp-dir option to be combined with a partial-dir
|
||||
setting that lets rsync avoid non-atomic updates (for those times when
|
||||
--temp-dir is not being used because space is tight).
|
||||
|
||||
- A new support script, files-to-excludes, will transform a list of files
|
||||
into a set of include/exclude directives that will copy those files.
|
||||
|
||||
- A new option, --executability (-E) can be used to preserve just the
|
||||
execute bit on files, for those times when using the --perms option is
|
||||
not desired.
|
||||
|
||||
- The daemon now logs each module-list request it receives.
|
||||
|
||||
- New log-format options: %M (modtime), %U (uid), %G (gid), and %B
|
||||
(permission bits, e.g. "rwxr-xrwt").
|
||||
|
||||
- The --dry-run option no longer forces the enabling of --verbose.
|
||||
|
||||
- Some minor documentation improvements.
|
||||
|
||||
- Updated some diffs in the patches dir.
|
||||
- Added a new environment variable to the pre-/post-xfer exec commands (in
|
||||
the daemon's config file): RSYNC_PID. This value will be the same in
|
||||
both the pre- and post-xfer commands, so it can be used if the pre-xfer
|
||||
command wants to cache some arg/request info for the post-xfer command.
|
||||
|
||||
INTERNAL:
|
||||
|
||||
- We now use sigaction() and sigprocmask() if possible, and fall back on
|
||||
signal() if not. Using sigprocmask() ensures that rsync enables all the
|
||||
signals that it needs, just in case it was started in a masked state.
|
||||
- Did a code audit using IBM's code-checker program and made several
|
||||
changes, including: replacing most of the strcpy() and sprintf()
|
||||
calls with strlcpy(), snprintf(), and memcpy(), adding a 0-value to
|
||||
an enum that had been intermingling a literal 0 with the defined enum
|
||||
values, silencing some uninitialized memory checks, marking some
|
||||
functions with a "noreturn" attribute, and changing an "if" that
|
||||
could never succeed on some platforms into a pre-processor directive
|
||||
that conditionally compiles the code.
|
||||
|
||||
- Some buffer sizes were expanded a bit, particularly on systems where
|
||||
MAXPATHLEN is overly small (e.g. cygwin).
|
||||
- Fixed a potential bug in f_name_cmp() when both the args are a
|
||||
top-level "." dir (which doesn't happen in normal operations).
|
||||
|
||||
- If io_printf() tries to format more data than fits in the buffer, exit
|
||||
with an error instead of transmitting a truncated buffer.
|
||||
- Changed exit_cleanup() so that it can never return instead of exit.
|
||||
The old code might return if it found the exit_cleanup() function
|
||||
was being called recursively. The new code is segmented so that
|
||||
any recursive calls move on to the next step of the exit-processing.
|
||||
|
||||
- If a va_copy macro is defined, lib/snprintf.c will use it when defining
|
||||
the VA_COPY macro.
|
||||
|
||||
- Reduced the amount of stack memory needed for each level of directory
|
||||
recursion by nearly MAXPATHLEN bytes.
|
||||
|
||||
- The wildmatch function was extended to allow an array of strings to be
|
||||
supplied as the string to match. This allows the exclude code to do less
|
||||
string copying.
|
||||
|
||||
- Got rid of the safe_fname() function (and all the myriad calls) and
|
||||
replaced it with a new function in the log.c code that filters all the
|
||||
output going to the terminal.
|
||||
|
||||
- Unified the f_name() and the f_name_to() functions.
|
||||
- The macro WIFEXITED(stat) will now be defined if the OS didn't already
|
||||
define it.
|
||||
|
||||
DEVELOPER RELATED:
|
||||
|
||||
- The diffs in the patches dir now require "patch -p1 <DIFF" instead of
|
||||
the previous -p0. Also, the version included in the release tar now
|
||||
affect generated files (e.g. configure, rsync.1, proto.h, etc.), so
|
||||
it is no longer necessary to run autoconf and/or yodl unless you're
|
||||
applying a patch that was checked out from CVS.
|
||||
- The acls.diff and xattrs.diff patches have received a bunch of work to
|
||||
make them much closer to being acceptable in the main distribution.
|
||||
The xattrs patch also has some preliminary Mac OS X compatibility code
|
||||
that allows Macs and non-macs to exchange extended attributes.
|
||||
|
||||
- Several diffs in the patches dir now use the proper --enable-FOO
|
||||
configure option instead of --with-FOO to turn on the inclusion of
|
||||
the newly patched feature.
|
||||
- A new diff in the patches dir, fake-root.diff, allows rsync to
|
||||
maintain a backup hierarchy with full owner, group, and device info
|
||||
without actually running as root. It does this using a special
|
||||
extended attribute, so it depends on xattrs.diff (which depends on
|
||||
acls.diff).
|
||||
|
||||
- There is a new script, "prepare-source" than can be used to update the
|
||||
various generated files (proto.h, configure, etc.) even before configure
|
||||
has created the Makefile (this is mainly useful when patching the source
|
||||
with a patch that doesn't affect generated files).
|
||||
- The rsync.yo and rsyncd.conf.yo files have been updated to work
|
||||
better with the latest yodl 2.x releases.
|
||||
|
||||
- The testsuite now sets HOME so that it won't be affected by a file such
|
||||
as ~/.popt.
|
||||
- Updated config.guess and config.sub to their 2006-02-23 version.
|
||||
|
||||
- Updated various files to include the latest FSF address and to have
|
||||
consistent opening comments.
|
||||
|
||||
409
OLDNEWS
409
OLDNEWS
@@ -1,3 +1,393 @@
|
||||
NEWS for rsync 2.6.8 (22 Apr 2006)
|
||||
Protocol: 29 (unchanged)
|
||||
Changes since 2.6.7:
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- Fixed a bug in the exclude code where an anchored exclude without any
|
||||
wildcards fails to match an absolute source arg, but only when --relative
|
||||
is in effect.
|
||||
|
||||
- Improved the I/O code for the generator to fix a potential hang when the
|
||||
receiver gets an EOF on the socket but the generator's select() call
|
||||
never indicates that the socket is writable for it to be notified about
|
||||
the EOF. (This can happen when using stunnel).
|
||||
|
||||
- Fixed a problem with the file-reading code where a failed read (such as
|
||||
that caused by a bad sector) would not advance the file's read-position
|
||||
beyond the failed read's data.
|
||||
|
||||
- Fixed a logging bug where the "log file" directive was not being honored
|
||||
in a single-use daemon (one spawned by a remote-shell connection or by
|
||||
init).
|
||||
|
||||
- If rsync cannot honor the --delete option, we output an error and exit
|
||||
instead of silently ignoring the option.
|
||||
|
||||
- Fixed a bug in the --link-dest code that prevented special files (such as
|
||||
fifos) from being linked.
|
||||
|
||||
- The ability to hard-link symlinks and special files is now determined at
|
||||
configure time instead of at runtime. This fixes a bug with --link-dest
|
||||
creating a hard-link to a symlink's referent on a BSD system.
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
- In daemon mode, if rsync fails to bind to the requested port, the
|
||||
error(s) returned by socket() and/or bind() are now logged.
|
||||
|
||||
- When we output a fatal error, we now output the version of rsync in the
|
||||
message.
|
||||
|
||||
- Improved the documentation for the --owner and --group options.
|
||||
|
||||
- The rsyncstats script in "support" has an improved line-parsing regex
|
||||
that is easier to read and also makes it to parse syslog-generated lines.
|
||||
|
||||
- A new script in "support": file-attr-restore, can be used to restore the
|
||||
attributes of a file-set (the permissions, ownership, and group info)
|
||||
taken from the cached output of a "find ARG... -ls" command.
|
||||
|
||||
DEVELOPER RELATED:
|
||||
|
||||
- Removed the unused function write_int_named(), the unused variable
|
||||
io_read_phase, and the rarely used variable io_write_phase. This also
|
||||
elides the confusing 'phase "unknown"' part of one error message.
|
||||
|
||||
- Removed two unused configure checks and two related (also unused)
|
||||
compatibility functions.
|
||||
|
||||
- The xattrs.diff patch received a security fix that prevents a potential
|
||||
buffer overflow in the receive_xattr() code.
|
||||
|
||||
- The acls.diff patch has been improved quite a bit, with more to come.
|
||||
|
||||
- A new patch was added: log-file.diff. This contains an early version of
|
||||
a future option, --log-file=FILE, that will allow any rsync to log its
|
||||
actions to a file (something that only a daemon supports at present).
|
||||
|
||||
|
||||
NEWS for rsync 2.6.7 (11 Mar 2006)
|
||||
Protocol: 29 (unchanged)
|
||||
Changes since 2.6.6:
|
||||
|
||||
OUTPUT CHANGES:
|
||||
|
||||
- The letter 'D' in the itemized output was being used for both devices
|
||||
(character or block) as well as other special files (such as fifos and
|
||||
named sockets). This has changed to separate non-device special files
|
||||
under the 'S' designation (e.g. "cS+++++++ path/fifo"). See also the
|
||||
"--specials" option, below.
|
||||
|
||||
- The way rsync escapes unreadable characters has changed. First, rsync
|
||||
now has support for recognizing valid multibyte character sequences in
|
||||
your current locale, allowing it to escape fewer characters than before
|
||||
for a locale such as UTF-8. Second, it now uses an escape idiom of
|
||||
"\#123", which is the literal string "\#" followed by exactly 3 octal
|
||||
digits. Rsync no longer doubles a backslash character in a filename
|
||||
(e.g. it used to output "foo\\bar" when copying "foo\bar") -- now it only
|
||||
escapes a backslash that is followed by a hash-sign and 3 digits (0-9)
|
||||
(e.g. it will output "foo\#134#789" when copying "foo\#789"). See also
|
||||
the --8-bit-output (-8) option, mentioned below.
|
||||
|
||||
Script writers: the local rsync is the one that outputs escaped names,
|
||||
so if you need to support unescaping of filenames for older rsyncs, I'd
|
||||
suggest that you parse the output of "rsync --version" and only use the
|
||||
old unescaping rules for 2.6.5 and 2.6.6.
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- Fixed a really old bug that caused --checksum (-c) to checksum all the
|
||||
files encountered during the delete scan (ouch).
|
||||
|
||||
- Fixed a potential hang in a remote generator: when the receiver gets a
|
||||
read-error on the socket, it now signals the generator about this so that
|
||||
the generator does not try to send any of the terminating error messages
|
||||
to the client (avoiding a potential hang in some setups).
|
||||
|
||||
- Made hard-links work with symlinks and devices again.
|
||||
|
||||
- If the sender gets an early EOF reading a source file, we propagate this
|
||||
error to the receiver so that it can discard the file and try requesting
|
||||
it again (which is the existing behavior for other kinds of read errors).
|
||||
|
||||
- If a device-file/special-file changes permissions, rsync now updates the
|
||||
permissions without recreating the file.
|
||||
|
||||
- If the user specifies a remote-host for both the source and destination,
|
||||
we now output a syntax error rather than trying to open the destination
|
||||
hostspec as a filename.
|
||||
|
||||
- When --inplace creates a new destination file, rsync now creates it with
|
||||
permissions 0600 instead of 0000 -- this makes restarting possible when
|
||||
the transfer gets interrupted in the middle of sending a new file.
|
||||
|
||||
- Reject the combination of --inplace and --sparse since the sparse-output
|
||||
algorithm doesn't work when overwriting existing data.
|
||||
|
||||
- Fixed the directory name in the error that is output when pop_dir()
|
||||
fails.
|
||||
|
||||
- Really fixed the parsing of a "!" entry in .cvsignore files this time.
|
||||
|
||||
- If the generator gets a stat() error on a file, output it (this used to
|
||||
require at least -vv for the error to be seen).
|
||||
|
||||
- If waitpid() fails or the child rsync didn't exit cleanly, we now handle
|
||||
the exit status properly and generate a better error.
|
||||
|
||||
- Fixed some glitches in the double-verbose output when using --copy-dest,
|
||||
--link-dest, or --compare-dest. Also improved how the verbose output
|
||||
handles hard-links (within the transfer) that had an up-to-date alternate
|
||||
"dest" file, and copied files (via --copy-dest).
|
||||
|
||||
- Fixed the matching of the dont-compress items (e.g. *.gz) against files
|
||||
that have a path component containing a slash.
|
||||
|
||||
- If code reading a filter/exclude file an EINTR error, rsync now clears
|
||||
the error flag on the file handle so it can keep on reading.
|
||||
|
||||
- If --relative is active, the sending side cleans up trailing "/" or "/."
|
||||
suffixes to avoid triggering a bug in older rsync versions. Also, we now
|
||||
reject a ".." dir if it would be sent as a relative dir.
|
||||
|
||||
- If a non-directory is in the way of a directory and rsync is run with
|
||||
--dry-run and --delete, rsync no longer complains about not being able
|
||||
to opendir() the not-yet present directory.
|
||||
|
||||
- When --list-only is used and a non-existent local destination dir was
|
||||
also specified as a destination, rsync no longer generates a warning
|
||||
about being unable to create the missing directory.
|
||||
|
||||
- Fixed some problems with --relative --no-implied-dirs when the
|
||||
destination directory did not yet exist: we can now create a symlink or
|
||||
device when it is the first thing in the missing dir, and --fuzzy no
|
||||
longer complains about being unable to open the missing dir.
|
||||
|
||||
- Fixed a bug where the --copy-links option would not affect implied
|
||||
directories without --copy-unsafe-links (see --relative).
|
||||
|
||||
- Got rid of the need for --force to be used in some circumstances with
|
||||
--delete-after (making it consistent with --delete-before/-during).
|
||||
|
||||
- Rsync now ignores the SIGXFSZ signal, just in case your OS sends this
|
||||
when a file is too large (rsync handles the write error).
|
||||
|
||||
- Fixed a bug in the Proxy-Authorization header's base64-encoded value: it
|
||||
was not properly padded with trailing '=' chars. This only affects a
|
||||
user that need to use a password-authenticated proxy for an outgoing
|
||||
daemon-rsync connection.
|
||||
|
||||
- If we're transferring an empty directory to a new name, rsync no longer
|
||||
forces S_IWUSR if it wasn't already set, nor does it accidentally leave
|
||||
it set.
|
||||
|
||||
- Fixed a bug in the debug output (-vvvvv) that could mention the wrong
|
||||
checksum for the current file offset.
|
||||
|
||||
- Rsync no longer allows a single directory to be copied over a non-
|
||||
directory destination arg.
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
- Added the --append option that makes rsync append data onto files that
|
||||
are longer on the source than the destination (this includes new files).
|
||||
|
||||
- Added the --min-size=SIZE option to exclude small files from the
|
||||
transfer.
|
||||
|
||||
- Added the --compress-level option to allow you to set how aggressive
|
||||
rsync's compression should be (this option implies --compress).
|
||||
|
||||
- Enhanced the parsing of the SIZE value for --min-size and --max-size to
|
||||
allow easy entry of multiples of 1000 (instead of just multiples of 1024)
|
||||
and off-by-one values too (e.g. --max-size=8mb-1).
|
||||
|
||||
- Added the --8-bit-output (-8) option, which tells rsync to avoid escaping
|
||||
high-bit characters that it thinks are unreadable in the current locale.
|
||||
|
||||
- The new option --human-readable (-h) changes the output of --progress,
|
||||
--stats, and the end-of-run summary to be easier to read. If repeated,
|
||||
the units become powers of 1024 instead of powers of 1000. (The old
|
||||
meaning of -h, as a shorthand for --help, still works as long as you
|
||||
just use it on its own, as in "rsync -h".)
|
||||
|
||||
- If lutimes() and/or lchmod() are around, use them to allow the
|
||||
preservation of attributes on symlinks.
|
||||
|
||||
- The --link-dest option now affects symlinks and devices (when possible).
|
||||
|
||||
- Added two config items to the rsyncd.conf parsing: "pre-xfer exec" and
|
||||
"post-xfer exec". These allow a command to be specified on a per-module
|
||||
basis that will be run before and/or after a daemon-mode transfer. (See
|
||||
the man page for a list of the environment variables that are set with
|
||||
information about the transfer.)
|
||||
|
||||
- When using the --relative option, you can now insert a dot dir in
|
||||
the source path to indicate where the replication of the source dirs
|
||||
should start. For example, if you specify a source path of
|
||||
rsync://host/module/foo/bar/./baz/dir with -R, rsync will now only
|
||||
replicate the "baz/dir" part of the source path (note: a trailing
|
||||
dot dir is unaffected unless it also has a trailing slash).
|
||||
|
||||
- Added some new --no-FOO options that make it easier to override unwanted
|
||||
implied or default options. For example, "-a --no-o" (aka "--archive
|
||||
--no-owner") can be used to turn off the preservation of file ownership
|
||||
that is implied by -a.
|
||||
|
||||
- Added the --chmod=MODE option that allows the destination permissions to
|
||||
be changed from the source permissions. E.g. --chmod=g+w,o-rwx
|
||||
|
||||
- Added the "incoming chmod" and "outgoing chmod" daemon options that allow
|
||||
a module to specify what permissions changes should be applied to all
|
||||
files copied to and from the daemon.
|
||||
|
||||
- Allow the --temp-dir option to be specified when starting a daemon, which
|
||||
sets the default temporary directory for incoming files.
|
||||
|
||||
- If --delete is combined with --dirs without --recursive, rsync will now
|
||||
delete in any directory whose content is being synchronized.
|
||||
|
||||
- If --backup is combined with --delete without --backup-dir (and without
|
||||
--delete-excluded), we add a "protect" filter-rule to ensure that files
|
||||
with the backup suffix are not deleted.
|
||||
|
||||
- The file-count stats that are output by --progress were improved to
|
||||
better indicate what the numbers mean. For instance, the output:
|
||||
"(xfer#5, to-check=8383/9999)" indicates that this was the fifth file
|
||||
to be transferred, and we still need to check 8383 more files out of
|
||||
a total of 9999.
|
||||
|
||||
- The include/exclude code now allows a dir/*** directive (with 3 trailing
|
||||
stars) to match both the dir itself as well as all the content below the
|
||||
dir (dir/** would not match the dir).
|
||||
|
||||
- Added the --prune-empty-dirs (-m) option that makes the receiving rsync
|
||||
discard empty chains of directories from the file-list. This makes it
|
||||
easier to selectively copy files from a source hierarchy and end up with
|
||||
just the directories needed to hold the resulting files.
|
||||
|
||||
- If the --itemize-changes (-i) option is repeated, rsync now includes
|
||||
unchanged files in the itemized output (similar to -vv, but without all
|
||||
the other verbose messages that can get in the way). Of course, the
|
||||
client must be version 2.6.7 for this to work, but the remote rsync only
|
||||
needs to be 2.6.7 if you're pushing files.
|
||||
|
||||
- Added the --specials option to tell rsync to copy non-device special
|
||||
files (which rsync now attempts even as a normal user). The --devices
|
||||
option now requests the copying of just devices (character and block).
|
||||
The -D option still requests both (e.g. --devices and --specials), -a
|
||||
still implies -D, and non-root users still get a silent downgrade that
|
||||
omits device copying.
|
||||
|
||||
- Added the --super option to make the receiver always attempt super-user
|
||||
activities. This is useful for systems that allow things such as devices
|
||||
to be created or ownership to be set without being UID 0, and is also
|
||||
useful for someone who wants to ensure that errors will be output if the
|
||||
receiving rsync isn't being run as root.
|
||||
|
||||
- Added the --sockopts option for those few who want to customize the TCP
|
||||
options used to contact a daemon rsync.
|
||||
|
||||
- Added a way for the --temp-dir option to be combined with a partial-dir
|
||||
setting that lets rsync avoid non-atomic updates (for those times when
|
||||
--temp-dir is not being used because space is tight).
|
||||
|
||||
- A new support script, files-to-excludes, will transform a list of files
|
||||
into a set of include/exclude directives that will copy those files.
|
||||
|
||||
- A new option, --executability (-E) can be used to preserve just the
|
||||
execute bit on files, for those times when using the --perms option is
|
||||
not desired.
|
||||
|
||||
- The daemon now logs each connection and also each module-list request
|
||||
that it receives.
|
||||
|
||||
- New log-format options: %M (modtime), %U (uid), %G (gid), and %B
|
||||
(permission bits, e.g. "rwxr-xrwt").
|
||||
|
||||
- The --dry-run option no longer forces the enabling of --verbose.
|
||||
|
||||
- The --remove-sent-files option now does a better job of incrementally
|
||||
removing the sent files on the sending side (older versions tended to
|
||||
clump up all the removals at the end).
|
||||
|
||||
- A daemon now supersedes its minimal SIGCHLD handler with the standard
|
||||
PID-remembering version after forking. This ensures that the generator
|
||||
can get the child-exit status from the receiver.
|
||||
|
||||
- Use of the --bwlimit option no longer interferes with the remote rsync
|
||||
sending error messages about invalid/refused options.
|
||||
|
||||
- Rsync no longer returns a usage error when used with one local source arg
|
||||
and no destination: this now implies the --list-only option, just like
|
||||
the comparable situation with a remote source arg.
|
||||
|
||||
- Added the --copy-dirlinks option, a more limited version of --copy-links.
|
||||
|
||||
- Various documentation improvements, including: a better synopsis, some
|
||||
improved examples, a better discussion of the presence and absence of
|
||||
--perms (including how it interacts with the new --executability and
|
||||
--chmod options), an extended discussion of --temp-dir, an improved
|
||||
discussion of --partial-dir, a better description of rsync's pattern
|
||||
matching characters, an improved --no-implied-dirs section, and the
|
||||
documenting of what the --stats option outputs.
|
||||
|
||||
- Various new and updated diffs in the patches dir, including: acls.diff,
|
||||
xattrs.diff, atimes.diff, detect-renamed.diff, and slp.diff.
|
||||
|
||||
INTERNAL:
|
||||
|
||||
- We now use sigaction() and sigprocmask() if possible, and fall back on
|
||||
signal() if not. Using sigprocmask() ensures that rsync enables all the
|
||||
signals that it needs, just in case it was started in a masked state.
|
||||
|
||||
- Some buffer sizes were expanded a bit, particularly on systems where
|
||||
MAXPATHLEN is overly small (e.g. cygwin).
|
||||
|
||||
- If io_printf() tries to format more data than fits in the buffer, exit
|
||||
with an error instead of transmitting a truncated buffer.
|
||||
|
||||
- If a va_copy macro is defined, lib/snprintf.c will use it when defining
|
||||
the VA_COPY macro.
|
||||
|
||||
- Reduced the amount of stack memory needed for each level of directory
|
||||
recursion by nearly MAXPATHLEN bytes.
|
||||
|
||||
- The wildmatch function was extended to allow an array of strings to be
|
||||
supplied as the string to match. This allows the exclude code to do less
|
||||
string copying.
|
||||
|
||||
- Got rid of the safe_fname() function (and all the myriad calls) and
|
||||
replaced it with a new function in the log.c code that filters all the
|
||||
output going to the terminal.
|
||||
|
||||
- Unified the f_name() and the f_name_to() functions.
|
||||
|
||||
- Improved the hash-table code the sender uses to handle checksums to make
|
||||
it use slightly less memory and run just a little faster.
|
||||
|
||||
DEVELOPER RELATED:
|
||||
|
||||
- The diffs in the patches dir now require "patch -p1 <DIFF" instead of
|
||||
the previous -p0. Also, the version included in the release tar now
|
||||
affect generated files (e.g. configure, rsync.1, proto.h, etc.), so
|
||||
it is no longer necessary to run autoconf and/or yodl unless you're
|
||||
applying a patch that was checked out from CVS.
|
||||
|
||||
- Several diffs in the patches dir now use the proper --enable-FOO
|
||||
configure option instead of --with-FOO to turn on the inclusion of
|
||||
the newly patched feature.
|
||||
|
||||
- There is a new script, "prepare-source" than can be used to update the
|
||||
various generated files (proto.h, configure, etc.) even before configure
|
||||
has created the Makefile (this is mainly useful when patching the source
|
||||
with a patch that doesn't affect generated files).
|
||||
|
||||
- The testsuite now sets HOME so that it won't be affected by a file such
|
||||
as ~/.popt.
|
||||
|
||||
|
||||
NEWS for rsync 2.6.6 (28 Jul 2005)
|
||||
Protocol: 29 (unchanged)
|
||||
Changes since 2.6.5:
|
||||
@@ -359,9 +749,11 @@ Changes since 2.6.3:
|
||||
(since the forked process already has a copy of the exclude list,
|
||||
there's no need to send them a set of duplicates).
|
||||
|
||||
- When --progress is specified, the output of items that the generator
|
||||
is creating (e.g. dirs, symlinks) is now integrated into the progress
|
||||
output without overlapping it. (Requires protocol 29.)
|
||||
- The output of the items that are being updated by the generator (dirs,
|
||||
symlinks, devices) is now intermingled in the proper order with the
|
||||
output from the items that the receiver is updating (regular files)
|
||||
when pulling. This misordering was particularly bad when --progress
|
||||
was specified. (Requires protocol 29.)
|
||||
|
||||
- When --timeout is specified, lulls that occur in the transfer while
|
||||
the generator is doing work that does not generate socket traffic
|
||||
@@ -768,6 +1160,8 @@ Changes since 2.6.2:
|
||||
user chose to combine the output of rsync's stdout and stderr (e.g.
|
||||
using the "2>&1").
|
||||
|
||||
- Fixed an option-parsing bug when --files-from got passed to a daemon.
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
- Added the --partial-dir=DIR option that lets you specify where to
|
||||
@@ -1034,6 +1428,9 @@ Changes since 2.6.0:
|
||||
- Fixed the ability to request an empty backup --suffix when sending
|
||||
files to an rsync daemon.
|
||||
|
||||
- Fixed an option-parsing bug when --files-from was sent to a server
|
||||
sender.
|
||||
|
||||
INTERNAL:
|
||||
|
||||
- Most of the I/O is now buffered, which results in a pretty large
|
||||
@@ -1293,7 +1690,7 @@ Changes since 2.5.5:
|
||||
* The --suffix option can now be used with --backup-dir. (Michael
|
||||
Zimmerman)
|
||||
|
||||
* Combining "::" syntax with the -rsh/-e option now uses the
|
||||
* Combining "::" syntax with the --rsh/-e option now uses the
|
||||
specified remote-shell as a transport to talk to a (newly-spawned)
|
||||
server-daemon. This allows someone to use daemon features, such
|
||||
as modules, over a secure protocol, such as ssh. (JD Paul)
|
||||
@@ -1685,6 +2082,10 @@ Changes since 2.4.6:
|
||||
|
||||
Partial Protocol History
|
||||
RELEASE DATE VER. DATE OF COMMIT* PROTOCOL
|
||||
06 Nov 2006 2.6.9 29
|
||||
22 Apr 2006 2.6.8 29
|
||||
11 Mar 2006 2.6.7 29
|
||||
28 Jul 2005 2.6.6 29
|
||||
01 Jun 2005 2.6.5 29
|
||||
30 Mar 2005 2.6.4 17 Jan 2005 29
|
||||
30 Sep 2004 2.6.3 28
|
||||
|
||||
41
access.c
41
access.c
@@ -1,29 +1,26 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
hosts allow/deny code for rsync
|
||||
|
||||
*/
|
||||
* Routines to authenticate access to a daemon (hosts allow/deny).
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2004, 2005 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
static int match_hostname(char *host, char *tok)
|
||||
{
|
||||
if (!host || !*host)
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
/* -*- c-file-style: "linux"; -*-
|
||||
/*
|
||||
* Support rsync daemon authentication.
|
||||
*
|
||||
* Copyright (C) 1998-2000 Andrew Tridgell
|
||||
* Copyright (C) 2002, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
Copyright (C) 1998-2000 by Andrew Tridgell
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* support rsync authentication */
|
||||
#include "rsync.h"
|
||||
|
||||
extern char *password_file;
|
||||
@@ -26,15 +27,13 @@ extern char *password_file;
|
||||
encode a buffer using base64 - simple and slow algorithm. null terminates
|
||||
the result.
|
||||
***************************************************************************/
|
||||
void base64_encode(char *buf, int len, char *out)
|
||||
void base64_encode(char *buf, int len, char *out, int pad)
|
||||
{
|
||||
char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
int bit_offset, byte_offset, idx, i;
|
||||
unsigned char *d = (unsigned char *)buf;
|
||||
int bytes = (len*8 + 5)/6;
|
||||
|
||||
memset(out, 0, bytes+1);
|
||||
|
||||
for (i = 0; i < bytes; i++) {
|
||||
byte_offset = (i*6)/8;
|
||||
bit_offset = (i*6)%8;
|
||||
@@ -48,6 +47,11 @@ void base64_encode(char *buf, int len, char *out)
|
||||
}
|
||||
out[i] = b64[idx];
|
||||
}
|
||||
|
||||
while (pad && (i % 4))
|
||||
out[i++] = '=';
|
||||
|
||||
out[i] = '\0';
|
||||
}
|
||||
|
||||
/* Generate a challenge buffer and return it base64-encoded. */
|
||||
@@ -69,7 +73,7 @@ static void gen_challenge(char *addr, char *challenge)
|
||||
sum_update(input, sizeof input);
|
||||
sum_end(md4_out);
|
||||
|
||||
base64_encode(md4_out, MD4_SUM_LENGTH, challenge);
|
||||
base64_encode(md4_out, MD4_SUM_LENGTH, challenge, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -208,7 +212,7 @@ static void generate_hash(char *in, char *challenge, char *out)
|
||||
sum_update(challenge, strlen(challenge));
|
||||
sum_end(buf);
|
||||
|
||||
base64_encode(buf, MD4_SUM_LENGTH, out);
|
||||
base64_encode(buf, MD4_SUM_LENGTH, out, 0);
|
||||
}
|
||||
|
||||
/* Possibly negotiate authentication with the client. Use "leader" to
|
||||
|
||||
44
backup.c
44
backup.c
@@ -1,27 +1,27 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1999
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* backup handling code */
|
||||
* Backup handling code.
|
||||
*
|
||||
* Copyright (C) 1999 Andrew Tridgell
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int backup_suffix_len;
|
||||
extern int backup_dir_len;
|
||||
extern unsigned int backup_dir_remainder;
|
||||
extern char backup_dir_buf[MAXPATHLEN];
|
||||
@@ -32,8 +32,6 @@ extern int am_root;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_specials;
|
||||
extern int preserve_links;
|
||||
extern int preserve_hard_links;
|
||||
extern int orig_umask;
|
||||
extern int safe_symlinks;
|
||||
|
||||
/* make a complete pathname for backup file */
|
||||
@@ -112,7 +110,7 @@ static int make_bak_dir(char *fullpath)
|
||||
}
|
||||
if (*p == '/') {
|
||||
*p = '\0';
|
||||
if (do_mkdir(fullpath, 0777 & ~orig_umask) == 0)
|
||||
if (mkdir_defmode(fullpath) == 0)
|
||||
break;
|
||||
if (errno != ENOENT) {
|
||||
rsyserr(FERROR, errno,
|
||||
@@ -141,7 +139,7 @@ static int make_bak_dir(char *fullpath)
|
||||
p += strlen(p);
|
||||
if (p == end)
|
||||
break;
|
||||
if (do_mkdir(fullpath, 0777 & ~orig_umask) < 0) {
|
||||
if (mkdir_defmode(fullpath) < 0) {
|
||||
rsyserr(FERROR, errno, "make_bak_dir mkdir %s failed",
|
||||
full_fname(fullpath));
|
||||
goto failure;
|
||||
|
||||
27
batch.c
27
batch.c
@@ -1,9 +1,24 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Weiss 1/1999
|
||||
Batch utilities for rsync.
|
||||
|
||||
*/
|
||||
/*
|
||||
* Support for the batch-file options.
|
||||
*
|
||||
* Copyright (C) 1999 Weiss
|
||||
* Copyright (C) 2004 Chris Shoemaker
|
||||
* Copyright (C) 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "zlib/zlib.h"
|
||||
|
||||
39
byteorder.h
39
byteorder.h
@@ -1,25 +1,26 @@
|
||||
/*
|
||||
simple byteorder handling
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Simple byteorder handling.
|
||||
*
|
||||
* Copyright (C) 1992-1995 Andrew Tridgell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#undef CAREFUL_ALIGNMENT
|
||||
|
||||
/* we know that the x86 can handle misalignment and has the "right"
|
||||
/* we know that the x86 can handle misalignment and has the "right"
|
||||
byteorder */
|
||||
#ifdef __i386__
|
||||
#define CAREFUL_ALIGNMENT 0
|
||||
|
||||
80
case_N.h
Normal file
80
case_N.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* End-of-run cleanup helper code used by cleanup.c.
|
||||
*
|
||||
* Copyright (C) 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* This is included by cleanup.c multiple times, once for every segement in
|
||||
* the _exit_cleanup() code. This produces the next "case N:" statement in
|
||||
* sequence and increments the cleanup_step variable by 1. This ensures that
|
||||
* our case statements never get out of whack due to added/removed steps. */
|
||||
|
||||
#if !defined EXIT_CLEANUP_CASE_0
|
||||
#define EXIT_CLEANUP_CASE_0
|
||||
case 0:
|
||||
#elif !defined EXIT_CLEANUP_CASE_1
|
||||
#define EXIT_CLEANUP_CASE_1
|
||||
case 1:
|
||||
#elif !defined EXIT_CLEANUP_CASE_2
|
||||
#define EXIT_CLEANUP_CASE_2
|
||||
case 2:
|
||||
#elif !defined EXIT_CLEANUP_CASE_3
|
||||
#define EXIT_CLEANUP_CASE_3
|
||||
case 3:
|
||||
#elif !defined EXIT_CLEANUP_CASE_4
|
||||
#define EXIT_CLEANUP_CASE_4
|
||||
case 4:
|
||||
#elif !defined EXIT_CLEANUP_CASE_5
|
||||
#define EXIT_CLEANUP_CASE_5
|
||||
case 5:
|
||||
#elif !defined EXIT_CLEANUP_CASE_6
|
||||
#define EXIT_CLEANUP_CASE_6
|
||||
case 6:
|
||||
#elif !defined EXIT_CLEANUP_CASE_7
|
||||
#define EXIT_CLEANUP_CASE_7
|
||||
case 7:
|
||||
#elif !defined EXIT_CLEANUP_CASE_8
|
||||
#define EXIT_CLEANUP_CASE_8
|
||||
case 8:
|
||||
#elif !defined EXIT_CLEANUP_CASE_9
|
||||
#define EXIT_CLEANUP_CASE_9
|
||||
case 9:
|
||||
#elif !defined EXIT_CLEANUP_CASE_10
|
||||
#define EXIT_CLEANUP_CASE_10
|
||||
case 10:
|
||||
#elif !defined EXIT_CLEANUP_CASE_11
|
||||
#define EXIT_CLEANUP_CASE_11
|
||||
case 11:
|
||||
#elif !defined EXIT_CLEANUP_CASE_12
|
||||
#define EXIT_CLEANUP_CASE_12
|
||||
case 12:
|
||||
#elif !defined EXIT_CLEANUP_CASE_13
|
||||
#define EXIT_CLEANUP_CASE_13
|
||||
case 13:
|
||||
#elif !defined EXIT_CLEANUP_CASE_14
|
||||
#define EXIT_CLEANUP_CASE_14
|
||||
case 14:
|
||||
#elif !defined EXIT_CLEANUP_CASE_15
|
||||
#define EXIT_CLEANUP_CASE_15
|
||||
case 15:
|
||||
#elif !defined EXIT_CLEANUP_CASE_16
|
||||
#define EXIT_CLEANUP_CASE_16
|
||||
case 16:
|
||||
#else
|
||||
#error Need to add more case statements!
|
||||
#endif
|
||||
cleanup_step++;
|
||||
37
checksum.c
37
checksum.c
@@ -1,21 +1,24 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
* Routines to support checksumming of bytes.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2004, 2005 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
42
chmod.c
42
chmod.c
@@ -1,6 +1,27 @@
|
||||
/*
|
||||
* Implement the core of the --chmod option.
|
||||
*
|
||||
* Copyright (C) 2002 Scott Howard
|
||||
* Copyright (C) 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int orig_umask;
|
||||
extern mode_t orig_umask;
|
||||
|
||||
#define FLAG_X_KEEP (1<<0)
|
||||
#define FLAG_DIRS_ONLY (1<<1)
|
||||
@@ -21,9 +42,10 @@ struct chmod_mode_struct {
|
||||
#define STATE_2ND_HALF 2
|
||||
|
||||
/* Parse a chmod-style argument, and break it down into one or more AND/OR
|
||||
* pairs in a linked list. We use a state machine to walk through the
|
||||
* options. */
|
||||
int parse_chmod(const char *modestr, struct chmod_mode_struct **root_mode_ptr)
|
||||
* pairs in a linked list. We return a pointer to new items on succcess
|
||||
* (appending the items to the specified list), or NULL on error. */
|
||||
struct chmod_mode_struct *parse_chmod(const char *modestr,
|
||||
struct chmod_mode_struct **root_mode_ptr)
|
||||
{
|
||||
int state = STATE_1ST_HALF;
|
||||
int where = 0, what = 0, op = 0, topbits = 0, topoct = 0, flags = 0;
|
||||
@@ -55,15 +77,15 @@ int parse_chmod(const char *modestr, struct chmod_mode_struct **root_mode_ptr)
|
||||
|
||||
switch (op) {
|
||||
case CHMOD_ADD:
|
||||
curr_mode->ModeAND = 07777;
|
||||
curr_mode->ModeAND = CHMOD_BITS;
|
||||
curr_mode->ModeOR = bits + topoct;
|
||||
break;
|
||||
case CHMOD_SUB:
|
||||
curr_mode->ModeAND = 07777 - bits - topoct;
|
||||
curr_mode->ModeAND = CHMOD_BITS - bits - topoct;
|
||||
curr_mode->ModeOR = 0;
|
||||
break;
|
||||
case CHMOD_EQ:
|
||||
curr_mode->ModeAND = 07777 - (where * 7) - (topoct ? topbits : 0);
|
||||
curr_mode->ModeAND = CHMOD_BITS - (where * 7) - (topoct ? topbits : 0);
|
||||
curr_mode->ModeOR = bits + topoct;
|
||||
break;
|
||||
}
|
||||
@@ -153,7 +175,7 @@ int parse_chmod(const char *modestr, struct chmod_mode_struct **root_mode_ptr)
|
||||
|
||||
if (state == STATE_ERROR) {
|
||||
free_chmod_mode(first_mode);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(curr_mode = *root_mode_ptr))
|
||||
@@ -164,7 +186,7 @@ int parse_chmod(const char *modestr, struct chmod_mode_struct **root_mode_ptr)
|
||||
curr_mode->next = first_mode;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return first_mode;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +195,7 @@ int parse_chmod(const char *modestr, struct chmod_mode_struct **root_mode_ptr)
|
||||
int tweak_mode(int mode, struct chmod_mode_struct *chmod_modes)
|
||||
{
|
||||
int IsX = mode & 0111;
|
||||
int NonPerm = mode & ~07777;
|
||||
int NonPerm = mode & ~CHMOD_BITS;
|
||||
|
||||
for ( ; chmod_modes; chmod_modes = chmod_modes->next) {
|
||||
if ((chmod_modes->flags & FLAG_DIRS_ONLY) && !S_ISDIR(NonPerm))
|
||||
|
||||
205
cleanup.c
205
cleanup.c
@@ -1,30 +1,35 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* End-of-run cleanup routines.
|
||||
*
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int io_error;
|
||||
extern int keep_partial;
|
||||
extern int log_got_error;
|
||||
extern char *partial_dir;
|
||||
extern char *logfile_name;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
static struct sigaction sigact;
|
||||
@@ -87,83 +92,117 @@ pid_t cleanup_child_pid = -1;
|
||||
*
|
||||
* @param code one of the RERR_* codes from errcode.h.
|
||||
**/
|
||||
void _exit_cleanup(int code, const char *file, int line)
|
||||
NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
{
|
||||
int ocode = code;
|
||||
static int inside_cleanup = 0;
|
||||
|
||||
if (inside_cleanup > 10) {
|
||||
/* prevent the occasional infinite recursion */
|
||||
return;
|
||||
}
|
||||
inside_cleanup++;
|
||||
static int cleanup_step = 0;
|
||||
static int exit_code = 0;
|
||||
static int unmodified_code = 0;
|
||||
|
||||
SIGACTION(SIGUSR1, SIG_IGN);
|
||||
SIGACTION(SIGUSR2, SIG_IGN);
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
code, file, line);
|
||||
}
|
||||
if (exit_code) /* Preserve first error code when recursing. */
|
||||
code = exit_code;
|
||||
|
||||
if (cleanup_child_pid != -1) {
|
||||
int status;
|
||||
if (wait_process(cleanup_child_pid, &status, WNOHANG)
|
||||
== cleanup_child_pid) {
|
||||
status = WEXITSTATUS(status);
|
||||
if (status > code)
|
||||
code = status;
|
||||
/* Some of our actions might cause a recursive call back here, so we
|
||||
* keep track of where we are in the cleanup and never repeat a step. */
|
||||
switch (cleanup_step) {
|
||||
#include "case_N.h" /* case 0: cleanup_step++; */
|
||||
|
||||
exit_code = unmodified_code = code;
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,
|
||||
"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
code, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
if (cleanup_got_literal && cleanup_fname && keep_partial
|
||||
&& handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
|
||||
char *fname = cleanup_fname;
|
||||
cleanup_fname = NULL;
|
||||
if (cleanup_fd_r != -1)
|
||||
close(cleanup_fd_r);
|
||||
if (cleanup_fd_w != -1) {
|
||||
flush_write_file(cleanup_fd_w);
|
||||
close(cleanup_fd_w);
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
|
||||
if (cleanup_child_pid != -1) {
|
||||
int status;
|
||||
int pid = wait_process(cleanup_child_pid, &status, WNOHANG);
|
||||
if (pid == cleanup_child_pid) {
|
||||
status = WEXITSTATUS(status);
|
||||
if (status > code)
|
||||
code = exit_code = status;
|
||||
}
|
||||
}
|
||||
finish_transfer(cleanup_new_fname, fname, NULL,
|
||||
cleanup_file, 0, !partial_dir);
|
||||
}
|
||||
io_flush(FULL_FLUSH);
|
||||
if (cleanup_fname)
|
||||
do_unlink(cleanup_fname);
|
||||
if (code)
|
||||
kill_all(SIGUSR1);
|
||||
if (cleanup_pid && cleanup_pid == getpid()) {
|
||||
char *pidf = lp_pid_file();
|
||||
if (pidf && *pidf)
|
||||
unlink(lp_pid_file());
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
|
||||
if (cleanup_got_literal && cleanup_fname && cleanup_new_fname
|
||||
&& keep_partial && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
|
||||
char *fname = cleanup_fname;
|
||||
cleanup_fname = NULL;
|
||||
if (cleanup_fd_r != -1)
|
||||
close(cleanup_fd_r);
|
||||
if (cleanup_fd_w != -1) {
|
||||
flush_write_file(cleanup_fd_w);
|
||||
close(cleanup_fd_w);
|
||||
}
|
||||
finish_transfer(cleanup_new_fname, fname, NULL,
|
||||
cleanup_file, 0, !partial_dir);
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
|
||||
io_flush(FULL_FLUSH);
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
|
||||
if (cleanup_fname)
|
||||
do_unlink(cleanup_fname);
|
||||
if (code)
|
||||
kill_all(SIGUSR1);
|
||||
if (cleanup_pid && cleanup_pid == getpid()) {
|
||||
char *pidf = lp_pid_file();
|
||||
if (pidf && *pidf)
|
||||
unlink(lp_pid_file());
|
||||
}
|
||||
|
||||
if (code == 0) {
|
||||
if (io_error & IOERR_DEL_LIMIT)
|
||||
code = exit_code = RERR_DEL_LIMIT;
|
||||
if (io_error & IOERR_VANISHED)
|
||||
code = exit_code = RERR_VANISHED;
|
||||
if (io_error & IOERR_GENERAL || log_got_error)
|
||||
code = exit_code = RERR_PARTIAL;
|
||||
}
|
||||
|
||||
if (code || am_daemon || (logfile_name && (am_server || !verbose)))
|
||||
log_exit(code, file, line);
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO,
|
||||
"_exit_cleanup(code=%d, file=%s, line=%d): "
|
||||
"about to call exit(%d)\n",
|
||||
unmodified_code, file, line, code);
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
|
||||
close_all();
|
||||
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (code == 0) {
|
||||
if (io_error & IOERR_DEL_LIMIT)
|
||||
code = RERR_DEL_LIMIT;
|
||||
if (io_error & IOERR_VANISHED)
|
||||
code = RERR_VANISHED;
|
||||
if (io_error & IOERR_GENERAL || log_got_error)
|
||||
code = RERR_PARTIAL;
|
||||
}
|
||||
|
||||
if (code)
|
||||
log_exit(code, file, line);
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n",
|
||||
ocode, file, line, code);
|
||||
}
|
||||
|
||||
close_all();
|
||||
exit(code);
|
||||
}
|
||||
|
||||
void cleanup_disable(void)
|
||||
{
|
||||
cleanup_fname = NULL;
|
||||
cleanup_fname = cleanup_new_fname = NULL;
|
||||
cleanup_got_literal = 0;
|
||||
}
|
||||
|
||||
@@ -171,8 +210,8 @@ void cleanup_disable(void)
|
||||
void cleanup_set(char *fnametmp, char *fname, struct file_struct *file,
|
||||
int fd_r, int fd_w)
|
||||
{
|
||||
cleanup_fname = fname ? fnametmp : NULL;
|
||||
cleanup_new_fname = fname;
|
||||
cleanup_fname = fnametmp;
|
||||
cleanup_new_fname = fname; /* can be NULL on a partial-dir failure */
|
||||
cleanup_file = file;
|
||||
cleanup_fd_r = fd_r;
|
||||
cleanup_fd_w = fd_w;
|
||||
|
||||
75
clientname.c
75
clientname.c
@@ -1,40 +1,35 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
rsync -- fast file replication program
|
||||
|
||||
Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file clientname.c
|
||||
*
|
||||
/*
|
||||
* Functions for looking up the remote name or addr of a socket.
|
||||
*
|
||||
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2002, 2003, 2004 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is now converted to use the new-style getaddrinfo()
|
||||
* interface, which supports IPv6 but is also supported on recent
|
||||
* IPv4-only machines. On systems that don't have that interface, we
|
||||
* emulate it using the KAME implementation.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
static const char default_name[] = "UNKNOWN";
|
||||
extern int am_daemon;
|
||||
extern int am_server;
|
||||
|
||||
|
||||
@@ -55,7 +50,7 @@ char *client_addr(int fd)
|
||||
initialised = 1;
|
||||
|
||||
if (am_server) { /* daemon over --rsh mode */
|
||||
strcpy(addr_buf, "0.0.0.0");
|
||||
strlcpy(addr_buf, "0.0.0.0", sizeof addr_buf);
|
||||
if ((ssh_info = getenv("SSH_CONNECTION")) != NULL
|
||||
|| (ssh_info = getenv("SSH_CLIENT")) != NULL
|
||||
|| (ssh_info = getenv("SSH2_CLIENT")) != NULL) {
|
||||
@@ -104,7 +99,7 @@ char *client_name(int fd)
|
||||
if (initialised)
|
||||
return name_buf;
|
||||
|
||||
strcpy(name_buf, default_name);
|
||||
strlcpy(name_buf, default_name, sizeof name_buf);
|
||||
initialised = 1;
|
||||
|
||||
memset(&ss, 0, sizeof ss);
|
||||
@@ -138,6 +133,8 @@ char *client_name(int fd)
|
||||
memcpy(&ss, answer->ai_addr, ss_len);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
freeaddrinfo(answer);
|
||||
} else {
|
||||
@@ -147,7 +144,7 @@ char *client_name(int fd)
|
||||
|
||||
if (lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf,
|
||||
port_buf, sizeof port_buf) == 0)
|
||||
check_name(fd, &ss, name_buf);
|
||||
check_name(fd, &ss, name_buf, sizeof name_buf);
|
||||
|
||||
return name_buf;
|
||||
}
|
||||
@@ -211,18 +208,18 @@ void client_sockaddr(int fd,
|
||||
**/
|
||||
int lookup_name(int fd, const struct sockaddr_storage *ss,
|
||||
socklen_t ss_len,
|
||||
char *name_buf, size_t name_buf_len,
|
||||
char *port_buf, size_t port_buf_len)
|
||||
char *name_buf, size_t name_buf_size,
|
||||
char *port_buf, size_t port_buf_size)
|
||||
{
|
||||
int name_err;
|
||||
|
||||
/* reverse lookup */
|
||||
name_err = getnameinfo((struct sockaddr *) ss, ss_len,
|
||||
name_buf, name_buf_len,
|
||||
port_buf, port_buf_len,
|
||||
name_buf, name_buf_size,
|
||||
port_buf, port_buf_size,
|
||||
NI_NAMEREQD | NI_NUMERICSERV);
|
||||
if (name_err != 0) {
|
||||
strcpy(name_buf, default_name);
|
||||
strlcpy(name_buf, default_name, name_buf_size);
|
||||
rprintf(FLOG, "name lookup failed for %s: %s\n",
|
||||
client_addr(fd), gai_strerror(name_err));
|
||||
return name_err;
|
||||
@@ -303,7 +300,7 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
|
||||
**/
|
||||
int check_name(int fd,
|
||||
const struct sockaddr_storage *ss,
|
||||
char *name_buf)
|
||||
char *name_buf, size_t name_buf_size)
|
||||
{
|
||||
struct addrinfo hints, *res, *res0;
|
||||
int error;
|
||||
@@ -317,7 +314,7 @@ int check_name(int fd,
|
||||
if (error) {
|
||||
rprintf(FLOG, "forward name lookup for %s failed: %s\n",
|
||||
name_buf, gai_strerror(error));
|
||||
strcpy(name_buf, default_name);
|
||||
strlcpy(name_buf, default_name, name_buf_size);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -333,13 +330,13 @@ int check_name(int fd,
|
||||
* address that was the same as ss. */
|
||||
rprintf(FLOG, "no known address for \"%s\": "
|
||||
"spoofed address?\n", name_buf);
|
||||
strcpy(name_buf, default_name);
|
||||
strlcpy(name_buf, default_name, name_buf_size);
|
||||
} else if (res == NULL) {
|
||||
/* We hit the end of the list without finding an
|
||||
* address that was the same as ss. */
|
||||
rprintf(FLOG, "%s is not a known address for \"%s\": "
|
||||
"spoofed address?\n", client_addr(fd), name_buf);
|
||||
strcpy(name_buf, default_name);
|
||||
strlcpy(name_buf, default_name, name_buf_size);
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
|
||||
117
clientserver.c
117
clientserver.c
@@ -1,7 +1,9 @@
|
||||
/* -*- c-file-style: "linux"; -*-
|
||||
/*
|
||||
* The socket based protocol for setting up a connection with rsyncd.
|
||||
*
|
||||
* Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001-2002 by Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001-2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2002, 2003, 2004, 2005, 2006 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
|
||||
@@ -13,22 +15,16 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* The socket based protocol for setting up a connection with
|
||||
* rsyncd.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int quiet;
|
||||
extern int output_motd;
|
||||
extern int list_only;
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
@@ -42,12 +38,15 @@ extern int filesfrom_fd;
|
||||
extern int remote_protocol;
|
||||
extern int protocol_version;
|
||||
extern int io_timeout;
|
||||
extern int orig_umask;
|
||||
extern int no_detach;
|
||||
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 *sockopts;
|
||||
extern char *config_file;
|
||||
extern char *logfile_format;
|
||||
extern char *files_from;
|
||||
extern char *tmpdir;
|
||||
extern struct chmod_mode_struct *chmod_modes;
|
||||
@@ -55,13 +54,16 @@ extern struct filter_list_struct server_filter_list;
|
||||
|
||||
char *auth_user;
|
||||
int read_only = 0;
|
||||
int daemon_log_format_has_i = 0;
|
||||
int daemon_log_format_has_o_or_i = 0;
|
||||
int module_id = -1;
|
||||
struct chmod_mode_struct *daemon_chmod_modes;
|
||||
|
||||
/* Length of lp_path() string when in daemon mode & not chrooted, else 0. */
|
||||
unsigned int module_dirlen = 0;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
static struct sigaction sigact;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Run a client connected to an rsyncd. The alternative to this
|
||||
* function for remote-shell connections is do_cmd().
|
||||
@@ -108,7 +110,7 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
return ret ? ret : client_run(fd, fd, -1, argc, argv);
|
||||
}
|
||||
|
||||
int start_inband_exchange(char *user, char *path, int f_in, int f_out,
|
||||
int start_inband_exchange(char *user, char *path, int f_in, int f_out,
|
||||
int argc)
|
||||
{
|
||||
int i;
|
||||
@@ -204,7 +206,10 @@ int start_inband_exchange(char *user, char *path, int f_in, int f_out,
|
||||
return -1;
|
||||
}
|
||||
|
||||
rprintf(FINFO, "%s\n", line);
|
||||
/* This might be a MOTD line or a module listing, but there is
|
||||
* no way to differentiate it. The manpage mentions this. */
|
||||
if (output_motd)
|
||||
rprintf(FINFO, "%s\n", line);
|
||||
}
|
||||
kluge_around_eof = 0;
|
||||
|
||||
@@ -263,7 +268,7 @@ static int read_arg_from_pipe(int fd, char *buf, int limit)
|
||||
return bp - buf;
|
||||
}
|
||||
|
||||
static int rsync_module(int f_in, int f_out, int i)
|
||||
static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
|
||||
{
|
||||
int argc = 0;
|
||||
int maxargs;
|
||||
@@ -272,8 +277,6 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
uid_t uid = (uid_t)-2; /* canonically "nobody" */
|
||||
gid_t gid = (gid_t)-2;
|
||||
char *p, *err_msg = NULL;
|
||||
char *addr = client_addr(f_in);
|
||||
char *host = client_name(f_in);
|
||||
char *name = lp_name(i);
|
||||
int use_chroot = lp_use_chroot(i);
|
||||
int start_glob = 0;
|
||||
@@ -325,13 +328,12 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
if (lp_read_only(i))
|
||||
read_only = 1;
|
||||
|
||||
if (lp_transfer_logging(i)) {
|
||||
if (log_format_has(lp_log_format(i), 'i'))
|
||||
daemon_log_format_has_i = 1;
|
||||
if (daemon_log_format_has_i
|
||||
|| log_format_has(lp_log_format(i), 'o'))
|
||||
daemon_log_format_has_o_or_i = 1;
|
||||
}
|
||||
if (lp_transfer_logging(i) && !logfile_format)
|
||||
logfile_format = lp_log_format(i);
|
||||
if (log_format_has(logfile_format, 'i'))
|
||||
logfile_format_has_i = 1;
|
||||
if (logfile_format_has_i || log_format_has(logfile_format, 'o'))
|
||||
logfile_format_has_o_or_i = 1;
|
||||
|
||||
am_root = (MY_UID() == 0);
|
||||
|
||||
@@ -391,7 +393,7 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
parse_rule(&server_filter_list, p, MATCHFLG_WORD_SPLIT,
|
||||
XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES);
|
||||
|
||||
log_init();
|
||||
log_init(1);
|
||||
|
||||
#ifdef HAVE_PUTENV
|
||||
if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
|
||||
@@ -420,17 +422,18 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
return -1;
|
||||
}
|
||||
if (pid) {
|
||||
char *ret1, *ret2;
|
||||
if (asprintf(&p, "RSYNC_PID=%ld", (long)pid) > 0)
|
||||
putenv(p);
|
||||
if (wait_process(pid, &status, 0) < 0)
|
||||
status = -1;
|
||||
if (asprintf(&ret1, "RSYNC_RAW_STATUS=%d", status) > 0)
|
||||
putenv(ret1);
|
||||
if (asprintf(&p, "RSYNC_RAW_STATUS=%d", status) > 0)
|
||||
putenv(p);
|
||||
if (WIFEXITED(status))
|
||||
status = WEXITSTATUS(status);
|
||||
else
|
||||
status = -1;
|
||||
if (asprintf(&ret2, "RSYNC_EXIT_STATUS=%d", status) > 0)
|
||||
putenv(ret2);
|
||||
if (asprintf(&p, "RSYNC_EXIT_STATUS=%d", status) > 0)
|
||||
putenv(p);
|
||||
system(lp_postxfer_exec(i));
|
||||
_exit(status);
|
||||
}
|
||||
@@ -440,6 +443,8 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
* send us the user's request via a pipe. */
|
||||
if (*lp_prexfer_exec(i)) {
|
||||
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");
|
||||
@@ -453,9 +458,8 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
len = read_arg_from_pipe(fds[0], buf, BIGPATHBUFLEN);
|
||||
if (len <= 0)
|
||||
_exit(1);
|
||||
if (asprintf(&p, "RSYNC_REQUEST=%s", buf) < 0)
|
||||
out_of_memory("rsync_module");
|
||||
putenv(p);
|
||||
if (asprintf(&p, "RSYNC_REQUEST=%s", buf) > 0)
|
||||
putenv(p);
|
||||
for (j = 0; ; j++) {
|
||||
len = read_arg_from_pipe(fds[0], buf,
|
||||
BIGPATHBUFLEN);
|
||||
@@ -464,9 +468,8 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
break;
|
||||
_exit(1);
|
||||
}
|
||||
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) < 0)
|
||||
out_of_memory("rsync_module");
|
||||
putenv(p);
|
||||
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) > 0)
|
||||
putenv(p);
|
||||
}
|
||||
close(fds[0]);
|
||||
close(STDIN_FILENO);
|
||||
@@ -504,7 +507,7 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!push_dir("/")) {
|
||||
if (!push_dir("/", 0)) {
|
||||
rsyserr(FLOG, errno, "chdir %s failed\n",
|
||||
lp_path(i));
|
||||
io_printf(f_out, "@ERROR: chdir failed\n");
|
||||
@@ -512,7 +515,7 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!push_dir(lp_path(i))) {
|
||||
if (!push_dir(lp_path(i), 0)) {
|
||||
rsyserr(FLOG, errno, "chdir %s failed\n",
|
||||
lp_path(i));
|
||||
io_printf(f_out, "@ERROR: chdir failed\n");
|
||||
@@ -685,12 +688,15 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
if (lp_timeout(i) && lp_timeout(i) > io_timeout)
|
||||
set_io_timeout(lp_timeout(i));
|
||||
|
||||
|
||||
/* If we have some incoming/outgoing chmod changes, append them to
|
||||
* any user-specified changes (making our changes have priority).
|
||||
* We also get a pointer to just our changes so that a receiver
|
||||
* process can use them separately if --perms wasn't specified. */
|
||||
if (am_sender)
|
||||
p = lp_outgoing_chmod(i);
|
||||
else
|
||||
p = lp_incoming_chmod(i);
|
||||
if (*p && !parse_chmod(p, &chmod_modes)) {
|
||||
if (*p && !(daemon_chmod_modes = parse_chmod(p, &chmod_modes))) {
|
||||
rprintf(FLOG, "Invalid \"%sing chmod\" directive: %s\n",
|
||||
am_sender ? "outgo" : "incom", p);
|
||||
}
|
||||
@@ -722,15 +728,21 @@ static void send_listing(int fd)
|
||||
int start_daemon(int f_in, int f_out)
|
||||
{
|
||||
char line[1024];
|
||||
char *motd;
|
||||
char *motd, *addr, *host;
|
||||
int i;
|
||||
|
||||
io_set_sock_fds(f_in, f_out);
|
||||
|
||||
/* We must load the config file before calling any function that
|
||||
* might cause log-file output to occur. This ensures that the
|
||||
* "log file" param gets honored for the 2 non-forked use-cases
|
||||
* (when rsync is run by init and run by a remote shell). */
|
||||
if (!lp_load(config_file, 0))
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
|
||||
log_init();
|
||||
addr = client_addr(f_in);
|
||||
host = client_name(f_in);
|
||||
rprintf(FLOG, "connect from %s (%s)\n", host, addr);
|
||||
|
||||
if (!am_server) {
|
||||
set_socket_options(f_in, "SO_KEEPALIVE");
|
||||
@@ -773,8 +785,6 @@ int start_daemon(int f_in, int f_out)
|
||||
return -1;
|
||||
|
||||
if (!*line || strcmp(line, "#list") == 0) {
|
||||
char *addr = client_addr(f_in);
|
||||
char *host = client_name(f_in);
|
||||
rprintf(FLOG, "module-list request from %s (%s)\n",
|
||||
host, addr);
|
||||
send_listing(f_out);
|
||||
@@ -788,15 +798,18 @@ int start_daemon(int f_in, int f_out)
|
||||
}
|
||||
|
||||
if ((i = lp_number(line)) < 0) {
|
||||
char *addr = client_addr(f_in);
|
||||
char *host = client_name(f_in);
|
||||
rprintf(FLOG, "unknown module '%s' tried from %s (%s)\n",
|
||||
line, host, addr);
|
||||
io_printf(f_out, "@ERROR: Unknown module '%s'\n", line);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rsync_module(f_in, f_out, i);
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigact.sa_flags = SA_NOCLDSTOP;
|
||||
#endif
|
||||
SIGACTION(SIGCHLD, remember_children);
|
||||
|
||||
return rsync_module(f_in, f_out, i, addr, host);
|
||||
}
|
||||
|
||||
int daemon_main(void)
|
||||
@@ -828,7 +841,7 @@ int daemon_main(void)
|
||||
if (bind_address == NULL && *lp_bind_address())
|
||||
bind_address = lp_bind_address();
|
||||
|
||||
log_init();
|
||||
log_init(0);
|
||||
|
||||
rprintf(FLOG, "rsyncd version %s starting, listening on port %d\n",
|
||||
RSYNC_VERSION, rsync_port);
|
||||
|
||||
44
compat.c
44
compat.c
@@ -1,27 +1,24 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file compat.c
|
||||
*
|
||||
/*
|
||||
* Compatibility routines for older rsync protocol versions.
|
||||
**/
|
||||
*
|
||||
* Copyright (C) Andrew Tridgell 1996
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -29,7 +26,6 @@ int remote_protocol = 0;
|
||||
|
||||
extern int verbose;
|
||||
extern int am_server;
|
||||
extern int am_sender;
|
||||
extern int inplace;
|
||||
extern int fuzzy_basis;
|
||||
extern int read_batch;
|
||||
|
||||
650
config.guess
vendored
650
config.guess
vendored
File diff suppressed because it is too large
Load Diff
206
config.sub
vendored
206
config.sub
vendored
@@ -1,9 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2003-08-18'
|
||||
timestamp='2006-07-02'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -21,14 +22,15 @@ timestamp='2003-08-18'
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
@@ -70,7 +72,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
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
|
||||
@@ -83,11 +85,11 @@ Try \`$me --help' for more information."
|
||||
while test $# -gt 0 ; do
|
||||
case $1 in
|
||||
--time-stamp | --time* | -t )
|
||||
echo "$timestamp" ; exit 0 ;;
|
||||
echo "$timestamp" ; exit ;;
|
||||
--version | -v )
|
||||
echo "$version" ; exit 0 ;;
|
||||
echo "$version" ; exit ;;
|
||||
--help | --h* | -h )
|
||||
echo "$usage"; exit 0 ;;
|
||||
echo "$usage"; exit ;;
|
||||
-- ) # Stop option processing
|
||||
shift; break ;;
|
||||
- ) # Use stdin as input.
|
||||
@@ -99,7 +101,7 @@ while test $# -gt 0 ; do
|
||||
*local*)
|
||||
# First pass through any local machine types.
|
||||
echo $1
|
||||
exit 0;;
|
||||
exit ;;
|
||||
|
||||
* )
|
||||
break ;;
|
||||
@@ -118,7 +120,9 @@ 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-dietlibc | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
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/'`
|
||||
;;
|
||||
@@ -144,7 +148,7 @@ 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)
|
||||
-apple | -axis | -knuth | -cray)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
@@ -169,6 +173,10 @@ case $os in
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
-sco6)
|
||||
os=-sco5v6
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco5)
|
||||
os=-sco3.2v5
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
@@ -185,6 +193,10 @@ case $os in
|
||||
# Don't forget version if it is 3.2v4 or newer.
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco5v6*)
|
||||
# Don't forget version if it is 3.2v4 or newer.
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco*)
|
||||
os=-sco3.2v2
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
@@ -229,14 +241,16 @@ case $basic_machine in
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| am33_2.0 \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| m32r | m68000 | m68k | m88k | mcore \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@@ -245,6 +259,7 @@ case $basic_machine in
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
| mips64vr5900 | mips64vr5900el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
@@ -253,20 +268,23 @@ case $basic_machine in
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nios | nios2 \
|
||||
| ns16k | ns32k \
|
||||
| openrisc | or32 \
|
||||
| or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| sh | sh[1234] | sh[23]e | sh[34]eb | 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 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
||||
| strongarm \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
| spu | strongarm \
|
||||
| tahoe | thumb | tic4x | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| we32k \
|
||||
| x86 | xscale | xstormy16 | xtensa \
|
||||
| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
@@ -277,6 +295,9 @@ case $basic_machine in
|
||||
;;
|
||||
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
|
||||
;;
|
||||
ms1)
|
||||
basic_machine=mt-unknown
|
||||
;;
|
||||
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
@@ -296,10 +317,10 @@ case $basic_machine in
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* \
|
||||
| bs2000-* \
|
||||
| avr-* | avr32-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||
| clipper-* | cydra-* \
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
@@ -307,9 +328,9 @@ case $basic_machine in
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| m32r-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | mcore-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
@@ -318,6 +339,7 @@ case $basic_machine in
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
| mips64vr5900-* | mips64vr5900el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
@@ -325,24 +347,28 @@ case $basic_machine in
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| mmix-* \
|
||||
| mt-* \
|
||||
| msp430-* \
|
||||
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
|
||||
| nios-* | nios2-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
|
||||
| xtensa-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| xstormy16-* | xtensa-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
;;
|
||||
@@ -362,6 +388,9 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
basic_machine=m68010-adobe
|
||||
os=-scout
|
||||
@@ -379,6 +408,9 @@ case $basic_machine in
|
||||
amd64)
|
||||
basic_machine=x86_64-pc
|
||||
;;
|
||||
amd64-*)
|
||||
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
amdahl)
|
||||
basic_machine=580-amdahl
|
||||
os=-sysv
|
||||
@@ -438,12 +470,27 @@ case $basic_machine in
|
||||
basic_machine=j90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
craynv)
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16c)
|
||||
basic_machine=cr16c-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
basic_machine=m68k-crds
|
||||
;;
|
||||
crisv32 | crisv32-* | etraxfs*)
|
||||
basic_machine=crisv32-axis
|
||||
;;
|
||||
cris | cris-* | etrax*)
|
||||
basic_machine=cris-axis
|
||||
;;
|
||||
crx)
|
||||
basic_machine=crx-unknown
|
||||
os=-elf
|
||||
;;
|
||||
da30 | da30-*)
|
||||
basic_machine=m68k-da30
|
||||
;;
|
||||
@@ -466,6 +513,10 @@ case $basic_machine in
|
||||
basic_machine=m88k-motorola
|
||||
os=-sysv3
|
||||
;;
|
||||
djgpp)
|
||||
basic_machine=i586-pc
|
||||
os=-msdosdjgpp
|
||||
;;
|
||||
dpx20 | dpx20-*)
|
||||
basic_machine=rs6000-bull
|
||||
os=-bosx
|
||||
@@ -644,10 +695,6 @@ case $basic_machine in
|
||||
mips3*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||
;;
|
||||
mmix*)
|
||||
basic_machine=mmix-knuth
|
||||
os=-mmixware
|
||||
;;
|
||||
monitor)
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
@@ -660,6 +707,9 @@ case $basic_machine in
|
||||
basic_machine=i386-pc
|
||||
os=-msdos
|
||||
;;
|
||||
ms1-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||
;;
|
||||
mvs)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
@@ -728,10 +778,6 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
nv1)
|
||||
basic_machine=nv1-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@@ -739,9 +785,12 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
;;
|
||||
or32 | or32-*)
|
||||
openrisc | openrisc-*)
|
||||
basic_machine=or32-unknown
|
||||
os=-coff
|
||||
;;
|
||||
os400)
|
||||
basic_machine=powerpc-ibm
|
||||
os=-os400
|
||||
;;
|
||||
OSE68000 | ose68000)
|
||||
basic_machine=m68000-ericsson
|
||||
@@ -768,6 +817,12 @@ case $basic_machine in
|
||||
pc532 | pc532-*)
|
||||
basic_machine=ns32k-pc532
|
||||
;;
|
||||
pc98)
|
||||
basic_machine=i386-pc
|
||||
;;
|
||||
pc98-*)
|
||||
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentium | p5 | k5 | k6 | nexgen | viac3)
|
||||
basic_machine=i586-pc
|
||||
;;
|
||||
@@ -824,6 +879,10 @@ case $basic_machine in
|
||||
basic_machine=i586-unknown
|
||||
os=-pw32
|
||||
;;
|
||||
rdos)
|
||||
basic_machine=i386-pc
|
||||
os=-rdos
|
||||
;;
|
||||
rom68k)
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
@@ -963,6 +1022,10 @@ case $basic_machine in
|
||||
tower | tower-32)
|
||||
basic_machine=m68k-ncr
|
||||
;;
|
||||
tpf)
|
||||
basic_machine=s390x-ibm
|
||||
os=-tpf
|
||||
;;
|
||||
udi29k)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
@@ -1006,6 +1069,10 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-winbond
|
||||
os=-proelf
|
||||
;;
|
||||
xbox)
|
||||
basic_machine=i686-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
@@ -1036,6 +1103,9 @@ case $basic_machine in
|
||||
romp)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
mmix)
|
||||
basic_machine=mmix-knuth
|
||||
;;
|
||||
rs6000)
|
||||
basic_machine=rs6000-ibm
|
||||
;;
|
||||
@@ -1052,13 +1122,10 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh3 | sh4 | 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
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
sparc | sparcv9 | sparcv9b)
|
||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
@@ -1131,19 +1198,23 @@ case $os in
|
||||
| -aos* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
|
||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -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* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1161,7 +1232,7 @@ case $os in
|
||||
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
||||
;;
|
||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
|
||||
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
|
||||
;;
|
||||
-mac*)
|
||||
@@ -1182,6 +1253,9 @@ case $os in
|
||||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-os400*)
|
||||
os=-os400
|
||||
;;
|
||||
-wince*)
|
||||
os=-wince
|
||||
;;
|
||||
@@ -1203,6 +1277,9 @@ case $os in
|
||||
-atheos*)
|
||||
os=-atheos
|
||||
;;
|
||||
-syllable*)
|
||||
os=-syllable
|
||||
;;
|
||||
-386bsd)
|
||||
os=-bsd
|
||||
;;
|
||||
@@ -1225,6 +1302,9 @@ case $os in
|
||||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-tpf*)
|
||||
os=-tpf
|
||||
;;
|
||||
-triton*)
|
||||
os=-sysv3
|
||||
;;
|
||||
@@ -1261,6 +1341,9 @@ case $os in
|
||||
-kaos*)
|
||||
os=-kaos
|
||||
;;
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@@ -1283,6 +1366,9 @@ else
|
||||
# system, and we'll never get to this point.
|
||||
|
||||
case $basic_machine in
|
||||
spu-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-acorn)
|
||||
os=-riscix1.2
|
||||
;;
|
||||
@@ -1292,9 +1378,9 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
os=-tops20
|
||||
@@ -1338,9 +1424,15 @@ case $basic_machine in
|
||||
*-be)
|
||||
os=-beos
|
||||
;;
|
||||
*-haiku)
|
||||
os=-haiku
|
||||
;;
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-knuth)
|
||||
os=-mmixware
|
||||
;;
|
||||
*-wec)
|
||||
os=-proelf
|
||||
;;
|
||||
@@ -1473,9 +1565,15 @@ case $basic_machine in
|
||||
-mvs* | -opened*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-os400*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-ptx*)
|
||||
vendor=sequent
|
||||
;;
|
||||
-tpf*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-vxsim* | -vxworks* | -windiss*)
|
||||
vendor=wrs
|
||||
;;
|
||||
@@ -1500,7 +1598,7 @@ case $basic_machine in
|
||||
esac
|
||||
|
||||
echo $basic_machine$os
|
||||
exit 0
|
||||
exit
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
|
||||
129
configure.in
129
configure.in
@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PREREQ(2.59)
|
||||
|
||||
RSYNC_VERSION=2.6.7pre1
|
||||
RSYNC_VERSION=2.6.9
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
|
||||
|
||||
@@ -123,15 +123,23 @@ else
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
|
||||
|
||||
AC_MSG_CHECKING([the group for user "nobody"])
|
||||
if grep '^nobody:' /etc/group >/dev/null 2>&1; then
|
||||
NOBODY_GROUP=nobody
|
||||
elif grep '^nogroup:' /etc/group >/dev/null 2>&1; then
|
||||
NOBODY_GROUP=nogroup
|
||||
else
|
||||
NOBODY_GROUP=nobody # test for others?
|
||||
AC_ARG_WITH(nobody-group,
|
||||
AC_HELP_STRING([--with-nobody-group=GROUP],
|
||||
[set the default unprivileged group (default nobody or nogroup)]),
|
||||
[ NOBODY_GROUP="$with_nobody_group" ])
|
||||
|
||||
if test x"$with_nobody_group" = x; then
|
||||
AC_MSG_CHECKING([the group for user "nobody"])
|
||||
if grep '^nobody:' /etc/group >/dev/null 2>&1; then
|
||||
NOBODY_GROUP=nobody
|
||||
elif grep '^nogroup:' /etc/group >/dev/null 2>&1; then
|
||||
NOBODY_GROUP=nogroup
|
||||
else
|
||||
NOBODY_GROUP=nobody # test for others?
|
||||
fi
|
||||
AC_MSG_RESULT($NOBODY_GROUP)
|
||||
fi
|
||||
AC_MSG_RESULT($NOBODY_GROUP)
|
||||
|
||||
AC_DEFINE_UNQUOTED(NOBODY_USER, "nobody", [unprivileged user--e.g. nobody])
|
||||
AC_DEFINE_UNQUOTED(NOBODY_GROUP, "$NOBODY_GROUP", [unprivileged group for unprivileged user])
|
||||
|
||||
@@ -302,6 +310,31 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
|
||||
netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h)
|
||||
AC_HEADER_MAJOR
|
||||
|
||||
AC_CACHE_CHECK([if makedev takes 3 args],rsync_cv_MAKEDEV_TAKES_3_ARGS,[
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#ifdef MAJOR_IN_MKDEV
|
||||
#include <sys/mkdev.h>
|
||||
# if !defined makedev && (defined mkdev || defined _WIN32 || defined __WIN32__)
|
||||
# define makedev mkdev
|
||||
# endif
|
||||
#elif defined MAJOR_IN_SYSMACROS
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
dev_t dev = makedev(0, 5, 7);
|
||||
if (major(dev) != 5 || minor(dev) != 7)
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
||||
],
|
||||
rsync_cv_MAKEDEV_TAKES_3_ARGS=yes,rsync_cv_MAKEDEV_TAKES_3_ARGS=no,rsync_cv_MAKEDEV_TAKES_3_ARGS=no)])
|
||||
if test x"$rsync_cv_MAKEDEV_TAKES_3_ARGS" = x"yes"; then
|
||||
AC_DEFINE(MAKEDEV_TAKES_3_ARGS, 1, [Define to 1 if makedev() takes 3 args])
|
||||
fi
|
||||
|
||||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
AC_CHECK_SIZEOF(long long)
|
||||
@@ -502,8 +535,7 @@ if test $ac_cv_func_getpgrp = yes; then
|
||||
AC_FUNC_GETPGRP
|
||||
fi
|
||||
|
||||
# Determine whether chown follows symlinks (it should).
|
||||
AC_CACHE_CHECK([whether chown() dereferences symlinks],rsync_cv_chown_follows_symlink,[
|
||||
AC_CACHE_CHECK([whether chown() modifies symlinks],rsync_cv_chown_modifies_symlink,[
|
||||
AC_TRY_RUN([
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
@@ -514,14 +546,52 @@ AC_CACHE_CHECK([whether chown() dereferences symlinks],rsync_cv_chown_follows_sy
|
||||
char const *dangling_symlink = "conftest.dangle";
|
||||
unlink(dangling_symlink);
|
||||
if (symlink("conftest.no-such", dangling_symlink) < 0) abort();
|
||||
if (chown(dangling_symlink, getuid(), getgid()) < 0 && errno == ENOENT) exit(0);
|
||||
exit(1);
|
||||
if (chown(dangling_symlink, getuid(), getgid()) < 0 && errno == ENOENT) exit(1);
|
||||
exit(0);
|
||||
}],
|
||||
rsync_cv_chown_follows_symlink=yes,rsync_cv_chown_follows_symlink=no,rsync_cv_chown_follows_symlink=yes)])
|
||||
if test $rsync_cv_chown_follows_symlink = no; then
|
||||
rsync_cv_chown_modifies_symlink=yes,rsync_cv_chown_modifies_symlink=no,rsync_cv_chown_modifies_symlink=no)])
|
||||
if test $rsync_cv_chown_modifies_symlink = yes; then
|
||||
AC_DEFINE(CHOWN_MODIFIES_SYMLINK, 1, [Define to 1 if chown modifies symlinks.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether link() can hard-link symlinks],rsync_cv_can_hardlink_symlink,[
|
||||
AC_TRY_RUN([
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#define FILENAME "conftest.dangle"
|
||||
main() {
|
||||
unlink(FILENAME);
|
||||
if (symlink("conftest.no-such", FILENAME) < 0) abort();
|
||||
if (link(FILENAME, FILENAME "2") < 0) exit(1);
|
||||
exit(0);
|
||||
}],
|
||||
rsync_cv_can_hardlink_symlink=yes,rsync_cv_can_hardlink_symlink=no,rsync_cv_can_hardlink_symlink=no)])
|
||||
if test $rsync_cv_can_hardlink_symlink = yes; then
|
||||
AC_DEFINE(CAN_HARDLINK_SYMLINK, 1, [Define to 1 if link() can hard-link symlinks.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether link() can hard-link special files],rsync_cv_can_hardlink_special,[
|
||||
AC_TRY_RUN([
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#define FILENAME "conftest.fifi"
|
||||
main() {
|
||||
unlink(FILENAME);
|
||||
if (mkfifo(FILENAME, 0777) < 0) abort();
|
||||
if (link(FILENAME, FILENAME "2") < 0) exit(1);
|
||||
exit(0);
|
||||
}],
|
||||
rsync_cv_can_hardlink_special=yes,rsync_cv_can_hardlink_special=no,rsync_cv_can_hardlink_special=no)])
|
||||
if test $rsync_cv_can_hardlink_special = yes; then
|
||||
AC_DEFINE(CAN_HARDLINK_SPECIAL, 1, [Define to 1 if link() can hard-link special files.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
@@ -650,35 +720,6 @@ if test x"$rsync_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then
|
||||
fi
|
||||
|
||||
|
||||
AC_CACHE_CHECK([for broken inet_ntoa],rsync_cv_REPLACE_INET_NTOA,[
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
main() { struct in_addr ip; ip.s_addr = 0x12345678;
|
||||
if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
|
||||
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(1); }
|
||||
exit(0);}],
|
||||
rsync_cv_REPLACE_INET_NTOA=no,rsync_cv_REPLACE_INET_NTOA=yes,rsync_cv_REPLACE_INET_NTOA=cross)])
|
||||
if test x"$rsync_cv_REPLACE_INET_NTOA" = x"yes"; then
|
||||
AC_DEFINE(REPLACE_INET_NTOA, 1, [Define to 1 if inet_ntoa() needs to be replaced])
|
||||
fi
|
||||
|
||||
|
||||
AC_CACHE_CHECK([for broken inet_aton],rsync_cv_REPLACE_INET_ATON,[
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
main() { struct in_addr ip;
|
||||
if (inet_aton("example", &ip) == 0) exit(0); exit(1);}],
|
||||
rsync_cv_REPLACE_INET_ATON=no,rsync_cv_REPLACE_INET_ATON=yes,rsync_cv_REPLACE_INET_ATON=cross)])
|
||||
if test x"$rsync_cv_REPLACE_INET_ATON" = x"yes"; then
|
||||
AC_DEFINE(REPLACE_INET_ATON, 1, [Define to 1 if inet_aton() needs to be replaced])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([if mknod creates FIFOs],rsync_cv_MKNOD_CREATES_FIFOS,[
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
|
||||
40
connection.c
40
connection.c
@@ -1,25 +1,25 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Support the max connections option.
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* support the max connections option */
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
simple routine to do connection counting
|
||||
****************************************************************************/
|
||||
@@ -39,7 +39,7 @@ int claim_connection(char *fname,int max_connections)
|
||||
/* find a free spot */
|
||||
for (i=0;i<max_connections;i++) {
|
||||
if (lock_range(fd, i*4, 4)) return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* only interested in open failures */
|
||||
errno = 0;
|
||||
|
||||
42
errcode.h
42
errcode.h
@@ -1,27 +1,27 @@
|
||||
/* -*- c-file-style: "linux"; -*-
|
||||
|
||||
Copyright (C) 1998-2000 by Andrew Tridgell
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* error codes returned by rsync. If you change these, please also update the
|
||||
* string mappings in log.c and the EXIT VALUES in rsync.yo
|
||||
* Error codes returned by rsync.
|
||||
*
|
||||
* Copyright (C) 1998-2000 Andrew Tridgell
|
||||
* Copyright (C) 2003, 2005 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* If you change these, please also update the string mappings in log.c and
|
||||
* the EXIT VALUES in rsync.yo. */
|
||||
|
||||
#define RERR_OK 0
|
||||
#define RERR_SYNTAX 1 /* syntax or usage error */
|
||||
#define RERR_PROTOCOL 2 /* protocol incompatibility */
|
||||
|
||||
98
exclude.c
98
exclude.c
@@ -1,8 +1,10 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
/*
|
||||
* The filter include/exclude routines.
|
||||
*
|
||||
* Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 1996 by Paul Mackerras
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
* Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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
|
||||
@@ -14,16 +16,11 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* a lot of this stuff was originally derived from GNU tar, although
|
||||
it has now changed so much that it is hard to tell :) */
|
||||
|
||||
/* include/exclude cluestick added by Martin Pool <mbp@samba.org> */
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
@@ -34,8 +31,6 @@ extern int list_only;
|
||||
extern int recurse;
|
||||
extern int io_error;
|
||||
extern int local_server;
|
||||
extern int saw_delete_opt;
|
||||
extern int saw_delete_excluded_opt;
|
||||
extern int prune_empty_dirs;
|
||||
extern int delete_mode;
|
||||
extern int delete_excluded;
|
||||
@@ -303,29 +298,28 @@ static char *parse_merge_name(const char *merge_file, unsigned int *len_ptr,
|
||||
strlcpy(to, merge_file, *len_ptr + 1);
|
||||
merge_file = to;
|
||||
}
|
||||
if (!sanitize_path(fn, merge_file, r, dirbuf_depth)) {
|
||||
if (!sanitize_path(fn, merge_file, r, dirbuf_depth, NULL)) {
|
||||
rprintf(FERROR, "merge-file name overflows: %s\n",
|
||||
merge_file);
|
||||
return NULL;
|
||||
}
|
||||
fn_len = strlen(fn);
|
||||
} else {
|
||||
strlcpy(fn, merge_file, len_ptr ? *len_ptr + 1 : MAXPATHLEN);
|
||||
clean_fname(fn, 1);
|
||||
fn_len = clean_fname(fn, 1);
|
||||
}
|
||||
|
||||
fn_len = strlen(fn);
|
||||
if (fn == buf)
|
||||
goto done;
|
||||
|
||||
if (dirbuf_len + fn_len >= MAXPATHLEN) {
|
||||
rprintf(FERROR, "merge-file name overflows: %s\n", fn);
|
||||
return NULL;
|
||||
/* If the name isn't in buf yet, it's wasn't absolute. */
|
||||
if (fn != buf) {
|
||||
if (dirbuf_len + fn_len >= MAXPATHLEN) {
|
||||
rprintf(FERROR, "merge-file name overflows: %s\n", fn);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(buf, dirbuf + prefix_skip, dirbuf_len - prefix_skip);
|
||||
memcpy(buf + dirbuf_len - prefix_skip, fn, fn_len + 1);
|
||||
fn_len = clean_fname(buf, 1);
|
||||
}
|
||||
memcpy(buf, dirbuf + prefix_skip, dirbuf_len - prefix_skip);
|
||||
memcpy(buf + dirbuf_len - prefix_skip, fn, fn_len + 1);
|
||||
fn_len = clean_fname(buf, 1);
|
||||
|
||||
done:
|
||||
if (len_ptr)
|
||||
*len_ptr = fn_len;
|
||||
return buf;
|
||||
@@ -505,6 +499,8 @@ static int rule_matches(char *name, struct filter_struct *ex, int name_is_dir)
|
||||
char *p, *pattern = ex->pattern;
|
||||
const char *strings[16]; /* more than enough */
|
||||
|
||||
if (*name == '/')
|
||||
name++;
|
||||
if (!*name)
|
||||
return 0;
|
||||
|
||||
@@ -536,8 +532,6 @@ static int rule_matches(char *name, struct filter_struct *ex, int name_is_dir)
|
||||
if (*pattern == '/') {
|
||||
anchored_match = 1;
|
||||
pattern++;
|
||||
if (strings[0][0] == '/')
|
||||
strings[0]++;
|
||||
}
|
||||
|
||||
if (!anchored_match && ex->u.slash_cnt
|
||||
@@ -562,7 +556,7 @@ static int rule_matches(char *name, struct filter_struct *ex, int name_is_dir)
|
||||
if (litmatch_array(pattern, strings, slash_handling))
|
||||
return ret_match;
|
||||
} else if (anchored_match) {
|
||||
if (strcmp(name,pattern) == 0)
|
||||
if (strcmp(name, pattern) == 0)
|
||||
return ret_match;
|
||||
} else {
|
||||
int l1 = strlen(name);
|
||||
@@ -852,13 +846,22 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags,
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
/* --delete-excluded turns an un-modified include/exclude into a
|
||||
* sender-side rule. We also affect per-dir merge files that take
|
||||
* no prefixes as a simple optimization. */
|
||||
if (delete_excluded
|
||||
&& !(new_mflags & (MATCHFLG_RECEIVER_SIDE|MATCHFLG_SENDER_SIDE))
|
||||
&& (!(new_mflags & MATCHFLG_PERDIR_MERGE)
|
||||
|| new_mflags & MATCHFLG_NO_PREFIXES))
|
||||
new_mflags |= MATCHFLG_SENDER_SIDE;
|
||||
|
||||
*len_ptr = len;
|
||||
*mflags_ptr = new_mflags;
|
||||
return (const char *)s;
|
||||
}
|
||||
|
||||
|
||||
static char default_cvsignore[] =
|
||||
static char default_cvsignore[] =
|
||||
/* These default ignored items come from the CVS manual. */
|
||||
"RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS"
|
||||
" .make.state .nse_depinfo *~ #* .#* ,* _$* *$"
|
||||
@@ -866,7 +869,7 @@ static char default_cvsignore[] =
|
||||
" *.a *.olb *.o *.obj *.so *.exe"
|
||||
" *.Z *.elc *.ln core"
|
||||
/* The rest we added to suit ourself. */
|
||||
" .svn/";
|
||||
" .svn/ .bzr/";
|
||||
|
||||
static void get_cvs_excludes(uint32 mflags)
|
||||
{
|
||||
@@ -903,12 +906,14 @@ void parse_rule(struct filter_list_struct *listp, const char *pattern,
|
||||
&pat_len, &new_mflags);
|
||||
if (!cp)
|
||||
break;
|
||||
|
||||
pattern = cp + pat_len;
|
||||
|
||||
if (pat_len >= MAXPATHLEN) {
|
||||
rprintf(FERROR, "discarding over-long filter: %s\n",
|
||||
cp);
|
||||
rprintf(FERROR, "discarding over-long filter: %.*s\n",
|
||||
(int)pat_len, cp);
|
||||
continue;
|
||||
}
|
||||
pattern = cp + pat_len;
|
||||
|
||||
if (new_mflags & MATCHFLG_CLEAR_LIST) {
|
||||
if (verbose > 2) {
|
||||
@@ -928,11 +933,9 @@ void parse_rule(struct filter_list_struct *listp, const char *pattern,
|
||||
}
|
||||
len = pat_len;
|
||||
if (new_mflags & MATCHFLG_EXCLUDE_SELF) {
|
||||
const char *name = strrchr(cp, '/');
|
||||
if (name)
|
||||
len -= ++name - cp;
|
||||
else
|
||||
name = cp;
|
||||
const char *name = cp + len;
|
||||
while (name > cp && name[-1] != '/') name--;
|
||||
len -= name - cp;
|
||||
add_rule(listp, name, len, 0, 0);
|
||||
new_mflags &= ~MATCHFLG_EXCLUDE_SELF;
|
||||
len = pat_len;
|
||||
@@ -1103,11 +1106,20 @@ static void send_rules(int f_out, struct filter_list_struct *flp)
|
||||
int elide = 0;
|
||||
char *p;
|
||||
|
||||
/* Note we need to check delete_excluded here in addition to
|
||||
* the code in parse_rule_tok() because some rules may have
|
||||
* been added before we found the --delete-excluded option.
|
||||
* We must also elide any CVS merge-file rules to avoid a
|
||||
* backward compatibility problem, and we elide any no-prefix
|
||||
* merge files as an optimization (since they can only have
|
||||
* include/exclude rules). */
|
||||
if (ent->match_flags & MATCHFLG_SENDER_SIDE)
|
||||
elide = am_sender ? 1 : -1;
|
||||
if (ent->match_flags & MATCHFLG_RECEIVER_SIDE)
|
||||
elide = elide ? 0 : am_sender ? -1 : 1;
|
||||
else if (delete_excluded && !elide)
|
||||
else if (delete_excluded && !elide
|
||||
&& (!(ent->match_flags & MATCHFLG_PERDIR_MERGE)
|
||||
|| ent->match_flags & MATCHFLG_NO_PREFIXES))
|
||||
elide = am_sender ? 1 : -1;
|
||||
if (elide < 0) {
|
||||
if (prev)
|
||||
@@ -1185,8 +1197,8 @@ void recv_filter_list(int f_in)
|
||||
char line[BIGPATHBUFLEN];
|
||||
int xflags = protocol_version >= 29 ? 0 : XFLG_OLD_PREFIXES;
|
||||
int receiver_wants_list = prune_empty_dirs
|
||||
|| (saw_delete_opt
|
||||
&& (!saw_delete_excluded_opt || protocol_version >= 29));
|
||||
|| (delete_mode
|
||||
&& (!delete_excluded || protocol_version >= 29));
|
||||
unsigned int len;
|
||||
|
||||
if (!local_server && (am_sender || receiver_wants_list)) {
|
||||
|
||||
42
fileio.c
42
fileio.c
@@ -1,25 +1,25 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
* File IO utilities used in rsync.
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
File IO utilities used in rsync
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
#ifndef ENODATA
|
||||
@@ -232,7 +232,6 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
}
|
||||
map->p_fd_offset = read_start;
|
||||
}
|
||||
map->p_fd_offset += read_size;
|
||||
map->p_offset = window_start;
|
||||
map->p_len = window_size;
|
||||
|
||||
@@ -246,6 +245,7 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
memset(map->p + read_offset, 0, read_size);
|
||||
break;
|
||||
}
|
||||
map->p_fd_offset += nread;
|
||||
read_offset += nread;
|
||||
read_size -= nread;
|
||||
}
|
||||
|
||||
185
flist.c
185
flist.c
@@ -1,34 +1,29 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/** @file flist.c
|
||||
* Generate and receive file lists
|
||||
* Generate and receive file lists.
|
||||
*
|
||||
* @sa http://lists.samba.org/pipermail/rsync/2000-June/002351.html
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2002, 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int list_only;
|
||||
extern int am_root;
|
||||
extern int am_server;
|
||||
@@ -43,10 +38,10 @@ extern int recurse;
|
||||
extern int xfer_dirs;
|
||||
extern int filesfrom_fd;
|
||||
extern int one_file_system;
|
||||
extern int copy_dirlinks;
|
||||
extern int keep_dirlinks;
|
||||
extern int preserve_links;
|
||||
extern int preserve_hard_links;
|
||||
extern int preserve_perms;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_specials;
|
||||
extern int preserve_uid;
|
||||
@@ -58,7 +53,6 @@ extern int copy_links;
|
||||
extern int copy_unsafe_links;
|
||||
extern int protocol_version;
|
||||
extern int sanitize_paths;
|
||||
extern const char *io_write_phase;
|
||||
extern struct stats stats;
|
||||
extern struct file_list *the_file_list;
|
||||
|
||||
@@ -96,15 +90,15 @@ static int show_filelist_p(void)
|
||||
|
||||
static void start_filelist_progress(char *kind)
|
||||
{
|
||||
rprintf(FINFO, "%s ... ", kind);
|
||||
rprintf(FCLIENT, "%s ... ", kind);
|
||||
if (verbose > 1 || do_progress)
|
||||
rprintf(FINFO, "\n");
|
||||
rprintf(FCLIENT, "\n");
|
||||
rflush(FINFO);
|
||||
}
|
||||
|
||||
static void emit_filelist_progress(int count)
|
||||
{
|
||||
rprintf(FINFO, " %d files...\r", count);
|
||||
rprintf(FCLIENT, " %d files...\r", count);
|
||||
}
|
||||
|
||||
static void maybe_emit_filelist_progress(int count)
|
||||
@@ -155,61 +149,53 @@ static void list_file_entry(struct file_struct *f)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stat either a symlink or its referent, depending on the settings of
|
||||
* copy_links, copy_unsafe_links, etc.
|
||||
/* Stat either a symlink or its referent, depending on the settings of
|
||||
* copy_links, copy_unsafe_links, etc. Returns -1 on error, 0 on success.
|
||||
*
|
||||
* @retval -1 on error
|
||||
* If path is the name of a symlink, then the linkbuf buffer (which must hold
|
||||
* MAXPATHLEN chars) will be set to the symlink's target string.
|
||||
*
|
||||
* @retval 0 for success
|
||||
*
|
||||
* @post If @p path is a symlink, then @p linkbuf (of size @c
|
||||
* MAXPATHLEN) contains the symlink target.
|
||||
*
|
||||
* @post @p buffer contains information about the link or the
|
||||
* referrent as appropriate, if they exist.
|
||||
**/
|
||||
static int readlink_stat(const char *path, STRUCT_STAT *buffer, char *linkbuf)
|
||||
* The stat structure pointed to by stp will contain information about the
|
||||
* link or the referent as appropriate, if they exist. */
|
||||
static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf)
|
||||
{
|
||||
#ifdef SUPPORT_LINKS
|
||||
if (copy_links)
|
||||
return do_stat(path, buffer);
|
||||
if (link_stat(path, buffer, 0) < 0)
|
||||
if (link_stat(path, stp, copy_dirlinks) < 0)
|
||||
return -1;
|
||||
if (S_ISLNK(buffer->st_mode)) {
|
||||
int l = readlink((char *)path, linkbuf, MAXPATHLEN - 1);
|
||||
if (l == -1)
|
||||
if (S_ISLNK(stp->st_mode)) {
|
||||
int llen = readlink(path, linkbuf, MAXPATHLEN - 1);
|
||||
if (llen < 0)
|
||||
return -1;
|
||||
linkbuf[l] = 0;
|
||||
linkbuf[llen] = '\0';
|
||||
if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) {
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
|
||||
path, linkbuf);
|
||||
}
|
||||
return do_stat(path, buffer);
|
||||
return do_stat(path, stp);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return do_stat(path, buffer);
|
||||
return do_stat(path, stp);
|
||||
#endif
|
||||
}
|
||||
|
||||
int link_stat(const char *path, STRUCT_STAT *buffer, int follow_dirlinks)
|
||||
int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks)
|
||||
{
|
||||
#ifdef SUPPORT_LINKS
|
||||
if (copy_links)
|
||||
return do_stat(path, buffer);
|
||||
if (do_lstat(path, buffer) < 0)
|
||||
return do_stat(path, stp);
|
||||
if (do_lstat(path, stp) < 0)
|
||||
return -1;
|
||||
if (follow_dirlinks && S_ISLNK(buffer->st_mode)) {
|
||||
if (follow_dirlinks && S_ISLNK(stp->st_mode)) {
|
||||
STRUCT_STAT st;
|
||||
if (do_stat(path, &st) == 0 && S_ISDIR(st.st_mode))
|
||||
*buffer = st;
|
||||
*stp = st;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return do_stat(path, buffer);
|
||||
return do_stat(path, stp);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -247,17 +233,21 @@ static int is_excluded(char *fname, int is_dir, int filter_level)
|
||||
static int to_wire_mode(mode_t mode)
|
||||
{
|
||||
#ifdef SUPPORT_LINKS
|
||||
if (S_ISLNK(mode) && (_S_IFLNK != 0120000))
|
||||
#if _S_IFLNK != 0120000
|
||||
if (S_ISLNK(mode))
|
||||
return (mode & ~(_S_IFMT)) | 0120000;
|
||||
#endif
|
||||
return (int)mode;
|
||||
#endif
|
||||
return mode;
|
||||
}
|
||||
|
||||
static mode_t from_wire_mode(int mode)
|
||||
{
|
||||
if ((mode & (_S_IFMT)) == 0120000 && (_S_IFLNK != 0120000))
|
||||
#if _S_IFLNK != 0120000
|
||||
if ((mode & (_S_IFMT)) == 0120000)
|
||||
return (mode & ~(_S_IFMT)) | _S_IFLNK;
|
||||
return (mode_t)mode;
|
||||
#endif
|
||||
return mode;
|
||||
}
|
||||
|
||||
static void send_directory(int f, struct file_list *flist,
|
||||
@@ -296,7 +286,7 @@ void flist_expand(struct file_list *flist)
|
||||
flist->malloced);
|
||||
|
||||
if (verbose >= 2 && flist->malloced != FLIST_START) {
|
||||
rprintf(FINFO, "[%s] expand file_list to %.0f bytes, did%s move\n",
|
||||
rprintf(FCLIENT, "[%s] expand file_list to %.0f bytes, did%s move\n",
|
||||
who_am_i(),
|
||||
(double)sizeof flist->files[0] * flist->malloced,
|
||||
(new_ptr == flist->files) ? " not" : "");
|
||||
@@ -328,15 +318,13 @@ static void send_file_entry(struct file_struct *file, int f)
|
||||
if (!file) {
|
||||
write_byte(f, 0);
|
||||
modtime = 0, mode = 0;
|
||||
dev = 0, rdev = makedev(0, 0);
|
||||
dev = 0, rdev = MAKEDEV(0, 0);
|
||||
rdev_major = 0;
|
||||
uid = 0, gid = 0;
|
||||
*lastname = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
io_write_phase = "send_file_entry";
|
||||
|
||||
f_name(file, fname);
|
||||
|
||||
flags = file->flags & XMIT_TOP_DIR;
|
||||
@@ -362,7 +350,7 @@ static void send_file_entry(struct file_struct *file, int f)
|
||||
flags |= XMIT_RDEV_MINOR_IS_SMALL;
|
||||
}
|
||||
} else if (protocol_version < 28)
|
||||
rdev = makedev(0, 0);
|
||||
rdev = MAKEDEV(0, 0);
|
||||
if (file->uid == uid)
|
||||
flags |= XMIT_SAME_UID;
|
||||
else
|
||||
@@ -462,7 +450,7 @@ static void send_file_entry(struct file_struct *file, int f)
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
if (flags & XMIT_HAS_IDEV_DATA) {
|
||||
if (file->link_u.idev) {
|
||||
if (protocol_version < 26) {
|
||||
/* 32-bit dev_t and ino_t */
|
||||
write_int(f, dev);
|
||||
@@ -488,8 +476,6 @@ static void send_file_entry(struct file_struct *file, int f)
|
||||
}
|
||||
|
||||
strlcpy(lastname, fname, MAXPATHLEN);
|
||||
|
||||
io_write_phase = "unknown";
|
||||
}
|
||||
|
||||
static struct file_struct *receive_file_entry(struct file_list *flist,
|
||||
@@ -515,7 +501,7 @@ static struct file_struct *receive_file_entry(struct file_list *flist,
|
||||
|
||||
if (!flist) {
|
||||
modtime = 0, mode = 0;
|
||||
dev = 0, rdev = makedev(0, 0);
|
||||
dev = 0, rdev = MAKEDEV(0, 0);
|
||||
rdev_major = 0;
|
||||
uid = 0, gid = 0;
|
||||
*lastname = '\0';
|
||||
@@ -548,7 +534,7 @@ static struct file_struct *receive_file_entry(struct file_list *flist,
|
||||
clean_fname(thisname, 0);
|
||||
|
||||
if (sanitize_paths)
|
||||
sanitize_path(thisname, thisname, "", 0);
|
||||
sanitize_path(thisname, thisname, "", 0, NULL);
|
||||
|
||||
if ((basename = strrchr(thisname, '/')) != NULL) {
|
||||
dirname_len = ++basename - thisname; /* counts future '\0' */
|
||||
@@ -592,10 +578,10 @@ static struct file_struct *receive_file_entry(struct file_list *flist,
|
||||
rdev_minor = read_byte(f);
|
||||
else
|
||||
rdev_minor = read_int(f);
|
||||
rdev = makedev(rdev_major, rdev_minor);
|
||||
rdev = MAKEDEV(rdev_major, rdev_minor);
|
||||
}
|
||||
} else if (protocol_version < 28)
|
||||
rdev = makedev(0, 0);
|
||||
rdev = MAKEDEV(0, 0);
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
if (preserve_links && S_ISLNK(mode)) {
|
||||
@@ -674,7 +660,7 @@ static struct file_struct *receive_file_entry(struct file_list *flist,
|
||||
file->u.link = bp;
|
||||
read_sbuf(f, bp, linkname_len - 1);
|
||||
if (sanitize_paths)
|
||||
sanitize_path(bp, bp, "", lastdir_depth);
|
||||
sanitize_path(bp, bp, "", lastdir_depth, NULL);
|
||||
bp += linkname_len;
|
||||
}
|
||||
#endif
|
||||
@@ -755,13 +741,14 @@ struct file_struct *make_file(char *fname, struct file_list *flist,
|
||||
}
|
||||
clean_fname(thisname, 0);
|
||||
if (sanitize_paths)
|
||||
sanitize_path(thisname, thisname, "", 0);
|
||||
sanitize_path(thisname, thisname, "", 0, NULL);
|
||||
|
||||
memset(sum, 0, SUM_LENGTH);
|
||||
|
||||
if (stp && S_ISDIR(stp->st_mode))
|
||||
if (stp && S_ISDIR(stp->st_mode)) {
|
||||
st = *stp; /* Needed for "symlink/." with --relative. */
|
||||
else if (readlink_stat(thisname, &st, linkname) != 0) {
|
||||
*linkname = '\0'; /* make IBM code checker happy */
|
||||
} else if (readlink_stat(thisname, &st, linkname) != 0) {
|
||||
int save_errno = errno;
|
||||
/* See if file is excluded before reporting an error. */
|
||||
if (filter_level != NO_FILTERS
|
||||
@@ -859,7 +846,7 @@ struct file_struct *make_file(char *fname, struct file_list *flist,
|
||||
? MD4_SUM_LENGTH : 0;
|
||||
|
||||
alloc_len = file_struct_len + dirname_len + basename_len
|
||||
+ linkname_len + sum_len;
|
||||
+ linkname_len + sum_len;
|
||||
if (flist)
|
||||
bp = pool_alloc(flist->file_pool, alloc_len, "make_file");
|
||||
else {
|
||||
@@ -1078,6 +1065,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
int64 start_write;
|
||||
int use_ff_fd = 0;
|
||||
|
||||
rprintf(FLOG, "building file list\n");
|
||||
if (show_filelist_p())
|
||||
start_filelist_progress("building file list");
|
||||
|
||||
@@ -1088,7 +1076,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
|
||||
io_start_buffering_out();
|
||||
if (filesfrom_fd >= 0) {
|
||||
if (argv[0] && !push_dir(argv[0])) {
|
||||
if (argv[0] && !push_dir(argv[0], 0)) {
|
||||
rsyserr(FERROR, errno, "push_dir %s failed",
|
||||
full_fname(argv[0]));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
@@ -1104,13 +1092,13 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
if (use_ff_fd) {
|
||||
if (read_filesfrom_line(filesfrom_fd, fbuf) == 0)
|
||||
break;
|
||||
sanitize_path(fbuf, fbuf, "", 0);
|
||||
sanitize_path(fbuf, fbuf, "", 0, NULL);
|
||||
} else {
|
||||
if (argc-- == 0)
|
||||
break;
|
||||
strlcpy(fbuf, *argv++, MAXPATHLEN);
|
||||
if (sanitize_paths)
|
||||
sanitize_path(fbuf, fbuf, "", 0);
|
||||
sanitize_path(fbuf, fbuf, "", 0, NULL);
|
||||
}
|
||||
|
||||
len = strlen(fbuf);
|
||||
@@ -1141,7 +1129,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
&& (len == 1 || fbuf[len-2] == '/');
|
||||
}
|
||||
|
||||
if (link_stat(fbuf, &st, keep_dirlinks) != 0) {
|
||||
if (link_stat(fbuf, &st, copy_dirlinks) != 0) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
rsyserr(FERROR, errno, "link_stat %s failed",
|
||||
full_fname(fbuf));
|
||||
@@ -1198,6 +1186,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (len == 1 && fn[0] == '/')
|
||||
fn[len++] = '.';
|
||||
fn[len] = '\0';
|
||||
/* Reject a ".." dir in the active part of the path. */
|
||||
for (p = fn; (p = strstr(p, "..")) != NULL; p += 2) {
|
||||
@@ -1222,7 +1212,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
|
||||
strlcpy(olddir, curr_dir, sizeof olddir);
|
||||
|
||||
if (!push_dir(dir)) {
|
||||
if (!push_dir(dir, 0)) {
|
||||
io_error |= IOERR_GENERAL;
|
||||
rsyserr(FERROR, errno, "push_dir %s failed",
|
||||
full_fname(dir));
|
||||
@@ -1256,7 +1246,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
if (fn != p || (*lp && *lp != '/')) {
|
||||
int save_copy_links = copy_links;
|
||||
int save_xfer_dirs = xfer_dirs;
|
||||
copy_links = copy_unsafe_links;
|
||||
copy_links |= copy_unsafe_links;
|
||||
xfer_dirs = 1;
|
||||
while ((slash = strchr(slash+1, '/')) != 0) {
|
||||
*slash = '\0';
|
||||
@@ -1344,6 +1334,7 @@ struct file_list *recv_file_list(int f)
|
||||
unsigned short flags;
|
||||
int64 start_read;
|
||||
|
||||
rprintf(FLOG, "receiving file list\n");
|
||||
if (show_filelist_p())
|
||||
start_filelist_progress("receiving file list");
|
||||
|
||||
@@ -1366,7 +1357,7 @@ struct file_list *recv_file_list(int f)
|
||||
flags |= read_byte(f) << 8;
|
||||
file = receive_file_entry(flist, flags, f);
|
||||
|
||||
if (S_ISREG(file->mode))
|
||||
if (S_ISREG(file->mode) || S_ISLNK(file->mode))
|
||||
stats.total_size += file->length;
|
||||
|
||||
flist->files[flist->count++] = file;
|
||||
@@ -1706,15 +1697,15 @@ static void output_flist(struct file_list *flist)
|
||||
for (i = 0; i < flist->count; i++) {
|
||||
file = flist->files[i];
|
||||
if ((am_root || am_sender) && preserve_uid)
|
||||
sprintf(uidbuf, " uid=%ld", (long)file->uid);
|
||||
snprintf(uidbuf, sizeof uidbuf, " uid=%ld", (long)file->uid);
|
||||
else
|
||||
*uidbuf = '\0';
|
||||
if (preserve_gid && file->gid != GID_NONE)
|
||||
sprintf(gidbuf, " gid=%ld", (long)file->gid);
|
||||
snprintf(gidbuf, sizeof gidbuf, " gid=%ld", (long)file->gid);
|
||||
else
|
||||
*gidbuf = '\0';
|
||||
if (!am_sender)
|
||||
sprintf(depthbuf, "%d", file->dir.depth);
|
||||
snprintf(depthbuf, sizeof depthbuf, "%d", file->dir.depth);
|
||||
rprintf(FINFO, "[%s] i=%d %s %s%s%s%s mode=0%o len=%.0f%s%s flags=%x\n",
|
||||
who, i, am_sender ? NS(file->dir.root) : depthbuf,
|
||||
file->dirname ? file->dirname : "",
|
||||
@@ -1771,10 +1762,6 @@ int f_name_cmp(struct file_struct *f1, struct file_struct *f2)
|
||||
c1 = (uchar*)"";
|
||||
} else
|
||||
state1 = s_BASE;
|
||||
} else if (!*c1) {
|
||||
type1 = t_path;
|
||||
state1 = s_SLASH;
|
||||
c1 = (uchar*)"/";
|
||||
} else {
|
||||
type1 = t_path;
|
||||
state1 = s_DIR;
|
||||
@@ -1788,10 +1775,6 @@ int f_name_cmp(struct file_struct *f1, struct file_struct *f2)
|
||||
c2 = (uchar*)"";
|
||||
} else
|
||||
state2 = s_BASE;
|
||||
} else if (!*c2) {
|
||||
type2 = t_path;
|
||||
state2 = s_SLASH;
|
||||
c2 = (uchar*)"/";
|
||||
} else {
|
||||
type2 = t_path;
|
||||
state2 = s_DIR;
|
||||
@@ -1800,9 +1783,7 @@ int f_name_cmp(struct file_struct *f1, struct file_struct *f2)
|
||||
if (type1 != type2)
|
||||
return type1 == t_PATH ? 1 : -1;
|
||||
|
||||
while (1) {
|
||||
if ((dif = (int)*c1++ - (int)*c2++) != 0)
|
||||
break;
|
||||
do {
|
||||
if (!*c1) {
|
||||
switch (state1) {
|
||||
case s_DIR:
|
||||
@@ -1865,7 +1846,7 @@ int f_name_cmp(struct file_struct *f1, struct file_struct *f2)
|
||||
if (type1 != type2)
|
||||
return type1 == t_PATH ? 1 : -1;
|
||||
}
|
||||
}
|
||||
} while ((dif = (int)*c1++ - (int)*c2++) == 0);
|
||||
|
||||
return dif;
|
||||
}
|
||||
@@ -1892,9 +1873,9 @@ char *f_name(struct file_struct *f, char *fbuf)
|
||||
int len = strlen(f->dirname);
|
||||
memcpy(fbuf, f->dirname, len);
|
||||
fbuf[len] = '/';
|
||||
strcpy(fbuf + len + 1, f->basename);
|
||||
strlcpy(fbuf + len + 1, f->basename, MAXPATHLEN - (len + 1));
|
||||
} else
|
||||
strcpy(fbuf, f->basename);
|
||||
strlcpy(fbuf, f->basename, MAXPATHLEN);
|
||||
|
||||
return fbuf;
|
||||
}
|
||||
|
||||
296
generator.c
296
generator.c
@@ -1,40 +1,39 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
rsync -- fast file replication program
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Routines that are exclusive to the generator process.
|
||||
*
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int do_xfers;
|
||||
extern int log_format_has_i;
|
||||
extern int log_format_has_o_or_i;
|
||||
extern int daemon_log_format_has_i;
|
||||
extern int stdout_format_has_i;
|
||||
extern int logfile_format_has_i;
|
||||
extern int am_root;
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int do_progress;
|
||||
extern int recurse;
|
||||
extern int relative_paths;
|
||||
extern int implied_dirs;
|
||||
extern int keep_dirlinks;
|
||||
extern int preserve_links;
|
||||
extern int preserve_devices;
|
||||
@@ -51,7 +50,7 @@ extern int delete_during;
|
||||
extern int delete_after;
|
||||
extern int module_id;
|
||||
extern int ignore_errors;
|
||||
extern int remove_sent_files;
|
||||
extern int remove_source_files;
|
||||
extern int delay_updates;
|
||||
extern int update_only;
|
||||
extern int ignore_existing;
|
||||
@@ -79,8 +78,8 @@ extern int copy_dest;
|
||||
extern int link_dest;
|
||||
extern int whole_file;
|
||||
extern int list_only;
|
||||
extern int new_root_dir;
|
||||
extern int read_batch;
|
||||
extern int orig_umask;
|
||||
extern int safe_symlinks;
|
||||
extern long block_size; /* "long" because popt can't set an int32. */
|
||||
extern int max_delete;
|
||||
@@ -95,8 +94,6 @@ extern struct file_list *the_file_list;
|
||||
extern struct filter_list_struct server_filter_list;
|
||||
|
||||
static int deletion_count = 0; /* used to implement --max-delete */
|
||||
static int can_link_symlinks = 1; /* start out optimistic */
|
||||
static int can_link_devices = 1;
|
||||
|
||||
/* For calling delete_file() */
|
||||
#define DEL_FORCE_RECURSE (1<<1) /* recurse even w/o --force */
|
||||
@@ -294,8 +291,8 @@ static void do_delete_pass(struct file_list *flist)
|
||||
STRUCT_STAT st;
|
||||
int j;
|
||||
|
||||
if (dry_run > 1 /* destination doesn't exist yet */
|
||||
|| list_only)
|
||||
/* dry_run is incremented when the destination doesn't exist yet. */
|
||||
if (dry_run > 1 || list_only)
|
||||
return;
|
||||
|
||||
for (j = 0; j < flist->count; j++) {
|
||||
@@ -361,7 +358,7 @@ void itemize(struct file_struct *file, int ndx, int statret, STRUCT_STAT *st,
|
||||
|
||||
iflags &= 0xffff;
|
||||
if ((iflags & SIGNIFICANT_ITEM_FLAGS || verbose > 1
|
||||
|| log_format_has_i > 1 || (xname && *xname)) && !read_batch) {
|
||||
|| stdout_format_has_i > 1 || (xname && *xname)) && !read_batch) {
|
||||
if (protocol_version >= 29) {
|
||||
if (ndx >= 0)
|
||||
write_int(sock_f_out, ndx);
|
||||
@@ -370,8 +367,10 @@ void itemize(struct file_struct *file, int ndx, int statret, STRUCT_STAT *st,
|
||||
write_byte(sock_f_out, fnamecmp_type);
|
||||
if (iflags & ITEM_XNAME_FOLLOWS)
|
||||
write_vstring(sock_f_out, xname, strlen(xname));
|
||||
} else if (ndx >= 0)
|
||||
log_item(file, &stats, iflags, xname);
|
||||
} else if (ndx >= 0) {
|
||||
enum logcode code = logfile_format_has_i ? FINFO : FCLIENT;
|
||||
log_item(code, file, &stats, iflags, xname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +453,7 @@ static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
|
||||
int64 l;
|
||||
int b = BLOCKSUM_BIAS;
|
||||
for (l = len; l >>= 1; b += 2) {}
|
||||
for (c = blength; c >>= 1 && b; b--) {}
|
||||
for (c = blength; (c >>= 1) && b; b--) {}
|
||||
/* add a bit, subtract rollsum, round up. */
|
||||
s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */
|
||||
s2length = MAX(s2length, csum_length);
|
||||
@@ -631,7 +630,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
|
||||
case 2:
|
||||
if (!unchanged_attrs(file, stp))
|
||||
continue;
|
||||
if ((always_checksum || ignore_times)
|
||||
if (always_checksum && preserve_times
|
||||
&& cmp_time(stp->st_mtime, file->modtime))
|
||||
continue;
|
||||
best_match = j;
|
||||
@@ -648,29 +647,31 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
|
||||
j = best_match;
|
||||
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
|
||||
if (link_stat(cmpbuf, stp, 0) < 0)
|
||||
match_level = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINK
|
||||
if (match_level == 3 && !copy_dest) {
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
if (link_dest) {
|
||||
if (hard_link_one(file, ndx, fname, 0, stp,
|
||||
cmpbuf, 1,
|
||||
itemizing && verbose > 1,
|
||||
code) < 0)
|
||||
goto try_a_copy;
|
||||
if (preserve_hard_links && file->link_u.links)
|
||||
if (preserve_hard_links && file->link_u.links) {
|
||||
if (dry_run)
|
||||
file->link_u.links->link_dest_used = j + 1;
|
||||
hard_link_cluster(file, ndx, itemizing, code);
|
||||
} else if (itemizing)
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (itemizing)
|
||||
itemize(file, ndx, 0, stp, 0, 0, NULL);
|
||||
if (verbose > 1 && maybe_ATTRS_REPORT) {
|
||||
code = daemon_log_format_has_i || dry_run
|
||||
? FCLIENT : FINFO;
|
||||
rprintf(code, "%s is uptodate\n", fname);
|
||||
rprintf(FCLIENT, "%s is uptodate\n", fname);
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (match_level >= 2) {
|
||||
try_a_copy: /* Copy the file locally. */
|
||||
@@ -687,8 +688,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
|
||||
if (maybe_ATTRS_REPORT
|
||||
&& ((!itemizing && verbose && match_level == 2)
|
||||
|| (verbose > 1 && match_level == 3))) {
|
||||
code = daemon_log_format_has_i || dry_run
|
||||
? FCLIENT : FINFO;
|
||||
code = match_level == 3 ? FCLIENT : FINFO;
|
||||
rprintf(code, "%s%s\n", fname,
|
||||
match_level == 3 ? " is uptodate" : "");
|
||||
}
|
||||
@@ -703,12 +703,12 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
|
||||
/* This is only called for non-regular files. We return -2 if we've finished
|
||||
* handling the file, or -1 if no dest-linking occurred. */
|
||||
static int try_dests_non(struct file_struct *file, char *fname, int ndx,
|
||||
int itemizing, int *possible_ptr,
|
||||
int maybe_ATTRS_REPORT, enum logcode code)
|
||||
int itemizing, int maybe_ATTRS_REPORT,
|
||||
enum logcode code)
|
||||
{
|
||||
char fnamebuf[MAXPATHLEN], lnk[MAXPATHLEN];
|
||||
char fnamebuf[MAXPATHLEN];
|
||||
STRUCT_STAT st;
|
||||
int len, i = 0;
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
pathjoin(fnamebuf, MAXPATHLEN, basis_dir[i], fname);
|
||||
@@ -717,35 +717,53 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
|
||||
continue;
|
||||
if (S_ISLNK(file->mode)) {
|
||||
#ifdef SUPPORT_LINKS
|
||||
char lnk[MAXPATHLEN];
|
||||
int len;
|
||||
if ((len = readlink(fnamebuf, lnk, MAXPATHLEN-1)) <= 0)
|
||||
continue;
|
||||
lnk[len] = '\0';
|
||||
if (strcmp(lnk, file->u.link) != 0)
|
||||
#endif
|
||||
continue;
|
||||
} else {
|
||||
} else if (IS_SPECIAL(file->mode)) {
|
||||
if (!IS_SPECIAL(st.st_mode) || st.st_rdev != file->u.rdev)
|
||||
continue;
|
||||
} else if (IS_DEVICE(file->mode)) {
|
||||
if (!IS_DEVICE(st.st_mode) || st.st_rdev != file->u.rdev)
|
||||
continue;
|
||||
} else {
|
||||
rprintf(FERROR,
|
||||
"internal: try_dests_non() called with invalid mode (%o)\n",
|
||||
(int)file->mode);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
if (link_dest) {
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
if (link_dest
|
||||
#ifndef CAN_HARDLINK_SYMLINK
|
||||
&& !S_ISLNK(file->mode)
|
||||
#endif
|
||||
#ifndef CAN_HARDLINK_SPECIAL
|
||||
&& !IS_SPECIAL(file->mode) && !IS_DEVICE(file->mode)
|
||||
#endif
|
||||
) {
|
||||
if (do_link(fnamebuf, fname) < 0) {
|
||||
/* TODO improve this to be based on errno? */
|
||||
*possible_ptr = 0;
|
||||
rsyserr(FERROR, errno,
|
||||
"failed to hard-link %s with %s",
|
||||
fnamebuf, fname);
|
||||
break;
|
||||
}
|
||||
if (preserve_hard_links && file->link_u.links)
|
||||
hard_link_cluster(file, ndx, itemizing, code);
|
||||
}
|
||||
if (itemizing && log_format_has_i && verbose > 1) {
|
||||
#endif
|
||||
if (itemizing && stdout_format_has_i && verbose > 1) {
|
||||
int changes = compare_dest ? 0 : ITEM_LOCAL_CHANGE
|
||||
+ (link_dest ? ITEM_XNAME_FOLLOWS : 0);
|
||||
char *lp = link_dest ? "" : NULL;
|
||||
itemize(file, ndx, 0, &st, changes, 0, lp);
|
||||
}
|
||||
if (verbose > 1 && maybe_ATTRS_REPORT) {
|
||||
code = daemon_log_format_has_i || dry_run
|
||||
? FCLIENT : FINFO;
|
||||
rprintf(code, "%s is uptodate\n", fname);
|
||||
rprintf(FCLIENT, "%s is uptodate\n", fname);
|
||||
}
|
||||
return -2;
|
||||
} while (basis_dir[++i] != NULL);
|
||||
@@ -770,8 +788,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
enum logcode code, int f_out)
|
||||
{
|
||||
static int missing_below = -1, excluded_below = -1;
|
||||
static char *fuzzy_dirname = "";
|
||||
static char *parent_dirname = "";
|
||||
static struct file_list *fuzzy_dirlist = NULL;
|
||||
static int need_fuzzy_dirlist = 0;
|
||||
struct file_struct *fuzzy_file = NULL;
|
||||
int fd = -1, f_copy = -1;
|
||||
STRUCT_STAT st, real_st, partial_st;
|
||||
@@ -789,12 +808,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
if (fuzzy_dirlist) {
|
||||
flist_free(fuzzy_dirlist);
|
||||
fuzzy_dirlist = NULL;
|
||||
fuzzy_dirname = "";
|
||||
}
|
||||
if (missing_below >= 0) {
|
||||
dry_run--;
|
||||
if (dry_run)
|
||||
dry_run--;
|
||||
missing_below = -1;
|
||||
}
|
||||
parent_dirname = "";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -821,23 +841,39 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
}
|
||||
}
|
||||
|
||||
if (missing_below >= 0 && file->dir.depth <= missing_below) {
|
||||
dry_run--;
|
||||
missing_below = -1;
|
||||
if (missing_below >= 0) {
|
||||
if (file->dir.depth <= missing_below) {
|
||||
if (dry_run)
|
||||
dry_run--;
|
||||
missing_below = -1;
|
||||
} else if (!dry_run)
|
||||
return;
|
||||
}
|
||||
if (dry_run > 1) {
|
||||
statret = -1;
|
||||
stat_errno = ENOENT;
|
||||
} else {
|
||||
if (fuzzy_basis && S_ISREG(file->mode)) {
|
||||
char *dn = file->dirname ? file->dirname : ".";
|
||||
if (fuzzy_dirname != dn
|
||||
&& strcmp(fuzzy_dirname, dn) != 0) {
|
||||
if (fuzzy_dirlist)
|
||||
flist_free(fuzzy_dirlist);
|
||||
fuzzy_dirlist = get_dirlist(dn, -1, 1);
|
||||
char *dn = file->dirname ? file->dirname : ".";
|
||||
if (parent_dirname != dn && strcmp(parent_dirname, dn) != 0) {
|
||||
if (relative_paths && !implied_dirs
|
||||
&& do_stat(dn, &st) < 0
|
||||
&& create_directory_path(fname) < 0) {
|
||||
rsyserr(FERROR, errno,
|
||||
"recv_generator: mkdir %s failed",
|
||||
full_fname(dn));
|
||||
}
|
||||
fuzzy_dirname = dn;
|
||||
if (fuzzy_dirlist) {
|
||||
flist_free(fuzzy_dirlist);
|
||||
fuzzy_dirlist = NULL;
|
||||
}
|
||||
if (fuzzy_basis)
|
||||
need_fuzzy_dirlist = 1;
|
||||
}
|
||||
parent_dirname = dn;
|
||||
|
||||
if (need_fuzzy_dirlist && S_ISREG(file->mode)) {
|
||||
fuzzy_dirlist = get_dirlist(dn, -1, 1);
|
||||
need_fuzzy_dirlist = 0;
|
||||
}
|
||||
|
||||
statret = link_stat(fname, &st,
|
||||
@@ -878,20 +914,34 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
dry_run++;
|
||||
}
|
||||
if (itemizing && f_out != -1) {
|
||||
itemize(file, ndx, statret, &st,
|
||||
statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
|
||||
int sr = statret;
|
||||
if (new_root_dir) {
|
||||
if (*fname == '.' && fname[1] == '\0')
|
||||
sr = -1;
|
||||
new_root_dir = 0;
|
||||
}
|
||||
itemize(file, ndx, sr, &st,
|
||||
sr ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
|
||||
}
|
||||
if (statret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
|
||||
if (!relative_paths || errno != ENOENT
|
||||
|| create_directory_path(fname, orig_umask) < 0
|
||||
|| create_directory_path(fname) < 0
|
||||
|| (do_mkdir(fname, file->mode) < 0 && errno != EEXIST)) {
|
||||
rsyserr(FERROR, errno,
|
||||
"recv_generator: mkdir %s failed",
|
||||
full_fname(fname));
|
||||
file->flags |= FLAG_MISSING;
|
||||
if (ndx+1 < the_file_list->count
|
||||
&& the_file_list->files[ndx+1]->dir.depth > file->dir.depth) {
|
||||
rprintf(FERROR,
|
||||
"*** Skipping everything below this failed directory ***\n");
|
||||
missing_below = file->dir.depth;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (set_file_attrs(fname, file, statret ? NULL : &st, 0)
|
||||
&& verbose && code && f_out != -1)
|
||||
&& verbose && code != FNONE && f_out != -1)
|
||||
rprintf(code, "%s/\n", fname);
|
||||
if (delete_during && f_out != -1 && !phase && dry_run < 2
|
||||
&& (file->flags & FLAG_DEL_HERE))
|
||||
@@ -939,6 +989,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
itemizing,
|
||||
code);
|
||||
}
|
||||
if (remove_source_files == 1)
|
||||
goto return_with_success;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -948,13 +1000,18 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
return;
|
||||
if (!S_ISLNK(st.st_mode))
|
||||
statret = -1;
|
||||
} else if (basis_dir[0] != NULL && can_link_symlinks) {
|
||||
} else if (basis_dir[0] != NULL) {
|
||||
if (try_dests_non(file, fname, ndx, itemizing,
|
||||
&can_link_symlinks,
|
||||
maybe_ATTRS_REPORT, code) == -2) {
|
||||
#ifndef CAN_HARDLINK_SYMLINK
|
||||
if (link_dest) {
|
||||
/* Resort to --copy-dest behavior. */
|
||||
} else
|
||||
#endif
|
||||
if (!copy_dest)
|
||||
return;
|
||||
itemizing = code = 0;
|
||||
itemizing = 0;
|
||||
code = FNONE;
|
||||
}
|
||||
}
|
||||
if (preserve_hard_links && file->link_u.links
|
||||
@@ -970,17 +1027,17 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
itemize(file, ndx, statret, &st,
|
||||
ITEM_LOCAL_CHANGE, 0, NULL);
|
||||
}
|
||||
if (code && verbose) {
|
||||
if (code != FNONE && verbose) {
|
||||
rprintf(code, "%s -> %s\n", fname,
|
||||
file->u.link);
|
||||
}
|
||||
if (remove_sent_files && !dry_run) {
|
||||
char numbuf[4];
|
||||
SIVAL(numbuf, 0, ndx);
|
||||
send_msg(MSG_SUCCESS, numbuf, 4);
|
||||
}
|
||||
if (preserve_hard_links && file->link_u.links)
|
||||
hard_link_cluster(file, ndx, itemizing, code);
|
||||
/* This does not check remove_source_files == 1
|
||||
* because this is one of the items that the old
|
||||
* --remove-sent-files option would remove. */
|
||||
if (remove_source_files)
|
||||
goto return_with_success;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
@@ -988,14 +1045,18 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
|
||||
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|
||||
|| (preserve_specials && IS_SPECIAL(file->mode))) {
|
||||
if (statret != 0
|
||||
&& (basis_dir[0] != NULL && can_link_devices)) {
|
||||
if (statret != 0 && basis_dir[0] != NULL) {
|
||||
if (try_dests_non(file, fname, ndx, itemizing,
|
||||
&can_link_devices,
|
||||
maybe_ATTRS_REPORT, code) == -2) {
|
||||
#ifndef CAN_HARDLINK_SPECIAL
|
||||
if (link_dest) {
|
||||
/* Resort to --copy-dest behavior. */
|
||||
} else
|
||||
#endif
|
||||
if (!copy_dest)
|
||||
return;
|
||||
itemizing = code = 0;
|
||||
itemizing = 0;
|
||||
code = FNONE;
|
||||
}
|
||||
}
|
||||
if (statret != 0
|
||||
@@ -1025,12 +1086,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
itemize(file, ndx, statret, &st,
|
||||
ITEM_LOCAL_CHANGE, 0, NULL);
|
||||
}
|
||||
if (code && verbose)
|
||||
if (code != FNONE && verbose)
|
||||
rprintf(code, "%s\n", fname);
|
||||
if (preserve_hard_links && file->link_u.links) {
|
||||
hard_link_cluster(file, ndx,
|
||||
itemizing, code);
|
||||
}
|
||||
if (remove_source_files == 1)
|
||||
goto return_with_success;
|
||||
}
|
||||
} else {
|
||||
if (itemizing)
|
||||
@@ -1038,6 +1101,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
|
||||
if (preserve_hard_links && file->link_u.links)
|
||||
hard_link_cluster(file, ndx, itemizing, code);
|
||||
if (remove_source_files == 1)
|
||||
goto return_with_success;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1092,9 +1157,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
if (statret != 0 && basis_dir[0] != NULL) {
|
||||
int j = try_dests_reg(file, fname, ndx, fnamecmpbuf, &st,
|
||||
itemizing, maybe_ATTRS_REPORT, code);
|
||||
if (j == -2)
|
||||
if (j == -2) {
|
||||
if (remove_source_files == 1)
|
||||
goto return_with_success;
|
||||
return;
|
||||
if (j != -1) {
|
||||
}
|
||||
if (j >= 0) {
|
||||
fnamecmp = fnamecmpbuf;
|
||||
fnamecmp_type = j;
|
||||
statret = 0;
|
||||
@@ -1112,7 +1180,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
} else
|
||||
partialptr = NULL;
|
||||
|
||||
if (statret != 0 && fuzzy_basis && dry_run <= 1) {
|
||||
if (statret != 0 && fuzzy_dirlist && dry_run <= 1) {
|
||||
int j = find_fuzzy(file, fuzzy_dirlist);
|
||||
if (j >= 0) {
|
||||
fuzzy_file = fuzzy_dirlist->files[j];
|
||||
@@ -1159,6 +1227,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
set_file_attrs(fname, file, &st, maybe_ATTRS_REPORT);
|
||||
if (preserve_hard_links && file->link_u.links)
|
||||
hard_link_cluster(file, ndx, itemizing, code);
|
||||
if (remove_source_files != 1)
|
||||
return;
|
||||
return_with_success:
|
||||
if (!dry_run) {
|
||||
char numbuf[4];
|
||||
SIVAL(numbuf, 0, ndx);
|
||||
send_msg(MSG_SUCCESS, numbuf, 4);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1173,7 +1249,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
if (!do_xfers || read_batch || whole_file)
|
||||
goto notify_others;
|
||||
|
||||
if (fuzzy_basis) {
|
||||
if (fuzzy_dirlist) {
|
||||
int j = flist_find(fuzzy_dirlist, file);
|
||||
if (j >= 0) /* don't use changing file as future fuzzy basis */
|
||||
fuzzy_dirlist->files[j]->flags |= FLAG_NO_FUZZY;
|
||||
@@ -1231,6 +1307,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
rprintf(FINFO, "generating and sending sums for %d\n", ndx);
|
||||
|
||||
notify_others:
|
||||
if (remove_source_files && !delay_updates && !phase)
|
||||
increment_active_files(ndx, itemizing, code);
|
||||
write_int(f_out, ndx);
|
||||
if (itemizing) {
|
||||
int iflags = ITEM_TRANSFER;
|
||||
@@ -1285,19 +1363,20 @@ void generate_files(int f_out, struct file_list *flist, char *local_name)
|
||||
int save_ignore_non_existing = ignore_non_existing;
|
||||
int save_do_progress = do_progress;
|
||||
int save_make_backups = make_backups;
|
||||
int dir_tweaking = !(list_only || local_name || dry_run);
|
||||
|
||||
if (protocol_version >= 29) {
|
||||
itemizing = 1;
|
||||
maybe_ATTRS_REPORT = log_format_has_i ? 0 : ATTRS_REPORT;
|
||||
code = daemon_log_format_has_i ? 0 : FLOG;
|
||||
maybe_ATTRS_REPORT = stdout_format_has_i ? 0 : ATTRS_REPORT;
|
||||
code = logfile_format_has_i ? FNONE : FLOG;
|
||||
} else if (am_daemon) {
|
||||
itemizing = daemon_log_format_has_i && do_xfers;
|
||||
itemizing = logfile_format_has_i && do_xfers;
|
||||
maybe_ATTRS_REPORT = ATTRS_REPORT;
|
||||
code = itemizing || !do_xfers ? FCLIENT : FINFO;
|
||||
} else if (!am_server) {
|
||||
itemizing = log_format_has_i;
|
||||
maybe_ATTRS_REPORT = log_format_has_i ? 0 : ATTRS_REPORT;
|
||||
code = itemizing ? 0 : FINFO;
|
||||
itemizing = stdout_format_has_i;
|
||||
maybe_ATTRS_REPORT = stdout_format_has_i ? 0 : ATTRS_REPORT;
|
||||
code = itemizing ? FNONE : FINFO;
|
||||
} else {
|
||||
itemizing = 0;
|
||||
maybe_ATTRS_REPORT = ATTRS_REPORT;
|
||||
@@ -1346,7 +1425,7 @@ void generate_files(int f_out, struct file_list *flist, char *local_name)
|
||||
* them. This is then fixed after the transfer is done. */
|
||||
#ifdef HAVE_CHMOD
|
||||
if (!am_root && S_ISDIR(file->mode) && !(file->mode & S_IWUSR)
|
||||
&& !list_only) {
|
||||
&& dir_tweaking) {
|
||||
mode_t mode = file->mode | S_IWUSR; /* user write */
|
||||
char *fname = local_name ? local_name : fbuf;
|
||||
if (do_chmod(fname, mode) < 0) {
|
||||
@@ -1426,8 +1505,7 @@ void generate_files(int f_out, struct file_list *flist, char *local_name)
|
||||
if (delete_after && !local_name && flist->count > 0)
|
||||
do_delete_pass(flist);
|
||||
|
||||
if ((need_retouch_dir_perms || need_retouch_dir_times)
|
||||
&& !list_only && !local_name && !dry_run) {
|
||||
if ((need_retouch_dir_perms || need_retouch_dir_times) && dir_tweaking) {
|
||||
int j = 0;
|
||||
/* Now we need to fix any directory permissions that were
|
||||
* modified during the transfer and/or re-set any tweaked
|
||||
@@ -1439,6 +1517,16 @@ void generate_files(int f_out, struct file_list *flist, char *local_name)
|
||||
continue;
|
||||
if (!need_retouch_dir_times && file->mode & S_IWUSR)
|
||||
continue;
|
||||
if (file->flags & FLAG_MISSING) {
|
||||
int missing = file->dir.depth;
|
||||
while (++i < flist->count) {
|
||||
file = flist->files[i];
|
||||
if (file->dir.depth <= missing)
|
||||
break;
|
||||
}
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
recv_generator(f_name(file, NULL), file, i, itemizing,
|
||||
maybe_ATTRS_REPORT, code, -1);
|
||||
if (allowed_lull && !(++j % lull_mod))
|
||||
|
||||
28
getgroups.c
28
getgroups.c
@@ -1,28 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* Print out the gids of all groups for the current user. This is like
|
||||
* `id -G` on Linux, but it's too hard to find a portable equivalent.
|
||||
*
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003, 2004 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file getgroups.c
|
||||
*
|
||||
* Print out the gids of all groups for the current user. This is
|
||||
* like `id -G` on Linux, but it's too hard to find a portable
|
||||
* equivalent.
|
||||
**/
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -63,6 +59,6 @@ main(UNUSED(int argc), UNUSED(char *argv[]))
|
||||
if (!gid_in_list)
|
||||
printf("%lu", (unsigned long)gid);
|
||||
printf("\n");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
84
hlink.c
84
hlink.c
@@ -1,30 +1,34 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
* Routines to support hard-linking.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int dry_run;
|
||||
extern int verbose;
|
||||
extern int do_xfers;
|
||||
extern int link_dest;
|
||||
extern int make_backups;
|
||||
extern int log_format_has_i;
|
||||
extern int remove_source_files;
|
||||
extern int stdout_format_has_i;
|
||||
extern char *basis_dir[];
|
||||
extern struct file_list *the_file_list;
|
||||
|
||||
@@ -51,14 +55,14 @@ static int hlink_compare(int *int1, int *int2)
|
||||
return f_name_cmp(f1, f2);
|
||||
}
|
||||
|
||||
static int *hlink_list;
|
||||
static int hlink_count;
|
||||
static int32 *hlink_list;
|
||||
static int32 hlink_count;
|
||||
|
||||
/* Analyze the data in the hlink_list[], remove items that aren't multiply
|
||||
* linked, and replace the dev+inode data with the hlindex+next linked list. */
|
||||
static void link_idev_data(void)
|
||||
{
|
||||
int cur, from, to, start;
|
||||
int32 cur, from, to, start;
|
||||
|
||||
alloc_pool_t hlink_pool;
|
||||
alloc_pool_t idev_pool = the_file_list->hlink_pool;
|
||||
@@ -79,6 +83,7 @@ static void link_idev_data(void)
|
||||
|
||||
FPTR(cur)->F_HLINDEX = to;
|
||||
FPTR(cur)->F_NEXT = hlink_list[++from];
|
||||
FPTR(cur)->link_u.links->link_dest_used = 0;
|
||||
}
|
||||
pool_free(idev_pool, 0, FPTR(cur)->link_u.idev);
|
||||
if (from > start) {
|
||||
@@ -90,6 +95,7 @@ static void link_idev_data(void)
|
||||
FPTR(cur)->F_HLINDEX = to;
|
||||
FPTR(cur)->F_NEXT = head;
|
||||
FPTR(cur)->flags |= FLAG_HLINK_EOL;
|
||||
FPTR(cur)->link_u.links->link_dest_used = 0;
|
||||
hlink_list[to++] = head;
|
||||
} else
|
||||
FPTR(cur)->link_u.links = NULL;
|
||||
@@ -102,7 +108,7 @@ static void link_idev_data(void)
|
||||
hlink_pool = NULL;
|
||||
} else {
|
||||
hlink_count = to;
|
||||
hlink_list = realloc_array(hlink_list, int, hlink_count);
|
||||
hlink_list = realloc_array(hlink_list, int32, hlink_count);
|
||||
if (!hlink_list)
|
||||
out_of_memory("init_hard_links");
|
||||
}
|
||||
@@ -119,7 +125,7 @@ void init_hard_links(void)
|
||||
if (hlink_list)
|
||||
free(hlink_list);
|
||||
|
||||
if (!(hlink_list = new_array(int, the_file_list->count)))
|
||||
if (!(hlink_list = new_array(int32, the_file_list->count)))
|
||||
out_of_memory("init_hard_links");
|
||||
|
||||
hlink_count = 0;
|
||||
@@ -181,13 +187,19 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
head = hlink_list[file->F_HLINDEX];
|
||||
if (ndx != head) {
|
||||
struct file_struct *head_file = FPTR(head);
|
||||
if (!log_format_has_i && verbose > 1) {
|
||||
if (!stdout_format_has_i && verbose > 1) {
|
||||
rprintf(FINFO, "\"%s\" is a hard link\n",
|
||||
f_name(file, NULL));
|
||||
}
|
||||
if (head_file->F_HLINDEX == FINISHED_LINK) {
|
||||
STRUCT_STAT st2, st3;
|
||||
char *toname = f_name(head_file, NULL);
|
||||
char toname[MAXPATHLEN];
|
||||
int ldu = head_file->link_u.links->link_dest_used;
|
||||
if (ldu) {
|
||||
pathjoin(toname, MAXPATHLEN, basis_dir[ldu-1],
|
||||
f_name(head_file, NULL));
|
||||
} else
|
||||
f_name(head_file, toname);
|
||||
if (link_stat(toname, &st2, 0) < 0) {
|
||||
rsyserr(FERROR, errno, "stat %s failed",
|
||||
full_fname(toname));
|
||||
@@ -206,8 +218,10 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
continue;
|
||||
statret = 1;
|
||||
st = &st3;
|
||||
if (verbose < 2 || !log_format_has_i)
|
||||
itemizing = code = 0;
|
||||
if (verbose < 2 || !stdout_format_has_i) {
|
||||
itemizing = 0;
|
||||
code = FNONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!unchanged_file(cmpbuf, file, &st3))
|
||||
@@ -220,6 +234,11 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
}
|
||||
maybe_hard_link(file, ndx, fname, statret, st,
|
||||
toname, &st2, itemizing, code);
|
||||
if (remove_source_files == 1 && do_xfers) {
|
||||
char numbuf[4];
|
||||
SIVAL(numbuf, 0, ndx);
|
||||
send_msg(MSG_SUCCESS, numbuf, 4);
|
||||
}
|
||||
file->F_HLINDEX = FINISHED_LINK;
|
||||
} else
|
||||
file->F_HLINDEX = SKIPPED_LINK;
|
||||
@@ -251,7 +270,7 @@ int hard_link_one(struct file_struct *file, int ndx, char *fname,
|
||||
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
|
||||
terse ? "" : toname);
|
||||
}
|
||||
if (code && verbose && !terse)
|
||||
if (code != FNONE && verbose && !terse)
|
||||
rprintf(code, "%s => %s\n", fname, toname);
|
||||
return 0;
|
||||
}
|
||||
@@ -285,6 +304,11 @@ void hard_link_cluster(struct file_struct *file, int master, int itemizing,
|
||||
statret = link_stat(hlink2, &st2, 0);
|
||||
maybe_hard_link(file, ndx, hlink2, statret, &st2,
|
||||
hlink1, &st1, itemizing, code);
|
||||
if (remove_source_files == 1 && do_xfers) {
|
||||
char numbuf[4];
|
||||
SIVAL(numbuf, 0, ndx);
|
||||
send_msg(MSG_SUCCESS, numbuf, 4);
|
||||
}
|
||||
file->F_HLINDEX = FINISHED_LINK;
|
||||
} while (!(file->flags & FLAG_HLINK_EOL));
|
||||
#endif
|
||||
|
||||
253
io.c
253
io.c
@@ -1,8 +1,10 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
/*
|
||||
* Socket and pipe I/O utilities used in rsync.
|
||||
*
|
||||
* Copyright (C) 1996-2001 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 1996-2001 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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
|
||||
@@ -14,25 +16,17 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file io.c
|
||||
*
|
||||
* Socket and pipe I/O utilities used in rsync.
|
||||
*
|
||||
* rsync provides its own multiplexing system, which is used to send
|
||||
* stderr and stdout over a single socket. We need this because
|
||||
* stdout normally carries the binary data stream, and stderr all our
|
||||
* error messages.
|
||||
/* Rsync provides its own multiplexing system, which is used to send
|
||||
* stderr and stdout over a single socket.
|
||||
*
|
||||
* For historical reasons this is off during the start of the
|
||||
* connection, but it's switched on quite early using
|
||||
* io_start_multiplex_out() and io_start_multiplex_in().
|
||||
**/
|
||||
* io_start_multiplex_out() and io_start_multiplex_in(). */
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -41,7 +35,6 @@
|
||||
|
||||
extern int bwlimit;
|
||||
extern size_t bwlimit_writemax;
|
||||
extern int verbose;
|
||||
extern int io_timeout;
|
||||
extern int allowed_lull;
|
||||
extern int am_server;
|
||||
@@ -53,7 +46,7 @@ extern int read_batch;
|
||||
extern int csum_length;
|
||||
extern int checksum_seed;
|
||||
extern int protocol_version;
|
||||
extern int remove_sent_files;
|
||||
extern int remove_source_files;
|
||||
extern int preserve_hard_links;
|
||||
extern char *filesfrom_host;
|
||||
extern struct stats stats;
|
||||
@@ -64,22 +57,6 @@ int ignore_timeout = 0;
|
||||
int batch_fd = -1;
|
||||
int batch_gen_fd = -1;
|
||||
|
||||
/**
|
||||
* The connection might be dropped at some point; perhaps because the
|
||||
* remote instance crashed. Just giving the offset on the stream is
|
||||
* not very helpful. So instead we try to make io_phase_name point to
|
||||
* something useful.
|
||||
*
|
||||
* For buffered/multiplexed I/O these names will be somewhat
|
||||
* approximate; perhaps for ease of support we would rather make the
|
||||
* buffer always flush when a single application-level I/O finishes.
|
||||
*
|
||||
* @todo Perhaps we want some simple stack functionality, but there's
|
||||
* no need to overdo it.
|
||||
**/
|
||||
const char *io_write_phase = phase_unknown;
|
||||
const char *io_read_phase = phase_unknown;
|
||||
|
||||
/* Ignore an EOF error if non-zero. See whine_about_eof(). */
|
||||
int kluge_around_eof = 0;
|
||||
|
||||
@@ -103,8 +80,10 @@ static char io_filesfrom_buf[2048];
|
||||
static char *io_filesfrom_bp;
|
||||
static char io_filesfrom_lastchar;
|
||||
static int io_filesfrom_buflen;
|
||||
static size_t contiguous_write_len = 0;
|
||||
static int defer_forwarding_messages = 0;
|
||||
static int select_timeout = SELECT_TIMEOUT;
|
||||
static int active_filecnt = 0;
|
||||
static OFF_T active_bytecnt = 0;
|
||||
|
||||
static void read_loop(int fd, char *buf, size_t len);
|
||||
|
||||
@@ -121,15 +100,15 @@ static struct flist_ndx_list redo_list, hlink_list;
|
||||
|
||||
struct msg_list_item {
|
||||
struct msg_list_item *next;
|
||||
char *buf;
|
||||
int len;
|
||||
char buf[1];
|
||||
};
|
||||
|
||||
struct msg_list {
|
||||
struct msg_list_item *head, *tail;
|
||||
};
|
||||
|
||||
static struct msg_list msg_list;
|
||||
static struct msg_list msg2genr, msg2sndr;
|
||||
|
||||
static void flist_ndx_push(struct flist_ndx_list *lp, int ndx)
|
||||
{
|
||||
@@ -225,23 +204,22 @@ void set_msg_fd_out(int fd)
|
||||
}
|
||||
|
||||
/* Add a message to the pending MSG_* list. */
|
||||
static void msg_list_add(int code, char *buf, int len)
|
||||
static void msg_list_add(struct msg_list *lst, int code, char *buf, int len)
|
||||
{
|
||||
struct msg_list_item *ml;
|
||||
struct msg_list_item *m;
|
||||
int sz = len + 4 + sizeof m[0] - 1;
|
||||
|
||||
if (!(ml = new(struct msg_list_item)))
|
||||
if (!(m = (struct msg_list_item *)new_array(char, sz)))
|
||||
out_of_memory("msg_list_add");
|
||||
ml->next = NULL;
|
||||
if (!(ml->buf = new_array(char, len+4)))
|
||||
out_of_memory("msg_list_add");
|
||||
SIVAL(ml->buf, 0, ((code+MPLEX_BASE)<<24) | len);
|
||||
memcpy(ml->buf+4, buf, len);
|
||||
ml->len = len+4;
|
||||
if (msg_list.tail)
|
||||
msg_list.tail->next = ml;
|
||||
m->next = NULL;
|
||||
m->len = len + 4;
|
||||
SIVAL(m->buf, 0, ((code+MPLEX_BASE)<<24) | len);
|
||||
memcpy(m->buf + 4, buf, len);
|
||||
if (lst->tail)
|
||||
lst->tail->next = m;
|
||||
else
|
||||
msg_list.head = ml;
|
||||
msg_list.tail = ml;
|
||||
lst->head = m;
|
||||
lst->tail = m;
|
||||
}
|
||||
|
||||
/* Read a message from the MSG_* fd and handle it. This is called either
|
||||
@@ -279,6 +257,8 @@ static void read_msg_fd(void)
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
read_loop(fd, buf, 4);
|
||||
if (remove_source_files)
|
||||
decrement_active_files(IVAL(buf,0));
|
||||
flist_ndx_push(&redo_list, IVAL(buf,0));
|
||||
break;
|
||||
case MSG_DELETED:
|
||||
@@ -287,7 +267,7 @@ static void read_msg_fd(void)
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
read_loop(fd, buf, len);
|
||||
io_multiplex_write(MSG_DELETED, buf, len);
|
||||
send_msg(MSG_DELETED, buf, len);
|
||||
break;
|
||||
case MSG_SUCCESS:
|
||||
if (len != 4 || !am_generator) {
|
||||
@@ -295,8 +275,10 @@ static void read_msg_fd(void)
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
read_loop(fd, buf, len);
|
||||
if (remove_sent_files)
|
||||
io_multiplex_write(MSG_SUCCESS, buf, len);
|
||||
if (remove_source_files) {
|
||||
decrement_active_files(IVAL(buf,0));
|
||||
send_msg(MSG_SUCCESS, buf, len);
|
||||
}
|
||||
if (preserve_hard_links)
|
||||
flist_ndx_push(&hlink_list, IVAL(buf,0));
|
||||
break;
|
||||
@@ -315,22 +297,45 @@ static void read_msg_fd(void)
|
||||
if (n >= sizeof buf)
|
||||
n = sizeof buf - 1;
|
||||
read_loop(fd, buf, n);
|
||||
rwrite((enum logcode)tag, buf, n);
|
||||
rwrite(tag, buf, n);
|
||||
len -= n;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rprintf(FERROR, "unknown message %d:%d\n", tag, len);
|
||||
rprintf(FERROR, "unknown message %d:%d [%s]\n",
|
||||
tag, len, who_am_i());
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
msg_fd_in = fd;
|
||||
}
|
||||
|
||||
/* This is used by the generator to limit how many file transfers can
|
||||
* be active at once when --remove-source-files is specified. Without
|
||||
* this, sender-side deletions were mostly happening at the end. */
|
||||
void increment_active_files(int ndx, int itemizing, enum logcode code)
|
||||
{
|
||||
/* TODO: tune these limits? */
|
||||
while (active_filecnt >= (active_bytecnt >= 128*1024 ? 10 : 50)) {
|
||||
if (hlink_list.head)
|
||||
check_for_finished_hlinks(itemizing, code);
|
||||
read_msg_fd();
|
||||
}
|
||||
|
||||
active_filecnt++;
|
||||
active_bytecnt += the_file_list->files[ndx]->length;
|
||||
}
|
||||
|
||||
void decrement_active_files(int ndx)
|
||||
{
|
||||
active_filecnt--;
|
||||
active_bytecnt -= the_file_list->files[ndx]->length;
|
||||
}
|
||||
|
||||
/* Try to push messages off the list onto the wire. If we leave with more
|
||||
* to do, return 0. On error, return -1. If everything flushed, return 1.
|
||||
* This is only active in the receiver. */
|
||||
static int msg_list_flush(int flush_it_all)
|
||||
static int msg2genr_flush(int flush_it_all)
|
||||
{
|
||||
static int written = 0;
|
||||
struct timeval tv;
|
||||
@@ -339,9 +344,9 @@ static int msg_list_flush(int flush_it_all)
|
||||
if (msg_fd_out < 0)
|
||||
return -1;
|
||||
|
||||
while (msg_list.head) {
|
||||
struct msg_list_item *ml = msg_list.head;
|
||||
int n = write(msg_fd_out, ml->buf + written, ml->len - written);
|
||||
while (msg2genr.head) {
|
||||
struct msg_list_item *m = msg2genr.head;
|
||||
int n = write(msg_fd_out, m->buf + written, m->len - written);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
@@ -355,26 +360,30 @@ static int msg_list_flush(int flush_it_all)
|
||||
tv.tv_usec = 0;
|
||||
if (!select(msg_fd_out+1, NULL, &fds, NULL, &tv))
|
||||
check_timeout();
|
||||
} else if ((written += n) == ml->len) {
|
||||
free(ml->buf);
|
||||
msg_list.head = ml->next;
|
||||
if (!msg_list.head)
|
||||
msg_list.tail = NULL;
|
||||
free(ml);
|
||||
} else if ((written += n) == m->len) {
|
||||
msg2genr.head = m->next;
|
||||
if (!msg2genr.head)
|
||||
msg2genr.tail = NULL;
|
||||
free(m);
|
||||
written = 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void send_msg(enum msgcode code, char *buf, int len)
|
||||
int send_msg(enum msgcode code, char *buf, int len)
|
||||
{
|
||||
if (msg_fd_out < 0) {
|
||||
io_multiplex_write(code, buf, len);
|
||||
return;
|
||||
if (!defer_forwarding_messages)
|
||||
return io_multiplex_write(code, buf, len);
|
||||
if (!io_multiplexing_out)
|
||||
return 0;
|
||||
msg_list_add(&msg2sndr, code, buf, len);
|
||||
return 1;
|
||||
}
|
||||
msg_list_add(code, buf, len);
|
||||
msg_list_flush(NORMAL_FLUSH);
|
||||
msg_list_add(&msg2genr, code, buf, len);
|
||||
msg2genr_flush(NORMAL_FLUSH);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int get_redo_num(int itemizing, enum logcode code)
|
||||
@@ -471,7 +480,7 @@ static int read_timeout(int fd, char *buf, size_t len)
|
||||
FD_ZERO(&r_fds);
|
||||
FD_ZERO(&w_fds);
|
||||
FD_SET(fd, &r_fds);
|
||||
if (msg_list.head) {
|
||||
if (msg2genr.head) {
|
||||
FD_SET(msg_fd_out, &w_fds);
|
||||
if (msg_fd_out > maxfd)
|
||||
maxfd = msg_fd_out;
|
||||
@@ -508,8 +517,8 @@ static int read_timeout(int fd, char *buf, size_t len)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (msg_list.head && FD_ISSET(msg_fd_out, &w_fds))
|
||||
msg_list_flush(NORMAL_FLUSH);
|
||||
if (msg2genr.head && FD_ISSET(msg_fd_out, &w_fds))
|
||||
msg2genr_flush(NORMAL_FLUSH);
|
||||
|
||||
if (io_filesfrom_f_out >= 0) {
|
||||
if (io_filesfrom_buflen) {
|
||||
@@ -624,13 +633,19 @@ int read_filesfrom_line(int fd, char *fname)
|
||||
if (cnt < 0 && (errno == EWOULDBLOCK
|
||||
|| errno == EINTR || errno == EAGAIN)) {
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
fd_set r_fds, e_fds;
|
||||
FD_ZERO(&r_fds);
|
||||
FD_SET(fd, &r_fds);
|
||||
FD_ZERO(&e_fds);
|
||||
FD_SET(fd, &e_fds);
|
||||
tv.tv_sec = select_timeout;
|
||||
tv.tv_usec = 0;
|
||||
if (!select(fd+1, &fds, NULL, NULL, &tv))
|
||||
if (!select(fd+1, &r_fds, NULL, &e_fds, &tv))
|
||||
check_timeout();
|
||||
if (FD_ISSET(fd, &e_fds)) {
|
||||
rsyserr(FINFO, errno,
|
||||
"select exception on fd %d", fd);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (cnt != 1)
|
||||
@@ -921,6 +936,11 @@ int read_vstring(int f, char *buf, int bufsize)
|
||||
void read_sum_head(int f, struct sum_struct *sum)
|
||||
{
|
||||
sum->count = read_int(f);
|
||||
if (sum->count < 0) {
|
||||
rprintf(FERROR, "Invalid checksum count %ld [%s]\n",
|
||||
(long)sum->count, who_am_i());
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
sum->blength = read_int(f);
|
||||
if (sum->blength < 0 || sum->blength > MAX_BLOCK_SIZE) {
|
||||
rprintf(FERROR, "Invalid block length %ld [%s]\n",
|
||||
@@ -977,16 +997,16 @@ void write_sum_head(int f, struct sum_struct *sum)
|
||||
static void sleep_for_bwlimit(int bytes_written)
|
||||
{
|
||||
static struct timeval prior_tv;
|
||||
static long total_written = 0;
|
||||
static long total_written = 0;
|
||||
struct timeval tv, start_tv;
|
||||
long elapsed_usec, sleep_usec;
|
||||
|
||||
#define ONE_SEC 1000000L /* # of microseconds in a second */
|
||||
|
||||
if (!bwlimit)
|
||||
if (!bwlimit_writemax)
|
||||
return;
|
||||
|
||||
total_written += bytes_written;
|
||||
total_written += bytes_written;
|
||||
|
||||
gettimeofday(&start_tv, NULL);
|
||||
if (prior_tv.tv_sec) {
|
||||
@@ -1022,20 +1042,23 @@ static void sleep_for_bwlimit(int bytes_written)
|
||||
static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
{
|
||||
size_t n, total = 0;
|
||||
fd_set w_fds, r_fds;
|
||||
fd_set w_fds, r_fds, e_fds;
|
||||
int maxfd, count, cnt, using_r_fds;
|
||||
int defer_save = defer_forwarding_messages;
|
||||
struct timeval tv;
|
||||
|
||||
no_flush++;
|
||||
|
||||
while (total < len) {
|
||||
FD_ZERO(&w_fds);
|
||||
FD_SET(fd,&w_fds);
|
||||
FD_SET(fd, &w_fds);
|
||||
FD_ZERO(&e_fds);
|
||||
FD_SET(fd, &e_fds);
|
||||
maxfd = fd;
|
||||
|
||||
if (msg_fd_in >= 0 && len-total >= contiguous_write_len) {
|
||||
if (msg_fd_in >= 0) {
|
||||
FD_ZERO(&r_fds);
|
||||
FD_SET(msg_fd_in,&r_fds);
|
||||
FD_SET(msg_fd_in, &r_fds);
|
||||
if (msg_fd_in > maxfd)
|
||||
maxfd = msg_fd_in;
|
||||
using_r_fds = 1;
|
||||
@@ -1047,7 +1070,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
|
||||
errno = 0;
|
||||
count = select(maxfd + 1, using_r_fds ? &r_fds : NULL,
|
||||
&w_fds, NULL, &tv);
|
||||
&w_fds, &e_fds, &tv);
|
||||
|
||||
if (count <= 0) {
|
||||
if (count < 0 && errno == EBADF)
|
||||
@@ -1056,6 +1079,11 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &e_fds)) {
|
||||
rsyserr(FINFO, errno,
|
||||
"select exception on fd %d", fd);
|
||||
}
|
||||
|
||||
if (using_r_fds && FD_ISSET(msg_fd_in, &r_fds))
|
||||
read_msg_fd();
|
||||
|
||||
@@ -1063,7 +1091,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
continue;
|
||||
|
||||
n = len - total;
|
||||
if (bwlimit && n > bwlimit_writemax)
|
||||
if (bwlimit_writemax && n > bwlimit_writemax)
|
||||
n = bwlimit_writemax;
|
||||
cnt = write(fd, buf + total, n);
|
||||
|
||||
@@ -1081,8 +1109,8 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
if (fd == sock_f_out)
|
||||
close_multiplexing_out();
|
||||
rsyserr(FERROR, errno,
|
||||
"writefd_unbuffered failed to write %ld bytes: phase \"%s\" [%s]",
|
||||
(long)len, io_write_phase, who_am_i());
|
||||
"writefd_unbuffered failed to write %ld bytes [%s]",
|
||||
(long)len, who_am_i());
|
||||
/* If the other side is sending us error messages, try
|
||||
* to grab any messages they sent before they died. */
|
||||
while (fd == sock_f_out && io_multiplexing_in) {
|
||||
@@ -1095,6 +1123,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
}
|
||||
|
||||
total += cnt;
|
||||
defer_forwarding_messages = 1;
|
||||
|
||||
if (fd == sock_f_out) {
|
||||
if (io_timeout || am_generator)
|
||||
@@ -1103,9 +1132,27 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
defer_forwarding_messages = defer_save;
|
||||
no_flush--;
|
||||
}
|
||||
|
||||
static void msg2sndr_flush(void)
|
||||
{
|
||||
if (defer_forwarding_messages)
|
||||
return;
|
||||
|
||||
while (msg2sndr.head && io_multiplexing_out) {
|
||||
struct msg_list_item *m = msg2sndr.head;
|
||||
if (!(msg2sndr.head = m->next))
|
||||
msg2sndr.tail = NULL;
|
||||
stats.total_written += m->len;
|
||||
defer_forwarding_messages = 1;
|
||||
writefd_unbuffered(sock_f_out, m->buf, m->len);
|
||||
defer_forwarding_messages = 0;
|
||||
free(m);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an message to a multiplexed stream. If this fails then rsync
|
||||
* exits.
|
||||
@@ -1117,13 +1164,6 @@ static void mplex_write(enum msgcode code, char *buf, size_t len)
|
||||
|
||||
SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
|
||||
|
||||
/* When the generator reads messages from the msg_fd_in pipe, it can
|
||||
* cause output to occur down the socket. Setting contiguous_write_len
|
||||
* prevents the reading of msg_fd_in once we actually start to write
|
||||
* this sequence of data (though we might read it before the start). */
|
||||
if (am_generator && msg_fd_in >= 0)
|
||||
contiguous_write_len = len + 4;
|
||||
|
||||
if (n > sizeof buffer - 4)
|
||||
n = 0;
|
||||
else
|
||||
@@ -1134,16 +1174,18 @@ static void mplex_write(enum msgcode code, char *buf, size_t len)
|
||||
len -= n;
|
||||
buf += n;
|
||||
|
||||
if (len)
|
||||
if (len) {
|
||||
defer_forwarding_messages = 1;
|
||||
writefd_unbuffered(sock_f_out, buf, len);
|
||||
|
||||
if (am_generator && msg_fd_in >= 0)
|
||||
contiguous_write_len = 0;
|
||||
defer_forwarding_messages = 0;
|
||||
msg2sndr_flush();
|
||||
}
|
||||
}
|
||||
|
||||
void io_flush(int flush_it_all)
|
||||
{
|
||||
msg_list_flush(flush_it_all);
|
||||
msg2genr_flush(flush_it_all);
|
||||
msg2sndr_flush();
|
||||
|
||||
if (!iobuf_out_cnt || no_flush)
|
||||
return;
|
||||
@@ -1204,13 +1246,6 @@ void write_int(int f,int32 x)
|
||||
writefd(f,b,4);
|
||||
}
|
||||
|
||||
void write_int_named(int f, int32 x, const char *phase)
|
||||
{
|
||||
io_write_phase = phase;
|
||||
write_int(f, x);
|
||||
io_write_phase = phase_unknown;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: int64 may actually be a 32-bit type if ./configure couldn't find any
|
||||
* 64-bit types on this platform.
|
||||
|
||||
106
lib/compat.c
106
lib/compat.c
@@ -1,42 +1,35 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file compat.c
|
||||
/*
|
||||
* Reimplementations of standard functions for platforms that don't have them.
|
||||
*
|
||||
* Reimplementations of standard functions for platforms that don't
|
||||
* have them.
|
||||
**/
|
||||
|
||||
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
char *strdup(char *s)
|
||||
{
|
||||
int l = strlen(s) + 1;
|
||||
char *ret = (char *)malloc(l);
|
||||
if (ret)
|
||||
strcpy(ret,s);
|
||||
return ret;
|
||||
int len = strlen(s) + 1;
|
||||
char *ret = (char *)malloc(len);
|
||||
if (ret)
|
||||
memcpy(ret, s, len);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -86,7 +79,7 @@
|
||||
/**
|
||||
* Find the first ocurrence in @p s of any character in @p accept.
|
||||
*
|
||||
* Derived from glibc
|
||||
* Derived from glibc
|
||||
**/
|
||||
char *strpbrk(const char *s, const char *accept)
|
||||
{
|
||||
@@ -105,7 +98,7 @@
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/**
|
||||
* Like strncpy but does not 0 fill the buffer and always null
|
||||
* Like strncpy but does not 0 fill the buffer and always null
|
||||
* terminates.
|
||||
*
|
||||
* @param bufsize is the size of the destination buffer.
|
||||
@@ -128,7 +121,7 @@
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/**
|
||||
* Like strncat() but does not 0 fill the buffer and always null
|
||||
* Like strncat() but does not 0 fill the buffer and always null
|
||||
* terminates.
|
||||
*
|
||||
* @param bufsize length of the buffer, which should be one more than
|
||||
@@ -150,49 +143,6 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REPLACE_INET_NTOA
|
||||
char *rep_inet_ntoa(struct in_addr ip)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)&ip.s_addr;
|
||||
static char buf[18];
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
snprintf(buf, 18, "%d.%d.%d.%d",
|
||||
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
|
||||
#else
|
||||
snprintf(buf, 18, "%d.%d.%d.%d",
|
||||
(int)p[3], (int)p[2], (int)p[1], (int)p[0]);
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REPLACE_INET_ATON
|
||||
int inet_aton(const char *cp, struct in_addr *inp)
|
||||
{
|
||||
unsigned int a1, a2, a3, a4;
|
||||
unsigned long ret;
|
||||
|
||||
if (strcmp(cp, "255.255.255.255") == 0) {
|
||||
inp->s_addr = (unsigned) -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sscanf(cp, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4 ||
|
||||
a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = (a1 << 24) | (a2 << 16) | (a3 << 8) | a4;
|
||||
|
||||
inp->s_addr = htonl(ret);
|
||||
|
||||
if (inp->s_addr == (unsigned) -1) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* some systems don't take the 2nd argument */
|
||||
int sys_gettimeofday(struct timeval *tv)
|
||||
{
|
||||
|
||||
@@ -75,13 +75,14 @@ inet_ntop4(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
static const char *fmt = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
size_t len;
|
||||
|
||||
if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
|
||||
{
|
||||
len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]);
|
||||
if (len >= size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
memcpy(dst, tmp, len + 1);
|
||||
|
||||
return (dst);
|
||||
}
|
||||
@@ -106,7 +107,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
int i, inc;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
@@ -157,13 +158,14 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp,
|
||||
sizeof tmp - (tp - tmp)))
|
||||
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += sprintf(tp, "%x", words[i]);
|
||||
inc = snprintf(tp, 5, "%x", words[i]);
|
||||
assert(inc < 5);
|
||||
tp += inc;
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
@@ -178,7 +180,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
memcpy(dst, tmp, tp - tmp);
|
||||
return (dst);
|
||||
}
|
||||
#endif /* AF_INET6 */
|
||||
|
||||
45
lib/mdfour.c
45
lib/mdfour.c
@@ -1,30 +1,31 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
a implementation of MD4 designed for use in the SMB authentication protocol
|
||||
Copyright (C) Andrew Tridgell 1997-1998.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
* Unix SMB/Netbios implementation.
|
||||
* Version 1.9.
|
||||
* An implementation of MD4 designed for use in the SMB authentication protocol.
|
||||
*
|
||||
* Copyright (C) 1997-1998 Andrew Tridgell
|
||||
* Copyright (C) 2005 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/* NOTE: This code makes no attempt to be fast!
|
||||
|
||||
It assumes that a int is at least 32 bits long
|
||||
*/
|
||||
*
|
||||
* It assumes that a int is at least 32 bits long. */
|
||||
|
||||
static struct mdfour *m;
|
||||
|
||||
|
||||
43
lib/mdfour.h
43
lib/mdfour.h
@@ -1,23 +1,24 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
a implementation of MD4 designed for use in the SMB authentication protocol
|
||||
Copyright (C) Andrew Tridgell 1997-1998.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
* Unix SMB/Netbios implementation.
|
||||
* Version 1.9.
|
||||
* An implementation of MD4 designed for use in the SMB authentication protocol.
|
||||
*
|
||||
* Copyright (C) 1997-1998 Andrew Tridgell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
struct mdfour {
|
||||
uint32 A, B, C, D;
|
||||
@@ -29,7 +30,3 @@ void mdfour_begin(struct mdfour *md);
|
||||
void mdfour_update(struct mdfour *md, unsigned char *in, uint32 n);
|
||||
void mdfour_result(struct mdfour *md, unsigned char *out);
|
||||
void mdfour(unsigned char *out, unsigned char *in, int n);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* A single utility routine.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/**
|
||||
* Produce a string representation of Unix mode bits like that used by
|
||||
* ls(1).
|
||||
*
|
||||
* @param buf buffer of at least 11 characters
|
||||
**/
|
||||
/* Produce a string representation of Unix mode bits like that used by ls(1).
|
||||
* The "buf" buffer must be at least 11 characters. */
|
||||
void permstring(char *perms, mode_t mode)
|
||||
{
|
||||
static const char *perm_map = "rwxrwxrwx";
|
||||
int i;
|
||||
|
||||
strcpy(perms, "----------");
|
||||
|
||||
for (i=0;i<9;i++) {
|
||||
if (mode & (1<<i)) perms[9-i] = perm_map[8-i];
|
||||
strlcpy(perms, "----------", 11);
|
||||
|
||||
for (i = 0; i < 9; i++) {
|
||||
if (mode & (1 << i))
|
||||
perms[9-i] = perm_map[8-i];
|
||||
}
|
||||
|
||||
/* Handle setuid/sticky bits. You might think the indices are
|
||||
@@ -45,18 +45,22 @@ void permstring(char *perms, mode_t mode)
|
||||
|
||||
if (mode & S_ISGID)
|
||||
perms[6] = (mode & S_IXGRP) ? 's' : 'S';
|
||||
|
||||
|
||||
#ifdef S_ISVTX
|
||||
if (mode & S_ISVTX)
|
||||
perms[9] = (mode & S_IXOTH) ? 't' : 'T';
|
||||
#endif
|
||||
|
||||
if (S_ISLNK(mode)) perms[0] = 'l';
|
||||
if (S_ISDIR(mode)) perms[0] = 'd';
|
||||
if (S_ISBLK(mode)) perms[0] = 'b';
|
||||
if (S_ISCHR(mode)) perms[0] = 'c';
|
||||
if (S_ISSOCK(mode)) perms[0] = 's';
|
||||
if (S_ISFIFO(mode)) perms[0] = 'p';
|
||||
}
|
||||
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
perms[0] = 'd';
|
||||
else if (S_ISLNK(mode))
|
||||
perms[0] = 'l';
|
||||
else if (S_ISBLK(mode))
|
||||
perms[0] = 'b';
|
||||
else if (S_ISCHR(mode))
|
||||
perms[0] = 'c';
|
||||
else if (S_ISSOCK(mode))
|
||||
perms[0] = 's';
|
||||
else if (S_ISFIFO(mode))
|
||||
perms[0] = 'p';
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ pool_stats(alloc_pool_t p, int fd, int summarize)
|
||||
|
||||
if (pool->live)
|
||||
FDEXTSTAT(pool->live);
|
||||
strcpy(buf, " FREE BOUND\n");
|
||||
strlcpy(buf, " FREE BOUND\n", sizeof buf);
|
||||
write(fd, buf, strlen(buf));
|
||||
|
||||
for (cur = pool->free; cur; cur = cur->next)
|
||||
|
||||
111
loadparm.c
111
loadparm.c
@@ -1,26 +1,26 @@
|
||||
/* This is based on loadparm.c from Samba, written by Andrew Tridgell
|
||||
and Karl Auer */
|
||||
|
||||
/* some fixes
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* some fixes
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Load parameters.
|
||||
@@ -57,6 +57,10 @@
|
||||
typedef char pstring[1024];
|
||||
#define pstrcpy(a,b) strlcpy(a,b,sizeof(pstring))
|
||||
|
||||
#ifndef LOG_DAEMON
|
||||
#define LOG_DAEMON 0
|
||||
#endif
|
||||
|
||||
/* the following are used by loadparm for option lists */
|
||||
typedef enum
|
||||
{
|
||||
@@ -99,13 +103,11 @@ struct parm_struct
|
||||
typedef struct
|
||||
{
|
||||
char *bind_address;
|
||||
char *log_file;
|
||||
char *motd_file;
|
||||
char *pid_file;
|
||||
char *socket_options;
|
||||
|
||||
int rsync_port;
|
||||
int syslog_facility;
|
||||
} global;
|
||||
|
||||
static global Globals;
|
||||
@@ -131,6 +133,7 @@ typedef struct
|
||||
char *include_from;
|
||||
char *incoming_chmod;
|
||||
char *lock_file;
|
||||
char *log_file;
|
||||
char *log_format;
|
||||
char *name;
|
||||
char *outgoing_chmod;
|
||||
@@ -144,6 +147,7 @@ typedef struct
|
||||
|
||||
int max_connections;
|
||||
int max_verbosity;
|
||||
int syslog_facility;
|
||||
int timeout;
|
||||
|
||||
BOOL ignore_errors;
|
||||
@@ -176,6 +180,7 @@ static service sDefault =
|
||||
/* include_from; */ NULL,
|
||||
/* incoming_chmod; */ NULL,
|
||||
/* lock_file; */ DEFAULT_LOCK_FILE,
|
||||
/* log_file; */ NULL,
|
||||
/* log_format; */ "%o %h [%a] %m (%u) %f %l",
|
||||
/* name; */ NULL,
|
||||
/* outgoing_chmod; */ NULL,
|
||||
@@ -189,6 +194,7 @@ static service sDefault =
|
||||
|
||||
/* max_connections; */ 0,
|
||||
/* max_verbosity; */ 1,
|
||||
/* syslog_facility; */ LOG_DAEMON,
|
||||
/* timeout; */ 0,
|
||||
|
||||
/* ignore_errors; */ False,
|
||||
@@ -282,12 +288,10 @@ static struct enum_list enum_facilities[] = {
|
||||
static struct parm_struct parm_table[] =
|
||||
{
|
||||
{"address", P_STRING, P_GLOBAL,&Globals.bind_address, NULL,0},
|
||||
{"log file", P_STRING, P_GLOBAL,&Globals.log_file, NULL,0},
|
||||
{"motd file", P_STRING, P_GLOBAL,&Globals.motd_file, NULL,0},
|
||||
{"pid file", P_STRING, P_GLOBAL,&Globals.pid_file, NULL,0},
|
||||
{"port", P_INTEGER,P_GLOBAL,&Globals.rsync_port, NULL,0},
|
||||
{"socket options", P_STRING, P_GLOBAL,&Globals.socket_options, NULL,0},
|
||||
{"syslog facility", P_ENUM, P_GLOBAL,&Globals.syslog_facility,enum_facilities,0},
|
||||
|
||||
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL,0},
|
||||
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL,0},
|
||||
@@ -305,6 +309,7 @@ static struct parm_struct parm_table[] =
|
||||
{"incoming chmod", P_STRING, P_LOCAL, &sDefault.incoming_chmod, NULL,0},
|
||||
{"list", P_BOOL, P_LOCAL, &sDefault.list, NULL,0},
|
||||
{"lock file", P_STRING, P_LOCAL, &sDefault.lock_file, NULL,0},
|
||||
{"log file", P_STRING, P_LOCAL, &sDefault.log_file, NULL,0},
|
||||
{"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL,0},
|
||||
{"max connections", P_INTEGER,P_LOCAL, &sDefault.max_connections, NULL,0},
|
||||
{"max verbosity", P_INTEGER,P_LOCAL, &sDefault.max_verbosity, NULL,0},
|
||||
@@ -319,6 +324,7 @@ static struct parm_struct parm_table[] =
|
||||
{"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options, NULL,0},
|
||||
{"secrets file", P_STRING, P_LOCAL, &sDefault.secrets_file, NULL,0},
|
||||
{"strict modes", P_BOOL, P_LOCAL, &sDefault.strict_modes, NULL,0},
|
||||
{"syslog facility", P_ENUM, P_LOCAL, &sDefault.syslog_facility,enum_facilities,0},
|
||||
{"temp dir", P_PATH, P_LOCAL, &sDefault.temp_dir, NULL,0},
|
||||
{"timeout", P_INTEGER,P_LOCAL, &sDefault.timeout, NULL,0},
|
||||
{"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging, NULL,0},
|
||||
@@ -330,18 +336,15 @@ static struct parm_struct parm_table[] =
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Initialise the global parameter structure.
|
||||
* Initialise the global parameter structure.
|
||||
***************************************************************************/
|
||||
static void init_globals(void)
|
||||
{
|
||||
memset(&Globals, 0, sizeof Globals);
|
||||
#ifdef LOG_DAEMON
|
||||
Globals.syslog_facility = LOG_DAEMON;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Initialise the sDefault parameter structure.
|
||||
* Initialise the sDefault parameter structure.
|
||||
***************************************************************************/
|
||||
static void init_locals(void)
|
||||
{
|
||||
@@ -373,13 +376,11 @@ static void init_locals(void)
|
||||
|
||||
|
||||
FN_GLOBAL_STRING(lp_bind_address, &Globals.bind_address)
|
||||
FN_GLOBAL_STRING(lp_log_file, &Globals.log_file)
|
||||
FN_GLOBAL_STRING(lp_motd_file, &Globals.motd_file)
|
||||
FN_GLOBAL_STRING(lp_pid_file, &Globals.pid_file)
|
||||
FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
|
||||
|
||||
FN_GLOBAL_INTEGER(lp_rsync_port, &Globals.rsync_port)
|
||||
FN_GLOBAL_INTEGER(lp_syslog_facility, &Globals.syslog_facility)
|
||||
|
||||
FN_LOCAL_STRING(lp_auth_users, auth_users)
|
||||
FN_LOCAL_STRING(lp_comment, comment)
|
||||
@@ -394,6 +395,7 @@ FN_LOCAL_STRING(lp_include, include)
|
||||
FN_LOCAL_STRING(lp_include_from, include_from)
|
||||
FN_LOCAL_STRING(lp_incoming_chmod, incoming_chmod)
|
||||
FN_LOCAL_STRING(lp_lock_file, lock_file)
|
||||
FN_LOCAL_STRING(lp_log_file, log_file)
|
||||
FN_LOCAL_STRING(lp_log_format, log_format)
|
||||
FN_LOCAL_STRING(lp_name, name)
|
||||
FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
|
||||
@@ -402,6 +404,7 @@ FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
|
||||
FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
|
||||
FN_LOCAL_STRING(lp_refuse_options, refuse_options)
|
||||
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
|
||||
FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility)
|
||||
FN_LOCAL_STRING(lp_temp_dir, temp_dir)
|
||||
FN_LOCAL_STRING(lp_uid, uid)
|
||||
|
||||
@@ -429,7 +432,7 @@ static BOOL do_section(char *sectionname);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
initialise a service to the defaults
|
||||
* initialise a service to the defaults
|
||||
***************************************************************************/
|
||||
static void init_service(service *pservice)
|
||||
{
|
||||
@@ -463,8 +466,8 @@ static void string_set(char **s, const char *v)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
add a new service to the services array initialising it with the given
|
||||
service
|
||||
* add a new service to the services array initialising it with the given
|
||||
* service
|
||||
***************************************************************************/
|
||||
static int add_a_service(service *pservice, char *name)
|
||||
{
|
||||
@@ -503,7 +506,7 @@ static int add_a_service(service *pservice, char *name)
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Do a case-insensitive, whitespace-ignoring string compare.
|
||||
* Do a case-insensitive, whitespace-ignoring string compare.
|
||||
***************************************************************************/
|
||||
static int strwicmp(char *psz1, char *psz2)
|
||||
{
|
||||
@@ -535,8 +538,8 @@ static int strwicmp(char *psz1, char *psz2)
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Map a parameter's string representation to something we can use.
|
||||
Returns False if the parameter string is not recognised, else TRUE.
|
||||
* Map a parameter's string representation to something we can use.
|
||||
* Returns False if the parameter string is not recognised, else TRUE.
|
||||
***************************************************************************/
|
||||
static int map_parameter(char *parmname)
|
||||
{
|
||||
@@ -555,9 +558,9 @@ static int map_parameter(char *parmname)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Set a boolean variable from the text value stored in the passed string.
|
||||
Returns True in success, False if the passed string does not correctly
|
||||
represent a boolean.
|
||||
* Set a boolean variable from the text value stored in the passed string.
|
||||
* Returns True in success, False if the passed string does not correctly
|
||||
* represent a boolean.
|
||||
***************************************************************************/
|
||||
static BOOL set_boolean(BOOL *pb, char *parmvalue)
|
||||
{
|
||||
@@ -583,7 +586,7 @@ static BOOL set_boolean(BOOL *pb, char *parmvalue)
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Find a service by name. Otherwise works like get_service.
|
||||
* Find a service by name. Otherwise works like get_service.
|
||||
***************************************************************************/
|
||||
static int getservicebyname(char *name, service *pserviceDest)
|
||||
{
|
||||
@@ -603,8 +606,7 @@ static int getservicebyname(char *name, service *pserviceDest)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Copy a service structure to another
|
||||
|
||||
* Copy a service structure to another
|
||||
***************************************************************************/
|
||||
static void copy_service(service *pserviceDest,
|
||||
service *pserviceSource)
|
||||
@@ -649,8 +651,8 @@ static void copy_service(service *pserviceDest,
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Process a parameter for a particular service number. If snum < 0
|
||||
then assume we are in the globals
|
||||
* Process a parameter for a particular service number. If snum < 0
|
||||
* then assume we are in the globals
|
||||
***************************************************************************/
|
||||
static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
|
||||
{
|
||||
@@ -741,7 +743,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Process a parameter.
|
||||
* Process a parameter.
|
||||
***************************************************************************/
|
||||
static BOOL do_parameter(char *parmname, char *parmvalue)
|
||||
{
|
||||
@@ -749,9 +751,9 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Process a new section (service). At this stage all sections are services.
|
||||
Later we'll have special sections that permit server parameters to be set.
|
||||
Returns True on success, False on failure.
|
||||
* Process a new section (service). At this stage all sections are services.
|
||||
* Later we'll have special sections that permit server parameters to be set.
|
||||
* Returns True on success, False on failure.
|
||||
***************************************************************************/
|
||||
static BOOL do_section(char *sectionname)
|
||||
{
|
||||
@@ -796,13 +798,12 @@ static BOOL do_section(char *sectionname)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Load the services array from the services file. Return True on success,
|
||||
False on failure.
|
||||
* Load the services array from the services file. Return True on success,
|
||||
* False on failure.
|
||||
***************************************************************************/
|
||||
BOOL lp_load(char *pszFname, int globals_only)
|
||||
{
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int am_root;
|
||||
pstring n2;
|
||||
BOOL bRetval;
|
||||
@@ -815,7 +816,7 @@ BOOL lp_load(char *pszFname, int globals_only)
|
||||
|
||||
if (pszFname)
|
||||
pstrcpy(n2,pszFname);
|
||||
else if (am_server && am_daemon && !am_root)
|
||||
else if (am_server && !am_root)
|
||||
pstrcpy(n2,RSYNCD_USERCONF);
|
||||
else
|
||||
pstrcpy(n2,RSYNCD_SYSCONF);
|
||||
@@ -829,7 +830,7 @@ BOOL lp_load(char *pszFname, int globals_only)
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
return the max number of services
|
||||
* return the max number of services
|
||||
***************************************************************************/
|
||||
int lp_numservices(void)
|
||||
{
|
||||
@@ -837,10 +838,10 @@ int lp_numservices(void)
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Return the number of the service with the given name, or -1 if it doesn't
|
||||
exist. Note that this is a DIFFERENT ANIMAL from the internal function
|
||||
getservicebyname()! This works ONLY if all services have been loaded, and
|
||||
does not copy the found service.
|
||||
* Return the number of the service with the given name, or -1 if it doesn't
|
||||
* exist. Note that this is a DIFFERENT ANIMAL from the internal function
|
||||
* getservicebyname()! This works ONLY if all services have been loaded, and
|
||||
* does not copy the found service.
|
||||
***************************************************************************/
|
||||
int lp_number(char *name)
|
||||
{
|
||||
|
||||
236
log.c
236
log.c
@@ -1,30 +1,25 @@
|
||||
/* -*- c-file-style: "linux"; -*-
|
||||
|
||||
Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2000-2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
Logging and utility functions.
|
||||
tridge, May 1998
|
||||
* Logging and utility functions.
|
||||
*
|
||||
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2000-2001 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
Mapping to human-readable messages added by Martin Pool
|
||||
<mbp@samba.org>, Oct 2000.
|
||||
*/
|
||||
#include "rsync.h"
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
#include <iconv.h>
|
||||
@@ -42,19 +37,24 @@ extern int msg_fd_out;
|
||||
extern int allow_8bit_chars;
|
||||
extern int protocol_version;
|
||||
extern int preserve_times;
|
||||
extern int log_format_has_i;
|
||||
extern int log_format_has_o_or_i;
|
||||
extern int daemon_log_format_has_o_or_i;
|
||||
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 mode_t orig_umask;
|
||||
extern char *auth_user;
|
||||
extern char *log_format;
|
||||
extern char *stdout_format;
|
||||
extern char *logfile_format;
|
||||
extern char *logfile_name;
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
extern iconv_t ic_chck;
|
||||
#endif
|
||||
extern char curr_dir[];
|
||||
extern unsigned int module_dirlen;
|
||||
|
||||
static int log_initialised;
|
||||
static int logfile_was_closed;
|
||||
static char *logfname;
|
||||
static FILE *logfile;
|
||||
static FILE *logfile_fp;
|
||||
struct stats stats;
|
||||
|
||||
int log_got_error = 0;
|
||||
@@ -90,7 +90,6 @@ struct {
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Map from rsync error code to name, or return NULL.
|
||||
*/
|
||||
@@ -108,10 +107,10 @@ static void logit(int priority, char *buf)
|
||||
{
|
||||
if (logfile_was_closed)
|
||||
logfile_reopen();
|
||||
if (logfile) {
|
||||
fprintf(logfile,"%s [%d] %s",
|
||||
if (logfile_fp) {
|
||||
fprintf(logfile_fp, "%s [%d] %s",
|
||||
timestring(time(NULL)), (int)getpid(), buf);
|
||||
fflush(logfile);
|
||||
fflush(logfile_fp);
|
||||
} else {
|
||||
syslog(priority, "%s", buf);
|
||||
}
|
||||
@@ -131,7 +130,7 @@ static void syslog_init()
|
||||
#endif
|
||||
|
||||
#ifdef LOG_DAEMON
|
||||
openlog("rsyncd", options, lp_syslog_facility());
|
||||
openlog("rsyncd", options, lp_syslog_facility(module_id));
|
||||
#else
|
||||
openlog("rsyncd", options);
|
||||
#endif
|
||||
@@ -143,37 +142,50 @@ static void syslog_init()
|
||||
|
||||
static void logfile_open(void)
|
||||
{
|
||||
extern int orig_umask;
|
||||
int old_umask = umask(022 | orig_umask);
|
||||
logfile = fopen(logfname, "a");
|
||||
mode_t old_umask = umask(022 | orig_umask);
|
||||
logfile_fp = fopen(logfile_name, "a");
|
||||
umask(old_umask);
|
||||
if (!logfile) {
|
||||
if (!logfile_fp) {
|
||||
int fopen_errno = errno;
|
||||
/* Rsync falls back to using syslog on failure. */
|
||||
syslog_init();
|
||||
rsyserr(FERROR, fopen_errno,
|
||||
"failed to open log-file %s", logfname);
|
||||
"failed to open log-file %s", logfile_name);
|
||||
rprintf(FINFO, "Ignoring \"log file\" setting.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void log_init(void)
|
||||
void log_init(int restart)
|
||||
{
|
||||
time_t t;
|
||||
if (log_initialised) {
|
||||
if (!restart)
|
||||
return;
|
||||
if (strcmp(logfile_name, lp_log_file(module_id)) != 0) {
|
||||
if (logfile_fp) {
|
||||
fclose(logfile_fp);
|
||||
logfile_fp = NULL;
|
||||
} else
|
||||
closelog();
|
||||
logfile_name = NULL;
|
||||
} else if (*logfile_name)
|
||||
return; /* unchanged, non-empty "log file" names */
|
||||
else if (lp_syslog_facility(-1) != lp_syslog_facility(module_id))
|
||||
closelog();
|
||||
else
|
||||
return; /* unchanged syslog settings */
|
||||
} else
|
||||
log_initialised = 1;
|
||||
|
||||
if (log_initialised)
|
||||
return;
|
||||
log_initialised = 1;
|
||||
|
||||
/* this looks pointless, but it is needed in order for the
|
||||
/* This looks pointless, but it is needed in order for the
|
||||
* C library on some systems to fetch the timezone info
|
||||
* before the chroot */
|
||||
t = time(NULL);
|
||||
localtime(&t);
|
||||
* before the chroot. */
|
||||
timestring(time(NULL));
|
||||
|
||||
/* optionally use a log file instead of syslog */
|
||||
logfname = lp_log_file();
|
||||
if (logfname && *logfname)
|
||||
/* Optionally use a log file instead of syslog. (Non-daemon
|
||||
* rsyncs will have already set logfile_name, as needed.) */
|
||||
if (am_daemon && !logfile_name)
|
||||
logfile_name = lp_log_file(module_id);
|
||||
if (logfile_name && *logfile_name)
|
||||
logfile_open();
|
||||
else
|
||||
syslog_init();
|
||||
@@ -181,10 +193,10 @@ void log_init(void)
|
||||
|
||||
void logfile_close(void)
|
||||
{
|
||||
if (logfile) {
|
||||
if (logfile_fp) {
|
||||
logfile_was_closed = 1;
|
||||
fclose(logfile);
|
||||
logfile = NULL;
|
||||
fclose(logfile_fp);
|
||||
logfile_fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,9 +241,6 @@ void rwrite(enum logcode code, char *buf, int len)
|
||||
if (len < 0)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
|
||||
if (quiet && code == FINFO)
|
||||
return;
|
||||
|
||||
if (am_server && msg_fd_out >= 0) {
|
||||
/* Pass the message to our sibling. */
|
||||
send_msg((enum msgcode)code, buf, len);
|
||||
@@ -243,7 +252,7 @@ void rwrite(enum logcode code, char *buf, int len)
|
||||
|
||||
if (code == FCLIENT)
|
||||
code = FINFO;
|
||||
else if (am_daemon) {
|
||||
else if (am_daemon || logfile_name) {
|
||||
static int in_block;
|
||||
char msg[2048];
|
||||
int priority = code == FERROR ? LOG_WARNING : LOG_INFO;
|
||||
@@ -252,19 +261,22 @@ void rwrite(enum logcode code, char *buf, int len)
|
||||
return;
|
||||
in_block = 1;
|
||||
if (!log_initialised)
|
||||
log_init();
|
||||
log_init(0);
|
||||
strlcpy(msg, buf, MIN((int)sizeof msg, len + 1));
|
||||
logit(priority, msg);
|
||||
in_block = 0;
|
||||
|
||||
if (code == FLOG || !am_server)
|
||||
if (code == FLOG || (am_daemon && !am_server))
|
||||
return;
|
||||
} else if (code == FLOG)
|
||||
return;
|
||||
|
||||
if (quiet && code != FERROR)
|
||||
return;
|
||||
|
||||
if (am_server) {
|
||||
/* Pass the message to the non-server side. */
|
||||
if (io_multiplex_write((enum msgcode)code, buf, len))
|
||||
if (send_msg((enum msgcode)code, buf, len))
|
||||
return;
|
||||
if (am_daemon) {
|
||||
/* TODO: can we send the error to the user somehow? */
|
||||
@@ -276,17 +288,8 @@ void rwrite(enum logcode code, char *buf, int len)
|
||||
case FERROR:
|
||||
log_got_error = 1;
|
||||
f = stderr;
|
||||
goto pre_scan;
|
||||
case FINFO:
|
||||
f = am_server ? stderr : stdout;
|
||||
pre_scan:
|
||||
while (len > 1 && *buf == '\n') {
|
||||
fputc(*buf, f);
|
||||
buf++;
|
||||
len--;
|
||||
}
|
||||
break;
|
||||
case FNAME:
|
||||
case FINFO:
|
||||
f = am_server ? stderr : stdout;
|
||||
break;
|
||||
default:
|
||||
@@ -382,7 +385,7 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
|
||||
char buf[BIGPATHBUFLEN];
|
||||
size_t len;
|
||||
|
||||
strcpy(buf, RSYNC_NAME ": ");
|
||||
strlcpy(buf, RSYNC_NAME ": ", sizeof buf);
|
||||
len = (sizeof RSYNC_NAME ": ") - 1;
|
||||
|
||||
va_start(ap, format);
|
||||
@@ -403,31 +406,18 @@ void rflush(enum logcode code)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
|
||||
if (am_daemon) {
|
||||
if (am_daemon || code == FLOG)
|
||||
return;
|
||||
}
|
||||
|
||||
if (code == FLOG) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (code == FERROR) {
|
||||
if (code == FERROR || am_server)
|
||||
f = stderr;
|
||||
}
|
||||
else
|
||||
f = stdout;
|
||||
|
||||
if (code == FINFO) {
|
||||
if (am_server)
|
||||
f = stderr;
|
||||
else
|
||||
f = stdout;
|
||||
}
|
||||
|
||||
if (!f) exit_cleanup(RERR_MESSAGEIO);
|
||||
fflush(f);
|
||||
}
|
||||
|
||||
/* a generic logging routine for send/recv, with parameter
|
||||
* substitiution */
|
||||
/* A generic logging routine for send/recv, with parameter substitiution. */
|
||||
static void log_formatted(enum logcode code, char *format, char *op,
|
||||
struct file_struct *file, struct stats *initial_stats,
|
||||
int iflags, char *hlink)
|
||||
@@ -524,6 +514,14 @@ static void log_formatted(enum logcode code, char *format, char *op,
|
||||
strlcpy(n, buf2, MAXPATHLEN);
|
||||
else
|
||||
n = buf2;
|
||||
} else if (*n != '/') {
|
||||
pathjoin(buf2, sizeof buf2,
|
||||
curr_dir + module_dirlen, n);
|
||||
clean_fname(buf2, 0);
|
||||
if (fmt[1])
|
||||
strlcpy(n, buf2, MAXPATHLEN);
|
||||
else
|
||||
n = buf2;
|
||||
} else
|
||||
clean_fname(n, 0);
|
||||
if (*n == '/')
|
||||
@@ -537,15 +535,15 @@ static void log_formatted(enum logcode code, char *format, char *op,
|
||||
case 'L':
|
||||
if (hlink && *hlink) {
|
||||
n = hlink;
|
||||
strcpy(buf2, " => ");
|
||||
strlcpy(buf2, " => ", sizeof buf2);
|
||||
} else if (S_ISLNK(file->mode) && file->u.link) {
|
||||
n = file->u.link;
|
||||
strcpy(buf2, " -> ");
|
||||
strlcpy(buf2, " -> ", sizeof buf2);
|
||||
} else {
|
||||
n = "";
|
||||
if (!fmt[1])
|
||||
break;
|
||||
strcpy(buf2, " ");
|
||||
strlcpy(buf2, " ", sizeof buf2);
|
||||
}
|
||||
strlcat(fmt, "s", sizeof fmt);
|
||||
snprintf(buf2 + 4, sizeof buf2 - 4, fmt, n);
|
||||
@@ -689,17 +687,20 @@ int log_format_has(const char *format, char esc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* log the transfer of a file */
|
||||
void log_item(struct file_struct *file, struct stats *initial_stats,
|
||||
int iflags, char *hlink)
|
||||
/* 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,
|
||||
struct stats *initial_stats, int iflags, char *hlink)
|
||||
{
|
||||
char *s_or_r = am_sender ? "send" : "recv";
|
||||
|
||||
if (lp_transfer_logging(module_id)) {
|
||||
log_formatted(FLOG, lp_log_format(module_id), s_or_r,
|
||||
if (code != FLOG && stdout_format && !am_server) {
|
||||
log_formatted(FCLIENT, stdout_format, s_or_r,
|
||||
file, initial_stats, iflags, hlink);
|
||||
} else if (log_format && !am_server) {
|
||||
log_formatted(FNAME, log_format, s_or_r,
|
||||
}
|
||||
if (code != FCLIENT && logfile_format && *logfile_format) {
|
||||
log_formatted(FLOG, logfile_format, s_or_r,
|
||||
file, initial_stats, iflags, hlink);
|
||||
}
|
||||
}
|
||||
@@ -709,14 +710,17 @@ 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
|
||||
|| log_format_has_i > 1 || (verbose > 1 && log_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 (am_daemon && !dry_run && see_item)
|
||||
log_item(file, &stats, iflags, buf);
|
||||
if (logfile_name && !dry_run && see_item
|
||||
&& (significant_flags || logfile_format_has_i))
|
||||
log_item(FLOG, file, &stats, iflags, buf);
|
||||
} else if (see_item || local_change || *buf
|
||||
|| (S_ISDIR(file->mode) && significant_flags))
|
||||
log_item(file, &stats, iflags, buf);
|
||||
|| (S_ISDIR(file->mode) && significant_flags)) {
|
||||
enum logcode code = significant_flags || logfile_format_has_i ? FINFO : FCLIENT;
|
||||
log_item(code, file, &stats, iflags, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void log_delete(char *fname, int mode)
|
||||
@@ -728,22 +732,22 @@ void log_delete(char *fname, int mode)
|
||||
file.mode = mode;
|
||||
file.basename = fname;
|
||||
|
||||
if (!verbose && !log_format)
|
||||
if (!verbose && !stdout_format)
|
||||
;
|
||||
else if (am_server && protocol_version >= 29 && len < MAXPATHLEN) {
|
||||
if (S_ISDIR(mode))
|
||||
len++; /* directories include trailing null */
|
||||
send_msg(MSG_DELETED, fname, len);
|
||||
} else {
|
||||
fmt = log_format_has_o_or_i ? log_format : "deleting %n";
|
||||
fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n";
|
||||
log_formatted(FCLIENT, fmt, "del.", &file, &stats,
|
||||
ITEM_DELETED, NULL);
|
||||
}
|
||||
|
||||
if (!am_daemon || dry_run || !lp_transfer_logging(module_id))
|
||||
if (!logfile_name || dry_run || !logfile_format)
|
||||
return;
|
||||
|
||||
fmt = daemon_log_format_has_o_or_i ? lp_log_format(module_id) : "deleting %n";
|
||||
fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n";
|
||||
log_formatted(FLOG, fmt, "del.", &file, &stats, ITEM_DELETED, NULL);
|
||||
}
|
||||
|
||||
@@ -769,11 +773,11 @@ void log_exit(int code, const char *file, int line)
|
||||
|
||||
/* VANISHED is not an error, only a warning */
|
||||
if (code == RERR_VANISHED) {
|
||||
rprintf(FINFO, "rsync warning: %s (code %d) at %s(%d) [%s]\n",
|
||||
name, code, file, line, who_am_i());
|
||||
rprintf(FINFO, "rsync warning: %s (code %d) at %s(%d) [%s=%s]\n",
|
||||
name, code, file, line, who_am_i(), RSYNC_VERSION);
|
||||
} else {
|
||||
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s]\n",
|
||||
name, code, file, line, who_am_i());
|
||||
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s=%s]\n",
|
||||
name, code, file, line, who_am_i(), RSYNC_VERSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
254
main.c
254
main.c
@@ -1,23 +1,25 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* The startup routines, including main(), for rsync.
|
||||
*
|
||||
* 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, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
|
||||
@@ -33,20 +35,24 @@ extern int am_sender;
|
||||
extern int am_generator;
|
||||
extern int am_daemon;
|
||||
extern int blocking_io;
|
||||
extern int remove_sent_files;
|
||||
extern int remove_source_files;
|
||||
extern int daemon_over_rsh;
|
||||
extern int need_messages_from_generator;
|
||||
extern int kluge_around_eof;
|
||||
extern int do_stats;
|
||||
extern int log_got_error;
|
||||
extern int module_id;
|
||||
extern int orig_umask;
|
||||
extern int copy_links;
|
||||
extern int copy_dirlinks;
|
||||
extern int keep_dirlinks;
|
||||
extern int preserve_hard_links;
|
||||
extern int protocol_version;
|
||||
extern int recurse;
|
||||
extern int relative_paths;
|
||||
extern int sanitize_paths;
|
||||
extern int curr_dir_depth;
|
||||
extern int curr_dir_len;
|
||||
extern int module_id;
|
||||
extern int rsync_port;
|
||||
extern int whole_file;
|
||||
extern int read_batch;
|
||||
@@ -57,11 +63,17 @@ extern int filesfrom_fd;
|
||||
extern pid_t cleanup_child_pid;
|
||||
extern struct stats stats;
|
||||
extern char *filesfrom_host;
|
||||
extern char *partial_dir;
|
||||
extern char *basis_dir[];
|
||||
extern char *rsync_path;
|
||||
extern char *shell_cmd;
|
||||
extern char *batch_name;
|
||||
extern char curr_dir[MAXPATHLEN];
|
||||
extern struct filter_list_struct server_filter_list;
|
||||
|
||||
int local_server = 0;
|
||||
int new_root_dir = 0;
|
||||
mode_t orig_umask = 0;
|
||||
struct file_list *the_file_list;
|
||||
|
||||
/* There's probably never more than at most 2 outstanding child processes,
|
||||
@@ -88,14 +100,14 @@ static int64 total_read, total_written;
|
||||
static void show_malloc_stats(void);
|
||||
|
||||
/* Works like waitpid(), but if we already harvested the child pid in our
|
||||
* sigchld_handler(), we succeed instead of returning an error. */
|
||||
* remember_children(), we succeed instead of returning an error. */
|
||||
pid_t wait_process(pid_t pid, int *status_ptr, int flags)
|
||||
{
|
||||
pid_t waited_pid = waitpid(pid, status_ptr, flags);
|
||||
|
||||
if (waited_pid == -1 && errno == ECHILD) {
|
||||
/* Status of requested child no longer available: check to
|
||||
* see if it was processed by sigchld_handler(). */
|
||||
* see if it was processed by remember_children(). */
|
||||
int cnt;
|
||||
for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
|
||||
if (pid == pid_stat_table[cnt].pid) {
|
||||
@@ -167,7 +179,6 @@ static void handle_stats(int f)
|
||||
return;
|
||||
|
||||
if (am_daemon) {
|
||||
log_exit(0, __FILE__, __LINE__);
|
||||
if (f == -1 || !am_sender)
|
||||
return;
|
||||
}
|
||||
@@ -188,7 +199,7 @@ static void handle_stats(int f)
|
||||
/* this is the client */
|
||||
|
||||
if (f < 0 && !am_sender) /* e.g. when we got an empty file list. */
|
||||
;
|
||||
;
|
||||
else if (!am_sender) {
|
||||
/* Read the first two in opposite order because the meaning of
|
||||
* read/write swaps when switching from sender to receiver. */
|
||||
@@ -215,7 +226,8 @@ static void handle_stats(int f)
|
||||
static void output_summary(void)
|
||||
{
|
||||
if (do_stats) {
|
||||
rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
|
||||
rprintf(FCLIENT, "\n");
|
||||
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",
|
||||
@@ -242,8 +254,9 @@ static void output_summary(void)
|
||||
}
|
||||
|
||||
if (verbose || do_stats) {
|
||||
rprintf(FCLIENT, "\n");
|
||||
rprintf(FINFO,
|
||||
"\nsent %s bytes received %s bytes %s bytes/sec\n",
|
||||
"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 %.2f\n",
|
||||
@@ -266,7 +279,8 @@ static void show_malloc_stats(void)
|
||||
|
||||
mi = mallinfo();
|
||||
|
||||
rprintf(FINFO, "\n" RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
|
||||
rprintf(FCLIENT, "\n");
|
||||
rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
|
||||
getpid(), am_server ? "server " : "",
|
||||
am_daemon ? "daemon " : "", who_am_i());
|
||||
rprintf(FINFO, " arena: %10ld (bytes from sbrk)\n",
|
||||
@@ -402,8 +416,8 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
|
||||
|
||||
if (verbose > 3) {
|
||||
for (i = 0; i < argc; i++)
|
||||
rprintf(FINFO, "cmd[%d]=%s ", i, args[i]);
|
||||
rprintf(FINFO, "\n");
|
||||
rprintf(FCLIENT, "cmd[%d]=%s ", i, args[i]);
|
||||
rprintf(FCLIENT, "\n");
|
||||
}
|
||||
|
||||
if (read_batch) {
|
||||
@@ -437,19 +451,21 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
|
||||
|
||||
/* The receiving side operates in one of two modes:
|
||||
*
|
||||
* 1. it enters a directory and receives one or more files, placing them
|
||||
* according to their names in the file-list.
|
||||
* 1. it receives any number of files into a destination directory,
|
||||
* placing them according to their names in the file-list.
|
||||
*
|
||||
* 2. it receives a single file and saves it using the name in the
|
||||
* destination path instead of its file-list name. This requires a
|
||||
* "local name" for writing out the destination file.
|
||||
*
|
||||
* So, our task is to figure out what mode/local-name we need and return
|
||||
* either a NULL for mode 1, or the local-name for mode 2. We also
|
||||
* change directory if there are any path components in dest_path. */
|
||||
* So, our task is to figure out what mode/local-name we need.
|
||||
* For mode 1, we change into the destination directory and return NULL.
|
||||
* For mode 2, we change into the directory containing the destination
|
||||
* file (if we aren't already there) and return the local-name. */
|
||||
static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
int statret;
|
||||
char *cp;
|
||||
|
||||
if (verbose > 2) {
|
||||
@@ -457,16 +473,14 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
flist->count, NS(dest_path));
|
||||
}
|
||||
|
||||
if (!dest_path)
|
||||
if (!dest_path || list_only)
|
||||
return NULL;
|
||||
|
||||
/* If the destination path refers to an existing directory, enter
|
||||
* it and use mode 1. If there is something other than a directory
|
||||
* at the destination path, we must be transferring one file
|
||||
* (anything at the destination will be overwritten). */
|
||||
if (do_stat(dest_path, &st) == 0) {
|
||||
/* See what currently exists at the destination. */
|
||||
if ((statret = do_stat(dest_path, &st)) == 0) {
|
||||
/* If the destination is a dir, enter it and use mode 1. */
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (!push_dir(dest_path)) {
|
||||
if (!push_dir(dest_path, 0)) {
|
||||
rsyserr(FERROR, errno, "push_dir#1 %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
@@ -479,37 +493,53 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
" copying more than 1 file\n");
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
/* Caution: flist->count could be 0! */
|
||||
if (flist->count == 1 && S_ISDIR(flist->files[0]->mode)) {
|
||||
rprintf(FERROR,
|
||||
"ERROR: cannot overwrite non-directory"
|
||||
" with a directory\n");
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
} else if (errno != ENOENT) {
|
||||
/* If we don't know what's at the destination, fail. */
|
||||
rsyserr(FERROR, errno, "ERROR: cannot stat destination %s",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
|
||||
cp = strrchr(dest_path, '/');
|
||||
|
||||
/* If the destination path ends in a slash or we are transferring
|
||||
* multiple files, create a directory at the destination path,
|
||||
* enter the new directory, and use mode 1. */
|
||||
/* If we need a destination directory because the transfer is not
|
||||
* of a single non-directory or the user has requested one via a
|
||||
* destination path ending in a slash, create one and use mode 1. */
|
||||
if (flist->count > 1 || (cp && !cp[1])) {
|
||||
/* Lop off the final slash (if any). */
|
||||
if (cp && !cp[1])
|
||||
*cp = '\0';
|
||||
|
||||
umask(orig_umask);
|
||||
if (do_mkdir(dest_path, 0777) != 0) {
|
||||
if (statret == 0) {
|
||||
rprintf(FERROR,
|
||||
"ERROR: destination path is not a directory\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
if (mkdir_defmode(dest_path) != 0) {
|
||||
rsyserr(FERROR, errno, "mkdir %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
umask(0);
|
||||
|
||||
new_root_dir = 1;
|
||||
|
||||
if (verbose)
|
||||
rprintf(FINFO, "created directory %s\n", dest_path);
|
||||
|
||||
if (dry_run) {
|
||||
/* Indicate that the destination directory doesn't
|
||||
* really exist and return mode 1. */
|
||||
/* Indicate that dest dir doesn't really exist. */
|
||||
dry_run++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!push_dir(dest_path)) {
|
||||
if (!push_dir(dest_path, dry_run > 1)) {
|
||||
rsyserr(FERROR, errno, "push_dir#2 %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
@@ -529,7 +559,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
dest_path = "/";
|
||||
|
||||
*cp = '\0';
|
||||
if (!push_dir(dest_path)) {
|
||||
if (!push_dir(dest_path, 0)) {
|
||||
rsyserr(FERROR, errno, "push_dir#3 %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
@@ -539,6 +569,38 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
return cp + 1;
|
||||
}
|
||||
|
||||
/* Call this if the destination dir (which is assumed to be in curr_dir)
|
||||
* does not yet exist and we can't create it due to being in dry-run
|
||||
* mode. We'll fix dirs that can be relative to the non-existent dir. */
|
||||
static void fix_basis_dirs(void)
|
||||
{
|
||||
char **dir, *new, *slash;
|
||||
int len;
|
||||
|
||||
if (dry_run <= 1)
|
||||
return;
|
||||
|
||||
slash = strrchr(curr_dir, '/');
|
||||
|
||||
for (dir = basis_dir; *dir; dir++) {
|
||||
if (**dir == '/')
|
||||
continue;
|
||||
len = curr_dir_len + 1 + strlen(*dir) + 1;
|
||||
if (!(new = new_array(char, len)))
|
||||
out_of_memory("fix_basis_dirs");
|
||||
if (slash && strncmp(*dir, "../", 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, *dir + 3);
|
||||
*slash = '/';
|
||||
} else
|
||||
pathjoin(new, len, curr_dir, *dir);
|
||||
*dir = new;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is only called by the sender. */
|
||||
static void read_final_goodbye(int f_in, int f_out)
|
||||
@@ -579,17 +641,20 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
return;
|
||||
}
|
||||
if (am_daemon && lp_read_only(module_id) && remove_sent_files) {
|
||||
if (am_daemon && lp_read_only(module_id) && remove_source_files) {
|
||||
rprintf(FERROR,
|
||||
"ERROR: --remove-sent-files cannot be used with a read-only module\n");
|
||||
"ERROR: --remove-%s-files cannot be used with a read-only module\n",
|
||||
remove_source_files == 1 ? "source" : "sent");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!relative_paths && !push_dir(dir)) {
|
||||
rsyserr(FERROR, errno, "push_dir#3 %s failed",
|
||||
full_fname(dir));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
if (!relative_paths) {
|
||||
if (!push_dir(dir, 0)) {
|
||||
rsyserr(FERROR, errno, "push_dir#3 %s failed",
|
||||
full_fname(dir));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
@@ -627,7 +692,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
|
||||
|
||||
/* The receiving side mustn't obey this, or an existing symlink that
|
||||
* points to an identical file won't be replaced by the referent. */
|
||||
copy_links = 0;
|
||||
copy_links = copy_dirlinks = 0;
|
||||
|
||||
if (preserve_hard_links)
|
||||
init_hard_links();
|
||||
@@ -742,7 +807,7 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
|
||||
dir = argv[0];
|
||||
argc--;
|
||||
argv++;
|
||||
if (!am_daemon && !push_dir(dir)) {
|
||||
if (!am_daemon && !push_dir(dir, 0)) {
|
||||
rsyserr(FERROR, errno, "push_dir#4 %s failed",
|
||||
full_fname(dir));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
@@ -773,6 +838,36 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
|
||||
if (argc > 0)
|
||||
local_name = get_local_name(flist,argv[0]);
|
||||
|
||||
/* Now that we know what our destination directory turned out to be,
|
||||
* we can sanitize the --link-/copy-/compare-dest args correctly. */
|
||||
if (sanitize_paths) {
|
||||
char **dir;
|
||||
for (dir = basis_dir; *dir; dir++) {
|
||||
*dir = sanitize_path(NULL, *dir, NULL, curr_dir_depth, NULL);
|
||||
}
|
||||
if (partial_dir) {
|
||||
partial_dir = sanitize_path(NULL, partial_dir, NULL, curr_dir_depth, NULL);
|
||||
}
|
||||
}
|
||||
fix_basis_dirs();
|
||||
|
||||
if (server_filter_list.head) {
|
||||
char **dir;
|
||||
struct filter_list_struct *elp = &server_filter_list;
|
||||
|
||||
for (dir = basis_dir; *dir; dir++) {
|
||||
if (check_filter(elp, *dir, 1) < 0)
|
||||
goto options_rejected;
|
||||
}
|
||||
if (partial_dir && *partial_dir == '/'
|
||||
&& check_filter(elp, partial_dir, 1) < 0) {
|
||||
options_rejected:
|
||||
rprintf(FERROR,
|
||||
"Your options have been rejected by the server.\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
}
|
||||
|
||||
exit_code = do_recv(f_in,f_out,flist,local_name);
|
||||
exit_cleanup(exit_code);
|
||||
}
|
||||
@@ -903,6 +998,8 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
if (flist && flist->count > 0) {
|
||||
local_name = get_local_name(flist, argv[0]);
|
||||
|
||||
fix_basis_dirs();
|
||||
|
||||
exit_code2 = do_recv(f_in, f_out, flist, local_name);
|
||||
} else {
|
||||
handle_stats(-1);
|
||||
@@ -960,12 +1057,12 @@ static int start_client(int argc, char *argv[])
|
||||
return rc;
|
||||
|
||||
if (!read_batch) { /* for read_batch, NO source is specified */
|
||||
argc--;
|
||||
shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
|
||||
if (shell_path) { /* source is remote */
|
||||
char *dummy1;
|
||||
int dummy2;
|
||||
if (argc && check_for_hostspec(argv[argc], &dummy1, &dummy2)) {
|
||||
if (--argc
|
||||
&& check_for_hostspec(argv[argc], &dummy1, &dummy2)) {
|
||||
rprintf(FERROR,
|
||||
"The source and destination cannot both be remote.\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
@@ -990,12 +1087,14 @@ static int start_client(int argc, char *argv[])
|
||||
} else { /* source is local, check dest arg */
|
||||
am_sender = 1;
|
||||
|
||||
if (argc < 1) { /* destination required */
|
||||
usage(FERROR);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
if (argc > 1)
|
||||
p = argv[--argc];
|
||||
else {
|
||||
p = ".";
|
||||
list_only = 1;
|
||||
}
|
||||
|
||||
shell_path = check_for_hostspec(argv[argc], &shell_machine, &rsync_port);
|
||||
shell_path = check_for_hostspec(p, &shell_machine, &rsync_port);
|
||||
if (shell_path && filesfrom_host && *filesfrom_host
|
||||
&& strcmp(filesfrom_host, shell_machine) != 0) {
|
||||
rprintf(FERROR,
|
||||
@@ -1010,7 +1109,7 @@ static int start_client(int argc, char *argv[])
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
shell_machine = NULL;
|
||||
shell_path = argv[argc];
|
||||
shell_path = p;
|
||||
} else if (rsync_port) {
|
||||
if (!shell_cmd) {
|
||||
return start_socket_client(shell_machine,
|
||||
@@ -1093,7 +1192,7 @@ static RETSIGTYPE sigusr2_handler(UNUSED(int val))
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
static RETSIGTYPE sigchld_handler(UNUSED(int val))
|
||||
RETSIGTYPE remember_children(UNUSED(int val))
|
||||
{
|
||||
#ifdef WNOHANG
|
||||
int cnt, status;
|
||||
@@ -1115,7 +1214,7 @@ static RETSIGTYPE sigchld_handler(UNUSED(int val))
|
||||
}
|
||||
#endif
|
||||
#ifndef HAVE_SIGACTION
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
signal(SIGCHLD, remember_children);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1159,8 +1258,8 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
|
||||
char cmd_buf[300];
|
||||
int ret;
|
||||
|
||||
sprintf(cmd_buf, get_panic_action(),
|
||||
getpid(), getpid());
|
||||
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. */
|
||||
@@ -1186,7 +1285,7 @@ int main(int argc,char *argv[])
|
||||
#endif
|
||||
SIGACTMASK(SIGUSR1, sigusr1_handler);
|
||||
SIGACTMASK(SIGUSR2, sigusr2_handler);
|
||||
SIGACTMASK(SIGCHLD, sigchld_handler);
|
||||
SIGACTMASK(SIGCHLD, remember_children);
|
||||
#ifdef MAINTAINER_MODE
|
||||
SIGACTMASK(SIGSEGV, rsync_panic_handler);
|
||||
SIGACTMASK(SIGFPE, rsync_panic_handler);
|
||||
@@ -1206,7 +1305,7 @@ int main(int argc,char *argv[])
|
||||
|
||||
/* we set a 0 umask so that correct file permissions can be
|
||||
* carried across */
|
||||
orig_umask = (int)umask(0);
|
||||
orig_umask = umask(0);
|
||||
|
||||
#if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
|
||||
setlocale(LC_CTYPE, "");
|
||||
@@ -1229,12 +1328,15 @@ int main(int argc,char *argv[])
|
||||
/* Ignore SIGPIPE; we consistently check error codes and will
|
||||
* see the EPIPE. */
|
||||
SIGACTION(SIGPIPE, SIG_IGN);
|
||||
#ifdef SIGXFSZ
|
||||
SIGACTION(SIGXFSZ, SIG_IGN);
|
||||
#endif
|
||||
|
||||
/* Initialize push_dir here because on some old systems getcwd
|
||||
* (implemented by forking "pwd" and reading its output) doesn't
|
||||
* work when there are other child processes. Also, on all systems
|
||||
* that implement getcwd that way "pwd" can't be found after chroot. */
|
||||
push_dir(NULL);
|
||||
push_dir(NULL, 0);
|
||||
|
||||
init_flist();
|
||||
|
||||
|
||||
146
match.c
146
match.c
@@ -1,89 +1,69 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
* Block matching used by the file-transfer code.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int am_server;
|
||||
extern int do_progress;
|
||||
extern int checksum_seed;
|
||||
extern int append_mode;
|
||||
|
||||
int updating_basis_file;
|
||||
|
||||
typedef unsigned short tag;
|
||||
|
||||
#define TABLESIZE (1<<16)
|
||||
#define NULL_TAG (-1)
|
||||
|
||||
static int false_alarms;
|
||||
static int tag_hits;
|
||||
static int hash_hits;
|
||||
static int matches;
|
||||
static int64 data_transfer;
|
||||
|
||||
static int total_false_alarms;
|
||||
static int total_tag_hits;
|
||||
static int total_hash_hits;
|
||||
static int total_matches;
|
||||
|
||||
extern struct stats stats;
|
||||
|
||||
struct target {
|
||||
tag t;
|
||||
int32 i;
|
||||
};
|
||||
#define TABLESIZE (1<<16)
|
||||
|
||||
static struct target *targets;
|
||||
|
||||
static int32 *tag_table;
|
||||
|
||||
#define gettag2(s1,s2) (((s1) + (s2)) & 0xFFFF)
|
||||
#define gettag(sum) gettag2((sum)&0xFFFF,(sum)>>16)
|
||||
|
||||
static int compare_targets(struct target *t1,struct target *t2)
|
||||
{
|
||||
return (int)t1->t - (int)t2->t;
|
||||
}
|
||||
static int32 *hash_table;
|
||||
|
||||
#define SUM2HASH2(s1,s2) (((s1) + (s2)) & 0xFFFF)
|
||||
#define SUM2HASH(sum) SUM2HASH2((sum)&0xFFFF,(sum)>>16)
|
||||
|
||||
static void build_hash_table(struct sum_struct *s)
|
||||
{
|
||||
int32 i;
|
||||
|
||||
if (!tag_table)
|
||||
tag_table = new_array(int32, TABLESIZE);
|
||||
|
||||
targets = new_array(struct target, s->count);
|
||||
if (!tag_table || !targets)
|
||||
out_of_memory("build_hash_table");
|
||||
|
||||
for (i = 0; i < s->count; i++) {
|
||||
targets[i].i = i;
|
||||
targets[i].t = gettag(s->sums[i].sum1);
|
||||
if (!hash_table) {
|
||||
hash_table = new_array(int32, TABLESIZE);
|
||||
if (!hash_table)
|
||||
out_of_memory("build_hash_table");
|
||||
}
|
||||
|
||||
qsort(targets,s->count,sizeof(targets[0]),(int (*)())compare_targets);
|
||||
memset(hash_table, 0xFF, TABLESIZE * sizeof hash_table[0]);
|
||||
|
||||
for (i = 0; i < TABLESIZE; i++)
|
||||
tag_table[i] = NULL_TAG;
|
||||
|
||||
for (i = s->count; i-- > 0; )
|
||||
tag_table[targets[i].t] = i;
|
||||
for (i = 0; i < s->count; i++) {
|
||||
uint32 t = SUM2HASH(s->sums[i].sum1);
|
||||
s->sums[i].chain = hash_table[t];
|
||||
hash_table[t] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,20 +157,22 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
}
|
||||
|
||||
do {
|
||||
tag t = gettag2(s1,s2);
|
||||
int done_csum2 = 0;
|
||||
int32 j = tag_table[t];
|
||||
int32 i;
|
||||
|
||||
if (verbose > 4)
|
||||
rprintf(FINFO,"offset=%.0f sum=%08x\n",(double)offset,sum);
|
||||
if (verbose > 4) {
|
||||
rprintf(FINFO, "offset=%.0f sum=%04x%04x\n",
|
||||
(double)offset, s2 & 0xFFFF, s1 & 0xFFFF);
|
||||
}
|
||||
|
||||
if (j == NULL_TAG)
|
||||
goto null_tag;
|
||||
i = hash_table[SUM2HASH2(s1,s2)];
|
||||
if (i < 0)
|
||||
goto null_hash;
|
||||
|
||||
sum = (s1 & 0xffff) | (s2 << 16);
|
||||
tag_hits++;
|
||||
hash_hits++;
|
||||
do {
|
||||
int32 l, i = targets[j].i;
|
||||
int32 l;
|
||||
|
||||
if (sum != s->sums[i].sum1)
|
||||
continue;
|
||||
@@ -206,9 +188,11 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET))
|
||||
continue;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"potential match at %.0f target=%.0f %.0f sum=%08x\n",
|
||||
(double)offset,(double)j,(double)i,sum);
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,
|
||||
"potential match at %.0f i=%ld sum=%08x\n",
|
||||
(double)offset, (long)i, sum);
|
||||
}
|
||||
|
||||
if (!done_csum2) {
|
||||
map = (schar *)map_ptr(buf,offset,l);
|
||||
@@ -225,8 +209,8 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
* one with an identical offset, so we prefer that over
|
||||
* the following want_i optimization. */
|
||||
if (updating_basis_file) {
|
||||
do {
|
||||
int32 i2 = targets[j].i;
|
||||
int32 i2;
|
||||
for (i2 = i; i2 >= 0; i2 = s->sums[i2].chain) {
|
||||
if (s->sums[i2].offset != offset)
|
||||
continue;
|
||||
if (i2 != i) {
|
||||
@@ -241,7 +225,7 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
* both the sender and the receiver. */
|
||||
s->sums[i].flags |= SUMFLG_SAME_OFFSET;
|
||||
goto set_want_i;
|
||||
} while (++j < s->count && targets[j].t == t);
|
||||
}
|
||||
}
|
||||
|
||||
/* we've found a match, but now check to see
|
||||
@@ -267,9 +251,9 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
s2 = sum >> 16;
|
||||
matches++;
|
||||
break;
|
||||
} while (++j < s->count && targets[j].t == t);
|
||||
} while ((i = s->sums[i].chain) >= 0);
|
||||
|
||||
null_tag:
|
||||
null_hash:
|
||||
backup = offset - last_match;
|
||||
/* We sometimes read 1 byte prior to last_match... */
|
||||
if (backup < 0)
|
||||
@@ -324,7 +308,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
|
||||
last_match = 0;
|
||||
false_alarms = 0;
|
||||
tag_hits = 0;
|
||||
hash_hits = 0;
|
||||
matches = 0;
|
||||
data_transfer = 0;
|
||||
|
||||
@@ -376,16 +360,11 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
rprintf(FINFO,"sending file_sum\n");
|
||||
write_buf(f,file_sum,MD4_SUM_LENGTH);
|
||||
|
||||
if (targets) {
|
||||
free(targets);
|
||||
targets=NULL;
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "false_alarms=%d tag_hits=%d matches=%d\n",
|
||||
false_alarms, tag_hits, matches);
|
||||
rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
|
||||
false_alarms, hash_hits, matches);
|
||||
|
||||
total_tag_hits += tag_hits;
|
||||
total_hash_hits += hash_hits;
|
||||
total_false_alarms += false_alarms;
|
||||
total_matches += matches;
|
||||
stats.literal_data += data_transfer;
|
||||
@@ -397,8 +376,7 @@ void match_report(void)
|
||||
return;
|
||||
|
||||
rprintf(FINFO,
|
||||
"total: matches=%d tag_hits=%d false_alarms=%d data=%.0f\n",
|
||||
total_matches,total_tag_hits,
|
||||
total_false_alarms,
|
||||
"total: matches=%d hash_hits=%d false_alarms=%d data=%.0f\n",
|
||||
total_matches, total_hash_hits, total_false_alarms,
|
||||
(double)stats.literal_data);
|
||||
}
|
||||
|
||||
@@ -54,15 +54,14 @@ BEGIN {
|
||||
printf "int %s(void);\n", a[2]
|
||||
}
|
||||
|
||||
/^static|^extern/ || !/^[a-zA-Z]/ || /[;]/ {
|
||||
/^static|^extern/ || /[;]/ {
|
||||
next;
|
||||
}
|
||||
|
||||
!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^uchar|^short|^struct|^BOOL|^void|^time|^const|^RETSIGTYPE/ {
|
||||
!/^[A-Za-z][A-Za-z0-9_]* / {
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
/[(].*[)][ \t]*$/ {
|
||||
printf "%s;\n",$0;
|
||||
next;
|
||||
@@ -73,4 +72,3 @@ BEGIN {
|
||||
printf "%s\n",$0;
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
243
options.c
243
options.c
@@ -1,7 +1,9 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
/*
|
||||
* Command-line (and received via daemon-socket) option parsing.
|
||||
*
|
||||
* Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2000, 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2002, 2003, 2004, 2005, 2006 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
|
||||
@@ -13,9 +15,9 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
@@ -41,6 +43,7 @@ int whole_file = -1;
|
||||
|
||||
int append_mode = 0;
|
||||
int keep_dirlinks = 0;
|
||||
int copy_dirlinks = 0;
|
||||
int copy_links = 0;
|
||||
int preserve_links = 0;
|
||||
int preserve_hard_links = 0;
|
||||
@@ -57,14 +60,12 @@ int cvs_exclude = 0;
|
||||
int dry_run = 0;
|
||||
int do_xfers = 1;
|
||||
int ignore_times = 0;
|
||||
int saw_delete_opt = 0;
|
||||
int saw_delete_excluded_opt = 0;
|
||||
int delete_mode = 0;
|
||||
int delete_during = 0;
|
||||
int delete_before = 0;
|
||||
int delete_after = 0;
|
||||
int delete_excluded = 0;
|
||||
int remove_sent_files = 0;
|
||||
int remove_source_files = 0;
|
||||
int one_file_system = 0;
|
||||
int protocol_version = PROTOCOL_VERSION;
|
||||
int sparse_files = 0;
|
||||
@@ -75,7 +76,6 @@ int am_server = 0;
|
||||
int am_sender = 0;
|
||||
int am_generator = 0;
|
||||
int am_starting_up = 1;
|
||||
int orig_umask = 0;
|
||||
int relative_paths = -1;
|
||||
int implied_dirs = 1;
|
||||
int numeric_ids = 0;
|
||||
@@ -147,7 +147,9 @@ char *partial_dir = NULL;
|
||||
char *basis_dir[MAX_BASIS_DIRS+1];
|
||||
char *config_file = NULL;
|
||||
char *shell_cmd = NULL;
|
||||
char *log_format = NULL;
|
||||
char *logfile_name = NULL;
|
||||
char *logfile_format = NULL;
|
||||
char *stdout_format = NULL;
|
||||
char *password_file = NULL;
|
||||
char *rsync_path = RSYNC_PATH;
|
||||
char *backup_dir = NULL;
|
||||
@@ -162,9 +164,12 @@ char *dest_option = NULL;
|
||||
|
||||
int verbose = 0;
|
||||
int quiet = 0;
|
||||
int output_motd = 1;
|
||||
int log_before_transfer = 0;
|
||||
int log_format_has_i = 0;
|
||||
int log_format_has_o_or_i = 0;
|
||||
int stdout_format_has_i = 0;
|
||||
int stdout_format_has_o_or_i = 0;
|
||||
int logfile_format_has_i = 0;
|
||||
int logfile_format_has_o_or_i = 0;
|
||||
int always_checksum = 0;
|
||||
int list_only = 0;
|
||||
|
||||
@@ -248,7 +253,8 @@ static void print_rsync_version(enum logcode f)
|
||||
(int) SIZEOF_INT64, (int) sizeof (int64));
|
||||
}
|
||||
|
||||
rprintf(f,"\nrsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n");
|
||||
rprintf(f,"\n");
|
||||
rprintf(f,"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n");
|
||||
rprintf(f,"are welcome to redistribute it under certain conditions. See the GNU\n");
|
||||
rprintf(f,"General Public Licence for details.\n");
|
||||
}
|
||||
@@ -258,10 +264,12 @@ void usage(enum logcode F)
|
||||
{
|
||||
print_rsync_version(F);
|
||||
|
||||
rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\n");
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"rsync is a file transfer program capable of efficient remote update\n");
|
||||
rprintf(F,"via a fast differencing algorithm.\n");
|
||||
|
||||
rprintf(F,"\nUsage: rsync [OPTION]... SRC [SRC]... DEST\n");
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
|
||||
@@ -270,9 +278,11 @@ void usage(enum logcode F)
|
||||
rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
|
||||
rprintf(F,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n");
|
||||
rprintf(F,"to an rsync daemon, and require SRC or DEST to start with a module name.\n");
|
||||
rprintf(F,"\nOptions\n");
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Options\n");
|
||||
rprintf(F," -v, --verbose increase verbosity\n");
|
||||
rprintf(F," -q, --quiet suppress non-error messages\n");
|
||||
rprintf(F," --no-motd suppress daemon-mode MOTD (see manpage caveat)\n");
|
||||
rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
|
||||
rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H)\n");
|
||||
rprintf(F," --no-OPTION turn off an implied OPTION (e.g. --no-D)\n");
|
||||
@@ -290,11 +300,12 @@ void usage(enum logcode F)
|
||||
rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
|
||||
rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n");
|
||||
rprintf(F," --safe-links ignore symlinks that point outside the source tree\n");
|
||||
rprintf(F," -H, --hard-links preserve hard links\n");
|
||||
rprintf(F," -k, --copy-dirlinks transform symlink to a dir into referent dir\n");
|
||||
rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
|
||||
rprintf(F," -H, --hard-links preserve hard links\n");
|
||||
rprintf(F," -p, --perms preserve permissions\n");
|
||||
rprintf(F," -E, --executability preserve the file's executability\n");
|
||||
rprintf(F," --chmod=CHMOD change destination permissions\n");
|
||||
rprintf(F," --chmod=CHMOD affect file and/or directory permissions\n");
|
||||
rprintf(F," -o, --owner preserve owner (super-user only)\n");
|
||||
rprintf(F," -g, --group preserve group\n");
|
||||
rprintf(F," --devices preserve device files (super-user only)\n");
|
||||
@@ -310,15 +321,15 @@ void usage(enum logcode F)
|
||||
rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n");
|
||||
rprintf(F," -e, --rsh=COMMAND specify the remote shell to use\n");
|
||||
rprintf(F," --rsync-path=PROGRAM specify the rsync to run on the remote machine\n");
|
||||
rprintf(F," --existing ignore non-existing files on receiving side\n");
|
||||
rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
|
||||
rprintf(F," --remove-sent-files sent files/symlinks are removed from sending side\n");
|
||||
rprintf(F," --existing skip creating new files on receiver\n");
|
||||
rprintf(F," --ignore-existing skip updating files that already exist on receiver\n");
|
||||
rprintf(F," --remove-source-files sender removes synchronized files (non-dirs)\n");
|
||||
rprintf(F," --del an alias for --delete-during\n");
|
||||
rprintf(F," --delete delete files that don't exist on the sending side\n");
|
||||
rprintf(F," --delete delete extraneous files from destination dirs\n");
|
||||
rprintf(F," --delete-before receiver deletes before transfer (default)\n");
|
||||
rprintf(F," --delete-during receiver deletes during transfer, not before\n");
|
||||
rprintf(F," --delete-after receiver deletes after transfer, not before\n");
|
||||
rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
|
||||
rprintf(F," --delete-excluded also delete excluded files from destination dirs\n");
|
||||
rprintf(F," --ignore-errors delete even if there are I/O errors\n");
|
||||
rprintf(F," --force force deletion of directories even if not empty\n");
|
||||
rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
|
||||
@@ -360,7 +371,9 @@ void usage(enum logcode F)
|
||||
rprintf(F," --progress show progress during transfer\n");
|
||||
rprintf(F," -P same as --partial --progress\n");
|
||||
rprintf(F," -i, --itemize-changes output a change-summary for all updates\n");
|
||||
rprintf(F," --log-format=FORMAT output filenames using the specified format\n");
|
||||
rprintf(F," --out-format=FORMAT output updates using the specified FORMAT\n");
|
||||
rprintf(F," --log-file=FILE log what we're doing to the specified FILE\n");
|
||||
rprintf(F," --log-file-format=FMT log updates using the specified FMT\n");
|
||||
rprintf(F," --password-file=FILE read password from FILE\n");
|
||||
rprintf(F," --list-only list the files instead of copying them\n");
|
||||
rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
|
||||
@@ -373,9 +386,10 @@ void usage(enum logcode F)
|
||||
rprintf(F," -6, --ipv6 prefer IPv6\n");
|
||||
#endif
|
||||
rprintf(F," --version print version number\n");
|
||||
rprintf(F," --help show this help screen\n");
|
||||
rprintf(F,"(-h) --help show this help (-h works with no other options)\n");
|
||||
|
||||
rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Use \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
|
||||
rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
|
||||
rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
|
||||
}
|
||||
@@ -395,6 +409,8 @@ static struct poptOption long_options[] = {
|
||||
{"no-verbose", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
|
||||
{"no-v", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
|
||||
{"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
|
||||
{"motd", 0, POPT_ARG_VAL, &output_motd, 1, 0, 0 },
|
||||
{"no-motd", 0, POPT_ARG_VAL, &output_motd, 0, 0, 0 },
|
||||
{"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
|
||||
{"human-readable", 'h', POPT_ARG_NONE, 0, 'h', 0, 0},
|
||||
{"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
|
||||
@@ -434,11 +450,15 @@ static struct poptOption long_options[] = {
|
||||
{"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 },
|
||||
{"copy-unsafe-links",0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 },
|
||||
{"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
|
||||
{"copy-dirlinks", 'k', POPT_ARG_NONE, ©_dirlinks, 0, 0, 0 },
|
||||
{"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
|
||||
{"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
|
||||
{"hard-links", 'H', POPT_ARG_VAL, &preserve_hard_links, 1, 0, 0 },
|
||||
{"no-hard-links", 0, POPT_ARG_VAL, &preserve_hard_links, 0, 0, 0 },
|
||||
{"no-H", 0, POPT_ARG_VAL, &preserve_hard_links, 0, 0, 0 },
|
||||
{"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
|
||||
{"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
|
||||
{"no-R", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
|
||||
{"implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 1, 0, 0 },
|
||||
{"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
|
||||
{"chmod", 0, POPT_ARG_STRING, 0, OPT_CHMOD, 0, 0 },
|
||||
{"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
|
||||
@@ -459,7 +479,8 @@ static struct poptOption long_options[] = {
|
||||
{"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
|
||||
{"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
|
||||
{"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
|
||||
{"remove-sent-files",0, POPT_ARG_NONE, &remove_sent_files, 0, 0, 0 },
|
||||
{"remove-sent-files",0, POPT_ARG_VAL, &remove_source_files, 2, 0, 0 }, /* deprecated */
|
||||
{"remove-source-files",0,POPT_ARG_VAL, &remove_source_files, 1, 0, 0 },
|
||||
{"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
|
||||
{"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
|
||||
{"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
|
||||
@@ -489,7 +510,10 @@ static struct poptOption long_options[] = {
|
||||
{"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
|
||||
{"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
|
||||
{"prune-empty-dirs",'m', POPT_ARG_NONE, &prune_empty_dirs, 0, 0, 0 },
|
||||
{"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
|
||||
{"log-file", 0, POPT_ARG_STRING, &logfile_name, 0, 0, 0 },
|
||||
{"log-file-format", 0, POPT_ARG_STRING, &logfile_format, 0, 0, 0 },
|
||||
{"out-format", 0, POPT_ARG_STRING, &stdout_format, 0, 0, 0 },
|
||||
{"log-format", 0, POPT_ARG_STRING, &stdout_format, 0, 0, 0 }, /* DEPRECATED */
|
||||
{"itemize-changes", 'i', POPT_ARG_NONE, 0, 'i', 0, 0 },
|
||||
{"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
|
||||
{"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
|
||||
@@ -533,12 +557,15 @@ static void daemon_usage(enum logcode F)
|
||||
{
|
||||
print_rsync_version(F);
|
||||
|
||||
rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"Usage: rsync --daemon [OPTION]...\n");
|
||||
rprintf(F," --address=ADDRESS bind to the specified address\n");
|
||||
rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
|
||||
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
|
||||
rprintf(F," --no-detach do not detach from the parent\n");
|
||||
rprintf(F," --port=PORT listen on alternate port number\n");
|
||||
rprintf(F," --log-file=FILE override the \"log file\" setting\n");
|
||||
rprintf(F," --log-file-format=FMT override the \"log format\" setting\n");
|
||||
rprintf(F," --sockopts=OPTIONS specify custom TCP options\n");
|
||||
rprintf(F," -v, --verbose increase verbosity\n");
|
||||
#ifdef INET6
|
||||
@@ -547,7 +574,8 @@ static void daemon_usage(enum logcode F)
|
||||
#endif
|
||||
rprintf(F," --help show this help screen\n");
|
||||
|
||||
rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
|
||||
rprintf(F,"\n");
|
||||
rprintf(F,"If you were not trying to invoke rsync as a daemon, avoid using any of the\n");
|
||||
rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
|
||||
}
|
||||
|
||||
@@ -562,6 +590,8 @@ static struct poptOption long_daemon_options[] = {
|
||||
{"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
|
||||
#endif
|
||||
{"detach", 0, POPT_ARG_VAL, &no_detach, 0, 0, 0 },
|
||||
{"log-file", 0, POPT_ARG_STRING, &logfile_name, 0, 0, 0 },
|
||||
{"log-file-format", 0, POPT_ARG_STRING, &logfile_format, 0, 0, 0 },
|
||||
{"no-detach", 0, POPT_ARG_VAL, &no_detach, 1, 0, 0 },
|
||||
{"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
|
||||
{"sockopts", 0, POPT_ARG_STRING, &sockopts, 0, 0, 0 },
|
||||
@@ -587,11 +617,13 @@ static char err_buf[200];
|
||||
void option_error(void)
|
||||
{
|
||||
if (!err_buf[0]) {
|
||||
strcpy(err_buf, "Error parsing options: "
|
||||
"option may be supported on client but not on server?\n");
|
||||
strlcpy(err_buf, "Error parsing options: option may "
|
||||
"be supported on client but not on server?\n",
|
||||
sizeof err_buf);
|
||||
}
|
||||
|
||||
rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
|
||||
@@ -661,17 +693,6 @@ static void set_refuse_options(char *bp)
|
||||
*cp = ' ';
|
||||
bp = cp + 1;
|
||||
}
|
||||
|
||||
for (op = long_options; ; op++) {
|
||||
*shortname = op->shortName;
|
||||
if (!op->longName && !*shortname)
|
||||
break;
|
||||
if (op->val == OPT_DAEMON) {
|
||||
if (op->argInfo == POPT_ARG_VAL)
|
||||
op->argInfo = POPT_ARG_NONE;
|
||||
op->val = (op - long_options) + OPT_REFUSED_BASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -776,6 +797,8 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
|
||||
if (ref && *ref)
|
||||
set_refuse_options(ref);
|
||||
if (am_daemon)
|
||||
set_refuse_options("log-file*");
|
||||
|
||||
/* TODO: Call poptReadDefaultConfig; handle errors. */
|
||||
|
||||
@@ -814,7 +837,9 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
|
||||
case OPT_DAEMON:
|
||||
if (am_daemon) {
|
||||
strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
|
||||
strlcpy(err_buf,
|
||||
"Attempt to hack rsync thwarted!\n",
|
||||
sizeof err_buf);
|
||||
return 0;
|
||||
}
|
||||
poptFreeContext(pc);
|
||||
@@ -885,14 +910,17 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
case OPT_INCLUDE_FROM:
|
||||
arg = poptGetOptArg(pc);
|
||||
if (sanitize_paths)
|
||||
arg = sanitize_path(NULL, arg, NULL, 0);
|
||||
arg = sanitize_path(NULL, arg, NULL, 0, NULL);
|
||||
if (server_filter_list.head) {
|
||||
char *cp = (char *)arg;
|
||||
char *cp = strdup(arg);
|
||||
if (!cp)
|
||||
out_of_memory("parse_arguments");
|
||||
if (!*cp)
|
||||
goto options_rejected;
|
||||
clean_fname(cp, 1);
|
||||
if (check_filter(&server_filter_list, cp, 0) < 0)
|
||||
goto options_rejected;
|
||||
free(cp);
|
||||
}
|
||||
parse_filter_file(&filter_list, arg,
|
||||
opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
|
||||
@@ -1016,7 +1044,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
break;
|
||||
|
||||
case OPT_LINK_DEST:
|
||||
#ifdef HAVE_LINK
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
link_dest = 1;
|
||||
dest_option = "--link-dest";
|
||||
goto set_dest_dir;
|
||||
@@ -1042,10 +1070,9 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
MAX_BASIS_DIRS, dest_option);
|
||||
return 0;
|
||||
}
|
||||
arg = poptGetOptArg(pc);
|
||||
if (sanitize_paths)
|
||||
arg = sanitize_path(NULL, arg, NULL, 0);
|
||||
basis_dir[basis_dir_cnt++] = (char *)arg;
|
||||
/* We defer sanitizing this arg until we know what
|
||||
* our destination directory is going to be. */
|
||||
basis_dir[basis_dir_cnt++] = (char *)poptGetOptArg(pc);
|
||||
break;
|
||||
|
||||
case OPT_CHMOD:
|
||||
@@ -1172,11 +1199,10 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
}
|
||||
delete_mode = delete_before = 1;
|
||||
}
|
||||
saw_delete_opt = delete_mode;
|
||||
saw_delete_excluded_opt = delete_excluded;
|
||||
if (!xfer_dirs) {
|
||||
delete_before = delete_during = delete_after = 0;
|
||||
delete_mode = delete_excluded = 0;
|
||||
if (!xfer_dirs && delete_mode) {
|
||||
snprintf(err_buf, sizeof err_buf,
|
||||
"--delete does not work without -r or -d.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (delete_mode && refused_delete) {
|
||||
@@ -1184,8 +1210,8 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (remove_sent_files) {
|
||||
/* We only want to infer this refusal of --remove-sent-files
|
||||
if (remove_source_files) {
|
||||
/* We only want to infer this refusal of --remove-source-files
|
||||
* via the refusal of "delete", not any of the "delete-FOO"
|
||||
* options. */
|
||||
if (refused_delete && am_sender) {
|
||||
@@ -1201,17 +1227,14 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
if (sanitize_paths) {
|
||||
int i;
|
||||
for (i = *argc; i-- > 0; )
|
||||
(*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
|
||||
(*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0, NULL);
|
||||
if (tmpdir)
|
||||
tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
|
||||
if (partial_dir)
|
||||
partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
|
||||
tmpdir = sanitize_path(NULL, tmpdir, NULL, 0, NULL);
|
||||
if (backup_dir)
|
||||
backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
|
||||
backup_dir = sanitize_path(NULL, backup_dir, NULL, 0, NULL);
|
||||
}
|
||||
if (server_filter_list.head && !am_sender) {
|
||||
struct filter_list_struct *elp = &server_filter_list;
|
||||
int i;
|
||||
if (tmpdir) {
|
||||
if (!*tmpdir)
|
||||
goto options_rejected;
|
||||
@@ -1219,18 +1242,6 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
if (check_filter(elp, tmpdir, 1) < 0)
|
||||
goto options_rejected;
|
||||
}
|
||||
if (partial_dir && *partial_dir) {
|
||||
clean_fname(partial_dir, 1);
|
||||
if (check_filter(elp, partial_dir, 1) < 0)
|
||||
goto options_rejected;
|
||||
}
|
||||
for (i = 0; i < basis_dir_cnt; i++) {
|
||||
if (!*basis_dir[i])
|
||||
goto options_rejected;
|
||||
clean_fname(basis_dir[i], 1);
|
||||
if (check_filter(elp, basis_dir[i], 1) < 0)
|
||||
goto options_rejected;
|
||||
}
|
||||
if (backup_dir) {
|
||||
if (!*backup_dir)
|
||||
goto options_rejected;
|
||||
@@ -1279,17 +1290,17 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
if (make_backups && !backup_dir)
|
||||
omit_dir_times = 1;
|
||||
|
||||
if (log_format) {
|
||||
if (am_server && log_format_has(log_format, 'I'))
|
||||
log_format_has_i = 2;
|
||||
else if (log_format_has(log_format, 'i'))
|
||||
log_format_has_i = itemize_changes | 1;
|
||||
if (!log_format_has(log_format, 'b')
|
||||
&& !log_format_has(log_format, 'c'))
|
||||
if (stdout_format) {
|
||||
if (am_server && log_format_has(stdout_format, 'I'))
|
||||
stdout_format_has_i = 2;
|
||||
else if (log_format_has(stdout_format, 'i'))
|
||||
stdout_format_has_i = itemize_changes | 1;
|
||||
if (!log_format_has(stdout_format, 'b')
|
||||
&& !log_format_has(stdout_format, 'c'))
|
||||
log_before_transfer = !am_server;
|
||||
} else if (itemize_changes) {
|
||||
log_format = "%i %n%L";
|
||||
log_format_has_i = itemize_changes;
|
||||
stdout_format = "%i %n%L";
|
||||
stdout_format_has_i = itemize_changes;
|
||||
log_before_transfer = !am_server;
|
||||
}
|
||||
|
||||
@@ -1301,12 +1312,26 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
|
||||
set_io_timeout(io_timeout);
|
||||
|
||||
if (verbose && !log_format) {
|
||||
log_format = "%n%L";
|
||||
if (verbose && !stdout_format) {
|
||||
stdout_format = "%n%L";
|
||||
log_before_transfer = !am_server;
|
||||
}
|
||||
if (log_format_has_i || log_format_has(log_format, 'o'))
|
||||
log_format_has_o_or_i = 1;
|
||||
if (stdout_format_has_i || log_format_has(stdout_format, 'o'))
|
||||
stdout_format_has_o_or_i = 1;
|
||||
|
||||
if (logfile_name && !am_daemon) {
|
||||
if (!logfile_format) {
|
||||
logfile_format = "%i %n%L";
|
||||
logfile_format_has_i = logfile_format_has_o_or_i = 1;
|
||||
} else {
|
||||
if (log_format_has(logfile_format, 'i'))
|
||||
logfile_format_has_i = 1;
|
||||
if (logfile_format_has_i || log_format_has(logfile_format, 'o'))
|
||||
logfile_format_has_o_or_i = 1;
|
||||
}
|
||||
log_init(0);
|
||||
} else if (!am_daemon)
|
||||
logfile_format = NULL;
|
||||
|
||||
if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
|
||||
bwlimit = daemon_bwlimit;
|
||||
@@ -1373,7 +1398,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
clean_fname(partial_dir, 1);
|
||||
if (!*partial_dir || strcmp(partial_dir, ".") == 0)
|
||||
partial_dir = NULL;
|
||||
else if (*partial_dir != '/') {
|
||||
else if (*partial_dir != '/' && !am_server) {
|
||||
parse_rule(&filter_list, partial_dir,
|
||||
MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
|
||||
}
|
||||
@@ -1411,7 +1436,7 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
}
|
||||
} else {
|
||||
if (sanitize_paths)
|
||||
files_from = sanitize_path(NULL, files_from, NULL, 0);
|
||||
files_from = sanitize_path(NULL, files_from, NULL, 0, NULL);
|
||||
if (server_filter_list.head) {
|
||||
if (!*files_from)
|
||||
goto options_rejected;
|
||||
@@ -1477,13 +1502,11 @@ void server_options(char **args,int *argc)
|
||||
argstr[x++] = 'b';
|
||||
if (update_only)
|
||||
argstr[x++] = 'u';
|
||||
if (!do_xfers) /* NOT "dry_run"! */
|
||||
if (!do_xfers) /* Note: NOT "dry_run"! */
|
||||
argstr[x++] = 'n';
|
||||
if (preserve_links)
|
||||
argstr[x++] = 'l';
|
||||
if (copy_links)
|
||||
argstr[x++] = 'L';
|
||||
if (xfer_dirs > (recurse || !delete_mode || !am_sender))
|
||||
if (xfer_dirs > (recurse || !delete_mode || !am_sender ? 1 : 0))
|
||||
argstr[x++] = 'd';
|
||||
if (am_sender) {
|
||||
if (keep_dirlinks)
|
||||
@@ -1492,6 +1515,11 @@ void server_options(char **args,int *argc)
|
||||
argstr[x++] = 'm';
|
||||
if (omit_dir_times == 2)
|
||||
argstr[x++] = 'O';
|
||||
} else {
|
||||
if (copy_links)
|
||||
argstr[x++] = 'L';
|
||||
if (copy_dirlinks)
|
||||
argstr[x++] = 'k';
|
||||
}
|
||||
|
||||
if (whole_file > 0)
|
||||
@@ -1568,12 +1596,13 @@ void server_options(char **args,int *argc)
|
||||
|
||||
/* The server side doesn't use our log-format, but in certain
|
||||
* circumstances they need to know a little about the option. */
|
||||
if (log_format && am_sender) {
|
||||
if (log_format_has_i > 1)
|
||||
if (stdout_format && am_sender) {
|
||||
/* Use --log-format, not --out-format, for compatibility. */
|
||||
if (stdout_format_has_i > 1)
|
||||
args[ac++] = "--log-format=%i%I";
|
||||
else if (log_format_has_i)
|
||||
else if (stdout_format_has_i)
|
||||
args[ac++] = "--log-format=%i";
|
||||
else if (log_format_has_o_or_i)
|
||||
else if (stdout_format_has_o_or_i)
|
||||
args[ac++] = "--log-format=%o";
|
||||
else if (!verbose)
|
||||
args[ac++] = "--log-format=X";
|
||||
@@ -1729,7 +1758,9 @@ void server_options(char **args,int *argc)
|
||||
if (fuzzy_basis && am_sender)
|
||||
args[ac++] = "--fuzzy";
|
||||
|
||||
if (remove_sent_files)
|
||||
if (remove_source_files == 1)
|
||||
args[ac++] = "--remove-source-files";
|
||||
else if (remove_source_files)
|
||||
args[ac++] = "--remove-sent-files";
|
||||
|
||||
*argc = ac;
|
||||
@@ -1750,10 +1781,10 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
|
||||
{
|
||||
char *p;
|
||||
int not_host;
|
||||
int hostlen;
|
||||
|
||||
if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
|
||||
char *path;
|
||||
int hostlen;
|
||||
s += strlen(URL_PREFIX);
|
||||
if ((p = strchr(s, '/')) != NULL) {
|
||||
hostlen = p - s;
|
||||
@@ -1782,6 +1813,7 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
|
||||
|
||||
if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
|
||||
s++;
|
||||
hostlen = p - s;
|
||||
*p = '\0';
|
||||
not_host = strchr(s, '/') || !strchr(s, ':');
|
||||
*p = ']';
|
||||
@@ -1791,6 +1823,7 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
|
||||
} else {
|
||||
if (!(p = strchr(s, ':')))
|
||||
return NULL;
|
||||
hostlen = p - s;
|
||||
*p = '\0';
|
||||
not_host = strchr(s, '/') != NULL;
|
||||
*p = ':';
|
||||
@@ -1798,8 +1831,8 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*host_ptr = new_array(char, p - s + 1);
|
||||
strlcpy(*host_ptr, s, p - s + 1);
|
||||
*host_ptr = new_array(char, hostlen + 1);
|
||||
strlcpy(*host_ptr, s, hostlen + 1);
|
||||
|
||||
if (p[1] == ':') {
|
||||
if (port_ptr && !*port_ptr)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Summary: A program for synchronizing files over a network.
|
||||
Name: rsync
|
||||
Version: 2.6.7pre1
|
||||
Version: 2.6.9
|
||||
Release: 1
|
||||
Group: Applications/Internet
|
||||
Source: ftp://rsync.samba.org/pub/rsync/rsync-%{version}.tar.gz
|
||||
|
||||
122
packaging/nightly-rsync
Executable file
122
packaging/nightly-rsync
Executable file
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
|
||||
# This script expects the directory ~/samba-rsync-ftp to exist and to be a
|
||||
# copy of the /home/ftp/pub/rsync dir on samba.org. It also requires a
|
||||
# pristine CVS checkout of rsync (don't use your normal rsync build dir
|
||||
# unless you're 100% sure that there are not unchecked-in changes).
|
||||
#
|
||||
# If this is run with -ctu, it will make an updated "nightly" tar file in
|
||||
# the nightly dir. It will also remove any old tar files, regenerate the
|
||||
# HTML man pages in the nightly dir, and then rsync the changes to the
|
||||
# samba.org server.
|
||||
|
||||
use Getopt::Long;
|
||||
use Date::Format;
|
||||
|
||||
# Choose any dir where a pristine rsync has been checked out of CVS.
|
||||
our $unpacked = $ENV{HOME} . '/release/nightly';
|
||||
# Where the local copy of /home/ftp/pub/rsync/nightly should be updated.
|
||||
our $nightly = $ENV{HOME} . '/samba-rsync-ftp/nightly';
|
||||
our $nightly_symlink = "$nightly/rsync-HEAD.tar.gz";
|
||||
|
||||
our($cvs_update, $make_tar, $upload, $help_opt);
|
||||
&Getopt::Long::Configure('bundling');
|
||||
&usage if !&GetOptions(
|
||||
'cvs-update|c' => \$cvs_update,
|
||||
'make-tar|t' => \$make_tar,
|
||||
'upload|u' => \$upload,
|
||||
'help|h' => \$help_opt,
|
||||
) || $help_opt;
|
||||
|
||||
our $name = time2str('rsync-HEAD-%Y%m%d-%H%M%Z', time, 'GMT');
|
||||
our $ztoday = time2str('%d %b %Y', time);
|
||||
our $today = $ztoday;
|
||||
|
||||
chdir($unpacked) or die $!;
|
||||
|
||||
if ($cvs_update) {
|
||||
print "Updating from cvs...\n";
|
||||
system 'cvs -q up' and die $!;
|
||||
}
|
||||
|
||||
if ($make_tar) {
|
||||
print "Generating list of active CVS files...\n";
|
||||
my($dir, @files);
|
||||
open(CVS, '-|', 'cvs status 2>&1') or die $!;
|
||||
while (<CVS>) {
|
||||
if (/^cvs status: Examining (.*)/) {
|
||||
if ($1 eq '.') {
|
||||
$dir = '';
|
||||
} else {
|
||||
push(@files, $1);
|
||||
$dir = $1 . '/';
|
||||
}
|
||||
} elsif (/^File: (.*?)\s+Status: (.*)/ && $1 ne '.cvsignore') {
|
||||
push(@files, $dir . $1);
|
||||
if ($2 ne 'Up-to-date') {
|
||||
print "*** Not up-to-date: $dir$1\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
close CVS;
|
||||
|
||||
print "Creating $unpacked/$name.tar.gz\n";
|
||||
chdir('..') or die $!;
|
||||
rename($unpacked, $name) or die $!;
|
||||
open(TAR, '|-', "fakeroot tar --files-from=- --no-recursion --mode=g-w -czf $nightly/$name.tar.gz $name") or die $!;
|
||||
foreach (@files) {
|
||||
print TAR "$name/$_\n";
|
||||
}
|
||||
close TAR;
|
||||
rename($name, $unpacked) or die $!;
|
||||
unlink($nightly_symlink);
|
||||
symlink("$name.tar.gz", $nightly_symlink);
|
||||
}
|
||||
|
||||
chdir($nightly) or die $!;
|
||||
|
||||
foreach my $fn (qw( rsync.yo rsyncd.conf.yo )) {
|
||||
my $html_fn = $fn;
|
||||
$html_fn =~ s/\.yo/.html/;
|
||||
|
||||
open(IN, '<', "$unpacked/$fn") or die $!;
|
||||
undef $/; $_ = <IN>; $/ = "\n";
|
||||
close IN;
|
||||
|
||||
s/^(manpage\([^)]+\)\(\d+\)\()[^)]+(\).*)/$1$today$2/m;
|
||||
#s/^(This man ?page is current for version) \S+ (of rsync)/$1 $version $2/m;
|
||||
|
||||
open(OUT, '>', $fn) or die $!;
|
||||
print OUT $_;
|
||||
close OUT;
|
||||
|
||||
system "yodl2html -o $html_fn $fn";
|
||||
|
||||
unlink($fn);
|
||||
}
|
||||
|
||||
system "find . -name 'rsync-HEAD-*' -daystart -mtime +14 | xargs rm -f";
|
||||
system 'ls -ltr';
|
||||
|
||||
if ($upload) {
|
||||
my $opt = '';
|
||||
if (defined $ENV{RSYNC_PARTIAL_DIR}) {
|
||||
$opt = " -f 'R $ENV{RSYNC_PARTIAL_DIR}'";
|
||||
}
|
||||
system "rsync$opt -aviHP --delete-after . samba.org:/home/ftp/pub/rsync/nightly";
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
sub usage
|
||||
{
|
||||
die <<EOT;
|
||||
Usage: nightly-rsync [OPTIONS]
|
||||
|
||||
-c, --cvs-update update $unpacked via CVS.
|
||||
-t, --make-tar create a new tar file in $nightly
|
||||
-u, --upload upload the revised nightly dir to samba.org
|
||||
-h, --help display this help
|
||||
EOT
|
||||
}
|
||||
319
packaging/release-rsync
Executable file
319
packaging/release-rsync
Executable file
@@ -0,0 +1,319 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
|
||||
# This script expects the directory ~/samba-rsync-ftp to exist and to
|
||||
# be a copy of the /home/ftp/pub/rsync dir on samba.org. If it is run
|
||||
# in test mode, it instead expects a dir named ~/tmp/samba-rsync-ftp
|
||||
# (e.g. copy ~/samba-rsync-ftp into ~/tmp and you can do a trial-run of
|
||||
# a release without affecting the files in the ~/samba-rsync-ftp dir).
|
||||
#
|
||||
# Run this as "release-rsync live" to affect ~/samba-rsync-ftp instead
|
||||
# of ~/tmp/samba-rsync-ftp.
|
||||
|
||||
use Date::Format;
|
||||
|
||||
my $dest = $ENV{HOME} . '/samba-rsync-ftp';
|
||||
my $releasedir = $ENV{HOME} . '/release';
|
||||
my $cvsroot = $ENV{CVSROOT} = 'samba.org:/data/cvs';
|
||||
|
||||
my $ztoday = time2str('%d %b %Y', time);
|
||||
my $today = $ztoday;
|
||||
$today =~ s/^0//;
|
||||
|
||||
my $break = <<EOT;
|
||||
==========================================================================
|
||||
EOT
|
||||
my $note = <<EOT;
|
||||
== Note: type "-a u,n" if you want to auto-accept the U,N suggestions. ==
|
||||
EOT
|
||||
|
||||
my $live = shift;
|
||||
my $skipping = '';
|
||||
|
||||
print $break;
|
||||
if ($live) {
|
||||
print <<EOT;
|
||||
== This will release a new version of rsync onto an unsuspecting world. ==
|
||||
EOT
|
||||
} else {
|
||||
print <<EOT;
|
||||
== **** TESTMODE **** (Add "live" arg to avoid this.) ==
|
||||
EOT
|
||||
$dest =~ s#([^/]+$)#tmp/$1#;
|
||||
$skipping = ' ** SKIPPING **';
|
||||
}
|
||||
die "$dest does not exist\n" unless -d $dest;
|
||||
|
||||
print $break, "\nChecking out the latest rsync into $releasedir ...\n";
|
||||
|
||||
mkdir($releasedir, 0755) or die $! unless -d $releasedir;
|
||||
chdir($releasedir) or die $!;
|
||||
|
||||
system 'rm -rf rsync';
|
||||
|
||||
my(%dirs, @files);
|
||||
open(CVS, '-|', 'cvs checkout -P rsync') or die $!;
|
||||
while (<CVS>) {
|
||||
print $_;
|
||||
next if /\.(cvs)?ignore$/;
|
||||
if (m#^[UP] rsync/(.*)#) {
|
||||
my $fn = $1;
|
||||
my($dir) = $fn =~ m#^(.+)/#;
|
||||
push(@files, $dir) if defined($dir) && !$dirs{$1}++;
|
||||
push(@files, $fn);
|
||||
}
|
||||
}
|
||||
|
||||
chdir('rsync') or die $!;
|
||||
|
||||
my($version, $lastversion);
|
||||
open(IN, 'configure.in') or die $!;
|
||||
while (<IN>) {
|
||||
if (/^RSYNC_VERSION=(.*)/) {
|
||||
$version = $lastversion = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
|
||||
$lastversion =~ s/(\d+)cvs$/ $1 - 1 /e;
|
||||
$version =~ s/cvs/pre1/ || $version =~ s/pre(\d+)/ 'pre' . ($1 + 1) /e;
|
||||
|
||||
print $break, "\nPlease enter the version number of this release: [$version] ";
|
||||
chomp($_ = <STDIN>);
|
||||
if ($_ eq '.') {
|
||||
$version =~ s/pre\d+//;
|
||||
} elsif ($_ ne '') {
|
||||
$version = $_;
|
||||
}
|
||||
$version =~ s/[-.]*pre[-.]*/pre/;
|
||||
|
||||
$lastversion =~ s/(\d+)pre\d+$/ $1 - 1 /e unless $version =~ /pre/;
|
||||
|
||||
my $cvstag = "release-$version";
|
||||
$cvstag =~ s/[.]/-/g;
|
||||
$cvstag =~ s/pre/-pre/;
|
||||
|
||||
print "Enter the previous version to produce a patch against: [$lastversion] ";
|
||||
chomp($_ = <STDIN>);
|
||||
$lastversion = $_ if $_ ne '';
|
||||
$lastversion =~ s/[-.]*pre[-.]*/pre/;
|
||||
|
||||
my $release = 1;
|
||||
print "Please enter the RPM release number of this release: [$release] ";
|
||||
chomp($_ = <STDIN>);
|
||||
$release = $_ if $_ ne '';
|
||||
|
||||
my $diffdir;
|
||||
my $skipping2;
|
||||
if ($lastversion =~ /pre/) {
|
||||
if ($version !~ /pre/) {
|
||||
die "You should not diff a release version against a pre-release version.\n";
|
||||
}
|
||||
$diffdir = "$dest/old-previews";
|
||||
$skipping2 = ' ** SKIPPING **';
|
||||
} elsif ($version =~ /pre/) {
|
||||
$diffdir = $dest;
|
||||
$skipping2 = ' ** SKIPPING **';
|
||||
} else {
|
||||
$diffdir = "$dest/old-versions";
|
||||
$skipping2 = '';
|
||||
}
|
||||
|
||||
print "\n", $break, <<EOT;
|
||||
\$version is "$version"
|
||||
\$lastversion is "$lastversion"
|
||||
\$cvstag is "$cvstag"
|
||||
\$dest is "$dest"
|
||||
\$releasedir is "$releasedir"
|
||||
\$diffdir is "$diffdir"
|
||||
\$release is "$release"
|
||||
|
||||
About to:
|
||||
- make sure that configure, config.h.in, and proto.h are updated
|
||||
- tweak the version in configure.in, configure, and the spec files
|
||||
- tweak NEWS and OLDNEWS to update the release date$skipping2
|
||||
- tweak the date in the *.yo files and re-generate the man pages
|
||||
- make sure that the patches dir has been updated
|
||||
- page through the "cvs diff" output
|
||||
|
||||
EOT
|
||||
print "<Press Enter to continue> ";
|
||||
$_ = <STDIN>;
|
||||
my $f_opt = /f/ ? ' -f' : '';
|
||||
|
||||
print $break;
|
||||
system "./prepare-source && touch proto.h";
|
||||
|
||||
my @tweak_files = ( glob('packaging/*.spec'), glob('packaging/*/*.spec'),
|
||||
glob('*.yo'), qw( configure.in configure ) );
|
||||
if ($version !~ /pre/) {
|
||||
push(@tweak_files, qw( NEWS OLDNEWS ));
|
||||
}
|
||||
foreach my $fn (@tweak_files) {
|
||||
open(IN, '<', $fn) or die $!;
|
||||
undef $/; $_ = <IN>; $/ = "\n";
|
||||
close IN;
|
||||
if ($fn =~ /configure/) {
|
||||
s/^RSYNC_VERSION=.*/RSYNC_VERSION=$version/m;
|
||||
} elsif ($fn =~ /\.spec/) {
|
||||
s/^(Version:) .*/$1 $version/m;
|
||||
s/^(Release:) .*/$1 $release/m;
|
||||
} elsif ($fn =~ /\.yo/) {
|
||||
s/^(manpage\([^)]+\)\(\d+\)\()[^)]+(\).*)/$1$today$2/m;
|
||||
s/^(This man ?page is current for version) \S+ (of rsync)/$1 $version $2/m;
|
||||
} elsif ($fn eq 'NEWS') {
|
||||
s/^(NEWS for rsync \Q$version\E) \(UNRELEASED\)\s*\n/$1 ($today)\n/mi
|
||||
or die "Couldn't update NEWS file with release date!\n";
|
||||
} elsif ($fn eq 'OLDNEWS') {
|
||||
s/^\t\S\S\s\S\S\S\s\d\d\d\d(\t\Q$version\E)/\t$ztoday$1/m
|
||||
or die "Couldn't update OLDNEWS file with release date!\n";
|
||||
} else {
|
||||
die "Unrecognized file in \@tweak_files: $fn\n";
|
||||
}
|
||||
open(OUT, '>', $fn) or die $!;
|
||||
print OUT $_;
|
||||
close OUT;
|
||||
}
|
||||
|
||||
system "yodl2man -o rsync.1 rsync.yo; ./tweak_manpage_dashes rsync.1";
|
||||
system "yodl2man -o rsyncd.conf.5 rsyncd.conf.yo; ./tweak_manpage_dashes rsyncd.conf.5";
|
||||
|
||||
mkdir('patches/tmp') or die $!;
|
||||
system "rsync -a --exclude=patches/ --exclude-from=.cvsignore . patches/tmp/cvsdir/";
|
||||
|
||||
print "\n", $break, $note, $break;
|
||||
system "patches/verify-patches -n -an$f_opt";
|
||||
|
||||
print $break;
|
||||
system "cvs -q diff | egrep -v '^(===============|RCS file: |retrieving revision |Index: )' | less -p '^diff .*'";
|
||||
|
||||
print $break, <<EOT;
|
||||
|
||||
About to:
|
||||
- "cvs commit" all changes$skipping
|
||||
- "cvs tag" this release as $cvstag$skipping
|
||||
- change the diffs in the patches dir to include generated files
|
||||
|
||||
EOT
|
||||
print "<Press Enter to continue> ";
|
||||
$_ = <STDIN>;
|
||||
|
||||
if ($live) {
|
||||
system "cvs commit -m 'Preparing for release of $version'";
|
||||
system "cvs tag -F $cvstag .";
|
||||
}
|
||||
|
||||
if (!/skip/i) {
|
||||
print "\n", $break, $note, $break;
|
||||
system "patches/verify-patches -pun -an";
|
||||
}
|
||||
|
||||
my $tar_name = "rsync-$version.tar.gz";
|
||||
my $diff_name = "rsync-$lastversion-$version.diffs.gz";
|
||||
my $tar_file = "$dest/$tar_name";
|
||||
my $diff_file = "$dest/$diff_name";
|
||||
|
||||
print $break, <<EOT;
|
||||
|
||||
About to do the following in the samba-rsync-ftp dir:
|
||||
- move the old tar/diff files into the appropriate old-* dirs
|
||||
- hard-link the moved tar/diff files on samba.org$skipping
|
||||
- create release tar, "$tar_name"
|
||||
- create release diffs, "$diff_name"
|
||||
- update README, *NEWS, TODO, and cvs.log
|
||||
- update rsync*.html man pages
|
||||
- gpg-sign the release files$skipping
|
||||
|
||||
EOT
|
||||
print "<Press Enter to continue> ";
|
||||
$_ = <STDIN>;
|
||||
|
||||
chdir($releasedir) or die $!;
|
||||
|
||||
print $break;
|
||||
system "rm -rf rsync-$version";
|
||||
rename('rsync', "rsync-$version") or die $!;
|
||||
|
||||
# When creating a pre-release after a normal release, there's nothing to move.
|
||||
if ($diffdir ne $dest) {
|
||||
chdir($dest) or die $!;
|
||||
|
||||
print "Shuffling old files ...\n";
|
||||
|
||||
# We need to run this regardless of $lastversion's "pre"ness.
|
||||
my @moved_files;
|
||||
foreach my $fn (glob('rsync*pre*.tar.gz*'), glob('rsync*pre*-NEWS')) {
|
||||
link($fn, "old-previews/$fn") or die $!;
|
||||
push(@moved_files, $fn);
|
||||
}
|
||||
|
||||
if ($version !~ /pre/) {
|
||||
foreach my $fn (glob('rsync*.tar.gz*'), glob('rsync*-NEWS')) {
|
||||
next if $fn =~ /^rsync.*pre/;
|
||||
link($fn, "old-versions/$fn") or die $!;
|
||||
push(@moved_files, $fn);
|
||||
}
|
||||
|
||||
foreach my $fn (glob('rsync*pre*.diffs.gz*')) {
|
||||
unlink($fn);
|
||||
}
|
||||
|
||||
foreach my $fn (glob('rsync*.diffs.gz*')) {
|
||||
link($fn, "old-patches/$fn") or die $!;
|
||||
push(@moved_files, $fn);
|
||||
}
|
||||
}
|
||||
|
||||
# Optimize our future upload (in the absence of --detect-renamed) by
|
||||
# using rsync to hard-link the above files on samba.org.
|
||||
if ($live) {
|
||||
system "rsync -avHOC --include='rsync*.gz*' --include='old-*/' --exclude='*' . samba.org:/home/ftp/pub/rsync";
|
||||
}
|
||||
foreach (@moved_files) {
|
||||
unlink($_);
|
||||
}
|
||||
|
||||
chdir($releasedir) or die $!;
|
||||
}
|
||||
|
||||
print "Creating $tar_file ...\n";
|
||||
system "fakeroot tar czf $tar_file rsync-$version";
|
||||
open(TAR, '|-', "fakeroot tar --files-from=- --no-recursion --mode=g+w -czf $tar_file rsync-$version") or die $!;
|
||||
foreach (@files) {
|
||||
print TAR "rsync-$version/$_\n";
|
||||
}
|
||||
close TAR;
|
||||
|
||||
print "Creating $diff_file ...\n";
|
||||
system "rm -rf rsync-$version rsync-$lastversion";
|
||||
system "tar xzf $tar_file; tar xzf $diffdir/rsync-$lastversion.tar.gz";
|
||||
## TWEAK THE VERSIONS AS DESIRED HERE ##
|
||||
#mkdir("rsync-$lastversion/support", 0755) or die $!;
|
||||
#rename("rsync-$lastversion/rsyncstats", "rsync-$lastversion/support/rsyncstats");
|
||||
#unlink("rsync-$lastversion/.ignore");
|
||||
## END ##
|
||||
system "diff -urN --exclude=patches rsync-$lastversion rsync-$version| gzip -9 >$diff_file";
|
||||
|
||||
print "Updating the other files in $dest ...\n";
|
||||
system "rsync -a rsync-$version/{README,NEWS,OLDNEWS,TODO} $dest";
|
||||
unlink("$dest/rsync-$version-NEWS");
|
||||
link("$dest/NEWS", "$dest/rsync-$version-NEWS");
|
||||
system "rsync -a $cvsroot/CVSROOT/rsync.updates $dest/cvs.log";
|
||||
|
||||
system "yodl2html -o $dest/rsync.html rsync-$version/rsync.yo";
|
||||
system "yodl2html -o $dest/rsyncd.conf.html rsync-$version/rsyncd.conf.yo";
|
||||
|
||||
system "rm -rf rsync-*";
|
||||
|
||||
if ($live) {
|
||||
chdir($dest) or die $!;
|
||||
system "gpg -ba $tar_name; gpg -ba $diff_name";
|
||||
print $break, <<EOT;
|
||||
|
||||
All done. Remember to announce the release on *BOTH*
|
||||
rsync-announce\@lists.samba.org and rsync\@lists.samba.org!
|
||||
EOT
|
||||
} else {
|
||||
print $break, "All done.\n";
|
||||
}
|
||||
19
params.c
19
params.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
This modules is based on the params.c module from Samba, written by Karl Auer
|
||||
and much modifed by Christopher Hertel.
|
||||
/* This modules is based on the params.c module from Samba, written by Karl Auer
|
||||
and much modifed by Christopher Hertel. */
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
@@ -12,11 +12,12 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* Module name: params
|
||||
*
|
||||
@@ -491,7 +492,7 @@ static FILE *OpenConfFile( char *FileName )
|
||||
OpenedFile = fopen( FileName, "r" );
|
||||
if( NULL == OpenedFile )
|
||||
{
|
||||
rsyserr(FERROR, errno, "rsync: unable to open configuration file \"%s\"",
|
||||
rsyserr(FERROR, errno, "unable to open configuration file \"%s\"",
|
||||
FileName);
|
||||
}
|
||||
|
||||
|
||||
25
pipe.c
25
pipe.c
@@ -1,8 +1,10 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
/*
|
||||
* Routines used to setup various kinds of inter-process pipes.
|
||||
*
|
||||
* Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2004, 2005, 2006 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
|
||||
@@ -14,9 +16,9 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
@@ -24,8 +26,9 @@
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
extern int blocking_io;
|
||||
extern int orig_umask;
|
||||
extern int filesfrom_fd;
|
||||
extern mode_t orig_umask;
|
||||
extern char *logfile_name;
|
||||
extern struct chmod_mode_struct *chmod_modes;
|
||||
|
||||
/**
|
||||
@@ -146,6 +149,12 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
|
||||
child_main(argc, argv);
|
||||
}
|
||||
|
||||
/* Let the client side handle this. */
|
||||
if (logfile_name) {
|
||||
logfile_name = NULL;
|
||||
logfile_close();
|
||||
}
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 ||
|
||||
close(to_child_pipe[0]) < 0) {
|
||||
rsyserr(FERROR, errno, "Failed to close");
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#!/bin/sh
|
||||
# Use autoconf, autoheader, yodl, etc. to ready the generated files
|
||||
# in the release. This is typically used after applying a diff from
|
||||
# "patches" directory in CVS.
|
||||
# Use autoconf, autoheader, yodl, etc. to ready the generated files in the
|
||||
# release. This is typically used after applying a diff from the "patches"
|
||||
# directory in a CVS-checked-out version.
|
||||
#
|
||||
# NOTE: if you use a diff from the "patches" directory in a release
|
||||
# tar as of 2.6.7, this is not needed (but doesn't hurt anything).
|
||||
# NOTE: if you use a diff from the "patches" directory of a *release tar*
|
||||
# (as opposed to from CVS), this is not needed (but doesn't hurt anything).
|
||||
dir=`dirname $0`
|
||||
if test x"$dir" = x -o x"$dir" = x.; then
|
||||
make -f prepare-source.mak
|
||||
else
|
||||
make -C "$dir" -f prepare-source.mak
|
||||
if test x"$dir" != x -a x"$dir" != x.; then
|
||||
cd "$dir"
|
||||
fi
|
||||
make -f prepare-source.mak
|
||||
|
||||
@@ -18,6 +18,8 @@ man: rsync.1 rsyncd.conf.5
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man -o rsync.1 rsync.yo
|
||||
-./tweak_manpage_dashes rsync.1
|
||||
|
||||
rsyncd.conf.5: rsyncd.conf.yo
|
||||
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
|
||||
-./tweak_manpage_dashes rsyncd.conf.5
|
||||
|
||||
20
progress.c
20
progress.c
@@ -1,8 +1,10 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
/*
|
||||
* Routines to output progress information during a file transfer.
|
||||
*
|
||||
* Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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
|
||||
@@ -14,9 +16,9 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
@@ -102,8 +104,8 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
stats.num_files - stats.current_file_index - 1,
|
||||
stats.num_files);
|
||||
} else
|
||||
strcpy(eol, "\r");
|
||||
rprintf(FINFO, "%12s %3d%% %7.2f%s %4d:%02d:%02d%s",
|
||||
strlcpy(eol, "\r", sizeof eol);
|
||||
rprintf(FCLIENT, "%12s %3d%% %7.2f%s %4d:%02d:%02d%s",
|
||||
human_num(ofs), pct, rate, units,
|
||||
remain_h, remain_m, remain_s, eol);
|
||||
}
|
||||
|
||||
130
receiver.c
130
receiver.c
@@ -1,50 +1,46 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Routines only used by the receiving process.
|
||||
*
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int do_xfers;
|
||||
extern int am_daemon;
|
||||
extern int am_server;
|
||||
extern int do_progress;
|
||||
extern int log_before_transfer;
|
||||
extern int log_format_has_i;
|
||||
extern int daemon_log_format_has_i;
|
||||
extern int stdout_format_has_i;
|
||||
extern int logfile_format_has_i;
|
||||
extern int csum_length;
|
||||
extern int read_batch;
|
||||
extern int write_batch;
|
||||
extern int batch_gen_fd;
|
||||
extern int protocol_version;
|
||||
extern int relative_paths;
|
||||
extern int keep_dirlinks;
|
||||
extern int preserve_hard_links;
|
||||
extern int preserve_perms;
|
||||
extern int io_error;
|
||||
extern int basis_dir_cnt;
|
||||
extern int make_backups;
|
||||
extern int cleanup_got_literal;
|
||||
extern int remove_sent_files;
|
||||
extern int module_id;
|
||||
extern int ignore_errors;
|
||||
extern int orig_umask;
|
||||
extern int remove_source_files;
|
||||
extern int append_mode;
|
||||
extern int sparse_files;
|
||||
extern int keep_partial;
|
||||
@@ -52,7 +48,7 @@ extern int checksum_seed;
|
||||
extern int inplace;
|
||||
extern int delay_updates;
|
||||
extern struct stats stats;
|
||||
extern char *log_format;
|
||||
extern char *stdout_format;
|
||||
extern char *tmpdir;
|
||||
extern char *partial_dir;
|
||||
extern char *basis_dir[];
|
||||
@@ -61,6 +57,8 @@ extern struct filter_list_struct server_filter_list;
|
||||
|
||||
static struct bitbag *delayed_bits = NULL;
|
||||
static int phase = 0;
|
||||
/* We're either updating the basis file or an identical copy: */
|
||||
static int updating_basis;
|
||||
|
||||
|
||||
/*
|
||||
@@ -86,15 +84,13 @@ static int phase = 0;
|
||||
|
||||
static int get_tmpname(char *fnametmp, char *fname)
|
||||
{
|
||||
int maxname, added, length = 0;
|
||||
char *f;
|
||||
int length = 0;
|
||||
int maxname;
|
||||
|
||||
if (tmpdir) {
|
||||
/* Note: this can't overflow, so the return value is safe */
|
||||
length = strlcpy(fnametmp, tmpdir, MAXPATHLEN - 2);
|
||||
fnametmp[length++] = '/';
|
||||
fnametmp[length] = '\0'; /* always NULL terminated */
|
||||
}
|
||||
|
||||
if ((f = strrchr(fname, '/')) != NULL) {
|
||||
@@ -107,8 +103,9 @@ static int get_tmpname(char *fnametmp, char *fname)
|
||||
} else
|
||||
f = fname;
|
||||
fnametmp[length++] = '.';
|
||||
fnametmp[length] = '\0'; /* always NULL terminated */
|
||||
|
||||
/* The maxname value is bufsize, and includes space for the '\0'.
|
||||
* (Note that NAME_MAX get -8 for the leading '.' above.) */
|
||||
maxname = MIN(MAXPATHLEN - 7 - length, NAME_MAX - 8);
|
||||
|
||||
if (maxname < 1) {
|
||||
@@ -117,8 +114,10 @@ static int get_tmpname(char *fnametmp, char *fname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
strlcpy(fnametmp + length, f, maxname);
|
||||
strcat(fnametmp + length, ".XXXXXX");
|
||||
added = strlcpy(fnametmp + length, f, maxname);
|
||||
if (added >= maxname)
|
||||
added = maxname - 1;
|
||||
memcpy(fnametmp + length + added, ".XXXXXX", 8);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -171,9 +170,9 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
sum_update(map_ptr(mapbuf, offset, len), len);
|
||||
offset = sum.flength;
|
||||
}
|
||||
if (fd != -1 && do_lseek(fd, offset, SEEK_SET) != offset) {
|
||||
rsyserr(FERROR, errno, "lseek failed on %s",
|
||||
full_fname(fname));
|
||||
if (fd != -1 && (j = do_lseek(fd, offset, SEEK_SET)) != offset) {
|
||||
rsyserr(FERROR, errno, "lseek of %s returned %.0f, not %.0f",
|
||||
full_fname(fname), (double)j, (double)offset);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
}
|
||||
@@ -220,15 +219,17 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
sum_update(map, len);
|
||||
}
|
||||
|
||||
if (inplace) {
|
||||
if (updating_basis) {
|
||||
if (offset == offset2 && fd != -1) {
|
||||
OFF_T pos;
|
||||
if (flush_write_file(fd) < 0)
|
||||
goto report_write_error;
|
||||
offset += len;
|
||||
if (do_lseek(fd, len, SEEK_CUR) != offset) {
|
||||
if ((pos = do_lseek(fd, len, SEEK_CUR)) != offset) {
|
||||
rsyserr(FERROR, errno,
|
||||
"lseek failed on %s",
|
||||
full_fname(fname));
|
||||
"lseek of %s returned %.0f, not %.0f",
|
||||
full_fname(fname),
|
||||
(double)pos, (double)offset);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
continue;
|
||||
@@ -298,7 +299,7 @@ static void handle_delayed_updates(struct file_list *flist, char *local_name)
|
||||
"rename failed for %s (from %s)",
|
||||
full_fname(fname), partialptr);
|
||||
} else {
|
||||
if (remove_sent_files
|
||||
if (remove_source_files
|
||||
|| (preserve_hard_links
|
||||
&& file->link_u.links)) {
|
||||
SIVAL(numbuf, 0, i);
|
||||
@@ -346,8 +347,8 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
struct file_struct *file;
|
||||
struct stats initial_stats;
|
||||
int save_make_backups = make_backups;
|
||||
int itemizing = am_daemon ? daemon_log_format_has_i
|
||||
: !am_server && log_format_has_i;
|
||||
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;
|
||||
int i, recv_ok;
|
||||
|
||||
@@ -362,6 +363,8 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
if (delay_updates)
|
||||
delayed_bits = bitbag_create(flist->count);
|
||||
|
||||
updating_basis = inplace;
|
||||
|
||||
while (1) {
|
||||
cleanup_disable();
|
||||
|
||||
@@ -423,14 +426,13 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
}
|
||||
|
||||
if (!do_xfers) { /* log the transfer */
|
||||
if (!am_server && log_format)
|
||||
log_item(file, &stats, iflags, NULL);
|
||||
log_item(FCLIENT, file, &stats, iflags, NULL);
|
||||
if (read_batch)
|
||||
discard_receive_data(f_in, file->length);
|
||||
continue;
|
||||
}
|
||||
if (write_batch < 0) {
|
||||
log_item(file, &stats, iflags, NULL);
|
||||
log_item(FINFO, file, &stats, iflags, NULL);
|
||||
if (!am_server)
|
||||
discard_receive_data(f_in, file->length);
|
||||
continue;
|
||||
@@ -462,6 +464,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
fnamecmp = get_backup_name(fname);
|
||||
break;
|
||||
case FNAMECMP_FUZZY:
|
||||
updating_basis = 0;
|
||||
if (file->dirname) {
|
||||
pathjoin(fnamecmpbuf, MAXPATHLEN,
|
||||
file->dirname, xname);
|
||||
@@ -470,6 +473,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
fnamecmp = xname;
|
||||
break;
|
||||
default:
|
||||
updating_basis = 0;
|
||||
if (fnamecmp_type >= basis_dir_cnt) {
|
||||
rprintf(FERROR,
|
||||
"invalid basis_dir index: %d.\n",
|
||||
@@ -516,7 +520,10 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
}
|
||||
}
|
||||
|
||||
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
|
||||
if (fd1 == -1) {
|
||||
st.st_mode = 0;
|
||||
st.st_size = 0;
|
||||
} else if (do_fstat(fd1,&st) != 0) {
|
||||
rsyserr(FERROR, errno, "fstat %s failed",
|
||||
full_fname(fnamecmp));
|
||||
discard_receive_data(f_in, file->length);
|
||||
@@ -549,7 +556,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
file->mode = dest_mode(file->mode, st.st_mode, exists);
|
||||
}
|
||||
|
||||
/* We now check to see if we are writing file "inplace" */
|
||||
/* We now check to see if we are writing the file "inplace" */
|
||||
if (inplace) {
|
||||
fd2 = do_open(fname, O_WRONLY|O_CREAT, 0600);
|
||||
if (fd2 == -1) {
|
||||
@@ -580,7 +587,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
* because their information should have been previously
|
||||
* transferred, but that may not be the case with -R */
|
||||
if (fd2 == -1 && relative_paths && errno == ENOENT
|
||||
&& create_directory_path(fnametmp, orig_umask) == 0) {
|
||||
&& create_directory_path(fnametmp) == 0) {
|
||||
/* Get back to name with XXXXXX in it. */
|
||||
get_tmpname(fnametmp, fname);
|
||||
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
|
||||
@@ -594,13 +601,12 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keep_partial)
|
||||
cleanup_set(fnametmp, partialptr, file, fd1, fd2);
|
||||
cleanup_set(fnametmp, partialptr, file, fd1, fd2);
|
||||
}
|
||||
|
||||
/* log the transfer */
|
||||
if (log_before_transfer)
|
||||
log_item(file, &initial_stats, iflags, NULL);
|
||||
log_item(FCLIENT, file, &initial_stats, iflags, NULL);
|
||||
else if (!am_server && verbose && do_progress)
|
||||
rprintf(FINFO, "%s\n", fname);
|
||||
|
||||
@@ -608,8 +614,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
|
||||
fname, fd2, file->length);
|
||||
|
||||
if (!log_before_transfer)
|
||||
log_item(file, &initial_stats, iflags, NULL);
|
||||
log_item(log_code, file, &initial_stats, iflags, NULL);
|
||||
|
||||
if (fd1 != -1)
|
||||
close(fd1);
|
||||
@@ -620,9 +625,14 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
}
|
||||
|
||||
if ((recv_ok && (!delay_updates || !partialptr)) || inplace) {
|
||||
if (partialptr == fname || *partial_dir == '/')
|
||||
partialptr = NULL;
|
||||
finish_transfer(fname, fnametmp, partialptr,
|
||||
char *temp_copy_name;
|
||||
if (partialptr == fname)
|
||||
partialptr = temp_copy_name = NULL;
|
||||
else if (*partial_dir == '/')
|
||||
temp_copy_name = NULL;
|
||||
else
|
||||
temp_copy_name = partialptr;
|
||||
finish_transfer(fname, fnametmp, temp_copy_name,
|
||||
file, recv_ok, 1);
|
||||
if (fnamecmp == partialptr) {
|
||||
do_unlink(partialptr);
|
||||
@@ -644,7 +654,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
cleanup_disable();
|
||||
|
||||
if (recv_ok > 0) {
|
||||
if (remove_sent_files
|
||||
if (remove_source_files
|
||||
|| (preserve_hard_links && file->link_u.links)) {
|
||||
SIVAL(numbuf, 0, i);
|
||||
send_msg(MSG_SUCCESS, numbuf, 4);
|
||||
|
||||
79
rsync.c
79
rsync.c
@@ -1,24 +1,24 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* this file contains code used by more than one part of the rsync
|
||||
process */
|
||||
* Routines common to more than one of the rsync processes.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
@@ -32,12 +32,10 @@
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int daemon_log_format_has_i;
|
||||
extern int preserve_perms;
|
||||
extern int preserve_executability;
|
||||
extern int preserve_times;
|
||||
extern int omit_dir_times;
|
||||
extern int orig_umask;
|
||||
extern int am_root;
|
||||
extern int am_server;
|
||||
extern int am_sender;
|
||||
@@ -49,7 +47,9 @@ extern int preserve_gid;
|
||||
extern int inplace;
|
||||
extern int keep_dirlinks;
|
||||
extern int make_backups;
|
||||
extern mode_t orig_umask;
|
||||
extern struct stats stats;
|
||||
extern struct chmod_mode_struct *daemon_chmod_modes;
|
||||
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
iconv_t ic_chck = (iconv_t)-1;
|
||||
@@ -100,23 +100,27 @@ void free_sums(struct sum_struct *s)
|
||||
|
||||
/* This is only called when we aren't preserving permissions. Figure out what
|
||||
* the permissions should be and return them merged back into the mode. */
|
||||
mode_t dest_mode(mode_t flist_mode, mode_t cur_mode, int exists)
|
||||
mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int exists)
|
||||
{
|
||||
int new_mode;
|
||||
/* If the file already exists, we'll return the local permissions,
|
||||
* possibly tweaked by the --executability option. */
|
||||
if (exists) {
|
||||
new_mode = (flist_mode & ~CHMOD_BITS) | (stat_mode & CHMOD_BITS);
|
||||
if (preserve_executability && S_ISREG(flist_mode)) {
|
||||
/* If the source file is executable, grant execute
|
||||
* rights to everyone who can read, but ONLY if the
|
||||
* file isn't already executable. */
|
||||
if (!(flist_mode & 0111))
|
||||
cur_mode &= ~0111;
|
||||
else if (!(cur_mode & 0111))
|
||||
cur_mode |= (cur_mode & 0444) >> 2;
|
||||
new_mode &= ~0111;
|
||||
else if (!(stat_mode & 0111))
|
||||
new_mode |= (new_mode & 0444) >> 2;
|
||||
}
|
||||
} else
|
||||
cur_mode = flist_mode & ACCESSPERMS & ~orig_umask;
|
||||
return (flist_mode & ~CHMOD_BITS) | (cur_mode & CHMOD_BITS);
|
||||
} else {
|
||||
/* Apply the umask and turn off special permissions. */
|
||||
new_mode = flist_mode & (~CHMOD_BITS | (ACCESSPERMS & ~orig_umask));
|
||||
}
|
||||
return new_mode;
|
||||
}
|
||||
|
||||
int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
|
||||
@@ -125,6 +129,7 @@ int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
|
||||
int updated = 0;
|
||||
STRUCT_STAT st2;
|
||||
int change_uid, change_gid;
|
||||
mode_t new_mode = file->mode;
|
||||
|
||||
if (!st) {
|
||||
if (dry_run)
|
||||
@@ -135,11 +140,11 @@ int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
|
||||
return 0;
|
||||
}
|
||||
st = &st2;
|
||||
if (!preserve_perms && S_ISDIR(file->mode)
|
||||
if (!preserve_perms && S_ISDIR(new_mode)
|
||||
&& st->st_mode & S_ISGID) {
|
||||
/* We just created this directory and its setgid
|
||||
* bit is on, so make sure it stays on. */
|
||||
file->mode |= S_ISGID;
|
||||
new_mode |= S_ISGID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,9 +205,11 @@ int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
|
||||
updated = 1;
|
||||
}
|
||||
|
||||
if (daemon_chmod_modes && !S_ISLNK(new_mode))
|
||||
new_mode = tweak_mode(new_mode, daemon_chmod_modes);
|
||||
#ifdef HAVE_CHMOD
|
||||
if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
|
||||
int ret = do_chmod(fname, file->mode);
|
||||
if ((st->st_mode & CHMOD_BITS) != (new_mode & CHMOD_BITS)) {
|
||||
int ret = do_chmod(fname, new_mode);
|
||||
if (ret < 0) {
|
||||
rsyserr(FERROR, errno,
|
||||
"failed to set permissions on %s",
|
||||
@@ -215,12 +222,10 @@ int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
|
||||
#endif
|
||||
|
||||
if (verbose > 1 && flags & ATTRS_REPORT) {
|
||||
enum logcode code = daemon_log_format_has_i || dry_run
|
||||
? FCLIENT : FINFO;
|
||||
if (updated)
|
||||
rprintf(code, "%s\n", fname);
|
||||
rprintf(FCLIENT, "%s\n", fname);
|
||||
else
|
||||
rprintf(code, "%s is uptodate\n", fname);
|
||||
rprintf(FCLIENT, "%s is uptodate\n", fname);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
79
rsync.h
79
rsync.h
@@ -1,23 +1,23 @@
|
||||
/*
|
||||
Copyright (C) by Andrew Tridgell 1996, 2000
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
* Copyright (C) 1996, 2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define False 0
|
||||
#define True 1
|
||||
@@ -64,6 +64,7 @@
|
||||
#define FLAG_DEL_HERE (1<<3) /* receiver/generator */
|
||||
#define FLAG_HLINK_TOL (1<<4) /* receiver/generator */
|
||||
#define FLAG_NO_FUZZY (1<<5) /* generator */
|
||||
#define FLAG_MISSING (1<<6) /* generator */
|
||||
|
||||
/* update this if you make incompatible changes */
|
||||
#define PROTOCOL_VERSION 29
|
||||
@@ -135,13 +136,15 @@
|
||||
#define FNAMECMP_FUZZY 0x83
|
||||
|
||||
/* For use by the itemize_changes code */
|
||||
#define ITEM_REPORT_ATIME (1<<0)
|
||||
#define ITEM_REPORT_CHECKSUM (1<<1)
|
||||
#define ITEM_REPORT_SIZE (1<<2)
|
||||
#define ITEM_REPORT_TIME (1<<3)
|
||||
#define ITEM_REPORT_PERMS (1<<4)
|
||||
#define ITEM_REPORT_OWNER (1<<5)
|
||||
#define ITEM_REPORT_GROUP (1<<6)
|
||||
#define ITEM_REPORT_XATTRS (1<<7)
|
||||
#define ITEM_REPORT_ACL (1<<7)
|
||||
#define ITEM_REPORT_XATTR (1<<8)
|
||||
#define ITEM_BASIS_TYPE_FOLLOWS (1<<11)
|
||||
#define ITEM_XNAME_FOLLOWS (1<<12)
|
||||
#define ITEM_IS_NEW (1<<13)
|
||||
@@ -155,10 +158,10 @@
|
||||
ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE))
|
||||
|
||||
|
||||
/* Log-message categories. Only FERROR and FINFO get sent over the socket.
|
||||
* FLOG and FCLIENT are only used on the daemon side for custom logging,
|
||||
* while FNAME is only used on the client side. */
|
||||
enum logcode { FERROR=1, FINFO=2, FLOG=3, FCLIENT=4, FNAME=5, FSOCKERR=6 };
|
||||
/* Log-message categories. Only FERROR and FINFO get sent over the socket,
|
||||
* but FLOG and FSOCKERR can be sent over the receiver -> generator pipe.
|
||||
* FLOG only goes to the log file, not the client; FCLIENT is the opposite. */
|
||||
enum logcode { FNONE=0, FERROR=1, FINFO=2, FLOG=3, FCLIENT=4, FSOCKERR=5 };
|
||||
|
||||
/* Messages types that are sent over the message channel. The logcode
|
||||
* values must all be present here with identical numbers. */
|
||||
@@ -311,6 +314,12 @@ enum msgcode {
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#ifdef MAKEDEV_TAKES_3_ARGS
|
||||
#define MAKEDEV(devmajor,devminor) makedev(0,devmajor,devminor)
|
||||
#else
|
||||
#define MAKEDEV(devmajor,devminor) makedev(devmajor,devminor)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COMPAT_H
|
||||
#include <compat.h>
|
||||
#endif
|
||||
@@ -380,10 +389,7 @@ enum msgcode {
|
||||
* to ensure that any code that really requires a 64-bit integer has
|
||||
* it (e.g. the checksum code uses two 32-bit integers for its 64-bit
|
||||
* counter). */
|
||||
#if SIZEOF_OFF64_T == 8
|
||||
# define int64 off64_t
|
||||
# define SIZEOF_INT64 8
|
||||
#elif SIZEOF_LONG == 8
|
||||
#if SIZEOF_LONG == 8
|
||||
# define int64 long
|
||||
# define SIZEOF_INT64 8
|
||||
#elif SIZEOF_INT == 8
|
||||
@@ -392,6 +398,9 @@ enum msgcode {
|
||||
#elif SIZEOF_LONG_LONG == 8
|
||||
# define int64 long long
|
||||
# define SIZEOF_INT64 8
|
||||
#elif SIZEOF_OFF64_T == 8
|
||||
# define int64 off64_t
|
||||
# define SIZEOF_INT64 8
|
||||
#elif SIZEOF_OFF_T == 8
|
||||
# define int64 off_t
|
||||
# define SIZEOF_INT64 8
|
||||
@@ -489,8 +498,9 @@ struct idev {
|
||||
#define HL_SKIP 1
|
||||
|
||||
struct hlink {
|
||||
int next;
|
||||
int hlindex;
|
||||
int32 next;
|
||||
int32 hlindex;
|
||||
unsigned short link_dest_used;
|
||||
};
|
||||
|
||||
#define F_DEV link_u.idev->dev
|
||||
@@ -560,6 +570,7 @@ struct sum_buf {
|
||||
OFF_T offset; /**< offset in file of this chunk */
|
||||
int32 len; /**< length of chunk of file */
|
||||
uint32 sum1; /**< simple checksum */
|
||||
int32 chain; /**< next hash-table collision */
|
||||
short flags; /**< flag bits */
|
||||
char sum2[SUM_LENGTH]; /**< checksum */
|
||||
};
|
||||
@@ -656,6 +667,7 @@ struct chmod_mode_struct;
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) x __attribute__((__unused__))
|
||||
#define NORETURN __attribute__((__noreturn__))
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
@@ -829,10 +841,6 @@ void rsyserr(enum logcode, int, const char *, ...)
|
||||
__attribute__((format (printf, 3, 4)))
|
||||
;
|
||||
|
||||
#ifdef REPLACE_INET_NTOA
|
||||
#define inet_ntoa rep_inet_ntoa
|
||||
#endif
|
||||
|
||||
/* Make sure that the O_BINARY flag is defined. */
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
@@ -849,6 +857,9 @@ size_t strlcat(char *d, const char *s, size_t bufsize);
|
||||
#ifndef WEXITSTATUS
|
||||
#define WEXITSTATUS(stat) ((int)(((stat)>>8)&0xFF))
|
||||
#endif
|
||||
#ifndef WIFEXITED
|
||||
#define WIFEXITED(stat) ((int)((stat)&0xFF) == 0)
|
||||
#endif
|
||||
|
||||
#define exit_cleanup(code) _exit_cleanup(code, __FILE__, __LINE__)
|
||||
|
||||
|
||||
470
rsync.yo
470
rsync.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsync)(1)(8 Feb 2006)()()
|
||||
manpage(rsync)(1)(6 Nov 2006)()()
|
||||
manpagename(rsync)(faster, flexible replacement for rcp)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -11,6 +11,8 @@ rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
|
||||
|
||||
rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST
|
||||
|
||||
rsync [OPTION]... SRC
|
||||
|
||||
rsync [OPTION]... [USER@]HOST:SRC [DEST]
|
||||
|
||||
rsync [OPTION]... [USER@]HOST::SRC [DEST]
|
||||
@@ -31,7 +33,7 @@ report that accompanies this package.
|
||||
|
||||
Some of the additional features of rsync are:
|
||||
|
||||
itemize(
|
||||
itemization(
|
||||
it() support for copying links, devices, owners, groups, and permissions
|
||||
it() exclude and exclude-from options similar to GNU tar
|
||||
it() a CVS exclude mode for ignoring the same files that CVS would ignore
|
||||
@@ -57,8 +59,8 @@ host specification, OR when an rsync:// URL is specified (see also the
|
||||
"USING RSYNC-DAEMON FEATURES VIA A REMOTE-SHELL CONNECTION" section for
|
||||
an exception to this latter rule).
|
||||
|
||||
As a special case, if a remote source is specified without a destination,
|
||||
the remote files are listed in an output format similar to "ls -l".
|
||||
As a special case, if a single source arg is specified without a
|
||||
destination, the files are listed in an output format similar to "ls -l".
|
||||
|
||||
As expected, if neither the source or destination path specify a remote
|
||||
host, the copy occurs locally (see also the bf(--list-only) option).
|
||||
@@ -180,7 +182,7 @@ CONNECTIONS section below for information on that.)
|
||||
Using rsync in this way is the same as using it with a remote shell except
|
||||
that:
|
||||
|
||||
itemize(
|
||||
itemization(
|
||||
it() you either use a double colon :: instead of a single colon to
|
||||
separate the hostname from the path, or you use an rsync:// URL.
|
||||
it() the first word of the "path" is actually a module name.
|
||||
@@ -238,7 +240,8 @@ verb( rsync -av --rsh=ssh host::module /dest)
|
||||
If you need to specify a different remote-shell user, keep in mind that the
|
||||
user@ prefix in front of the host is specifying the rsync-user value (for a
|
||||
module that requires user-based authentication). This means that you must
|
||||
give the '-l user' option to ssh when specifying the remote-shell:
|
||||
give the '-l user' option to ssh when specifying the remote-shell, as in
|
||||
this example that uses the short version of the bf(--rsh) option:
|
||||
|
||||
verb( rsync -av -e "ssh -l ssh-user" rsync-user@host::module /dest)
|
||||
|
||||
@@ -251,7 +254,7 @@ In order to connect to an rsync daemon, the remote system needs to have a
|
||||
daemon already running (or it needs to have configured something like inetd
|
||||
to spawn an rsync daemon for incoming connections on a particular port).
|
||||
For full information on how to start a daemon that will handling incoming
|
||||
socket connections, see the rsyncd.conf(5) man page -- that is the config
|
||||
socket connections, see the bf(rsyncd.conf)(5) man page -- that is the config
|
||||
file for the daemon, and it contains the full details for how to run the
|
||||
daemon (including stand-alone and inetd configurations).
|
||||
|
||||
@@ -296,6 +299,7 @@ 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
|
||||
-q, --quiet suppress non-error messages
|
||||
--no-motd suppress daemon-mode MOTD (see caveat)
|
||||
-c, --checksum skip based on checksum, not mod-time & size
|
||||
-a, --archive archive mode; same as -rlptgoD (no -H)
|
||||
--no-OPTION turn off an implied OPTION (e.g. --no-D)
|
||||
@@ -313,11 +317,12 @@ 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
|
||||
-H, --hard-links preserve hard links
|
||||
-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
|
||||
-p, --perms preserve permissions
|
||||
-E, --executability preserve executability
|
||||
--chmod=CHMOD change destination permissions
|
||||
--chmod=CHMOD affect file and/or directory permissions
|
||||
-o, --owner preserve owner (super-user only)
|
||||
-g, --group preserve group
|
||||
--devices preserve device files (super-user only)
|
||||
@@ -333,15 +338,15 @@ to the detailed description below for a complete description. verb(
|
||||
-B, --block-size=SIZE force a fixed checksum block-size
|
||||
-e, --rsh=COMMAND specify the remote shell to use
|
||||
--rsync-path=PROGRAM specify the rsync to run on remote machine
|
||||
--existing ignore non-existing files on receiving side
|
||||
--ignore-existing ignore files that already exist on receiver
|
||||
--remove-sent-files sent files/symlinks are removed from sender
|
||||
--existing skip creating new files on receiver
|
||||
--ignore-existing skip updating files that exist on receiver
|
||||
--remove-source-files sender removes synchronized files (non-dir)
|
||||
--del an alias for --delete-during
|
||||
--delete delete files that don't exist on sender
|
||||
--delete delete extraneous files from dest dirs
|
||||
--delete-before receiver deletes before transfer (default)
|
||||
--delete-during receiver deletes during xfer, not before
|
||||
--delete-after receiver deletes after transfer, not before
|
||||
--delete-excluded also delete excluded files on receiver
|
||||
--delete-excluded also delete excluded files from dest dirs
|
||||
--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
|
||||
@@ -383,7 +388,9 @@ to the detailed description below for a complete description. verb(
|
||||
--progress show progress during transfer
|
||||
-P same as --partial --progress
|
||||
-i, --itemize-changes output a change-summary for all updates
|
||||
--log-format=FORMAT output filenames using the specified format
|
||||
--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 password from FILE
|
||||
--list-only list the files instead of copying them
|
||||
--bwlimit=KBPS limit I/O bandwidth; KBytes per second
|
||||
@@ -395,7 +402,7 @@ to the detailed description below for a complete description. verb(
|
||||
-4, --ipv4 prefer IPv4
|
||||
-6, --ipv6 prefer IPv6
|
||||
--version print version number
|
||||
--help show this help screen)
|
||||
(-h) --help show this help (see below for -h comment))
|
||||
|
||||
Rsync can also be run as a daemon, in which case the following options are
|
||||
accepted: verb(
|
||||
@@ -405,11 +412,13 @@ accepted: verb(
|
||||
--config=FILE specify alternate rsyncd.conf file
|
||||
--no-detach do not detach from the parent
|
||||
--port=PORT listen on alternate port number
|
||||
--log-file=FILE override the "log file" setting
|
||||
--log-file-format=FMT override the "log format" setting
|
||||
--sockopts=OPTIONS specify custom TCP options
|
||||
-v, --verbose increase verbosity
|
||||
-4, --ipv4 prefer IPv4
|
||||
-6, --ipv6 prefer IPv6
|
||||
--help show this help screen)
|
||||
-h, --help show this help (if used after --daemon))
|
||||
|
||||
manpageoptions()
|
||||
|
||||
@@ -422,8 +431,8 @@ can be used instead.
|
||||
startdit()
|
||||
dit(bf(--help)) Print a short help page describing the options
|
||||
available in rsync and exit. For backward-compatibility with older
|
||||
versions of rsync, the same help output can also be requested by using
|
||||
the bf(-h) option without any other args.
|
||||
versions of rsync, the help will also be output if you use the bf(-h)
|
||||
option without any other args.
|
||||
|
||||
dit(bf(--version)) print the rsync version number and exit.
|
||||
|
||||
@@ -436,22 +445,30 @@ information at the end. More than two bf(-v) flags should only be used if
|
||||
you are debugging rsync.
|
||||
|
||||
Note that the names of the transferred files that are output are done using
|
||||
a default bf(--log-format) of "%n%L", which tells you just the name of the
|
||||
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(--log-format) setting), the
|
||||
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(--log-format) option for more details.
|
||||
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
|
||||
from the remote server. This flag is useful when invoking rsync from
|
||||
cron.
|
||||
|
||||
dit(bf(--no-motd)) This option affects the information that is output
|
||||
by the client at the start of a daemon transfer. This suppresses the
|
||||
message-of-the-day (MOTD) text, but it also affects the list of modules
|
||||
that the daemon sends in response to the "rsync host::" request (due to
|
||||
a limitation in the rsync protocol), so omit this option if you want to
|
||||
request the list of modules from the deamon.
|
||||
|
||||
dit(bf(-I, --ignore-times)) Normally rsync will skip any files that are
|
||||
already the same size and have the same modification time-stamp.
|
||||
This option turns off this "quick check" behavior.
|
||||
This option turns off this "quick check" behavior, causing all files to
|
||||
be updated.
|
||||
|
||||
dit(bf(--size-only)) Normally rsync will not transfer any files that are
|
||||
already the same size and have the same modification time-stamp. With the
|
||||
@@ -468,11 +485,21 @@ transferring to or from an MS Windows FAT filesystem (which represents
|
||||
times with a 2-second resolution), bf(--modify-window=1) is useful
|
||||
(allowing times to differ by up to 1 second).
|
||||
|
||||
dit(bf(-c, --checksum)) This forces the sender to checksum all files using
|
||||
a 128-bit MD4 checksum before transfer. The checksum is then
|
||||
explicitly checked on the receiver and any files of the same name
|
||||
which already exist and have the same checksum and size on the
|
||||
receiver are not transferred. This option can be quite slow.
|
||||
dit(bf(-c, --checksum)) This forces the sender to checksum em(every)
|
||||
regular file using a 128-bit MD4 checksum. It does this during the initial
|
||||
file-system scan as it builds the list of all available files. The receiver
|
||||
then checksums its version of each file (if it exists and it has the same
|
||||
size as its sender-side counterpart) in order to decide which files need to
|
||||
be updated: files with either a changed size or a changed checksum are
|
||||
selected for transfer. Since this whole-file checksumming of all files on
|
||||
both sides of the connection occurs in addition to the automatic checksum
|
||||
verifications that occur during a file's transfer, this option can be quite
|
||||
slow.
|
||||
|
||||
Note that rsync always verifies that each em(transferred) file was correctly
|
||||
reconstructed on the receiving side by checking its whole-file checksum, but
|
||||
that automatic after-the-transfer verification has nothing to do with this
|
||||
option's before-the-transfer "Does this file need to be updated?" check.
|
||||
|
||||
dit(bf(-a, --archive)) This is equivalent to bf(-rlptgoD). It is a quick
|
||||
way of saying you want recursion and want to preserve almost
|
||||
@@ -514,21 +541,21 @@ example, if you used this command:
|
||||
|
||||
quote(tt( rsync -av /foo/bar/baz.c remote:/tmp/))
|
||||
|
||||
... this would create a file called baz.c in /tmp/ on the remote
|
||||
... this would create a file named baz.c in /tmp/ on the remote
|
||||
machine. If instead you used
|
||||
|
||||
quote(tt( rsync -avR /foo/bar/baz.c remote:/tmp/))
|
||||
|
||||
then a file called /tmp/foo/bar/baz.c would be created on the remote
|
||||
then a file named /tmp/foo/bar/baz.c would be created on the remote
|
||||
machine -- the full path name is preserved. To limit the amount of
|
||||
path information that is sent, you have a couple options: (1) With
|
||||
a modern rsync on the sending side (beginning with 2.6.7), you can
|
||||
insert a dot dir into the source path, like this:
|
||||
insert a dot and a slash into the source path, like this:
|
||||
|
||||
quote(tt( rsync -avR /foo/./bar/baz.c remote:/tmp/))
|
||||
|
||||
That would create /tmp/bar/baz.c on the remote machine. (Note that the
|
||||
dot dir must followed by a slash, so "/foo/." would not be abbreviated.)
|
||||
dot must be followed by a slash, so "/foo/." would not be abbreviated.)
|
||||
(2) For older rsync versions, you would need to use a chdir to limit the
|
||||
source path. For example, when pushing files:
|
||||
|
||||
@@ -544,16 +571,35 @@ tt( rsync -avR --rsync-path="cd /foo; rsync" \ )nl()
|
||||
tt( remote:bar/baz.c /tmp/)
|
||||
)
|
||||
|
||||
dit(bf(--no-implied-dirs)) When combined with the bf(--relative) option, the
|
||||
implied directories in each path are not explicitly duplicated as part
|
||||
of the transfer. This makes the transfer more optimal and also allows
|
||||
the two sides to have non-matching symlinks in the implied part of the
|
||||
path. For instance, if you transfer the file "/path/foo/file" with bf(-R),
|
||||
the default is for rsync to ensure that "/path" and "/path/foo" on the
|
||||
destination exactly match the directories/symlinks of the source. Using
|
||||
the bf(--no-implied-dirs) option would omit both of these implied dirs,
|
||||
which means that if "/path" was a real directory on one machine and a
|
||||
symlink of the other machine, rsync would not try to change this.
|
||||
dit(bf(--no-implied-dirs)) This option affects the default behavior of the
|
||||
bf(--relative) option. When it is specified, the attributes of the implied
|
||||
directories from the source names are not included in the transfer. This
|
||||
means that the corresponding path elements on the destination system are
|
||||
left unchanged if they exist, and any missing implied directories are
|
||||
created with default attributes. This even allows these implied path
|
||||
elements to have big differences, such as being a symlink to a directory on
|
||||
one side of the transfer, and a real directory on the other side.
|
||||
|
||||
For instance, if a command-line arg or a files-from entry told rsync to
|
||||
transfer the file "path/foo/file", the directories "path" and "path/foo"
|
||||
are implied when bf(--relative) is used. If "path/foo" is a symlink to
|
||||
"bar" on the destination system, the receiving rsync would ordinarily
|
||||
delete "path/foo", recreate it as a directory, and receive the file into
|
||||
the new directory. With bf(--no-implied-dirs), the receiving rsync updates
|
||||
"path/foo/file" using the existing path elements, which means that the file
|
||||
ends up being created in "path/bar". Another way to accomplish this link
|
||||
preservation is to use the bf(--keep-dirlinks) option (which will also
|
||||
affect symlinks to directories in the rest of the transfer).
|
||||
|
||||
In a similar but opposite scenario, if the transfer of "path/foo/file" is
|
||||
requested and "path/foo" is a symlink on the sending side, running without
|
||||
bf(--no-implied-dirs) would cause rsync to transform "path/foo" on the
|
||||
receiving side into an identical symlink, and then attempt to transfer
|
||||
"path/foo/file", which might fail if the duplicated symlink did not point
|
||||
to a directory on the receiving side. Another way to avoid this sending of
|
||||
a symlink as an implied directory is to use bf(--copy-unsafe-links), or
|
||||
bf(--copy-dirlinks) (both of which also affect symlinks in the rest of the
|
||||
transfer -- see their descriptions for full details).
|
||||
|
||||
dit(bf(-b, --backup)) With this option, preexisting destination files are
|
||||
renamed as each file is transferred or deleted. You can control where the
|
||||
@@ -572,8 +618,8 @@ your rules specify a trailing inclusion/exclusion of '*', the auto-added
|
||||
rule would never be reached).
|
||||
|
||||
dit(bf(--backup-dir=DIR)) In combination with the bf(--backup) option, this
|
||||
tells rsync to store all backups in the specified directory. This is
|
||||
very useful for incremental backups. You can additionally
|
||||
tells rsync to store all backups in the specified directory on the receiving
|
||||
side. This can be used for incremental backups. You can additionally
|
||||
specify a backup suffix using the bf(--suffix) option
|
||||
(otherwise the files backed up in the specified directory
|
||||
will keep their original filenames).
|
||||
@@ -640,7 +686,7 @@ bf(--dirs) and bf(--recursive), bf(--recursive) takes precedence.
|
||||
dit(bf(-l, --links)) When symlinks are encountered, recreate the
|
||||
symlink on the destination.
|
||||
|
||||
dit(bf(-L, --copy-links)) When symlinks are encountered, the file that
|
||||
dit(bf(-L, --copy-links)) When symlinks are encountered, the item that
|
||||
they point to (the referent) is copied, rather than the symlink. In older
|
||||
versions of rsync, this option also had the side-effect of telling the
|
||||
receiving side to follow symlinks, such as symlinks to directories. In a
|
||||
@@ -652,33 +698,49 @@ will still have the side-effect of bf(-K) on that older receiving rsync.
|
||||
dit(bf(--copy-unsafe-links)) This tells rsync to copy the referent of
|
||||
symbolic links that point outside the copied tree. Absolute symlinks
|
||||
are also treated like ordinary files, and so are any symlinks in the
|
||||
source path itself when bf(--relative) is used.
|
||||
source path itself when bf(--relative) is used. This option has no
|
||||
additional effect if bf(--copy-links) was also specified.
|
||||
|
||||
dit(bf(--safe-links)) This tells rsync to ignore any symbolic links
|
||||
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(-H, --hard-links)) This tells rsync to recreate hard links on
|
||||
the remote system to be the same as the local system. Without this
|
||||
option hard links are treated like regular files.
|
||||
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
|
||||
they would be using bf(--copy-links).
|
||||
|
||||
Without this option, if the sending side has replaced a directory with a
|
||||
symlink to a directory, the receiving side will delete anything that is in
|
||||
the way of the new symlink, including a directory hierarchy (as long as
|
||||
bf(--force) or bf(--delete) is in effect).
|
||||
|
||||
See also bf(--keep-dirlinks) for an analogous option for the receiving
|
||||
side.
|
||||
|
||||
dit(bf(-K, --keep-dirlinks)) This option causes the receiving side to treat
|
||||
a symlink to a directory as though it were a real directory, but only if it
|
||||
matches a real directory from the sender. Without this option, the
|
||||
receiver's symlink would be deleted and replaced with a real directory.
|
||||
|
||||
For example, suppose you transfer a directory "foo" that contains a file
|
||||
"file", but "foo" is a symlink to directory "bar" on the receiver. Without
|
||||
bf(--keep-dirlinks), the receiver deletes symlink "foo", recreates it as a
|
||||
directory, and receives the file into the new directory. With
|
||||
bf(--keep-dirlinks), the receiver keeps the symlink and "file" ends up in
|
||||
"bar".
|
||||
|
||||
See also bf(--copy-dirlinks) for an analogous option for the sending side.
|
||||
|
||||
dit(bf(-H, --hard-links)) This tells rsync to look for hard-linked files in
|
||||
the transfer and link together the corresponding files on the receiving
|
||||
side. Without this option, hard-linked files in the transfer are treated
|
||||
as though they were separate files.
|
||||
|
||||
Note that rsync can only detect hard links if both parts of the link
|
||||
are in the list of files being sent.
|
||||
|
||||
This option can be quite slow, so only use it if you need it.
|
||||
|
||||
dit(bf(-K, --keep-dirlinks)) On the receiving side, if a symlink is
|
||||
pointing to a directory, it will be treated as matching a directory
|
||||
from the sender.
|
||||
|
||||
dit(bf(-W, --whole-file)) With this option the incremental rsync algorithm
|
||||
is not used and the whole file is sent as-is instead. The transfer may be
|
||||
faster if this option is used when the bandwidth between the source and
|
||||
destination machines is higher than the bandwidth to disk (especially when the
|
||||
"disk" is actually a networked filesystem). This is the default when both
|
||||
the source and destination are specified as local paths.
|
||||
|
||||
dit(bf(-p, --perms)) This option causes the receiving rsync to set the
|
||||
destination permissions to be the same as the source permissions. (See
|
||||
also the bf(--chmod) option for a way to modify what rsync considers to
|
||||
@@ -686,7 +748,7 @@ be the source permissions.)
|
||||
|
||||
When this option is em(off), permissions are set as follows:
|
||||
|
||||
quote(itemize(
|
||||
quote(itemization(
|
||||
it() Existing files (including updated files) retain their existing
|
||||
permissions, though the bf(--executability) option might change just
|
||||
the execute permission for the file.
|
||||
@@ -733,7 +795,7 @@ not enabled. A regular file is considered to be executable if at least one
|
||||
executability differs from that of the corresponding source file, rsync
|
||||
modifies the destination file's permissions as follows:
|
||||
|
||||
quote(itemize(
|
||||
quote(itemization(
|
||||
it() To make a file non-executable, rsync turns off all its 'x'
|
||||
permissions.
|
||||
it() To make a file executable, rsync turns on each 'x' permission that
|
||||
@@ -762,20 +824,27 @@ See the bf(--perms) and bf(--executability) options for how the resulting
|
||||
permission value can be applied to the files in the transfer.
|
||||
|
||||
dit(bf(-o, --owner)) This option causes rsync to set the owner of the
|
||||
destination file to be the same as the source file. By default, the
|
||||
preservation is done by name, but may fall back to using the ID number
|
||||
in some circumstances (see the bf(--numeric-ids) option for a full
|
||||
discussion).
|
||||
This option has no effect if the receiving rsync is not run as the
|
||||
super-user and bf(--super) is not specified.
|
||||
destination file to be the same as the source file, but only if the
|
||||
receiving rsync is being run as the super-user (see also the bf(--super)
|
||||
option to force rsync to attempt super-user activities).
|
||||
Without this option, the owner is set to the invoking user on the
|
||||
receiving side.
|
||||
|
||||
The preservation of ownership will associate matching names by default, but
|
||||
may fall back to using the ID number in some circumstances (see also the
|
||||
bf(--numeric-ids) option for a full discussion).
|
||||
|
||||
dit(bf(-g, --group)) This option causes rsync to set the group of the
|
||||
destination file to be the same as the source file. If the receiving
|
||||
program is not running as the super-user (or with the bf(--no-super)
|
||||
option), only groups that the
|
||||
receiver is a member of will be preserved. By default, the preservation
|
||||
is done by name, but may fall back to using the ID number in some
|
||||
circumstances. See the bf(--numeric-ids) option for a full discussion.
|
||||
program is not running as the super-user (or if bf(--no-super) was
|
||||
specified), only groups that the invoking user on the receiving side
|
||||
is a member of will be preserved.
|
||||
Without this option, the group is set to the default group of the invoking
|
||||
user on the receiving side.
|
||||
|
||||
The preservation of group information will associate matching names by
|
||||
default, but may fall back to using the ID number in some circumstances
|
||||
(see also the bf(--numeric-ids) option for a full discussion).
|
||||
|
||||
dit(bf(--devices)) This option causes rsync to transfer character and
|
||||
block device files to the remote system to recreate these devices.
|
||||
@@ -810,9 +879,6 @@ also for ensuring that you will get errors if the receiving side isn't
|
||||
being running as the super-user. To turn off super-user activities, the
|
||||
super-user can use bf(--no-super).
|
||||
|
||||
dit(bf(-n, --dry-run)) This tells rsync to not do any file transfers,
|
||||
instead it will just report the actions it would have taken.
|
||||
|
||||
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.
|
||||
@@ -821,6 +887,16 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs"
|
||||
filesystem. It doesn't seem to handle seeks over null regions
|
||||
correctly and ends up corrupting the files.
|
||||
|
||||
dit(bf(-n, --dry-run)) This tells rsync to not do any file transfers,
|
||||
instead it will just report the actions it would have taken.
|
||||
|
||||
dit(bf(-W, --whole-file)) With this option the incremental rsync algorithm
|
||||
is not used and the whole file is sent as-is instead. The transfer may be
|
||||
faster if this option is used when the bandwidth between the source and
|
||||
destination machines is higher than the bandwidth to disk (especially when the
|
||||
"disk" is actually a networked filesystem). This is the default when both
|
||||
the source and destination are specified as local paths.
|
||||
|
||||
dit(bf(-x, --one-file-system)) This tells rsync to avoid crossing a
|
||||
filesystem boundary when recursing. This does not limit the user's ability
|
||||
to specify items to copy from multiple filesystems, just rsync's recursion
|
||||
@@ -840,17 +916,18 @@ treated like a mount-point. Symlinks to non-directories are unaffected
|
||||
by this option.
|
||||
|
||||
dit(bf(--existing, --ignore-non-existing)) This tells rsync to skip
|
||||
updating files that do not exist yet on the destination. If this option is
|
||||
creating files (including directories) that do not exist
|
||||
yet on the destination. If this option is
|
||||
combined with the bf(--ignore-existing) option, no files will be updated
|
||||
(which can be useful if all you want to do is to delete missing files).
|
||||
(which can be useful if all you want to do is to delete extraneous files).
|
||||
|
||||
dit(bf(--ignore-existing)) This tells rsync to skip updating files that
|
||||
already exist on the destination. See also bf(--ignore-non-existing).
|
||||
already exist on the destination (this does em(not) ignore existing
|
||||
directores, or nothing would get done). See also bf(--existing).
|
||||
|
||||
dit(bf(--remove-sent-files)) This tells rsync to remove from the sending
|
||||
side the files and/or symlinks that are newly created or whose content is
|
||||
updated on the receiving side. Directories and devices are not removed,
|
||||
nor are files/symlinks whose attributes are merely changed.
|
||||
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.
|
||||
|
||||
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
|
||||
@@ -1020,7 +1097,7 @@ are delimited by whitespace).
|
||||
Finally, any file is ignored if it is in the same directory as a
|
||||
.cvsignore file and matches one of the patterns listed therein. Unlike
|
||||
rsync's filter/exclude files, these patterns are split on whitespace.
|
||||
See the bf(cvs(1)) manual for more information.
|
||||
See the bf(cvs)(1) manual for more information.
|
||||
|
||||
If you're combining bf(-C) with your own bf(--filter) rules, you should
|
||||
note that these CVS excludes are appended at the end of your own rules,
|
||||
@@ -1087,7 +1164,7 @@ exact list of files to transfer (as read from the specified FILE or bf(-)
|
||||
for standard input). It also tweaks the default behavior of rsync to make
|
||||
transferring just the specified files and directories easier:
|
||||
|
||||
quote(itemize(
|
||||
quote(itemization(
|
||||
it() The bf(--relative) (bf(-R)) option is implied, which preserves the path
|
||||
information that is specified for each item in the file (use
|
||||
bf(--no-relative) or bf(--no-R) if you want to turn that off).
|
||||
@@ -1232,6 +1309,11 @@ and the attributes updated.
|
||||
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.
|
||||
|
||||
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
|
||||
substitute for transferring the file, never as an additional check after the
|
||||
file is updated.
|
||||
|
||||
If em(DIR) is a relative path, it is relative to the destination directory.
|
||||
See also bf(--compare-dest) and bf(--copy-dest).
|
||||
|
||||
@@ -1244,7 +1326,7 @@ dit(bf(-z, --compress)) With this option, rsync compresses the file data
|
||||
as it is sent to the destination machine, which reduces the amount of data
|
||||
being transmitted -- something that is useful over a slow connection.
|
||||
|
||||
Note this this option typically achieves better compression ratios that can
|
||||
Note that this option typically achieves better compression ratios than can
|
||||
be achieved by using a compressing remote shell or a compressing transport
|
||||
because it takes advantage of the implicit information in the matching data
|
||||
blocks that are not explicitly sent over the connection.
|
||||
@@ -1287,7 +1369,7 @@ option in the bf(--daemon) mode section.
|
||||
dit(bf(--sockopts)) This option can provide endless fun for people
|
||||
who like to tune their systems to the utmost degree. You can set all
|
||||
sorts of socket options which may make transfers faster (or
|
||||
slower!). Read the man page for the setsockopt() system call for
|
||||
slower!). Read the man page for the code(setsockopt()) system call for
|
||||
details on some of the options you may be able to set. By default no
|
||||
special socket options are set. This only affects direct socket
|
||||
connections to a remote rsync daemon. This option also exists in the
|
||||
@@ -1301,7 +1383,7 @@ ssh prefers non-blocking I/O.)
|
||||
|
||||
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(--log-format='%i %n%L').
|
||||
This is exactly the same as specifying bf(--out-format='%i %n%L').
|
||||
If you repeat the option, unchanged files will also be output, but only
|
||||
if the receiving rsync is at least version 2.6.7 (you can use bf(-vv)
|
||||
with older versions of rsync, but that also turns on the output of other
|
||||
@@ -1315,14 +1397,14 @@ modified.
|
||||
|
||||
The update types that replace the bf(Y) are as follows:
|
||||
|
||||
quote(itemize(
|
||||
quote(itemization(
|
||||
it() A bf(<) means that a file is being transferred to the remote host
|
||||
(sent).
|
||||
it() A bf(>) means that a file is being transferred to the local host
|
||||
(received).
|
||||
it() A bf(c) means that a local change/creation is occurring for the item
|
||||
(such as the creation of a directory or the changing of a symlink, etc.).
|
||||
it() A bf(h) means that the item is a hard-link to another item (requires
|
||||
it() A bf(h) means that the item is a hard link to another item (requires
|
||||
bf(--hard-links)).
|
||||
it() A bf(.) means that the item is not being updated (though it might
|
||||
have attributes that are being modified).
|
||||
@@ -1341,7 +1423,7 @@ a "?" (this can happen when talking to an older rsync).
|
||||
|
||||
The attribute that is associated with each letter is as follows:
|
||||
|
||||
quote(itemize(
|
||||
quote(itemization(
|
||||
it() A bf(c) means the checksum of the file is different and will be
|
||||
updated by the file transfer (requires bf(--checksum)).
|
||||
it() A bf(s) means the size of the file is different and will be updated
|
||||
@@ -1365,36 +1447,89 @@ the string "*deleting" for each item that is being removed (assuming that
|
||||
you are talking to a recent enough rsync that it logs deletions instead of
|
||||
outputting them as a verbose message).
|
||||
|
||||
dit(bf(--log-format=FORMAT)) This allows you to specify exactly what the
|
||||
rsync client outputs to the user on a per-file basis. The format is a text
|
||||
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. For a list of the possible escape characters, see
|
||||
the "log format" setting in the rsyncd.conf manpage. (Note that this
|
||||
option does not affect what a daemon logs to its logfile.)
|
||||
the "log format" setting in the rsyncd.conf manpage.
|
||||
|
||||
Specifying this 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) unless the itemize-changes escape (%i) is included in
|
||||
the string, in which case the logging of names increases to mention any
|
||||
touched directory). In addition, if the itemize-changes escape (%i) is
|
||||
included in the string, the logging of names increases to mention any
|
||||
item that is changed in any way (as long as the receiving side is at least
|
||||
2.6.4). See the bf(--itemize-changes) option for a description of the
|
||||
output of "%i".
|
||||
|
||||
The bf(--verbose) option implies a format of "%n%L", but you can use
|
||||
bf(--log-format) without bf(--verbose) if you like, or you can override
|
||||
bf(--out-format) without bf(--verbose) if you like, or you can override
|
||||
the format of its per-file output using this option.
|
||||
|
||||
Rsync will output the log-format string prior to a file's transfer unless
|
||||
Rsync will output the out-format string prior to a file's transfer unless
|
||||
one of the transfer-statistic escapes is requested, in which case the
|
||||
logging is done at the end of the file's transfer. When this late logging
|
||||
is in effect and bf(--progress) is also specified, rsync will also output
|
||||
the name of the file being transferred prior to its progress information
|
||||
(followed, of course, by the log-format output).
|
||||
(followed, of course, by the out-format output).
|
||||
|
||||
dit(bf(--log-file=FILE)) This option causes rsync to log what it is doing
|
||||
to a file. This is similar to the logging that a daemon does, but can be
|
||||
requested for the client side and/or the server side of a non-daemon
|
||||
transfer. If specified as a client option, transfer logging will be
|
||||
enabled with a default format of "%i %n%L". See the bf(--log-file-format)
|
||||
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 --rsync-path="rsync --log-file=/tmp/rlog" src/ dest/)
|
||||
|
||||
This is very useful if you need to debug why a connection is closing
|
||||
unexpectedly.
|
||||
|
||||
dit(bf(--log-file-format=FORMAT)) This allows you to specify exactly what
|
||||
per-update logging is put into the file specified by the bf(--log-file) option
|
||||
(which must also be specified for this option to have any effect). If you
|
||||
specify an empty string, updated files will not be mentioned in the log file.
|
||||
For a list of the possible escape characters, see the "log format" setting
|
||||
in the rsyncd.conf manpage.
|
||||
|
||||
dit(bf(--stats)) This tells rsync to print a verbose set of statistics
|
||||
on the file transfer, allowing you to tell how effective the rsync
|
||||
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.
|
||||
it() bf(Number of files transferred) is the count of normal files that
|
||||
were updated via the rsync 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.
|
||||
it() bf(Total transferred file size) is the total sum of all files sizes
|
||||
for just the transferred files.
|
||||
it() bf(Literal data) is how much unmatched file-update data we had to
|
||||
send to the receiver for it to recreate the updated files.
|
||||
it() bf(Matched data) is how much data the receiver got locally when
|
||||
recreating the updated files.
|
||||
it() bf(File list size) is how big the file-list data was when the sender
|
||||
sent it to the receiver. This is smaller than the in-memory size for the
|
||||
file list due to some compressing of duplicated data when rsync sends the
|
||||
list.
|
||||
it() bf(File list generation time) is the number of seconds that the
|
||||
sender spent creating the file list. This requires a modern rsync on the
|
||||
sending side for this to be present.
|
||||
it() bf(File list transfer time) is the number of seconds that the sender
|
||||
spent sending the file list to the receiver.
|
||||
it() bf(Total bytes sent) is the count of all the bytes that rsync sent
|
||||
from the client side to the server side.
|
||||
it() bf(Total bytes received) is the count of all non-message bytes that
|
||||
rsync received by the client side from the server side. "Non-message"
|
||||
bytes means that we don't count the bytes for a verbose message that the
|
||||
server sent to us, which makes the stats more consistent.
|
||||
))
|
||||
|
||||
dit(bf(-8, --8-bit-output)) This tells rsync to leave all high-bit characters
|
||||
unescaped in the output instead of trying to test them to see if they're
|
||||
valid in the current locale and escaping the invalid ones. All control
|
||||
@@ -1459,7 +1594,7 @@ is a security risk. E.g. AVOID "/tmp".
|
||||
|
||||
You can also set the partial-dir value the RSYNC_PARTIAL_DIR environment
|
||||
variable. Setting this in the environment does not force bf(--partial) to be
|
||||
enabled, but rather it effects where partial files go when bf(--partial) is
|
||||
enabled, but rather it affects where partial files go when bf(--partial) is
|
||||
specified. For instance, instead of using bf(--partial-dir=.rsync-tmp)
|
||||
along with bf(--progress), you could set RSYNC_PARTIAL_DIR=.rsync-tmp in your
|
||||
environment and then just use the bf(-P) option to turn on the use of the
|
||||
@@ -1525,7 +1660,7 @@ the necessary destination directories to hold the .pdf files, and ensures
|
||||
that any superfluous files and directories in the destination are removed
|
||||
(note the hide filter of non-directories being used instead of an exclude):
|
||||
|
||||
quote( rsync -avm --del --include='*.pdf' -f 'hide! */' src/ dest)
|
||||
quote( rsync -avm --del --include='*.pdf' -f 'hide,! */' src/ dest)
|
||||
|
||||
If you didn't want to remove superfluous destination files, the more
|
||||
time-honored options of "--include='*/' --exclude='*'" would work fine
|
||||
@@ -1536,24 +1671,34 @@ showing the progress of the transfer. This gives a bored user
|
||||
something to watch.
|
||||
Implies bf(--verbose) if it wasn't already specified.
|
||||
|
||||
When the file is transferring, the data looks like this:
|
||||
While rsync is transferring a regular file, it updates a progress line that
|
||||
looks like this:
|
||||
|
||||
verb( 782448 63% 110.64kB/s 0:00:04)
|
||||
|
||||
This tells you the current file size, the percentage of the transfer that
|
||||
is complete, the current calculated file-completion rate (including both
|
||||
data over the wire and data being matched locally), and the estimated time
|
||||
remaining in this transfer.
|
||||
In this example, the receiver has reconstructed 782448 bytes or 63% of the
|
||||
sender's file, which is being reconstructed at a rate of 110.64 kilobytes
|
||||
per second, and the transfer will finish in 4 seconds if the current rate
|
||||
is maintained until the end.
|
||||
|
||||
After a file is complete, the data looks like this:
|
||||
These statistics can be misleading if the incremental transfer algorithm is
|
||||
in use. For example, if the sender's file consists of the basis file
|
||||
followed by additional data, the reported rate will probably drop
|
||||
dramatically when the receiver gets to the literal data, and the transfer
|
||||
will probably take much longer to finish than the receiver estimated as it
|
||||
was finishing the matched part of the file.
|
||||
|
||||
verb( 1238099 100% 146.38kB/s 0:00:08 (5, 57.1% of 396))
|
||||
When the file transfer finishes, rsync replaces the progress line with a
|
||||
summary line that looks like this:
|
||||
|
||||
This tells you the final file size, that it's 100% complete, the final
|
||||
transfer rate for the file, the amount of elapsed time it took to transfer
|
||||
the file, and the addition of a total-transfer summary in parentheses.
|
||||
These additional numbers tell you how many files have been updated, and
|
||||
what percent of the total number of files has been scanned.
|
||||
verb( 1238099 100% 146.38kB/s 0:00:08 (xfer#5, to-check=169/396))
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
@@ -1567,13 +1712,18 @@ must not be world readable. It should contain just the password as a
|
||||
single line.
|
||||
|
||||
dit(bf(--list-only)) This option will cause the source files to be listed
|
||||
instead of transferred. This option is inferred if there is no destination
|
||||
specified, so you don't usually need to use it explicitly. However, it can
|
||||
come in handy for a user that wants to avoid the "bf(-r --exclude='/*/*')"
|
||||
options that rsync might use as a compatibility kluge when generating a
|
||||
non-recursive listing, or to list the files that are involved in a local
|
||||
copy (since the destination path is not optional for a local copy, you
|
||||
must specify this option explicitly and still include a destination).
|
||||
instead of transferred. This option is inferred if there is a single source
|
||||
arg and no destination specified, so its main uses are: (1) to turn a copy
|
||||
command that includes a
|
||||
destination arg into a file-listing command, (2) to be able to specify more
|
||||
than one local source arg (note: be sure to include the destination), or
|
||||
(3) to avoid the automatically added "bf(-r --exclude='/*/*')" options that
|
||||
rsync usually uses as a compatibility kluge when generating a non-recursive
|
||||
listing. Caution: keep in mind that a source arg with a wild-card is expanded
|
||||
by the shell into multiple args, so it is never safe to try to list such an arg
|
||||
without using this option. For example:
|
||||
|
||||
verb( rsync -av --list-only foo* dest/)
|
||||
|
||||
dit(bf(--bwlimit=KBPS)) This option allows you to specify a maximum
|
||||
transfer rate in kilobytes per second. This option is most effective when
|
||||
@@ -1625,11 +1775,11 @@ rsync daemon. See also these options in the bf(--daemon) mode section.
|
||||
dit(bf(--checksum-seed=NUM)) Set the MD4 checksum seed to the integer
|
||||
NUM. This 4 byte checksum seed is included in each block and file
|
||||
MD4 checksum calculation. By default the checksum seed is generated
|
||||
by the server and defaults to the current time(). This option
|
||||
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.
|
||||
Note that setting NUM to 0 causes rsync to use the default of time()
|
||||
Note that setting NUM to 0 causes rsync to use the default of code(time())
|
||||
for checksum seed.
|
||||
enddit()
|
||||
|
||||
@@ -1646,7 +1796,7 @@ If standard input is a socket then rsync will assume that it is being
|
||||
run via inetd, otherwise it will detach from the current terminal and
|
||||
become a background daemon. The daemon will read the config file
|
||||
(rsyncd.conf) on each connect made by a client and respond to
|
||||
requests accordingly. See the rsyncd.conf(5) man page for more
|
||||
requests accordingly. See the bf(rsyncd.conf)(5) man page for more
|
||||
details.
|
||||
|
||||
dit(bf(--address)) By default rsync will bind to the wildcard address when
|
||||
@@ -1680,6 +1830,15 @@ dit(bf(--port=PORT)) This specifies an alternate TCP port number for the
|
||||
daemon to listen on rather than the default of 873. See also the "port"
|
||||
global option in the rsyncd.conf manpage.
|
||||
|
||||
dit(bf(--log-file=FILE)) This option tells the rsync daemon to use the
|
||||
given log-file name instead of using the "log file" setting in the config
|
||||
file.
|
||||
|
||||
dit(bf(--log-file-format=FORMAT)) This option tells the rsync daemon to use the
|
||||
given FORMAT string instead of using the "log format" setting in the config
|
||||
file. It also enables "transfer logging" unless the string is empty, in which
|
||||
case transfer logging is turned off.
|
||||
|
||||
dit(bf(--sockopts)) This overrides the bf(socket options) setting in the
|
||||
rsyncd.conf file and has the same syntax.
|
||||
|
||||
@@ -1766,12 +1925,12 @@ The include/exclude rules each specify a pattern that is matched against
|
||||
the names of the files that are going to be transferred. These patterns
|
||||
can take several forms:
|
||||
|
||||
itemize(
|
||||
itemization(
|
||||
it() if the pattern starts with a / then it is anchored to a
|
||||
particular spot in the hierarchy of files, otherwise it is matched
|
||||
against the end of the pathname. This is similar to a leading ^ in
|
||||
regular expressions.
|
||||
Thus "/foo" would match a file called "foo" at either the "root of the
|
||||
Thus "/foo" would match a file named "foo" at either the "root of the
|
||||
transfer" (for a global rule) or in the merge-file's directory (for a
|
||||
per-directory rule).
|
||||
An unqualified "foo" would match any file or directory named "foo"
|
||||
@@ -1785,7 +1944,6 @@ itemize(
|
||||
of the transfer.
|
||||
it() if the pattern ends with a / then it will only match a
|
||||
directory, not a file, link, or device.
|
||||
|
||||
it() rsync chooses between doing a simple string match and wildcard
|
||||
matching by checking if the pattern contains one of these three wildcard
|
||||
characters: '*', '?', and '[' .
|
||||
@@ -1830,7 +1988,8 @@ This fails because the parent directory "some" is excluded by the '*'
|
||||
rule, so rsync never visits any of the files in the "some" or "some/path"
|
||||
directories. One solution is to ask for all directories in the hierarchy
|
||||
to be included by using a single rule: "+ */" (put it somewhere before the
|
||||
"- *" rule). Another solution is to add specific include rules for all
|
||||
"- *" rule), and perhaps use the bf(--prune-empty-dirs) option. Another
|
||||
solution is to add specific include rules for all
|
||||
the parent dirs that need to be visited. For instance, this set of rules
|
||||
works fine:
|
||||
|
||||
@@ -1844,16 +2003,18 @@ tt(- *)nl()
|
||||
|
||||
Here are some examples of exclude/include matching:
|
||||
|
||||
itemize(
|
||||
itemization(
|
||||
it() "- *.o" would exclude all filenames matching *.o
|
||||
it() "- /foo" would exclude a file called foo in the transfer-root directory
|
||||
it() "- foo/" would exclude any directory called foo
|
||||
it() "- /foo/*/bar" would exclude any file called bar two
|
||||
levels below a directory called foo in the transfer-root directory
|
||||
it() "- /foo/**/bar" would exclude any file called bar two
|
||||
or more levels below a directory called foo in the transfer-root directory
|
||||
it() "- /foo" would exclude a file (or directory) named foo in the
|
||||
transfer-root directory
|
||||
it() "- foo/" would exclude any directory named foo
|
||||
it() "- /foo/*/bar" would exclude any file named bar which is at two
|
||||
levels below a directory named foo in the transfer-root directory
|
||||
it() "- /foo/**/bar" would exclude any file named bar two
|
||||
or more levels below a directory named foo in the transfer-root directory
|
||||
it() The combination of "+ */", "+ *.c", and "- *" would include all
|
||||
directories and C source files but nothing else.
|
||||
directories and C source files but nothing else (see also the
|
||||
bf(--prune-empty-dirs) option)
|
||||
it() The combination of "+ foo/", "+ foo/bar.c", and "- *" would include
|
||||
only the foo directory and foo/bar.c (the foo directory must be
|
||||
explicitly included or it would be excluded by the "*")
|
||||
@@ -1889,7 +2050,7 @@ tt(:n- .non-inherited-per-dir-excludes)nl()
|
||||
|
||||
The following modifiers are accepted after a merge or dir-merge rule:
|
||||
|
||||
itemize(
|
||||
itemization(
|
||||
it() A bf(-) specifies that the file should consist of only exclude
|
||||
patterns, with no other rule-parsing except for in-file comments.
|
||||
it() A bf(+) specifies that the file should consist of only include
|
||||
@@ -1907,7 +2068,7 @@ itemize(
|
||||
"- foo + bar" is parsed as two rules (assuming that prefix-parsing wasn't
|
||||
also disabled).
|
||||
it() You may also specify any of the modifiers for the "+" or "-" rules
|
||||
(below) in order to have the rules that are read-in from the file
|
||||
(below) in order to have the rules that are read in from the file
|
||||
default to having that modifier set. For instance, "merge,-/ .excl" would
|
||||
treat the contents of .excl as absolute-path excludes,
|
||||
while "dir-merge,s .filt" and ":sC" would each make all their
|
||||
@@ -1916,7 +2077,7 @@ itemize(
|
||||
|
||||
The following modifiers are accepted after a "+" or "-":
|
||||
|
||||
itemize(
|
||||
itemization(
|
||||
it() A "/" specifies that the include/exclude rule should be matched
|
||||
against the absolute pathname of the current item. For example,
|
||||
"-/ /etc/passwd" would exclude the passwd file any time the transfer
|
||||
@@ -1970,7 +2131,7 @@ tt(- *.o)nl()
|
||||
|
||||
This will merge the contents of the /home/user/.global-filter file at the
|
||||
start of the list and also turns the ".rules" filename into a per-directory
|
||||
filter file. All rules read-in prior to the start of the directory scan
|
||||
filter file. All rules read in prior to the start of the directory scan
|
||||
follow the global anchoring rules (i.e. a leading slash matches at the root
|
||||
of the transfer).
|
||||
|
||||
@@ -2160,7 +2321,8 @@ For convenience, one additional file is creating when the write-batch
|
||||
option is used. This file's name is created by appending
|
||||
".sh" to the batch filename. The .sh file contains
|
||||
a command-line suitable for updating a destination tree using that
|
||||
batch file. It can be executed using a Bourne(-like) shell, optionally
|
||||
batch file. It can be executed using a Bourne (or Bourne-like) shell,
|
||||
optionally
|
||||
passing in an alternate destination tree pathname which is then used
|
||||
instead of the original path. This is useful when the destination tree
|
||||
path differs from the original destination tree path.
|
||||
@@ -2190,7 +2352,7 @@ and the information to repeat this operation is stored in "foo" and
|
||||
into the directory /bdest/dir. The differences between the two examples
|
||||
reveals some of the flexibility you have in how you deal with batches:
|
||||
|
||||
itemize(
|
||||
itemization(
|
||||
it() The first example shows that the initial copy doesn't have to be
|
||||
local -- you can push or pull data to/from a remote host using either the
|
||||
remote-shell syntax or rsync daemon syntax, as desired.
|
||||
@@ -2288,7 +2450,7 @@ and duplicate all safe symlinks.
|
||||
dit(bf(--copy-unsafe-links)) Turn all unsafe symlinks into files, noisily
|
||||
skip all safe symlinks.
|
||||
|
||||
dit(bf(--links --safe-links)) Duplicate safe symlinks and skip unsafe
|
||||
dit(bf(--links --safe-links)) Duplicate safe symlinks and skip unsafe
|
||||
ones.
|
||||
|
||||
dit(bf(--links)) Duplicate all symlinks.
|
||||
@@ -2337,7 +2499,7 @@ dit(bf(12)) Error in rsync protocol data stream
|
||||
dit(bf(13)) Errors with program diagnostics
|
||||
dit(bf(14)) Error in IPC code
|
||||
dit(bf(20)) Received SIGUSR1 or SIGINT
|
||||
dit(bf(21)) Some error returned by waitpid()
|
||||
dit(bf(21)) Some error returned by code(waitpid())
|
||||
dit(bf(22)) Error allocating core memory buffers
|
||||
dit(bf(23)) Partial transfer due to error
|
||||
dit(bf(24)) Partial transfer due to vanished source files
|
||||
@@ -2374,11 +2536,11 @@ manpagefiles()
|
||||
|
||||
manpageseealso()
|
||||
|
||||
rsyncd.conf(5)
|
||||
bf(rsyncd.conf)(5)
|
||||
|
||||
manpagebugs()
|
||||
|
||||
times are transferred as unix time_t values
|
||||
times are transferred as *nix time_t values
|
||||
|
||||
When transferring to FAT filesystems rsync may re-sync
|
||||
unmodified files.
|
||||
@@ -2394,7 +2556,17 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
|
||||
This man page is current for version 2.6.7pre1 of rsync.
|
||||
This man page is current for version 2.6.9 of rsync.
|
||||
|
||||
manpagesection(INTERNAL OPTIONS)
|
||||
|
||||
The options bf(--server) and bf(--sender) are used internally by rsync,
|
||||
and should never be typed by a user under normal circumstances. Some
|
||||
awareness of these options may be needed in certain scenarios, such as
|
||||
when setting up a login that can only run an rsync command. For instance,
|
||||
the support directory of the rsync distribution has an example script
|
||||
named rrsync (for restricted rsync) that can be used with a restricted
|
||||
ssh login.
|
||||
|
||||
manpagesection(CREDITS)
|
||||
|
||||
|
||||
126
rsyncd.conf.yo
126
rsyncd.conf.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsyncd.conf)(5)(8 Feb 2006)()()
|
||||
manpage(rsyncd.conf)(5)(6 Nov 2006)()()
|
||||
manpagename(rsyncd.conf)(configuration file for rsync in daemon mode)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -8,27 +8,27 @@ rsyncd.conf
|
||||
manpagedescription()
|
||||
|
||||
The rsyncd.conf file is the runtime configuration file for rsync when
|
||||
run as an rsync daemon.
|
||||
run as an rsync daemon.
|
||||
|
||||
The rsyncd.conf file controls authentication, access, logging and
|
||||
available modules.
|
||||
|
||||
manpagesection(FILE FORMAT)
|
||||
|
||||
The file consists of modules and parameters. A module begins with the
|
||||
The file consists of modules and parameters. A module begins with the
|
||||
name of the module in square brackets and continues until the next
|
||||
module begins. Modules contain parameters of the form 'name = value'.
|
||||
|
||||
The file is line-based -- that is, each newline-terminated line represents
|
||||
either a comment, a module name or a parameter.
|
||||
|
||||
Only the first equals sign in a parameter is significant. Whitespace before
|
||||
Only the first equals sign in a parameter is significant. Whitespace before
|
||||
or after the first equals sign is discarded. Leading, trailing and internal
|
||||
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 beginning with a hash (#) is ignored, as are lines containing
|
||||
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
|
||||
@@ -37,12 +37,12 @@ customary UNIX fashion.
|
||||
The values following the equals sign in parameters are all either a string
|
||||
(no quotes needed) or a boolean, which may be given as yes/no, 0/1 or
|
||||
true/false. Case is not significant in boolean values, but is preserved
|
||||
in string values.
|
||||
in string values.
|
||||
|
||||
manpagesection(LAUNCHING THE RSYNC DAEMON)
|
||||
|
||||
The rsync daemon is launched by specifying the bf(--daemon) option to
|
||||
rsync.
|
||||
rsync.
|
||||
|
||||
The daemon must run with root privileges if you wish to use chroot, to
|
||||
bind to a port numbered under 1024 (as is the default 873), or to set
|
||||
@@ -58,7 +58,7 @@ When run via inetd you should add a line like this to /etc/services:
|
||||
verb( rsync 873/tcp)
|
||||
|
||||
and a single line something like this to /etc/inetd.conf:
|
||||
|
||||
|
||||
verb( rsync stream tcp nowait root /usr/bin/rsync rsyncd --daemon)
|
||||
|
||||
Replace "/usr/bin/rsync" with the path to where you have rsync installed on
|
||||
@@ -67,12 +67,12 @@ reread its config file.
|
||||
|
||||
Note that you should bf(not) send the rsync daemon a HUP signal to force
|
||||
it to reread the tt(rsyncd.conf) file. The file is re-read on each client
|
||||
connection.
|
||||
connection.
|
||||
|
||||
manpagesection(GLOBAL OPTIONS)
|
||||
|
||||
The first parameters in the file (before a [module] header) are the
|
||||
global parameters.
|
||||
global parameters.
|
||||
|
||||
You may also include any module parameters in the global part of the
|
||||
config file in which case the supplied value will override the
|
||||
@@ -84,25 +84,9 @@ dit(bf(motd file)) The "motd file" option allows you to specify a
|
||||
usually contains site information and any legal notices. The default
|
||||
is no motd file.
|
||||
|
||||
dit(bf(log file)) The "log file" option tells the rsync daemon to log
|
||||
messages to that file rather than using syslog. This is particularly
|
||||
useful on systems (such as AIX) where syslog() doesn't work for
|
||||
chrooted programs. If the daemon fails to open to specified file, it
|
||||
will fall back to using syslog and output an error about the failure.
|
||||
(Note that a failure to open the specified log file used to be a fatal
|
||||
error.)
|
||||
|
||||
dit(bf(pid file)) The "pid file" option tells the rsync daemon to write
|
||||
its process ID to that file.
|
||||
|
||||
dit(bf(syslog facility)) The "syslog facility" option 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
|
||||
defined on your system. Common names are auth, authpriv, cron, daemon,
|
||||
ftp, kern, lpr, mail, news, security, syslog, user, uucp, local0,
|
||||
local1, local2, local3, local4, local5, local6 and local7. The default
|
||||
is 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
|
||||
is being run by inetd, and is superseded by the bf(--port) command-line option.
|
||||
@@ -114,7 +98,7 @@ being run by inetd, and is superseded by the bf(--address) command-line option.
|
||||
dit(bf(socket options)) This option can provide endless fun for people
|
||||
who like to tune their systems to the utmost degree. You can set all
|
||||
sorts of socket options which may make transfers faster (or
|
||||
slower!). Read the man page for the setsockopt() system call for
|
||||
slower!). Read the man page for the code(setsockopt()) system call for
|
||||
details on some of the options you may be able to set. By default no
|
||||
special socket options are set. These settings are superseded by the
|
||||
bf(--sockopts) command-line option.
|
||||
@@ -142,7 +126,7 @@ for each module in tt(rsyncd.conf).
|
||||
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
|
||||
holes, but it has the disadvantages of requiring super-user privileges,
|
||||
holes, but it has the disadvantages of requiring super-user privileges,
|
||||
of not being able to follow symbolic links that are either absolute or outside
|
||||
of the new root path, and of complicating the preservation of usernames and groups
|
||||
(see below). When "use chroot" is false, for security reasons,
|
||||
@@ -154,7 +138,7 @@ The default for "use chroot" is true.
|
||||
|
||||
In order to preserve usernames and groupnames, rsync needs to be able to
|
||||
use the standard library functions for looking up names and IDs (i.e.
|
||||
getpwuid(), getgrgid(), getpwname(), and getgrnam()). This means a
|
||||
code(getpwuid()), code(getgrgid()), code(getpwname()), and code(getgrnam())). This means a
|
||||
process in the chroot namespace will need to have access to the resources
|
||||
used by these library functions (traditionally /etc/passwd and
|
||||
/etc/group). If these resources are not available, rsync will only be
|
||||
@@ -180,6 +164,29 @@ Any clients connecting when the maximum has been reached will receive a
|
||||
message telling them to try later. The default is 0 which means no limit.
|
||||
See also the "lock file" option.
|
||||
|
||||
dit(bf(log file)) When the "log file" option is set to a non-empty
|
||||
string, the rsync daemon will log messages to the indicated file rather
|
||||
than using syslog. This is particularly useful on systems (such as AIX)
|
||||
where code(syslog()) doesn't work for chrooted programs. The file is
|
||||
opened before code(chroot()) is called, allowing it to be placed outside
|
||||
the transfer. If this value is set on a per-module basis instead of
|
||||
globally, the global log will still contain any authorization failures
|
||||
or config-file error messages.
|
||||
|
||||
If the daemon fails to open to 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.)
|
||||
|
||||
dit(bf(syslog facility)) The "syslog facility" option 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
|
||||
defined on your system. Common names are auth, authpriv, cron, daemon,
|
||||
ftp, kern, lpr, mail, news, security, syslog, user, uucp, local0,
|
||||
local1, local2, local3, local4, local5, local6 and local7. The default
|
||||
is daemon. This setting has no effect if the "log file" setting is a
|
||||
non-empty string (either set in the per-modules settings, or inherited
|
||||
from the global settings).
|
||||
|
||||
dit(bf(max verbosity)) The "max verbosity" option allows you to control
|
||||
the maximum amount of verbose information that you'll allow the daemon to
|
||||
generate (since the information goes into the log file). The default is 1,
|
||||
@@ -188,7 +195,7 @@ which allows the client to request one level of verbosity.
|
||||
dit(bf(lock file)) The "lock file" option specifies the file to use to
|
||||
support the "max connections" option. The rsync daemon uses record
|
||||
locking on this file to ensure that the max connections limit is not
|
||||
exceeded for the modules sharing the lock file.
|
||||
exceeded for the modules sharing the lock file.
|
||||
The default is tt(/var/run/rsyncd.lock).
|
||||
|
||||
dit(bf(read only)) The "read only" option determines whether clients
|
||||
@@ -240,7 +247,7 @@ Because this exclude list is not passed to the client it only applies on
|
||||
the daemon: that is, it excludes files received by a client when receiving
|
||||
from a daemon and files deleted on a daemon when sending to a daemon, but
|
||||
it doesn't exclude files from being deleted on a client when receiving
|
||||
from a daemon.
|
||||
from a daemon.
|
||||
|
||||
dit(bf(exclude from)) The "exclude from" option specifies a filename
|
||||
on the daemon that contains exclude patterns, one per line.
|
||||
@@ -266,10 +273,9 @@ See the "exclude" option above.
|
||||
dit(bf(incoming chmod)) This option allows you to specify a set of
|
||||
comma-separated chmod strings that will affect the permissions of all
|
||||
incoming files (files that are being received by the daemon). These
|
||||
changes happen after any user-requested changes the client requested via
|
||||
bf(--chmod). Note, however, the if the client didn't specify bf(--perms),
|
||||
the daemon's umask setting will still mask the value before it is used, so
|
||||
be sure it is set appropriately if this is a concern.
|
||||
changes happen after all other permission calculations, and this will
|
||||
even override destination-default and/or existing permissions when the
|
||||
client does not specify bf(--perms).
|
||||
See the description of the bf(--chmod) rsync option and the bf(chmod)(1)
|
||||
manpage for information on the format of this string.
|
||||
|
||||
@@ -295,7 +301,7 @@ usernames and passwords are stored in the file specified by the
|
||||
connect without a password (this is called "anonymous rsync").
|
||||
|
||||
See also the "CONNECTING TO AN RSYNC DAEMON OVER A REMOTE SHELL
|
||||
PROGRAM" section in rsync(1) for information on how handle an
|
||||
PROGRAM" section 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.
|
||||
|
||||
@@ -307,13 +313,13 @@ 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.
|
||||
you may find that passwords longer than 8 characters don't work.
|
||||
|
||||
There is no default for the "secrets file" option, you must choose a name
|
||||
(such as tt(/etc/rsyncd.secrets)). The file must normally not be readable
|
||||
by "other"; see "strict modes".
|
||||
|
||||
dit(bf(strict modes)) The "strict modes" option determines whether or not
|
||||
dit(bf(strict modes)) The "strict modes" option determines whether or not
|
||||
the permissions on the secrets file will be checked. If "strict modes" is
|
||||
true, then the secrets file must not be readable by any user ID other
|
||||
than the one that the rsync daemon is running under. If "strict modes" is
|
||||
@@ -327,7 +333,7 @@ connection is rejected.
|
||||
|
||||
Each pattern can be in one of five forms:
|
||||
|
||||
quote(itemize(
|
||||
quote(itemization(
|
||||
it() a dotted decimal IPv4 address of the form a.b.c.d, or an IPv6 address
|
||||
of the form a:b:c::d:e:f. In this case the incoming machine's IP address
|
||||
must match exactly.
|
||||
@@ -358,7 +364,7 @@ You can also combine "hosts allow" with a separate "hosts deny"
|
||||
option. If both options are specified then the "hosts allow" option s
|
||||
checked first and a match results in the client being able to
|
||||
connect. The "hosts deny" option is then checked and a match means
|
||||
that the host is rejected. If the host does not match either the
|
||||
that the host is rejected. If the host does not match either the
|
||||
"hosts allow" or the "hosts deny" patterns then it is allowed to
|
||||
connect.
|
||||
|
||||
@@ -377,14 +383,14 @@ phase of the transfer. Normally rsync skips the bf(--delete) step if any
|
||||
I/O errors have occurred in order to prevent disastrous deletion due
|
||||
to a temporary resource shortage or other I/O error. In some cases this
|
||||
test is counter productive so you can use this option to turn off this
|
||||
behavior.
|
||||
behavior.
|
||||
|
||||
dit(bf(ignore nonreadable)) This tells the rsync daemon to completely
|
||||
ignore files that are not readable by the user. This is useful for
|
||||
public archives that may have some non-readable files among the
|
||||
directories, and the sysadmin doesn't want those files to be seen at all.
|
||||
|
||||
dit(bf(transfer logging)) The "transfer logging" option enables per-file
|
||||
dit(bf(transfer logging)) The "transfer logging" option enables per-file
|
||||
logging of downloads and uploads in a format somewhat similar to that
|
||||
used by ftp daemons. The daemon always logs the transfer at the end, so
|
||||
if a transfer is aborted, no mention will be made in the log file.
|
||||
@@ -406,9 +412,9 @@ rsyncstats.)
|
||||
|
||||
The single-character escapes that are understood are as follows:
|
||||
|
||||
quote(itemize(
|
||||
quote(itemization(
|
||||
it() %a the remote IP address
|
||||
it() %b the number of bytes actually transferred
|
||||
it() %b the number of bytes actually transferred
|
||||
it() %B the permission bits of the file (e.g. rwxrwxrwt)
|
||||
it() %c the checksum bytes received for this file (only when sending)
|
||||
it() %f the filename (long form on sender; no trailing "/")
|
||||
@@ -460,15 +466,18 @@ without the former, instead refuse "delete-*" -- that refuses all the
|
||||
delete modes without affecting bf(--remove-sent-files).
|
||||
|
||||
When an option is refused, the daemon prints an error message and exits.
|
||||
To prevent all compression, you can use "dont compress = *" (see below)
|
||||
To prevent all compression when serving files,
|
||||
you can use "dont compress = *" (see below)
|
||||
instead of "refuse options = compress" to avoid returning an error to a
|
||||
client that requests compression.
|
||||
|
||||
dit(bf(dont compress)) The "dont compress" option allows you to select
|
||||
filenames based on wildcard patterns that should not be compressed
|
||||
during transfer. Compression is expensive in terms of CPU usage so it
|
||||
when pulling files from the daemon (no analogous option exists to
|
||||
govern the pushing of files to a daemon).
|
||||
Compression is expensive in terms of CPU usage, so it
|
||||
is usually good to not try to compress files that won't compress well,
|
||||
such as already compressed files.
|
||||
such as already compressed files.
|
||||
|
||||
The "dont compress" option takes a space-separated list of
|
||||
case-insensitive wildcard patterns. Any source filename matching one
|
||||
@@ -483,22 +492,25 @@ 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:
|
||||
|
||||
quote(itemize(
|
||||
quote(itemization(
|
||||
it() bf(RSYNC_MODULE_NAME): The name of the module being accessed.
|
||||
it() bf(RSYNC_MODULE_PATH): The path configured for the module.
|
||||
it() bf(RSYNC_HOST_ADDR): The accessing host's IP address.
|
||||
it() bf(RSYNC_HOST_NAME): The accessing host's name.
|
||||
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.).
|
||||
it() bf(RSYNC_ARG#): (pre-xfer only) The pre-request arguments are set
|
||||
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) rsync's exit value. This will be 0 for a
|
||||
successful run, a positive value for an error that rsync returned
|
||||
(e.g. 23=partial xfer), or a -1 if rsync failed to exit properly.
|
||||
it() bf(RSYNC_RAW_STATUS): (post-xfer only) the raw exit value from waitpid().
|
||||
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
|
||||
error that occurs on the client side does not currently get sent to the
|
||||
server side, so this is not the final exit status for the whole transfer.
|
||||
it() bf(RSYNC_RAW_STATUS): (post-xfer only) the raw exit value from code(waitpid()).
|
||||
))
|
||||
|
||||
Even though the commands can be associated with a particular module, they
|
||||
@@ -556,7 +568,7 @@ pid file = /var/run/rsyncd.pid
|
||||
[rsyncftp]
|
||||
path = /var/ftp/pub/rsync
|
||||
comment = rsync ftp area (approx 6 MB)
|
||||
|
||||
|
||||
[sambawww]
|
||||
path = /public_html/samba
|
||||
comment = Samba WWW pages (approx 240 MB)
|
||||
@@ -581,7 +593,7 @@ manpagefiles()
|
||||
|
||||
manpageseealso()
|
||||
|
||||
rsync(1)
|
||||
bf(rsync)(1)
|
||||
|
||||
manpagediagnostics()
|
||||
|
||||
@@ -592,7 +604,7 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
|
||||
This man page is current for version 2.6.7pre1 of rsync.
|
||||
This man page is current for version 2.6.9 of rsync.
|
||||
|
||||
manpagesection(CREDITS)
|
||||
|
||||
@@ -614,7 +626,7 @@ manpagesection(THANKS)
|
||||
|
||||
Thanks to Warren Stanley for his original idea and patch for the rsync
|
||||
daemon. Thanks to Karsten Thygesen for his many suggestions and
|
||||
documentation!
|
||||
documentation!
|
||||
|
||||
manpageauthor()
|
||||
|
||||
@@ -622,4 +634,4 @@ rsync was written by Andrew Tridgell and Paul Mackerras.
|
||||
Many people have later contributed to it.
|
||||
|
||||
Mailing lists for support and development are available at
|
||||
url(http://lists.samba.org)(lists.samba.org)
|
||||
url(http://lists.samba.org)(lists.samba.org)
|
||||
|
||||
47
runtests.sh
47
runtests.sh
@@ -1,6 +1,7 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
# Copyright (C) 2003, 2004, 2005, 2006 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
|
||||
@@ -13,8 +14,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# rsync top-level test script -- this invokes all the other more
|
||||
# detailed tests in order. This script can either be called by `make
|
||||
@@ -138,9 +138,27 @@ if [ "x$loglevel" != x ] && [ "$loglevel" -gt 8 ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
POSIXLY_CORRECT=1
|
||||
if test x"$TOOLDIR" = x; then
|
||||
TOOLDIR=`pwd`
|
||||
fi
|
||||
srcdir=`dirname $0`
|
||||
if test x"$srcdir" = x -o x"$srcdir" = x.; then
|
||||
srcdir="$TOOLDIR"
|
||||
fi
|
||||
if test x"$rsync_bin" = x; then
|
||||
rsync_bin="$TOOLDIR/rsync"
|
||||
fi
|
||||
|
||||
# This allows the user to specify extra rsync options -- use carefully!
|
||||
RSYNC="$rsync_bin $*"
|
||||
#RSYNC="valgrind $rsync_bin $*"
|
||||
|
||||
export POSIXLY_CORRECT TOOLDIR srcdir RSYNC
|
||||
|
||||
echo "============================================================"
|
||||
echo "$0 running in `pwd`"
|
||||
echo " rsync_bin=$rsync_bin"
|
||||
echo "$0 running in $TOOLDIR"
|
||||
echo " rsync_bin=$RSYNC"
|
||||
echo " srcdir=$srcdir"
|
||||
|
||||
if [ -f /usr/bin/whoami ]; then
|
||||
@@ -163,13 +181,17 @@ else
|
||||
echo " preserve_scratch=no"
|
||||
fi
|
||||
|
||||
# We'll use setfacl if it's around and it supports the -k option.
|
||||
if setfacl --help 2>/dev/null | grep ' -k,' >/dev/null; then
|
||||
setfacl=setfacl
|
||||
# Check if setfacl is around and if it supports the -k or -s option.
|
||||
if setfacl --help 2>&1 | grep ' -k,\|\[-[a-z]*k' >/dev/null; then
|
||||
setfacl_nodef='setfacl -k'
|
||||
elif setfacl -s u::7,g::5,o:5 testsuite 2>/dev/null; then
|
||||
setfacl_nodef='setfacl -s u::7,g::5,o:5'
|
||||
else
|
||||
setfacl=true
|
||||
setfacl_nodef=true
|
||||
fi
|
||||
|
||||
export setfacl_nodef
|
||||
|
||||
if [ ! -f "$rsync_bin" ]; then
|
||||
echo "rsync_bin $rsync_bin is not a file" >&2
|
||||
exit 2
|
||||
@@ -180,11 +202,6 @@ if [ ! -d "$srcdir" ]; then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
RSYNC="$rsync_bin"
|
||||
#RSYNC="valgrind --tool=addrcheck $rsync_bin"
|
||||
|
||||
export rsync_bin RSYNC
|
||||
|
||||
skipped=0
|
||||
missing=0
|
||||
passed=0
|
||||
@@ -193,7 +210,7 @@ failed=0
|
||||
# Prefix for scratch directory. We create separate directories for
|
||||
# each test case, so that they can be left behind in case of failure
|
||||
# to aid investigation.
|
||||
scratchbase="`pwd`"/testtmp
|
||||
scratchbase="$TOOLDIR"/testtmp
|
||||
echo " scratchbase=$scratchbase"
|
||||
|
||||
suitedir="$srcdir/testsuite"
|
||||
@@ -204,7 +221,7 @@ prep_scratch() {
|
||||
[ -d "$scratchdir" ] && rm -rf "$scratchdir"
|
||||
mkdir "$scratchdir"
|
||||
# Get rid of default ACLs and dir-setgid to avoid confusing some tests.
|
||||
$setfacl -k "$scratchdir"
|
||||
$setfacl_nodef "$scratchdir" || true
|
||||
chmod g-s "$scratchdir"
|
||||
return 0
|
||||
}
|
||||
|
||||
71
sender.c
71
sender.c
@@ -1,21 +1,24 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
* Routines only used by the sending process.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -24,14 +27,14 @@ extern int do_xfers;
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int log_before_transfer;
|
||||
extern int log_format_has_i;
|
||||
extern int daemon_log_format_has_i;
|
||||
extern int stdout_format_has_i;
|
||||
extern int logfile_format_has_i;
|
||||
extern int csum_length;
|
||||
extern int append_mode;
|
||||
extern int io_error;
|
||||
extern int allowed_lull;
|
||||
extern int protocol_version;
|
||||
extern int remove_sent_files;
|
||||
extern int remove_source_files;
|
||||
extern int updating_basis_file;
|
||||
extern int make_backups;
|
||||
extern int do_progress;
|
||||
@@ -40,7 +43,7 @@ extern int batch_fd;
|
||||
extern int write_batch;
|
||||
extern struct stats stats;
|
||||
extern struct file_list *the_file_list;
|
||||
extern char *log_format;
|
||||
extern char *stdout_format;
|
||||
|
||||
|
||||
/**
|
||||
@@ -125,17 +128,19 @@ void successful_send(int ndx)
|
||||
return;
|
||||
|
||||
file = the_file_list->files[ndx];
|
||||
/* The generator might tell us about symlinks we didn't send. */
|
||||
if (!(file->flags & FLAG_SENT) && !S_ISLNK(file->mode))
|
||||
return;
|
||||
if (file->dir.root) {
|
||||
offset = stringjoin(fname, sizeof fname,
|
||||
file->dir.root, "/", NULL);
|
||||
} else
|
||||
offset = 0;
|
||||
f_name(file, fname + offset);
|
||||
if (remove_sent_files && do_unlink(fname) == 0 && verbose > 1)
|
||||
rprintf(FINFO, "sender removed %s\n", fname + offset);
|
||||
if (remove_source_files) {
|
||||
if (do_unlink(fname) == 0) {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO, "sender removed %s\n", fname + offset);
|
||||
} else
|
||||
rsyserr(FERROR, errno, "sender failed to remove %s", fname + offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
|
||||
@@ -215,8 +220,8 @@ void send_files(struct file_list *flist, int f_out, int f_in)
|
||||
int phase = 0, max_phase = protocol_version >= 29 ? 2 : 1;
|
||||
struct stats initial_stats;
|
||||
int save_make_backups = make_backups;
|
||||
int itemizing = am_daemon ? daemon_log_format_has_i
|
||||
: !am_server && log_format_has_i;
|
||||
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 i, j;
|
||||
|
||||
@@ -278,8 +283,7 @@ void send_files(struct file_list *flist, int f_out, int f_in)
|
||||
stats.total_transferred_size += file->length;
|
||||
|
||||
if (!do_xfers) { /* log the transfer */
|
||||
if (!am_server && log_format)
|
||||
log_item(file, &stats, iflags, NULL);
|
||||
log_item(FCLIENT, file, &stats, iflags, NULL);
|
||||
write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
|
||||
xname, xlen);
|
||||
continue;
|
||||
@@ -340,9 +344,9 @@ void send_files(struct file_list *flist, int f_out, int f_in)
|
||||
rprintf(FINFO, "calling match_sums %s\n", fname);
|
||||
|
||||
if (log_before_transfer)
|
||||
log_item(file, &initial_stats, iflags, NULL);
|
||||
log_item(FCLIENT, file, &initial_stats, iflags, NULL);
|
||||
else if (!am_server && verbose && do_progress)
|
||||
rprintf(FINFO, "%s\n", fname2);
|
||||
rprintf(FCLIENT, "%s\n", fname2);
|
||||
|
||||
set_compression(fname);
|
||||
|
||||
@@ -350,8 +354,7 @@ void send_files(struct file_list *flist, int f_out, int f_in)
|
||||
if (do_progress)
|
||||
end_progress(st.st_size);
|
||||
|
||||
if (!log_before_transfer)
|
||||
log_item(file, &initial_stats, iflags, NULL);
|
||||
log_item(log_code, file, &initial_stats, iflags, NULL);
|
||||
|
||||
if (mbuf) {
|
||||
j = unmap_file(mbuf);
|
||||
|
||||
87
socket.c
87
socket.c
@@ -1,37 +1,34 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
rsync -- fast file replication program
|
||||
|
||||
Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file socket.c
|
||||
*
|
||||
/*
|
||||
* Socket functions used in rsync.
|
||||
*
|
||||
* This file is now converted to use the new-style getaddrinfo()
|
||||
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* This file is now converted to use the new-style getaddrinfo()
|
||||
* interface, which supports IPv6 but is also supported on recent
|
||||
* IPv4-only machines. On systems that don't have that interface, we
|
||||
* emulate it using the KAME implementation.
|
||||
**/
|
||||
* emulate it using the KAME implementation. */
|
||||
|
||||
#include "rsync.h"
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
extern char *bind_address;
|
||||
extern int default_af_hint;
|
||||
@@ -58,13 +55,13 @@ static int establish_proxy_connection(int fd, char *host, int port,
|
||||
proxy_user, ":", proxy_pass, NULL);
|
||||
len = strlen(buffer);
|
||||
|
||||
if ((len*8 + 5) / 6 >= (int)sizeof authbuf) {
|
||||
if ((len*8 + 5) / 6 >= (int)sizeof authbuf - 3) {
|
||||
rprintf(FERROR,
|
||||
"authentication information is too long\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
base64_encode(buffer, len, authbuf);
|
||||
base64_encode(buffer, len, authbuf, 1);
|
||||
authhdr = "\r\nProxy-Authorization: Basic ";
|
||||
} else {
|
||||
*authbuf = '\0';
|
||||
@@ -333,9 +330,9 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
|
||||
int af_hint)
|
||||
{
|
||||
int one = 1;
|
||||
int s, *socks, maxs, i;
|
||||
int s, *socks, maxs, i, ecnt;
|
||||
struct addrinfo hints, *all_ai, *resp;
|
||||
char portbuf[10];
|
||||
char portbuf[10], **errmsgs;
|
||||
int error;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
@@ -353,17 +350,25 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
|
||||
/* Count max number of sockets we might open. */
|
||||
for (maxs = 0, resp = all_ai; resp; resp = resp->ai_next, maxs++) {}
|
||||
|
||||
if (!(socks = new_array(int, maxs + 1)))
|
||||
socks = new_array(int, maxs + 1);
|
||||
errmsgs = new_array(char *, maxs);
|
||||
if (!socks || !errmsgs)
|
||||
out_of_memory("open_socket_in");
|
||||
|
||||
/* We may not be able to create the socket, if for example the
|
||||
* machine knows about IPv6 in the C library, but not in the
|
||||
* kernel. */
|
||||
for (resp = all_ai, i = 0; resp; resp = resp->ai_next) {
|
||||
for (resp = all_ai, i = ecnt = 0; resp; resp = resp->ai_next) {
|
||||
s = socket(resp->ai_family, resp->ai_socktype,
|
||||
resp->ai_protocol);
|
||||
|
||||
if (s == -1) {
|
||||
int r = asprintf(&errmsgs[ecnt++],
|
||||
"socket(%d,%d,%d) failed: %s\n",
|
||||
(int)resp->ai_family, (int)resp->ai_socktype,
|
||||
(int)resp->ai_protocol, strerror(errno));
|
||||
if (r < 0)
|
||||
out_of_memory("open_socket_in");
|
||||
/* See if there's another address that will work... */
|
||||
continue;
|
||||
}
|
||||
@@ -385,6 +390,11 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
|
||||
/* Now we've got a socket - we need to bind it. */
|
||||
if (bind(s, resp->ai_addr, resp->ai_addrlen) < 0) {
|
||||
/* Nope, try another */
|
||||
int r = asprintf(&errmsgs[ecnt++],
|
||||
"bind() failed: %s (address-family %d)\n",
|
||||
strerror(errno), (int)resp->ai_family);
|
||||
if (r < 0)
|
||||
out_of_memory("open_socket_in");
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
@@ -396,6 +406,15 @@ static int *open_socket_in(int type, int port, const char *bind_addr,
|
||||
if (all_ai)
|
||||
freeaddrinfo(all_ai);
|
||||
|
||||
/* 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 || verbose > 1)
|
||||
rwrite(FLOG, errmsgs[s], strlen(errmsgs[s]));
|
||||
free(errmsgs[s]);
|
||||
}
|
||||
free(errmsgs);
|
||||
|
||||
if (!i) {
|
||||
rprintf(FERROR,
|
||||
"unable to bind any inbound sockets on port %d\n",
|
||||
|
||||
@@ -55,7 +55,7 @@ EOT
|
||||
|
||||
foreach my $opt (sort keys %long_opt) {
|
||||
my $val = $long_opt{$opt};
|
||||
$val = 1 if $opt =~ /^max-/;
|
||||
$val = 1 if $opt =~ /^(max-|min-)/;
|
||||
$val = 3 if $opt eq 'files-from';
|
||||
$val = '$ro ? -1 : ' . $val if $opt =~ /^remove-/;
|
||||
print " '$opt' => $val,\n";
|
||||
|
||||
173
support/file-attr-restore
Executable file
173
support/file-attr-restore
Executable file
@@ -0,0 +1,173 @@
|
||||
#!/usr/bin/perl
|
||||
# This script will parse the output of "find ARG [ARG...] -ls" and
|
||||
# apply (at your discretion) the permissions, owner, and group info
|
||||
# it reads onto any existing files and dirs (it doesn't try to affect
|
||||
# symlinks). Run this with --help (-h) for a usage summary.
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
|
||||
our($p_opt, $o_opt, $g_opt, $map_file, $dry_run, $verbosity, $help_opt);
|
||||
|
||||
&Getopt::Long::Configure('bundling');
|
||||
&usage if !&GetOptions(
|
||||
'all|a' => sub { $p_opt = $o_opt = $g_opt = 1 },
|
||||
'perms|p' => \$p_opt,
|
||||
'owner|o' => \$o_opt,
|
||||
'groups|g' => \$g_opt,
|
||||
'map|m=s' => \$map_file,
|
||||
'dry-run|n' => \$dry_run,
|
||||
'help|h' => \$help_opt,
|
||||
'verbose|v+' => \$verbosity,
|
||||
) || $help_opt;
|
||||
|
||||
our(%uid_hash, %gid_hash);
|
||||
|
||||
$" = ', '; # How to join arrays referenced in double-quotes.
|
||||
|
||||
&parse_map_file($map_file) if defined $map_file;
|
||||
|
||||
my $detail_line = qr{
|
||||
^ \s* \d+ \s+ # ignore inode
|
||||
\d+ \s+ # ignore size
|
||||
([-bcdlps]) # 1. File type
|
||||
( [-r][-w][-xsS] # 2. user-permissions
|
||||
[-r][-w][-xsS] # 3. group-permissions
|
||||
[-r][-w][-xtT] ) \s+ # 4. other-permissions
|
||||
\d+ \s+ # ignore number of links
|
||||
(\S+) \s+ # 5. owner
|
||||
(\S+) \s+ # 6. group
|
||||
(?: \d+ \s+ )? # ignore size (when present)
|
||||
\w+ \s+ \d+ \s+ # ignore month and date
|
||||
\d+ (?: : \d+ )? \s+ # ignore time or year
|
||||
([^\r\n]+) $ # 7. name
|
||||
}x;
|
||||
|
||||
while (<>) {
|
||||
my($type, $perms, $owner, $group, $name) = /$detail_line/;
|
||||
die "Invalid input line $.:\n$_" unless defined $name;
|
||||
die "A filename is not properly escaped:\n$_" unless $name =~ /^[^"\\]*(\\(\d\d\d|\D)[^"\\]*)*$/;
|
||||
my $fn = $name;
|
||||
$fn =~ s/\\(\d+|.)/ eval "\"\\$1\"" /eg;
|
||||
if ($type eq '-') {
|
||||
undef $type unless -f $fn;
|
||||
} elsif ($type eq 'd') {
|
||||
undef $type unless -d $fn;
|
||||
} elsif ($type eq 'b') {
|
||||
undef $type unless -b $fn;
|
||||
} elsif ($type eq 'c') {
|
||||
undef $type unless -c $fn;
|
||||
} elsif ($type eq 'p') {
|
||||
undef $type unless -p $fn;
|
||||
} elsif ($type eq 's') {
|
||||
undef $type unless -S $fn;
|
||||
} else {
|
||||
if ($verbosity) {
|
||||
if ($type eq 'l') {
|
||||
$name =~ s/ -> .*//;
|
||||
$type = 'symlink';
|
||||
} else {
|
||||
$type = "type '$type'";
|
||||
}
|
||||
print "Skipping $name ($type ignored)\n";
|
||||
}
|
||||
next;
|
||||
}
|
||||
if (!defined $type) {
|
||||
my $reason = -e _ ? "types don't match" : 'missing';
|
||||
print "Skipping $name ($reason)\n";
|
||||
next;
|
||||
}
|
||||
my($cur_mode, $cur_uid, $cur_gid) = (stat(_))[2,4,5];
|
||||
$cur_mode &= 07777;
|
||||
my $highs = join('', $perms =~ /..(.)..(.)..(.)/);
|
||||
$highs =~ tr/-rwxSTst/00001111/;
|
||||
$perms =~ tr/-STrwxst/00011111/;
|
||||
my $mode = $p_opt ? oct('0b' . $highs . $perms) : $cur_mode;
|
||||
my $uid = $o_opt ? $uid_hash{$owner} : $cur_uid;
|
||||
if (!defined $uid) {
|
||||
if ($owner =~ /^\d+$/) {
|
||||
$uid = $owner;
|
||||
} else {
|
||||
$uid = getpwnam($owner);
|
||||
}
|
||||
$uid_hash{$owner} = $uid;
|
||||
}
|
||||
my $gid = $g_opt ? $gid_hash{$group} : $cur_gid;
|
||||
if (!defined $gid) {
|
||||
if ($group =~ /^\d+$/) {
|
||||
$gid = $group;
|
||||
} else {
|
||||
$gid = getgrnam($group);
|
||||
}
|
||||
$gid_hash{$group} = $gid;
|
||||
}
|
||||
|
||||
my @changes;
|
||||
if ($mode != $cur_mode) {
|
||||
push(@changes, 'permissions');
|
||||
if (!$dry_run && !chmod($mode, $fn)) {
|
||||
warn "chmod($mode, \"$name\") failed: $!\n";
|
||||
}
|
||||
}
|
||||
if ($uid != $cur_uid || $gid != $cur_gid) {
|
||||
push(@changes, 'owner') if $uid != $cur_uid;
|
||||
push(@changes, 'group') if $gid != $cur_gid;
|
||||
if (!$dry_run) {
|
||||
if (!chown($uid, $gid, $fn)) {
|
||||
warn "chown($uid, $gid, \"$name\") failed: $!\n";
|
||||
}
|
||||
if (($mode & 06000) && !chmod($mode, $fn)) {
|
||||
warn "post-chown chmod($mode, \"$name\") failed: $!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (@changes) {
|
||||
print "$name: changed @changes\n";
|
||||
} elsif ($verbosity) {
|
||||
print "$name: OK\n";
|
||||
}
|
||||
}
|
||||
exit;
|
||||
|
||||
sub parse_map_file
|
||||
{
|
||||
my($fn) = @_;
|
||||
open(IN, $fn) or die "Unable to open $fn: $!\n";
|
||||
while (<IN>) {
|
||||
if (/^user\s+(\S+)\s+(\S+)/) {
|
||||
$uid_hash{$1} = $2;
|
||||
} elsif (/^group\s+(\S+)\s+(\S+)/) {
|
||||
$gid_hash{$1} = $2;
|
||||
} else {
|
||||
die "Invalid line #$. in mapfile `$fn':\n$_";
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
}
|
||||
|
||||
sub usage
|
||||
{
|
||||
die <<EOT;
|
||||
Usage: file-attr-restore [OPTIONS] FILE [FILE...]
|
||||
-a, --all Restore all the attributes (-pog)
|
||||
-p, --perms Restore the permissions
|
||||
-o, --owner Restore the ownership
|
||||
-g, --groups Restore the group
|
||||
-m, --map=FILE Read user/group mappings from FILE
|
||||
-n, --dry-run Don't actually make the changes
|
||||
-v, --verbose Increase verbosity
|
||||
-h, --help Show this help text
|
||||
|
||||
The FILE arg(s) should have been created by running the "find"
|
||||
program with "-ls" as the output specifier.
|
||||
|
||||
The input file for the --map option must be in this format:
|
||||
|
||||
user FROM TO
|
||||
group FROM TO
|
||||
|
||||
The "FROM" should be an user/group mentioned in the input, and the TO
|
||||
should be either a uid/gid number, or a local user/group name.
|
||||
EOT
|
||||
}
|
||||
@@ -50,17 +50,19 @@ die "$0 -ro: sending to read-only server not allowed\n" if $ro && !$am_sender;
|
||||
# To disable a short-named option, add its letter to this string:
|
||||
our $short_disabled = '';
|
||||
|
||||
our $short_no_arg = 'CDHIKLORSWbcdglnoprtuvxz'; # DO NOT REMOVE ANY
|
||||
our $short_no_arg = 'CDEHIKLORSWbcdgklmnoprtuvxz'; # DO NOT REMOVE ANY
|
||||
our $short_with_num = 'B'; # DO NOT REMOVE ANY
|
||||
|
||||
# To disable a long-named option, change its value to a -1. The values mean:
|
||||
# 0 = the option has no arg; 1 = the arg doesn't need any checking; 2 = only
|
||||
# check the arg when receiving; and 3 = always check the arg.
|
||||
our %long_opt = (
|
||||
'append' => 0,
|
||||
'backup-dir' => 2,
|
||||
'bwlimit' => 1,
|
||||
'checksum-seed' => 1,
|
||||
'compare-dest' => 2,
|
||||
'compress-level' => 1,
|
||||
'copy-dest' => 2,
|
||||
'copy-unsafe-links' => 0,
|
||||
'daemon' => 0,
|
||||
@@ -83,19 +85,25 @@ our %long_opt = (
|
||||
'log-format' => 1,
|
||||
'max-delete' => 1,
|
||||
'max-size' => 1,
|
||||
'min-size' => 1,
|
||||
'modify-window' => 1,
|
||||
'no-implied-dirs' => 0,
|
||||
'no-r' => 0,
|
||||
'no-relative' => 0,
|
||||
'no-specials' => 0,
|
||||
'numeric-ids' => 0,
|
||||
'only-write-batch' => 1,
|
||||
'partial' => 0,
|
||||
'partial-dir' => 2,
|
||||
'remove-sent-files' => $ro ? -1 : 0,
|
||||
'remove-source-files' => $ro ? -1 : 0,
|
||||
'safe-links' => 0,
|
||||
'sender' => 0,
|
||||
'server' => 0,
|
||||
'size-only' => 0,
|
||||
'specials' => 0,
|
||||
'suffix' => 1,
|
||||
'super' => 0,
|
||||
'temp-dir' => 2,
|
||||
'timeout' => 1,
|
||||
);
|
||||
|
||||
@@ -52,9 +52,22 @@ if ($only_section) {
|
||||
|
||||
line: while (<LOG>) {
|
||||
|
||||
my $syslog_prefix = '\w\w\w +\d+ \d\d:\d\d:\d\d \S+ rsyncd';
|
||||
my $rsyncd_prefix = '\d\d\d\d/\d\d/\d\d \d\d:\d\d:\d\d ';
|
||||
|
||||
next unless ($day,$time,$op,$host,$module,$file,$bytes)
|
||||
= m#^ (\d+/\d\d/\d\d)\s+(\d\d:\d\d:\d\d)\s+\[\d+\]\s+(send|recv|[<>]f\S+)\s+
|
||||
(\S+)\s+\[\d+\.\d+\.\d+\.\d+\]\s+(\S+)\s+\(\S*\)\s+(.*)\s+(\d+) $ #x;
|
||||
= m{^
|
||||
( \w\w\w\s+\d+ | \d+/\d\d/\d\d ) \s+ # day
|
||||
(\d\d:\d\d:\d\d) \s+ # time
|
||||
[^[]* \[\d+\]:? \s+ # pid (ignored)
|
||||
(send|recv|[<>]f\S+) \s+ # op (%o or %i)
|
||||
(\S+) \s+ # host
|
||||
\[\d+\.\d+\.\d+\.\d+\] \s+ # IP (ignored)
|
||||
(\S+) \s+ # module
|
||||
\(\S*\) \s+ # user (ignored)
|
||||
(.*) \s+ # file name
|
||||
(\d+) # file length in bytes
|
||||
$ }x;
|
||||
|
||||
# TODO actually divide the data by into send/recv categories
|
||||
if ($op =~ /^>/) {
|
||||
|
||||
49
syscall.c
49
syscall.c
@@ -1,28 +1,25 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file syscall.c
|
||||
*
|
||||
/*
|
||||
* Syscall wrappers to ensure that nothing gets done in dry_run mode
|
||||
* and to handle system peculiarities.
|
||||
**/
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -168,10 +165,10 @@ void trim_trailing_slashes(char *name)
|
||||
/* Some BSD systems cannot make a directory if the name
|
||||
* contains a trailing slash.
|
||||
* <http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html> */
|
||||
|
||||
|
||||
/* Don't change empty string; and also we can't improve on
|
||||
* "/" */
|
||||
|
||||
|
||||
l = strlen(name);
|
||||
while (l > 1) {
|
||||
if (name[--l] != '/')
|
||||
@@ -184,7 +181,7 @@ int do_mkdir(char *fname, mode_t mode)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
trim_trailing_slashes(fname);
|
||||
trim_trailing_slashes(fname);
|
||||
return mkdir(fname, mode);
|
||||
}
|
||||
|
||||
|
||||
58
t_stub.c
58
t_stub.c
@@ -1,35 +1,33 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/**
|
||||
* @file t_stub.c
|
||||
*
|
||||
/*
|
||||
* This file contains really simple implementations for rsync global
|
||||
* functions, so that module test harnesses can run standalone.
|
||||
**/
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
int modify_window = 0;
|
||||
int module_id = -1;
|
||||
int relative_paths = 0;
|
||||
int human_readable = 0;
|
||||
int module_dirlen = 0;
|
||||
mode_t orig_umask = 002;
|
||||
char *partial_dir;
|
||||
struct filter_list_struct server_filter_list;
|
||||
|
||||
@@ -68,16 +66,20 @@ struct filter_list_struct server_filter_list;
|
||||
|
||||
char *lp_name(UNUSED(int mod))
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL lp_use_chroot(UNUSED(int mod))
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *lp_path(UNUSED(int mod))
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *who_am_i(void)
|
||||
{
|
||||
return "tester";
|
||||
}
|
||||
|
||||
30
t_unsafe.c
30
t_unsafe.c
@@ -1,36 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* Test harness for unsafe_symlink(). Not linked into rsync itself.
|
||||
*
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Test harness for unsafe_symlink(). Not linked into @c rsync itself.
|
||||
*
|
||||
* Prints either "safe" or "unsafe" depending on the two arguments.
|
||||
* Always returns 0 unless something extraordinary happens.
|
||||
**/
|
||||
/* Prints either "safe" or "unsafe" depending on the two arguments.
|
||||
* Always returns 0 unless something extraordinary happens. */
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
int dry_run, read_only, list_only, verbose;
|
||||
int preserve_perms = 0;
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -41,6 +37,6 @@ main(int argc, char **argv)
|
||||
|
||||
printf("%s\n",
|
||||
unsafe_symlink(argv[1], argv[2]) ? "unsafe" : "safe");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,5 +38,35 @@ chmod +w "$checkdir" "$checkdir"/dir*
|
||||
|
||||
checkit "$RSYNC -avv --chmod ug-s,a+rX,D+w \"$fromdir/\" \"$todir/\"" "$checkdir" "$todir"
|
||||
|
||||
rm -r "$fromdir" "$checkdir" "$todir"
|
||||
makepath "$todir"
|
||||
makepath "$fromdir/foo"
|
||||
touch "$fromdir/bar"
|
||||
|
||||
checkit "$RSYNC -avv \"$fromdir/\" \"$checkdir/\"" "$fromdir" "$checkdir"
|
||||
chmod o+x "$fromdir"/bar
|
||||
|
||||
checkit "$RSYNC -avv --chmod=Fo-x \"$fromdir/\" \"$todir/\"" "$checkdir" "$todir"
|
||||
|
||||
# Tickle a bug in rsync 2.6.8: if you push a new directory with --perms off to
|
||||
# a daemon with an incoming chmod, the daemon pretends the directory is a file
|
||||
# for the purposes of the second application of the incoming chmod.
|
||||
|
||||
build_rsyncd_conf
|
||||
cat >>"$scratchdir/test-rsyncd.conf" <<EOF
|
||||
[test-incoming-chmod]
|
||||
path = $todir
|
||||
read only = no
|
||||
incoming chmod = Fo-x
|
||||
EOF
|
||||
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
rm -r "$todir"
|
||||
makepath "$todir"
|
||||
|
||||
checkit "$RSYNC -rtvv \"$fromdir/\" localhost::test-incoming-chmod/" "$checkdir" "$todir"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
|
||||
@@ -23,5 +23,19 @@ checkit "$RSYNC -avv --remove-sent-files \
|
||||
|
||||
diff -r "$chkdir/empty" "$fromdir"
|
||||
|
||||
# Make sure that "P" but not "-" per-dir merge-file filters take effect with
|
||||
# --delete-excluded.
|
||||
cat >"$todir/filters" <<EOF
|
||||
P foo
|
||||
- bar
|
||||
EOF
|
||||
touch "$todir/foo" "$todir/bar" "$todir/baz"
|
||||
|
||||
$RSYNC -r --exclude=baz --filter=': filters' --delete-excluded "$fromdir/" "$todir/"
|
||||
|
||||
test -f "$todir/foo" || test_fail "rsync deleted $todir/foo"
|
||||
test -f "$todir/bar" && test_fail "rsync did not delete $todir/bar"
|
||||
test -f "$todir/baz" && test_fail "rsync did not delete $todir/baz"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
|
||||
@@ -203,5 +203,13 @@ $RSYNC -av --delete-excluded --exclude='*' "$fromdir/" "$todir/"
|
||||
checkit "$RSYNC -avv -f dir-merge,-_.excl \
|
||||
\"$fromdir/\" \"$todir/\"" "$chkdir" "$todir"
|
||||
|
||||
relative_opts='--relative --chmod=Du+w --copy-unsafe-links'
|
||||
$RSYNC -av $relative_opts "$fromdir/foo" "$chkdir/"
|
||||
rm -rf "$chkdir$fromdir/foo/down"
|
||||
$RSYNC -av $relative_opts --existing --filter='-! */' "$fromdir/foo" "$chkdir/"
|
||||
|
||||
checkit "$RSYNC -avv $relative_opts --exclude=\"$fromdir/foo/down\" \
|
||||
\"$fromdir/foo\" \"$todir\"" "$chkdir$fromdir/foo" "$todir$fromdir/foo"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
|
||||
@@ -29,6 +29,7 @@ ln "$fromdir/foo/config1" "$fromdir/foo/extra"
|
||||
$RSYNC -iplr "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
cd+++++++ ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
>f+++++++ bar/baz/rsync
|
||||
@@ -130,11 +131,11 @@ EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
|
||||
|
||||
mv "$todir" "$lddir"
|
||||
$RSYNC -ivvplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
$RSYNC -ivvplrtH --copy-dest=../ld "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
cf bar/baz/rsync
|
||||
@@ -147,10 +148,10 @@ EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -iplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
$RSYNC -iplrtH --copy-dest=../ld "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
cd+++++++ foo/
|
||||
@@ -181,7 +182,7 @@ $RSYNC -ivvplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
hf bar/baz/rsync
|
||||
@@ -194,16 +195,27 @@ EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -iplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
$RSYNC -iplrtH --dry-run --link-dest=../ld "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
cd+++++++ foo/
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 12 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -iplrtH --link-dest=../ld "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
cd+++++++ ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
cd+++++++ foo/
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 13 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -vvplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
@@ -219,7 +231,7 @@ foo/config2 is uptodate
|
||||
"foo/extra" is a hard link
|
||||
foo/sym is uptodate
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 13 failed"
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -ivvplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
@@ -228,7 +240,7 @@ filter_outfile
|
||||
# TODO fix really-old problem when combining -H with --compare-dest:
|
||||
# missing output for foo/extra hard-link (and it might not be updated)!
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
.f bar/baz/rsync
|
||||
@@ -237,18 +249,18 @@ cd+++++++ foo/
|
||||
.f foo/config2
|
||||
.L foo/sym -> ../bar/baz/rsync
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -iplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
cd+++++++ foo/
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 16 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -vvplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
@@ -265,7 +277,7 @@ foo/config2 is uptodate
|
||||
"foo/extra" is a hard link
|
||||
foo/sym is uptodate
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 16 failed"
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 17 failed"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
|
||||
@@ -224,17 +224,19 @@ build_rsyncd_conf() {
|
||||
port=2612
|
||||
pidfile="$scratchdir/rsyncd.pid"
|
||||
logfile="$scratchdir/rsyncd.log"
|
||||
hostname=`uname -n`
|
||||
|
||||
cat >"$conf" <<EOF
|
||||
# rsyncd configuration file autogenerated by $0
|
||||
|
||||
pid file = $pidfile
|
||||
use chroot = no
|
||||
hosts allow = localhost, 127.0.0.1
|
||||
hosts allow = localhost 127.0.0.1 $hostname
|
||||
log file = $logfile
|
||||
log format = %i %h [%a] %m (%u) %l %f%L
|
||||
transfer logging = yes
|
||||
exclude = foobar.baz
|
||||
max verbosity = 9
|
||||
|
||||
uid = 0
|
||||
gid = 0
|
||||
|
||||
@@ -245,6 +247,10 @@ gid = 0
|
||||
[test-to]
|
||||
path = $todir
|
||||
read only = no
|
||||
|
||||
[test-scratch]
|
||||
path = $scratchdir
|
||||
read only = no
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
37
tls.c
37
tls.c
@@ -1,6 +1,8 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
/*
|
||||
* Trivial ls for comparing two directories after running an rsync.
|
||||
*
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2004, 2005 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
|
||||
@@ -11,17 +13,12 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file tls.c
|
||||
*
|
||||
* Trivial @c ls for comparing two directories after running an rsync.
|
||||
*
|
||||
* The problem with using the system's own ls is that some features
|
||||
/* The problem with using the system's own ls is that some features
|
||||
* have little quirks that make directories look different when for
|
||||
* our purposes they're the same -- for example, the BSD braindamage
|
||||
* about setting the mode on symlinks based on your current umask.
|
||||
@@ -34,9 +31,7 @@
|
||||
*
|
||||
* A key requirement for this program is that the output be "very
|
||||
* reproducible." So we mask away information that can accidentally
|
||||
* change.
|
||||
**/
|
||||
|
||||
* change. */
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -48,7 +43,6 @@ int read_only = 1;
|
||||
int list_only = 0;
|
||||
int preserve_perms = 0;
|
||||
|
||||
|
||||
static void failed(char const *what, char const *where)
|
||||
{
|
||||
fprintf(stderr, PROGRAM ": %s %s: %s\n",
|
||||
@@ -56,8 +50,6 @@ static void failed(char const *what, char const *where)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void list_file(const char *fname)
|
||||
{
|
||||
STRUCT_STAT buf;
|
||||
@@ -82,7 +74,7 @@ static void list_file(const char *fname)
|
||||
buf.st_mode &= ~0777;
|
||||
buf.st_mtime = (time_t)0;
|
||||
buf.st_uid = buf.st_gid = 0;
|
||||
strcpy(linkbuf, " -> ");
|
||||
strlcpy(linkbuf, " -> ", sizeof linkbuf);
|
||||
/* const-cast required for silly UNICOS headers */
|
||||
len = readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
|
||||
if (len == -1)
|
||||
@@ -99,16 +91,16 @@ static void list_file(const char *fname)
|
||||
if (buf.st_mtime) {
|
||||
mt = gmtime(&buf.st_mtime);
|
||||
|
||||
sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
snprintf(datebuf, sizeof datebuf,
|
||||
"%04d-%02d-%02d %02d:%02d:%02d",
|
||||
(int)mt->tm_year + 1900,
|
||||
(int)mt->tm_mon + 1,
|
||||
(int)mt->tm_mday,
|
||||
(int)mt->tm_hour,
|
||||
(int)mt->tm_min,
|
||||
(int)mt->tm_sec);
|
||||
} else {
|
||||
strcpy(datebuf, " ");
|
||||
}
|
||||
} else
|
||||
strlcpy(datebuf, " ", sizeof datebuf);
|
||||
|
||||
/* TODO: Perhaps escape special characters in fname? */
|
||||
|
||||
@@ -124,7 +116,6 @@ static void list_file(const char *fname)
|
||||
datebuf, fname, linkbuf);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
43
token.c
43
token.c
@@ -1,21 +1,24 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
* Routines used by the file-transfer code.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003, 2004, 2005 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "zlib/zlib.h"
|
||||
@@ -105,7 +108,6 @@ static int32 simple_recv_token(int f, char **data)
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/* non-compressing send token */
|
||||
static void simple_send_token(int f, int32 token, struct map_struct *buf,
|
||||
OFF_T offset, int32 n)
|
||||
@@ -124,7 +126,6 @@ static void simple_send_token(int f, int32 token, struct map_struct *buf,
|
||||
write_int(f, -(token+1));
|
||||
}
|
||||
|
||||
|
||||
/* Flag bytes in compressed stream are encoded as follows: */
|
||||
#define END_FLAG 0 /* that's all folks */
|
||||
#define TOKEN_LONG 0x20 /* followed by 32-bit token number */
|
||||
@@ -188,10 +189,8 @@ send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
|
||||
last_run_end = 0;
|
||||
run_start = token;
|
||||
flush_pending = 0;
|
||||
|
||||
} else if (last_token == -2) {
|
||||
run_start = token;
|
||||
|
||||
} else if (nb != 0 || token != last_token + 1
|
||||
|| token >= run_start + 65536) {
|
||||
/* output previous run */
|
||||
@@ -295,7 +294,6 @@ send_deflated_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* tells us what the receiver is in the middle of doing */
|
||||
static enum { r_init, r_idle, r_running, r_inflating, r_inflated } recv_state;
|
||||
|
||||
@@ -494,7 +492,6 @@ void send_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
|
||||
send_deflated_token(f, token, buf, offset, n, toklen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* receive a token or buffer from the other end. If the reurn value is >0 then
|
||||
* it is a data buffer of that length, and *data will point at the data.
|
||||
|
||||
24
trimslash.c
24
trimslash.c
@@ -1,19 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* Simple utility used only by the test harness.
|
||||
*
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
@@ -24,16 +27,11 @@ int read_only = 1;
|
||||
int list_only = 0;
|
||||
int preserve_perms = 0;
|
||||
|
||||
/**
|
||||
* @file trimslash.c
|
||||
*
|
||||
* Test harness; not linked into release.
|
||||
**/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr, "trimslash: needs at least one argument\n");
|
||||
return 1;
|
||||
|
||||
8
tweak_manpage
Executable file
8
tweak_manpage
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/perl -i -p
|
||||
s{(--\w[-\w]+)}{ $x = $1; $x =~ s/-/\\-/g; $x }eg;
|
||||
s/(?<!\\)-(['"\d*])/\\-$1/g;
|
||||
s#(['"(= /,])-(?!-)#$1\\-#g;
|
||||
s/(\\fB)-/$1\\-/g;
|
||||
s/(\[\w)-(\w\])/$1\\-$2/g;
|
||||
s{(\\f\(CW.*?\\fP)}{ $x = $1; $x =~ s/(?<!\\)-/\\-/g; $x }eg;
|
||||
s/(\.\w+)-/$1\\-/g;
|
||||
53
uidlist.c
53
uidlist.c
@@ -1,27 +1,28 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
* Handle the mapping of uid/gid and user/group names between systems.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2004, 2005, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* handle the mapping of uid/gid and user/group names between systems.
|
||||
If the source username/group does not exist on the target then use
|
||||
the numeric IDs. Never do any mapping for uid=0 or gid=0 as these
|
||||
are special.
|
||||
*/
|
||||
/* If the source username/group does not exist on the target then use
|
||||
* the numeric IDs. Never do any mapping for uid=0 or gid=0 as these
|
||||
* are special. */
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -125,12 +126,10 @@ static int is_in_group(gid_t gid)
|
||||
char *gidbuf = new_array(char, ngroups*21+32);
|
||||
if (!gidbuf)
|
||||
out_of_memory("is_in_group");
|
||||
sprintf(gidbuf, "process has %d gid%s: ",
|
||||
ngroups, ngroups == 1? "" : "s");
|
||||
pos = strlen(gidbuf);
|
||||
pos = snprintf(gidbuf, 32, "process has %d gid%s: ",
|
||||
ngroups, ngroups == 1? "" : "s");
|
||||
for (n = 0; n < ngroups; n++) {
|
||||
sprintf(gidbuf+pos, " %d", (int)gidset[n]);
|
||||
pos += strlen(gidbuf+pos);
|
||||
pos += snprintf(gidbuf+pos, 21, " %d", (int)gidset[n]);
|
||||
}
|
||||
rprintf(FINFO, "%s\n", gidbuf);
|
||||
free(gidbuf);
|
||||
|
||||
176
util.c
176
util.c
@@ -1,8 +1,10 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
/*
|
||||
* Utility routines used in rsync.
|
||||
*
|
||||
* Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003, 2004, 2005, 2006 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
|
||||
@@ -14,17 +16,11 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Utilities used in rsync
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
@@ -33,21 +29,23 @@ extern int module_id;
|
||||
extern int modify_window;
|
||||
extern int relative_paths;
|
||||
extern int human_readable;
|
||||
extern unsigned int module_dirlen;
|
||||
extern mode_t orig_umask;
|
||||
extern char *partial_dir;
|
||||
extern struct filter_list_struct server_filter_list;
|
||||
|
||||
int sanitize_paths = 0;
|
||||
|
||||
char curr_dir[MAXPATHLEN];
|
||||
unsigned int curr_dir_len;
|
||||
int curr_dir_depth; /* This is only set for a sanitizing daemon. */
|
||||
|
||||
|
||||
/**
|
||||
* Set a fd into nonblocking mode
|
||||
**/
|
||||
/* Set a fd into nonblocking mode. */
|
||||
void set_nonblocking(int fd)
|
||||
{
|
||||
int val;
|
||||
|
||||
if ((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
if ((val = fcntl(fd, F_GETFL)) == -1)
|
||||
return;
|
||||
if (!(val & NONBLOCK_FLAG)) {
|
||||
val |= NONBLOCK_FLAG;
|
||||
@@ -55,14 +53,12 @@ void set_nonblocking(int fd)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a fd into blocking mode
|
||||
**/
|
||||
/* Set a fd into blocking mode. */
|
||||
void set_blocking(int fd)
|
||||
{
|
||||
int val;
|
||||
|
||||
if ((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
if ((val = fcntl(fd, F_GETFL)) == -1)
|
||||
return;
|
||||
if (val & NONBLOCK_FLAG) {
|
||||
val &= ~NONBLOCK_FLAG;
|
||||
@@ -96,7 +92,7 @@ int fd_pair(int fd[2])
|
||||
|
||||
void print_child_argv(char **cmd)
|
||||
{
|
||||
rprintf(FINFO, "opening connection using ");
|
||||
rprintf(FCLIENT, "opening connection using ");
|
||||
for (; *cmd; cmd++) {
|
||||
/* Look for characters that ought to be quoted. This
|
||||
* is not a great quoting algorithm, but it's
|
||||
@@ -105,23 +101,23 @@ void print_child_argv(char **cmd)
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789"
|
||||
",.-_=+@/") != strlen(*cmd)) {
|
||||
rprintf(FINFO, "\"%s\" ", *cmd);
|
||||
rprintf(FCLIENT, "\"%s\" ", *cmd);
|
||||
} else {
|
||||
rprintf(FINFO, "%s ", *cmd);
|
||||
rprintf(FCLIENT, "%s ", *cmd);
|
||||
}
|
||||
}
|
||||
rprintf(FINFO, "\n");
|
||||
rprintf(FCLIENT, "\n");
|
||||
}
|
||||
|
||||
void out_of_memory(char *str)
|
||||
NORETURN void out_of_memory(char *str)
|
||||
{
|
||||
rprintf(FERROR, "ERROR: out of memory in %s\n", str);
|
||||
rprintf(FERROR, "ERROR: out of memory in %s [%s]\n", str, who_am_i());
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
|
||||
void overflow_exit(char *str)
|
||||
NORETURN void overflow_exit(char *str)
|
||||
{
|
||||
rprintf(FERROR, "ERROR: buffer overflow in %s\n", str);
|
||||
rprintf(FERROR, "ERROR: buffer overflow in %s [%s]\n", str, who_am_i());
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
|
||||
@@ -169,28 +165,43 @@ int set_modtime(char *fname, time_t modtime, mode_t mode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Create any necessary directories in fname. Unfortunately we don't know
|
||||
what perms to give the directory when this is called so we need to rely
|
||||
on the umask
|
||||
**/
|
||||
int create_directory_path(char *fname, int base_umask)
|
||||
/* This creates a new directory with default permissions. Since there
|
||||
* might be some directory-default permissions affecting this, we can't
|
||||
* force the permissions directly using the original umask and mkdir(). */
|
||||
int mkdir_defmode(char *fname)
|
||||
{
|
||||
int ret;
|
||||
|
||||
umask(orig_umask);
|
||||
ret = do_mkdir(fname, ACCESSPERMS);
|
||||
umask(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create any necessary directories in fname. Any missing directories are
|
||||
* created with default permissions. */
|
||||
int create_directory_path(char *fname)
|
||||
{
|
||||
char *p;
|
||||
int ret = 0;
|
||||
|
||||
while (*fname == '/')
|
||||
fname++;
|
||||
while (strncmp(fname, "./", 2) == 0)
|
||||
fname += 2;
|
||||
|
||||
umask(orig_umask);
|
||||
p = fname;
|
||||
while ((p = strchr(p,'/')) != NULL) {
|
||||
*p = 0;
|
||||
do_mkdir(fname, 0777 & ~base_umask);
|
||||
*p = '/';
|
||||
p++;
|
||||
*p = '\0';
|
||||
if (do_mkdir(fname, ACCESSPERMS) < 0 && errno != EEXIST)
|
||||
ret = -1;
|
||||
*p++ = '/';
|
||||
}
|
||||
return 0;
|
||||
umask(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,7 +359,7 @@ int robust_unlink(const char *fname)
|
||||
/* start where the last one left off to reduce chance of clashes */
|
||||
start = counter;
|
||||
do {
|
||||
sprintf(&path[pos], "%03d", counter);
|
||||
snprintf(&path[pos], MAX_RENAMES_DIGITS+1, "%03d", counter);
|
||||
if (++counter >= MAX_RENAMES)
|
||||
counter = 1;
|
||||
} while ((rc = access(path, 0)) == 0 && counter != start);
|
||||
@@ -533,7 +544,7 @@ static void glob_expand_one(char *s, char ***argv_ptr, int *argc_ptr,
|
||||
s = ".";
|
||||
|
||||
if (sanitize_paths)
|
||||
s = sanitize_path(NULL, s, "", 0);
|
||||
s = sanitize_path(NULL, s, "", 0, NULL);
|
||||
else
|
||||
s = strdup(s);
|
||||
|
||||
@@ -664,7 +675,7 @@ int count_dir_elements(const char *p)
|
||||
int cnt = 0, new_component = 1;
|
||||
while (*p) {
|
||||
if (*p++ == '/')
|
||||
new_component = 1;
|
||||
new_component = (*p != '.' || (p[1] != '/' && p[1] != '\0'));
|
||||
else if (new_component) {
|
||||
new_component = 0;
|
||||
cnt++;
|
||||
@@ -739,22 +750,29 @@ unsigned int clean_fname(char *name, BOOL collapse_dot_dot)
|
||||
* The rootdir string contains a value to use in place of a leading slash.
|
||||
* Specify NULL to get the default of lp_path(module_id).
|
||||
*
|
||||
* If depth is >= 0, it is a count of how many '..'s to allow at the start
|
||||
* of the path. Use -1 to allow unlimited depth.
|
||||
* The depth var is a count of how many '..'s to allow at the start of the
|
||||
* path. If symlink is set, combine its value with the "p" value to get
|
||||
* the target path, and **return NULL if any '..'s try to escape**.
|
||||
*
|
||||
* We also clean the path in a manner similar to clean_fname() but with a
|
||||
* few differences:
|
||||
* few differences:
|
||||
*
|
||||
* Turns multiple adjacent slashes into a single slash, gets rid of "." dir
|
||||
* elements (INCLUDING a trailing dot dir), PRESERVES a trailing slash, and
|
||||
* ALWAYS collapses ".." elements (except for those at the start of the
|
||||
* string up to "depth" deep). If the resulting name would be empty,
|
||||
* change it into a ".". */
|
||||
char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
|
||||
char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth,
|
||||
const char *symlink)
|
||||
{
|
||||
char *start, *sanp;
|
||||
char *start, *sanp, *save_dest = dest;
|
||||
int rlen = 0, leave_one_dotdir = relative_paths;
|
||||
|
||||
if (symlink && *symlink == '/') {
|
||||
p = symlink;
|
||||
symlink = "";
|
||||
}
|
||||
|
||||
if (dest != p) {
|
||||
int plen = strlen(p);
|
||||
if (*p == '/') {
|
||||
@@ -777,7 +795,18 @@ char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
|
||||
}
|
||||
|
||||
start = sanp = dest + rlen;
|
||||
while (*p != '\0') {
|
||||
while (1) {
|
||||
if (*p == '\0') {
|
||||
if (!symlink || !*symlink)
|
||||
break;
|
||||
while (sanp != start && sanp[-1] != '/') {
|
||||
/* strip last element */
|
||||
sanp--;
|
||||
}
|
||||
/* Append a relative symlink */
|
||||
p = symlink;
|
||||
symlink = "";
|
||||
}
|
||||
/* discard leading or extra slashes */
|
||||
if (*p == '/') {
|
||||
p++;
|
||||
@@ -799,6 +828,11 @@ char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
|
||||
if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
|
||||
/* ".." component followed by slash or end */
|
||||
if (depth <= 0 || sanp != start) {
|
||||
if (symlink && sanp == start) {
|
||||
if (!save_dest)
|
||||
free(dest);
|
||||
return NULL;
|
||||
}
|
||||
p += 2;
|
||||
if (sanp != start) {
|
||||
/* back up sanp one level */
|
||||
@@ -827,15 +861,10 @@ char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
|
||||
return dest;
|
||||
}
|
||||
|
||||
char curr_dir[MAXPATHLEN];
|
||||
unsigned int curr_dir_len;
|
||||
|
||||
/**
|
||||
* Like chdir(), but it keeps track of the current directory (in the
|
||||
/* Like chdir(), but it keeps track of the current directory (in the
|
||||
* global "curr_dir"), and ensures that the path size doesn't overflow.
|
||||
* Also cleans the path using the clean_fname() function.
|
||||
**/
|
||||
int push_dir(char *dir)
|
||||
* Also cleans the path using the clean_fname() function. */
|
||||
int push_dir(char *dir, int set_path_only)
|
||||
{
|
||||
static int initialised;
|
||||
unsigned int len;
|
||||
@@ -856,7 +885,7 @@ int push_dir(char *dir)
|
||||
if ((*dir == '/' ? len : curr_dir_len + 1 + len) >= sizeof curr_dir)
|
||||
return 0;
|
||||
|
||||
if (chdir(dir))
|
||||
if (!set_path_only && chdir(dir))
|
||||
return 0;
|
||||
|
||||
if (*dir == '/') {
|
||||
@@ -869,6 +898,11 @@ int push_dir(char *dir)
|
||||
}
|
||||
|
||||
curr_dir_len = clean_fname(curr_dir, 1);
|
||||
if (sanitize_paths) {
|
||||
if (module_dirlen > curr_dir_len)
|
||||
module_dirlen = curr_dir_len;
|
||||
curr_dir_depth = count_dir_elements(curr_dir + module_dirlen);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -885,6 +919,8 @@ int pop_dir(char *dir)
|
||||
curr_dir_len = strlcpy(curr_dir, dir, sizeof curr_dir);
|
||||
if (curr_dir_len >= sizeof curr_dir)
|
||||
curr_dir_len = sizeof curr_dir - 1;
|
||||
if (sanitize_paths)
|
||||
curr_dir_depth = count_dir_elements(curr_dir + module_dirlen);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -906,7 +942,7 @@ char *full_fname(const char *fn)
|
||||
if (*fn == '/')
|
||||
p1 = p2 = "";
|
||||
else {
|
||||
p1 = curr_dir;
|
||||
p1 = curr_dir + module_dirlen;
|
||||
for (p2 = p1; *p2 == '/'; p2++) {}
|
||||
if (*p2)
|
||||
p2 = "/";
|
||||
@@ -915,17 +951,11 @@ char *full_fname(const char *fn)
|
||||
m1 = " (in ";
|
||||
m2 = lp_name(module_id);
|
||||
m3 = ")";
|
||||
if (p1 == curr_dir) {
|
||||
if (!lp_use_chroot(module_id)) {
|
||||
char *p = lp_path(module_id);
|
||||
if (*p != '/' || p[1])
|
||||
p1 += strlen(p);
|
||||
}
|
||||
}
|
||||
} else
|
||||
m1 = m2 = m3 = "";
|
||||
|
||||
asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3);
|
||||
if (asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3) <= 0)
|
||||
out_of_memory("full_fname");
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -951,13 +981,11 @@ char *partial_dir_fname(const char *fname)
|
||||
if ((int)pathjoin(t, sz, partial_dir, fn) >= sz)
|
||||
return NULL;
|
||||
if (server_filter_list.head) {
|
||||
static int len;
|
||||
if (!len)
|
||||
len = strlen(partial_dir);
|
||||
t[len] = '\0';
|
||||
t = strrchr(partial_fname, '/');
|
||||
*t = '\0';
|
||||
if (check_filter(&server_filter_list, partial_fname, 1) < 0)
|
||||
return NULL;
|
||||
t[len] = '/';
|
||||
*t = '/';
|
||||
if (check_filter(&server_filter_list, partial_fname, 0) < 0)
|
||||
return NULL;
|
||||
}
|
||||
@@ -1087,7 +1115,7 @@ char *human_num(int64 num)
|
||||
units = 'K';
|
||||
}
|
||||
if (units) {
|
||||
sprintf(bufs[n], "%.2f%c", dnum, units);
|
||||
snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units);
|
||||
return bufs[n];
|
||||
}
|
||||
}
|
||||
|
||||
20
wildtest.c
20
wildtest.c
@@ -1,6 +1,22 @@
|
||||
/*
|
||||
** wildmatch test suite.
|
||||
*/
|
||||
* Test suite for the wildmatch code.
|
||||
*
|
||||
* Copyright (C) 2003, 2004, 2006 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*#define COMPARE_WITH_FNMATCH*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user