mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 23:05:52 -04:00
Compare commits
721 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
2857451ca2 | ||
|
|
2bc3835ee0 | ||
|
|
4f417448b4 | ||
|
|
503f163446 | ||
|
|
f17e769e28 | ||
|
|
f65e6a1276 | ||
|
|
4c248a3615 | ||
|
|
7794db7c0d | ||
|
|
3ca9e5d8ad | ||
|
|
5ca8a90c24 | ||
|
|
0679ac4ca9 | ||
|
|
20a0269782 | ||
|
|
a892d905bb | ||
|
|
bc880cb8d2 | ||
|
|
2243a9353e | ||
|
|
10f994a52a | ||
|
|
0f86c74eba | ||
|
|
c2b5407678 | ||
|
|
350879d8d1 | ||
|
|
a6a276027c | ||
|
|
45b79c8959 | ||
|
|
d0022dd908 | ||
|
|
e0f4a661be | ||
|
|
507433f6ca | ||
|
|
5974c662ff | ||
|
|
aa0bec8a52 | ||
|
|
2d2f71fb27 | ||
|
|
36f59b5802 | ||
|
|
7fc87d2daf | ||
|
|
3648ab3a24 | ||
|
|
7a9d183fc4 | ||
|
|
2a62f5ee19 | ||
|
|
f9cfaae952 | ||
|
|
bd4576fe4b | ||
|
|
4e194bf178 | ||
|
|
ef4e0d5e7e | ||
|
|
e6d8e70925 | ||
|
|
a6c5741c37 | ||
|
|
3ea7fc6ccf | ||
|
|
20926fbd63 | ||
|
|
2a3f3ba45d | ||
|
|
662127e6c7 | ||
|
|
0be05d6038 | ||
|
|
1f77038ef2 | ||
|
|
77ed253c73 | ||
|
|
b988781801 | ||
|
|
595251de24 | ||
|
|
c85631421d | ||
|
|
12c8cd02fc | ||
|
|
9656de5d13 | ||
|
|
9a31746b10 | ||
|
|
ceccbacc34 | ||
|
|
ff2e2ccfc1 | ||
|
|
12bda6f710 | ||
|
|
c53b6fd0ac | ||
|
|
b31243b472 | ||
|
|
c8d19f90a6 | ||
|
|
114bafe0d0 | ||
|
|
5ef8c5c6d4 | ||
|
|
9b499e9537 | ||
|
|
00f00f846b | ||
|
|
998113fedf | ||
|
|
ee5544112a | ||
|
|
7eaabd8fac | ||
|
|
4fc808dd98 | ||
|
|
7cfb250c93 | ||
|
|
47f480b619 | ||
|
|
fa9e950b1a | ||
|
|
49f4d850ce | ||
|
|
b3e15181ae | ||
|
|
aca5500aea | ||
|
|
427b6179b9 | ||
|
|
afa73c75b5 | ||
|
|
8261af7422 | ||
|
|
44e604f416 | ||
|
|
5173f99e68 | ||
|
|
8a3d4658eb | ||
|
|
6b43924848 | ||
|
|
eace352b39 | ||
|
|
fdbe8989fe | ||
|
|
18d7e9f46e | ||
|
|
c6fbd563d8 | ||
|
|
a5df33bb62 | ||
|
|
5cf4896050 | ||
|
|
2fb450bd99 | ||
|
|
4ea58045e2 | ||
|
|
29433538ff | ||
|
|
d382140904 | ||
|
|
b8e9c234e6 | ||
|
|
60ee01f517 | ||
|
|
2b28968dfb | ||
|
|
90b13cf606 | ||
|
|
d81894fc21 | ||
|
|
f5cbae9329 | ||
|
|
7a6653bc6c | ||
|
|
72f2d1b384 | ||
|
|
b66e31bf15 | ||
|
|
ea26c854af | ||
|
|
ef1f62807e | ||
|
|
d8aeda1e50 | ||
|
|
07efba8ec0 | ||
|
|
2959fe7447 | ||
|
|
4601589720 | ||
|
|
9f8225566e | ||
|
|
5e65c96705 | ||
|
|
a9d6e6fcac | ||
|
|
860dcf68ad | ||
|
|
812848323b | ||
|
|
344f9ba7fa | ||
|
|
2d5279ac9a | ||
|
|
fa3e4a0548 | ||
|
|
656c20715e | ||
|
|
a72885e042 | ||
|
|
b587adda1f | ||
|
|
50fd4832c2 | ||
|
|
c094d9320d | ||
|
|
aaccaa887d | ||
|
|
5481e42cd6 | ||
|
|
b3964d1d86 | ||
|
|
e35d9f2d6d | ||
|
|
4d16780366 | ||
|
|
1661fe9b0c | ||
|
|
63344ad4e1 | ||
|
|
90cf7d199f | ||
|
|
730df9d222 | ||
|
|
882d8c1cab | ||
|
|
17af842d2d | ||
|
|
bbe42182df | ||
|
|
81b096feef | ||
|
|
7627e92c54 | ||
|
|
f7bce90cf0 | ||
|
|
b33ce4c800 | ||
|
|
757287d8a5 | ||
|
|
3ed8eafccb | ||
|
|
d8b1c923ef | ||
|
|
4a4d2b1ba0 | ||
|
|
12fa790ea0 | ||
|
|
21955d9c92 | ||
|
|
a0d9819f8c | ||
|
|
a9af5d8eba | ||
|
|
65854cf91a | ||
|
|
9ec1ef2535 | ||
|
|
36119f6e2a | ||
|
|
e912bd4dfb | ||
|
|
c3ef136d41 | ||
|
|
8eda7a4bb8 | ||
|
|
78d146e866 | ||
|
|
77860bacd0 | ||
|
|
63cf5ae72c | ||
|
|
120cde9562 | ||
|
|
e6ffb966dd | ||
|
|
207522aef5 | ||
|
|
a1cc199b34 | ||
|
|
c22260706c | ||
|
|
d5782b52a2 | ||
|
|
85aecef6c3 | ||
|
|
876c993680 | ||
|
|
a272ff8c1b | ||
|
|
7402d58369 | ||
|
|
c0b134a445 | ||
|
|
a324d49bfc | ||
|
|
9c000f5e7b | ||
|
|
0e887ef29a | ||
|
|
fb72aaba48 | ||
|
|
a3869e9227 | ||
|
|
d671ccfc8e | ||
|
|
35bf8fa084 | ||
|
|
f7916cbf3f | ||
|
|
2b7dab686c | ||
|
|
a98cad00eb | ||
|
|
facdce2c1f | ||
|
|
34937987a6 | ||
|
|
831f06a5a5 | ||
|
|
5fe3c86f25 | ||
|
|
04f48837d1 | ||
|
|
f5b14759fb | ||
|
|
def97ff9a9 | ||
|
|
d38772e06f | ||
|
|
351f5e2f6c | ||
|
|
8778174936 | ||
|
|
e5f6a04d15 | ||
|
|
f8d47c1cb4 | ||
|
|
b5c6a6aeeb | ||
|
|
4e7d07c8d4 | ||
|
|
fc2dd77ec7 | ||
|
|
7b6fa00ff8 | ||
|
|
9ac3591366 | ||
|
|
6a819e02da | ||
|
|
4cff7c50db | ||
|
|
669302a172 | ||
|
|
c738605098 | ||
|
|
90cf838b18 | ||
|
|
67e4043e8c | ||
|
|
5e58e3f9cf | ||
|
|
49140b27c6 | ||
|
|
9cdadbb13a | ||
|
|
0ace7b2567 | ||
|
|
ccb8f5788b | ||
|
|
4e5baafedf | ||
|
|
0e82af2d27 | ||
|
|
535737bf39 | ||
|
|
6e6cc16399 | ||
|
|
bb0d8edfad | ||
|
|
ebec5eb689 | ||
|
|
5cb31dcf92 | ||
|
|
0ccffd7c80 | ||
|
|
57b66a2458 | ||
|
|
b8a39ed58a | ||
|
|
f5a910dd73 | ||
|
|
e16adcdff3 | ||
|
|
cf9b4794fd | ||
|
|
6d8c6bdbe5 | ||
|
|
8bbe41b53b | ||
|
|
ba30fb5c3c | ||
|
|
0938e8eee5 | ||
|
|
3b17384631 | ||
|
|
243c995f5f | ||
|
|
96b87581ff | ||
|
|
3de73827d7 | ||
|
|
458aeea4a6 | ||
|
|
14cbb64539 | ||
|
|
a9e4762634 | ||
|
|
487094a0d7 | ||
|
|
f608ebb106 | ||
|
|
87001ac6c2 | ||
|
|
ede1f0ebc9 | ||
|
|
b435d7174c | ||
|
|
2a59d2cc31 | ||
|
|
b8595e609a | ||
|
|
d37bc73a48 | ||
|
|
1902a7652f | ||
|
|
6ab423a5b6 | ||
|
|
c2be690cc6 | ||
|
|
f5a49d0e44 | ||
|
|
03e23e0730 | ||
|
|
eb598fac4f | ||
|
|
be0602ec3c | ||
|
|
6cbde57d88 | ||
|
|
5e4ff5f9c5 | ||
|
|
18e1289f27 | ||
|
|
99aaa6ca25 | ||
|
|
24172e4b2f | ||
|
|
beaf495400 | ||
|
|
79f48760f3 | ||
|
|
785abd4802 | ||
|
|
0ee6ca9800 | ||
|
|
7543020807 | ||
|
|
47b50b9bd0 | ||
|
|
45c49b52a4 | ||
|
|
0ee32c62d3 | ||
|
|
70e98a4348 | ||
|
|
fddf529df9 | ||
|
|
141c62659e | ||
|
|
61e16468f0 | ||
|
|
b74b3d538e | ||
|
|
d3db3eef1b | ||
|
|
90d5b12e72 | ||
|
|
955a3a3ded | ||
|
|
aec75b037b | ||
|
|
e5daa2731a | ||
|
|
390621a7ab | ||
|
|
478bb47c40 | ||
|
|
685517abd1 | ||
|
|
515afe7cf1 | ||
|
|
ec497df1a0 | ||
|
|
8e74463643 | ||
|
|
933d1dfd0f | ||
|
|
0fe987e226 | ||
|
|
770de8994e | ||
|
|
37cf7b4191 | ||
|
|
1a3ef40da9 | ||
|
|
0314302e9c | ||
|
|
9639c71842 | ||
|
|
d2da915cd0 | ||
|
|
e725abcf4e | ||
|
|
de01941274 | ||
|
|
d802ea54da | ||
|
|
c81a20fb7a | ||
|
|
6bf32edb8c | ||
|
|
4a50a2176e | ||
|
|
9e90555fd1 | ||
|
|
2067ec7342 | ||
|
|
c2c5682c0b | ||
|
|
4c72f27dd9 | ||
|
|
36d8d1a626 | ||
|
|
3447d61048 | ||
|
|
a3887c2644 | ||
|
|
8a1f3153b9 | ||
|
|
165dd4a636 | ||
|
|
541b23d144 | ||
|
|
7987ece7cc | ||
|
|
48224e4c43 | ||
|
|
6d4ecad122 | ||
|
|
1578919c37 | ||
|
|
10a1d6b4a0 | ||
|
|
2b7e12924d | ||
|
|
82f0c63e8a | ||
|
|
5d9530fe47 | ||
|
|
37f35d89d1 | ||
|
|
08c88178aa | ||
|
|
0fb2fc4a1d | ||
|
|
da2d13e3ce | ||
|
|
64318670a8 | ||
|
|
3c19f72c16 | ||
|
|
8938d67ef8 | ||
|
|
05724c07cf | ||
|
|
955c3145c3 | ||
|
|
8ea17b5098 | ||
|
|
b20fe0e6ac | ||
|
|
24787acd08 | ||
|
|
d71dad3bd3 | ||
|
|
889439c205 | ||
|
|
bee9df73c1 | ||
|
|
60613dc896 | ||
|
|
e175fb07f7 | ||
|
|
4a70af6f81 | ||
|
|
8f14cc496b | ||
|
|
3b4ecc6b80 | ||
|
|
a7e60f0c59 | ||
|
|
3d7cc5710d | ||
|
|
86fc7e6880 | ||
|
|
acee11fc60 | ||
|
|
b2e7c91313 | ||
|
|
97b7bff4d6 | ||
|
|
e16ca9ef31 | ||
|
|
b2e6caa01e | ||
|
|
2997e9f769 | ||
|
|
2374023982 | ||
|
|
902f03d101 | ||
|
|
cfe3978049 | ||
|
|
7752df41b7 | ||
|
|
d8b108c2a1 | ||
|
|
184dd27a18 | ||
|
|
0e5665d3ab | ||
|
|
ef3bb69ad8 | ||
|
|
45d41d08bd | ||
|
|
dd32e2c3d4 | ||
|
|
2b7e0f33a6 | ||
|
|
0582cdae8d | ||
|
|
9e8ea423e2 | ||
|
|
0c983c1fd4 | ||
|
|
3381ffa6ea | ||
|
|
3b15340966 | ||
|
|
91683c434b | ||
|
|
9e7530c414 | ||
|
|
8fd30fc43c | ||
|
|
b1b04fcdd4 | ||
|
|
56f0c976be | ||
|
|
9aacb4df0e | ||
|
|
0fdb1aa8ff | ||
|
|
bad0110609 | ||
|
|
3cc185a088 | ||
|
|
e8a8167ad9 | ||
|
|
854a1aad35 | ||
|
|
84e6d6fdcd | ||
|
|
f14a65d94c | ||
|
|
37439b36e7 | ||
|
|
c95ca2a228 | ||
|
|
97d8e7095f | ||
|
|
20c1926a01 | ||
|
|
d030233def | ||
|
|
35812ea1f9 | ||
|
|
d649b78920 | ||
|
|
7e43da819e | ||
|
|
40aaa571b4 | ||
|
|
470319d33b | ||
|
|
1db954e9bc | ||
|
|
d697314b42 | ||
|
|
59dd678603 | ||
|
|
02b5cb238b | ||
|
|
74de13d19c | ||
|
|
837d01dd5a | ||
|
|
926d86d1f9 | ||
|
|
aeb213ea0c | ||
|
|
7c6ea3d8c7 | ||
|
|
d409c6ac9c | ||
|
|
92f0b9d6ab | ||
|
|
2c8c8bbaad | ||
|
|
4fc8140a60 | ||
|
|
699f7024f1 | ||
|
|
ce0da32a9c | ||
|
|
82360c6b17 | ||
|
|
493568465b | ||
|
|
bf485d3d6b | ||
|
|
e90aab4982 | ||
|
|
550d4e2346 | ||
|
|
991daf008d | ||
|
|
505ada146c | ||
|
|
75c51953f1 | ||
|
|
8d6c1c4e97 | ||
|
|
10a1a3f511 | ||
|
|
40e6752fba | ||
|
|
dbefb6b4e4 | ||
|
|
6016841086 | ||
|
|
0047f535ef | ||
|
|
90eca40d27 | ||
|
|
0417c34e2d | ||
|
|
d64c2b226a | ||
|
|
868676dc15 | ||
|
|
e31058d41e | ||
|
|
ea8291d8f7 | ||
|
|
1348267518 | ||
|
|
f0323d68eb | ||
|
|
12a01be14f | ||
|
|
e0a18ce3f7 | ||
|
|
8ad5cea371 | ||
|
|
9059e0ac2f | ||
|
|
29fad7a3d8 | ||
|
|
02efda9f01 | ||
|
|
35a388b141 | ||
|
|
9a4a237ede | ||
|
|
5efbddbadb | ||
|
|
6a94c58b00 | ||
|
|
e3f8395360 | ||
|
|
f2b4c0840e | ||
|
|
08d82b84cb | ||
|
|
fbe57fdc95 | ||
|
|
92cdc39372 | ||
|
|
78be8e0fc9 | ||
|
|
a5b786d80f | ||
|
|
f853b777be | ||
|
|
fed1f3f4fe | ||
|
|
18cad44967 | ||
|
|
d17c9a4486 | ||
|
|
b6e22a47d3 | ||
|
|
ec69bdbd64 | ||
|
|
a8cbb57c9b | ||
|
|
b8cc35874e | ||
|
|
c3851185f3 | ||
|
|
e7ee91defc | ||
|
|
cfce9f6dc3 | ||
|
|
4afcb709a7 | ||
|
|
a912a980ec | ||
|
|
2c64b25827 | ||
|
|
38b9170c52 | ||
|
|
f40aa6fb07 | ||
|
|
b616493883 | ||
|
|
e86e2fa173 | ||
|
|
11bfaf6351 | ||
|
|
d37d1c44ff | ||
|
|
c89330313e | ||
|
|
c9dc1300ba | ||
|
|
53cf0b8bfb | ||
|
|
56961becc2 | ||
|
|
1dc42d123d | ||
|
|
d2ea5980ba | ||
|
|
15cf186b85 | ||
|
|
4fdb03a648 | ||
|
|
8f5b554f0b | ||
|
|
8cd3db27b6 | ||
|
|
273a7ed59f | ||
|
|
23deb0bcee | ||
|
|
7ea7bebf6b | ||
|
|
97894c6473 | ||
|
|
1f86fcf5dc | ||
|
|
bb9bdba4c9 | ||
|
|
5b9cc6953a | ||
|
|
33544bf422 | ||
|
|
20accf4d06 | ||
|
|
3fac51e21e | ||
|
|
d999d312c4 | ||
|
|
a22ca88565 | ||
|
|
9ec8bd87bb | ||
|
|
f11ece28ff | ||
|
|
f90f71498e | ||
|
|
32199c6b00 | ||
|
|
870dddc5eb | ||
|
|
9d0d18b590 | ||
|
|
bec617b934 | ||
|
|
c20936b88b | ||
|
|
0869881764 | ||
|
|
a840b5c736 | ||
|
|
2907884f94 | ||
|
|
754a080ffc | ||
|
|
94f20a9f45 | ||
|
|
6cc1198288 | ||
|
|
a015788d21 | ||
|
|
c8d3465726 | ||
|
|
00b9618460 | ||
|
|
d11f5c6e2b | ||
|
|
25007999df | ||
|
|
8ce6546310 | ||
|
|
151f59f155 | ||
|
|
89f2a4c231 | ||
|
|
496be30db6 | ||
|
|
cd426074e1 | ||
|
|
3f7bfac2a0 | ||
|
|
9425918d74 | ||
|
|
cc637fcc51 | ||
|
|
9db1743490 | ||
|
|
ba3542cfcb | ||
|
|
81f5b275db | ||
|
|
f3ee726894 | ||
|
|
b5be9e6c5f | ||
|
|
1e1cf68934 | ||
|
|
4a2744cee3 | ||
|
|
12febd804f | ||
|
|
687c6b14a0 | ||
|
|
a1f99493b3 | ||
|
|
9819f005b6 | ||
|
|
2a6793bf1f | ||
|
|
bf287ee946 | ||
|
|
b8b0668e85 | ||
|
|
092906933b | ||
|
|
e8432be95f | ||
|
|
6ff2f4ba67 | ||
|
|
309a5be873 | ||
|
|
26c87bb630 | ||
|
|
ea9b2add97 | ||
|
|
301569f081 | ||
|
|
b21456102a | ||
|
|
b8a47c9bc6 | ||
|
|
85fbfa10a8 | ||
|
|
555bc0e31a | ||
|
|
ef1233cbb3 | ||
|
|
1524815ed3 | ||
|
|
985af7035e | ||
|
|
b3181708f2 | ||
|
|
3f6c17cf14 | ||
|
|
2e5a7629c0 | ||
|
|
70318468df | ||
|
|
782d109121 | ||
|
|
30e7b0b28d | ||
|
|
910ee8c92e | ||
|
|
8af1bc9011 | ||
|
|
6a12f0d619 | ||
|
|
4f3be36e30 | ||
|
|
fc9d64c947 | ||
|
|
db10766ab2 | ||
|
|
a3dcb79085 | ||
|
|
20667b6d7f | ||
|
|
93e28fbd99 | ||
|
|
87a57a3072 | ||
|
|
bad1fa4476 | ||
|
|
8fe27e7631 | ||
|
|
a1c75ed05c | ||
|
|
e73ad2be54 | ||
|
|
59b0e7a82d | ||
|
|
b4fc3987f2 | ||
|
|
58418cb0c4 | ||
|
|
5794112ad0 | ||
|
|
f2b6fe44a6 | ||
|
|
215b444cae | ||
|
|
a45f581b2a | ||
|
|
dfdd71ecff |
23
INSTALL
23
INSTALL
@@ -1,4 +1,4 @@
|
||||
To build and install rsync
|
||||
To build and install rsync:
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
@@ -9,8 +9,15 @@ to ./configure. To see them, use:
|
||||
|
||||
$ ./configure --help
|
||||
|
||||
Configure tries to figure out if the local system uses group "nobody" or
|
||||
"nogroup" by looking in the /etc/group file. (This is only used for the
|
||||
default group of an rsync daemon, which attempts to run with "nobody"
|
||||
user and group permissions.) You can change the default user and group
|
||||
for the daemon by editing the NOBODY_USER and NOBODY_GROUP defines in
|
||||
config.h, or just override them in your /etc/rsyncd.conf file.
|
||||
|
||||
As of 2.4.7, rsync uses Eric Troan's popt option-parsing library. A
|
||||
cut-down copy of release 1.5 is included in the rsync distribution,
|
||||
cut-down copy of release 1.6.4 is included in the rsync distribution,
|
||||
and will be used if there is no popt library on your build host, or if
|
||||
the --with-included-popt option is passed to ./configure.
|
||||
|
||||
@@ -18,7 +25,6 @@ If you configure using --enable-maintainer-mode, then rsync will try
|
||||
to pop up an xterm on DISPLAY=:0 if it crashes. You might find this
|
||||
useful, but it should be turned off for production builds.
|
||||
|
||||
|
||||
RPM NOTES
|
||||
---------
|
||||
|
||||
@@ -37,16 +43,15 @@ fails:
|
||||
|
||||
Install gcc or HP's "ANSI/C Compiler".
|
||||
|
||||
|
||||
|
||||
MAC OSX NOTES
|
||||
-------------
|
||||
|
||||
Mac OS X (Darwin) seems to have an IPv6 stack, but it does not
|
||||
completely implement the "New Sockets" API.
|
||||
Some versions of Mac OS X (Darwin) seem to have an IPv6 stack, but do
|
||||
not completely implement the "New Sockets" API.
|
||||
|
||||
<http://www.ipv6.org/impl/mac.html> says that Apple do not support
|
||||
IPv6 yet. If your build fails, try again with --disable-ipv6.
|
||||
<http://www.ipv6.org/impl/mac.html> says that Apple started to support
|
||||
IPv6 in 10.2 (Jaguar). If your build fails, try again after running
|
||||
configure with --disable-ipv6.
|
||||
|
||||
IBM AIX NOTES
|
||||
-------------
|
||||
|
||||
36
Makefile.in
36
Makefile.in
@@ -28,13 +28,12 @@ VERSION=@VERSION@
|
||||
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h lib/pool_alloc.h
|
||||
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
|
||||
lib/permstring.o lib/pool_alloc.o @LIBOBJS@
|
||||
ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
|
||||
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
|
||||
zlib/zutil.o zlib/adler32.o
|
||||
ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
|
||||
zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
|
||||
OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
|
||||
main.o checksum.o match.o syscall.o log.o backup.o
|
||||
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
|
||||
fileio.o batch.o clientname.o
|
||||
fileio.o batch.o clientname.o chmod.o
|
||||
OBJS3=progress.o pipe.o
|
||||
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
|
||||
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
|
||||
@@ -91,29 +90,14 @@ T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o t_stub.o lib/compat.o lib/snprintf.o
|
||||
t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
|
||||
|
||||
gen: $(srcdir)/configure $(srcdir)/config.h.in proto man
|
||||
gen:
|
||||
cd $(srcdir) && $(MAKE) -f prepare-source.mak gen
|
||||
|
||||
man: $(srcdir)/rsync.1 $(srcdir)/rsyncd.conf.5
|
||||
|
||||
$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
|
||||
cd $(srcdir); autoconf
|
||||
|
||||
$(srcdir)/config.h.in: $(srcdir)/configure.in $(srcdir)/aclocal.m4
|
||||
cd $(srcdir); autoheader
|
||||
|
||||
$(srcdir)/rsync.1: $(srcdir)/rsync.yo
|
||||
yodl2man -o $(srcdir)/rsync.1 $(srcdir)/rsync.yo
|
||||
|
||||
$(srcdir)/rsyncd.conf.5: $(srcdir)/rsyncd.conf.yo
|
||||
yodl2man -o $(srcdir)/rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
|
||||
man:
|
||||
cd $(srcdir) && $(MAKE) -f prepare-source.mak man
|
||||
|
||||
proto:
|
||||
cat $(srcdir)/*.c $(srcdir)/lib/compat.c | awk -f $(srcdir)/mkproto.awk >$(srcdir)/proto.h.new
|
||||
if diff $(srcdir)/proto.h $(srcdir)/proto.h.new >/dev/null; then \
|
||||
rm $(srcdir)/proto.h.new; \
|
||||
else \
|
||||
mv $(srcdir)/proto.h.new $(srcdir)/proto.h; \
|
||||
fi
|
||||
cd $(srcdir) && $(MAKE) -f prepare-source.mak proto.h
|
||||
|
||||
clean: cleantests
|
||||
rm -f *~ $(OBJS) $(TLS_OBJ) $(CHECK_PROGS) $(CHECK_OBJS)
|
||||
@@ -161,8 +145,8 @@ check: all $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin=`pwd`/rsync$(EXEEXT) srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
|
||||
wildtest.o: wildtest.c lib/wildmatch.c rsync.h
|
||||
wildtest$(EXEEXT): wildtest.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o @BUILD_POPT@ $(LIBS)
|
||||
wildtest$(EXEEXT): wildtest.o lib/compat.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o lib/compat.o @BUILD_POPT@ $(LIBS)
|
||||
|
||||
# This does *not* depend on building or installing: you can use it to
|
||||
# check a version installed from a binary or some other source tree,
|
||||
|
||||
200
NEWS
200
NEWS
@@ -1,181 +1,67 @@
|
||||
NEWS for rsync 2.6.5 (1 Jun 2005)
|
||||
NEWS for rsync 2.6.8 (22 Apr 2006)
|
||||
Protocol: 29 (unchanged)
|
||||
Changes since 2.6.4:
|
||||
|
||||
OUTPUT CHANGES:
|
||||
|
||||
- Non-printable chars in filenames are now output using backslash-
|
||||
escaped characters rather than '?'s. Any non-printable character is
|
||||
output using 3 digits of octal (e.g. "\n" -> "\012"), and a backslash
|
||||
is now output as "\\". Rsync also uses your locale setting, which
|
||||
can make it treat fewer high-bit characters as non-printable.
|
||||
|
||||
- If rsync received an empty file-list when pulling files, it would
|
||||
output a "nothing to do" message and exit with a 0 (success) exit
|
||||
status, even if the remote rsync returned an error (it did not do
|
||||
this under the same conditions when pushing files). This was changed
|
||||
to make the pulling behavior the same as the pushing behavior: we
|
||||
now do the normal end-of-run outputting (depending on options) and
|
||||
exit with the appropriate exit status.
|
||||
Changes since 2.6.7:
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- A crash bug was fixed when a daemon had its "path" set to "/", did
|
||||
not have chroot enabled, and used some anchored excludes in the
|
||||
rsyncd.conf file.
|
||||
|
||||
- Fixed a bug in the transfer of a single file when -H is specified
|
||||
(rsync would either infinite loop or perhaps crash).
|
||||
|
||||
- Fixed a case where the generator might try (and fail) to tweak the
|
||||
write-permissions of a read-only directory in list-only mode (this
|
||||
only caused an annoying warning message).
|
||||
|
||||
- If --compare-dest or --link-dest uses a locally-copied file as the
|
||||
basis for an updated version, log this better when --verbose or -i
|
||||
- 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.
|
||||
|
||||
- Fixed the accidental disabling of --backup during the --delete-after
|
||||
processing.
|
||||
- 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).
|
||||
|
||||
- Restored the ability to use the --address option in client mode (in
|
||||
addition to its use in daemon mode).
|
||||
- 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.
|
||||
|
||||
- Make sure that some temporary progress information from the delete
|
||||
processing does not get left on the screen when it is followed by a
|
||||
newline.
|
||||
- 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).
|
||||
|
||||
- When --existing skips a directory with extra verbosity, refer to it
|
||||
as a "directory", not a "file".
|
||||
- If rsync cannot honor the --delete option, we output an error and exit
|
||||
instead of silently ignoring the option.
|
||||
|
||||
- When transferring a single file to a different-named file, any
|
||||
generator messages that are source-file related no longer refer to
|
||||
the file by the destination filename.
|
||||
- Fixed a bug in the --link-dest code that prevented special files (such as
|
||||
fifos) from being linked.
|
||||
|
||||
- Fixed a bug where hard-linking a group of files might fail if the
|
||||
generator hasn't created a needed destination directory yet.
|
||||
|
||||
- Fixed a bug where a hard-linked group of files that is newly-linked
|
||||
to a file in a --link-dest dir doesn't link the files from the rest
|
||||
of the cluster.
|
||||
|
||||
- When deleting files with the --one-file-system (-x) option set, rsync
|
||||
no longer tries to remove files from inside a mount-point on the
|
||||
receiving side. Also, we don't complain about being unable to remove
|
||||
the mount-point dir.
|
||||
|
||||
- Fixed a compatibility problem when using --cvs-ignore (-C) and
|
||||
sending files to an older rsync without using --delete.
|
||||
|
||||
- Make sure that a "- !" or "+ !" include/exclude pattern does not
|
||||
trigger the list-clearing action that is reserved for "!".
|
||||
|
||||
- Avoid a timeout in the generator when the sender/receiver aren't
|
||||
handling the generator's checksum output quickly enough.
|
||||
|
||||
- Fixed the omission of some directories in the delete processing when
|
||||
--relative (-R) was combined with a source path that had a trailing
|
||||
slash.
|
||||
|
||||
- Fixed a case where rsync would erroneously delete some files and then
|
||||
re-transfer them when the options --relative (-R) and --recursive
|
||||
(-r) were both enabled (along with --delete) and a source path had a
|
||||
trailing slash.
|
||||
|
||||
- Make sure that --max-size doesn't affect a device or a symlink.
|
||||
|
||||
- Make sure that a system with a really small MAXPATHLEN does not cause
|
||||
the buffers in readfd_unbuffered() to be too small to receive normal
|
||||
messages. (This mainly affected Cygwin.)
|
||||
|
||||
- If a source pathname ends with a filename of "..", treat it as if
|
||||
"../" had been specified (so that we don't copy files to the parent
|
||||
dir of the destination).
|
||||
|
||||
- If --delete is combined with a file-listing rsync command (i.e. no
|
||||
transfer is happening), avoid outputting a warning that we couldn't
|
||||
delete anything.
|
||||
|
||||
- If --stats is specified with --delete-after, ensure that all the
|
||||
"deleting" messages are output before the statistics.
|
||||
|
||||
- Improved one "if" in the deletion code that was only checking errno
|
||||
for ENOTEMPTY when it should have also been checking for EEXIST (for
|
||||
compatibility with OS variations).
|
||||
- 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:
|
||||
|
||||
- Added the --only-write-batch=FILE option that may be used (instead
|
||||
of --write-batch=FILE) to create a batch file without doing any
|
||||
actual updating of the destination. This allows you to divert all
|
||||
the file-updating data away from a slow data link (as long as you
|
||||
are pushing the data to the remote server when creating the batch).
|
||||
- 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 the generator is taking a long time to fill up its output buffer
|
||||
(e.g. if the transferred files are few, small, or missing), it now
|
||||
periodically flushes the output buffer so that the sender/receiver
|
||||
can get started on the files sooner rather than later.
|
||||
- When we output a fatal error, we now output the version of rsync in the
|
||||
message.
|
||||
|
||||
- Improved the keep-alive code to handle a long silence between the
|
||||
sender and the receiver that can occur when the sender is receiving
|
||||
the checksum data for a large file.
|
||||
- Improved the documentation for the --owner and --group options.
|
||||
|
||||
- Improved the auth-errors that are logged by the daemon to include
|
||||
some information on why the authorization failed: wrong user,
|
||||
password mismatch, etc. (The client-visible message is unchanged!)
|
||||
- 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.
|
||||
|
||||
- Improved the client's handling of an "@ERROR" from a daemon so that
|
||||
it does not complain about an unexpectedly closed socket (since we
|
||||
really did expect the socket to close).
|
||||
- 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.
|
||||
|
||||
- If the daemon can't open the log-file specified in rsyncd.conf, fall
|
||||
back to using syslog and log an appropriate warning. This is better
|
||||
than what was typically a totally silent (and fatal) failure (since a
|
||||
daemon is not usually run with the --no-detach option that was
|
||||
necessary to see the error on stderr).
|
||||
DEVELOPER RELATED:
|
||||
|
||||
- The man pages now consistently refer to an rsync daemon as a "daemon"
|
||||
instead of a "server" (to distinguish it from the server process in a
|
||||
non-daemon transfer).
|
||||
- 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.
|
||||
|
||||
- Made a small change to the rrsync script (restricted rsync -- in the
|
||||
support dir) to make a read-only server reject all --remove-* options
|
||||
when sending files (to future-proof it against the possibility of
|
||||
other similar options being added at some point).
|
||||
- Removed two unused configure checks and two related (also unused)
|
||||
compatibility functions.
|
||||
|
||||
INTERNAL:
|
||||
- The xattrs.diff patch received a security fix that prevents a potential
|
||||
buffer overflow in the receive_xattr() code.
|
||||
|
||||
- Rsync now calls setlocale(LC_CTYPE, ""). This enables isprint() to
|
||||
better discern which filename characters need to be escaped in
|
||||
messages (which should result in fewer escaped characters in some
|
||||
locales).
|
||||
- The acls.diff patch has been improved quite a bit, with more to come.
|
||||
|
||||
- Improved the naming of the log-file open/reopen/close functions.
|
||||
|
||||
- Removed some protocol-compatibility code that was only needed to help
|
||||
someone running a pre-release of 2.6.4.
|
||||
|
||||
BUILD CHANGES:
|
||||
|
||||
- Added configure option "--disable-locale" to disable any use of
|
||||
setlocale() in the binary.
|
||||
|
||||
- Fixed a bug in the SUPPORT{,_HARD}_LINKS #defines which prevented
|
||||
rsync from being built without symlink or hard-link support.
|
||||
|
||||
- Only #define HAVE_REMSH if it is going to be set to 1.
|
||||
|
||||
- Configure now disables the use of mkstemp() under HP-UX (since they
|
||||
refuse to fix its broken handling of large files).
|
||||
|
||||
- Configure now explicitly checks for the lseek64() function so that
|
||||
the code can use HAVE_LSEEK64 instead of inferring lseek64()'s
|
||||
presence based on the presence of the off64_t type.
|
||||
|
||||
- Configure no longer mentions the change in the default remote-shell
|
||||
(from rsh to ssh) that occurred for the 2.6.0 release.
|
||||
|
||||
- Some minor enhancements to the test scripts.
|
||||
|
||||
- Added a few new *.diff files to the patches dir, including a patch
|
||||
that enables the optional copying of extended attributes.
|
||||
- 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).
|
||||
|
||||
592
OLDNEWS
592
OLDNEWS
@@ -1,3 +1,573 @@
|
||||
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:
|
||||
|
||||
SECURITY FIXES:
|
||||
|
||||
- The zlib code was upgraded to version 1.2.3 in order to make it more
|
||||
secure. While the widely-publicized security problem in zlib 1.2.2 did
|
||||
not affect rsync, another security problem surfaced that affects rsync's
|
||||
zlib 1.1.4.
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- The setting of flist->high in clean_flist() was wrong for an empty list.
|
||||
This could cause flist_find() to crash in certain rare circumstances
|
||||
(e.g. if just the right directory setup was around when --fuzzy was
|
||||
combined with --link-dest).
|
||||
|
||||
- The outputting of hard-linked files when verbosity was > 1 was not right:
|
||||
(1) Without -i it would output the name of each hard-linked file as
|
||||
though it had been changed; it now outputs a "is hard linked" message for
|
||||
the file. (2) With -i it would output all dots for the unchanged
|
||||
attributes of a hard-link; it now changes those dots to spaces, as is
|
||||
done for other totally unchanged items.
|
||||
|
||||
- When backing up a changed symlink or device, get rid of any old backup
|
||||
item so that we don't get an "already exists" error.
|
||||
|
||||
- A couple places that were comparing a local and a remote modification-
|
||||
time were not honoring the --modify-window option.
|
||||
|
||||
- Fixed a bug where the 'p' (permissions) itemized-changes flag might get
|
||||
set too often (if some non-significant mode bits differed).
|
||||
|
||||
- Fixed a really old, minor bug that could cause rsync to warn about being
|
||||
unable to mkdir() a path that ends in "/." because it just created the
|
||||
directory (required --relative, --no-implied-dirs, a source path that
|
||||
ended in either a trailing slash or a trailing "/.", and a non-existing
|
||||
destination dir to tickle the bug in a recent version).
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
- Made the "max verbosity" setting in the rsyncd.conf file settable on a
|
||||
per-module basis (which now matches the documentation).
|
||||
|
||||
- The support/rrsync script has been upgraded to verify the args of options
|
||||
that take args (instead of rejecting any such options). The script was
|
||||
also changed to try to be more secure and to fix a problem in the parsing
|
||||
of a pull operation that has multiple sources.
|
||||
|
||||
- Improved the documentation that explains the difference between a
|
||||
normal daemon transfer and a daemon-over remote-shell transfer.
|
||||
|
||||
- Some of the diffs supplied in the patches dir were fixed and/or
|
||||
improved.
|
||||
|
||||
BUILD CHANGES:
|
||||
|
||||
- Made configure define NOBODY_USER (currently hard-wired to "nobody") and
|
||||
NOBODY_GROUP (set to either "nobody" or "nogroup" depending on what we
|
||||
find in the /etc/group file).
|
||||
|
||||
- Added a test to the test suite, itemized.test, that tests the output of
|
||||
-i (log-format w/%i) and some double-verbose messages.
|
||||
|
||||
|
||||
NEWS for rsync 2.6.5 (1 Jun 2005)
|
||||
Protocol: 29 (unchanged)
|
||||
Changes since 2.6.4:
|
||||
|
||||
OUTPUT CHANGES:
|
||||
|
||||
- Non-printable chars in filenames are now output using backslash-
|
||||
escaped characters rather than '?'s. Any non-printable character is
|
||||
output using 3 digits of octal (e.g. "\n" -> "\012"), and a backslash
|
||||
is now output as "\\". Rsync also uses your locale setting, which
|
||||
can make it treat fewer high-bit characters as non-printable.
|
||||
|
||||
- If rsync received an empty file-list when pulling files, it would
|
||||
output a "nothing to do" message and exit with a 0 (success) exit
|
||||
status, even if the remote rsync returned an error (it did not do
|
||||
this under the same conditions when pushing files). This was changed
|
||||
to make the pulling behavior the same as the pushing behavior: we
|
||||
now do the normal end-of-run outputting (depending on options) and
|
||||
exit with the appropriate exit status.
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- A crash bug was fixed when a daemon had its "path" set to "/", did
|
||||
not have chroot enabled, and used some anchored excludes in the
|
||||
rsyncd.conf file.
|
||||
|
||||
- Fixed a bug in the transfer of a single file when -H is specified
|
||||
(rsync would either infinite loop or perhaps crash).
|
||||
|
||||
- Fixed a case where the generator might try (and fail) to tweak the
|
||||
write-permissions of a read-only directory in list-only mode (this
|
||||
only caused an annoying warning message).
|
||||
|
||||
- If --compare-dest or --link-dest uses a locally-copied file as the
|
||||
basis for an updated version, log this better when --verbose or -i
|
||||
is in effect.
|
||||
|
||||
- Fixed the accidental disabling of --backup during the --delete-after
|
||||
processing.
|
||||
|
||||
- Restored the ability to use the --address option in client mode (in
|
||||
addition to its use in daemon mode).
|
||||
|
||||
- Make sure that some temporary progress information from the delete
|
||||
processing does not get left on the screen when it is followed by a
|
||||
newline.
|
||||
|
||||
- When --existing skips a directory with extra verbosity, refer to it
|
||||
as a "directory", not a "file".
|
||||
|
||||
- When transferring a single file to a different-named file, any
|
||||
generator messages that are source-file related no longer refer to
|
||||
the file by the destination filename.
|
||||
|
||||
- Fixed a bug where hard-linking a group of files might fail if the
|
||||
generator hasn't created a needed destination directory yet.
|
||||
|
||||
- Fixed a bug where a hard-linked group of files that is newly-linked
|
||||
to a file in a --link-dest dir doesn't link the files from the rest
|
||||
of the cluster.
|
||||
|
||||
- When deleting files with the --one-file-system (-x) option set, rsync
|
||||
no longer tries to remove files from inside a mount-point on the
|
||||
receiving side. Also, we don't complain about being unable to remove
|
||||
the mount-point dir.
|
||||
|
||||
- Fixed a compatibility problem when using --cvs-ignore (-C) and
|
||||
sending files to an older rsync without using --delete.
|
||||
|
||||
- Make sure that a "- !" or "+ !" include/exclude pattern does not
|
||||
trigger the list-clearing action that is reserved for "!".
|
||||
|
||||
- Avoid a timeout in the generator when the sender/receiver aren't
|
||||
handling the generator's checksum output quickly enough.
|
||||
|
||||
- Fixed the omission of some directories in the delete processing when
|
||||
--relative (-R) was combined with a source path that had a trailing
|
||||
slash.
|
||||
|
||||
- Fixed a case where rsync would erroneously delete some files and then
|
||||
re-transfer them when the options --relative (-R) and --recursive
|
||||
(-r) were both enabled (along with --delete) and a source path had a
|
||||
trailing slash.
|
||||
|
||||
- Make sure that --max-size doesn't affect a device or a symlink.
|
||||
|
||||
- Make sure that a system with a really small MAXPATHLEN does not cause
|
||||
the buffers in readfd_unbuffered() to be too small to receive normal
|
||||
messages. (This mainly affected Cygwin.)
|
||||
|
||||
- If a source pathname ends with a filename of "..", treat it as if
|
||||
"../" had been specified (so that we don't copy files to the parent
|
||||
dir of the destination).
|
||||
|
||||
- If --delete is combined with a file-listing rsync command (i.e. no
|
||||
transfer is happening), avoid outputting a warning that we couldn't
|
||||
delete anything.
|
||||
|
||||
- If --stats is specified with --delete-after, ensure that all the
|
||||
"deleting" messages are output before the statistics.
|
||||
|
||||
- Improved one "if" in the deletion code that was only checking errno
|
||||
for ENOTEMPTY when it should have also been checking for EEXIST (for
|
||||
compatibility with OS variations).
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
- Added the --only-write-batch=FILE option that may be used (instead
|
||||
of --write-batch=FILE) to create a batch file without doing any
|
||||
actual updating of the destination. This allows you to divert all
|
||||
the file-updating data away from a slow data link (as long as you
|
||||
are pushing the data to the remote server when creating the batch).
|
||||
|
||||
- When the generator is taking a long time to fill up its output buffer
|
||||
(e.g. if the transferred files are few, small, or missing), it now
|
||||
periodically flushes the output buffer so that the sender/receiver
|
||||
can get started on the files sooner rather than later.
|
||||
|
||||
- Improved the keep-alive code to handle a long silence between the
|
||||
sender and the receiver that can occur when the sender is receiving
|
||||
the checksum data for a large file.
|
||||
|
||||
- Improved the auth-errors that are logged by the daemon to include
|
||||
some information on why the authorization failed: wrong user,
|
||||
password mismatch, etc. (The client-visible message is unchanged!)
|
||||
|
||||
- Improved the client's handling of an "@ERROR" from a daemon so that
|
||||
it does not complain about an unexpectedly closed socket (since we
|
||||
really did expect the socket to close).
|
||||
|
||||
- If the daemon can't open the log-file specified in rsyncd.conf, fall
|
||||
back to using syslog and log an appropriate warning. This is better
|
||||
than what was typically a totally silent (and fatal) failure (since a
|
||||
daemon is not usually run with the --no-detach option that was
|
||||
necessary to see the error on stderr).
|
||||
|
||||
- The man pages now consistently refer to an rsync daemon as a "daemon"
|
||||
instead of a "server" (to distinguish it from the server process in a
|
||||
non-daemon transfer).
|
||||
|
||||
- Made a small change to the rrsync script (restricted rsync -- in the
|
||||
support dir) to make a read-only server reject all --remove-* options
|
||||
when sending files (to future-proof it against the possibility of
|
||||
other similar options being added at some point).
|
||||
|
||||
INTERNAL:
|
||||
|
||||
- Rsync now calls setlocale(LC_CTYPE, ""). This enables isprint() to
|
||||
better discern which filename characters need to be escaped in
|
||||
messages (which should result in fewer escaped characters in some
|
||||
locales).
|
||||
|
||||
- Improved the naming of the log-file open/reopen/close functions.
|
||||
|
||||
- Removed some protocol-compatibility code that was only needed to help
|
||||
someone running a pre-release of 2.6.4.
|
||||
|
||||
BUILD CHANGES:
|
||||
|
||||
- Added configure option "--disable-locale" to disable any use of
|
||||
setlocale() in the binary.
|
||||
|
||||
- Fixed a bug in the SUPPORT{,_HARD}_LINKS #defines which prevented
|
||||
rsync from being built without symlink or hard-link support.
|
||||
|
||||
- Only #define HAVE_REMSH if it is going to be set to 1.
|
||||
|
||||
- Configure now disables the use of mkstemp() under HP-UX (since they
|
||||
refuse to fix its broken handling of large files).
|
||||
|
||||
- Configure now explicitly checks for the lseek64() function so that
|
||||
the code can use HAVE_LSEEK64 instead of inferring lseek64()'s
|
||||
presence based on the presence of the off64_t type.
|
||||
|
||||
- Configure no longer mentions the change in the default remote-shell
|
||||
(from rsh to ssh) that occurred for the 2.6.0 release.
|
||||
|
||||
- Some minor enhancements to the test scripts.
|
||||
|
||||
- Added a few new *.diff files to the patches dir, including a patch
|
||||
that enables the optional copying of extended attributes.
|
||||
|
||||
|
||||
NEWS for rsync 2.6.4 (30 March 2005)
|
||||
Protocol: 29 (changed)
|
||||
Changes since 2.6.3:
|
||||
@@ -45,7 +615,7 @@ Changes since 2.6.3:
|
||||
|
||||
- An OS that has a binary mode for its files (such as cygwin) needed
|
||||
setmode(fd, O_BINARY) called on the temp-file we opened with
|
||||
mkstemp(). (Fix derived from the cygwin's 2.6.3 rsync package.)
|
||||
mkstemp(). (Fix derived from cygwin's 2.6.3 rsync package.)
|
||||
|
||||
- Fixed a potential hang when verbosity is high, the client side is
|
||||
the sender, and the file-list is large.
|
||||
@@ -110,9 +680,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
|
||||
@@ -389,6 +961,8 @@ Changes since 2.6.3:
|
||||
- Handle an operating system that use mkdev() in place of makedev().
|
||||
|
||||
- Improved configure to better handle cross-compiling.
|
||||
|
||||
|
||||
NEWS for rsync 2.6.3 (30 Sep 2004)
|
||||
Protocol: 28 (unchanged)
|
||||
Changes since 2.6.2:
|
||||
@@ -517,6 +1091,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
|
||||
@@ -730,7 +1306,7 @@ Changes since 2.6.0:
|
||||
- We now reset the "new data has been sent" flag at the start of
|
||||
each file we send. This makes sure that an interrupted transfer
|
||||
with the --partial option set doesn't keep a shorter temp file
|
||||
than the current basis file when no new data has been transfered
|
||||
than the current basis file when no new data has been transferred
|
||||
over the wire for that file.
|
||||
|
||||
- Fixed a byte-order problem in --batch-mode on big-endian machines.
|
||||
@@ -783,6 +1359,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
|
||||
@@ -1434,6 +2013,9 @@ Changes since 2.4.6:
|
||||
|
||||
Partial Protocol History
|
||||
RELEASE DATE VER. DATE OF COMMIT* PROTOCOL
|
||||
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
|
||||
|
||||
120
TODO
120
TODO
@@ -1,22 +1,17 @@
|
||||
-*- indented-text -*-
|
||||
|
||||
BUGS ---------------------------------------------------------------
|
||||
Do not rely on having a group called "nobody"
|
||||
|
||||
FEATURES ------------------------------------------------------------
|
||||
Use chroot only if supported
|
||||
Allow supplementary groups in rsyncd.conf 2002/04/09
|
||||
Handling IPv6 on old machines
|
||||
Other IPv6 stuff:
|
||||
Other IPv6 stuff
|
||||
Add ACL support 2001/12/02
|
||||
Lazy directory creation
|
||||
proxy authentication 2002/01/23
|
||||
SOCKS 2002/01/23
|
||||
FAT support
|
||||
Allow forcing arbitrary permissions 2002/03/12
|
||||
--diff david.e.sewell 2002/03/15
|
||||
Add daemon --no-fork option
|
||||
Create more granular verbosity jw 2003/05/15
|
||||
Create more granular verbosity 2003/05/15
|
||||
|
||||
DOCUMENTATION --------------------------------------------------------
|
||||
Keep list of open issues and todos on the web site
|
||||
@@ -25,22 +20,19 @@ Perhaps redo manual as SGML
|
||||
LOGGING --------------------------------------------------------------
|
||||
Memory accounting
|
||||
Improve error messages
|
||||
Better statistics: Rasmus 2002/03/08
|
||||
Better statistics Rasmus 2002/03/08
|
||||
Perhaps flush stdout like syslog
|
||||
Log deamon sessions that just list modules
|
||||
Log child death on signal
|
||||
Log errors with function that reports process of origin
|
||||
verbose output David Stein 2001/12/20
|
||||
internationalization
|
||||
|
||||
DEVELOPMENT --------------------------------------------------------
|
||||
Handling duplicate names
|
||||
Use generic zlib 2002/02/25
|
||||
TDB: 2002/03/12
|
||||
TDB 2002/03/12
|
||||
Splint 2002/03/12
|
||||
|
||||
PERFORMANCE ----------------------------------------------------------
|
||||
File list structure in memory
|
||||
Traverse just one directory at a time
|
||||
Allow skipping MD4 file_sum 2002/04/08
|
||||
Accelerate MD4
|
||||
@@ -52,8 +44,6 @@ Test on kernel source
|
||||
Test large files
|
||||
Create mutator program for testing
|
||||
Create configure option to enable dangerous tests
|
||||
If tests are skipped, say why.
|
||||
Test daemon feature to disallow particular options.
|
||||
Create pipe program for testing
|
||||
Create test makefile target for some tests
|
||||
|
||||
@@ -66,17 +56,6 @@ reverse rsync over HTTP Range
|
||||
|
||||
|
||||
|
||||
BUGS ---------------------------------------------------------------
|
||||
|
||||
|
||||
Do not rely on having a group called "nobody"
|
||||
|
||||
http://www.linuxbase.org/spec/refspecs/LSB_1.1.0/gLSB/usernames.html
|
||||
|
||||
On Debian it's "nogroup"
|
||||
|
||||
-- --
|
||||
|
||||
FEATURES ------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -133,7 +112,7 @@ Handling IPv6 on old machines
|
||||
-- --
|
||||
|
||||
|
||||
Other IPv6 stuff:
|
||||
Other IPv6 stuff
|
||||
|
||||
Implement suggestions from http://www.kame.net/newsletter/19980604/
|
||||
and ftp://ftp.iij.ad.jp/pub/RFC/rfc2553.txt
|
||||
@@ -159,15 +138,6 @@ Add ACL support 2001/12/02
|
||||
-- --
|
||||
|
||||
|
||||
Lazy directory creation
|
||||
|
||||
With the current common --include '*/' --exclude '*' pattern, people
|
||||
can end up with many empty directories. We might avoid this by
|
||||
lazily creating such directories.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
proxy authentication 2002/01/23
|
||||
|
||||
Allow RSYNC_PROXY to be http://user:pass@proxy.foo:3128/, and do
|
||||
@@ -199,35 +169,6 @@ FAT support
|
||||
-- --
|
||||
|
||||
|
||||
Allow forcing arbitrary permissions 2002/03/12
|
||||
|
||||
On 12 Mar 2002, Dave Dykstra <dwd@bell-labs.com> wrote:
|
||||
> If we would add an option to do that functionality, I
|
||||
> would vote for one that was more general which could mask
|
||||
> off any set of permission bits and possibly add any set of
|
||||
> bits. Perhaps a chmod-like syntax if it could be
|
||||
> implemented simply.
|
||||
|
||||
I think that would be good too. For example, people uploading files
|
||||
to a web server might like to say
|
||||
|
||||
rsync -avzP --chmod a+rX ./ sourcefrog.net:/home/www/sourcefrog/
|
||||
|
||||
Ideally the patch would implement as many of the gnu chmod semantics
|
||||
as possible. I think the mode parser should be a separate function
|
||||
that passes back something like (mask,set) description to the rest
|
||||
of the program. For bonus points there would be a test case for the
|
||||
parser.
|
||||
|
||||
Possibly also --chown
|
||||
|
||||
(Debian #23628)
|
||||
|
||||
NOTE: there is a patch that implements this in the "patches" subdir.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
--diff david.e.sewell 2002/03/15
|
||||
|
||||
Allow people to specify the diff command. (Might want to use wdiff,
|
||||
@@ -252,7 +193,7 @@ Add daemon --no-fork option
|
||||
-- --
|
||||
|
||||
|
||||
Create more granular verbosity jw 2003/05/15
|
||||
Create more granular verbosity 2003/05/15
|
||||
|
||||
Control output with the --report option.
|
||||
|
||||
@@ -322,14 +263,10 @@ Improve error messages
|
||||
our load? (Debian #28416) Probably fixed now, but a test case would
|
||||
be good.
|
||||
|
||||
When running as a daemon, some errors should both be returned to the
|
||||
user and logged. This will make interacting with a daemon less
|
||||
cryptic.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Better statistics: Rasmus 2002/03/08
|
||||
Better statistics Rasmus 2002/03/08
|
||||
|
||||
<Rasmus>
|
||||
hey, how about an rsync option that just gives you the
|
||||
@@ -355,14 +292,6 @@ Perhaps flush stdout like syslog
|
||||
-- --
|
||||
|
||||
|
||||
Log deamon sessions that just list modules
|
||||
|
||||
At the connections that just get a list of modules are not logged,
|
||||
but they should be.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Log child death on signal
|
||||
|
||||
If a child of the rsync daemon dies with a signal, we should notice
|
||||
@@ -371,15 +300,6 @@ Log child death on signal
|
||||
-- --
|
||||
|
||||
|
||||
Log errors with function that reports process of origin
|
||||
|
||||
Use a separate function for reporting errors; prefix it with
|
||||
"rsync:" or "rsync(remote)", or perhaps even "rsync(local
|
||||
generator): ".
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
verbose output David Stein 2001/12/20
|
||||
|
||||
At end of transfer, show how many files were or were not transferred
|
||||
@@ -445,7 +365,7 @@ Use generic zlib 2002/02/25
|
||||
-- --
|
||||
|
||||
|
||||
TDB: 2002/03/12
|
||||
TDB 2002/03/12
|
||||
|
||||
Rather than storing the file list in memory, store it in a TDB.
|
||||
|
||||
@@ -472,20 +392,6 @@ Splint 2002/03/12
|
||||
|
||||
PERFORMANCE ----------------------------------------------------------
|
||||
|
||||
File list structure in memory
|
||||
|
||||
Rather than one big array, perhaps have a tree in memory mirroring
|
||||
the directory tree.
|
||||
|
||||
This might make sorting much faster! (I'm not sure it's a big CPU
|
||||
problem, mind you.)
|
||||
|
||||
It might also reduce memory use in storing repeated directory names
|
||||
-- again I'm not sure this is a problem.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Traverse just one directory at a time
|
||||
|
||||
Traverse just one directory at a time. Tridge says it's possible.
|
||||
@@ -586,16 +492,6 @@ Create configure option to enable dangerous tests
|
||||
-- --
|
||||
|
||||
|
||||
If tests are skipped, say why.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Test daemon feature to disallow particular options.
|
||||
|
||||
-- --
|
||||
|
||||
|
||||
Create pipe program for testing
|
||||
|
||||
Create pipe program that makes slow/jerky connections for
|
||||
|
||||
2
access.c
2
access.c
@@ -208,7 +208,7 @@ static int match_address(char *addr, char *tok)
|
||||
|
||||
ret = match_binary(a, t, mask, addrlen);
|
||||
|
||||
out:
|
||||
out:
|
||||
freeaddrinfo(resa);
|
||||
freeaddrinfo(rest);
|
||||
return ret;
|
||||
|
||||
@@ -21,21 +21,18 @@
|
||||
#include "rsync.h"
|
||||
|
||||
extern char *password_file;
|
||||
extern int am_root;
|
||||
|
||||
/***************************************************************************
|
||||
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;
|
||||
@@ -49,6 +46,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. */
|
||||
@@ -70,7 +72,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,13 +92,13 @@ static int get_secret(int module, char *user, char *secret, int len)
|
||||
return 0;
|
||||
|
||||
if (do_stat(fname, &st) == -1) {
|
||||
rsyserr(FLOG, errno, "stat(%s)", safe_fname(fname));
|
||||
rsyserr(FLOG, errno, "stat(%s)", fname);
|
||||
ok = 0;
|
||||
} else if (lp_strict_modes(module)) {
|
||||
if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
|
||||
ok = 0;
|
||||
} else if (am_root && (st.st_uid != 0)) {
|
||||
} else if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
|
||||
ok = 0;
|
||||
}
|
||||
@@ -160,19 +162,19 @@ static char *getpassf(char *filename)
|
||||
|
||||
if ((fd = open(filename,O_RDONLY)) < 0) {
|
||||
rsyserr(FERROR, errno, "could not open password file \"%s\"",
|
||||
safe_fname(filename));
|
||||
filename);
|
||||
if (envpw)
|
||||
rprintf(FERROR, "falling back to RSYNC_PASSWORD environment variable.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (do_stat(filename, &st) == -1) {
|
||||
rsyserr(FERROR, errno, "stat(%s)", safe_fname(filename));
|
||||
rsyserr(FERROR, errno, "stat(%s)", filename);
|
||||
ok = 0;
|
||||
} else if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FERROR,"password file must not be other-accessible\n");
|
||||
ok = 0;
|
||||
} else if (am_root && st.st_uid != 0) {
|
||||
} else if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
rprintf(FERROR,"password file must be owned by root when running as root\n");
|
||||
ok = 0;
|
||||
}
|
||||
@@ -209,7 +211,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
|
||||
@@ -223,7 +225,7 @@ char *auth_server(int f_in, int f_out, int module, char *host, char *addr,
|
||||
{
|
||||
char *users = lp_auth_users(module);
|
||||
char challenge[MD4_SUM_LENGTH*2];
|
||||
char line[MAXPATHLEN];
|
||||
char line[BIGPATHBUFLEN];
|
||||
char secret[512];
|
||||
char pass2[MD4_SUM_LENGTH*2];
|
||||
char *tok, *pass;
|
||||
|
||||
72
backup.c
72
backup.c
@@ -21,7 +21,6 @@
|
||||
#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];
|
||||
@@ -30,9 +29,8 @@ extern char *backup_dir;
|
||||
|
||||
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 */
|
||||
@@ -65,8 +63,7 @@ static int make_simple_backup(char *fname)
|
||||
if (do_rename(fname, fnamebak) == 0) {
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO, "backed up %s to %s\n",
|
||||
safe_fname(fname),
|
||||
safe_fname(fnamebak));
|
||||
fname, fnamebak);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -81,7 +78,7 @@ static int make_simple_backup(char *fname)
|
||||
continue;
|
||||
|
||||
rsyserr(FERROR, rename_errno, "rename %s to backup %s",
|
||||
safe_fname(fname), safe_fname(fnamebak));
|
||||
fname, fnamebak);
|
||||
errno = rename_errno;
|
||||
return 0;
|
||||
}
|
||||
@@ -112,7 +109,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 +138,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;
|
||||
@@ -149,7 +146,7 @@ static int make_bak_dir(char *fullpath)
|
||||
}
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
failure:
|
||||
while (p != end) {
|
||||
*p = '/';
|
||||
p += strlen(p);
|
||||
@@ -160,8 +157,9 @@ failure:
|
||||
/* robustly move a file, creating new directory structures if necessary */
|
||||
static int robust_move(char *src, char *dst)
|
||||
{
|
||||
if (robust_rename(src, dst, 0755) < 0 && (errno != ENOENT
|
||||
|| make_bak_dir(dst) < 0 || robust_rename(src, dst, 0755) < 0))
|
||||
if (robust_rename(src, dst, NULL, 0755) < 0
|
||||
&& (errno != ENOENT || make_bak_dir(dst) < 0
|
||||
|| robust_rename(src, dst, NULL, 0755) < 0))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
@@ -181,25 +179,24 @@ static int keep_backup(char *fname)
|
||||
if (do_lstat(fname, &st) < 0)
|
||||
return 1;
|
||||
|
||||
if (!(file = make_file(fname, NULL, NO_FILTERS)))
|
||||
if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
|
||||
return 1; /* the file could have disappeared */
|
||||
|
||||
if (!(buf = get_backup_name(fname)))
|
||||
return 0;
|
||||
|
||||
/* Check to see if this is a device file, or link */
|
||||
if (IS_DEVICE(file->mode)) {
|
||||
if (am_root && preserve_devices) {
|
||||
if (do_mknod(buf, file->mode, file->u.rdev) < 0
|
||||
&& (errno != ENOENT || make_bak_dir(buf) < 0
|
||||
|| do_mknod(buf, file->mode, file->u.rdev) < 0)) {
|
||||
rsyserr(FERROR, errno, "mknod %s failed",
|
||||
full_fname(buf));
|
||||
} else if (verbose > 2) {
|
||||
rprintf(FINFO,
|
||||
"make_backup: DEVICE %s successful.\n",
|
||||
safe_fname(fname));
|
||||
}
|
||||
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|
||||
|| (preserve_specials && IS_SPECIAL(file->mode))) {
|
||||
do_unlink(buf);
|
||||
if (do_mknod(buf, file->mode, file->u.rdev) < 0
|
||||
&& (errno != ENOENT || make_bak_dir(buf) < 0
|
||||
|| do_mknod(buf, file->mode, file->u.rdev) < 0)) {
|
||||
rsyserr(FERROR, errno, "mknod %s failed",
|
||||
full_fname(buf));
|
||||
} else if (verbose > 2) {
|
||||
rprintf(FINFO, "make_backup: DEVICE %s successful.\n",
|
||||
fname);
|
||||
}
|
||||
kept = 1;
|
||||
do_unlink(fname);
|
||||
@@ -230,21 +227,24 @@ static int keep_backup(char *fname)
|
||||
full_fname(buf), file->u.link);
|
||||
}
|
||||
kept = 1;
|
||||
} else {
|
||||
do_unlink(buf);
|
||||
if (do_symlink(file->u.link, buf) < 0
|
||||
&& (errno != ENOENT || make_bak_dir(buf) < 0
|
||||
|| do_symlink(file->u.link, buf) < 0)) {
|
||||
rsyserr(FERROR, errno, "link %s -> \"%s\"",
|
||||
full_fname(buf),
|
||||
file->u.link);
|
||||
}
|
||||
do_unlink(fname);
|
||||
kept = 1;
|
||||
}
|
||||
if (do_symlink(file->u.link, buf) < 0
|
||||
&& (errno != ENOENT || make_bak_dir(buf) < 0
|
||||
|| do_symlink(file->u.link, buf) < 0)) {
|
||||
rsyserr(FERROR, errno, "link %s -> \"%s\"",
|
||||
full_fname(buf), safe_fname(file->u.link));
|
||||
}
|
||||
do_unlink(fname);
|
||||
kept = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!kept && !S_ISREG(file->mode)) {
|
||||
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
|
||||
safe_fname(fname));
|
||||
fname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -252,19 +252,19 @@ static int keep_backup(char *fname)
|
||||
if (!kept) {
|
||||
if (robust_move(fname, buf) != 0) {
|
||||
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
|
||||
full_fname(fname), safe_fname(buf));
|
||||
full_fname(fname), buf);
|
||||
} else if (st.st_nlink > 1) {
|
||||
/* If someone has hard-linked the file into the backup
|
||||
* dir, rename() might return success but do nothing! */
|
||||
robust_unlink(fname); /* Just in case... */
|
||||
}
|
||||
}
|
||||
set_perms(buf, file, NULL, 0);
|
||||
set_file_attrs(buf, file, NULL, 0);
|
||||
free(file);
|
||||
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO, "backed up %s to %s\n",
|
||||
safe_fname(fname), safe_fname(buf));
|
||||
fname, buf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
59
batch.c
59
batch.c
@@ -6,9 +6,9 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "zlib/zlib.h"
|
||||
#include <time.h>
|
||||
|
||||
extern int am_sender;
|
||||
extern int eol_nulls;
|
||||
extern int recurse;
|
||||
extern int xfer_dirs;
|
||||
@@ -19,11 +19,14 @@ extern int preserve_uid;
|
||||
extern int preserve_gid;
|
||||
extern int always_checksum;
|
||||
extern int do_compression;
|
||||
extern int def_compress_level;
|
||||
extern int protocol_version;
|
||||
extern char *batch_name;
|
||||
|
||||
extern struct filter_list_struct filter_list;
|
||||
|
||||
static int tweaked_compress_level;
|
||||
|
||||
static int *flag_ptr[] = {
|
||||
&recurse, /* 0 */
|
||||
&preserve_uid, /* 1 */
|
||||
@@ -33,7 +36,7 @@ static int *flag_ptr[] = {
|
||||
&preserve_hard_links, /* 5 */
|
||||
&always_checksum, /* 6 */
|
||||
&xfer_dirs, /* 7 (protocol 29) */
|
||||
&do_compression, /* 8 (protocol 29) */
|
||||
&tweaked_compress_level,/* 8 (protocol 29) */
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -54,6 +57,12 @@ void write_stream_flags(int fd)
|
||||
{
|
||||
int i, flags;
|
||||
|
||||
#if Z_DEFAULT_COMPRESSION == -1
|
||||
tweaked_compress_level = do_compression ? def_compress_level + 2 : 0;
|
||||
#else
|
||||
#error internal logic error! Fix def_compress_level logic above and below too!
|
||||
#endif
|
||||
|
||||
/* Start the batch file with a bitmap of data-stream-affecting
|
||||
* flags. */
|
||||
if (protocol_version < 29)
|
||||
@@ -88,6 +97,13 @@ void read_stream_flags(int fd)
|
||||
else if (xfer_dirs < 2)
|
||||
xfer_dirs = 0;
|
||||
}
|
||||
|
||||
if (tweaked_compress_level == 0 || tweaked_compress_level == 2)
|
||||
do_compression = 0;
|
||||
else {
|
||||
do_compression = 1;
|
||||
def_compress_level = tweaked_compress_level - 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_arg(int fd, char *arg)
|
||||
@@ -148,7 +164,7 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
|
||||
S_IRUSR | S_IWUSR | S_IEXEC);
|
||||
if (fd < 0) {
|
||||
rsyserr(FERROR, errno, "Batch file %s open error",
|
||||
safe_fname(filename));
|
||||
filename);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
@@ -194,42 +210,7 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
|
||||
write_filter_rules(fd);
|
||||
if (write(fd, "\n", 1) != 1 || close(fd) < 0) {
|
||||
rsyserr(FERROR, errno, "Batch file %s write error",
|
||||
safe_fname(filename));
|
||||
filename);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
}
|
||||
|
||||
void show_flist(int index, struct file_struct **fptr)
|
||||
{
|
||||
/* for debugging show_flist(flist->count, flist->files * */
|
||||
|
||||
int i;
|
||||
for (i = 0; i < index; i++) {
|
||||
rprintf(FINFO, "flist->flags=%#x\n", fptr[i]->flags);
|
||||
rprintf(FINFO, "flist->modtime=%#lx\n",
|
||||
(long unsigned) fptr[i]->modtime);
|
||||
rprintf(FINFO, "flist->length=%.0f\n",
|
||||
(double) fptr[i]->length);
|
||||
rprintf(FINFO, "flist->mode=%#o\n", (int) fptr[i]->mode);
|
||||
rprintf(FINFO, "flist->basename=%s\n",
|
||||
safe_fname(fptr[i]->basename));
|
||||
if (fptr[i]->dirname) {
|
||||
rprintf(FINFO, "flist->dirname=%s\n",
|
||||
safe_fname(fptr[i]->dirname));
|
||||
}
|
||||
if (am_sender && fptr[i]->dir.root) {
|
||||
rprintf(FINFO, "flist->dir.root=%s\n",
|
||||
safe_fname(fptr[i]->dir.root));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* for debugging */
|
||||
void show_argvs(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
rprintf(FINFO, "BATCH.C:show_argvs,argc=%d\n", argc);
|
||||
for (i = 0; i < argc; i++)
|
||||
rprintf(FINFO, "i=%d,argv[i]=%s\n", i, safe_fname(argv[i]));
|
||||
}
|
||||
|
||||
205
chmod.c
Normal file
205
chmod.c
Normal file
@@ -0,0 +1,205 @@
|
||||
#include "rsync.h"
|
||||
|
||||
extern mode_t orig_umask;
|
||||
|
||||
#define FLAG_X_KEEP (1<<0)
|
||||
#define FLAG_DIRS_ONLY (1<<1)
|
||||
#define FLAG_FILES_ONLY (1<<2)
|
||||
|
||||
struct chmod_mode_struct {
|
||||
struct chmod_mode_struct *next;
|
||||
int ModeAND, ModeOR;
|
||||
char flags;
|
||||
};
|
||||
|
||||
#define CHMOD_ADD 1
|
||||
#define CHMOD_SUB 2
|
||||
#define CHMOD_EQ 3
|
||||
|
||||
#define STATE_ERROR 0
|
||||
#define STATE_1ST_HALF 1
|
||||
#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 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;
|
||||
struct chmod_mode_struct *first_mode = NULL, *curr_mode = NULL,
|
||||
*prev_mode = NULL;
|
||||
|
||||
while (state != STATE_ERROR) {
|
||||
if (!*modestr || *modestr == ',') {
|
||||
int bits;
|
||||
|
||||
if (!op) {
|
||||
state = STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
prev_mode = curr_mode;
|
||||
curr_mode = new_array(struct chmod_mode_struct, 1);
|
||||
if (prev_mode)
|
||||
prev_mode->next = curr_mode;
|
||||
else
|
||||
first_mode = curr_mode;
|
||||
curr_mode->next = NULL;
|
||||
|
||||
if (where)
|
||||
bits = where * what;
|
||||
else {
|
||||
where = 0111;
|
||||
bits = (where * what) & ~orig_umask;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case CHMOD_ADD:
|
||||
curr_mode->ModeAND = CHMOD_BITS;
|
||||
curr_mode->ModeOR = bits + topoct;
|
||||
break;
|
||||
case CHMOD_SUB:
|
||||
curr_mode->ModeAND = CHMOD_BITS - bits - topoct;
|
||||
curr_mode->ModeOR = 0;
|
||||
break;
|
||||
case CHMOD_EQ:
|
||||
curr_mode->ModeAND = CHMOD_BITS - (where * 7) - (topoct ? topbits : 0);
|
||||
curr_mode->ModeOR = bits + topoct;
|
||||
break;
|
||||
}
|
||||
|
||||
curr_mode->flags = flags;
|
||||
|
||||
if (!*modestr)
|
||||
break;
|
||||
modestr++;
|
||||
|
||||
state = STATE_1ST_HALF;
|
||||
where = what = op = topoct = topbits = flags = 0;
|
||||
}
|
||||
|
||||
if (state != STATE_2ND_HALF) {
|
||||
switch (*modestr) {
|
||||
case 'D':
|
||||
if (flags & FLAG_FILES_ONLY)
|
||||
state = STATE_ERROR;
|
||||
flags |= FLAG_DIRS_ONLY;
|
||||
break;
|
||||
case 'F':
|
||||
if (flags & FLAG_DIRS_ONLY)
|
||||
state = STATE_ERROR;
|
||||
flags |= FLAG_FILES_ONLY;
|
||||
break;
|
||||
case 'u':
|
||||
where |= 0100;
|
||||
topbits |= 04000;
|
||||
break;
|
||||
case 'g':
|
||||
where |= 0010;
|
||||
topbits |= 02000;
|
||||
break;
|
||||
case 'o':
|
||||
where |= 0001;
|
||||
break;
|
||||
case 'a':
|
||||
where |= 0111;
|
||||
break;
|
||||
case '+':
|
||||
op = CHMOD_ADD;
|
||||
state = STATE_2ND_HALF;
|
||||
break;
|
||||
case '-':
|
||||
op = CHMOD_SUB;
|
||||
state = STATE_2ND_HALF;
|
||||
break;
|
||||
case '=':
|
||||
op = CHMOD_EQ;
|
||||
state = STATE_2ND_HALF;
|
||||
break;
|
||||
default:
|
||||
state = STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (*modestr) {
|
||||
case 'r':
|
||||
what |= 4;
|
||||
break;
|
||||
case 'w':
|
||||
what |= 2;
|
||||
break;
|
||||
case 'X':
|
||||
flags |= FLAG_X_KEEP;
|
||||
/* FALL THROUGH */
|
||||
case 'x':
|
||||
what |= 1;
|
||||
break;
|
||||
case 's':
|
||||
if (topbits)
|
||||
topoct |= topbits;
|
||||
else
|
||||
topoct = 04000;
|
||||
break;
|
||||
case 't':
|
||||
topoct |= 01000;
|
||||
break;
|
||||
default:
|
||||
state = STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
modestr++;
|
||||
}
|
||||
|
||||
if (state == STATE_ERROR) {
|
||||
free_chmod_mode(first_mode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(curr_mode = *root_mode_ptr))
|
||||
*root_mode_ptr = first_mode;
|
||||
else {
|
||||
while (curr_mode->next)
|
||||
curr_mode = curr_mode->next;
|
||||
curr_mode->next = first_mode;
|
||||
}
|
||||
|
||||
return first_mode;
|
||||
}
|
||||
|
||||
|
||||
/* Takes an existing file permission and a list of AND/OR changes, and
|
||||
* create a new permissions. */
|
||||
int tweak_mode(int mode, struct chmod_mode_struct *chmod_modes)
|
||||
{
|
||||
int IsX = mode & 0111;
|
||||
int NonPerm = mode & ~CHMOD_BITS;
|
||||
|
||||
for ( ; chmod_modes; chmod_modes = chmod_modes->next) {
|
||||
if ((chmod_modes->flags & FLAG_DIRS_ONLY) && !S_ISDIR(NonPerm))
|
||||
continue;
|
||||
if ((chmod_modes->flags & FLAG_FILES_ONLY) && S_ISDIR(NonPerm))
|
||||
continue;
|
||||
mode &= chmod_modes->ModeAND;
|
||||
if ((chmod_modes->flags & FLAG_X_KEEP) && !IsX && !S_ISDIR(NonPerm))
|
||||
mode |= chmod_modes->ModeOR & ~0111;
|
||||
else
|
||||
mode |= chmod_modes->ModeOR;
|
||||
}
|
||||
|
||||
return mode | NonPerm;
|
||||
}
|
||||
|
||||
/* Free the linked list created by parse_chmod. */
|
||||
int free_chmod_mode(struct chmod_mode_struct *chmod_modes)
|
||||
{
|
||||
struct chmod_mode_struct *next;
|
||||
|
||||
while (chmod_modes) {
|
||||
next = chmod_modes->next;
|
||||
free(chmod_modes);
|
||||
chmod_modes = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
21
cleanup.c
21
cleanup.c
@@ -26,6 +26,10 @@ extern int keep_partial;
|
||||
extern int log_got_error;
|
||||
extern char *partial_dir;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
static struct sigaction sigact;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Close all open sockets and files, allowing a (somewhat) graceful
|
||||
* shutdown() of socket connections. This eliminates the abortive
|
||||
@@ -94,17 +98,18 @@ void _exit_cleanup(int code, const char *file, int line)
|
||||
}
|
||||
inside_cleanup++;
|
||||
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
signal(SIGUSR2, SIG_IGN);
|
||||
SIGACTION(SIGUSR1, SIG_IGN);
|
||||
SIGACTION(SIGUSR2, SIG_IGN);
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
code, safe_fname(file), line);
|
||||
code, file, line);
|
||||
}
|
||||
|
||||
if (cleanup_child_pid != -1) {
|
||||
int status;
|
||||
if (waitpid(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) {
|
||||
if (wait_process(cleanup_child_pid, &status, WNOHANG)
|
||||
== cleanup_child_pid) {
|
||||
status = WEXITSTATUS(status);
|
||||
if (status > code)
|
||||
code = status;
|
||||
@@ -121,8 +126,8 @@ void _exit_cleanup(int code, const char *file, int line)
|
||||
flush_write_file(cleanup_fd_w);
|
||||
close(cleanup_fd_w);
|
||||
}
|
||||
finish_transfer(cleanup_new_fname, fname, cleanup_file, 0,
|
||||
!partial_dir);
|
||||
finish_transfer(cleanup_new_fname, fname, NULL,
|
||||
cleanup_file, 0, !partial_dir);
|
||||
}
|
||||
io_flush(FULL_FLUSH);
|
||||
if (cleanup_fname)
|
||||
@@ -149,7 +154,7 @@ void _exit_cleanup(int code, const char *file, int line)
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n",
|
||||
ocode, safe_fname(file), line, code);
|
||||
ocode, file, line, code);
|
||||
}
|
||||
|
||||
close_all();
|
||||
@@ -166,7 +171,7 @@ void cleanup_disable(void)
|
||||
void cleanup_set(char *fnametmp, char *fname, struct file_struct *file,
|
||||
int fd_r, int fd_w)
|
||||
{
|
||||
cleanup_fname = fnametmp;
|
||||
cleanup_fname = fname ? fnametmp : NULL;
|
||||
cleanup_new_fname = fname;
|
||||
cleanup_file = file;
|
||||
cleanup_fd_r = fd_r;
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "rsync.h"
|
||||
|
||||
static const char default_name[] = "UNKNOWN";
|
||||
extern int am_daemon;
|
||||
extern int am_server;
|
||||
|
||||
|
||||
@@ -321,7 +320,6 @@ int check_name(int fd,
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* Given all these results, we expect that one of them will be
|
||||
* the same as ss. The comparison is a bit complicated. */
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
|
||||
284
clientserver.c
284
clientserver.c
@@ -28,6 +28,7 @@
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int quiet;
|
||||
extern int list_only;
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
@@ -41,23 +42,31 @@ 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 mode_t orig_umask;
|
||||
extern char *bind_address;
|
||||
extern struct filter_list_struct server_filter_list;
|
||||
extern char *sockopts;
|
||||
extern char *config_file;
|
||||
extern char *files_from;
|
||||
extern char *tmpdir;
|
||||
extern struct chmod_mode_struct *chmod_modes;
|
||||
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().
|
||||
@@ -97,6 +106,8 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
if (fd == -1)
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
|
||||
set_socket_options(fd, sockopts);
|
||||
|
||||
ret = start_inband_exchange(user, path, fd, fd, argc);
|
||||
|
||||
return ret ? ret : client_run(fd, fd, -1, argc, argv);
|
||||
@@ -108,7 +119,7 @@ int start_inband_exchange(char *user, char *path, int f_in, int f_out,
|
||||
int i;
|
||||
char *sargs[MAX_ARGS];
|
||||
int sargc = 0;
|
||||
char line[MAXPATHLEN];
|
||||
char line[BIGPATHBUFLEN];
|
||||
char *p;
|
||||
|
||||
if (argc == 0 && !am_sender)
|
||||
@@ -215,24 +226,62 @@ int start_inband_exchange(char *user, char *path, int f_in, int f_out,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *finish_pre_exec(pid_t pid, int fd, char *request,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int j, status = -1;
|
||||
|
||||
if (request) {
|
||||
write_buf(fd, request, strlen(request)+1);
|
||||
for (j = 0; j < argc; j++)
|
||||
write_buf(fd, argv[j], strlen(argv[j])+1);
|
||||
}
|
||||
|
||||
static int rsync_module(int f_in, int f_out, int i)
|
||||
write_byte(fd, 0);
|
||||
|
||||
close(fd);
|
||||
|
||||
if (wait_process(pid, &status, 0) < 0
|
||||
|| !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
char *e;
|
||||
if (asprintf(&e, "pre-xfer exec returned failure (%d)\n", status) < 0)
|
||||
out_of_memory("finish_pre_exec");
|
||||
return e;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int read_arg_from_pipe(int fd, char *buf, int limit)
|
||||
{
|
||||
char *bp = buf, *eob = buf + limit - 1;
|
||||
|
||||
while (1) {
|
||||
if (read(fd, bp, 1) != 1)
|
||||
return -1;
|
||||
if (*bp == '\0')
|
||||
break;
|
||||
if (bp < eob)
|
||||
bp++;
|
||||
}
|
||||
*bp = '\0';
|
||||
|
||||
return bp - buf;
|
||||
}
|
||||
|
||||
static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
|
||||
{
|
||||
int argc = 0;
|
||||
int maxargs;
|
||||
char **argv;
|
||||
char **argp;
|
||||
char line[MAXPATHLEN];
|
||||
char line[BIGPATHBUFLEN];
|
||||
uid_t uid = (uid_t)-2; /* canonically "nobody" */
|
||||
gid_t gid = (gid_t)-2;
|
||||
char *p;
|
||||
char *addr = client_addr(f_in);
|
||||
char *host = client_name(f_in);
|
||||
char *p, *err_msg = NULL;
|
||||
char *name = lp_name(i);
|
||||
int use_chroot = lp_use_chroot(i);
|
||||
int start_glob = 0;
|
||||
int ret;
|
||||
int ret, pre_exec_fd = -1;
|
||||
pid_t pre_exec_pid = 0;
|
||||
char *request = NULL;
|
||||
|
||||
if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
|
||||
@@ -256,7 +305,7 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
if (!claim_connection(lp_lock_file(i), lp_max_connections(i))) {
|
||||
if (errno) {
|
||||
rsyserr(FLOG, errno, "failed to open lock file %s",
|
||||
safe_fname(lp_lock_file(i)));
|
||||
lp_lock_file(i));
|
||||
io_printf(f_out, "@ERROR: failed to open lock file\n");
|
||||
} else {
|
||||
rprintf(FLOG, "max connections (%d) reached\n",
|
||||
@@ -326,27 +375,118 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
|
||||
p = lp_filter(i);
|
||||
parse_rule(&server_filter_list, p, MATCHFLG_WORD_SPLIT,
|
||||
XFLG_ANCHORED2ABS);
|
||||
XFLG_ABS_IF_SLASH);
|
||||
|
||||
p = lp_include_from(i);
|
||||
parse_filter_file(&server_filter_list, p, MATCHFLG_INCLUDE,
|
||||
XFLG_ANCHORED2ABS | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
|
||||
XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
|
||||
|
||||
p = lp_include(i);
|
||||
parse_rule(&server_filter_list, p,
|
||||
MATCHFLG_INCLUDE | MATCHFLG_WORD_SPLIT,
|
||||
XFLG_ANCHORED2ABS | XFLG_OLD_PREFIXES);
|
||||
XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES);
|
||||
|
||||
p = lp_exclude_from(i);
|
||||
parse_filter_file(&server_filter_list, p, 0,
|
||||
XFLG_ANCHORED2ABS | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
|
||||
XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
|
||||
|
||||
p = lp_exclude(i);
|
||||
parse_rule(&server_filter_list, p, MATCHFLG_WORD_SPLIT,
|
||||
XFLG_ANCHORED2ABS | XFLG_OLD_PREFIXES);
|
||||
XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES);
|
||||
|
||||
log_init();
|
||||
|
||||
#ifdef HAVE_PUTENV
|
||||
if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
|
||||
char *modname, *modpath, *hostaddr, *hostname, *username;
|
||||
int status;
|
||||
if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
|
||||
|| asprintf(&modpath, "RSYNC_MODULE_PATH=%s", lp_path(i)) < 0
|
||||
|| asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0
|
||||
|| asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0
|
||||
|| asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0)
|
||||
out_of_memory("rsync_module");
|
||||
putenv(modname);
|
||||
putenv(modpath);
|
||||
putenv(hostaddr);
|
||||
putenv(hostname);
|
||||
putenv(username);
|
||||
umask(orig_umask);
|
||||
/* For post-xfer exec, fork a new process to run the rsync
|
||||
* daemon while this process waits for the exit status and
|
||||
* runs the indicated command at that point. */
|
||||
if (*lp_postxfer_exec(i)) {
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
rsyserr(FLOG, errno, "fork failed");
|
||||
io_printf(f_out, "@ERROR: fork failed\n");
|
||||
return -1;
|
||||
}
|
||||
if (pid) {
|
||||
char *ret1, *ret2;
|
||||
if (wait_process(pid, &status, 0) < 0)
|
||||
status = -1;
|
||||
if (asprintf(&ret1, "RSYNC_RAW_STATUS=%d", status) > 0)
|
||||
putenv(ret1);
|
||||
if (WIFEXITED(status))
|
||||
status = WEXITSTATUS(status);
|
||||
else
|
||||
status = -1;
|
||||
if (asprintf(&ret2, "RSYNC_EXIT_STATUS=%d", status) > 0)
|
||||
putenv(ret2);
|
||||
system(lp_postxfer_exec(i));
|
||||
_exit(status);
|
||||
}
|
||||
}
|
||||
/* For pre-xfer exec, fork a child process to run the indicated
|
||||
* command, though it first waits for the parent process to
|
||||
* send us the user's request via a pipe. */
|
||||
if (*lp_prexfer_exec(i)) {
|
||||
int fds[2];
|
||||
if (pipe(fds) < 0 || (pre_exec_pid = fork()) < 0) {
|
||||
rsyserr(FLOG, errno, "pre-xfer exec preparation failed");
|
||||
io_printf(f_out, "@ERROR: pre-xfer exec preparation failed\n");
|
||||
return -1;
|
||||
}
|
||||
if (pre_exec_pid == 0) {
|
||||
char buf[BIGPATHBUFLEN];
|
||||
int j, len;
|
||||
close(fds[1]);
|
||||
set_blocking(fds[0]);
|
||||
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);
|
||||
for (j = 0; ; j++) {
|
||||
len = read_arg_from_pipe(fds[0], buf,
|
||||
BIGPATHBUFLEN);
|
||||
if (len <= 0) {
|
||||
if (!len)
|
||||
break;
|
||||
_exit(1);
|
||||
}
|
||||
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) < 0)
|
||||
out_of_memory("rsync_module");
|
||||
putenv(p);
|
||||
}
|
||||
close(fds[0]);
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
status = system(lp_prexfer_exec(i));
|
||||
if (!WIFEXITED(status))
|
||||
_exit(1);
|
||||
_exit(WEXITSTATUS(status));
|
||||
}
|
||||
close(fds[0]);
|
||||
set_blocking(fds[1]);
|
||||
pre_exec_fd = fds[1];
|
||||
}
|
||||
umask(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (use_chroot) {
|
||||
/*
|
||||
* XXX: The 'use chroot' flag is a fairly reliable
|
||||
@@ -362,14 +502,14 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
*/
|
||||
if (chroot(lp_path(i))) {
|
||||
rsyserr(FLOG, errno, "chroot %s failed",
|
||||
safe_fname(lp_path(i)));
|
||||
lp_path(i));
|
||||
io_printf(f_out, "@ERROR: chroot failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!push_dir("/")) {
|
||||
rsyserr(FLOG, errno, "chdir %s failed\n",
|
||||
safe_fname(lp_path(i)));
|
||||
lp_path(i));
|
||||
io_printf(f_out, "@ERROR: chdir failed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -377,7 +517,7 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
} else {
|
||||
if (!push_dir(lp_path(i))) {
|
||||
rsyserr(FLOG, errno, "chdir %s failed\n",
|
||||
safe_fname(lp_path(i)));
|
||||
lp_path(i));
|
||||
io_printf(f_out, "@ERROR: chdir failed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -419,6 +559,16 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
am_root = (MY_UID() == 0);
|
||||
}
|
||||
|
||||
if (lp_temp_dir(i) && *lp_temp_dir(i)) {
|
||||
tmpdir = lp_temp_dir(i);
|
||||
if (strlen(tmpdir) >= MAXPATHLEN - 10) {
|
||||
rprintf(FLOG,
|
||||
"the 'temp dir' value for %s is WAY too long -- ignoring.\n",
|
||||
name);
|
||||
tmpdir = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
io_printf(f_out, "@RSYNCD: OK\n");
|
||||
|
||||
maxargs = MAX_ARGS;
|
||||
@@ -443,22 +593,37 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
if (!(argv[argc] = strdup(p)))
|
||||
out_of_memory("rsync_module");
|
||||
|
||||
if (start_glob) {
|
||||
if (start_glob == 1) {
|
||||
request = strdup(p);
|
||||
start_glob++;
|
||||
}
|
||||
glob_expand(name, &argv, &argc, &maxargs);
|
||||
} else
|
||||
switch (start_glob) {
|
||||
case 0:
|
||||
argc++;
|
||||
if (strcmp(line, ".") == 0)
|
||||
start_glob = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (pre_exec_pid) {
|
||||
err_msg = finish_pre_exec(pre_exec_pid,
|
||||
pre_exec_fd, p,
|
||||
argc, argv);
|
||||
pre_exec_pid = 0;
|
||||
}
|
||||
request = strdup(p);
|
||||
start_glob = 2;
|
||||
/* FALL THROUGH */
|
||||
default:
|
||||
if (!err_msg)
|
||||
glob_expand(name, &argv, &argc, &maxargs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(line, ".") == 0)
|
||||
start_glob = 1;
|
||||
if (pre_exec_pid) {
|
||||
err_msg = finish_pre_exec(pre_exec_pid, pre_exec_fd, request,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
verbose = 0; /* future verbosity is controlled by client options */
|
||||
argp = argv;
|
||||
ret = parse_arguments(&argc, (const char ***) &argp, 0);
|
||||
ret = parse_arguments(&argc, (const char ***) &argv, 0);
|
||||
quiet = 0; /* Don't let someone try to be tricky. */
|
||||
|
||||
if (filesfrom_fd == 0)
|
||||
filesfrom_fd = f_in;
|
||||
@@ -478,14 +643,14 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
|
||||
#ifndef DEBUG
|
||||
/* don't allow the logs to be flooded too fast */
|
||||
if (verbose > lp_max_verbosity())
|
||||
verbose = lp_max_verbosity();
|
||||
if (verbose > lp_max_verbosity(i))
|
||||
verbose = lp_max_verbosity(i);
|
||||
#endif
|
||||
|
||||
if (protocol_version < 23
|
||||
&& (protocol_version == 22 || am_sender))
|
||||
io_start_multiplex_out();
|
||||
else if (!ret) {
|
||||
else if (!ret || err_msg) {
|
||||
/* We have to get I/O multiplexing started so that we can
|
||||
* get the error back to the client. This means getting
|
||||
* the protocol setup finished first in later versions. */
|
||||
@@ -511,8 +676,11 @@ static int rsync_module(int f_in, int f_out, int i)
|
||||
io_start_multiplex_out();
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
option_error();
|
||||
if (!ret || err_msg) {
|
||||
if (err_msg)
|
||||
rprintf(FERROR, err_msg);
|
||||
else
|
||||
option_error();
|
||||
msleep(400);
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
}
|
||||
@@ -520,7 +688,20 @@ 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));
|
||||
|
||||
start_server(f_in, f_out, argc, argp);
|
||||
/* 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 && !(daemon_chmod_modes = parse_chmod(p, &chmod_modes))) {
|
||||
rprintf(FLOG, "Invalid \"%sing chmod\" directive: %s\n",
|
||||
am_sender ? "outgo" : "incom", p);
|
||||
}
|
||||
|
||||
start_server(f_in, f_out, argc, argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -546,20 +727,29 @@ static void send_listing(int fd)
|
||||
here */
|
||||
int start_daemon(int f_in, int f_out)
|
||||
{
|
||||
char line[200];
|
||||
char *motd;
|
||||
char line[1024];
|
||||
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");
|
||||
set_socket_options(f_in, lp_socket_options());
|
||||
if (sockopts)
|
||||
set_socket_options(f_in, sockopts);
|
||||
else
|
||||
set_socket_options(f_in, lp_socket_options());
|
||||
set_nonblocking(f_in);
|
||||
}
|
||||
|
||||
@@ -595,6 +785,8 @@ int start_daemon(int f_in, int f_out)
|
||||
return -1;
|
||||
|
||||
if (!*line || strcmp(line, "#list") == 0) {
|
||||
rprintf(FLOG, "module-list request from %s (%s)\n",
|
||||
host, addr);
|
||||
send_listing(f_out);
|
||||
return -1;
|
||||
}
|
||||
@@ -606,17 +798,19 @@ 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)
|
||||
{
|
||||
@@ -664,7 +858,7 @@ int daemon_main(void)
|
||||
0666 & ~orig_umask)) == -1) {
|
||||
cleanup_set_pid(0);
|
||||
rsyserr(FLOG, errno, "failed to create pid file %s",
|
||||
safe_fname(pid_file));
|
||||
pid_file);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
|
||||
|
||||
49
compat.c
49
compat.c
@@ -29,12 +29,12 @@ 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;
|
||||
extern int checksum_seed;
|
||||
extern int basis_dir_cnt;
|
||||
extern int prune_empty_dirs;
|
||||
extern int protocol_version;
|
||||
extern char *dest_option;
|
||||
|
||||
@@ -78,25 +78,38 @@ void setup_protocol(int f_out,int f_in)
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (fuzzy_basis && protocol_version < 29) {
|
||||
rprintf(FERROR,
|
||||
"--fuzzy requires protocol 29 or higher (negotiated %d).\n",
|
||||
protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if (protocol_version < 29) {
|
||||
if (fuzzy_basis) {
|
||||
rprintf(FERROR,
|
||||
"--fuzzy requires protocol 29 or higher"
|
||||
" (negotiated %d).\n",
|
||||
protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (basis_dir_cnt && inplace && protocol_version < 29) {
|
||||
rprintf(FERROR,
|
||||
"%s with --inplace requires protocol 29 or higher (negotiated %d).\n",
|
||||
dest_option, protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if (basis_dir_cnt && inplace) {
|
||||
rprintf(FERROR,
|
||||
"%s with --inplace requires protocol 29 or higher"
|
||||
" (negotiated %d).\n",
|
||||
dest_option, protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (basis_dir_cnt > 1 && protocol_version < 29) {
|
||||
rprintf(FERROR,
|
||||
"Multiple %s options requires protocol 29 or higher (negotiated %d).\n",
|
||||
dest_option, protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
if (basis_dir_cnt > 1) {
|
||||
rprintf(FERROR,
|
||||
"Using more than one %s option requires protocol"
|
||||
" 29 or higher (negotiated %d).\n",
|
||||
dest_option, protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (prune_empty_dirs) {
|
||||
rprintf(FERROR,
|
||||
"--prune-empty-dirs requires protocol 29 or higher"
|
||||
" (negotiated %d).\n",
|
||||
protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
}
|
||||
|
||||
if (am_server) {
|
||||
|
||||
184
configure.in
184
configure.in
@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PREREQ(2.59)
|
||||
|
||||
RSYNC_VERSION=2.6.5
|
||||
RSYNC_VERSION=2.6.8
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
|
||||
|
||||
@@ -26,8 +26,7 @@ AC_SUBST(SHELL)
|
||||
AC_DEFINE([_GNU_SOURCE], 1,
|
||||
[Define _GNU_SOURCE so that we get all necessary prototypes])
|
||||
|
||||
if test "x$ac_cv_prog_cc_stdc" = xno
|
||||
then
|
||||
if test x"$ac_cv_prog_cc_stdc" = x"no"; then
|
||||
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
|
||||
fi
|
||||
|
||||
@@ -38,12 +37,10 @@ fi
|
||||
|
||||
AC_MSG_CHECKING([whether to include debugging symbols])
|
||||
AC_ARG_ENABLE(debug,
|
||||
AC_HELP_STRING([--enable-debug],
|
||||
[including debugging symbols and features (default yes)]),
|
||||
[], [])
|
||||
AC_HELP_STRING([--disable-debug],
|
||||
[turn off debugging symbols and features]))
|
||||
|
||||
if test x"$enable_debug" = x"no"
|
||||
then
|
||||
if test x"$enable_debug" = x"no"; then
|
||||
AC_MSG_RESULT(no)
|
||||
CFLAGS=${CFLAGS-"-O"}
|
||||
else
|
||||
@@ -54,14 +51,10 @@ else
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
AC_ARG_ENABLE(profile,
|
||||
AC_HELP_STRING([--enable-profile],
|
||||
[turn on CPU profiling (default no)],
|
||||
[], []))
|
||||
if test x"$enable_profile" = xyes
|
||||
then
|
||||
[turn on CPU profiling]))
|
||||
if test x"$enable_profile" = x"yes"; then
|
||||
CFLAGS="$CFLAGS -pg"
|
||||
fi
|
||||
|
||||
@@ -69,10 +62,8 @@ fi
|
||||
# Specifically, this turns on panic_action handling.
|
||||
AC_ARG_ENABLE(maintainer-mode,
|
||||
AC_HELP_STRING([--enable-maintainer-mode],
|
||||
[turn on extra debug features],
|
||||
[], []))
|
||||
if test x"$enable_maintainer_mode" = xyes
|
||||
then
|
||||
[turn on extra debug features]))
|
||||
if test x"$enable_maintainer_mode" = x"yes"; then
|
||||
CFLAGS="$CFLAGS -DMAINTAINER_MODE"
|
||||
fi
|
||||
|
||||
@@ -82,16 +73,15 @@ fi
|
||||
CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
|
||||
|
||||
# If GCC, turn on warnings.
|
||||
if test x"$GCC" = x"yes"
|
||||
then
|
||||
if test x"$GCC" = x"yes"; then
|
||||
CFLAGS="$CFLAGS -Wall -W"
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(included-popt,
|
||||
[ --with-included-popt use bundled popt library, not from system])
|
||||
AC_HELP_STRING([--with-included-popt], [use bundled popt library, not from system]))
|
||||
|
||||
AC_ARG_WITH(rsync-path,
|
||||
[ --with-rsync-path=PATH set default --rsync-path to PATH (default: rsync)],
|
||||
AC_HELP_STRING([--with-rsync-path=PATH], [set default --rsync-path to PATH (default: rsync)]),
|
||||
[ RSYNC_PATH="$with_rsync_path" ],
|
||||
[ RSYNC_PATH="rsync" ])
|
||||
|
||||
@@ -126,16 +116,26 @@ if test x$HAVE_REMSH = x1; then
|
||||
AC_DEFINE(HAVE_REMSH, 1, [Define to 1 if remote shell is remsh, not rsh])
|
||||
fi
|
||||
|
||||
if test x"$with_rsh" != x
|
||||
then
|
||||
if test x"$with_rsh" != x; then
|
||||
RSYNC_RSH="$with_rsh"
|
||||
else
|
||||
RSYNC_RSH="ssh"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
|
||||
|
||||
# arrgh. libc in the current debian stable screws up the largefile
|
||||
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)
|
||||
AC_DEFINE_UNQUOTED(NOBODY_USER, "nobody", [unprivileged user--e.g. nobody])
|
||||
AC_DEFINE_UNQUOTED(NOBODY_GROUP, "$NOBODY_GROUP", [unprivileged group for unprivileged user])
|
||||
|
||||
# arrgh. libc in some old debian version screwed up the largefile
|
||||
# stuff, getting byte range locking wrong
|
||||
AC_CACHE_CHECK([for broken largefile support],rsync_cv_HAVE_BROKEN_LARGEFILE,[
|
||||
AC_TRY_RUN([
|
||||
@@ -181,21 +181,9 @@ ipv6lib=none
|
||||
ipv6trylibc=yes
|
||||
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
AC_HELP_STRING([--disable-ipv6], [don't even try to use IPv6]))
|
||||
|
||||
dnl Do you want to disable use of locale functions
|
||||
AH_TEMPLATE([CONFIG_LOCALE],
|
||||
[Undefine if you don't want locale features. By default this is defined.])
|
||||
AC_ARG_ENABLE([locale],
|
||||
AC_HELP_STRING([--disable-locale], [turn off locale features]),
|
||||
[if test x$enableval = xyes; then
|
||||
AC_DEFINE(CONFIG_LOCALE)
|
||||
fi],
|
||||
AC_DEFINE(CONFIG_LOCALE)
|
||||
)
|
||||
|
||||
if test "x$enable_ipv6" != xno
|
||||
then
|
||||
AC_HELP_STRING([--disable-ipv6],
|
||||
[don't even try to use IPv6]))
|
||||
if test x"$enable_ipv6" != x"no"; then
|
||||
AC_MSG_CHECKING([ipv6 stack type])
|
||||
for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
|
||||
case $i in
|
||||
@@ -284,6 +272,16 @@ yes
|
||||
AC_SEARCH_LIBS(getaddrinfo, inet6)
|
||||
fi
|
||||
|
||||
dnl Do you want to disable use of locale functions
|
||||
AC_ARG_ENABLE([locale],
|
||||
AC_HELP_STRING([--disable-locale],
|
||||
[turn off locale features]))
|
||||
AH_TEMPLATE([CONFIG_LOCALE],
|
||||
[Undefine if you don't want locale features. By default this is defined.])
|
||||
if test x"$enable_locale" != x"no"; then
|
||||
AC_DEFINE(CONFIG_LOCALE)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to call shutdown on all sockets])
|
||||
case $host_os in
|
||||
*cygwin* ) AC_MSG_RESULT(yes)
|
||||
@@ -301,7 +299,7 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
|
||||
unistd.h utime.h grp.h compat.h sys/param.h ctype.h sys/wait.h \
|
||||
sys/ioctl.h sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h \
|
||||
sys/un.h glob.h mcheck.h arpa/inet.h arpa/nameser.h locale.h \
|
||||
netdb.h malloc.h float.h)
|
||||
netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h)
|
||||
AC_HEADER_MAJOR
|
||||
|
||||
AC_CHECK_SIZEOF(int)
|
||||
@@ -368,7 +366,11 @@ if test x"$ac_cv_func_connect" = x"no"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(resolv, inet_ntop)
|
||||
AC_SEARCH_LIBS(inet_ntop, resolv)
|
||||
|
||||
# Solaris and HP-UX weirdness:
|
||||
# Search for libiconv_open (not iconv_open) to discover if -liconv is needed!
|
||||
AC_SEARCH_LIBS(libiconv_open, iconv)
|
||||
|
||||
dnl AC_MSG_NOTICE([Looking in libraries: $LIBS])
|
||||
|
||||
@@ -487,19 +489,20 @@ dnl AC_FUNC_MEMCMP
|
||||
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_FUNC_ALLOCA
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod mkfifo \
|
||||
fchmod fstat strchr readlink link utime utimes strftime mtrace ftruncate \
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
|
||||
fchmod fstat ftruncate strchr readlink link utime utimes lutimes strftime \
|
||||
memmove lchown vsnprintf snprintf vasprintf asprintf setsid glob strpbrk \
|
||||
strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
|
||||
setlocale setmode open64 lseek64 mkstemp64 va_copy __va_copy)
|
||||
setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
|
||||
strerror putenv iconv_open locale_charset nl_langinfo \
|
||||
sigaction sigprocmask)
|
||||
|
||||
AC_CHECK_FUNCS(getpgrp tcgetpgrp)
|
||||
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>
|
||||
@@ -510,14 +513,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>
|
||||
@@ -532,14 +573,12 @@ if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
|
||||
AC_DEFINE(HAVE_SOCKETPAIR, 1, [Define to 1 if you have the "socketpair" function])
|
||||
fi
|
||||
|
||||
if test x"$with_included_popt" != x"yes"
|
||||
then
|
||||
if test x"$with_included_popt" != x"yes"; then
|
||||
AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to use included libpopt])
|
||||
if test x"$with_included_popt" = x"yes"
|
||||
then
|
||||
if test x"$with_included_popt" = x"yes"; then
|
||||
AC_MSG_RESULT($srcdir/popt)
|
||||
BUILD_POPT='$(popt_OBJS)'
|
||||
CFLAGS="$CFLAGS -I$srcdir/popt"
|
||||
@@ -648,35 +687,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>
|
||||
@@ -684,7 +694,7 @@ AC_TRY_RUN([
|
||||
#include <errno.h>
|
||||
main() { int rc, ec; char *fn = "fifo-test";
|
||||
unlink(fn); rc = mknod(fn,S_IFIFO,0600); ec = errno; unlink(fn);
|
||||
if (rc) {printf("%d %d\n",rc,ec); return ec;}
|
||||
if (rc) {printf("(%d %d) ",rc,ec); return ec;}
|
||||
return 0;}],
|
||||
rsync_cv_MKNOD_CREATES_FIFOS=yes,rsync_cv_MKNOD_CREATES_FIFOS=no,rsync_cv_MKNOD_CREATES_FIFOS=cross)])
|
||||
if test x"$rsync_cv_MKNOD_CREATES_FIFOS" = x"yes"; then
|
||||
@@ -698,7 +708,7 @@ AC_TRY_RUN([
|
||||
#include <errno.h>
|
||||
main() { int rc, ec; char *fn = "sock-test";
|
||||
unlink(fn); rc = mknod(fn,S_IFSOCK,0600); ec = errno; unlink(fn);
|
||||
if (rc) {printf("%d %d\n",rc,ec); return ec;}
|
||||
if (rc) {printf("(%d %d) ",rc,ec); return ec;}
|
||||
return 0;}],
|
||||
rsync_cv_MKNOD_CREATES_SOCKETS=yes,rsync_cv_MKNOD_CREATES_SOCKETS=no,rsync_cv_MKNOD_CREATES_SOCKETS=cross)])
|
||||
if test x"$rsync_cv_MKNOD_CREATES_SOCKETS" = x"yes"; then
|
||||
|
||||
@@ -34,8 +34,11 @@
|
||||
#define RERR_STREAMIO 12 /* error in rsync protocol data stream */
|
||||
#define RERR_MESSAGEIO 13 /* errors with program diagnostics */
|
||||
#define RERR_IPC 14 /* error in IPC code */
|
||||
#define RERR_CRASHED 15 /* sibling crashed */
|
||||
#define RERR_TERMINATED 16 /* sibling terminated abnormally */
|
||||
|
||||
#define RERR_SIGNAL 20 /* status returned when sent SIGUSR1, SIGINT */
|
||||
#define RERR_SIGNAL1 19 /* status returned when sent SIGUSR1 */
|
||||
#define RERR_SIGNAL 20 /* status returned when sent SIGINT, SIGTERM, SIGHUP */
|
||||
#define RERR_WAITCHILD 21 /* some error returned by waitpid() */
|
||||
#define RERR_MALLOC 22 /* error allocating core memory buffers */
|
||||
#define RERR_PARTIAL 23 /* partial transfer */
|
||||
|
||||
160
exclude.c
160
exclude.c
@@ -34,6 +34,7 @@ extern int list_only;
|
||||
extern int recurse;
|
||||
extern int io_error;
|
||||
extern int local_server;
|
||||
extern int prune_empty_dirs;
|
||||
extern int delete_mode;
|
||||
extern int delete_excluded;
|
||||
extern int cvs_exclude;
|
||||
@@ -46,8 +47,8 @@ extern unsigned int curr_dir_len;
|
||||
extern unsigned int module_dirlen;
|
||||
|
||||
struct filter_list_struct filter_list = { 0, 0, "" };
|
||||
struct filter_list_struct cvs_filter_list = { 0, 0, " [cvsignore]" };
|
||||
struct filter_list_struct server_filter_list = { 0, 0, " [server]" };
|
||||
struct filter_list_struct cvs_filter_list = { 0, 0, " [global CVS]" };
|
||||
struct filter_list_struct server_filter_list = { 0, 0, " [daemon]" };
|
||||
|
||||
/* Need room enough for ":MODS " prefix plus some room to grow. */
|
||||
#define MAX_RULE_PREFIX (16)
|
||||
@@ -133,9 +134,9 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
|
||||
listp->debug_type);
|
||||
}
|
||||
|
||||
/* This flag also indicates that we're reading a list that
|
||||
/* These flags also indicate that we're reading a list that
|
||||
* needs to be filtered now, not post-filtered later. */
|
||||
if (xflags & XFLG_ANCHORED2ABS) {
|
||||
if (xflags & (XFLG_ANCHORED2ABS|XFLG_ABS_IF_SLASH)) {
|
||||
uint32 mf = mflags & (MATCHFLG_RECEIVER_SIDE|MATCHFLG_SENDER_SIDE);
|
||||
if (am_sender) {
|
||||
if (mf == MATCHFLG_RECEIVER_SIDE)
|
||||
@@ -150,10 +151,14 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
|
||||
out_of_memory("add_rule");
|
||||
memset(ret, 0, sizeof ret[0]);
|
||||
|
||||
if (xflags & XFLG_ANCHORED2ABS && *pat == '/'
|
||||
&& !(mflags & (MATCHFLG_ABS_PATH | MATCHFLG_MERGE_FILE))) {
|
||||
if (!(mflags & (MATCHFLG_ABS_PATH | MATCHFLG_MERGE_FILE))
|
||||
&& ((xflags & (XFLG_ANCHORED2ABS|XFLG_ABS_IF_SLASH) && *pat == '/')
|
||||
|| (xflags & XFLG_ABS_IF_SLASH && strchr(pat, '/') != NULL))) {
|
||||
mflags |= MATCHFLG_ABS_PATH;
|
||||
ex_len = dirbuf_len - module_dirlen - 1;
|
||||
if (*pat == '/')
|
||||
ex_len = dirbuf_len - module_dirlen - 1;
|
||||
else
|
||||
ex_len = 0;
|
||||
} else
|
||||
ex_len = 0;
|
||||
if (!(ret->pattern = new_array(char, ex_len + pat_len + 1)))
|
||||
@@ -170,6 +175,12 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
|
||||
/* If the pattern starts with **, note that. */
|
||||
if (cp == ret->pattern)
|
||||
mflags |= MATCHFLG_WILD2_PREFIX;
|
||||
/* If the pattern ends with ***, note that. */
|
||||
if (pat_len >= 3
|
||||
&& ret->pattern[pat_len-3] == '*'
|
||||
&& ret->pattern[pat_len-2] == '*'
|
||||
&& ret->pattern[pat_len-1] == '*')
|
||||
mflags |= MATCHFLG_WILD3_SUFFIX;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +303,7 @@ static char *parse_merge_name(const char *merge_file, unsigned int *len_ptr,
|
||||
}
|
||||
if (!sanitize_path(fn, merge_file, r, dirbuf_depth)) {
|
||||
rprintf(FERROR, "merge-file name overflows: %s\n",
|
||||
safe_fname(merge_file));
|
||||
merge_file);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
@@ -305,8 +316,7 @@ static char *parse_merge_name(const char *merge_file, unsigned int *len_ptr,
|
||||
goto done;
|
||||
|
||||
if (dirbuf_len + fn_len >= MAXPATHLEN) {
|
||||
rprintf(FERROR, "merge-file name overflows: %s\n",
|
||||
safe_fname(fn));
|
||||
rprintf(FERROR, "merge-file name overflows: %s\n", fn);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(buf, dirbuf + prefix_skip, dirbuf_len - prefix_skip);
|
||||
@@ -488,71 +498,69 @@ void pop_local_filters(void *mem)
|
||||
|
||||
static int rule_matches(char *name, struct filter_struct *ex, int name_is_dir)
|
||||
{
|
||||
char *p, full_name[MAXPATHLEN];
|
||||
int match_start = 0;
|
||||
int slash_handling, str_cnt = 0, anchored_match = 0;
|
||||
int ret_match = ex->match_flags & MATCHFLG_NEGATE ? 0 : 1;
|
||||
char *pattern = ex->pattern;
|
||||
char *p, *pattern = ex->pattern;
|
||||
const char *strings[16]; /* more than enough */
|
||||
|
||||
if (!*name)
|
||||
return 0;
|
||||
|
||||
/* If the pattern does not have any slashes AND it does not have
|
||||
* a "**" (which could match a slash), then we just match the
|
||||
* name portion of the path. */
|
||||
if (!ex->u.slash_cnt && !(ex->match_flags & MATCHFLG_WILD2)) {
|
||||
/* If the pattern does not have any slashes AND it does
|
||||
* not have a "**" (which could match a slash), then we
|
||||
* just match the name portion of the path. */
|
||||
if ((p = strrchr(name,'/')) != NULL)
|
||||
name = p+1;
|
||||
}
|
||||
else if (ex->match_flags & MATCHFLG_ABS_PATH && *name != '/'
|
||||
} else if (ex->match_flags & MATCHFLG_ABS_PATH && *name != '/'
|
||||
&& curr_dir_len > module_dirlen + 1) {
|
||||
pathjoin(full_name, sizeof full_name,
|
||||
curr_dir + module_dirlen + 1, name);
|
||||
name = full_name;
|
||||
/* If we're matching against an absolute-path pattern,
|
||||
* we need to prepend our full path info. */
|
||||
strings[str_cnt++] = curr_dir + module_dirlen + 1;
|
||||
strings[str_cnt++] = "/";
|
||||
} else if (ex->match_flags & MATCHFLG_WILD2_PREFIX && *name != '/') {
|
||||
/* Allow "**"+"/" to match at the start of the string. */
|
||||
strings[str_cnt++] = "/";
|
||||
}
|
||||
|
||||
if (ex->match_flags & MATCHFLG_DIRECTORY && !name_is_dir)
|
||||
strings[str_cnt++] = name;
|
||||
if (name_is_dir) {
|
||||
/* Allow a trailing "/"+"***" to match the directory. */
|
||||
if (ex->match_flags & MATCHFLG_WILD3_SUFFIX)
|
||||
strings[str_cnt++] = "/";
|
||||
} else if (ex->match_flags & MATCHFLG_DIRECTORY)
|
||||
return !ret_match;
|
||||
strings[str_cnt] = NULL;
|
||||
|
||||
if (*pattern == '/') {
|
||||
match_start = 1;
|
||||
anchored_match = 1;
|
||||
pattern++;
|
||||
if (*name == '/')
|
||||
name++;
|
||||
if (strings[0][0] == '/')
|
||||
strings[0]++;
|
||||
}
|
||||
|
||||
if (!anchored_match && ex->u.slash_cnt
|
||||
&& !(ex->match_flags & MATCHFLG_WILD2)) {
|
||||
/* A non-anchored match with an infix slash and no "**"
|
||||
* needs to match the last slash_cnt+1 name elements. */
|
||||
slash_handling = ex->u.slash_cnt + 1;
|
||||
} else if (!anchored_match && !(ex->match_flags & MATCHFLG_WILD2_PREFIX)
|
||||
&& ex->match_flags & MATCHFLG_WILD2) {
|
||||
/* A non-anchored match with an infix or trailing "**" (but not
|
||||
* a prefixed "**") needs to try matching after every slash. */
|
||||
slash_handling = -1;
|
||||
} else {
|
||||
/* The pattern matches only at the start of the path or name. */
|
||||
slash_handling = 0;
|
||||
}
|
||||
|
||||
if (ex->match_flags & MATCHFLG_WILD) {
|
||||
/* A non-anchored match with an infix slash and no "**"
|
||||
* needs to match the last slash_cnt+1 name elements. */
|
||||
if (!match_start && ex->u.slash_cnt
|
||||
&& !(ex->match_flags & MATCHFLG_WILD2)) {
|
||||
int cnt = ex->u.slash_cnt + 1;
|
||||
for (p = name + strlen(name) - 1; p >= name; p--) {
|
||||
if (*p == '/' && !--cnt)
|
||||
break;
|
||||
}
|
||||
name = p+1;
|
||||
}
|
||||
if (wildmatch(pattern, name))
|
||||
if (wildmatch_array(pattern, strings, slash_handling))
|
||||
return ret_match;
|
||||
if (ex->match_flags & MATCHFLG_WILD2_PREFIX) {
|
||||
/* If the **-prefixed pattern has a '/' as the next
|
||||
* character, then try to match the rest of the
|
||||
* pattern at the root. */
|
||||
if (pattern[2] == '/' && wildmatch(pattern+3, name))
|
||||
return ret_match;
|
||||
}
|
||||
else if (!match_start && ex->match_flags & MATCHFLG_WILD2) {
|
||||
/* A non-anchored match with an infix or trailing "**"
|
||||
* (but not a prefixed "**") needs to try matching
|
||||
* after every slash. */
|
||||
while ((name = strchr(name, '/')) != NULL) {
|
||||
name++;
|
||||
if (wildmatch(pattern, name))
|
||||
return ret_match;
|
||||
}
|
||||
}
|
||||
} else if (match_start) {
|
||||
if (strcmp(name,pattern) == 0)
|
||||
} else if (str_cnt > 1) {
|
||||
if (litmatch_array(pattern, strings, slash_handling))
|
||||
return ret_match;
|
||||
} else if (anchored_match) {
|
||||
if (strcmp(strings[0], pattern) == 0)
|
||||
return ret_match;
|
||||
} else {
|
||||
int l1 = strlen(name);
|
||||
@@ -577,11 +585,13 @@ static void report_filter_result(char const *name,
|
||||
* case we add it back in here. */
|
||||
|
||||
if (verbose >= 2) {
|
||||
rprintf(FINFO, "[%s] %scluding %s %s because of pattern %s%s%s\n",
|
||||
who_am_i(),
|
||||
ent->match_flags & MATCHFLG_INCLUDE ? "in" : "ex",
|
||||
name_is_dir ? "directory" : "file", name, ent->pattern,
|
||||
ent->match_flags & MATCHFLG_DIRECTORY ? "/" : "", type);
|
||||
static char *actions[2][2]
|
||||
= { {"show", "hid"}, {"risk", "protect"} };
|
||||
const char *w = who_am_i();
|
||||
rprintf(FINFO, "[%s] %sing %s %s because of pattern %s%s%s\n",
|
||||
w, actions[*w!='s'][!(ent->match_flags&MATCHFLG_INCLUDE)],
|
||||
name_is_dir ? "directory" : "file", name, ent->pattern,
|
||||
ent->match_flags & MATCHFLG_DIRECTORY ? "/" : "", type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -827,7 +837,8 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags,
|
||||
len = strlen((char*)s);
|
||||
|
||||
if (new_mflags & MATCHFLG_CLEAR_LIST) {
|
||||
if (!(xflags & XFLG_OLD_PREFIXES) && len) {
|
||||
if (!(mflags & MATCHFLG_NO_PREFIXES)
|
||||
&& !(xflags & XFLG_OLD_PREFIXES) && len) {
|
||||
rprintf(FERROR,
|
||||
"'!' rule has trailing characters: %s\n", p);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
@@ -954,7 +965,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
|
||||
uint32 mflags, int xflags)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[MAXPATHLEN+MAX_RULE_PREFIX+1]; /* +1 for trailing slash. */
|
||||
char line[BIGPATHBUFLEN];
|
||||
char *eob = line + sizeof line - 1;
|
||||
int word_split = mflags & MATCHFLG_WORD_SPLIT;
|
||||
|
||||
@@ -976,7 +987,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "[%s] parse_filter_file(%s,%x,%x)%s\n",
|
||||
who_am_i(), safe_fname(fname), mflags, xflags,
|
||||
who_am_i(), fname, mflags, xflags,
|
||||
fp ? "" : " [not found]");
|
||||
}
|
||||
|
||||
@@ -985,7 +996,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
|
||||
rsyserr(FERROR, errno,
|
||||
"failed to open %sclude file %s",
|
||||
mflags & MATCHFLG_INCLUDE ? "in" : "ex",
|
||||
safe_fname(fname));
|
||||
fname);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
return;
|
||||
@@ -997,8 +1008,10 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
|
||||
int ch, overflow = 0;
|
||||
while (1) {
|
||||
if ((ch = getc(fp)) == EOF) {
|
||||
if (ferror(fp) && errno == EINTR)
|
||||
if (ferror(fp) && errno == EINTR) {
|
||||
clearerr(fp);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (word_split && isspace(ch))
|
||||
@@ -1135,8 +1148,8 @@ static void send_rules(int f_out, struct filter_list_struct *flp)
|
||||
/* This is only called by the client. */
|
||||
void send_filter_list(int f_out)
|
||||
{
|
||||
int receiver_wants_list = delete_mode
|
||||
&& (!delete_excluded || protocol_version >= 29);
|
||||
int receiver_wants_list = prune_empty_dirs
|
||||
|| (delete_mode && (!delete_excluded || protocol_version >= 29));
|
||||
|
||||
if (local_server || (am_sender && !receiver_wants_list))
|
||||
f_out = -1;
|
||||
@@ -1167,16 +1180,17 @@ void send_filter_list(int f_out)
|
||||
/* This is only called by the server. */
|
||||
void recv_filter_list(int f_in)
|
||||
{
|
||||
char line[MAXPATHLEN+MAX_RULE_PREFIX+1]; /* +1 for trailing slash. */
|
||||
char line[BIGPATHBUFLEN];
|
||||
int xflags = protocol_version >= 29 ? 0 : XFLG_OLD_PREFIXES;
|
||||
int receiver_wants_list = delete_mode
|
||||
&& (!delete_excluded || protocol_version >= 29);
|
||||
int receiver_wants_list = prune_empty_dirs
|
||||
|| (delete_mode
|
||||
&& (!delete_excluded || protocol_version >= 29));
|
||||
unsigned int len;
|
||||
|
||||
if (!local_server && (am_sender || receiver_wants_list)) {
|
||||
while ((len = read_int(f_in)) != 0) {
|
||||
if (len >= sizeof line)
|
||||
overflow("recv_rules");
|
||||
overflow_exit("recv_rules");
|
||||
read_sbuf(f_in, line, len);
|
||||
parse_rule(&filter_list, line, 0, xflags);
|
||||
}
|
||||
|
||||
51
fileio.c
51
fileio.c
@@ -22,6 +22,10 @@
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
#ifndef ENODATA
|
||||
#define ENODATA EAGAIN
|
||||
#endif
|
||||
|
||||
extern int sparse_files;
|
||||
|
||||
static char last_byte;
|
||||
@@ -217,34 +221,35 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
rprintf(FERROR, "invalid read_size of %ld in map_ptr\n",
|
||||
(long)read_size);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
} else {
|
||||
if (map->p_fd_offset != read_start) {
|
||||
OFF_T ret = do_lseek(map->fd, read_start, SEEK_SET);
|
||||
if (ret != read_start) {
|
||||
rsyserr(FERROR, errno,
|
||||
"lseek returned %.0f, not %.0f",
|
||||
(double)ret, (double)read_start);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
map->p_fd_offset = read_start;
|
||||
}
|
||||
|
||||
if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) {
|
||||
if (nread < 0) {
|
||||
nread = 0;
|
||||
if (!map->status)
|
||||
map->status = errno;
|
||||
}
|
||||
/* the best we can do is zero the buffer - the file
|
||||
has changed mid transfer! */
|
||||
memset(map->p+read_offset+nread, 0, read_size - nread);
|
||||
}
|
||||
map->p_fd_offset += nread;
|
||||
}
|
||||
|
||||
if (map->p_fd_offset != read_start) {
|
||||
OFF_T ret = do_lseek(map->fd, read_start, SEEK_SET);
|
||||
if (ret != read_start) {
|
||||
rsyserr(FERROR, errno, "lseek returned %.0f, not %.0f",
|
||||
(double)ret, (double)read_start);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
map->p_fd_offset = read_start;
|
||||
}
|
||||
map->p_offset = window_start;
|
||||
map->p_len = window_size;
|
||||
|
||||
while (read_size > 0) {
|
||||
nread = read(map->fd, map->p + read_offset, read_size);
|
||||
if (nread <= 0) {
|
||||
if (!map->status)
|
||||
map->status = nread ? errno : ENODATA;
|
||||
/* The best we can do is zero the buffer -- the file
|
||||
* has changed mid transfer! */
|
||||
memset(map->p + read_offset, 0, read_size);
|
||||
break;
|
||||
}
|
||||
map->p_fd_offset += nread;
|
||||
read_offset += nread;
|
||||
read_size -= nread;
|
||||
}
|
||||
|
||||
return map->p;
|
||||
}
|
||||
|
||||
|
||||
753
generator.c
753
generator.c
File diff suppressed because it is too large
Load Diff
51
hlink.c
51
hlink.c
@@ -20,9 +20,11 @@
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int dry_run;
|
||||
extern int verbose;
|
||||
extern int link_dest;
|
||||
extern int make_backups;
|
||||
extern int log_format_has_i;
|
||||
extern char *basis_dir[];
|
||||
extern struct file_list *the_file_list;
|
||||
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
@@ -172,26 +174,49 @@ int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
{
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
int head;
|
||||
if (!file->link_u.links)
|
||||
return 0;
|
||||
if (skip && !(file->flags & FLAG_HLINK_EOL))
|
||||
head = hlink_list[file->F_HLINDEX] = file->F_NEXT;
|
||||
else
|
||||
head = hlink_list[file->F_HLINDEX];
|
||||
if (ndx != head) {
|
||||
struct file_struct *head_file = FPTR(head);
|
||||
if (verbose > 2) {
|
||||
if (!log_format_has_i && verbose > 1) {
|
||||
rprintf(FINFO, "\"%s\" is a hard link\n",
|
||||
safe_fname(f_name(file)));
|
||||
f_name(file, NULL));
|
||||
}
|
||||
if (head_file->F_HLINDEX == FINISHED_LINK) {
|
||||
STRUCT_STAT st2;
|
||||
char *toname = f_name(head_file);
|
||||
STRUCT_STAT st2, st3;
|
||||
char *toname = f_name(head_file, NULL);
|
||||
if (link_stat(toname, &st2, 0) < 0) {
|
||||
rsyserr(FERROR, errno, "stat %s failed",
|
||||
full_fname(toname));
|
||||
return -1;
|
||||
}
|
||||
if (statret < 0 && basis_dir[0] != NULL) {
|
||||
char cmpbuf[MAXPATHLEN];
|
||||
int j = 0;
|
||||
do {
|
||||
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
|
||||
if (link_stat(cmpbuf, &st3, 0) < 0)
|
||||
continue;
|
||||
if (link_dest) {
|
||||
if (st2.st_dev != st3.st_dev
|
||||
|| st2.st_ino != st3.st_ino)
|
||||
continue;
|
||||
statret = 1;
|
||||
st = &st3;
|
||||
if (verbose < 2 || !log_format_has_i)
|
||||
itemizing = code = 0;
|
||||
break;
|
||||
}
|
||||
if (!unchanged_file(cmpbuf, file, &st3))
|
||||
continue;
|
||||
statret = 1;
|
||||
st = &st3;
|
||||
if (unchanged_attrs(file, &st3))
|
||||
break;
|
||||
} while (basis_dir[++j] != NULL);
|
||||
}
|
||||
maybe_hard_link(file, ndx, fname, statret, st,
|
||||
toname, &st2, itemizing, code);
|
||||
file->F_HLINDEX = FINISHED_LINK;
|
||||
@@ -216,7 +241,7 @@ int hard_link_one(struct file_struct *file, int ndx, char *fname,
|
||||
} else
|
||||
code = FERROR;
|
||||
rsyserr(code, errno, "link %s => %s failed",
|
||||
full_fname(fname), safe_fname(toname));
|
||||
full_fname(fname), toname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -225,10 +250,8 @@ 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) {
|
||||
rprintf(code, "%s => %s\n",
|
||||
safe_fname(fname), safe_fname(toname));
|
||||
}
|
||||
if (code && verbose && !terse)
|
||||
rprintf(code, "%s => %s\n", fname, toname);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -244,7 +267,7 @@ void hard_link_cluster(struct file_struct *file, int master, int itemizing,
|
||||
int statret, ndx = master;
|
||||
|
||||
file->F_HLINDEX = FINISHED_LINK;
|
||||
if (link_stat(f_name_to(file, hlink1), &st1, 0) < 0)
|
||||
if (link_stat(f_name(file, hlink1), &st1, 0) < 0)
|
||||
return;
|
||||
if (!(file->flags & FLAG_HLINK_TOL)) {
|
||||
while (!(file->flags & FLAG_HLINK_EOL)) {
|
||||
@@ -257,7 +280,7 @@ void hard_link_cluster(struct file_struct *file, int master, int itemizing,
|
||||
file = FPTR(ndx);
|
||||
if (file->F_HLINDEX != SKIPPED_LINK)
|
||||
continue;
|
||||
hlink2 = f_name(file);
|
||||
hlink2 = f_name(file, NULL);
|
||||
statret = link_stat(hlink2, &st2, 0);
|
||||
maybe_hard_link(file, ndx, hlink2, statret, &st2,
|
||||
hlink1, &st1, itemizing, code);
|
||||
|
||||
327
io.c
327
io.c
@@ -41,7 +41,6 @@
|
||||
|
||||
extern int bwlimit;
|
||||
extern size_t bwlimit_writemax;
|
||||
extern int verbose;
|
||||
extern int io_timeout;
|
||||
extern int allowed_lull;
|
||||
extern int am_server;
|
||||
@@ -64,22 +63,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 +86,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);
|
||||
|
||||
@@ -119,14 +104,17 @@ struct flist_ndx_list {
|
||||
|
||||
static struct flist_ndx_list redo_list, hlink_list;
|
||||
|
||||
struct msg_list {
|
||||
struct msg_list *next;
|
||||
char *buf;
|
||||
struct msg_list_item {
|
||||
struct msg_list_item *next;
|
||||
int len;
|
||||
char buf[1];
|
||||
};
|
||||
|
||||
static struct msg_list *msg_list_head;
|
||||
static struct msg_list *msg_list_tail;
|
||||
struct msg_list {
|
||||
struct msg_list_item *head, *tail;
|
||||
};
|
||||
|
||||
static struct msg_list msg2genr, msg2sndr;
|
||||
|
||||
static void flist_ndx_push(struct flist_ndx_list *lp, int ndx)
|
||||
{
|
||||
@@ -222,33 +210,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 *ml;
|
||||
struct msg_list_item *m;
|
||||
int sz = len + 4 + sizeof m[0] - 1;
|
||||
|
||||
if (!(ml = new(struct msg_list)))
|
||||
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;
|
||||
}
|
||||
|
||||
void send_msg(enum msgcode code, char *buf, int len)
|
||||
{
|
||||
if (msg_fd_out < 0) {
|
||||
io_multiplex_write(code, buf, len);
|
||||
return;
|
||||
}
|
||||
msg_list_add(code, buf, len);
|
||||
msg_list_push(NORMAL_FLUSH);
|
||||
lst->head = m;
|
||||
lst->tail = m;
|
||||
}
|
||||
|
||||
/* Read a message from the MSG_* fd and handle it. This is called either
|
||||
@@ -286,6 +263,8 @@ static void read_msg_fd(void)
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
read_loop(fd, buf, 4);
|
||||
if (remove_sent_files)
|
||||
decrement_active_files(IVAL(buf,0));
|
||||
flist_ndx_push(&redo_list, IVAL(buf,0));
|
||||
break;
|
||||
case MSG_DELETED:
|
||||
@@ -294,7 +273,10 @@ static void read_msg_fd(void)
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
read_loop(fd, buf, len);
|
||||
io_multiplex_write(MSG_DELETED, buf, len);
|
||||
if (defer_forwarding_messages)
|
||||
msg_list_add(&msg2sndr, MSG_DELETED, buf, len);
|
||||
else
|
||||
io_multiplex_write(MSG_DELETED, buf, len);
|
||||
break;
|
||||
case MSG_SUCCESS:
|
||||
if (len != 4 || !am_generator) {
|
||||
@@ -302,11 +284,23 @@ 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_sent_files) {
|
||||
decrement_active_files(IVAL(buf,0));
|
||||
if (defer_forwarding_messages)
|
||||
msg_list_add(&msg2sndr, MSG_SUCCESS, buf, len);
|
||||
else
|
||||
io_multiplex_write(MSG_SUCCESS, buf, len);
|
||||
}
|
||||
if (preserve_hard_links)
|
||||
flist_ndx_push(&hlink_list, IVAL(buf,0));
|
||||
break;
|
||||
case MSG_SOCKERR:
|
||||
if (!am_generator) {
|
||||
rprintf(FERROR, "invalid message %d:%d\n", tag, len);
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
close_multiplexing_out();
|
||||
/* FALL THROUGH */
|
||||
case MSG_INFO:
|
||||
case MSG_ERROR:
|
||||
case MSG_LOG:
|
||||
@@ -315,22 +309,48 @@ 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);
|
||||
if (am_generator && am_server && defer_forwarding_messages)
|
||||
msg_list_add(&msg2sndr, tag, buf, n);
|
||||
else
|
||||
rwrite((enum logcode)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-sent-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. */
|
||||
int msg_list_push(int flush_it_all)
|
||||
static int msg2genr_flush(int flush_it_all)
|
||||
{
|
||||
static int written = 0;
|
||||
struct timeval tv;
|
||||
@@ -339,9 +359,9 @@ int msg_list_push(int flush_it_all)
|
||||
if (msg_fd_out < 0)
|
||||
return -1;
|
||||
|
||||
while (msg_list_head) {
|
||||
struct msg_list *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,18 +375,27 @@ int msg_list_push(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)
|
||||
{
|
||||
if (msg_fd_out < 0) {
|
||||
io_multiplex_write(code, buf, len);
|
||||
return;
|
||||
}
|
||||
msg_list_add(&msg2genr, code, buf, len);
|
||||
msg2genr_flush(NORMAL_FLUSH);
|
||||
}
|
||||
|
||||
int get_redo_num(int itemizing, enum logcode code)
|
||||
{
|
||||
while (1) {
|
||||
@@ -434,7 +463,6 @@ static void whine_about_eof(int fd)
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read from a socket with I/O timeout. return the number of bytes
|
||||
* read. If no bytes can be read then exit, never return a number <= 0.
|
||||
@@ -448,11 +476,11 @@ static void whine_about_eof(int fd)
|
||||
*/
|
||||
static int read_timeout(int fd, char *buf, size_t len)
|
||||
{
|
||||
int n, ret = 0;
|
||||
int n, cnt = 0;
|
||||
|
||||
io_flush(NORMAL_FLUSH);
|
||||
|
||||
while (ret == 0) {
|
||||
while (cnt == 0) {
|
||||
/* until we manage to read *something* */
|
||||
fd_set r_fds, w_fds;
|
||||
struct timeval tv;
|
||||
@@ -462,7 +490,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;
|
||||
@@ -499,8 +527,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_push(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) {
|
||||
@@ -578,21 +606,23 @@ static int read_timeout(int fd, char *buf, size_t len)
|
||||
continue;
|
||||
|
||||
/* Don't write errors on a dead socket. */
|
||||
if (fd == sock_f_in)
|
||||
if (fd == sock_f_in) {
|
||||
close_multiplexing_out();
|
||||
rsyserr(FERROR, errno, "read error");
|
||||
rsyserr(FSOCKERR, errno, "read error");
|
||||
} else
|
||||
rsyserr(FERROR, errno, "read error");
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
buf += n;
|
||||
len -= n;
|
||||
ret += n;
|
||||
cnt += n;
|
||||
|
||||
if (fd == sock_f_in && io_timeout)
|
||||
last_io_in = time(NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -642,7 +672,6 @@ int read_filesfrom_line(int fd, char *fname)
|
||||
return s - fname;
|
||||
}
|
||||
|
||||
|
||||
static char *iobuf_out;
|
||||
static int iobuf_out_cnt;
|
||||
|
||||
@@ -655,7 +684,6 @@ void io_start_buffering_out(void)
|
||||
iobuf_out_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
static char *iobuf_in;
|
||||
static size_t iobuf_in_siz;
|
||||
|
||||
@@ -668,7 +696,6 @@ void io_start_buffering_in(void)
|
||||
out_of_memory("io_start_buffering_in");
|
||||
}
|
||||
|
||||
|
||||
void io_end_buffering(void)
|
||||
{
|
||||
io_flush(NORMAL_FLUSH);
|
||||
@@ -678,14 +705,12 @@ void io_end_buffering(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void maybe_flush_socket(void)
|
||||
{
|
||||
if (iobuf_out && iobuf_out_cnt && time(NULL) - last_io_out >= 5)
|
||||
io_flush(NORMAL_FLUSH);
|
||||
}
|
||||
|
||||
|
||||
void maybe_send_keepalive(void)
|
||||
{
|
||||
if (time(NULL) - last_io_out >= allowed_lull) {
|
||||
@@ -700,7 +725,6 @@ void maybe_send_keepalive(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Continue trying to read len bytes - don't return until len has been
|
||||
* read.
|
||||
@@ -715,7 +739,6 @@ static void read_loop(int fd, char *buf, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read from the file descriptor handling multiplexing - return number
|
||||
* of bytes read.
|
||||
@@ -727,12 +750,8 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
|
||||
static size_t remaining;
|
||||
static size_t iobuf_in_ndx;
|
||||
size_t msg_bytes;
|
||||
int tag, ret = 0;
|
||||
#if MAXPATHLEN < 4096
|
||||
char line[4096+1024];
|
||||
#else
|
||||
char line[MAXPATHLEN+1024];
|
||||
#endif
|
||||
int tag, cnt = 0;
|
||||
char line[BIGPATHBUFLEN];
|
||||
|
||||
if (!iobuf_in || fd != sock_f_in)
|
||||
return read_timeout(fd, buf, len);
|
||||
@@ -742,13 +761,13 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
|
||||
iobuf_in_ndx = 0;
|
||||
}
|
||||
|
||||
while (ret == 0) {
|
||||
while (cnt == 0) {
|
||||
if (remaining) {
|
||||
len = MIN(len, remaining);
|
||||
memcpy(buf, iobuf_in + iobuf_in_ndx, len);
|
||||
iobuf_in_ndx += len;
|
||||
remaining -= len;
|
||||
ret = len;
|
||||
cnt = len;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -774,12 +793,13 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
|
||||
if (msg_bytes >= sizeof line)
|
||||
goto overflow;
|
||||
read_loop(fd, line, msg_bytes);
|
||||
line[msg_bytes] = '\0';
|
||||
/* A directory name was sent with the trailing null */
|
||||
if (msg_bytes > 0 && !line[msg_bytes-1])
|
||||
log_delete(line, S_IFDIR);
|
||||
else
|
||||
else {
|
||||
line[msg_bytes] = '\0';
|
||||
log_delete(line, S_IFREG);
|
||||
}
|
||||
break;
|
||||
case MSG_SUCCESS:
|
||||
if (msg_bytes != 4) {
|
||||
@@ -812,11 +832,9 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
|
||||
if (remaining == 0)
|
||||
io_flush(NORMAL_FLUSH);
|
||||
|
||||
return ret;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Do a buffered read from @p fd. Don't return until all @p n bytes
|
||||
* have been read. If all @p n can't be read then exit with an
|
||||
@@ -824,12 +842,12 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
|
||||
**/
|
||||
static void readfd(int fd, char *buffer, size_t N)
|
||||
{
|
||||
int ret;
|
||||
int cnt;
|
||||
size_t total = 0;
|
||||
|
||||
while (total < N) {
|
||||
ret = readfd_unbuffered(fd, buffer + total, N-total);
|
||||
total += ret;
|
||||
cnt = readfd_unbuffered(fd, buffer + total, N-total);
|
||||
total += cnt;
|
||||
}
|
||||
|
||||
if (fd == write_batch_monitor_in) {
|
||||
@@ -841,7 +859,6 @@ static void readfd(int fd, char *buffer, size_t N)
|
||||
stats.total_read += total;
|
||||
}
|
||||
|
||||
|
||||
int read_shortint(int f)
|
||||
{
|
||||
uchar b[2];
|
||||
@@ -849,37 +866,36 @@ int read_shortint(int f)
|
||||
return (b[1] << 8) + b[0];
|
||||
}
|
||||
|
||||
|
||||
int32 read_int(int f)
|
||||
{
|
||||
char b[4];
|
||||
int32 ret;
|
||||
int32 num;
|
||||
|
||||
readfd(f,b,4);
|
||||
ret = IVAL(b,0);
|
||||
if (ret == (int32)0xffffffff)
|
||||
num = IVAL(b,0);
|
||||
if (num == (int32)0xffffffff)
|
||||
return -1;
|
||||
return ret;
|
||||
return num;
|
||||
}
|
||||
|
||||
int64 read_longint(int f)
|
||||
{
|
||||
int64 ret;
|
||||
int64 num;
|
||||
char b[8];
|
||||
ret = read_int(f);
|
||||
num = read_int(f);
|
||||
|
||||
if ((int32)ret != (int32)0xffffffff)
|
||||
return ret;
|
||||
if ((int32)num != (int32)0xffffffff)
|
||||
return num;
|
||||
|
||||
#if SIZEOF_INT64 < 8
|
||||
rprintf(FERROR, "Integer overflow: attempted 64-bit offset\n");
|
||||
exit_cleanup(RERR_UNSUPPORTED);
|
||||
#else
|
||||
readfd(f,b,8);
|
||||
ret = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
|
||||
num = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
return num;
|
||||
}
|
||||
|
||||
void read_buf(int f,char *buf,size_t len)
|
||||
@@ -924,6 +940,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",
|
||||
@@ -961,7 +982,6 @@ void write_sum_head(int f, struct sum_struct *sum)
|
||||
write_int(f, sum->remainder);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sleep after writing to limit I/O bandwidth usage.
|
||||
*
|
||||
@@ -987,7 +1007,7 @@ static void sleep_for_bwlimit(int bytes_written)
|
||||
|
||||
#define ONE_SEC 1000000L /* # of microseconds in a second */
|
||||
|
||||
if (!bwlimit)
|
||||
if (!bwlimit_writemax)
|
||||
return;
|
||||
|
||||
total_written += bytes_written;
|
||||
@@ -1017,9 +1037,8 @@ static void sleep_for_bwlimit(int bytes_written)
|
||||
total_written = (sleep_usec - elapsed_usec) * bwlimit / (ONE_SEC/1024);
|
||||
}
|
||||
|
||||
|
||||
/* Write len bytes to the file descriptor fd, looping as necessary to get
|
||||
* the job done and also (in certain circumstnces) reading any data on
|
||||
* the job done and also (in certain circumstances) reading any data on
|
||||
* msg_fd_in to avoid deadlock.
|
||||
*
|
||||
* This function underlies the multiplexing system. The body of the
|
||||
@@ -1028,7 +1047,8 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
{
|
||||
size_t n, total = 0;
|
||||
fd_set w_fds, r_fds;
|
||||
int maxfd, count, ret, using_r_fds;
|
||||
int maxfd, count, cnt, using_r_fds;
|
||||
int defer_save = defer_forwarding_messages;
|
||||
struct timeval tv;
|
||||
|
||||
no_flush++;
|
||||
@@ -1038,7 +1058,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
FD_SET(fd,&w_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);
|
||||
if (msg_fd_in > maxfd)
|
||||
@@ -1068,12 +1088,12 @@ 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;
|
||||
ret = write(fd, buf + total, n);
|
||||
cnt = write(fd, buf + total, n);
|
||||
|
||||
if (ret <= 0) {
|
||||
if (ret < 0) {
|
||||
if (cnt <= 0) {
|
||||
if (cnt < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (errno == EWOULDBLOCK || errno == EAGAIN) {
|
||||
@@ -1086,8 +1106,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) {
|
||||
@@ -1099,18 +1119,36 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
total += ret;
|
||||
total += cnt;
|
||||
defer_forwarding_messages = 1;
|
||||
|
||||
if (fd == sock_f_out) {
|
||||
if (io_timeout || am_generator)
|
||||
last_io_out = time(NULL);
|
||||
sleep_for_bwlimit(ret);
|
||||
sleep_for_bwlimit(cnt);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -1118,38 +1156,33 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
**/
|
||||
static void mplex_write(enum msgcode code, char *buf, size_t len)
|
||||
{
|
||||
char buffer[4096];
|
||||
char buffer[1024];
|
||||
size_t n = 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 = sizeof buffer - 4;
|
||||
n = 0;
|
||||
else
|
||||
memcpy(buffer + 4, buf, n);
|
||||
|
||||
memcpy(&buffer[4], buf, n);
|
||||
writefd_unbuffered(sock_f_out, buffer, n+4);
|
||||
|
||||
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_push(flush_it_all);
|
||||
msg2genr_flush(flush_it_all);
|
||||
msg2sndr_flush();
|
||||
|
||||
if (!iobuf_out_cnt || no_flush)
|
||||
return;
|
||||
@@ -1161,7 +1194,6 @@ void io_flush(int flush_it_all)
|
||||
iobuf_out_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
static void writefd(int fd,char *buf,size_t len)
|
||||
{
|
||||
if (fd == msg_fd_out) {
|
||||
@@ -1196,7 +1228,6 @@ static void writefd(int fd,char *buf,size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void write_shortint(int f, int x)
|
||||
{
|
||||
uchar b[2];
|
||||
@@ -1205,7 +1236,6 @@ void write_shortint(int f, int x)
|
||||
writefd(f, (char *)b, 2);
|
||||
}
|
||||
|
||||
|
||||
void write_int(int f,int32 x)
|
||||
{
|
||||
char b[4];
|
||||
@@ -1213,15 +1243,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.
|
||||
@@ -1283,7 +1304,6 @@ void write_vstring(int f, char *str, int len)
|
||||
writefd(f, str, len);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a line of up to @p maxlen characters into @p buf (not counting
|
||||
* the trailing null). Strips the (required) trailing newline and all
|
||||
@@ -1309,11 +1329,10 @@ int read_line(int f, char *buf, size_t maxlen)
|
||||
return maxlen > 0;
|
||||
}
|
||||
|
||||
|
||||
void io_printf(int fd, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[1024];
|
||||
char buf[BIGPATHBUFLEN];
|
||||
int len;
|
||||
|
||||
va_start(ap, format);
|
||||
@@ -1323,10 +1342,14 @@ void io_printf(int fd, const char *format, ...)
|
||||
if (len < 0)
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
|
||||
if (len > (int)sizeof buf) {
|
||||
rprintf(FERROR, "io_printf() was too long for the buffer.\n");
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
write_sbuf(fd, buf);
|
||||
}
|
||||
|
||||
|
||||
/** Setup for multiplexing a MSG_* stream with the data stream. */
|
||||
void io_start_multiplex_out(void)
|
||||
{
|
||||
|
||||
43
lib/compat.c
43
lib/compat.c
@@ -150,49 +150,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)
|
||||
{
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
*
|
||||
* @param buf buffer of at least 11 characters
|
||||
**/
|
||||
void permstring(char *perms,
|
||||
int mode)
|
||||
void permstring(char *perms, mode_t mode)
|
||||
{
|
||||
static const char *perm_map = "rwxrwxrwx";
|
||||
int i;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#define PERMSTRING_SIZE 11
|
||||
|
||||
void permstring(char *perms, int mode);
|
||||
void permstring(char *perms, mode_t mode);
|
||||
|
||||
@@ -56,8 +56,7 @@ pool_create(size_t size, size_t quantum,
|
||||
pool->size = size /* round extent size to min alignment reqs */
|
||||
? (size + MINALIGN - 1) & ~(MINALIGN - 1)
|
||||
: POOL_DEF_EXTENT;
|
||||
if (pool->flags & POOL_INTERN)
|
||||
{
|
||||
if (pool->flags & POOL_INTERN) {
|
||||
pool->size -= sizeof (struct pool_extent);
|
||||
flags |= POOL_APPEND;
|
||||
}
|
||||
@@ -77,15 +76,13 @@ pool_destroy(alloc_pool_t p)
|
||||
if (!pool)
|
||||
return;
|
||||
|
||||
if (pool->live)
|
||||
{
|
||||
if (pool->live) {
|
||||
cur = pool->live;
|
||||
free(cur->start);
|
||||
if (!(pool->flags & POOL_APPEND))
|
||||
free(cur);
|
||||
}
|
||||
for (cur = pool->free; cur; cur = next)
|
||||
{
|
||||
for (cur = pool->free; cur; cur = next) {
|
||||
next = cur->next;
|
||||
free(cur->start);
|
||||
if (!(pool->flags & POOL_APPEND))
|
||||
@@ -109,16 +106,14 @@ pool_alloc(alloc_pool_t p, size_t len, char *bomb)
|
||||
if (len > pool->size)
|
||||
goto bomb;
|
||||
|
||||
if (!pool->live || len > pool->live->free)
|
||||
{
|
||||
if (!pool->live || len > pool->live->free) {
|
||||
void *start;
|
||||
size_t free;
|
||||
size_t bound;
|
||||
size_t sqew;
|
||||
size_t asize;
|
||||
|
||||
if (pool->live)
|
||||
{
|
||||
if (pool->live) {
|
||||
pool->live->next = pool->free;
|
||||
pool->free = pool->live;
|
||||
}
|
||||
@@ -137,16 +132,11 @@ pool_alloc(alloc_pool_t p, size_t len, char *bomb)
|
||||
memset(start, 0, pool->size);
|
||||
|
||||
if (pool->flags & POOL_APPEND)
|
||||
{
|
||||
pool->live = PTR_ADD(start, free);
|
||||
}
|
||||
else if (!(pool->live = (struct pool_extent *) malloc(sizeof (struct pool_extent))))
|
||||
{
|
||||
goto bomb;
|
||||
}
|
||||
if (pool->flags & POOL_QALIGN && pool->quantum > 1
|
||||
&& (sqew = (size_t)PTR_ADD(start, free) % pool->quantum))
|
||||
{
|
||||
&& (sqew = (size_t)PTR_ADD(start, free) % pool->quantum)) {
|
||||
bound += sqew;
|
||||
free -= sqew;
|
||||
}
|
||||
@@ -186,8 +176,7 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
|
||||
else if (pool->quantum > 1 && len % pool->quantum)
|
||||
len += pool->quantum - len % pool->quantum;
|
||||
|
||||
if (!addr && pool->live)
|
||||
{
|
||||
if (!addr && pool->live) {
|
||||
pool->live->next = pool->free;
|
||||
pool->free = pool->live;
|
||||
pool->live = NULL;
|
||||
@@ -197,35 +186,28 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
|
||||
pool->b_freed += len;
|
||||
|
||||
cur = pool->live;
|
||||
if (cur
|
||||
&& addr >= cur->start
|
||||
&& addr < PTR_ADD(cur->start, pool->size))
|
||||
{
|
||||
if (addr == PTR_ADD(cur->start, cur->free))
|
||||
{
|
||||
if (cur && addr >= cur->start
|
||||
&& addr < PTR_ADD(cur->start, pool->size)) {
|
||||
if (addr == PTR_ADD(cur->start, cur->free)) {
|
||||
if (pool->flags & POOL_CLEAR)
|
||||
memset(addr, 0, len);
|
||||
pool->b_freed += len;
|
||||
} else {
|
||||
} else
|
||||
cur->bound += len;
|
||||
}
|
||||
if (cur->free + cur->bound >= pool->size)
|
||||
{
|
||||
if (cur->free + cur->bound >= pool->size) {
|
||||
size_t sqew;
|
||||
|
||||
cur->free = pool->size;
|
||||
cur->bound = 0;
|
||||
if (pool->flags & POOL_QALIGN && pool->quantum > 1
|
||||
&& (sqew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum))
|
||||
{
|
||||
&& (sqew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum)) {
|
||||
cur->bound += sqew;
|
||||
cur->free -= sqew;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (prev = NULL, cur = pool->free; cur; prev = cur, cur = cur->next)
|
||||
{
|
||||
for (prev = NULL, cur = pool->free; cur; prev = cur, cur = cur->next) {
|
||||
if (addr >= cur->start
|
||||
&& addr < PTR_ADD(cur->start, pool->size))
|
||||
break;
|
||||
@@ -233,16 +215,14 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
|
||||
if (!cur)
|
||||
return;
|
||||
|
||||
if (prev)
|
||||
{
|
||||
if (prev) {
|
||||
prev->next = cur->next;
|
||||
cur->next = pool->free;
|
||||
pool->free = cur;
|
||||
}
|
||||
cur->bound += len;
|
||||
|
||||
if (cur->free + cur->bound >= pool->size)
|
||||
{
|
||||
if (cur->free + cur->bound >= pool->size) {
|
||||
pool->free = cur->next;
|
||||
|
||||
free(cur->start);
|
||||
@@ -254,11 +234,11 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
|
||||
}
|
||||
|
||||
#define FDPRINT(label, value) \
|
||||
snprintf(buf, BUFSIZ, label, value), \
|
||||
write(fd, buf, strlen(buf));
|
||||
snprintf(buf, sizeof buf, label, value), \
|
||||
write(fd, buf, strlen(buf))
|
||||
|
||||
#define FDEXTSTAT(ext) \
|
||||
snprintf(buf, BUFSIZ, " %12ld %5ld\n", \
|
||||
snprintf(buf, sizeof buf, " %12ld %5ld\n", \
|
||||
(long) ext->free, \
|
||||
(long) ext->bound), \
|
||||
write(fd, buf, strlen(buf))
|
||||
@@ -291,14 +271,10 @@ pool_stats(alloc_pool_t p, int fd, int summarize)
|
||||
write(fd, "\n", 1);
|
||||
|
||||
if (pool->live)
|
||||
{
|
||||
FDEXTSTAT(pool->live);
|
||||
}
|
||||
strcpy(buf, " FREE BOUND\n");
|
||||
write(fd, buf, strlen(buf));
|
||||
|
||||
for (cur = pool->free; cur; cur = cur->next)
|
||||
{
|
||||
FDEXTSTAT(cur);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef VA_COPY
|
||||
#ifdef HAVE_VA_COPY
|
||||
#if defined HAVE_VA_COPY || defined va_copy
|
||||
#define VA_COPY(dest, src) va_copy(dest, src)
|
||||
#else
|
||||
#ifdef HAVE___VA_COPY
|
||||
|
||||
313
lib/wildmatch.c
313
lib/wildmatch.c
@@ -57,173 +57,312 @@
|
||||
int wildmatch_iteration_count;
|
||||
#endif
|
||||
|
||||
static int domatch(const uchar *p, const uchar *text)
|
||||
static int force_lower_case = 0;
|
||||
|
||||
/* Match pattern "p" against the a virtually-joined string consisting
|
||||
* of "text" and any strings in array "a". */
|
||||
static int dowild(const uchar *p, const uchar *text, const uchar*const *a)
|
||||
{
|
||||
int matched, special;
|
||||
uchar ch, prev;
|
||||
uchar p_ch;
|
||||
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
wildmatch_iteration_count++;
|
||||
#endif
|
||||
|
||||
for ( ; (ch = *p) != '\0'; text++, p++) {
|
||||
if (*text == '\0' && ch != '*')
|
||||
return FALSE;
|
||||
switch (ch) {
|
||||
for ( ; (p_ch = *p) != '\0'; text++, p++) {
|
||||
int matched, special;
|
||||
uchar t_ch, prev_ch;
|
||||
while ((t_ch = *text) == '\0') {
|
||||
if (*a == NULL) {
|
||||
if (p_ch != '*')
|
||||
return ABORT_ALL;
|
||||
break;
|
||||
}
|
||||
text = *a++;
|
||||
}
|
||||
if (force_lower_case && ISUPPER(t_ch))
|
||||
t_ch = tolower(t_ch);
|
||||
switch (p_ch) {
|
||||
case '\\':
|
||||
/* Literal match with following character. Note that the test
|
||||
* in "default" handles the p[1] == '\0' failure case. */
|
||||
ch = *++p;
|
||||
p_ch = *++p;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (*text != ch)
|
||||
if (t_ch != p_ch)
|
||||
return FALSE;
|
||||
continue;
|
||||
case '?':
|
||||
/* Match anything but '/'. */
|
||||
if (*text == '/')
|
||||
if (t_ch == '/')
|
||||
return FALSE;
|
||||
continue;
|
||||
case '*':
|
||||
if (*++p == '*') {
|
||||
while (*++p == '*') {}
|
||||
special = TRUE;
|
||||
}
|
||||
else
|
||||
} else
|
||||
special = FALSE;
|
||||
if (*p == '\0') {
|
||||
/* Trailing "**" matches everything. Trailing "*" matches
|
||||
* only if there are no more slash characters. */
|
||||
return special? TRUE : strchr((char*)text, '/') == NULL;
|
||||
if (!special) {
|
||||
do {
|
||||
if (strchr((char*)text, '/') != NULL)
|
||||
return FALSE;
|
||||
} while ((text = *a++) != NULL);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
for ( ; *text; text++) {
|
||||
if ((matched = domatch(p, text)) != FALSE) {
|
||||
while (1) {
|
||||
if (t_ch == '\0') {
|
||||
if ((text = *a++) == NULL)
|
||||
break;
|
||||
t_ch = *text;
|
||||
continue;
|
||||
}
|
||||
if ((matched = dowild(p, text, a)) != FALSE) {
|
||||
if (!special || matched != ABORT_TO_STARSTAR)
|
||||
return matched;
|
||||
}
|
||||
else if (!special && *text == '/')
|
||||
} else if (!special && t_ch == '/')
|
||||
return ABORT_TO_STARSTAR;
|
||||
t_ch = *++text;
|
||||
}
|
||||
return ABORT_ALL;
|
||||
case '[':
|
||||
ch = *++p;
|
||||
p_ch = *++p;
|
||||
#ifdef NEGATE_CLASS2
|
||||
if (ch == NEGATE_CLASS2)
|
||||
ch = NEGATE_CLASS;
|
||||
if (p_ch == NEGATE_CLASS2)
|
||||
p_ch = NEGATE_CLASS;
|
||||
#endif
|
||||
/* Assign literal TRUE/FALSE because of "matched" comparison. */
|
||||
special = ch == NEGATE_CLASS? TRUE : FALSE;
|
||||
special = p_ch == NEGATE_CLASS? TRUE : FALSE;
|
||||
if (special) {
|
||||
/* Inverted character class. */
|
||||
ch = *++p;
|
||||
p_ch = *++p;
|
||||
}
|
||||
prev = 0;
|
||||
prev_ch = 0;
|
||||
matched = FALSE;
|
||||
do {
|
||||
if (!ch)
|
||||
if (!p_ch)
|
||||
return ABORT_ALL;
|
||||
if (ch == '\\') {
|
||||
ch = *++p;
|
||||
if (!ch)
|
||||
if (p_ch == '\\') {
|
||||
p_ch = *++p;
|
||||
if (!p_ch)
|
||||
return ABORT_ALL;
|
||||
if (*text == ch)
|
||||
if (t_ch == p_ch)
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (ch == '-' && prev && p[1] && p[1] != ']') {
|
||||
ch = *++p;
|
||||
if (ch == '\\') {
|
||||
ch = *++p;
|
||||
if (!ch)
|
||||
} else if (p_ch == '-' && prev_ch && p[1] && p[1] != ']') {
|
||||
p_ch = *++p;
|
||||
if (p_ch == '\\') {
|
||||
p_ch = *++p;
|
||||
if (!p_ch)
|
||||
return ABORT_ALL;
|
||||
}
|
||||
if (*text <= ch && *text >= prev)
|
||||
if (t_ch <= p_ch && t_ch >= prev_ch)
|
||||
matched = TRUE;
|
||||
ch = 0; /* This makes "prev" get set to 0. */
|
||||
}
|
||||
else if (ch == '[' && p[1] == ':') {
|
||||
p_ch = 0; /* This makes "prev_ch" get set to 0. */
|
||||
} else if (p_ch == '[' && p[1] == ':') {
|
||||
const uchar *s;
|
||||
int i;
|
||||
for (s = p += 2; (ch = *p) && ch != ']'; p++) {}
|
||||
if (!ch)
|
||||
for (s = p += 2; (p_ch = *p) && p_ch != ']'; p++) {}
|
||||
if (!p_ch)
|
||||
return ABORT_ALL;
|
||||
i = p - s - 1;
|
||||
if (i < 0 || p[-1] != ':') {
|
||||
/* Didn't find ":]", so treat like a normal set. */
|
||||
p = s - 2;
|
||||
ch = '[';
|
||||
if (*text == ch)
|
||||
p_ch = '[';
|
||||
if (t_ch == p_ch)
|
||||
matched = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (CC_EQ(s,i, "alnum")) {
|
||||
if (ISALNUM(*text))
|
||||
if (ISALNUM(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "alpha")) {
|
||||
if (ISALPHA(*text))
|
||||
} else if (CC_EQ(s,i, "alpha")) {
|
||||
if (ISALPHA(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "blank")) {
|
||||
if (ISBLANK(*text))
|
||||
} else if (CC_EQ(s,i, "blank")) {
|
||||
if (ISBLANK(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "cntrl")) {
|
||||
if (ISCNTRL(*text))
|
||||
} else if (CC_EQ(s,i, "cntrl")) {
|
||||
if (ISCNTRL(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "digit")) {
|
||||
if (ISDIGIT(*text))
|
||||
} else if (CC_EQ(s,i, "digit")) {
|
||||
if (ISDIGIT(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "graph")) {
|
||||
if (ISGRAPH(*text))
|
||||
} else if (CC_EQ(s,i, "graph")) {
|
||||
if (ISGRAPH(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "lower")) {
|
||||
if (ISLOWER(*text))
|
||||
} else if (CC_EQ(s,i, "lower")) {
|
||||
if (ISLOWER(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "print")) {
|
||||
if (ISPRINT(*text))
|
||||
} else if (CC_EQ(s,i, "print")) {
|
||||
if (ISPRINT(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "punct")) {
|
||||
if (ISPUNCT(*text))
|
||||
} else if (CC_EQ(s,i, "punct")) {
|
||||
if (ISPUNCT(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "space")) {
|
||||
if (ISSPACE(*text))
|
||||
} else if (CC_EQ(s,i, "space")) {
|
||||
if (ISSPACE(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "upper")) {
|
||||
if (ISUPPER(*text))
|
||||
} else if (CC_EQ(s,i, "upper")) {
|
||||
if (ISUPPER(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (CC_EQ(s,i, "xdigit")) {
|
||||
if (ISXDIGIT(*text))
|
||||
} else if (CC_EQ(s,i, "xdigit")) {
|
||||
if (ISXDIGIT(t_ch))
|
||||
matched = TRUE;
|
||||
}
|
||||
else /* malformed [:class:] string */
|
||||
} else /* malformed [:class:] string */
|
||||
return ABORT_ALL;
|
||||
ch = 0; /* This makes "prev" get set to 0. */
|
||||
}
|
||||
else if (*text == ch)
|
||||
p_ch = 0; /* This makes "prev_ch" get set to 0. */
|
||||
} else if (t_ch == p_ch)
|
||||
matched = TRUE;
|
||||
} while (prev = ch, (ch = *++p) != ']');
|
||||
if (matched == special || *text == '/')
|
||||
} while (prev_ch = p_ch, (p_ch = *++p) != ']');
|
||||
if (matched == special || t_ch == '/')
|
||||
return FALSE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return *text == '\0';
|
||||
do {
|
||||
if (*text)
|
||||
return FALSE;
|
||||
} while ((text = *a++) != NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Find the pattern (p) in the text string (t). */
|
||||
int wildmatch(const char *p, const char *t)
|
||||
/* Match literal string "s" against the a virtually-joined string consisting
|
||||
* of "text" and any strings in array "a". */
|
||||
static int doliteral(const uchar *s, const uchar *text, const uchar*const *a)
|
||||
{
|
||||
for ( ; *s != '\0'; text++, s++) {
|
||||
while (*text == '\0') {
|
||||
if ((text = *a++) == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
if (*text != *s)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
do {
|
||||
if (*text)
|
||||
return FALSE;
|
||||
} while ((text = *a++) != NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Return the last "count" path elements from the concatenated string.
|
||||
* We return a string pointer to the start of the string, and update the
|
||||
* array pointer-pointer to point to any remaining string elements. */
|
||||
static const uchar *trailing_N_elements(const uchar*const **a_ptr, int count)
|
||||
{
|
||||
const uchar*const *a = *a_ptr;
|
||||
const uchar*const *first_a = a;
|
||||
|
||||
while (*a)
|
||||
a++;
|
||||
|
||||
while (a != first_a) {
|
||||
const uchar *s = *--a;
|
||||
s += strlen((char*)s);
|
||||
while (--s >= *a) {
|
||||
if (*s == '/' && !--count) {
|
||||
*a_ptr = a+1;
|
||||
return s+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
*a_ptr = a+1;
|
||||
return *a;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Match the "pattern" against the "text" string. */
|
||||
int wildmatch(const char *pattern, const char *text)
|
||||
{
|
||||
static const uchar *nomore[1]; /* A NULL pointer. */
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
wildmatch_iteration_count = 0;
|
||||
#endif
|
||||
return domatch((const uchar*)p, (const uchar*)t) == TRUE;
|
||||
return dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;
|
||||
}
|
||||
|
||||
/* Match the "pattern" against the forced-to-lower-case "text" string. */
|
||||
int iwildmatch(const char *pattern, const char *text)
|
||||
{
|
||||
static const uchar *nomore[1]; /* A NULL pointer. */
|
||||
int ret;
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
wildmatch_iteration_count = 0;
|
||||
#endif
|
||||
force_lower_case = 1;
|
||||
ret = dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;
|
||||
force_lower_case = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Match pattern "p" against the a virtually-joined string consisting
|
||||
* of all the pointers in array "texts" (which has a NULL pointer at the
|
||||
* end). The int "where" can be 0 (normal matching), > 0 (match only
|
||||
* the trailing N slash-separated filename components of "texts"), or < 0
|
||||
* (match the "pattern" at the start or after any slash in "texts"). */
|
||||
int wildmatch_array(const char *pattern, const char*const *texts, int where)
|
||||
{
|
||||
const uchar *p = (const uchar*)pattern;
|
||||
const uchar*const *a = (const uchar*const*)texts;
|
||||
const uchar *text;
|
||||
int matched;
|
||||
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
wildmatch_iteration_count = 0;
|
||||
#endif
|
||||
|
||||
if (where > 0)
|
||||
text = trailing_N_elements(&a, where);
|
||||
else
|
||||
text = *a++;
|
||||
if (!text)
|
||||
return FALSE;
|
||||
|
||||
if ((matched = dowild(p, text, a)) != TRUE && where < 0
|
||||
&& matched != ABORT_ALL) {
|
||||
while (1) {
|
||||
if (*text == '\0') {
|
||||
if ((text = (uchar*)*a++) == NULL)
|
||||
return FALSE;
|
||||
continue;
|
||||
}
|
||||
if (*text++ == '/' && (matched = dowild(p, text, a)) != FALSE
|
||||
&& matched != ABORT_TO_STARSTAR)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return matched == TRUE;
|
||||
}
|
||||
|
||||
/* Match literal string "s" against the a virtually-joined string consisting
|
||||
* of all the pointers in array "texts" (which has a NULL pointer at the
|
||||
* end). The int "where" can be 0 (normal matching), or > 0 (match
|
||||
* only the trailing N slash-separated filename components of "texts"). */
|
||||
int litmatch_array(const char *string, const char*const *texts, int where)
|
||||
{
|
||||
const uchar *s = (const uchar*)string;
|
||||
const uchar*const *a = (const uchar* const*)texts;
|
||||
const uchar *text;
|
||||
|
||||
if (where > 0)
|
||||
text = trailing_N_elements(&a, where);
|
||||
else
|
||||
text = *a++;
|
||||
if (!text)
|
||||
return FALSE;
|
||||
|
||||
return doliteral(s, text, a) == TRUE;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/* wildmatch.h */
|
||||
|
||||
int wildmatch(const char *p, const char *text);
|
||||
int wildmatch(const char *pattern, const char *text);
|
||||
int iwildmatch(const char *pattern, const char *text);
|
||||
int wildmatch_array(const char *pattern, const char*const *texts, int where);
|
||||
int litmatch_array(const char *string, const char*const *texts, int where);
|
||||
|
||||
271
loadparm.c
271
loadparm.c
@@ -98,95 +98,107 @@ struct parm_struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *motd_file;
|
||||
char *bind_address;
|
||||
char *log_file;
|
||||
char *motd_file;
|
||||
char *pid_file;
|
||||
char *socket_options;
|
||||
char *bind_address;
|
||||
int syslog_facility;
|
||||
int max_verbosity;
|
||||
|
||||
int rsync_port;
|
||||
int syslog_facility;
|
||||
} global;
|
||||
|
||||
static global Globals;
|
||||
|
||||
|
||||
/*
|
||||
* This structure describes a single service.
|
||||
* This structure describes a single service. Their order must match the
|
||||
* initializers below, which you can accomplish by keeping each sub-section
|
||||
* sorted. (e.g. in vim, just visually select each subsection and use !sort.)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
char *path;
|
||||
char *auth_users;
|
||||
char *comment;
|
||||
char *lock_file;
|
||||
BOOL read_only;
|
||||
BOOL write_only;
|
||||
BOOL list;
|
||||
BOOL use_chroot;
|
||||
BOOL transfer_logging;
|
||||
BOOL ignore_errors;
|
||||
char *uid;
|
||||
char *dont_compress;
|
||||
char *exclude;
|
||||
char *exclude_from;
|
||||
char *filter;
|
||||
char *gid;
|
||||
char *hosts_allow;
|
||||
char *hosts_deny;
|
||||
char *auth_users;
|
||||
char *secrets_file;
|
||||
BOOL strict_modes;
|
||||
char *filter;
|
||||
char *exclude;
|
||||
char *exclude_from;
|
||||
char *include;
|
||||
char *include_from;
|
||||
char *incoming_chmod;
|
||||
char *lock_file;
|
||||
char *log_format;
|
||||
char *name;
|
||||
char *outgoing_chmod;
|
||||
char *path;
|
||||
char *postxfer_exec;
|
||||
char *prexfer_exec;
|
||||
char *refuse_options;
|
||||
char *dont_compress;
|
||||
int timeout;
|
||||
char *secrets_file;
|
||||
char *temp_dir;
|
||||
char *uid;
|
||||
|
||||
int max_connections;
|
||||
int max_verbosity;
|
||||
int timeout;
|
||||
|
||||
BOOL ignore_errors;
|
||||
BOOL ignore_nonreadable;
|
||||
BOOL list;
|
||||
BOOL read_only;
|
||||
BOOL strict_modes;
|
||||
BOOL transfer_logging;
|
||||
BOOL use_chroot;
|
||||
BOOL write_only;
|
||||
} service;
|
||||
|
||||
|
||||
/* This is a default service used to prime a services structure */
|
||||
/* This is a default service used to prime a services structure. In order
|
||||
* to make these easy to keep sorted in the same way as the variables
|
||||
* above, use the variable name in the leading comment, including a
|
||||
* trailing ';' (to avoid a sorting problem with trailing digits). */
|
||||
static service sDefault =
|
||||
{
|
||||
NULL, /* name */
|
||||
NULL, /* path */
|
||||
NULL, /* comment */
|
||||
DEFAULT_LOCK_FILE, /* lock file */
|
||||
True, /* read only */
|
||||
False, /* write only */
|
||||
True, /* list */
|
||||
True, /* use chroot */
|
||||
False, /* transfer logging */
|
||||
False, /* ignore errors */
|
||||
"nobody",/* uid */
|
||||
/* auth_users; */ NULL,
|
||||
/* comment; */ NULL,
|
||||
/* dont_compress; */ "*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz",
|
||||
/* exclude; */ NULL,
|
||||
/* exclude_from; */ NULL,
|
||||
/* filter; */ NULL,
|
||||
/* gid; */ NOBODY_GROUP,
|
||||
/* hosts_allow; */ NULL,
|
||||
/* hosts_deny; */ NULL,
|
||||
/* include; */ NULL,
|
||||
/* include_from; */ NULL,
|
||||
/* incoming_chmod; */ NULL,
|
||||
/* lock_file; */ DEFAULT_LOCK_FILE,
|
||||
/* log_format; */ "%o %h [%a] %m (%u) %f %l",
|
||||
/* name; */ NULL,
|
||||
/* outgoing_chmod; */ NULL,
|
||||
/* path; */ NULL,
|
||||
/* postxfer_exec; */ NULL,
|
||||
/* prexfer_exec; */ NULL,
|
||||
/* refuse_options; */ NULL,
|
||||
/* secrets_file; */ NULL,
|
||||
/* temp_dir; */ NULL,
|
||||
/* uid; */ NOBODY_USER,
|
||||
|
||||
/* TODO: This causes problems on Debian, where it is called
|
||||
* "nogroup". Debian patch this in their version of the
|
||||
* package, but it would be nice to be consistent. Possibly
|
||||
* other systems are different again.
|
||||
*
|
||||
* What is the best behaviour? Perhaps always using (gid_t)
|
||||
* -2? */
|
||||
"nobody",/* gid */
|
||||
/* max_connections; */ 0,
|
||||
/* max_verbosity; */ 1,
|
||||
/* timeout; */ 0,
|
||||
|
||||
NULL, /* hosts allow */
|
||||
NULL, /* hosts deny */
|
||||
NULL, /* auth users */
|
||||
NULL, /* secrets file */
|
||||
True, /* strict modes */
|
||||
NULL, /* filter */
|
||||
NULL, /* exclude */
|
||||
NULL, /* exclude from */
|
||||
NULL, /* include */
|
||||
NULL, /* include from */
|
||||
"%o %h [%a] %m (%u) %f %l", /* log format */
|
||||
NULL, /* refuse options */
|
||||
"*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /* dont compress */
|
||||
0, /* timeout */
|
||||
0, /* max connections */
|
||||
False /* ignore nonreadable */
|
||||
/* ignore_errors; */ False,
|
||||
/* ignore_nonreadable; */ False,
|
||||
/* list; */ True,
|
||||
/* read_only; */ True,
|
||||
/* strict_modes; */ True,
|
||||
/* transfer_logging; */ False,
|
||||
/* use_chroot; */ True,
|
||||
/* write_only; */ False,
|
||||
};
|
||||
|
||||
|
||||
@@ -269,44 +281,51 @@ static struct enum_list enum_facilities[] = {
|
||||
/* note that we do not initialise the defaults union - it is not allowed in ANSI C */
|
||||
static struct parm_struct parm_table[] =
|
||||
{
|
||||
{"motd file", P_STRING, P_GLOBAL, &Globals.motd_file, NULL, 0},
|
||||
{"syslog facility", P_ENUM, P_GLOBAL, &Globals.syslog_facility, enum_facilities,0},
|
||||
{"socket options", P_STRING, P_GLOBAL, &Globals.socket_options,NULL, 0},
|
||||
{"log file", P_STRING, P_GLOBAL, &Globals.log_file, NULL, 0},
|
||||
{"pid file", P_STRING, P_GLOBAL, &Globals.pid_file, NULL, 0},
|
||||
{"max verbosity", P_INTEGER, P_GLOBAL, &Globals.max_verbosity, NULL, 0},
|
||||
{"port", P_INTEGER, P_GLOBAL, &Globals.rsync_port, NULL, 0},
|
||||
{"address", P_STRING, P_GLOBAL, &Globals.bind_address, NULL, 0},
|
||||
{"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},
|
||||
|
||||
{"timeout", P_INTEGER, P_LOCAL, &sDefault.timeout, NULL, 0},
|
||||
{"max connections", P_INTEGER, P_LOCAL, &sDefault.max_connections,NULL, 0},
|
||||
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL, 0},
|
||||
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, 0},
|
||||
{"lock file", P_STRING, P_LOCAL, &sDefault.lock_file, NULL, 0},
|
||||
{"path", P_PATH, P_LOCAL, &sDefault.path, NULL, 0},
|
||||
{"read only", P_BOOL, P_LOCAL, &sDefault.read_only, NULL, 0},
|
||||
{"write only", P_BOOL, P_LOCAL, &sDefault.write_only, NULL, 0},
|
||||
{"list", P_BOOL, P_LOCAL, &sDefault.list, NULL, 0},
|
||||
{"use chroot", P_BOOL, P_LOCAL, &sDefault.use_chroot, NULL, 0},
|
||||
{"ignore nonreadable",P_BOOL, P_LOCAL, &sDefault.ignore_nonreadable, NULL, 0},
|
||||
{"uid", P_STRING, P_LOCAL, &sDefault.uid, NULL, 0},
|
||||
{"gid", P_STRING, P_LOCAL, &sDefault.gid, NULL, 0},
|
||||
{"hosts allow", P_STRING, P_LOCAL, &sDefault.hosts_allow, NULL, 0},
|
||||
{"hosts deny", P_STRING, P_LOCAL, &sDefault.hosts_deny, NULL, 0},
|
||||
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL, 0},
|
||||
{"secrets file", P_STRING, P_LOCAL, &sDefault.secrets_file,NULL, 0},
|
||||
{"strict modes", P_BOOL, P_LOCAL, &sDefault.strict_modes,NULL, 0},
|
||||
{"filter", P_STRING, P_LOCAL, &sDefault.filter, NULL, 0},
|
||||
{"exclude", P_STRING, P_LOCAL, &sDefault.exclude, NULL, 0},
|
||||
{"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from,NULL, 0},
|
||||
{"include", P_STRING, P_LOCAL, &sDefault.include, NULL, 0},
|
||||
{"include from", P_STRING, P_LOCAL, &sDefault.include_from,NULL, 0},
|
||||
{"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging,NULL,0},
|
||||
{"ignore errors", P_BOOL, P_LOCAL, &sDefault.ignore_errors,NULL,0},
|
||||
{"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0},
|
||||
{"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options,NULL, 0},
|
||||
{"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress,NULL, 0},
|
||||
{NULL, P_BOOL, P_NONE, NULL, NULL, 0}
|
||||
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL,0},
|
||||
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL,0},
|
||||
{"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress, NULL,0},
|
||||
{"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from, NULL,0},
|
||||
{"exclude", P_STRING, P_LOCAL, &sDefault.exclude, NULL,0},
|
||||
{"filter", P_STRING, P_LOCAL, &sDefault.filter, NULL,0},
|
||||
{"gid", P_STRING, P_LOCAL, &sDefault.gid, NULL,0},
|
||||
{"hosts allow", P_STRING, P_LOCAL, &sDefault.hosts_allow, NULL,0},
|
||||
{"hosts deny", P_STRING, P_LOCAL, &sDefault.hosts_deny, NULL,0},
|
||||
{"ignore errors", P_BOOL, P_LOCAL, &sDefault.ignore_errors, NULL,0},
|
||||
{"ignore nonreadable",P_BOOL, P_LOCAL, &sDefault.ignore_nonreadable,NULL,0},
|
||||
{"include from", P_STRING, P_LOCAL, &sDefault.include_from, NULL,0},
|
||||
{"include", P_STRING, P_LOCAL, &sDefault.include, NULL,0},
|
||||
{"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 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},
|
||||
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL,0},
|
||||
{"outgoing chmod", P_STRING, P_LOCAL, &sDefault.outgoing_chmod, NULL,0},
|
||||
{"path", P_PATH, P_LOCAL, &sDefault.path, NULL,0},
|
||||
#ifdef HAVE_PUTENV
|
||||
{"post-xfer exec", P_STRING, P_LOCAL, &sDefault.postxfer_exec, NULL,0},
|
||||
{"pre-xfer exec", P_STRING, P_LOCAL, &sDefault.prexfer_exec, NULL,0},
|
||||
#endif
|
||||
{"read only", P_BOOL, P_LOCAL, &sDefault.read_only, NULL,0},
|
||||
{"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},
|
||||
{"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},
|
||||
{"uid", P_STRING, P_LOCAL, &sDefault.uid, NULL,0},
|
||||
{"use chroot", P_BOOL, P_LOCAL, &sDefault.use_chroot, NULL,0},
|
||||
{"write only", P_BOOL, P_LOCAL, &sDefault.write_only, NULL,0},
|
||||
{NULL, P_BOOL, P_NONE, NULL, NULL,0}
|
||||
};
|
||||
|
||||
|
||||
@@ -319,7 +338,6 @@ static void init_globals(void)
|
||||
#ifdef LOG_DAEMON
|
||||
Globals.syslog_facility = LOG_DAEMON;
|
||||
#endif
|
||||
Globals.max_verbosity = 1;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@@ -354,43 +372,51 @@ static void init_locals(void)
|
||||
int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
|
||||
|
||||
|
||||
FN_GLOBAL_STRING(lp_motd_file, &Globals.motd_file)
|
||||
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_syslog_facility, &Globals.syslog_facility)
|
||||
FN_GLOBAL_INTEGER(lp_max_verbosity, &Globals.max_verbosity)
|
||||
FN_GLOBAL_INTEGER(lp_rsync_port, &Globals.rsync_port)
|
||||
FN_GLOBAL_STRING(lp_bind_address, &Globals.bind_address)
|
||||
|
||||
FN_LOCAL_STRING(lp_name, name)
|
||||
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)
|
||||
FN_LOCAL_STRING(lp_path, path)
|
||||
FN_LOCAL_STRING(lp_lock_file, lock_file)
|
||||
FN_LOCAL_BOOL(lp_read_only, read_only)
|
||||
FN_LOCAL_BOOL(lp_write_only, write_only)
|
||||
FN_LOCAL_BOOL(lp_list, list)
|
||||
FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
|
||||
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
|
||||
FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
|
||||
FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
|
||||
FN_LOCAL_STRING(lp_uid, uid)
|
||||
FN_LOCAL_STRING(lp_dont_compress, dont_compress)
|
||||
FN_LOCAL_STRING(lp_exclude, exclude)
|
||||
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
|
||||
FN_LOCAL_STRING(lp_filter, filter)
|
||||
FN_LOCAL_STRING(lp_gid, gid)
|
||||
FN_LOCAL_STRING(lp_hosts_allow, hosts_allow)
|
||||
FN_LOCAL_STRING(lp_hosts_deny, hosts_deny)
|
||||
FN_LOCAL_STRING(lp_auth_users, auth_users)
|
||||
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
|
||||
FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
|
||||
FN_LOCAL_STRING(lp_filter, filter)
|
||||
FN_LOCAL_STRING(lp_exclude, exclude)
|
||||
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
|
||||
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_format, log_format)
|
||||
FN_LOCAL_STRING(lp_name, name)
|
||||
FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
|
||||
FN_LOCAL_STRING(lp_path, path)
|
||||
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_dont_compress, dont_compress)
|
||||
FN_LOCAL_INTEGER(lp_timeout, timeout)
|
||||
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
|
||||
FN_LOCAL_STRING(lp_temp_dir, temp_dir)
|
||||
FN_LOCAL_STRING(lp_uid, uid)
|
||||
|
||||
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
|
||||
FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
|
||||
FN_LOCAL_INTEGER(lp_timeout, timeout)
|
||||
|
||||
FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
|
||||
FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
|
||||
FN_LOCAL_BOOL(lp_list, list)
|
||||
FN_LOCAL_BOOL(lp_read_only, read_only)
|
||||
FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
|
||||
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
|
||||
FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
|
||||
FN_LOCAL_BOOL(lp_write_only, write_only)
|
||||
|
||||
/* local prototypes */
|
||||
static int strwicmp(char *psz1, char *psz2);
|
||||
@@ -776,7 +802,6 @@ 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;
|
||||
@@ -789,7 +814,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);
|
||||
|
||||
235
log.c
235
log.c
@@ -26,6 +26,9 @@
|
||||
<mbp@samba.org>, Oct 2000.
|
||||
*/
|
||||
#include "rsync.h"
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
@@ -36,12 +39,18 @@ extern int local_server;
|
||||
extern int quiet;
|
||||
extern int module_id;
|
||||
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 mode_t orig_umask;
|
||||
extern char *auth_user;
|
||||
extern char *log_format;
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
extern iconv_t ic_chck;
|
||||
#endif
|
||||
|
||||
static int log_initialised;
|
||||
static int logfile_was_closed;
|
||||
@@ -65,8 +74,11 @@ struct {
|
||||
{ RERR_STREAMIO , "error in rsync protocol data stream" },
|
||||
{ RERR_MESSAGEIO , "errors with program diagnostics" },
|
||||
{ RERR_IPC , "error in IPC code" },
|
||||
{ RERR_SIGNAL , "received SIGUSR1 or SIGINT" },
|
||||
{ RERR_WAITCHILD , "some error returned by waitpid()" },
|
||||
{ RERR_CRASHED , "sibling process crashed" },
|
||||
{ RERR_TERMINATED , "sibling process terminated abnormally" },
|
||||
{ RERR_SIGNAL1 , "received SIGUSR1" },
|
||||
{ RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" },
|
||||
{ RERR_WAITCHILD , "waitpid() failed" },
|
||||
{ RERR_MALLOC , "error allocating core memory buffers" },
|
||||
{ RERR_PARTIAL , "some files could not be transferred" },
|
||||
{ RERR_VANISHED , "some files vanished before they could be transferred" },
|
||||
@@ -80,7 +92,6 @@ struct {
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Map from rsync error code to name, or return NULL.
|
||||
*/
|
||||
@@ -94,7 +105,6 @@ static char const *rerr_name(int code)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void logit(int priority, char *buf)
|
||||
{
|
||||
if (logfile_was_closed)
|
||||
@@ -134,8 +144,7 @@ static void syslog_init()
|
||||
|
||||
static void logfile_open(void)
|
||||
{
|
||||
extern int orig_umask;
|
||||
int old_umask = umask(022 | orig_umask);
|
||||
mode_t old_umask = umask(022 | orig_umask);
|
||||
logfile = fopen(logfname, "a");
|
||||
umask(old_umask);
|
||||
if (!logfile) {
|
||||
@@ -187,20 +196,41 @@ void logfile_reopen(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void filtered_fwrite(FILE *f, const char *buf, int len, int use_isprint)
|
||||
{
|
||||
const char *s, *end = buf + len;
|
||||
for (s = buf; s < end; s++) {
|
||||
if ((s < end - 4
|
||||
&& *s == '\\' && s[1] == '#'
|
||||
&& isdigit(*(uchar*)(s+2))
|
||||
&& isdigit(*(uchar*)(s+3))
|
||||
&& isdigit(*(uchar*)(s+4)))
|
||||
|| (*s != '\t'
|
||||
&& ((use_isprint && !isprint(*(uchar*)s))
|
||||
|| *(uchar*)s < ' '))) {
|
||||
if (s != buf && fwrite(buf, s - buf, 1, f) != 1)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
fprintf(f, "\\#%03o", *(uchar*)s);
|
||||
buf = s + 1;
|
||||
}
|
||||
}
|
||||
if (buf != end && fwrite(buf, end - buf, 1, f) != 1)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
|
||||
/* this is the underlying (unformatted) rsync debugging function. Call
|
||||
* it with FINFO, FERROR or FLOG */
|
||||
* it with FINFO, FERROR or FLOG. Note: recursion can happen with
|
||||
* certain fatal conditions. */
|
||||
void rwrite(enum logcode code, char *buf, int len)
|
||||
{
|
||||
int trailing_CR_or_NL;
|
||||
FILE *f = NULL;
|
||||
/* recursion can happen with certain fatal conditions */
|
||||
|
||||
if (quiet && code == FINFO)
|
||||
return;
|
||||
|
||||
if (len < 0)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
|
||||
buf[len] = 0;
|
||||
if (quiet && code == FINFO)
|
||||
return;
|
||||
|
||||
if (am_server && msg_fd_out >= 0) {
|
||||
/* Pass the message to our sibling. */
|
||||
@@ -208,6 +238,9 @@ void rwrite(enum logcode code, char *buf, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
if (code == FSOCKERR) /* This gets simplified for a non-sibling. */
|
||||
code = FERROR;
|
||||
|
||||
if (code == FCLIENT)
|
||||
code = FINFO;
|
||||
else if (am_daemon) {
|
||||
@@ -239,31 +272,67 @@ void rwrite(enum logcode code, char *buf, int len)
|
||||
}
|
||||
}
|
||||
|
||||
if (code == FERROR) {
|
||||
switch (code) {
|
||||
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:
|
||||
f = am_server ? stderr : stdout;
|
||||
break;
|
||||
default:
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
|
||||
if (code == FINFO)
|
||||
f = am_server ? stderr : stdout;
|
||||
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
|
||||
? buf[--len] : 0;
|
||||
|
||||
if (!f)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
if (ic_chck != (iconv_t)-1) {
|
||||
char convbuf[1024];
|
||||
char *in_buf = buf, *out_buf = convbuf;
|
||||
size_t in_cnt = len, out_cnt = sizeof convbuf - 1;
|
||||
|
||||
if (fwrite(buf, len, 1, f) != 1)
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
iconv(ic_chck, NULL, 0, NULL, 0);
|
||||
while (iconv(ic_chck, &in_buf,&in_cnt,
|
||||
&out_buf,&out_cnt) == (size_t)-1) {
|
||||
if (out_buf != convbuf) {
|
||||
filtered_fwrite(f, convbuf, out_buf - convbuf, 0);
|
||||
out_buf = convbuf;
|
||||
out_cnt = sizeof convbuf - 1;
|
||||
}
|
||||
if (errno == E2BIG)
|
||||
continue;
|
||||
fprintf(f, "\\#%03o", *(uchar*)in_buf++);
|
||||
in_cnt--;
|
||||
}
|
||||
if (out_buf != convbuf)
|
||||
filtered_fwrite(f, convbuf, out_buf - convbuf, 0);
|
||||
} else
|
||||
#endif
|
||||
filtered_fwrite(f, buf, len, !allow_8bit_chars);
|
||||
|
||||
if (buf[len-1] == '\r' || buf[len-1] == '\n')
|
||||
if (trailing_CR_or_NL) {
|
||||
fputc(trailing_CR_or_NL, f);
|
||||
fflush(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This is the rsync debugging function. Call it with FINFO, FERROR or
|
||||
* FLOG. */
|
||||
void rprintf(enum logcode code, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[MAXPATHLEN+512];
|
||||
char buf[BIGPATHBUFLEN];
|
||||
size_t len;
|
||||
|
||||
va_start(ap, format);
|
||||
@@ -274,7 +343,7 @@ void rprintf(enum logcode code, const char *format, ...)
|
||||
* truncate the resulting string. (Note that configure ensures
|
||||
* that we have a vsnprintf() that doesn't ever return -1.) */
|
||||
if (len > sizeof buf - 1) {
|
||||
const char ellipsis[] = "[...]";
|
||||
static const char ellipsis[] = "[...]";
|
||||
|
||||
/* Reset length, and zero-terminate the end of our buffer */
|
||||
len = sizeof buf - 1;
|
||||
@@ -290,7 +359,7 @@ void rprintf(enum logcode code, const char *format, ...)
|
||||
* If the input format string has a trailing newline,
|
||||
* we copy it into that extra null; if it doesn't, well,
|
||||
* all we lose is one byte. */
|
||||
strncpy(buf+len-sizeof ellipsis, ellipsis, sizeof ellipsis);
|
||||
memcpy(buf+len-sizeof ellipsis, ellipsis, sizeof ellipsis);
|
||||
if (format[strlen(format)-1] == '\n') {
|
||||
buf[len-1] = '\n';
|
||||
}
|
||||
@@ -299,7 +368,6 @@ void rprintf(enum logcode code, const char *format, ...)
|
||||
rwrite(code, buf, len);
|
||||
}
|
||||
|
||||
|
||||
/* This is like rprintf, but it also tries to print some
|
||||
* representation of the error code. Normally errcode = errno.
|
||||
*
|
||||
@@ -311,7 +379,7 @@ void rprintf(enum logcode code, const char *format, ...)
|
||||
void rsyserr(enum logcode code, int errcode, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[MAXPATHLEN+512];
|
||||
char buf[BIGPATHBUFLEN];
|
||||
size_t len;
|
||||
|
||||
strcpy(buf, RSYNC_NAME ": ");
|
||||
@@ -331,8 +399,6 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
|
||||
rwrite(code, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void rflush(enum logcode code)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
@@ -360,8 +426,6 @@ void rflush(enum logcode code)
|
||||
fflush(f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* a generic logging routine for send/recv, with parameter
|
||||
* substitiution */
|
||||
static void log_formatted(enum logcode code, char *format, char *op,
|
||||
@@ -399,51 +463,83 @@ static void log_formatted(enum logcode code, char *format, char *op,
|
||||
n = NULL;
|
||||
|
||||
switch (*p) {
|
||||
case 'h': if (am_daemon) n = client_name(0); break;
|
||||
case 'a': if (am_daemon) n = client_addr(0); break;
|
||||
case 'h':
|
||||
if (am_daemon)
|
||||
n = client_name(0);
|
||||
break;
|
||||
case 'a':
|
||||
if (am_daemon)
|
||||
n = client_addr(0);
|
||||
break;
|
||||
case 'l':
|
||||
strlcat(fmt, ".0f", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt,
|
||||
(double)file->length);
|
||||
n = buf2;
|
||||
break;
|
||||
case 'U':
|
||||
strlcat(fmt, "ld", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt,
|
||||
(long)file->uid);
|
||||
n = buf2;
|
||||
break;
|
||||
case 'G':
|
||||
if (file->gid == GID_NONE)
|
||||
n = "DEFAULT";
|
||||
else {
|
||||
strlcat(fmt, "ld", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt,
|
||||
(long)file->gid);
|
||||
n = buf2;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
strlcat(fmt, "ld", sizeof fmt);
|
||||
snprintf(buf2, sizeof buf2, fmt,
|
||||
(long)getpid());
|
||||
n = buf2;
|
||||
break;
|
||||
case 'o': n = op; break;
|
||||
case 'M':
|
||||
n = timestring(file->modtime);
|
||||
{
|
||||
char *cp = n;
|
||||
while ((cp = strchr(cp, ' ')) != NULL)
|
||||
*cp = '-';
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
n = buf2 + MAXPATHLEN - PERMSTRING_SIZE;
|
||||
permstring(n - 1, file->mode); /* skip the type char */
|
||||
break;
|
||||
case 'o':
|
||||
n = op;
|
||||
break;
|
||||
case 'f':
|
||||
n = safe_fname(f_name(file));
|
||||
n = f_name(file, NULL);
|
||||
if (am_sender && file->dir.root) {
|
||||
pathjoin(buf2, sizeof buf2,
|
||||
file->dir.root, n);
|
||||
/* The buffer from safe_fname() has more
|
||||
* room than MAXPATHLEN, so this is safe. */
|
||||
clean_fname(buf2, 0);
|
||||
if (fmt[1])
|
||||
strcpy(n, buf2);
|
||||
strlcpy(n, buf2, MAXPATHLEN);
|
||||
else
|
||||
n = buf2;
|
||||
}
|
||||
clean_fname(n, 0);
|
||||
} else
|
||||
clean_fname(n, 0);
|
||||
if (*n == '/')
|
||||
n++;
|
||||
break;
|
||||
case 'n':
|
||||
n = safe_fname(f_name(file));
|
||||
if (S_ISDIR(file->mode)) {
|
||||
/* The buffer from safe_fname() has more
|
||||
* room than MAXPATHLEN, so this is safe. */
|
||||
strcat(n, "/");
|
||||
}
|
||||
n = f_name(file, NULL);
|
||||
if (S_ISDIR(file->mode))
|
||||
strlcat(n, "/", MAXPATHLEN);
|
||||
break;
|
||||
case 'L':
|
||||
if (hlink && *hlink) {
|
||||
n = safe_fname(hlink);
|
||||
n = hlink;
|
||||
strcpy(buf2, " => ");
|
||||
} else if (S_ISLNK(file->mode) && file->u.link) {
|
||||
n = safe_fname(file->u.link);
|
||||
n = file->u.link;
|
||||
strcpy(buf2, " -> ");
|
||||
} else {
|
||||
n = "";
|
||||
@@ -455,10 +551,18 @@ static void log_formatted(enum logcode code, char *format, char *op,
|
||||
snprintf(buf2 + 4, sizeof buf2 - 4, fmt, n);
|
||||
n = buf2;
|
||||
break;
|
||||
case 'm': n = lp_name(module_id); break;
|
||||
case 't': n = timestring(time(NULL)); break;
|
||||
case 'P': n = lp_path(module_id); break;
|
||||
case 'u': n = auth_user; break;
|
||||
case 'm':
|
||||
n = lp_name(module_id);
|
||||
break;
|
||||
case 't':
|
||||
n = timestring(time(NULL));
|
||||
break;
|
||||
case 'P':
|
||||
n = lp_path(module_id);
|
||||
break;
|
||||
case 'u':
|
||||
n = auth_user;
|
||||
break;
|
||||
case 'b':
|
||||
if (am_sender) {
|
||||
b = stats.total_written -
|
||||
@@ -494,17 +598,17 @@ static void log_formatted(enum logcode code, char *format, char *op,
|
||||
: !(iflags & ITEM_TRANSFER) ? '.'
|
||||
: !local_server && *op == 's' ? '<' : '>';
|
||||
n[1] = S_ISDIR(file->mode) ? 'd'
|
||||
: IS_SPECIAL(file->mode) ? 'S'
|
||||
: IS_DEVICE(file->mode) ? 'D'
|
||||
: S_ISLNK(file->mode) ? 'L' : 'f';
|
||||
n[2] = !(iflags & ITEM_REPORT_CHECKSUM) ? '.' : 'c';
|
||||
n[3] = !(iflags & ITEM_REPORT_SIZE) ? '.' : 's';
|
||||
n[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
|
||||
: !preserve_times || IS_DEVICE(file->mode)
|
||||
|| S_ISLNK(file->mode) ? 'T' : 't';
|
||||
: !preserve_times || S_ISLNK(file->mode) ? 'T' : 't';
|
||||
n[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
|
||||
n[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
|
||||
n[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
|
||||
n[8] = !(iflags & ITEM_REPORT_XATTRS) ? '.' : 'a';
|
||||
n[8] = '.';
|
||||
n[9] = '\0';
|
||||
|
||||
if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
|
||||
@@ -512,7 +616,8 @@ static void log_formatted(enum logcode code, char *format, char *op,
|
||||
int i;
|
||||
for (i = 2; n[i]; i++)
|
||||
n[i] = ch;
|
||||
} else if (!(iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE))) {
|
||||
} else if (n[0] == '.' || n[0] == 'h'
|
||||
|| (n[0] == 'c' && n[1] == 'f')) {
|
||||
int i;
|
||||
for (i = 2; n[i]; i++) {
|
||||
if (n[i] != '.')
|
||||
@@ -594,7 +699,7 @@ void log_item(struct file_struct *file, struct stats *initial_stats,
|
||||
log_formatted(FLOG, lp_log_format(module_id), s_or_r,
|
||||
file, initial_stats, iflags, hlink);
|
||||
} else if (log_format && !am_server) {
|
||||
log_formatted(FINFO, log_format, s_or_r,
|
||||
log_formatted(FNAME, log_format, s_or_r,
|
||||
file, initial_stats, iflags, hlink);
|
||||
}
|
||||
}
|
||||
@@ -602,12 +707,15 @@ void log_item(struct file_struct *file, struct stats *initial_stats,
|
||||
void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
|
||||
char *buf)
|
||||
{
|
||||
int see_item = itemizing && (iflags || verbose > 1);
|
||||
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));
|
||||
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);
|
||||
} else if (see_item || iflags & ITEM_LOCAL_CHANGE || *buf
|
||||
|| (S_ISDIR(file->mode) && iflags & SIGNIFICANT_ITEM_FLAGS))
|
||||
} else if (see_item || local_change || *buf
|
||||
|| (S_ISDIR(file->mode) && significant_flags))
|
||||
log_item(file, &stats, iflags, buf);
|
||||
}
|
||||
|
||||
@@ -639,7 +747,6 @@ void log_delete(char *fname, int mode)
|
||||
log_formatted(FLOG, fmt, "del.", &file, &stats, ITEM_DELETED, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called when the transfer is interrupted for some reason.
|
||||
*
|
||||
@@ -662,11 +769,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)\n",
|
||||
name, code, file, line);
|
||||
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)\n",
|
||||
name, code, file, line);
|
||||
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s=%s]\n",
|
||||
name, code, file, line, who_am_i(), RSYNC_VERSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
417
main.c
417
main.c
@@ -40,17 +40,14 @@ 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 fuzzy_basis;
|
||||
extern int relative_paths;
|
||||
extern int rsync_port;
|
||||
extern int inplace;
|
||||
extern int make_backups;
|
||||
extern int whole_file;
|
||||
extern int read_batch;
|
||||
extern int write_batch;
|
||||
@@ -60,22 +57,30 @@ 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;
|
||||
|
||||
int local_server = 0;
|
||||
mode_t orig_umask = 0;
|
||||
struct file_list *the_file_list;
|
||||
|
||||
/* There's probably never more than at most 2 outstanding child processes,
|
||||
* but set it higher, just in case. */
|
||||
#define MAXCHILDPROCS 5
|
||||
#define MAXCHILDPROCS 7
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
# ifdef HAVE_SIGPROCMASK
|
||||
# define SIGACTMASK(n,h) SIGACTION(n,h), sigaddset(&sigmask,(n))
|
||||
# else
|
||||
# define SIGACTMASK(n,h) SIGACTION(n,h)
|
||||
# endif
|
||||
static struct sigaction sigact;
|
||||
#endif
|
||||
|
||||
struct pid_status {
|
||||
pid_t pid;
|
||||
int status;
|
||||
int status;
|
||||
} pid_stat_table[MAXCHILDPROCS];
|
||||
|
||||
static time_t starttime, endtime;
|
||||
@@ -83,38 +88,58 @@ static int64 total_read, total_written;
|
||||
|
||||
static void show_malloc_stats(void);
|
||||
|
||||
/****************************************************************************
|
||||
wait for a process to exit, calling io_flush while waiting
|
||||
****************************************************************************/
|
||||
void wait_process(pid_t pid, int *status)
|
||||
/* Works like waitpid(), but if we already harvested the child pid in our
|
||||
* 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;
|
||||
int cnt;
|
||||
|
||||
while ((waited_pid = waitpid(pid, status, WNOHANG)) == 0) {
|
||||
msleep(20);
|
||||
io_flush(FULL_FLUSH);
|
||||
}
|
||||
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 the sigchld_handler.
|
||||
*/
|
||||
for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
|
||||
/* Status of requested child no longer available: check to
|
||||
* see if it was processed by remember_children(). */
|
||||
int cnt;
|
||||
for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
|
||||
if (pid == pid_stat_table[cnt].pid) {
|
||||
*status = pid_stat_table[cnt].status;
|
||||
*status_ptr = pid_stat_table[cnt].status;
|
||||
pid_stat_table[cnt].pid = 0;
|
||||
break;
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return waited_pid;
|
||||
}
|
||||
|
||||
/* Wait for a process to exit, calling io_flush while waiting. */
|
||||
static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
|
||||
{
|
||||
pid_t waited_pid;
|
||||
int status;
|
||||
|
||||
while ((waited_pid = wait_process(pid, &status, WNOHANG)) == 0) {
|
||||
msleep(20);
|
||||
io_flush(FULL_FLUSH);
|
||||
}
|
||||
|
||||
/* TODO: If the child exited on a signal, then log an
|
||||
* appropriate error message. Perhaps we should also accept a
|
||||
* message describing the purpose of the child. Also indicate
|
||||
* this to the caller so that thhey know something went
|
||||
* wrong. */
|
||||
*status = WEXITSTATUS(*status);
|
||||
* this to the caller so that they know something went wrong. */
|
||||
if (waited_pid < 0) {
|
||||
rsyserr(FERROR, errno, "waitpid");
|
||||
*exit_code_ptr = RERR_WAITCHILD;
|
||||
} else if (!WIFEXITED(status)) {
|
||||
#ifdef WCOREDUMP
|
||||
if (WCOREDUMP(status))
|
||||
*exit_code_ptr = RERR_CRASHED;
|
||||
else
|
||||
#endif
|
||||
if (WIFSIGNALED(status))
|
||||
*exit_code_ptr = RERR_TERMINATED;
|
||||
else
|
||||
*exit_code_ptr = RERR_WAITCHILD;
|
||||
} else
|
||||
*exit_code_ptr = WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
/* This function gets called from all 3 processes. We want the client side
|
||||
@@ -194,14 +219,14 @@ static void output_summary(void)
|
||||
rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
|
||||
rprintf(FINFO,"Number of files transferred: %d\n",
|
||||
stats.num_transferred_files);
|
||||
rprintf(FINFO,"Total file size: %.0f bytes\n",
|
||||
(double)stats.total_size);
|
||||
rprintf(FINFO,"Total transferred file size: %.0f bytes\n",
|
||||
(double)stats.total_transferred_size);
|
||||
rprintf(FINFO,"Literal data: %.0f bytes\n",
|
||||
(double)stats.literal_data);
|
||||
rprintf(FINFO,"Matched data: %.0f bytes\n",
|
||||
(double)stats.matched_data);
|
||||
rprintf(FINFO,"Total file size: %s bytes\n",
|
||||
human_num(stats.total_size));
|
||||
rprintf(FINFO,"Total transferred file size: %s bytes\n",
|
||||
human_num(stats.total_transferred_size));
|
||||
rprintf(FINFO,"Literal data: %s bytes\n",
|
||||
human_num(stats.literal_data));
|
||||
rprintf(FINFO,"Matched data: %s bytes\n",
|
||||
human_num(stats.matched_data));
|
||||
rprintf(FINFO,"File list size: %d\n", stats.flist_size);
|
||||
if (stats.flist_buildtime) {
|
||||
rprintf(FINFO,
|
||||
@@ -211,19 +236,19 @@ static void output_summary(void)
|
||||
"File list transfer time: %.3f seconds\n",
|
||||
(double)stats.flist_xfertime / 1000);
|
||||
}
|
||||
rprintf(FINFO,"Total bytes sent: %.0f\n",
|
||||
(double)total_written);
|
||||
rprintf(FINFO,"Total bytes received: %.0f\n",
|
||||
(double)total_read);
|
||||
rprintf(FINFO,"Total bytes sent: %s\n",
|
||||
human_num(total_written));
|
||||
rprintf(FINFO,"Total bytes received: %s\n",
|
||||
human_num(total_read));
|
||||
}
|
||||
|
||||
if (verbose || do_stats) {
|
||||
rprintf(FINFO,
|
||||
"\nsent %.0f bytes received %.0f bytes %.2f bytes/sec\n",
|
||||
(double)total_written, (double)total_read,
|
||||
(total_written + total_read)/(0.5 + (endtime - starttime)));
|
||||
rprintf(FINFO, "total size is %.0f speedup is %.2f\n",
|
||||
(double)stats.total_size,
|
||||
"\nsent %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",
|
||||
human_num(stats.total_size),
|
||||
(double)stats.total_size / (total_written+total_read));
|
||||
}
|
||||
|
||||
@@ -278,10 +303,11 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
|
||||
int i, argc = 0;
|
||||
char *args[MAX_ARGS];
|
||||
pid_t ret;
|
||||
char *tok, *dir = NULL;
|
||||
char *dir = NULL;
|
||||
int dash_l_set = 0;
|
||||
|
||||
if (!read_batch && !local_server) {
|
||||
char *t, *f, in_quote = '\0';
|
||||
char *rsh_env = getenv(RSYNC_RSH_ENV);
|
||||
if (!cmd)
|
||||
cmd = rsh_env;
|
||||
@@ -291,13 +317,39 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
|
||||
if (!cmd)
|
||||
goto oom;
|
||||
|
||||
for (tok = strtok(cmd, " "); tok; tok = strtok(NULL, " ")) {
|
||||
for (t = f = cmd; *f; f++) {
|
||||
if (*f == ' ')
|
||||
continue;
|
||||
/* Comparison leaves rooms for server_options(). */
|
||||
if (argc >= MAX_ARGS - MAX_SERVER_ARGS) {
|
||||
rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
args[argc++] = tok;
|
||||
args[argc++] = t;
|
||||
while (*f != ' ' || in_quote) {
|
||||
if (!*f) {
|
||||
if (in_quote) {
|
||||
rprintf(FERROR,
|
||||
"Missing trailing-%c in remote-shell command.\n",
|
||||
in_quote);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
f--;
|
||||
break;
|
||||
}
|
||||
if (*f == '\'' || *f == '"') {
|
||||
if (!in_quote) {
|
||||
in_quote = *f++;
|
||||
continue;
|
||||
}
|
||||
if (*f == in_quote && *++f != in_quote) {
|
||||
in_quote = '\0';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*t++ = *f++;
|
||||
}
|
||||
*t++ = '\0';
|
||||
}
|
||||
|
||||
/* check to see if we've already been given '-l user' in
|
||||
@@ -350,10 +402,9 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
|
||||
args[argc] = NULL;
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,"cmd=");
|
||||
for (i = 0; i < argc; i++)
|
||||
rprintf(FINFO, "%s ", safe_fname(args[i]));
|
||||
rprintf(FINFO,"\n");
|
||||
rprintf(FINFO, "cmd[%d]=%s ", i, args[i]);
|
||||
rprintf(FINFO, "\n");
|
||||
}
|
||||
|
||||
if (read_batch) {
|
||||
@@ -380,62 +431,122 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
|
||||
|
||||
return ret;
|
||||
|
||||
oom:
|
||||
oom:
|
||||
out_of_memory("do_cmd");
|
||||
return 0; /* not reached */
|
||||
}
|
||||
|
||||
|
||||
static char *get_local_name(struct file_list *flist,char *name)
|
||||
/* The receiving side operates in one of two modes:
|
||||
*
|
||||
* 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. */
|
||||
static char *get_local_name(struct file_list *flist, char *dest_path)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
int e;
|
||||
char *cp;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"get_local_name count=%d %s\n",
|
||||
flist->count, NS(name));
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "get_local_name count=%d %s\n",
|
||||
flist->count, NS(dest_path));
|
||||
}
|
||||
|
||||
if (!name)
|
||||
if (!dest_path || list_only)
|
||||
return NULL;
|
||||
|
||||
if (do_stat(name,&st) == 0) {
|
||||
/* 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) {
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (!push_dir(name)) {
|
||||
if (!push_dir(dest_path)) {
|
||||
rsyserr(FERROR, errno, "push_dir#1 %s failed",
|
||||
full_fname(name));
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (flist->count > 1) {
|
||||
rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
|
||||
rprintf(FERROR,
|
||||
"ERROR: destination must be a directory when"
|
||||
" copying more than 1 file\n");
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
if (flist->count <= 1 && ((e = strlen(name)) <= 1 || name[e-1] != '/'))
|
||||
return name;
|
||||
|
||||
if (do_mkdir(name,0777 & ~orig_umask) != 0) {
|
||||
rsyserr(FERROR, errno, "mkdir %s failed", full_fname(name));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO, "created directory %s\n", safe_fname(name));
|
||||
|
||||
if (dry_run) {
|
||||
dry_run++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!push_dir(name)) {
|
||||
rsyserr(FERROR, errno, "push_dir#2 %s failed",
|
||||
full_fname(name));
|
||||
/* 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) {
|
||||
rsyserr(FERROR, errno, "cannot stat destination %s",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
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 (flist->count > 1 || (cp && !cp[1])) {
|
||||
/* Lop off the final slash (if any). */
|
||||
if (cp && !cp[1])
|
||||
*cp = '\0';
|
||||
|
||||
if (mkdir_defmode(dest_path) != 0) {
|
||||
rsyserr(FERROR, errno, "mkdir %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
|
||||
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. */
|
||||
dry_run++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!push_dir(dest_path)) {
|
||||
rsyserr(FERROR, errno, "push_dir#2 %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Otherwise, we are writing a single file, possibly on top of an
|
||||
* existing non-directory. Change to the item's parent directory
|
||||
* (if it has a path component), return the basename of the
|
||||
* destination file as the local name, and use mode 2. */
|
||||
if (!cp)
|
||||
return dest_path;
|
||||
|
||||
if (cp == dest_path)
|
||||
dest_path = "/";
|
||||
|
||||
*cp = '\0';
|
||||
if (!push_dir(dest_path)) {
|
||||
rsyserr(FERROR, errno, "push_dir#3 %s failed",
|
||||
full_fname(dest_path));
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
*cp = '/';
|
||||
|
||||
return cp + 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -463,9 +574,8 @@ static void read_final_goodbye(int f_in, int f_out)
|
||||
}
|
||||
|
||||
|
||||
static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
|
||||
static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
struct file_list *flist;
|
||||
char *dir = argv[0];
|
||||
|
||||
@@ -494,14 +604,6 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (strcmp(dir,".")) {
|
||||
int l = strlen(dir);
|
||||
if (strcmp(dir,"/") == 0)
|
||||
l = 0;
|
||||
for (i = 0; i < argc; i++)
|
||||
argv[i] += l+1;
|
||||
}
|
||||
|
||||
if (argc == 0 && (recurse || list_only)) {
|
||||
argc = 1;
|
||||
argv--;
|
||||
@@ -530,12 +632,12 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
|
||||
static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
|
||||
{
|
||||
int pid;
|
||||
int status = 0;
|
||||
int exit_code = 0;
|
||||
int error_pipe[2];
|
||||
|
||||
/* 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();
|
||||
@@ -616,14 +718,14 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
|
||||
|
||||
set_msg_fd_in(-1);
|
||||
kill(pid, SIGUSR2);
|
||||
wait_process(pid, &status);
|
||||
return status;
|
||||
wait_process_with_flush(pid, &exit_code);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
|
||||
static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
|
||||
{
|
||||
int status;
|
||||
int exit_code;
|
||||
struct file_list *flist;
|
||||
char *local_name = NULL;
|
||||
char *dir = NULL;
|
||||
@@ -646,7 +748,6 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (argc > 0) {
|
||||
dir = argv[0];
|
||||
argc--;
|
||||
@@ -679,17 +780,11 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
|
||||
}
|
||||
the_file_list = flist;
|
||||
|
||||
if (argc > 0) {
|
||||
if (strcmp(dir,".")) {
|
||||
argv[0] += strlen(dir);
|
||||
if (argv[0][0] == '/')
|
||||
argv[0]++;
|
||||
}
|
||||
if (argc > 0)
|
||||
local_name = get_local_name(flist,argv[0]);
|
||||
}
|
||||
|
||||
status = do_recv(f_in,f_out,flist,local_name);
|
||||
exit_cleanup(status);
|
||||
exit_code = do_recv(f_in,f_out,flist,local_name);
|
||||
exit_cleanup(exit_code);
|
||||
}
|
||||
|
||||
|
||||
@@ -707,6 +802,9 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
|
||||
|
||||
io_set_sock_fds(f_in, f_out);
|
||||
setup_protocol(f_out, f_in);
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
setup_iconv();
|
||||
#endif
|
||||
|
||||
if (protocol_version >= 23)
|
||||
io_start_multiplex_out();
|
||||
@@ -732,7 +830,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
|
||||
int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
{
|
||||
struct file_list *flist = NULL;
|
||||
int status = 0, status2 = 0;
|
||||
int exit_code = 0, exit_code2 = 0;
|
||||
char *local_name = NULL;
|
||||
|
||||
cleanup_child_pid = pid;
|
||||
@@ -743,6 +841,9 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
|
||||
io_set_sock_fds(f_in, f_out);
|
||||
setup_protocol(f_out,f_in);
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
setup_iconv();
|
||||
#endif
|
||||
|
||||
if (protocol_version >= 23 && !read_batch)
|
||||
io_start_multiplex_in();
|
||||
@@ -784,11 +885,11 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
|
||||
io_flush(FULL_FLUSH);
|
||||
wait_process(pid, &status);
|
||||
wait_process_with_flush(pid, &exit_code);
|
||||
}
|
||||
output_summary();
|
||||
io_flush(FULL_FLUSH);
|
||||
exit_cleanup(status);
|
||||
exit_cleanup(exit_code);
|
||||
}
|
||||
|
||||
if (need_messages_from_generator && !read_batch)
|
||||
@@ -812,7 +913,7 @@ 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]);
|
||||
|
||||
status2 = do_recv(f_in, f_out, flist, local_name);
|
||||
exit_code2 = do_recv(f_in, f_out, flist, local_name);
|
||||
} else {
|
||||
handle_stats(-1);
|
||||
output_summary();
|
||||
@@ -822,10 +923,10 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
|
||||
io_flush(FULL_FLUSH);
|
||||
wait_process(pid, &status);
|
||||
wait_process_with_flush(pid, &exit_code);
|
||||
}
|
||||
|
||||
return MAX(status, status2);
|
||||
return MAX(exit_code, exit_code2);
|
||||
}
|
||||
|
||||
static int copy_argv (char *argv[])
|
||||
@@ -869,9 +970,16 @@ 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)) {
|
||||
rprintf(FERROR,
|
||||
"The source and destination cannot both be remote.\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
argv++;
|
||||
if (filesfrom_host && *filesfrom_host
|
||||
&& strcmp(filesfrom_host, shell_machine) != 0) {
|
||||
@@ -892,12 +1000,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,
|
||||
@@ -912,7 +1022,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,
|
||||
@@ -942,10 +1052,10 @@ static int start_client(int argc, char *argv[])
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
|
||||
shell_cmd ? safe_fname(shell_cmd) : "",
|
||||
shell_machine ? safe_fname(shell_machine) : "",
|
||||
shell_user ? safe_fname(shell_user) : "",
|
||||
shell_path ? safe_fname(shell_path) : "");
|
||||
shell_cmd ? shell_cmd : "",
|
||||
shell_machine ? shell_machine : "",
|
||||
shell_user ? shell_user : "",
|
||||
shell_path ? shell_path : "");
|
||||
}
|
||||
|
||||
/* for remote source, only single dest arg can remain ... */
|
||||
@@ -982,7 +1092,7 @@ static int start_client(int argc, char *argv[])
|
||||
|
||||
static RETSIGTYPE sigusr1_handler(UNUSED(int val))
|
||||
{
|
||||
exit_cleanup(RERR_SIGNAL);
|
||||
exit_cleanup(RERR_SIGNAL1);
|
||||
}
|
||||
|
||||
static RETSIGTYPE sigusr2_handler(UNUSED(int val))
|
||||
@@ -995,7 +1105,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;
|
||||
@@ -1004,8 +1114,7 @@ static RETSIGTYPE sigchld_handler(UNUSED(int val))
|
||||
* get him to explain why he put it in, so rather than taking it
|
||||
* out we're instead saving the child exit statuses for later use.
|
||||
* The waitpid() loop presumably eliminates all possibility of leaving
|
||||
* zombie children, maybe that's why he did it.
|
||||
*/
|
||||
* zombie children, maybe that's why he did it. */
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||
/* save the child's exit status */
|
||||
for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
|
||||
@@ -1017,6 +1126,9 @@ static RETSIGTYPE sigchld_handler(UNUSED(int val))
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef HAVE_SIGACTION
|
||||
signal(SIGCHLD, remember_children);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1076,16 +1188,23 @@ int main(int argc,char *argv[])
|
||||
int ret;
|
||||
int orig_argc = argc;
|
||||
char **orig_argv = argv;
|
||||
#ifdef HAVE_SIGACTION
|
||||
# ifdef HAVE_SIGPROCMASK
|
||||
sigset_t sigmask;
|
||||
|
||||
signal(SIGUSR1, sigusr1_handler);
|
||||
signal(SIGUSR2, sigusr2_handler);
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
sigemptyset(&sigmask);
|
||||
# endif
|
||||
sigact.sa_flags = SA_NOCLDSTOP;
|
||||
#endif
|
||||
SIGACTMASK(SIGUSR1, sigusr1_handler);
|
||||
SIGACTMASK(SIGUSR2, sigusr2_handler);
|
||||
SIGACTMASK(SIGCHLD, remember_children);
|
||||
#ifdef MAINTAINER_MODE
|
||||
signal(SIGSEGV, rsync_panic_handler);
|
||||
signal(SIGFPE, rsync_panic_handler);
|
||||
signal(SIGABRT, rsync_panic_handler);
|
||||
signal(SIGBUS, rsync_panic_handler);
|
||||
#endif /* def MAINTAINER_MODE */
|
||||
SIGACTMASK(SIGSEGV, rsync_panic_handler);
|
||||
SIGACTMASK(SIGFPE, rsync_panic_handler);
|
||||
SIGACTMASK(SIGABRT, rsync_panic_handler);
|
||||
SIGACTMASK(SIGBUS, rsync_panic_handler);
|
||||
#endif
|
||||
|
||||
starttime = time(NULL);
|
||||
am_root = (MY_UID() == 0);
|
||||
@@ -1099,7 +1218,11 @@ 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, "");
|
||||
#endif
|
||||
|
||||
if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
|
||||
/* FIXME: We ought to call the same error-handling
|
||||
@@ -1108,16 +1231,18 @@ int main(int argc,char *argv[])
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
signal(SIGINT,SIGNAL_CAST sig_int);
|
||||
signal(SIGHUP,SIGNAL_CAST sig_int);
|
||||
signal(SIGTERM,SIGNAL_CAST sig_int);
|
||||
SIGACTMASK(SIGINT, sig_int);
|
||||
SIGACTMASK(SIGHUP, sig_int);
|
||||
SIGACTMASK(SIGTERM, sig_int);
|
||||
#if defined HAVE_SIGACTION && HAVE_SIGPROCMASK
|
||||
sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
|
||||
#endif
|
||||
|
||||
/* Ignore SIGPIPE; we consistently check error codes and will
|
||||
* see the EPIPE. */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
#if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
|
||||
setlocale(LC_CTYPE, "");
|
||||
SIGACTION(SIGPIPE, SIG_IGN);
|
||||
#ifdef SIGXFSZ
|
||||
SIGACTION(SIGXFSZ, SIG_IGN);
|
||||
#endif
|
||||
|
||||
/* Initialize push_dir here because on some old systems getcwd
|
||||
|
||||
132
match.c
132
match.c
@@ -20,69 +20,47 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +105,6 @@ static void matched(int f, struct sum_struct *s, struct map_struct *buf,
|
||||
sum_update(map_ptr(buf, last_match + j, n1), n1);
|
||||
}
|
||||
|
||||
|
||||
if (i >= 0)
|
||||
last_match = offset + s->sums[i].len;
|
||||
else
|
||||
@@ -177,20 +154,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 +185,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 +206,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 +222,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 +248,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,12 +305,31 @@ 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;
|
||||
|
||||
sum_init(checksum_seed);
|
||||
|
||||
if (append_mode) {
|
||||
OFF_T j = 0;
|
||||
for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
|
||||
if (buf && do_progress)
|
||||
show_progress(last_match, buf->file_size);
|
||||
sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
|
||||
CHUNK_SIZE);
|
||||
last_match = j;
|
||||
}
|
||||
if (last_match < s->flength) {
|
||||
int32 len = s->flength - last_match;
|
||||
if (buf && do_progress)
|
||||
show_progress(last_match, buf->file_size);
|
||||
sum_update(map_ptr(buf, last_match, len), len);
|
||||
last_match = s->flength;
|
||||
}
|
||||
s->count = 0;
|
||||
}
|
||||
|
||||
if (len > 0 && s->count > 0) {
|
||||
build_hash_table(s);
|
||||
|
||||
@@ -343,7 +343,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
} else {
|
||||
OFF_T j;
|
||||
/* by doing this in pieces we avoid too many seeks */
|
||||
for (j = CHUNK_SIZE; j < len; j += CHUNK_SIZE)
|
||||
for (j = last_match + CHUNK_SIZE; j < len; j += CHUNK_SIZE)
|
||||
matched(f, s, buf, j, -2);
|
||||
matched(f, s, buf, len, -1);
|
||||
}
|
||||
@@ -357,16 +357,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;
|
||||
@@ -378,8 +373,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);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ BEGIN {
|
||||
next;
|
||||
}
|
||||
|
||||
!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^uchar|^short|^struct|^BOOL|^void|^time|^const/ {
|
||||
!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^uchar|^short|^struct|^BOOL|^void|^time|^const|^RETSIGTYPE/ {
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Summary: A program for synchronizing files over a network.
|
||||
Name: rsync
|
||||
Version: 2.6.5
|
||||
Version: 2.6.8
|
||||
Release: 1
|
||||
Group: Applications/Internet
|
||||
Source: ftp://rsync.samba.org/pub/rsync/rsync-%{version}.tar.gz
|
||||
|
||||
116
packaging/nightly-rsync
Executable file
116
packaging/nightly-rsync
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/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($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 $!;
|
||||
}
|
||||
|
||||
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) {
|
||||
$ENV{RSYNC_PARTIAL_DIR} = ''; # The rsync on samba.org is OLD.
|
||||
system "rsync -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
|
||||
}
|
||||
320
packaging/release-rsync
Executable file
320
packaging/release-rsync
Executable file
@@ -0,0 +1,320 @@
|
||||
#!/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;
|
||||
} else {
|
||||
s/^(NEWS for rsync \Q$version\E) \(UNRELEASED\)\s*\n/$1 ($today)\n/m;
|
||||
s/^\t\S\S\s\S\S\S\s\d\d\d\d(\t\Q$version\E)/\t$ztoday$1/m;
|
||||
}
|
||||
open(OUT, '>', $fn) or die $!;
|
||||
print OUT $_;
|
||||
close OUT;
|
||||
}
|
||||
|
||||
system "yodl2man -o rsync.1 rsync.yo";
|
||||
system "yodl2man -o rsyncd.conf.5 rsyncd.conf.yo";
|
||||
#system "perl -pi -e \"s/\\\\\\'/\\\\&'/g\" rsync.1 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
|
||||
- copy 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')) {
|
||||
my $new_fn = "old-previews/$fn";
|
||||
rename($fn, $new_fn) or die $!;
|
||||
push(@moved_files, $new_fn);
|
||||
}
|
||||
|
||||
if ($version !~ /pre/) {
|
||||
foreach my $fn (glob('rsync*.tar.gz*'), glob('rsync*-NEWS')) {
|
||||
next if $fn =~ /^rsync.*pre/;
|
||||
my $new_fn = "old-versions/$fn";
|
||||
rename($fn, $new_fn) or die $!;
|
||||
push(@moved_files, $new_fn);
|
||||
}
|
||||
|
||||
foreach my $fn (glob('rsync*.diffs.gz*')) {
|
||||
next if $fn =~ /^rsync.*pre/;
|
||||
my $new_fn = "old-patches/$fn";
|
||||
rename($fn, $new_fn) or die $!;
|
||||
push(@moved_files, $new_fn);
|
||||
}
|
||||
}
|
||||
|
||||
# Optimize our future upload (in the absence of --detect-renamed) by
|
||||
# copying the above moved files on the remote server.
|
||||
if ($live) {
|
||||
my $remote_cmd = '';
|
||||
foreach (@moved_files) {
|
||||
my($path, $fn) = m#(.*)/([^/]+)$#;
|
||||
$remote_cmd .= "cp -p /home/ftp/pub/rsync/{$fn,$path};";
|
||||
}
|
||||
system "ssh samba.org '$remote_cmd'";
|
||||
}
|
||||
foreach (glob("rsync*pre*.diffs.gz*")) {
|
||||
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";
|
||||
}
|
||||
4
params.c
4
params.c
@@ -491,8 +491,8 @@ static FILE *OpenConfFile( char *FileName )
|
||||
OpenedFile = fopen( FileName, "r" );
|
||||
if( NULL == OpenedFile )
|
||||
{
|
||||
rsyserr(FERROR, errno, "rsync: unable to open configuration file \"%s\"",
|
||||
safe_fname(FileName));
|
||||
rsyserr(FERROR, errno, "unable to open configuration file \"%s\"",
|
||||
FileName);
|
||||
}
|
||||
|
||||
return( OpenedFile );
|
||||
|
||||
21
pipe.c
21
pipe.c
@@ -24,11 +24,12 @@
|
||||
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 struct chmod_mode_struct *chmod_modes;
|
||||
|
||||
/**
|
||||
* Create a child connected to use on stdin/stdout.
|
||||
* Create a child connected to us via its stdin/stdout.
|
||||
*
|
||||
* This is derived from CVS code
|
||||
*
|
||||
@@ -78,8 +79,7 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
|
||||
if (blocking_io > 0)
|
||||
set_blocking(STDOUT_FILENO);
|
||||
execvp(command[0], command);
|
||||
rsyserr(FERROR, errno, "Failed to exec %s",
|
||||
safe_fname(command[0]));
|
||||
rsyserr(FERROR, errno, "Failed to exec %s", command[0]);
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
@@ -111,6 +111,9 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
|
||||
/* The parent process is always the sender for a local rsync. */
|
||||
assert(am_sender);
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 ||
|
||||
fd_pair(from_child_pipe) < 0) {
|
||||
rsyserr(FERROR, errno, "pipe");
|
||||
@@ -124,11 +127,10 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
am_sender = !am_sender;
|
||||
am_sender = 0;
|
||||
am_server = 1;
|
||||
|
||||
if (!am_sender)
|
||||
filesfrom_fd = -1;
|
||||
filesfrom_fd = -1;
|
||||
chmod_modes = NULL; /* Let the sending side handle this. */
|
||||
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
@@ -144,9 +146,6 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
|
||||
child_main(argc, argv);
|
||||
}
|
||||
|
||||
if (!am_sender)
|
||||
filesfrom_fd = -1;
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 ||
|
||||
close(to_child_pipe[0]) < 0) {
|
||||
rsyserr(FERROR, errno, "Failed to close");
|
||||
|
||||
12
prepare-source
Executable file
12
prepare-source
Executable file
@@ -0,0 +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.
|
||||
#
|
||||
# NOTE: if you use a diff from the "patches" directory in a release
|
||||
# tar, this is not needed (but doesn't hurt anything).
|
||||
dir=`dirname $0`
|
||||
if test x"$dir" != x -o x"$dir" != x.; then
|
||||
cd "$dir"
|
||||
fi
|
||||
make -f prepare-source.mak
|
||||
23
prepare-source.mak
Normal file
23
prepare-source.mak
Normal file
@@ -0,0 +1,23 @@
|
||||
gen: configure config.h.in proto.h man
|
||||
|
||||
configure: configure.in aclocal.m4
|
||||
autoconf
|
||||
|
||||
config.h.in: configure.in aclocal.m4
|
||||
autoheader && touch config.h.in
|
||||
|
||||
proto.h: *.c lib/compat.c
|
||||
cat *.c lib/compat.c | awk -f mkproto.awk >proto.h.new
|
||||
if diff proto.h proto.h.new >/dev/null; then \
|
||||
rm proto.h.new; \
|
||||
else \
|
||||
mv proto.h.new proto.h; \
|
||||
fi
|
||||
|
||||
man: rsync.1 rsyncd.conf.5
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man -o rsync.1 rsync.yo
|
||||
|
||||
rsyncd.conf.5: rsyncd.conf.yo
|
||||
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
|
||||
@@ -97,15 +97,14 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
remain_h = (int) (remain / 3600.0);
|
||||
|
||||
if (is_last) {
|
||||
snprintf(eol, sizeof eol, " (%d, %.1f%% of %d)\n",
|
||||
snprintf(eol, sizeof eol, " (xfer#%d, to-check=%d/%d)\n",
|
||||
stats.num_transferred_files,
|
||||
(float)((stats.current_file_index+1) * 100)
|
||||
/ stats.num_files,
|
||||
stats.num_files - stats.current_file_index - 1,
|
||||
stats.num_files);
|
||||
} else
|
||||
strcpy(eol, "\r");
|
||||
rprintf(FINFO, "%12.0f %3d%% %7.2f%s %4d:%02d:%02d%s",
|
||||
(double) ofs, pct, rate, units,
|
||||
rprintf(FINFO, "%12s %3d%% %7.2f%s %4d:%02d:%02d%s",
|
||||
human_num(ofs), pct, rate, units,
|
||||
remain_h, remain_m, remain_s, eol);
|
||||
}
|
||||
|
||||
|
||||
167
receiver.c
167
receiver.c
@@ -34,17 +34,14 @@ 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 append_mode;
|
||||
extern int sparse_files;
|
||||
extern int keep_partial;
|
||||
extern int checksum_seed;
|
||||
extern int inplace;
|
||||
@@ -57,70 +54,9 @@ extern char *basis_dir[];
|
||||
extern struct file_list *the_file_list;
|
||||
extern struct filter_list_struct server_filter_list;
|
||||
|
||||
#define SLOT_SIZE (16*1024) /* Desired size in bytes */
|
||||
#define PER_SLOT_BITS (SLOT_SIZE * 8) /* Number of bits per slot */
|
||||
#define PER_SLOT_INTS (SLOT_SIZE / 4) /* Number of int32s per slot */
|
||||
|
||||
static uint32 **delayed_bits = NULL;
|
||||
static int delayed_slot_cnt = 0;
|
||||
static struct bitbag *delayed_bits = NULL;
|
||||
static int phase = 0;
|
||||
|
||||
static void init_delayed_bits(int max_ndx)
|
||||
{
|
||||
delayed_slot_cnt = (max_ndx + PER_SLOT_BITS - 1) / PER_SLOT_BITS;
|
||||
|
||||
if (!(delayed_bits = (uint32**)calloc(delayed_slot_cnt, sizeof (uint32*))))
|
||||
out_of_memory("set_delayed_bit");
|
||||
}
|
||||
|
||||
static void set_delayed_bit(int ndx)
|
||||
{
|
||||
int slot = ndx / PER_SLOT_BITS;
|
||||
ndx %= PER_SLOT_BITS;
|
||||
|
||||
if (!delayed_bits[slot]) {
|
||||
if (!(delayed_bits[slot] = (uint32*)calloc(PER_SLOT_INTS, 4)))
|
||||
out_of_memory("set_delayed_bit");
|
||||
}
|
||||
|
||||
delayed_bits[slot][ndx/32] |= 1u << (ndx % 32);
|
||||
}
|
||||
|
||||
/* Call this with -1 to start checking from 0. Returns -1 at the end. */
|
||||
static int next_delayed_bit(int after)
|
||||
{
|
||||
uint32 bits, mask;
|
||||
int i, ndx = after + 1;
|
||||
int slot = ndx / PER_SLOT_BITS;
|
||||
ndx %= PER_SLOT_BITS;
|
||||
|
||||
mask = (1u << (ndx % 32)) - 1;
|
||||
for (i = ndx / 32; slot < delayed_slot_cnt; slot++, i = mask = 0) {
|
||||
if (!delayed_bits[slot])
|
||||
continue;
|
||||
for ( ; i < PER_SLOT_INTS; i++, mask = 0) {
|
||||
if (!(bits = delayed_bits[slot][i] & ~mask))
|
||||
continue;
|
||||
/* The xor magic figures out the lowest enabled bit in
|
||||
* bits, and the switch quickly computes log2(bit). */
|
||||
switch (bits ^ (bits & (bits-1))) {
|
||||
#define LOG2(n) case 1u << n: return slot*PER_SLOT_BITS + i*32 + n
|
||||
LOG2(0); LOG2(1); LOG2(2); LOG2(3);
|
||||
LOG2(4); LOG2(5); LOG2(6); LOG2(7);
|
||||
LOG2(8); LOG2(9); LOG2(10); LOG2(11);
|
||||
LOG2(12); LOG2(13); LOG2(14); LOG2(15);
|
||||
LOG2(16); LOG2(17); LOG2(18); LOG2(19);
|
||||
LOG2(20); LOG2(21); LOG2(22); LOG2(23);
|
||||
LOG2(24); LOG2(25); LOG2(26); LOG2(27);
|
||||
LOG2(28); LOG2(29); LOG2(30); LOG2(31);
|
||||
}
|
||||
return -1; /* impossible... */
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_tmpname() - create a tmp filename for a given filename
|
||||
@@ -171,8 +107,7 @@ static int get_tmpname(char *fnametmp, char *fname)
|
||||
maxname = MIN(MAXPATHLEN - 7 - length, NAME_MAX - 8);
|
||||
|
||||
if (maxname < 1) {
|
||||
rprintf(FERROR, "temporary filename too long: %s\n",
|
||||
safe_fname(fname));
|
||||
rprintf(FERROR, "temporary filename too long: %s\n", fname);
|
||||
fnametmp[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
@@ -205,13 +140,39 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
|
||||
mapbuf = map_file(fd_r, size_r, read_size, sum.blength);
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "recv mapped %s of size %.0f\n",
|
||||
safe_fname(fname_r), (double)size_r);
|
||||
fname_r, (double)size_r);
|
||||
}
|
||||
} else
|
||||
mapbuf = NULL;
|
||||
|
||||
sum_init(checksum_seed);
|
||||
|
||||
if (append_mode) {
|
||||
OFF_T j;
|
||||
sum.flength = (OFF_T)sum.count * sum.blength;
|
||||
if (sum.remainder)
|
||||
sum.flength -= sum.blength - sum.remainder;
|
||||
for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
|
||||
if (do_progress)
|
||||
show_progress(offset, total_size);
|
||||
sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
|
||||
CHUNK_SIZE);
|
||||
offset = j;
|
||||
}
|
||||
if (offset < sum.flength) {
|
||||
int32 len = sum.flength - offset;
|
||||
if (do_progress)
|
||||
show_progress(offset, total_size);
|
||||
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));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
}
|
||||
|
||||
while ((i = recv_token(f_in, &data)) != 0) {
|
||||
if (do_progress)
|
||||
show_progress(offset, total_size);
|
||||
@@ -315,22 +276,22 @@ static void handle_delayed_updates(struct file_list *flist, char *local_name)
|
||||
char *fname, *partialptr, numbuf[4];
|
||||
int i;
|
||||
|
||||
for (i = -1; (i = next_delayed_bit(i)) >= 0; ) {
|
||||
for (i = -1; (i = bitbag_next_bit(delayed_bits, i)) >= 0; ) {
|
||||
struct file_struct *file = flist->files[i];
|
||||
fname = local_name ? local_name : f_name(file);
|
||||
fname = local_name ? local_name : f_name(file, NULL);
|
||||
if ((partialptr = partial_dir_fname(fname)) != NULL) {
|
||||
if (make_backups && !make_backup(fname))
|
||||
continue;
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "renaming %s to %s\n",
|
||||
safe_fname(partialptr),
|
||||
safe_fname(fname));
|
||||
partialptr, fname);
|
||||
}
|
||||
/* We don't use robust_rename() here because the
|
||||
* partial-dir must be on the same drive. */
|
||||
if (do_rename(partialptr, fname) < 0) {
|
||||
rsyserr(FERROR, errno,
|
||||
"rename failed for %s (from %s)",
|
||||
full_fname(fname),
|
||||
safe_fname(partialptr));
|
||||
full_fname(fname), partialptr);
|
||||
} else {
|
||||
if (remove_sent_files
|
||||
|| (preserve_hard_links
|
||||
@@ -338,8 +299,7 @@ static void handle_delayed_updates(struct file_list *flist, char *local_name)
|
||||
SIVAL(numbuf, 0, i);
|
||||
send_msg(MSG_SUCCESS,numbuf,4);
|
||||
}
|
||||
handle_partial_dir(partialptr,
|
||||
PDIR_DELETE);
|
||||
handle_partial_dir(partialptr, PDIR_DELETE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,7 +312,7 @@ static int get_next_gen_i(int batch_gen_fd, int next_gen_i, int desired_i)
|
||||
rprintf(FINFO,
|
||||
"(No batched update for%s \"%s\")\n",
|
||||
phase ? " resend of" : "",
|
||||
safe_fname(f_name(the_file_list->files[next_gen_i])));
|
||||
f_name(the_file_list->files[next_gen_i], NULL));
|
||||
}
|
||||
next_gen_i = read_int(batch_gen_fd);
|
||||
if (next_gen_i == -1)
|
||||
@@ -395,7 +355,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
}
|
||||
|
||||
if (delay_updates)
|
||||
init_delayed_bits(flist->count);
|
||||
delayed_bits = bitbag_create(flist->count);
|
||||
|
||||
while (1) {
|
||||
cleanup_disable();
|
||||
@@ -417,6 +377,10 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
send_msg(MSG_DONE, "", 0);
|
||||
if (keep_partial && !partial_dir)
|
||||
make_backups = 0; /* prevents double backup */
|
||||
if (append_mode) {
|
||||
append_mode = 0;
|
||||
sparse_files = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -426,10 +390,10 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
continue;
|
||||
|
||||
file = flist->files[i];
|
||||
fname = local_name ? local_name : f_name_to(file, fbuf);
|
||||
fname = local_name ? local_name : f_name(file, fbuf);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "recv_files(%s)\n", safe_fname(fname));
|
||||
rprintf(FINFO, "recv_files(%s)\n", fname);
|
||||
|
||||
if (!(iflags & ITEM_TRANSFER)) {
|
||||
maybe_log_item(file, iflags, itemizing, xname);
|
||||
@@ -470,8 +434,9 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
if (read_batch) {
|
||||
next_gen_i = get_next_gen_i(batch_gen_fd, next_gen_i, i);
|
||||
if (i < next_gen_i) {
|
||||
rprintf(FINFO, "(Skipping batched update for \"%s\")\n",
|
||||
safe_fname(fname));
|
||||
rprintf(FINFO,
|
||||
"(Skipping batched update for \"%s\")\n",
|
||||
fname);
|
||||
discard_receive_data(f_in, file->length);
|
||||
continue;
|
||||
}
|
||||
@@ -572,16 +537,16 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
fd1 = -1;
|
||||
}
|
||||
|
||||
if (fd1 != -1 && !preserve_perms) {
|
||||
/* if the file exists already and we aren't preserving
|
||||
* permissions then act as though the remote end sent
|
||||
* us the file permissions we already have */
|
||||
file->mode = st.st_mode;
|
||||
/* If we're not preserving permissions, change the file-list's
|
||||
* mode based on the local permissions and some heuristics. */
|
||||
if (!preserve_perms) {
|
||||
int exists = fd1 != -1;
|
||||
file->mode = dest_mode(file->mode, st.st_mode, exists);
|
||||
}
|
||||
|
||||
/* We now check to see if we are writing file "inplace" */
|
||||
if (inplace) {
|
||||
fd2 = do_open(fname, O_WRONLY|O_CREAT, 0);
|
||||
fd2 = do_open(fname, O_WRONLY|O_CREAT, 0600);
|
||||
if (fd2 == -1) {
|
||||
rsyserr(FERROR, errno, "open %s failed",
|
||||
full_fname(fname));
|
||||
@@ -610,7 +575,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);
|
||||
@@ -624,7 +589,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (partialptr)
|
||||
if (keep_partial)
|
||||
cleanup_set(fnametmp, partialptr, file, fd1, fd2);
|
||||
}
|
||||
|
||||
@@ -632,7 +597,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
if (log_before_transfer)
|
||||
log_item(file, &initial_stats, iflags, NULL);
|
||||
else if (!am_server && verbose && do_progress)
|
||||
rprintf(FINFO, "%s\n", safe_fname(fname));
|
||||
rprintf(FINFO, "%s\n", fname);
|
||||
|
||||
/* recv file data */
|
||||
recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
|
||||
@@ -650,17 +615,20 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
}
|
||||
|
||||
if ((recv_ok && (!delay_updates || !partialptr)) || inplace) {
|
||||
finish_transfer(fname, fnametmp, file, recv_ok, 1);
|
||||
if (partialptr != fname && fnamecmp == partialptr) {
|
||||
if (partialptr == fname || *partial_dir == '/')
|
||||
partialptr = NULL;
|
||||
finish_transfer(fname, fnametmp, partialptr,
|
||||
file, recv_ok, 1);
|
||||
if (fnamecmp == partialptr) {
|
||||
do_unlink(partialptr);
|
||||
handle_partial_dir(partialptr, PDIR_DELETE);
|
||||
}
|
||||
} else if (keep_partial && partialptr
|
||||
&& handle_partial_dir(partialptr, PDIR_CREATE)) {
|
||||
finish_transfer(partialptr, fnametmp, file, recv_ok,
|
||||
!partial_dir);
|
||||
finish_transfer(partialptr, fnametmp, NULL,
|
||||
file, recv_ok, !partial_dir);
|
||||
if (delay_updates && recv_ok) {
|
||||
set_delayed_bit(i);
|
||||
bitbag_set_bit(delayed_bits, i);
|
||||
recv_ok = -1;
|
||||
}
|
||||
} else {
|
||||
@@ -695,8 +663,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
|
||||
}
|
||||
rprintf(msgtype,
|
||||
"%s: %s failed verification -- update %s%s.\n",
|
||||
errstr, safe_fname(fname),
|
||||
keptstr, redostr);
|
||||
errstr, fname, keptstr, redostr);
|
||||
}
|
||||
if (!phase) {
|
||||
SIVAL(numbuf, 0, i);
|
||||
|
||||
177
rsync.c
177
rsync.c
@@ -21,10 +21,20 @@
|
||||
process */
|
||||
|
||||
#include "rsync.h"
|
||||
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
#if defined HAVE_LIBCHARSET_H && defined HAVE_LOCALE_CHARSET
|
||||
#include <libcharset.h>
|
||||
#elif defined HAVE_LANGINFO_H && defined HAVE_NL_LANGINFO
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
|
||||
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 am_root;
|
||||
@@ -32,13 +42,53 @@ extern int am_server;
|
||||
extern int am_sender;
|
||||
extern int am_generator;
|
||||
extern int am_starting_up;
|
||||
extern int allow_8bit_chars;
|
||||
extern int preserve_uid;
|
||||
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;
|
||||
|
||||
static const char *default_charset(void)
|
||||
{
|
||||
#if defined HAVE_LIBCHARSET_H && defined HAVE_LOCALE_CHARSET
|
||||
return locale_charset();
|
||||
#elif defined HAVE_LANGINFO_H && defined HAVE_NL_LANGINFO
|
||||
return nl_langinfo(CODESET);
|
||||
#else
|
||||
return ""; /* Works with (at the very least) gnu iconv... */
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup_iconv()
|
||||
{
|
||||
if (!am_server && !allow_8bit_chars) {
|
||||
const char *defset = default_charset();
|
||||
|
||||
/* It's OK if this fails... */
|
||||
ic_chck = iconv_open(defset, defset);
|
||||
|
||||
if (verbose > 3) {
|
||||
if (ic_chck == (iconv_t)-1) {
|
||||
rprintf(FINFO,
|
||||
"note: iconv_open(\"%s\", \"%s\") failed (%d)"
|
||||
" -- using isprint() instead of iconv().\n",
|
||||
defset, defset, errno);
|
||||
} else {
|
||||
rprintf(FINFO,
|
||||
"note: iconv_open(\"%s\", \"%s\") succeeded.\n",
|
||||
defset, defset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
free a sums struct
|
||||
@@ -49,9 +99,31 @@ void free_sums(struct sum_struct *s)
|
||||
free(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)
|
||||
{
|
||||
/* If the file already exists, we'll return the local permissions,
|
||||
* possibly tweaked by the --executability option. */
|
||||
if (exists) {
|
||||
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;
|
||||
}
|
||||
} else
|
||||
cur_mode = flist_mode & ACCESSPERMS & ~orig_umask;
|
||||
if (daemon_chmod_modes && !S_ISLNK(flist_mode))
|
||||
cur_mode = tweak_mode(cur_mode, daemon_chmod_modes);
|
||||
return (flist_mode & ~CHMOD_BITS) | (cur_mode & CHMOD_BITS);
|
||||
}
|
||||
|
||||
int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
|
||||
int flags)
|
||||
int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
|
||||
int flags)
|
||||
{
|
||||
int updated = 0;
|
||||
STRUCT_STAT st2;
|
||||
@@ -66,19 +138,26 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
|
||||
return 0;
|
||||
}
|
||||
st = &st2;
|
||||
if (!preserve_perms && S_ISDIR(file->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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!preserve_times || S_ISLNK(st->st_mode)
|
||||
|| (S_ISDIR(st->st_mode) && omit_dir_times))
|
||||
flags |= PERMS_SKIP_MTIME;
|
||||
if (!(flags & PERMS_SKIP_MTIME)
|
||||
&& cmp_modtime(st->st_mtime, file->modtime) != 0) {
|
||||
if (set_modtime(fname,file->modtime) != 0) {
|
||||
if (!preserve_times || (S_ISDIR(st->st_mode) && omit_dir_times))
|
||||
flags |= ATTRS_SKIP_MTIME;
|
||||
if (!(flags & ATTRS_SKIP_MTIME)
|
||||
&& cmp_time(st->st_mtime, file->modtime) != 0) {
|
||||
int ret = set_modtime(fname, file->modtime, st->st_mode);
|
||||
if (ret < 0) {
|
||||
rsyserr(FERROR, errno, "failed to set times on %s",
|
||||
full_fname(fname));
|
||||
return 0;
|
||||
}
|
||||
updated = 1;
|
||||
if (ret == 0) /* ret == 1 if symlink could not be set */
|
||||
updated = 1;
|
||||
}
|
||||
|
||||
change_uid = am_root && preserve_uid && st->st_uid != file->uid;
|
||||
@@ -94,13 +173,13 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
|
||||
if (change_uid) {
|
||||
rprintf(FINFO,
|
||||
"set uid of %s from %ld to %ld\n",
|
||||
safe_fname(fname),
|
||||
fname,
|
||||
(long)st->st_uid, (long)file->uid);
|
||||
}
|
||||
if (change_gid) {
|
||||
rprintf(FINFO,
|
||||
"set gid of %s from %ld to %ld\n",
|
||||
safe_fname(fname),
|
||||
fname,
|
||||
(long)st->st_gid, (long)file->gid);
|
||||
}
|
||||
}
|
||||
@@ -125,31 +204,31 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
|
||||
}
|
||||
|
||||
#ifdef HAVE_CHMOD
|
||||
if (!S_ISLNK(st->st_mode)) {
|
||||
if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
|
||||
updated = 1;
|
||||
if (do_chmod(fname,(file->mode & CHMOD_BITS)) != 0) {
|
||||
rsyserr(FERROR, errno, "failed to set permissions on %s",
|
||||
full_fname(fname));
|
||||
return 0;
|
||||
}
|
||||
if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
|
||||
int ret = do_chmod(fname, file->mode);
|
||||
if (ret < 0) {
|
||||
rsyserr(FERROR, errno,
|
||||
"failed to set permissions on %s",
|
||||
full_fname(fname));
|
||||
return 0;
|
||||
}
|
||||
if (ret == 0) /* ret == 1 if symlink could not be set */
|
||||
updated = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (verbose > 1 && flags & PERMS_REPORT) {
|
||||
if (verbose > 1 && flags & ATTRS_REPORT) {
|
||||
enum logcode code = daemon_log_format_has_i || dry_run
|
||||
? FCLIENT : FINFO;
|
||||
if (updated)
|
||||
rprintf(code, "%s\n", safe_fname(fname));
|
||||
rprintf(code, "%s\n", fname);
|
||||
else
|
||||
rprintf(code, "%s is uptodate\n", safe_fname(fname));
|
||||
rprintf(code, "%s is uptodate\n", fname);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
void sig_int(void)
|
||||
RETSIGTYPE sig_int(UNUSED(int val))
|
||||
{
|
||||
/* KLUGE: if the user hits Ctrl-C while ssh is prompting
|
||||
* for a password, then our cleanup's sending of a SIGUSR1
|
||||
@@ -163,36 +242,39 @@ void sig_int(void)
|
||||
exit_cleanup(RERR_SIGNAL);
|
||||
}
|
||||
|
||||
|
||||
/* finish off a file transfer, renaming the file and setting the permissions
|
||||
and ownership */
|
||||
void finish_transfer(char *fname, char *fnametmp, struct file_struct *file,
|
||||
int ok_to_set_time, int overwriting_basis)
|
||||
/* Finish off a file transfer: renaming the file and setting the file's
|
||||
* attributes (e.g. permissions, ownership, etc.). If partialptr is not
|
||||
* NULL and the robust_rename() call is forced to copy the temp file, we
|
||||
* stage the file into the partial-dir and then rename it into place. */
|
||||
void finish_transfer(char *fname, char *fnametmp, char *partialptr,
|
||||
struct file_struct *file, int ok_to_set_time,
|
||||
int overwriting_basis)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (inplace) {
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "finishing %s\n", safe_fname(fname));
|
||||
goto do_set_perms;
|
||||
rprintf(FINFO, "finishing %s\n", fname);
|
||||
fnametmp = fname;
|
||||
goto do_set_file_attrs;
|
||||
}
|
||||
|
||||
if (make_backups && overwriting_basis && !make_backup(fname))
|
||||
return;
|
||||
|
||||
/* Change permissions before putting the file into place. */
|
||||
set_perms(fnametmp, file, NULL, ok_to_set_time ? 0 : PERMS_SKIP_MTIME);
|
||||
set_file_attrs(fnametmp, file, NULL,
|
||||
ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
|
||||
|
||||
/* move tmp file over real file */
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "renaming %s to %s\n",
|
||||
safe_fname(fnametmp), safe_fname(fname));
|
||||
}
|
||||
ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
|
||||
ret = robust_rename(fnametmp, fname, partialptr,
|
||||
file->mode & INITACCESSPERMS);
|
||||
if (ret < 0) {
|
||||
rsyserr(FERROR, errno, "%s %s -> \"%s\"",
|
||||
ret == -2 ? "copy" : "rename",
|
||||
full_fname(fnametmp), safe_fname(fname));
|
||||
ret == -2 ? "copy" : "rename",
|
||||
full_fname(fnametmp), fname);
|
||||
do_unlink(fnametmp);
|
||||
return;
|
||||
}
|
||||
@@ -200,8 +282,21 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file,
|
||||
/* The file was moved into place (not copied), so it's done. */
|
||||
return;
|
||||
}
|
||||
do_set_perms:
|
||||
set_perms(fname, file, NULL, ok_to_set_time ? 0 : PERMS_SKIP_MTIME);
|
||||
/* The file was copied, so tweak the perms of the copied file. If it
|
||||
* was copied to partialptr, move it into its final destination. */
|
||||
fnametmp = partialptr ? partialptr : fname;
|
||||
|
||||
do_set_file_attrs:
|
||||
set_file_attrs(fnametmp, file, NULL,
|
||||
ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
|
||||
|
||||
if (partialptr) {
|
||||
if (do_rename(fnametmp, fname) < 0) {
|
||||
rsyserr(FERROR, errno, "rename %s -> \"%s\"",
|
||||
full_fname(fnametmp), fname);
|
||||
} else
|
||||
handle_partial_dir(partialptr, PDIR_DELETE);
|
||||
}
|
||||
}
|
||||
|
||||
const char *who_am_i(void)
|
||||
|
||||
92
rsync.h
92
rsync.h
@@ -58,12 +58,12 @@
|
||||
/* These flags are used in the live flist data. */
|
||||
|
||||
#define FLAG_TOP_DIR (1<<0)
|
||||
#define FLAG_SENT (1<<1) /* sender */
|
||||
#define FLAG_HLINK_EOL (1<<1) /* receiver/generator */
|
||||
#define FLAG_MOUNT_POINT (1<<2) /* sender */
|
||||
#define FLAG_NO_FUZZY (1<<2) /* generator */
|
||||
#define FLAG_MOUNT_POINT (1<<2) /* sender/generator */
|
||||
#define FLAG_DEL_HERE (1<<3) /* receiver/generator */
|
||||
#define FLAG_SENT (1<<3) /* sender */
|
||||
#define FLAG_HLINK_TOL (1<<4) /* receiver/generator */
|
||||
#define FLAG_NO_FUZZY (1<<5) /* generator */
|
||||
|
||||
/* update this if you make incompatible changes */
|
||||
#define PROTOCOL_VERSION 29
|
||||
@@ -115,9 +115,10 @@
|
||||
#define XFLG_FATAL_ERRORS (1<<0)
|
||||
#define XFLG_OLD_PREFIXES (1<<1)
|
||||
#define XFLG_ANCHORED2ABS (1<<2)
|
||||
#define XFLG_ABS_IF_SLASH (1<<3)
|
||||
|
||||
#define PERMS_REPORT (1<<0)
|
||||
#define PERMS_SKIP_MTIME (1<<1)
|
||||
#define ATTRS_REPORT (1<<0)
|
||||
#define ATTRS_SKIP_MTIME (1<<1)
|
||||
|
||||
#define FULL_FLUSH 1
|
||||
#define NORMAL_FLUSH 0
|
||||
@@ -133,26 +134,22 @@
|
||||
#define FNAMECMP_BACKUP 0x82
|
||||
#define FNAMECMP_FUZZY 0x83
|
||||
|
||||
/* For calling delete_file() */
|
||||
#define DEL_NO_RECURSE (1<<1)
|
||||
#define DEL_FORCE_RECURSE (1<<2) /* recurse even w/o --force */
|
||||
#define DEL_TERSE (1<<3)
|
||||
|
||||
/* 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)
|
||||
#define ITEM_LOCAL_CHANGE (1<<14)
|
||||
#define ITEM_TRANSFER (1<<15)
|
||||
/* These are outside the range of the transmitted flags. */
|
||||
#define ITEM_NO_DEST_AND_NO_UPDATE (1<<16) /* used by itemize() */
|
||||
#define ITEM_MISSING_DATA (1<<16) /* used by log_formatted() */
|
||||
#define ITEM_DELETED (1<<17) /* used by log_formatted() */
|
||||
|
||||
@@ -160,16 +157,17 @@
|
||||
ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE))
|
||||
|
||||
|
||||
/* Log-message categories. FLOG and FCLIENT are only used on the daemon
|
||||
* side for custom logging -- they don't get sent over the socket. */
|
||||
enum logcode { FERROR=1, FINFO=2, FLOG=3, FCLIENT=4 };
|
||||
/* 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 };
|
||||
|
||||
/* Messages types that are sent over the message channel. The logcode
|
||||
* values must all be present here with identical numbers. */
|
||||
enum msgcode {
|
||||
MSG_DATA=0, /* raw data on the multiplexed stream */
|
||||
MSG_ERROR=FERROR, MSG_INFO=FINFO, /* remote logging */
|
||||
MSG_LOG=FLOG, MSG_FCLIENT=FCLIENT, /* sibling logging */
|
||||
MSG_LOG=FLOG, MSG_SOCKERR=FSOCKERR, /* sibling logging */
|
||||
MSG_REDO=9, /* reprocess indicated flist index */
|
||||
MSG_SUCCESS=100,/* successfully updated indicated flist index */
|
||||
MSG_DELETED=101,/* successfully deleted a file on receiving side */
|
||||
@@ -319,6 +317,10 @@ enum msgcode {
|
||||
#include <compat.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "lib/pool_alloc.h"
|
||||
@@ -463,6 +465,14 @@ struct idev {
|
||||
#define MAXPATHLEN 1024
|
||||
#endif
|
||||
|
||||
/* We want a roomy line buffer that can hold more than MAXPATHLEN,
|
||||
* and significantly more than an overly short MAXPATHLEN. */
|
||||
#if MAXPATHLEN < 4096
|
||||
#define BIGPATHBUFLEN (4096+1024)
|
||||
#else
|
||||
#define BIGPATHBUFLEN (MAXPATHLEN+1024)
|
||||
#endif
|
||||
|
||||
#ifndef NAME_MAX
|
||||
#define NAME_MAX 255
|
||||
#endif
|
||||
@@ -552,6 +562,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 */
|
||||
};
|
||||
@@ -579,11 +590,11 @@ struct map_struct {
|
||||
|
||||
#define MATCHFLG_WILD (1<<0) /* pattern has '*', '[', and/or '?' */
|
||||
#define MATCHFLG_WILD2 (1<<1) /* pattern has '**' */
|
||||
#define MATCHFLG_WILD2_PREFIX (1<<2) /* pattern starts with '**' */
|
||||
#define MATCHFLG_ABS_PATH (1<<3) /* path-match on absolute path */
|
||||
#define MATCHFLG_INCLUDE (1<<4) /* this is an include, not an exclude */
|
||||
#define MATCHFLG_DIRECTORY (1<<5) /* this matches only directories */
|
||||
#define MATCHFLG_CLEAR_LIST (1<<6) /* this item is the "!" token */
|
||||
#define MATCHFLG_WILD2_PREFIX (1<<2) /* pattern starts with "**" */
|
||||
#define MATCHFLG_WILD3_SUFFIX (1<<3) /* pattern ends with "***" */
|
||||
#define MATCHFLG_ABS_PATH (1<<4) /* path-match on absolute path */
|
||||
#define MATCHFLG_INCLUDE (1<<5) /* this is an include, not an exclude */
|
||||
#define MATCHFLG_DIRECTORY (1<<6) /* this matches only directories */
|
||||
#define MATCHFLG_WORD_SPLIT (1<<7) /* split rules on whitespace */
|
||||
#define MATCHFLG_NO_INHERIT (1<<8) /* don't inherit these rules */
|
||||
#define MATCHFLG_NO_PREFIXES (1<<9) /* parse no prefixes from patterns */
|
||||
@@ -595,6 +606,7 @@ struct map_struct {
|
||||
#define MATCHFLG_CVS_IGNORE (1<<15)/* rule was -C or :C */
|
||||
#define MATCHFLG_SENDER_SIDE (1<<16)/* rule applies to the sending side */
|
||||
#define MATCHFLG_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */
|
||||
#define MATCHFLG_CLEAR_LIST (1<<18)/* this item is the "!" token */
|
||||
|
||||
#define MATCHFLGS_FROM_CONTAINER (MATCHFLG_ABS_PATH | MATCHFLG_INCLUDE \
|
||||
| MATCHFLG_DIRECTORY | MATCHFLG_SENDER_SIDE \
|
||||
@@ -631,6 +643,7 @@ struct stats {
|
||||
int current_file_index;
|
||||
};
|
||||
|
||||
struct chmod_mode_struct;
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "lib/mdfour.h"
|
||||
@@ -638,6 +651,15 @@ struct stats {
|
||||
#include "lib/permstring.h"
|
||||
#include "lib/addrinfo.h"
|
||||
|
||||
#if !defined __GNUC__ || defined __APPLE__
|
||||
/* Apparently the OS X port of gcc gags on __attribute__.
|
||||
*
|
||||
* <http://www.opensource.apple.com/bugs/X/gcc/2512150.html> */
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) x __attribute__((__unused__))
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
/* We have replacement versions of these if they're missing. */
|
||||
@@ -681,7 +703,12 @@ extern int errno;
|
||||
#define SUPPORT_HARD_LINKS 1
|
||||
#endif
|
||||
|
||||
#define SIGNAL_CAST (RETSIGTYPE (*)())
|
||||
#ifdef HAVE_SIGACTION
|
||||
#define SIGACTION(n,h) sigact.sa_handler=(h), sigaction((n),&sigact,NULL)
|
||||
#define signal(n,h) we_need_to_call_SIGACTION_not_signal(n,h)
|
||||
#else
|
||||
#define SIGACTION(n,h) signal(n,h)
|
||||
#endif
|
||||
|
||||
#ifndef EWOULDBLOCK
|
||||
#define EWOULDBLOCK EAGAIN
|
||||
@@ -778,7 +805,8 @@ extern int errno;
|
||||
#define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
|
||||
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
|
||||
#define IS_SPECIAL(mode) (S_ISSOCK(mode) || S_ISFIFO(mode))
|
||||
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode))
|
||||
|
||||
/* Initial mask on permissions given to temporary files. Mask off setuid
|
||||
bits and group access because of potential race-condition security
|
||||
@@ -786,15 +814,7 @@ extern int errno;
|
||||
#define INITACCESSPERMS 0700
|
||||
|
||||
/* handler for null strings in printf format */
|
||||
#define NS(s) ((s)?safe_fname(s):"<NULL>")
|
||||
|
||||
#if !defined __GNUC__ || defined __APPLE__
|
||||
/* Apparently the OS X port of gcc gags on __attribute__.
|
||||
*
|
||||
* <http://www.opensource.apple.com/bugs/X/gcc/2512150.html> */
|
||||
#define __attribute__(x)
|
||||
|
||||
#endif
|
||||
#define NS(s) ((s)?(s):"<NULL>")
|
||||
|
||||
/* Convenient wrappers for malloc and realloc. Use them. */
|
||||
#define new(type) ((type *)malloc(sizeof(type)))
|
||||
@@ -812,10 +832,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
|
||||
@@ -860,7 +876,3 @@ int inet_pton(int af, const char *src, void *dst);
|
||||
#ifdef MAINTAINER_MODE
|
||||
const char *get_panic_action(void);
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) x __attribute__((__unused__))
|
||||
|
||||
extern const char *io_write_phase, *io_read_phase;
|
||||
|
||||
141
rsyncd.conf.yo
141
rsyncd.conf.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsyncd.conf)(5)(1 Jun 2005)()()
|
||||
manpage(rsyncd.conf)(5)(22 Apr 2006)()()
|
||||
manpagename(rsyncd.conf)(configuration file for rsync in daemon mode)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -52,9 +52,6 @@ write the appropriate data, log, and lock files.
|
||||
You can launch it either via inetd, as a stand-alone daemon, or from
|
||||
an rsync client via a remote shell. If run as a stand-alone daemon then
|
||||
just run the command "bf(rsync --daemon)" from a suitable startup script.
|
||||
If run from an rsync client via a remote shell (by specifying both the
|
||||
bf(--rsh) (bf(-e)) option and daemon mode with "::" or "rsync://"), the bf(--daemon)
|
||||
option is automatically passed to the remote side.
|
||||
|
||||
When run via inetd you should add a line like this to /etc/services:
|
||||
|
||||
@@ -89,7 +86,7 @@ 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
|
||||
useful on systems (such as AIX) where code(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
|
||||
@@ -117,9 +114,10 @@ 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.
|
||||
special socket options are set. These settings are superseded by the
|
||||
bf(--sockopts) command-line option.
|
||||
|
||||
enddit()
|
||||
|
||||
@@ -156,7 +154,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
|
||||
@@ -166,7 +164,7 @@ specified.
|
||||
Note that you are free to setup user/group information in the chroot area
|
||||
differently from your normal system. For example, you could abbreviate
|
||||
the list of users and groups. Also, you can protect this information from
|
||||
being downloaded/uploaded by adding an exclude rule to the rsync.conf file
|
||||
being downloaded/uploaded by adding an exclude rule to the rsyncd.conf file
|
||||
(e.g. "exclude = /etc/**"). Note that having the exclusion affect uploads
|
||||
is a relatively new feature in rsync, so make sure your daemon is
|
||||
at least 2.6.3 to effect this. Also note that it is safest to exclude a
|
||||
@@ -265,6 +263,25 @@ only superficially equivalent to the client specifying the
|
||||
bf(--include-from) option with a equivalent file.
|
||||
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 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.
|
||||
|
||||
dit(bf(outgoing chmod)) This option allows you to specify a set of
|
||||
comma-separated chmod strings that will affect the permissions of all
|
||||
outgoing files (files that are being sent out from the daemon). These
|
||||
changes happen first, making the sent permissions appear to be different
|
||||
than those stored in the filesystem itself. For instance, you could
|
||||
disable group write permissions on the server while having it appear to
|
||||
be on to the clients.
|
||||
See the description of the bf(--chmod) rsync option and the bf(chmod)(1)
|
||||
manpage for information on the format of this string.
|
||||
|
||||
dit(bf(auth users)) The "auth users" option specifies a comma and
|
||||
space-separated list of usernames that will be allowed to connect to
|
||||
this module. The usernames do not need to exist on the local
|
||||
@@ -272,12 +289,12 @@ system. The usernames may also contain shell wildcard characters. If
|
||||
"auth users" is set then the client will be challenged to supply a
|
||||
username and password to connect to the module. A challenge response
|
||||
authentication protocol is used for this exchange. The plain text
|
||||
usernames are passwords are stored in the file specified by the
|
||||
usernames and passwords are stored in the file specified by the
|
||||
"secrets file" option. The default is for all users to be able to
|
||||
connect without a password (this is called "anonymous rsync").
|
||||
|
||||
See also the "CONNECTING TO AN RSYNC DAEMON OVER A REMOTE SHELL
|
||||
PROGRAM" section in 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.
|
||||
|
||||
@@ -389,24 +406,25 @@ rsyncstats.)
|
||||
The single-character escapes that are understood are as follows:
|
||||
|
||||
quote(itemize(
|
||||
it() %h for the remote host name
|
||||
it() %a for the remote IP address
|
||||
it() %l for the length of the file in bytes
|
||||
it() %p for the process ID of this rsync session
|
||||
it() %o for the operation, which is "send", "recv", or "del."
|
||||
(the latter includes the trailing period)
|
||||
it() %f for the filename (long form on sender; no trailing "/")
|
||||
it() %n for the filename (short form; trailing "/" on dir)
|
||||
it() %L either the string " -> SYMLINK", or " => HARDLINK" or an
|
||||
empty string (where bf(SYMLINK) or bf(HARDLINK) is a filename)
|
||||
it() %P for the module path
|
||||
it() %m for the module name
|
||||
it() %t for the current date time
|
||||
it() %u for the authenticated username (or the null string)
|
||||
it() %b for the number of bytes actually transferred
|
||||
it() %c when sending files this gives the number of checksum bytes
|
||||
received for this file
|
||||
it() %a the remote IP address
|
||||
it() %b the number of bytes actually transferred
|
||||
it() %B the permission bits of the file (e.g. rwxrwxrwt)
|
||||
it() %c the checksum bytes received for this file (only when sending)
|
||||
it() %f the filename (long form on sender; no trailing "/")
|
||||
it() %G the gid of the file (decimal) or "DEFAULT"
|
||||
it() %h the remote host name
|
||||
it() %i an itemized list of what is being updated
|
||||
it() %l the length of the file in bytes
|
||||
it() %L the string " -> SYMLINK", " => HARDLINK", or "" (where bf(SYMLINK) or bf(HARDLINK) is a filename)
|
||||
it() %m the module name
|
||||
it() %M the last-modified time of the file
|
||||
it() %n the filename (short form; trailing "/" on dir)
|
||||
it() %o the operation, which is "send", "recv", or "del." (the latter includes the trailing period)
|
||||
it() %p the process ID of this rsync session
|
||||
it() %P the module path
|
||||
it() %t the current date time
|
||||
it() %u the authenticated username or an empty string
|
||||
it() %U the uid of the file (decimal)
|
||||
))
|
||||
|
||||
For a list of what the characters mean that are output by "%i", see the
|
||||
@@ -457,16 +475,45 @@ of the patterns will not be compressed during transfer.
|
||||
|
||||
The default setting is tt(*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz)
|
||||
|
||||
dit(bf(pre-xfer exec), bf(post-xfer exec)) You may specify a command to be run
|
||||
before and/or after the transfer. If the bf(pre-xfer exec) command fails, the
|
||||
transfer is aborted before it begins.
|
||||
|
||||
The following environment variables will be set, though some are
|
||||
specific to the pre-xfer or the post-xfer environment:
|
||||
|
||||
quote(itemize(
|
||||
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_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 code(waitpid()).
|
||||
))
|
||||
|
||||
Even though the commands can be associated with a particular module, they
|
||||
are run using the permissions of the user that started the daemon (not the
|
||||
module's uid/gid setting) without any chroot restrictions.
|
||||
|
||||
enddit()
|
||||
|
||||
manpagesection(AUTHENTICATION STRENGTH)
|
||||
|
||||
The authentication protocol used in rsync is a 128 bit MD4 based
|
||||
challenge response system. Although I believe that no one has ever
|
||||
demonstrated a brute-force break of this sort of system you should
|
||||
realize that this is not a "military strength" authentication system.
|
||||
It should be good enough for most purposes but if you want really top
|
||||
quality security then I recommend that you run rsync over ssh.
|
||||
challenge response system. This is fairly weak protection, though (with
|
||||
at least one brute-force hash-finding algorithm publicly available), so
|
||||
if you want really top-quality security, then I recommend that you run
|
||||
rsync over ssh. (Yes, a future version of rsync will switch over to a
|
||||
stronger hashing method.)
|
||||
|
||||
Also note that the rsync daemon protocol does not currently provide any
|
||||
encryption of the data that is transferred over the connection. Only
|
||||
@@ -476,32 +523,6 @@ encryption.
|
||||
Future versions of rsync may support SSL for better authentication and
|
||||
encryption, but that is still being investigated.
|
||||
|
||||
manpagesection(RUNNING AN RSYNC DAEMON OVER A REMOTE SHELL PROGRAM)
|
||||
|
||||
If rsync is run with both the bf(--daemon) and bf(--rsh) (bf(-e)) options, it will
|
||||
spawn an rsync daemon using a remote shell connection. Several
|
||||
configuration options will not be available unless the remote user is
|
||||
root (e.g. chroot, setuid/setgid, etc.). There is no need to configure
|
||||
inetd or the services map to include the rsync daemon port if you run an
|
||||
rsync daemon only via a remote shell program.
|
||||
|
||||
ADVANCED: To run an rsync daemon out of a single-use ssh key, use the
|
||||
"command=em(COMMAND)" syntax in the remote user's authorized_keys entry,
|
||||
where command would be
|
||||
|
||||
quote(tt(rsync --server --daemon .))
|
||||
|
||||
NOTE: rsync's argument parsing expects the trailing ".", so make sure
|
||||
that it's there. If you want to use an rsyncd.conf(5)-style
|
||||
configuration file other than the default, you can added a
|
||||
bf(--config) option to the em(command):
|
||||
|
||||
quote(tt(rsync --server --daemon --config=em(file) .))
|
||||
|
||||
Note that the "--server" here is the internal option that rsync uses to
|
||||
run the remote version of rsync that it communicates with, and thus you
|
||||
should not be using the bf(--server) option under normal circumstances.
|
||||
|
||||
manpagesection(EXAMPLES)
|
||||
|
||||
A simple rsyncd.conf file that allow anonymous rsync to a ftp area at
|
||||
@@ -570,7 +591,7 @@ url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
|
||||
This man page is current for version 2.6.5 of rsync.
|
||||
This man page is current for version 2.6.8 of rsync.
|
||||
|
||||
manpagesection(CREDITS)
|
||||
|
||||
|
||||
18
runtests.sh
18
runtests.sh
@@ -85,7 +85,7 @@
|
||||
# they're explicitly given on the command line.
|
||||
|
||||
# Also, we can't count on 'cp -a' or 'mkdir -p', although they're
|
||||
# pretty handy.
|
||||
# pretty handy (see function makepath for the latter).
|
||||
|
||||
# I think some of the GNU documentation suggests that we shouldn't
|
||||
# rely on shell functions. However, the Bash manual seems to say that
|
||||
@@ -100,6 +100,8 @@
|
||||
# You cannot do "export VAR=VALUE" all on one line; the export must be
|
||||
# separate from the assignment. (SCO SysV)
|
||||
|
||||
# Don't rely on grep -q, as that doesn't work everywhere -- just redirect
|
||||
# stdout to /dev/null to keep it quiet.
|
||||
|
||||
|
||||
# STILL TO DO:
|
||||
@@ -124,6 +126,7 @@ set -e
|
||||
. "./shconfig"
|
||||
|
||||
RUNSHFLAGS='-e'
|
||||
export RUNSHFLAGS
|
||||
|
||||
# for Solaris
|
||||
[ -d /usr/xpg4/bin ] && PATH="/usr/xpg4/bin/:$PATH"
|
||||
@@ -160,6 +163,14 @@ else
|
||||
echo " preserve_scratch=no"
|
||||
fi
|
||||
|
||||
# Check if setfacl is around and if it supports the -k or -s option.
|
||||
if setfacl --help 2>/dev/null | grep ' -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_nodef=true
|
||||
fi
|
||||
|
||||
if [ ! -f "$rsync_bin" ]; then
|
||||
echo "rsync_bin $rsync_bin is not a file" >&2
|
||||
@@ -174,7 +185,7 @@ fi
|
||||
RSYNC="$rsync_bin"
|
||||
#RSYNC="valgrind --tool=addrcheck $rsync_bin"
|
||||
|
||||
export rsync_bin RSYNC
|
||||
export rsync_bin RSYNC setfacl_nodef
|
||||
|
||||
skipped=0
|
||||
missing=0
|
||||
@@ -194,6 +205,9 @@ export scratchdir suitedir
|
||||
prep_scratch() {
|
||||
[ -d "$scratchdir" ] && rm -rf "$scratchdir"
|
||||
mkdir "$scratchdir"
|
||||
# Get rid of default ACLs and dir-setgid to avoid confusing some tests.
|
||||
$setfacl_nodef "$scratchdir"
|
||||
chmod g-s "$scratchdir"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
35
sender.c
35
sender.c
@@ -27,6 +27,7 @@ extern int log_before_transfer;
|
||||
extern int log_format_has_i;
|
||||
extern int daemon_log_format_has_i;
|
||||
extern int csum_length;
|
||||
extern int append_mode;
|
||||
extern int io_error;
|
||||
extern int allowed_lull;
|
||||
extern int protocol_version;
|
||||
@@ -72,6 +73,13 @@ static struct sum_struct *receive_sums(int f)
|
||||
(double)s->count, (long)s->blength, (long)s->remainder);
|
||||
}
|
||||
|
||||
if (append_mode) {
|
||||
s->flength = (OFF_T)s->count * s->blength;
|
||||
if (s->remainder)
|
||||
s->flength -= s->blength - s->remainder;
|
||||
return s;
|
||||
}
|
||||
|
||||
if (s->count == 0)
|
||||
return(s);
|
||||
|
||||
@@ -125,11 +133,9 @@ void successful_send(int ndx)
|
||||
file->dir.root, "/", NULL);
|
||||
} else
|
||||
offset = 0;
|
||||
f_name_to(file, fname + offset);
|
||||
if (remove_sent_files && do_unlink(fname) == 0 && verbose > 1) {
|
||||
rprintf(FINFO, "sender removed %s\n",
|
||||
safe_fname(fname + offset));
|
||||
}
|
||||
f_name(file, fname + offset);
|
||||
if (remove_sent_files && do_unlink(fname) == 0 && verbose > 1)
|
||||
rprintf(FINFO, "sender removed %s\n", fname + offset);
|
||||
}
|
||||
|
||||
static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
|
||||
@@ -231,6 +237,7 @@ void send_files(struct file_list *flist, int f_out, int f_in)
|
||||
/* For inplace: redo phase turns off the backup
|
||||
* flag so that we do a regular inplace send. */
|
||||
make_backups = 0;
|
||||
append_mode = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -247,7 +254,7 @@ void send_files(struct file_list *flist, int f_out, int f_in)
|
||||
fname[offset++] = '/';
|
||||
} else
|
||||
offset = 0;
|
||||
fname2 = f_name_to(file, fname + offset);
|
||||
fname2 = f_name(file, fname + offset);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "send_files(%d, %s)\n", i, fname);
|
||||
@@ -322,22 +329,20 @@ void send_files(struct file_list *flist, int f_out, int f_in)
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "send_files mapped %s of size %.0f\n",
|
||||
safe_fname(fname), (double)st.st_size);
|
||||
fname, (double)st.st_size);
|
||||
}
|
||||
|
||||
write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
|
||||
xname, xlen);
|
||||
write_sum_head(f_xfer, s);
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "calling match_sums %s\n",
|
||||
safe_fname(fname));
|
||||
}
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "calling match_sums %s\n", fname);
|
||||
|
||||
if (log_before_transfer)
|
||||
log_item(file, &initial_stats, iflags, NULL);
|
||||
else if (!am_server && verbose && do_progress)
|
||||
rprintf(FINFO, "%s\n", safe_fname(fname2));
|
||||
rprintf(FINFO, "%s\n", fname2);
|
||||
|
||||
set_compression(fname);
|
||||
|
||||
@@ -361,10 +366,8 @@ void send_files(struct file_list *flist, int f_out, int f_in)
|
||||
|
||||
free_sums(s);
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "sender finished %s\n",
|
||||
safe_fname(fname));
|
||||
}
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "sender finished %s\n", fname);
|
||||
|
||||
/* Flag that we actually sent this entry. */
|
||||
file->flags |= FLAG_SENT;
|
||||
|
||||
49
socket.c
49
socket.c
@@ -32,10 +32,16 @@
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
extern char *bind_address;
|
||||
extern int default_af_hint;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
static struct sigaction sigact;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Establish a proxy connection on an open socket to a web proxy by
|
||||
* using the CONNECT method. If proxy_user and proxy_pass are not NULL,
|
||||
@@ -54,13 +60,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';
|
||||
@@ -329,9 +335,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);
|
||||
@@ -349,17 +355,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;
|
||||
}
|
||||
@@ -381,6 +395,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;
|
||||
}
|
||||
@@ -392,6 +411,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",
|
||||
@@ -433,7 +461,9 @@ static RETSIGTYPE sigchld_handler(UNUSED(int val))
|
||||
#ifdef WNOHANG
|
||||
while (waitpid(-1, NULL, WNOHANG) > 0) {}
|
||||
#endif
|
||||
#ifndef HAVE_SIGACTION
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -442,6 +472,10 @@ void start_accept_loop(int port, int (*fn)(int, int))
|
||||
fd_set deffds;
|
||||
int *sp, maxfd, i;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigact.sa_flags = SA_NOCLDSTOP;
|
||||
#endif
|
||||
|
||||
/* open an incoming socket */
|
||||
sp = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
|
||||
if (sp == NULL)
|
||||
@@ -465,7 +499,6 @@ void start_accept_loop(int port, int (*fn)(int, int))
|
||||
maxfd = sp[i];
|
||||
}
|
||||
|
||||
|
||||
/* now accept incoming connections - forking a new process
|
||||
* for each incoming connection */
|
||||
while (1) {
|
||||
@@ -500,7 +533,7 @@ void start_accept_loop(int port, int (*fn)(int, int))
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
SIGACTION(SIGCHLD, sigchld_handler);
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
int ret;
|
||||
|
||||
64
support/cull_options
Executable file
64
support/cull_options
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/perl
|
||||
# This script outputs some perl code that parses all possible options
|
||||
# that the code in options.c might send to the server. This perl code
|
||||
# is included in the rrsync script.
|
||||
use strict;
|
||||
|
||||
our(%short_no_arg, %short_with_num, %long_opt);
|
||||
our $last_long_opt;
|
||||
|
||||
open(IN, '../options.c') or die "Unable to open ../options.c: $!\n";
|
||||
|
||||
while (<IN>) {
|
||||
if (/\Qargstr[x++]\E = '(.)'/) {
|
||||
$short_no_arg{$1} = 1;
|
||||
undef $last_long_opt;
|
||||
} elsif (/\Qasprintf(\E[^,]+, "-([a-zA-Z0-9])\%l?[ud]"/) {
|
||||
$short_with_num{$1} = 1;
|
||||
undef $last_long_opt;
|
||||
} elsif (/\Qargs[ac++]\E = "--([^"=]+)"/) {
|
||||
$last_long_opt = $1;
|
||||
$long_opt{$1} = 0;
|
||||
} elsif (defined($last_long_opt)
|
||||
&& /\Qargs[ac++]\E = ([^["\s]+);/ && $1 ne 'dest_option') {
|
||||
$long_opt{$last_long_opt} = 2;
|
||||
undef $last_long_opt;
|
||||
} elsif (/dest_option = "--([^"]+)"/) {
|
||||
$long_opt{$1} = 2;
|
||||
undef $last_long_opt;
|
||||
} elsif (/\Qasprintf(\E[^,]+, "--([^"=]+)=/ || /\Qargs[ac++]\E = "--([^"=]+)=/) {
|
||||
$long_opt{$1} = 1;
|
||||
undef $last_long_opt;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
|
||||
my $short_no_arg = join('', sort keys %short_no_arg);
|
||||
my $short_with_num = join('', sort keys %short_with_num);
|
||||
|
||||
print <<EOT;
|
||||
|
||||
# These options are the only options that rsync might send to the server,
|
||||
# and only in the option format that the stock rsync produces.
|
||||
|
||||
# To disable a short-named option, add its letter to this string:
|
||||
our \$short_disabled = '';
|
||||
|
||||
our \$short_no_arg = '$short_no_arg'; # DO NOT REMOVE ANY
|
||||
our \$short_with_num = '$short_with_num'; # 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 = (
|
||||
EOT
|
||||
|
||||
foreach my $opt (sort keys %long_opt) {
|
||||
my $val = $long_opt{$opt};
|
||||
$val = 1 if $opt =~ /^max-/;
|
||||
$val = 3 if $opt eq 'files-from';
|
||||
$val = '$ro ? -1 : ' . $val if $opt =~ /^remove-/;
|
||||
print " '$opt' => $val,\n";
|
||||
}
|
||||
|
||||
print ");\n\n";
|
||||
172
support/file-attr-restore
Executable file
172
support/file-attr-restore
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/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 = eval "\"$name\"";
|
||||
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
|
||||
}
|
||||
27
support/files-to-excludes
Executable file
27
support/files-to-excludes
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/perl
|
||||
# This script takes an input of filenames and outputs a set of
|
||||
# include/exclude directives that can be used by rsync to copy
|
||||
# just the indicated files using an --exclude-from=FILE option.
|
||||
use strict;
|
||||
|
||||
my %hash;
|
||||
|
||||
while (<>) {
|
||||
chomp;
|
||||
s#^/+##;
|
||||
my $path = '/';
|
||||
while (m#([^/]+/)/*#g) {
|
||||
$path .= $1;
|
||||
print "+ $path\n" unless $hash{$path}++;
|
||||
}
|
||||
if (m#([^/]+)$#) {
|
||||
print "+ $path$1\n";
|
||||
} else {
|
||||
delete $hash{$path};
|
||||
}
|
||||
}
|
||||
|
||||
foreach (sort keys %hash) {
|
||||
print "- $_*\n";
|
||||
}
|
||||
print "- /*\n";
|
||||
34
support/logfilter
Executable file
34
support/logfilter
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/perl
|
||||
# Filter the rsync daemon log messages by module name. The log file can be
|
||||
# in either syslog format or rsync's own log-file format. Note that the
|
||||
# MODULE_NAME parameter is used in a regular-expression match in order to
|
||||
# allow regex wildcards to be used. You can also limit the output by
|
||||
# directory hierarchy in a module. Examples:
|
||||
#
|
||||
# logfilter foo /var/log/rsyncd.log # output lines for module foo
|
||||
# logfilter foo/dir /var/log/syslog # limit lines to those in dir of foo
|
||||
|
||||
use strict;
|
||||
|
||||
my $match = shift;
|
||||
die "Usage: logfilter MODULE_NAME [LOGFILE ...]\n" unless defined $match;
|
||||
|
||||
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 ';
|
||||
|
||||
my %pids;
|
||||
|
||||
while (<>) {
|
||||
my($pid,$msg) = /^(?:$syslog_prefix|$rsyncd_prefix)\[(\d+)\]:? (.*)/o;
|
||||
next unless defined $pid;
|
||||
my($mod_spec) = $msg =~ /^rsync (?:on|to) (\S+) from /;
|
||||
if (defined $mod_spec) {
|
||||
if ($mod_spec =~ /^$match(\/\S*)?$/o) {
|
||||
$pids{$pid} = 1;
|
||||
} else {
|
||||
delete $pids{$pid};
|
||||
}
|
||||
}
|
||||
next unless $pids{$pid};
|
||||
print $_;
|
||||
}
|
||||
201
support/rrsync
201
support/rrsync
@@ -2,18 +2,28 @@
|
||||
# Name: /usr/local/bin/rrsync (should also have a symlink in /usr/bin)
|
||||
# Purpose: Restricts rsync to subdirectory declared in .ssh/authorized_keys
|
||||
# Author: Joe Smith <js-cgi@inwap.com> 30-Sep-2004
|
||||
# Modified by Wayne Davison <wayned@samba.org> 12-Jan-2005
|
||||
# Modified by: Wayne Davison <wayned@samba.org>
|
||||
use strict;
|
||||
|
||||
use Socket;
|
||||
use Cwd 'abs_path';
|
||||
use File::Glob ':glob';
|
||||
|
||||
# You may configure these values to your liking. See also the section
|
||||
# of options if you want to disable any options that rsync accepts.
|
||||
use constant RSYNC => '/usr/bin/rsync';
|
||||
use constant LOGFILE => 'rrsync.log';
|
||||
|
||||
my $Usage = <<EOM;
|
||||
Use 'command="$0 [-ro] SUBDIR"'
|
||||
in front of lines in $ENV{HOME}/.ssh/authorized_keys
|
||||
EOM
|
||||
|
||||
my $ro = (@ARGV and $ARGV[0] eq '-ro') ? shift : ''; # -ro = Read-Only
|
||||
my $subdir = shift;
|
||||
die "No subdirectory specified\n$Usage" unless defined $subdir;
|
||||
our $ro = (@ARGV && $ARGV[0] eq '-ro') ? shift : ''; # -ro = Read-Only
|
||||
our $subdir = shift;
|
||||
die "$0: No subdirectory specified\n$Usage" unless defined $subdir;
|
||||
$subdir = abs_path($subdir);
|
||||
die "$0: Restricted directory does not exist!\n" if $subdir ne '/' && !-d $subdir;
|
||||
|
||||
# The client uses "rsync -av -e ssh src/ server:dir/", and sshd on the server
|
||||
# executes this program when .ssh/authorized_keys has 'command="..."'.
|
||||
@@ -22,53 +32,166 @@ die "No subdirectory specified\n$Usage" unless defined $subdir;
|
||||
# command="rrsync -ro results" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAmkHG1WCjC...
|
||||
#
|
||||
# Format of the envrionment variables set by sshd:
|
||||
# SSH_ORIGINAL_COMMAND=rsync --server -vlogDtpr --partial . dir # push
|
||||
# SSH_ORIGINAL_COMMAND=rsync --server --sender -vlogDtpr --partial . dir # pull
|
||||
# SSH_ORIGINAL_COMMAND=rsync --server -vlogDtpr --partial . ARG # push
|
||||
# SSH_ORIGINAL_COMMAND=rsync --server --sender -vlogDtpr --partial . ARGS # pull
|
||||
# SSH_CONNECTION=client_addr client_port server_port
|
||||
|
||||
my $command = $ENV{SSH_ORIGINAL_COMMAND};
|
||||
die "Not invoked via sshd\n$Usage" unless defined $command;
|
||||
die "SSH_ORIGINAL_COMMAND='$command' is not rsync\n" unless $command =~ /^rsync\s/;
|
||||
die "$0 -ro: sending to read-only server not allowed\n"
|
||||
if $ro and $command !~ /^rsync --server --sender /;
|
||||
die "$0 -ro: use of $1 with read-only server not allowed\n"
|
||||
if $ro and $command =~ /\s(--remove-\S+)/;
|
||||
die "$0: Not invoked via sshd\n$Usage" unless defined $command;
|
||||
die "$0: SSH_ORIGINAL_COMMAND='$command' is not rsync\n" unless $command =~ s/^rsync\s+//;
|
||||
our $am_sender = $command =~ /^--server\s+--sender\s/; # Restrictive on purpose!
|
||||
die "$0 -ro: sending to read-only server not allowed\n" if $ro && !$am_sender;
|
||||
|
||||
my ($cmd,$dir) = $command =~ /^(rsync\s+(?:-[-a-zA-Z]+\s+)+\.) ?("[^"]*"|[^\s"]*)$/;
|
||||
die "$0: invalid rsync-command syntax or options\n" if !defined $cmd;
|
||||
### START of options data produced by the cull_options script. ###
|
||||
|
||||
# Enforce default of $subdir instead of the normal $HOME default.
|
||||
my $orig = $dir;
|
||||
my @dirs;
|
||||
$dir =~ s/^"(.*?)"$/$1/;
|
||||
$dir =~ s/^\s+//;
|
||||
$dir =~ s/\s+$//;
|
||||
foreach (split(/(?<!\\)\s+/, $dir)) {
|
||||
s/\\(\s)/$1/g; # Unescape any escaped whitespace
|
||||
if ($subdir eq '/') { # Less checking for '/' access
|
||||
$dir = '/' if $dir eq '';
|
||||
} else {
|
||||
s#^/##; # Don't allow absolute paths
|
||||
$_ = "$subdir/$_" unless m#^\Q$subdir\E(/|$)#;
|
||||
1 while s#/\.\.(/|$)#/__/#g; # Don't allow foo/../../etc
|
||||
}
|
||||
tr#-_/a-zA-Z0-9.,+@^%: #_#c; # Don't allow '"&;|!=()[]{}<>*?#\$
|
||||
s/(\s)/\\$1/g; # Re-escape whitespace
|
||||
push(@dirs, $_);
|
||||
# These options are the only options that rsync might send to the server,
|
||||
# and only in the option format that the stock rsync produces.
|
||||
|
||||
# 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_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 = (
|
||||
'backup-dir' => 2,
|
||||
'bwlimit' => 1,
|
||||
'checksum-seed' => 1,
|
||||
'compare-dest' => 2,
|
||||
'copy-dest' => 2,
|
||||
'copy-unsafe-links' => 0,
|
||||
'daemon' => 0,
|
||||
'delay-updates' => 0,
|
||||
'delete' => 0,
|
||||
'delete-after' => 0,
|
||||
'delete-before' => 0,
|
||||
'delete-during' => 0,
|
||||
'delete-excluded' => 0,
|
||||
'existing' => 0,
|
||||
'files-from' => 3,
|
||||
'force' => 0,
|
||||
'from0' => 0,
|
||||
'fuzzy' => 0,
|
||||
'ignore-errors' => 0,
|
||||
'ignore-existing' => 0,
|
||||
'inplace' => 0,
|
||||
'link-dest' => 2,
|
||||
'list-only' => 0,
|
||||
'log-format' => 1,
|
||||
'max-delete' => 1,
|
||||
'max-size' => 1,
|
||||
'modify-window' => 1,
|
||||
'no-implied-dirs' => 0,
|
||||
'no-relative' => 0,
|
||||
'numeric-ids' => 0,
|
||||
'only-write-batch' => 1,
|
||||
'partial' => 0,
|
||||
'partial-dir' => 2,
|
||||
'remove-sent-files' => $ro ? -1 : 0,
|
||||
'safe-links' => 0,
|
||||
'sender' => 0,
|
||||
'server' => 0,
|
||||
'size-only' => 0,
|
||||
'suffix' => 1,
|
||||
'temp-dir' => 2,
|
||||
'timeout' => 1,
|
||||
);
|
||||
|
||||
### END of options data produced by the cull_options script. ###
|
||||
|
||||
if ($short_disabled ne '') {
|
||||
$short_no_arg =~ s/[$short_disabled]//go;
|
||||
$short_with_num =~ s/[$short_disabled]//go;
|
||||
}
|
||||
push(@dirs, $subdir) unless @dirs;
|
||||
$dir = join(' ', @dirs);
|
||||
$short_no_arg = "[$short_no_arg]" if length($short_no_arg) > 1;
|
||||
$short_with_num = "[$short_with_num]" if length($short_with_num) > 1;
|
||||
|
||||
if (-f LOGFILE and open LOG,'>>',LOGFILE) {
|
||||
my $write_log = -f LOGFILE && open(LOG, '>>', LOGFILE);
|
||||
|
||||
chdir($subdir) or die "$0: Unable to chdir to restricted dir: $!\n";
|
||||
|
||||
my(@opts, @args);
|
||||
my $in_options = 1;
|
||||
my $last_opt = '';
|
||||
my $check_type;
|
||||
while ($command =~ /((?:[^\s\\]+|\\.[^\s\\]*)+)/g) {
|
||||
$_ = $1;
|
||||
if ($check_type) {
|
||||
push(@opts, check_arg($last_opt, $_, $check_type));
|
||||
$check_type = 0;
|
||||
} elsif ($in_options) {
|
||||
push(@opts, $_);
|
||||
if ($_ eq '.') {
|
||||
$in_options = 0;
|
||||
} else {
|
||||
next if /^-$short_no_arg+$/o || /^-$short_with_num\d+$/o;
|
||||
|
||||
my($opt,$arg) = /^--([^=]+)(?:=(.*))?$/;
|
||||
my $disabled;
|
||||
if (defined $opt) {
|
||||
my $ct = $long_opt{$opt};
|
||||
last unless defined $ct;
|
||||
next if $ct == 0;
|
||||
if ($ct > 0) {
|
||||
if (!defined $arg) {
|
||||
$check_type = $ct;
|
||||
$last_opt = $opt;
|
||||
next;
|
||||
}
|
||||
$arg = check_arg($opt, $arg, $ct);
|
||||
$opts[-1] =~ s/=.*/=$arg/;
|
||||
next;
|
||||
}
|
||||
$disabled = 1;
|
||||
$opt = "--$opt";
|
||||
} elsif ($short_disabled ne '') {
|
||||
$disabled = /^-$short_no_arg*([$short_disabled])/o;
|
||||
$opt = "-$1";
|
||||
}
|
||||
|
||||
last unless $disabled; # Generate generic failure
|
||||
die "$0: option $opt has been disabled on this server.\n";
|
||||
}
|
||||
} else {
|
||||
if ($subdir ne '/') {
|
||||
# Validate args to ensure they don't try to leave our restricted dir.
|
||||
s#//+#/#g;
|
||||
s#^/##;
|
||||
s#^$#.#;
|
||||
die "Do not use .. in any path!\n" if m#(^|/)\\?\.\\?\.(\\?/|$)#;
|
||||
}
|
||||
push(@args, bsd_glob($_, GLOB_LIMIT|GLOB_NOCHECK|GLOB_BRACE|GLOB_QUOTE));
|
||||
}
|
||||
}
|
||||
die "$0: invalid rsync-command syntax or options\n" if $in_options;
|
||||
|
||||
@args = ( '.' ) if !@args;
|
||||
|
||||
if ($write_log) {
|
||||
my ($mm,$hh) = (localtime)[1,2];
|
||||
my $host = $ENV{SSH_CONNECTION} || 'unknown';
|
||||
$host =~ s/ .*//; # Keep only the client's IP addr
|
||||
$host =~ s/ .*//; # Keep only the client's IP addr
|
||||
$host =~ s/^::ffff://;
|
||||
$host = gethostbyaddr(inet_aton($host),AF_INET) || $host;
|
||||
my $dir_result = $dir eq $orig ? " OK" : "> \"$dir\"";
|
||||
printf LOG "%02d:%02d %-13s [%s] =%s\n", $hh, $mm, $host, $command, $dir_result;
|
||||
printf LOG "%02d:%02d %-13s [%s]\n", $hh, $mm, $host, "@opts @args";
|
||||
close LOG;
|
||||
}
|
||||
|
||||
exec "$cmd \"$dir\"" or die "exec($cmd \"$dir\") failed: $? $!";
|
||||
# Note: This assumes that the rsync protocol will not be maliciously hijacked.
|
||||
exec(RSYNC, @opts, @args) or die "exec(rsync @opts @args) failed: $? $!";
|
||||
|
||||
sub check_arg
|
||||
{
|
||||
my($opt, $arg, $type) = @_;
|
||||
$arg =~ s/\\(.)/$1/g;
|
||||
if ($subdir ne '/' && ($type == 3 || ($type == 2 && !$am_sender))) {
|
||||
$arg =~ s#//#/#g;
|
||||
die "Do not use .. in --$opt; anchor the path at the root of your restricted dir.\n"
|
||||
if $arg =~ m#(^|/)\.\.(/|$)#;
|
||||
$arg =~ s#^/#$subdir/#;
|
||||
}
|
||||
$arg;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
use Getopt::Long;
|
||||
|
||||
# You may wish to edit the next line to customize for your default log file.
|
||||
$usage_file = "/var/adm/rsyncd.log";
|
||||
$usage_file = "/var/log/rsyncd.log";
|
||||
|
||||
# Edit the following lines for default report settings.
|
||||
# Entries defined here will be over-ridden by the command line.
|
||||
@@ -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 =~ /^>/) {
|
||||
|
||||
@@ -7,20 +7,13 @@
|
||||
* -o Save the output coming from PROGRAM to the OUTPUT_FILE
|
||||
*
|
||||
* If you want to capture the flow of data for an rsync command, use one of
|
||||
* the following commands (the first two are push commands, the last two are
|
||||
* pull commands):
|
||||
* the following commands (the resulting files should be identical):
|
||||
*
|
||||
* rsync -av --rsh="savetransfer -i /tmp/from.sender ssh"
|
||||
* --rsync-path="savetransfer -i /tmp/to.receiver rsync" FILES HOST:DEST
|
||||
* rsync -av --rsh="savetransfer -i /tmp/to.server ssh"
|
||||
* --rsync-path="savetransfer -i /tmp/from.client rsync" SOURCE DEST
|
||||
*
|
||||
* rsync -av --rsh="savetransfer -o /tmp/to.sender ssh"
|
||||
* --rsync-path="savetransfer -o /tmp/from.generator rsync" FILES HOST:DEST
|
||||
*
|
||||
* rsync -av --rsh="savetransfer -i /tmp/from.generator ssh"
|
||||
* --rsync-path="savetransfer -i /tmp/to.sender rsync" HOST:FILES DEST
|
||||
*
|
||||
* rsync -av --rsh="savetransfer -o /tmp/to.receiver ssh"
|
||||
* --rsync-path="savetransfer -o /tmp/from.sender rsync" HOST:FILES DEST
|
||||
* rsync -av --rsh="savetransfer -o /tmp/from.server ssh"
|
||||
* --rsync-path="savetransfer -o /tmp/to.client rsync" SOURCE DEST
|
||||
*
|
||||
* Note that this program aborts after 30 seconds of inactivity, so you'll need
|
||||
* to change it if that is not enough dead time for your transfer. Also, some
|
||||
|
||||
32
syscall.c
32
syscall.c
@@ -45,14 +45,14 @@ extern int preserve_perms;
|
||||
|
||||
#define RETURN_ERROR_IF_RO_OR_LO RETURN_ERROR_IF(read_only || list_only, EROFS)
|
||||
|
||||
int do_unlink(char *fname)
|
||||
int do_unlink(const char *fname)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
return unlink(fname);
|
||||
}
|
||||
|
||||
int do_symlink(char *fname1, char *fname2)
|
||||
int do_symlink(const char *fname1, const char *fname2)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
@@ -60,7 +60,7 @@ int do_symlink(char *fname1, char *fname2)
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINK
|
||||
int do_link(char *fname1, char *fname2)
|
||||
int do_link(const char *fname1, const char *fname2)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
@@ -104,7 +104,11 @@ int do_mknod(char *pathname, mode_t mode, dev_t dev)
|
||||
|| (bind(sock, (struct sockaddr*)&saddr, sizeof saddr)) < 0)
|
||||
return -1;
|
||||
close(sock);
|
||||
#ifdef HAVE_CHMOD
|
||||
return do_chmod(pathname, mode);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_MKNOD
|
||||
@@ -114,14 +118,14 @@ int do_mknod(char *pathname, mode_t mode, dev_t dev)
|
||||
#endif
|
||||
}
|
||||
|
||||
int do_rmdir(char *pathname)
|
||||
int do_rmdir(const char *pathname)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
return rmdir(pathname);
|
||||
}
|
||||
|
||||
int do_open(char *pathname, int flags, mode_t mode)
|
||||
int do_open(const char *pathname, int flags, mode_t mode)
|
||||
{
|
||||
if (flags != O_RDONLY) {
|
||||
RETURN_ERROR_IF(dry_run, 0);
|
||||
@@ -137,21 +141,27 @@ int do_chmod(const char *path, mode_t mode)
|
||||
int code;
|
||||
if (dry_run) return 0;
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
code = chmod(path, mode);
|
||||
if (S_ISLNK(mode)) {
|
||||
#ifdef HAVE_LCHMOD
|
||||
code = lchmod(path, mode & CHMOD_BITS);
|
||||
#else
|
||||
code = 1;
|
||||
#endif
|
||||
} else
|
||||
code = chmod(path, mode & CHMOD_BITS);
|
||||
if (code != 0 && preserve_perms)
|
||||
return code;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int do_rename(char *fname1, char *fname2)
|
||||
int do_rename(const char *fname1, const char *fname2)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
RETURN_ERROR_IF_RO_OR_LO;
|
||||
return rename(fname1, fname2);
|
||||
}
|
||||
|
||||
|
||||
void trim_trailing_slashes(char *name)
|
||||
{
|
||||
int l;
|
||||
@@ -170,7 +180,6 @@ void trim_trailing_slashes(char *name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int do_mkdir(char *fname, mode_t mode)
|
||||
{
|
||||
if (dry_run) return 0;
|
||||
@@ -179,7 +188,6 @@ int do_mkdir(char *fname, mode_t mode)
|
||||
return mkdir(fname, mode);
|
||||
}
|
||||
|
||||
|
||||
/* like mkstemp but forces permissions */
|
||||
int do_mkstemp(char *template, mode_t perms)
|
||||
{
|
||||
@@ -244,7 +252,11 @@ int do_fstat(int fd, STRUCT_STAT *st)
|
||||
OFF_T do_lseek(int fd, OFF_T offset, int whence)
|
||||
{
|
||||
#ifdef HAVE_LSEEK64
|
||||
#if !SIZEOF_OFF64_T
|
||||
OFF_T lseek64();
|
||||
#else
|
||||
off64_t lseek64();
|
||||
#endif
|
||||
return lseek64(fd, offset, whence);
|
||||
#else
|
||||
return lseek(fd, offset, whence);
|
||||
|
||||
3
t_stub.c
3
t_stub.c
@@ -28,6 +28,9 @@
|
||||
|
||||
int modify_window = 0;
|
||||
int module_id = -1;
|
||||
int relative_paths = 0;
|
||||
int human_readable = 0;
|
||||
mode_t orig_umask = 002;
|
||||
char *partial_dir;
|
||||
struct filter_list_struct server_filter_list;
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@ name2="$fromdir/name2"
|
||||
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
cat $srcdir/[gr]*.[ch] > "$name1"
|
||||
cat $srcdir/[et]*.[ch] > "$name2"
|
||||
cat "$srcdir"/[gr]*.[ch] > "$name1"
|
||||
cat "$srcdir"/[et]*.[ch] > "$name2"
|
||||
|
||||
checkit "$RSYNC -avv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
checkit "$RSYNC -avv \"$fromdir/\" \"$chkdir/\"" "$fromdir" "$chkdir"
|
||||
cat $srcdir/[fgpr]*.[ch] > "$name1"
|
||||
cat $srcdir/[etw]*.[ch] > "$name2"
|
||||
cat "$srcdir"/[fgpr]*.[ch] > "$name1"
|
||||
cat "$srcdir"/[etw]*.[ch] > "$name2"
|
||||
|
||||
$RSYNC -avv --no-whole-file --backup "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
@@ -49,8 +49,8 @@ diff -r $diffopt "$chkdir" "$bakdir" || test_fail "backup dir contents are bogus
|
||||
rm "$bakdir/dname"
|
||||
|
||||
checkit "$RSYNC -avv --del \"$fromdir/\" \"$chkdir/\"" "$fromdir" "$chkdir"
|
||||
cat $srcdir/[efgr]*.[ch] > "$name1"
|
||||
cat $srcdir/[ew]*.[ch] > "$name2"
|
||||
cat "$srcdir"/[efgr]*.[ch] > "$name1"
|
||||
cat "$srcdir"/[ew]*.[ch] > "$name2"
|
||||
|
||||
checkit "$RSYNC -avv --inplace --no-whole-file --backup --backup-dir=\"$bakdir\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
|
||||
| tee "$outfile"
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
cd "$tmpdir"
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
# Build some hardlinks
|
||||
|
||||
mygrps="`rsync_getgroups`" || fail "Can't get groups"
|
||||
|
||||
42
testsuite/chmod-option.test
Normal file
42
testsuite/chmod-option.test
Normal file
@@ -0,0 +1,42 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test that the --chmod option functions correctly.
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
# Build some files
|
||||
|
||||
fromdir="$scratchdir/from"
|
||||
todir="$scratchdir/to"
|
||||
checkdir="$scratchdir/check"
|
||||
|
||||
mkdir "$fromdir"
|
||||
name1="$fromdir/name1"
|
||||
name2="$fromdir/name2"
|
||||
dir1="$fromdir/dir1"
|
||||
dir2="$fromdir/dir2"
|
||||
echo "This is the file" > "$name1"
|
||||
echo "This is the other file" > "$name2"
|
||||
mkdir "$dir1" "$dir2"
|
||||
|
||||
chmod 4700 "$name1" || test_skipped "Can't chmod"
|
||||
chmod 700 "$dir1"
|
||||
chmod 770 "$dir2"
|
||||
|
||||
# Copy the files we've created over to another directory
|
||||
checkit "$RSYNC -avv \"$fromdir/\" \"$checkdir/\"" "$fromdir" "$checkdir"
|
||||
|
||||
# And then manually make the changes which should occur
|
||||
umask 002
|
||||
chmod ug-s,a+rX "$checkdir"/*
|
||||
chmod +w "$checkdir" "$checkdir"/dir*
|
||||
|
||||
checkit "$RSYNC -avv --chmod ug-s,a+rX,D+w \"$fromdir/\" \"$todir/\"" "$checkdir" "$todir"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL see
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test that various read-only and set[ug]id permissions work properly,
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
tmpdir2=/tmp
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL see
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test that various read-only and set[ug]id permissions work properly,
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
chmod 440 "$fromdir/text"
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
case `id -u` in
|
||||
'') ;; # If "id" failed, try to continue...
|
||||
0) ;;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL see
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync handling of the --compare-dest option.
|
||||
@@ -14,8 +14,6 @@ alt2dir="$tmpdir/alt2"
|
||||
|
||||
# Build some files/dirs/links to copy
|
||||
|
||||
set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
# Setup the alt and chk dirs
|
||||
|
||||
@@ -26,8 +26,6 @@ build_rsyncd_conf
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
# Build chkdir with a normal rsync and an --exclude.
|
||||
|
||||
@@ -20,8 +20,6 @@ build_rsyncd_conf
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
# Build chkdir with a normal rsync and an --exclude.
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
|
||||
# Copyright (C) 2005 by Wayne Davison <wayned@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL see
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync handling of various delete directives.
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
makepath "$chkdir"
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
chkfile="$scratchdir/rsync.chk"
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
# Build some hardlinks
|
||||
|
||||
case `id -u` in
|
||||
@@ -16,7 +19,7 @@ case `id -u` in
|
||||
0) ;;
|
||||
*) if [ -f /usr/bin/fakeroot ]; then
|
||||
echo "Let's try re-running the script under fakeroot..."
|
||||
exec /usr/bin/fakeroot /bin/sh "$0"
|
||||
exec /usr/bin/fakeroot /bin/sh $RUNSHFLAGS "$0"
|
||||
fi
|
||||
test_skipped "Rsync won't copy devices unless we're root"
|
||||
;;
|
||||
@@ -25,15 +28,66 @@ esac
|
||||
# TODO: Need to test whether hardlinks are possible on this OS/filesystem
|
||||
|
||||
mkdir "$fromdir"
|
||||
mkdir "$todir"
|
||||
mknod "$fromdir/char" c 41 67 || test_skipped "Can't create char device node unless root"
|
||||
mknod "$fromdir/char2" c 42 68 || test_skipped "Can't create char device node unless root"
|
||||
mknod "$fromdir/char3" c 42 69 || test_skipped "Can't create char device node unless root"
|
||||
mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node unless root"
|
||||
mknod "$fromdir/block2" b 42 73 || test_skipped "Can't create block device node unless root"
|
||||
mknod "$fromdir/block3" b 105 73 || test_skipped "Can't create block device node unless root"
|
||||
ln "$fromdir/block3" "$fromdir/block2.5" || echo "Skipping hard-linked device test..."
|
||||
mkfifo "$fromdir/fifo" || test_skipped "Can't run mkfifo"
|
||||
touch -r "$fromdir/block" "$fromdir/block2"
|
||||
|
||||
checkit "$RSYNC -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" skip_file_diff
|
||||
$RSYNC -ai "$fromdir/block" "$todir/block2" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
cD+++++++ block
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
|
||||
|
||||
$RSYNC -ai "$fromdir/block2" "$todir/block" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
cD+++++++ block2
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
|
||||
|
||||
sleep 1
|
||||
|
||||
$RSYNC -Di "$fromdir/block3" "$todir/block" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
cD..T.... block3
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
|
||||
|
||||
$RSYNC -aiHvv "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cD..t.... block
|
||||
cD....... block2
|
||||
cD+++++++ block3
|
||||
hD+++++++ block2.5 => block3
|
||||
cD+++++++ char
|
||||
cD+++++++ char2
|
||||
cD+++++++ char3
|
||||
cS+++++++ fifo
|
||||
EOT
|
||||
if test ! -b "$fromdir/block2.5"; then
|
||||
sed -e '/block2\.5/d' \
|
||||
<"$chkfile" >"$chkfile.new"
|
||||
mv "$chkfile.new" "$chkfile"
|
||||
fi
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
|
||||
|
||||
echo "check how the directory listings compare with diff:"
|
||||
echo ""
|
||||
( cd "$fromdir" && rsync_ls_lR . ) > "$tmpdir/ls-from"
|
||||
( cd "$todir" && rsync_ls_lR . ) > "$tmpdir/ls-to"
|
||||
diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
|
||||
41
testsuite/dir-sgid.test
Normal file
41
testsuite/dir-sgid.test
Normal file
@@ -0,0 +1,41 @@
|
||||
#! /bin/sh
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test that rsync obeys directory setgid. -- Matt McCutchen
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
umask 077
|
||||
|
||||
# Call as: testit <dirname> <dirperms> <file-expected> <program-expected> <dir-expected>
|
||||
testit() {
|
||||
todir="$scratchdir/$1"
|
||||
mkdir "$todir"
|
||||
chmod $2 "$todir"
|
||||
# Make sure we obey directory setgid when creating a directory to hold multiple transferred files,
|
||||
# even though the directory itself is outside the transfer
|
||||
$RSYNC -rvv "$scratchdir/dir" "$scratchdir/file" "$scratchdir/program" "$todir/to/"
|
||||
check_perms "$todir/to" $5 "Target $1"
|
||||
check_perms "$todir/to/dir" $5 "Target $1"
|
||||
check_perms "$todir/to/file" $3 "Target $1"
|
||||
check_perms "$todir/to/program" $4 "Target $1"
|
||||
}
|
||||
|
||||
echo "File!" >"$scratchdir/file"
|
||||
echo "#!/bin/sh" >"$scratchdir/program"
|
||||
mkdir "$scratchdir/dir"
|
||||
chmod 2764 "$scratchdir/dir" || test_skipped "Can't chmod"
|
||||
chmod 664 "$scratchdir/file"
|
||||
chmod 775 "$scratchdir/program"
|
||||
[ -g "$scratchdir/dir" ] || test_skipped "The directory setgid bit vanished!"
|
||||
mkdir "$scratchdir/dir/blah"
|
||||
[ -g "$scratchdir/dir/blah" ] || test_skipped "Your filesystem doesn't use directory setgid; maybe it's BSD."
|
||||
|
||||
# Test some target directories
|
||||
testit setgid-off 700 rw------- rwx------ rwx------
|
||||
testit setgid-on 2700 rw------- rwx------ rwx--S---
|
||||
|
||||
# Hooray
|
||||
exit 0
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL see
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync handling of duplicate filenames.
|
||||
@@ -21,8 +21,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
# Build some hardlinks
|
||||
|
||||
mkdir "$fromdir"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Copyright (C) 2003, 2004, 2005 by Wayne Davison <wayned@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL see
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync handling of exclude/include directives.
|
||||
@@ -12,18 +12,18 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
HOME="$scratchdir"
|
||||
CVSIGNORE='*.junk'
|
||||
export HOME CVSIGNORE
|
||||
|
||||
set -x
|
||||
export CVSIGNORE
|
||||
|
||||
# Build some files/dirs/links to copy
|
||||
|
||||
makepath "$fromdir/foo/down/to/you"
|
||||
makepath "$fromdir/foo/sub"
|
||||
makepath "$fromdir/bar/down/to/foo/too"
|
||||
makepath "$fromdir/bar/down/to/bar/baz"
|
||||
makepath "$fromdir/mid/for/foo/and/that/is/who"
|
||||
makepath "$fromdir/new/keep/this"
|
||||
makepath "$fromdir/new/lose/this"
|
||||
cat >"$fromdir/.filt" <<EOF
|
||||
exclude down
|
||||
: .filt-temp
|
||||
@@ -32,13 +32,14 @@ clear
|
||||
- *.bak
|
||||
- *.old
|
||||
EOF
|
||||
echo kept >"$fromdir/foo/file1"
|
||||
echo filtered-1 >"$fromdir/foo/file1"
|
||||
echo removed >"$fromdir/foo/file2"
|
||||
echo cvsout >"$fromdir/foo/file2.old"
|
||||
cat >"$fromdir/foo/.filt" <<EOF
|
||||
include .filt
|
||||
- file1
|
||||
- /file1
|
||||
EOF
|
||||
echo not-filtered-1 >"$fromdir/foo/sub/file1"
|
||||
cat >"$fromdir/bar/.filt" <<EOF
|
||||
- home-cvs-exclude
|
||||
dir-merge .filt2
|
||||
@@ -87,8 +88,12 @@ cat >"$excl" <<EOF
|
||||
- /bar
|
||||
# This should match against the whole path, not just the name.
|
||||
+ foo**too
|
||||
# This should float at the end of the path.
|
||||
# These should float at the end of the path.
|
||||
+ foo/s?b/
|
||||
- foo/*/
|
||||
# Test how /** differs from /***
|
||||
- new/keep/**
|
||||
- new/lose/***
|
||||
# Test some normal excludes. Competing lines are paired.
|
||||
+ t[o]/
|
||||
- to
|
||||
@@ -109,6 +114,8 @@ sleep 1 # Ensures that the rm commands will tweak the directory times.
|
||||
|
||||
rm -r "$chkdir"/foo/down
|
||||
rm -r "$chkdir"/mid/for/foo/and
|
||||
rm -r "$chkdir"/new/keep/this
|
||||
rm -r "$chkdir"/new/lose
|
||||
rm "$chkdir"/foo/file[235-9]
|
||||
rm "$chkdir"/bar/down/to/foo/to "$chkdir"/bar/down/to/foo/file[235-9]
|
||||
rm "$chkdir"/mid/for/foo/extra
|
||||
@@ -196,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
|
||||
|
||||
47
testsuite/executability.test
Normal file
47
testsuite/executability.test
Normal file
@@ -0,0 +1,47 @@
|
||||
#! /bin/sh
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test the --executability or -E option. -- Matt McCutchen
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
# Put some files in the From directory
|
||||
mkdir "$fromdir"
|
||||
cat <<EOF >"$fromdir/1"
|
||||
#!/bin/sh
|
||||
echo 'Program One!'
|
||||
EOF
|
||||
cat <<EOF >"$fromdir/2"
|
||||
#!/bin/sh
|
||||
echo 'Program Two!'
|
||||
EOF
|
||||
|
||||
chmod 1700 "$fromdir/1" || test_skipped "Can't chmod"
|
||||
chmod 600 "$fromdir/2"
|
||||
|
||||
$RSYNC -rvv "$fromdir/" "$todir/"
|
||||
|
||||
check_perms "$todir/1" rwx------ 1
|
||||
check_perms "$todir/2" rw------- 1
|
||||
|
||||
# Mix up the permissions a bit
|
||||
chmod 600 "$fromdir/1"
|
||||
chmod 601 "$fromdir/2"
|
||||
chmod 604 "$todir/2"
|
||||
|
||||
$RSYNC -rvv "$fromdir/" "$todir/"
|
||||
|
||||
# No -E, so nothing should have changed
|
||||
check_perms "$todir/1" rwx------ 2
|
||||
check_perms "$todir/2" rw----r-- 2
|
||||
|
||||
$RSYNC -rvvE "$fromdir/" "$todir/"
|
||||
|
||||
# Now things should have happened!
|
||||
check_perms "$todir/1" rw------- 3
|
||||
check_perms "$todir/2" rwx---r-x 3
|
||||
|
||||
# Hooray
|
||||
exit 0
|
||||
@@ -2,15 +2,13 @@
|
||||
|
||||
# Copyright (C) 2005 by Wayne Davison <wayned@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL see
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test rsync handling of the --fuzzy option.
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
mkdir "$fromdir"
|
||||
mkdir "$todir"
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
# Build some hardlinks
|
||||
|
||||
fromdir="$scratchdir/from"
|
||||
|
||||
271
testsuite/itemize.test
Normal file
271
testsuite/itemize.test
Normal file
@@ -0,0 +1,271 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2005 by Wayne Davison <wayned@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test the output of various copy commands to ensure itemized output
|
||||
# and double-verbose output is correct.
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
lddir="$tmpdir/ld"
|
||||
|
||||
chkfile="$scratchdir/rsync.chk"
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
makepath "$fromdir/foo"
|
||||
makepath "$fromdir/bar/baz"
|
||||
cp -p "$srcdir/configure.in" "$fromdir/foo/config1"
|
||||
cp -p "$srcdir/config.h.in" "$fromdir/foo/config2"
|
||||
cp -p "$srcdir/rsync.h" "$fromdir/bar/baz/rsync"
|
||||
chmod 600 "$fromdir"/foo/config? "$fromdir/bar/baz/rsync"
|
||||
umask 0
|
||||
ln -s ../bar/baz/rsync "$fromdir/foo/sym"
|
||||
umask 022
|
||||
ln "$fromdir/foo/config1" "$fromdir/foo/extra"
|
||||
|
||||
$RSYNC -iplr "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
>f+++++++ bar/baz/rsync
|
||||
cd+++++++ foo/
|
||||
>f+++++++ foo/config1
|
||||
>f+++++++ foo/config2
|
||||
>f+++++++ foo/extra
|
||||
cL+++++++ foo/sym -> ../bar/baz/rsync
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
|
||||
|
||||
# Ensure there are no accidental directory-time problems.
|
||||
$RSYNC -a -f '-! */' "$fromdir/" "$todir"
|
||||
|
||||
cp -p "$srcdir/configure.in" "$fromdir/foo/config2"
|
||||
chmod 601 "$fromdir/foo/config2"
|
||||
$RSYNC -iplrH "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
>f..T.... bar/baz/rsync
|
||||
>f..T.... foo/config1
|
||||
>f.sTp... foo/config2
|
||||
hf..T.... foo/extra => foo/config1
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
|
||||
|
||||
$RSYNC -a -f '-! */' "$fromdir/" "$todir"
|
||||
sleep 1 # For directory mod below to ensure time difference
|
||||
rm "$todir/foo/sym"
|
||||
umask 0
|
||||
ln -s ../bar/baz "$todir/foo/sym"
|
||||
umask 022
|
||||
cp -p "$srcdir/config.h.in" "$fromdir/foo/config2"
|
||||
chmod 600 "$fromdir/foo/config2"
|
||||
chmod 777 "$todir/bar/baz/rsync"
|
||||
|
||||
$RSYNC -iplrtc "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
.f..tp... bar/baz/rsync
|
||||
.d..t.... foo/
|
||||
.f..t.... foo/config1
|
||||
>fcstp... foo/config2
|
||||
cL..T.... foo/sym -> ../bar/baz/rsync
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
|
||||
|
||||
cp -p "$srcdir/configure.in" "$fromdir/foo/config2"
|
||||
chmod 600 "$fromdir/foo/config2"
|
||||
# Lack of -t is for unchanged hard-link stress-test!
|
||||
$RSYNC -vvplrH "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
bar/baz/rsync is uptodate
|
||||
foo/config1 is uptodate
|
||||
foo/config2
|
||||
"foo/extra" is a hard link
|
||||
foo/sym is uptodate
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
|
||||
|
||||
chmod 747 "$todir/bar/baz/rsync"
|
||||
$RSYNC -a -f '-! */' "$fromdir/" "$todir"
|
||||
$RSYNC -ivvplrtH "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
.d ./
|
||||
.d bar/
|
||||
.d bar/baz/
|
||||
.f...p... bar/baz/rsync
|
||||
.d foo/
|
||||
.f foo/config1
|
||||
>f..t.... foo/config2
|
||||
hf foo/extra
|
||||
.L foo/sym -> ../bar/baz/rsync
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
|
||||
|
||||
chmod 757 "$todir/foo/config1"
|
||||
touch "$todir/foo/config2"
|
||||
$RSYNC -vplrtH "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
foo/config2
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 6 failed"
|
||||
|
||||
chmod 757 "$todir/foo/config1"
|
||||
touch "$todir/foo/config2"
|
||||
$RSYNC -iplrtH "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
.f...p... foo/config1
|
||||
>f..t.... foo/config2
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
|
||||
|
||||
mv "$todir" "$lddir"
|
||||
$RSYNC -ivvplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
cf bar/baz/rsync
|
||||
cd+++++++ foo/
|
||||
cf foo/config1
|
||||
cf foo/config2
|
||||
hf foo/extra => foo/config1
|
||||
cL..T.... foo/sym -> ../bar/baz/rsync
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -iplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
cd+++++++ foo/
|
||||
hf foo/extra => foo/config1
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -vvplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
./
|
||||
bar/
|
||||
bar/baz/
|
||||
bar/baz/rsync is uptodate
|
||||
foo/
|
||||
foo/config1 is uptodate
|
||||
foo/config2 is uptodate
|
||||
"foo/extra" is a hard link
|
||||
foo/extra => foo/config1
|
||||
foo/sym is uptodate
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 10 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -ivvplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
hf bar/baz/rsync
|
||||
cd+++++++ foo/
|
||||
hf foo/config1
|
||||
hf foo/config2
|
||||
hf foo/extra => foo/config1
|
||||
hL foo/sym -> ../bar/baz/rsync
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -iplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
cd+++++++ foo/
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 12 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -vvplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
./
|
||||
bar/
|
||||
bar/baz/
|
||||
bar/baz/rsync is uptodate
|
||||
foo/
|
||||
foo/config1 is uptodate
|
||||
foo/config2 is uptodate
|
||||
"foo/extra" is a hard link
|
||||
foo/sym is uptodate
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 13 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -ivvplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
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+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
.f bar/baz/rsync
|
||||
cd+++++++ foo/
|
||||
.f foo/config1
|
||||
.f foo/config2
|
||||
.L foo/sym -> ../bar/baz/rsync
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -iplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
cat <<EOT >"$chkfile"
|
||||
.d..t.... ./
|
||||
cd+++++++ bar/
|
||||
cd+++++++ bar/baz/
|
||||
cd+++++++ foo/
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
|
||||
|
||||
rm -rf "$todir"
|
||||
$RSYNC -vvplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
|
||||
| tee "$outfile"
|
||||
filter_outfile
|
||||
cat <<EOT >"$chkfile"
|
||||
./
|
||||
bar/
|
||||
bar/baz/
|
||||
bar/baz/rsync is uptodate
|
||||
foo/
|
||||
foo/config1 is uptodate
|
||||
foo/config2 is uptodate
|
||||
"foo/extra" is a hard link
|
||||
foo/sym is uptodate
|
||||
EOT
|
||||
diff $diffopt "$chkfile" "$outfile" || test_fail "test 16 failed"
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
longname=This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
# Build some files/dirs/links to copy
|
||||
|
||||
from1dir="${fromdir}1"
|
||||
|
||||
@@ -32,6 +32,9 @@ else
|
||||
diffopt="-c"
|
||||
fi
|
||||
|
||||
HOME="$scratchdir"
|
||||
export HOME
|
||||
|
||||
runtest() {
|
||||
echo $ECHO_N "Test $1: $ECHO_C"
|
||||
if eval "$2"
|
||||
@@ -44,15 +47,38 @@ runtest() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Call this if you want to filter out verbose messages (-v or -vv) from
|
||||
# the output of an rsync run (whittling the output down to just the file
|
||||
# messages). This isn't needed if you use -i without -v.
|
||||
filter_outfile() {
|
||||
sed -e '/^building file list /d' \
|
||||
-e '/^created directory /d' \
|
||||
-e '/^done$/d' \
|
||||
-e '/ --whole-file$/d' \
|
||||
-e '/^total: /d' \
|
||||
-e '/^$/,$d' \
|
||||
<"$outfile" >"$outfile.new"
|
||||
mv "$outfile.new" "$outfile"
|
||||
}
|
||||
|
||||
printmsg() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
|
||||
rsync_ls_lR() {
|
||||
find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls"
|
||||
}
|
||||
|
||||
check_perms() {
|
||||
perms=`"$TOOLDIR/tls" "$1" | sed 's/^[-d]\(.........\).*/\1/'`
|
||||
if test $perms = $2; then
|
||||
return 0
|
||||
fi
|
||||
echo "permissions: $perms on $1"
|
||||
echo "should be: $2"
|
||||
test_fail "failed test $3"
|
||||
}
|
||||
|
||||
rsync_getgroups() {
|
||||
"$TOOLDIR/getgroups"
|
||||
}
|
||||
@@ -92,7 +118,7 @@ hands_setup() {
|
||||
ln -s nolf "$fromdir/nolf-symlink"
|
||||
umask 022
|
||||
|
||||
cat $srcdir/*.c > "$fromdir/text"
|
||||
cat "$srcdir"/*.c > "$fromdir/text"
|
||||
mkdir "$fromdir/dir"
|
||||
cp "$fromdir/text" "$fromdir/dir"
|
||||
mkdir "$fromdir/dir/subdir"
|
||||
@@ -118,7 +144,7 @@ hands_setup() {
|
||||
####################
|
||||
# Many machines do not have "mkdir -p", so we have to build up long paths.
|
||||
# How boring.
|
||||
makepath () {
|
||||
makepath() {
|
||||
echo " makepath $1"
|
||||
p="$1"
|
||||
(
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
build_symlinks || test_fail "failed to build symlinks"
|
||||
|
||||
# Copy recursively, but without -l or -L or -a, and all the symlinks
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
"$TOOLDIR/trimslash" "/usr/local/bin" "/usr/local/bin/" "/usr/local/bin///" \
|
||||
"//a//" "////" \
|
||||
"/Users/Wierd Macintosh Name/// Ooh, translucent plastic/" \
|
||||
|
||||
@@ -32,8 +32,6 @@ ln -s ../files/file1 "from/safe/links/"
|
||||
ln -s ../files/file2 "from/safe/links/"
|
||||
ln -s ../../unsafe/unsafefile "from/safe/links/"
|
||||
|
||||
set -x
|
||||
|
||||
echo "rsync with relative path and just -a";
|
||||
$RSYNC -avv from/safe/ to
|
||||
test_symlink to/links/file1
|
||||
|
||||
@@ -9,12 +9,15 @@
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
"$TOOLDIR/wildtest" "$srcdir/wildtest.txt" >"$scratchdir/wild.out"
|
||||
diff $diffopt "$scratchdir/wild.out" - <<EOF
|
||||
# This test exercises the wildmatch() function (with no options) and the
|
||||
# wildmatch_join() function (using -x and/or -e).
|
||||
for opts in "" -x1 "-x1 -e1" "-x1 -e1se" -x2 "-x2 -ese" -x3 "-x3 -e1" -x4 "-x4 -e2e" -x5 "-x5 -es"; do
|
||||
echo Running wildtest with "$opts"
|
||||
"$TOOLDIR/wildtest" $opts "$srcdir/wildtest.txt" >"$scratchdir/wild.out"
|
||||
diff $diffopt "$scratchdir/wild.out" - <<EOF
|
||||
No wildmatch errors found.
|
||||
EOF
|
||||
done
|
||||
|
||||
# The script would have aborted on error, so getting here means we've won.
|
||||
exit 0
|
||||
|
||||
12
tls.c
12
tls.c
@@ -100,12 +100,12 @@ static void list_file(const char *fname)
|
||||
mt = gmtime(&buf.st_mtime);
|
||||
|
||||
sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
mt->tm_year + 1900,
|
||||
mt->tm_mon + 1,
|
||||
mt->tm_mday,
|
||||
mt->tm_hour,
|
||||
mt->tm_min,
|
||||
mt->tm_sec);
|
||||
(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, " ");
|
||||
}
|
||||
|
||||
58
token.c
58
token.c
@@ -22,46 +22,60 @@
|
||||
|
||||
extern int do_compression;
|
||||
extern int module_id;
|
||||
extern int def_compress_level;
|
||||
|
||||
static int compression_level = Z_DEFAULT_COMPRESSION;
|
||||
static int compression_level, per_file_default_level;
|
||||
|
||||
/* determine the compression level based on a wildcard filename list */
|
||||
void set_compression(char *fname)
|
||||
{
|
||||
char *dont;
|
||||
char *tok;
|
||||
static char *match_list;
|
||||
char *s;
|
||||
|
||||
if (!do_compression)
|
||||
return;
|
||||
|
||||
compression_level = Z_DEFAULT_COMPRESSION;
|
||||
dont = lp_dont_compress(module_id);
|
||||
|
||||
if (!dont || !*dont)
|
||||
return;
|
||||
|
||||
if (dont[0] == '*' && !dont[1]) {
|
||||
/* an optimization to skip the rest of this routine */
|
||||
compression_level = 0;
|
||||
return;
|
||||
if (!match_list) {
|
||||
char *t, *f = lp_dont_compress(module_id);
|
||||
int len = strlen(f);
|
||||
if (!(match_list = t = new_array(char, len + 2)))
|
||||
out_of_memory("set_compression");
|
||||
while (*f) {
|
||||
if (*f == ' ') {
|
||||
f++;
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
if (isupper(*(unsigned char *)f))
|
||||
*t++ = tolower(*(unsigned char *)f);
|
||||
else
|
||||
*t++ = *f;
|
||||
} while (*++f != ' ' && *f);
|
||||
*t++ = '\0';
|
||||
}
|
||||
/* Optimize a match-string of "*". */
|
||||
if (t - match_list == 2 && match_list[0] == '*') {
|
||||
t = match_list;
|
||||
per_file_default_level = 0;
|
||||
} else
|
||||
per_file_default_level = def_compress_level;
|
||||
*t++ = '\0';
|
||||
}
|
||||
|
||||
dont = strdup(dont);
|
||||
fname = strdup(fname);
|
||||
if (!dont || !fname)
|
||||
compression_level = per_file_default_level;
|
||||
|
||||
if (!*match_list)
|
||||
return;
|
||||
|
||||
strlower(dont);
|
||||
strlower(fname);
|
||||
if ((s = strrchr(fname, '/')) != NULL)
|
||||
fname = s + 1;
|
||||
|
||||
for (tok = strtok(dont, " "); tok; tok = strtok(NULL, " ")) {
|
||||
if (wildmatch(tok, fname)) {
|
||||
for (s = match_list; *s; s += strlen(s) + 1) {
|
||||
if (iwildmatch(s, fname)) {
|
||||
compression_level = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(dont);
|
||||
free(fname);
|
||||
}
|
||||
|
||||
/* non-compressing recv token */
|
||||
|
||||
@@ -324,7 +324,6 @@ void recv_uid_list(int f, struct file_list *flist)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (preserve_gid && !numeric_ids) {
|
||||
/* read the gid list */
|
||||
while ((id = read_int(f)) != 0) {
|
||||
@@ -337,8 +336,7 @@ void recv_uid_list(int f, struct file_list *flist)
|
||||
}
|
||||
}
|
||||
|
||||
/* now convert the uid/gid of all files in the list to the mapped
|
||||
* uid/gid */
|
||||
/* Now convert all the uids/gids from sender values to our values. */
|
||||
if (am_root && preserve_uid && !numeric_ids) {
|
||||
for (i = 0; i < flist->count; i++)
|
||||
flist->files[i]->uid = match_uid(flist->files[i]->uid);
|
||||
|
||||
342
util.c
342
util.c
@@ -31,6 +31,9 @@ extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int module_id;
|
||||
extern int modify_window;
|
||||
extern int relative_paths;
|
||||
extern int human_readable;
|
||||
extern mode_t orig_umask;
|
||||
extern char *partial_dir;
|
||||
extern struct filter_list_struct server_filter_list;
|
||||
|
||||
@@ -68,7 +71,6 @@ void set_blocking(int fd)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a file descriptor pair - like pipe() but use socketpair if
|
||||
* possible (because of blocking issues on pipes).
|
||||
@@ -93,7 +95,6 @@ int fd_pair(int fd[2])
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void print_child_argv(char **cmd)
|
||||
{
|
||||
rprintf(FINFO, "opening connection using ");
|
||||
@@ -105,34 +106,36 @@ void print_child_argv(char **cmd)
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789"
|
||||
",.-_=+@/") != strlen(*cmd)) {
|
||||
rprintf(FINFO, "\"%s\" ", safe_fname(*cmd));
|
||||
rprintf(FINFO, "\"%s\" ", *cmd);
|
||||
} else {
|
||||
rprintf(FINFO, "%s ", safe_fname(*cmd));
|
||||
rprintf(FINFO, "%s ", *cmd);
|
||||
}
|
||||
}
|
||||
rprintf(FINFO, "\n");
|
||||
}
|
||||
|
||||
|
||||
void out_of_memory(char *str)
|
||||
{
|
||||
rprintf(FERROR, "ERROR: out of memory in %s\n", str);
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
|
||||
void overflow(char *str)
|
||||
void overflow_exit(char *str)
|
||||
{
|
||||
rprintf(FERROR, "ERROR: buffer overflow in %s\n", str);
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int set_modtime(char *fname, time_t modtime)
|
||||
int set_modtime(char *fname, time_t modtime, mode_t mode)
|
||||
{
|
||||
#if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
|
||||
if (S_ISLNK(mode))
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
if (verbose > 2) {
|
||||
rprintf(FINFO, "set modtime of %s to (%ld) %s",
|
||||
safe_fname(fname), (long)modtime,
|
||||
fname, (long)modtime,
|
||||
asctime(localtime(&modtime)));
|
||||
}
|
||||
|
||||
@@ -140,7 +143,18 @@ int set_modtime(char *fname, time_t modtime)
|
||||
return 0;
|
||||
|
||||
{
|
||||
#ifdef HAVE_UTIMBUF
|
||||
#ifdef HAVE_UTIMES
|
||||
struct timeval t[2];
|
||||
t[0].tv_sec = time(NULL);
|
||||
t[0].tv_usec = 0;
|
||||
t[1].tv_sec = modtime;
|
||||
t[1].tv_usec = 0;
|
||||
# ifdef HAVE_LUTIMES
|
||||
if (S_ISLNK(mode))
|
||||
return lutimes(fname, t);
|
||||
# endif
|
||||
return utimes(fname, t);
|
||||
#elif defined HAVE_UTIMBUF
|
||||
struct utimbuf tbuf;
|
||||
tbuf.actime = time(NULL);
|
||||
tbuf.modtime = modtime;
|
||||
@@ -151,41 +165,49 @@ int set_modtime(char *fname, time_t modtime)
|
||||
t[1] = modtime;
|
||||
return utime(fname,t);
|
||||
#else
|
||||
struct timeval t[2];
|
||||
t[0].tv_sec = time(NULL);
|
||||
t[0].tv_usec = 0;
|
||||
t[1].tv_sec = modtime;
|
||||
t[1].tv_usec = 0;
|
||||
return utimes(fname,t);
|
||||
#error No file-time-modification routine found!
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/**
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write @p len bytes at @p ptr to descriptor @p desc, retrying if
|
||||
@@ -216,7 +238,6 @@ int full_write(int desc, char *ptr, size_t len)
|
||||
return total_written;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read @p len bytes at @p ptr from descriptor @p desc, retrying if
|
||||
* interrupted.
|
||||
@@ -242,12 +263,11 @@ static int safe_read(int desc, char *ptr, size_t len)
|
||||
return n_chars;
|
||||
}
|
||||
|
||||
|
||||
/** Copy a file.
|
||||
*
|
||||
* This is used in conjunction with the --temp-dir, --backup, and
|
||||
* --copy-dest options. */
|
||||
int copy_file(char *source, char *dest, mode_t mode)
|
||||
int copy_file(const char *source, const char *dest, mode_t mode)
|
||||
{
|
||||
int ifd;
|
||||
int ofd;
|
||||
@@ -316,7 +336,7 @@ int copy_file(char *source, char *dest, mode_t mode)
|
||||
* --delete trying to remove old .rsyncNNN files, hence it renames it
|
||||
* each time.
|
||||
**/
|
||||
int robust_unlink(char *fname)
|
||||
int robust_unlink(const char *fname)
|
||||
{
|
||||
#ifndef ETXTBSY
|
||||
return do_unlink(fname);
|
||||
@@ -351,7 +371,7 @@ int robust_unlink(char *fname)
|
||||
|
||||
if (verbose > 0) {
|
||||
rprintf(FINFO,"renaming %s to %s because of text busy\n",
|
||||
safe_fname(fname), safe_fname(path));
|
||||
fname, path);
|
||||
}
|
||||
|
||||
/* maybe we should return rename()'s exit status? Nah. */
|
||||
@@ -364,8 +384,11 @@ int robust_unlink(char *fname)
|
||||
}
|
||||
|
||||
/* Returns 0 on successful rename, 1 if we successfully copied the file
|
||||
* across filesystems, -2 if copy_file() failed, and -1 on other errors. */
|
||||
int robust_rename(char *from, char *to, int mode)
|
||||
* across filesystems, -2 if copy_file() failed, and -1 on other errors.
|
||||
* If partialptr is not NULL and we need to do a copy, copy the file into
|
||||
* the active partial-dir instead of over the destination file. */
|
||||
int robust_rename(char *from, char *to, char *partialptr,
|
||||
int mode)
|
||||
{
|
||||
int tries = 4;
|
||||
|
||||
@@ -381,6 +404,11 @@ int robust_rename(char *from, char *to, int mode)
|
||||
break;
|
||||
#endif
|
||||
case EXDEV:
|
||||
if (partialptr) {
|
||||
if (!handle_partial_dir(partialptr,PDIR_CREATE))
|
||||
return -1;
|
||||
to = partialptr;
|
||||
}
|
||||
if (copy_file(from, to, mode) != 0)
|
||||
return -2;
|
||||
do_unlink(from);
|
||||
@@ -392,7 +420,6 @@ int robust_rename(char *from, char *to, int mode)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static pid_t all_pids[10];
|
||||
static int num_pids;
|
||||
|
||||
@@ -436,7 +463,6 @@ void kill_all(int sig)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Turn a user name into a uid */
|
||||
int name_to_uid(char *name, uid_t *uid)
|
||||
{
|
||||
@@ -465,7 +491,6 @@ int name_to_gid(char *name, gid_t *gid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Lock a byte range in a open file */
|
||||
int lock_range(int fd, int offset, int len)
|
||||
{
|
||||
@@ -517,7 +542,6 @@ static void glob_expand_one(char *s, char ***argv_ptr, int *argc_ptr,
|
||||
filter_server_path(s);
|
||||
#else
|
||||
glob_t globbuf;
|
||||
int i;
|
||||
|
||||
if (maxargs <= argc)
|
||||
return;
|
||||
@@ -542,9 +566,9 @@ static void glob_expand_one(char *s, char ***argv_ptr, int *argc_ptr,
|
||||
if (globbuf.gl_pathc == 0)
|
||||
argv[argc++] = s;
|
||||
else {
|
||||
int j = globbuf.gl_pathc;
|
||||
int i;
|
||||
free(s);
|
||||
for (i = 0; i < j; i++) {
|
||||
for (i = 0; i < (int)globbuf.gl_pathc; i++) {
|
||||
if (!(argv[argc++] = strdup(globbuf.gl_pathv[i])))
|
||||
out_of_memory("glob_expand_one");
|
||||
}
|
||||
@@ -745,7 +769,7 @@ unsigned int clean_fname(char *name, BOOL collapse_dot_dot)
|
||||
char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
|
||||
{
|
||||
char *start, *sanp;
|
||||
int rlen = 0;
|
||||
int rlen = 0, leave_one_dotdir = relative_paths;
|
||||
|
||||
if (dest != p) {
|
||||
int plen = strlen(p);
|
||||
@@ -780,9 +804,13 @@ char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
|
||||
* always be left pointing after a slash
|
||||
*/
|
||||
if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
|
||||
/* skip "." component */
|
||||
p++;
|
||||
continue;
|
||||
if (leave_one_dotdir && p[1])
|
||||
leave_one_dotdir = 0;
|
||||
else {
|
||||
/* skip "." component */
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
|
||||
/* ".." component followed by slash or end */
|
||||
@@ -877,43 +905,6 @@ int pop_dir(char *dir)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return the filename, turning any non-printable characters into escaped
|
||||
* characters (e.g. \n -> \012, \ -> \\). This ensures that outputting it
|
||||
* cannot generate an empty line nor corrupt the screen. This function can
|
||||
* return only MAX_SAFE_NAMES values at a time! The returned value can be
|
||||
* longer than MAXPATHLEN (because we may be trying to output an error about
|
||||
* a too-long filename)! */
|
||||
char *safe_fname(const char *fname)
|
||||
{
|
||||
#define MAX_SAFE_NAMES 4
|
||||
static char fbuf[MAX_SAFE_NAMES][MAXPATHLEN*2];
|
||||
static int ndx = 0;
|
||||
int limit = sizeof fbuf / MAX_SAFE_NAMES - 1;
|
||||
char *t;
|
||||
|
||||
ndx = (ndx + 1) % MAX_SAFE_NAMES;
|
||||
for (t = fbuf[ndx]; *fname; fname++) {
|
||||
if (*fname == '\\') {
|
||||
if ((limit -= 2) < 0)
|
||||
break;
|
||||
*t++ = '\\';
|
||||
*t++ = '\\';
|
||||
} else if (!isprint(*(uchar*)fname)) {
|
||||
if ((limit -= 4) < 0)
|
||||
break;
|
||||
sprintf(t, "\\%03o", *(uchar*)fname);
|
||||
t += 4;
|
||||
} else {
|
||||
if (--limit < 0)
|
||||
break;
|
||||
*t++ = *fname;
|
||||
}
|
||||
}
|
||||
*t = '\0';
|
||||
|
||||
return fbuf[ndx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a quoted string with the full pathname of the indicated filename.
|
||||
* The string " (in MODNAME)" may also be appended. The returned pointer
|
||||
@@ -928,7 +919,6 @@ char *full_fname(const char *fn)
|
||||
if (result)
|
||||
free(result);
|
||||
|
||||
fn = safe_fname(fn);
|
||||
if (*fn == '/')
|
||||
p1 = p2 = "";
|
||||
else {
|
||||
@@ -1023,22 +1013,6 @@ int handle_partial_dir(const char *fname, int create)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** We need to supply our own strcmp function for file list comparisons
|
||||
to ensure that signed/unsigned usage is consistent between machines. */
|
||||
int u_strcmp(const char *cs1, const char *cs2)
|
||||
{
|
||||
const uchar *s1 = (const uchar *)cs1;
|
||||
const uchar *s2 = (const uchar *)cs2;
|
||||
|
||||
while (*s1 && *s2 && (*s1 == *s2)) {
|
||||
s1++; s2++;
|
||||
}
|
||||
|
||||
return (int)*s1 - (int)*s2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a symlink points outside the current directory tree.
|
||||
* This is considered "unsafe" because e.g. when mirroring somebody
|
||||
@@ -1103,6 +1077,63 @@ int unsafe_symlink(const char *dest, const char *src)
|
||||
return (depth < 0);
|
||||
}
|
||||
|
||||
/* Return the int64 number as a string. If the --human-readable option was
|
||||
* specified, we may output the number in K, M, or G units. We can return
|
||||
* up to 4 buffers at a time. */
|
||||
char *human_num(int64 num)
|
||||
{
|
||||
static char bufs[4][128]; /* more than enough room */
|
||||
static unsigned int n;
|
||||
char *s;
|
||||
|
||||
n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
|
||||
|
||||
if (human_readable) {
|
||||
char units = '\0';
|
||||
int mult = human_readable == 1 ? 1000 : 1024;
|
||||
double dnum = 0;
|
||||
if (num > mult*mult*mult) {
|
||||
dnum = (double)num / (mult*mult*mult);
|
||||
units = 'G';
|
||||
} else if (num > mult*mult) {
|
||||
dnum = (double)num / (mult*mult);
|
||||
units = 'M';
|
||||
} else if (num > mult) {
|
||||
dnum = (double)num / mult;
|
||||
units = 'K';
|
||||
}
|
||||
if (units) {
|
||||
sprintf(bufs[n], "%.2f%c", dnum, units);
|
||||
return bufs[n];
|
||||
}
|
||||
}
|
||||
|
||||
s = bufs[n] + sizeof bufs[0] - 1;
|
||||
*s = '\0';
|
||||
|
||||
if (!num)
|
||||
*--s = '0';
|
||||
while (num) {
|
||||
*--s = (num % 10) + '0';
|
||||
num /= 10;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return the double number as a string. If the --human-readable option was
|
||||
* specified, we may output the number in K, M, or G units. We use a buffer
|
||||
* from human_num() to return our result. */
|
||||
char *human_dnum(double dnum, int decimal_digits)
|
||||
{
|
||||
char *buf = human_num(dnum);
|
||||
int len = strlen(buf);
|
||||
if (isdigit(*(uchar*)(buf+len-1))) {
|
||||
/* There's extra room in buf prior to the start of the num. */
|
||||
buf -= decimal_digits + 1;
|
||||
snprintf(buf, len + decimal_digits + 2, "%.*f", decimal_digits, dnum);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the date and time as a string
|
||||
@@ -1111,6 +1142,7 @@ char *timestring(time_t t)
|
||||
{
|
||||
static char TimeBuf[200];
|
||||
struct tm *tm = localtime(&t);
|
||||
char *p;
|
||||
|
||||
#ifdef HAVE_STRFTIME
|
||||
strftime(TimeBuf, sizeof TimeBuf - 1, "%Y/%m/%d %H:%M:%S", tm);
|
||||
@@ -1118,14 +1150,12 @@ char *timestring(time_t t)
|
||||
strlcpy(TimeBuf, asctime(tm), sizeof TimeBuf);
|
||||
#endif
|
||||
|
||||
if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
|
||||
TimeBuf[strlen(TimeBuf)-1] = 0;
|
||||
}
|
||||
if ((p = strchr(TimeBuf, '\n')) != NULL)
|
||||
*p = '\0';
|
||||
|
||||
return(TimeBuf);
|
||||
return TimeBuf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sleep for a specified number of milliseconds.
|
||||
*
|
||||
@@ -1154,11 +1184,8 @@ int msleep(int t)
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if two file modification times are equivalent (either
|
||||
* exact or in the modification timestamp window established by
|
||||
* --modify-window).
|
||||
/* Determine if two time_t values are equivalent (either exact, or in
|
||||
* the modification timestamp window established by --modify-window).
|
||||
*
|
||||
* @retval 0 if the times should be treated as the same
|
||||
*
|
||||
@@ -1166,7 +1193,7 @@ int msleep(int t)
|
||||
*
|
||||
* @retval -1 if the 2nd is later
|
||||
**/
|
||||
int cmp_modtime(time_t file1, time_t file2)
|
||||
int cmp_time(time_t file1, time_t file2)
|
||||
{
|
||||
if (file2 > file1) {
|
||||
if (file2 - file1 <= modify_window)
|
||||
@@ -1212,7 +1239,6 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define MALLOC_MAX 0x40000000
|
||||
|
||||
void *_new_array(unsigned int size, unsigned long num)
|
||||
@@ -1338,3 +1364,95 @@ uint32 fuzzy_distance(const char *s1, int len1, const char *s2, int len2)
|
||||
|
||||
return a[len2-1];
|
||||
}
|
||||
|
||||
#define BB_SLOT_SIZE (16*1024) /* Desired size in bytes */
|
||||
#define BB_PER_SLOT_BITS (BB_SLOT_SIZE * 8) /* Number of bits per slot */
|
||||
#define BB_PER_SLOT_INTS (BB_SLOT_SIZE / 4) /* Number of int32s per slot */
|
||||
|
||||
struct bitbag {
|
||||
uint32 **bits;
|
||||
int slot_cnt;
|
||||
};
|
||||
|
||||
struct bitbag *bitbag_create(int max_ndx)
|
||||
{
|
||||
struct bitbag *bb = new(struct bitbag);
|
||||
bb->slot_cnt = (max_ndx + BB_PER_SLOT_BITS - 1) / BB_PER_SLOT_BITS;
|
||||
|
||||
if (!(bb->bits = (uint32**)calloc(bb->slot_cnt, sizeof (uint32*))))
|
||||
out_of_memory("bitbag_create");
|
||||
|
||||
return bb;
|
||||
}
|
||||
|
||||
void bitbag_set_bit(struct bitbag *bb, int ndx)
|
||||
{
|
||||
int slot = ndx / BB_PER_SLOT_BITS;
|
||||
ndx %= BB_PER_SLOT_BITS;
|
||||
|
||||
if (!bb->bits[slot]) {
|
||||
if (!(bb->bits[slot] = (uint32*)calloc(BB_PER_SLOT_INTS, 4)))
|
||||
out_of_memory("bitbag_set_bit");
|
||||
}
|
||||
|
||||
bb->bits[slot][ndx/32] |= 1u << (ndx % 32);
|
||||
}
|
||||
|
||||
#if 0 /* not needed yet */
|
||||
void bitbag_clear_bit(struct bitbag *bb, int ndx)
|
||||
{
|
||||
int slot = ndx / BB_PER_SLOT_BITS;
|
||||
ndx %= BB_PER_SLOT_BITS;
|
||||
|
||||
if (!bb->bits[slot])
|
||||
return;
|
||||
|
||||
bb->bits[slot][ndx/32] &= ~(1u << (ndx % 32));
|
||||
}
|
||||
|
||||
int bitbag_check_bit(struct bitbag *bb, int ndx)
|
||||
{
|
||||
int slot = ndx / BB_PER_SLOT_BITS;
|
||||
ndx %= BB_PER_SLOT_BITS;
|
||||
|
||||
if (!bb->bits[slot])
|
||||
return 0;
|
||||
|
||||
return bb->bits[slot][ndx/32] & (1u << (ndx % 32)) ? 1 : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Call this with -1 to start checking from 0. Returns -1 at the end. */
|
||||
int bitbag_next_bit(struct bitbag *bb, int after)
|
||||
{
|
||||
uint32 bits, mask;
|
||||
int i, ndx = after + 1;
|
||||
int slot = ndx / BB_PER_SLOT_BITS;
|
||||
ndx %= BB_PER_SLOT_BITS;
|
||||
|
||||
mask = (1u << (ndx % 32)) - 1;
|
||||
for (i = ndx / 32; slot < bb->slot_cnt; slot++, i = mask = 0) {
|
||||
if (!bb->bits[slot])
|
||||
continue;
|
||||
for ( ; i < BB_PER_SLOT_INTS; i++, mask = 0) {
|
||||
if (!(bits = bb->bits[slot][i] & ~mask))
|
||||
continue;
|
||||
/* The xor magic figures out the lowest enabled bit in
|
||||
* bits, and the switch quickly computes log2(bit). */
|
||||
switch (bits ^ (bits & (bits-1))) {
|
||||
#define LOG2(n) case 1u << n: return slot*BB_PER_SLOT_BITS + i*32 + n
|
||||
LOG2(0); LOG2(1); LOG2(2); LOG2(3);
|
||||
LOG2(4); LOG2(5); LOG2(6); LOG2(7);
|
||||
LOG2(8); LOG2(9); LOG2(10); LOG2(11);
|
||||
LOG2(12); LOG2(13); LOG2(14); LOG2(15);
|
||||
LOG2(16); LOG2(17); LOG2(18); LOG2(19);
|
||||
LOG2(20); LOG2(21); LOG2(22); LOG2(23);
|
||||
LOG2(24); LOG2(25); LOG2(26); LOG2(27);
|
||||
LOG2(28); LOG2(29); LOG2(30); LOG2(31);
|
||||
}
|
||||
return -1; /* impossible... */
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
47
wildtest.c
47
wildtest.c
@@ -7,7 +7,7 @@
|
||||
#define WILD_TEST_ITERATIONS
|
||||
#include "lib/wildmatch.c"
|
||||
|
||||
#include "popt.h"
|
||||
#include <popt.h>
|
||||
|
||||
#ifdef COMPARE_WITH_FNMATCH
|
||||
#include <fnmatch.h>
|
||||
@@ -20,10 +20,16 @@ int wildmatch_errors = 0;
|
||||
typedef char bool;
|
||||
|
||||
int output_iterations = 0;
|
||||
int explode_mod = 0;
|
||||
int empties_mod = 0;
|
||||
int empty_at_start = 0;
|
||||
int empty_at_end = 0;
|
||||
|
||||
static struct poptOption long_options[] = {
|
||||
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
|
||||
{"iterations", 'i', POPT_ARG_NONE, &output_iterations, 0, 0, 0},
|
||||
{"empties", 'e', POPT_ARG_STRING, 0, 'e', 0, 0},
|
||||
{"explode", 'x', POPT_ARG_INT, &explode_mod, 0, 0, 0},
|
||||
{0,0,0,0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -40,7 +46,28 @@ run_test(int line, bool matches, bool same_as_fnmatch,
|
||||
same_as_fnmatch = 0; /* Get rid of unused-variable compiler warning. */
|
||||
#endif
|
||||
|
||||
matched = wildmatch(pattern, text);
|
||||
if (explode_mod) {
|
||||
char buf[MAXPATHLEN*2], *texts[MAXPATHLEN];
|
||||
int pos = 0, cnt = 0, ndx = 0, len = strlen(text);
|
||||
|
||||
if (empty_at_start)
|
||||
texts[ndx++] = "";
|
||||
/* An empty string must turn into at least one empty array item. */
|
||||
while (1) {
|
||||
texts[ndx] = buf + ndx * (explode_mod + 1);
|
||||
strlcpy(texts[ndx++], text + pos, explode_mod + 1);
|
||||
if (pos + explode_mod >= len)
|
||||
break;
|
||||
pos += explode_mod;
|
||||
if (!(++cnt % empties_mod))
|
||||
texts[ndx++] = "";
|
||||
}
|
||||
if (empty_at_end)
|
||||
texts[ndx++] = "";
|
||||
texts[ndx] = NULL;
|
||||
matched = wildmatch_array(pattern, (const char**)texts, 0);
|
||||
} else
|
||||
matched = wildmatch(pattern, text);
|
||||
#ifdef COMPARE_WITH_FNMATCH
|
||||
fn_matched = !fnmatch(pattern, text, flags);
|
||||
#endif
|
||||
@@ -66,6 +93,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char buf[2048], *s, *string[2], *end[2];
|
||||
const char *arg;
|
||||
FILE *fp;
|
||||
int opt, line, i, flag[2];
|
||||
poptContext pc = poptGetContext("wildtest", argc, (const char**)argv,
|
||||
@@ -73,6 +101,16 @@ main(int argc, char **argv)
|
||||
|
||||
while ((opt = poptGetNextOpt(pc)) != -1) {
|
||||
switch (opt) {
|
||||
case 'e':
|
||||
arg = poptGetOptArg(pc);
|
||||
empties_mod = atoi(arg);
|
||||
if (strchr(arg, 's'))
|
||||
empty_at_start = 1;
|
||||
if (strchr(arg, 'e'))
|
||||
empty_at_end = 1;
|
||||
if (!explode_mod)
|
||||
explode_mod = 1024;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: %s\n",
|
||||
poptBadOption(pc, POPT_BADOPTION_NOALIAS),
|
||||
@@ -81,9 +119,12 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (explode_mod && !empties_mod)
|
||||
empties_mod = 1024;
|
||||
|
||||
argv = (char**)poptGetArgs(pc);
|
||||
if (!argv || argv[1]) {
|
||||
fprintf(stderr, "Usage: wildtest TESTFILE\n");
|
||||
fprintf(stderr, "Usage: wildtest [OPTIONS] TESTFILE\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
0 1 bar/baz/foo */foo
|
||||
0 0 foo/bar/baz **/bar*
|
||||
1 1 deep/foo/bar/baz **/bar/*
|
||||
0 1 deep/foo/bar/baz/ **/bar/*
|
||||
1 1 deep/foo/bar/baz/ **/bar/**
|
||||
0 1 deep/foo/bar **/bar/*
|
||||
1 1 deep/foo/bar/ **/bar/**
|
||||
1 1 foo/bar/baz **/bar**
|
||||
1 1 foo/bar/baz/x */bar/**
|
||||
0 0 deep/foo/bar/baz/x */bar/**
|
||||
|
||||
390
zlib/ChangeLog
390
zlib/ChangeLog
@@ -1,5 +1,379 @@
|
||||
|
||||
ChangeLog file for zlib
|
||||
ChangeLog file for zlib
|
||||
|
||||
Changes in 1.2.3 (18 July 2005)
|
||||
- Apply security vulnerability fixes to contrib/infback9 as well
|
||||
- Clean up some text files (carriage returns, trailing space)
|
||||
- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
|
||||
|
||||
Changes in 1.2.2.4 (11 July 2005)
|
||||
- Add inflatePrime() function for starting inflation at bit boundary
|
||||
- Avoid some Visual C warnings in deflate.c
|
||||
- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
|
||||
compile
|
||||
- Fix some spelling errors in comments [Betts]
|
||||
- Correct inflateInit2() error return documentation in zlib.h
|
||||
- Added zran.c example of compressed data random access to examples
|
||||
directory, shows use of inflatePrime()
|
||||
- Fix cast for assignments to strm->state in inflate.c and infback.c
|
||||
- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
|
||||
- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
|
||||
- Add cast in trees.c t avoid a warning [Oberhumer]
|
||||
- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
|
||||
- Update make_vms.com [Zinser]
|
||||
- Initialize state->write in inflateReset() since copied in inflate_fast()
|
||||
- Be more strict on incomplete code sets in inflate_table() and increase
|
||||
ENOUGH and MAXD -- this repairs a possible security vulnerability for
|
||||
invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for
|
||||
discovering the vulnerability and providing test cases.
|
||||
- Add ia64 support to configure for HP-UX [Smith]
|
||||
- Add error return to gzread() for format or i/o error [Levin]
|
||||
- Use malloc.h for OS/2 [Necasek]
|
||||
|
||||
Changes in 1.2.2.3 (27 May 2005)
|
||||
- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
|
||||
- Typecast fread() return values in gzio.c [Vollant]
|
||||
- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
|
||||
- Fix crc check bug in gzread() after gzungetc() [Heiner]
|
||||
- Add the deflateTune() function to adjust internal compression parameters
|
||||
- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
|
||||
- Remove an incorrect assertion in examples/zpipe.c
|
||||
- Add C++ wrapper in infback9.h [Donais]
|
||||
- Fix bug in inflateCopy() when decoding fixed codes
|
||||
- Note in zlib.h how much deflateSetDictionary() actually uses
|
||||
- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
|
||||
- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
|
||||
- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
|
||||
- Add gzdirect() function to indicate transparent reads
|
||||
- Update contrib/minizip [Vollant]
|
||||
- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
|
||||
- Add casts in crc32.c to avoid warnings [Oberhumer]
|
||||
- Add contrib/masmx64 [Vollant]
|
||||
- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
|
||||
|
||||
Changes in 1.2.2.2 (30 December 2004)
|
||||
- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
|
||||
avoid implicit memcpy calls (portability for no-library compilation)
|
||||
- Increase sprintf() buffer size in gzdopen() to allow for large numbers
|
||||
- Add INFLATE_STRICT to check distances against zlib header
|
||||
- Improve WinCE errno handling and comments [Chang]
|
||||
- Remove comment about no gzip header processing in FAQ
|
||||
- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
|
||||
- Add updated make_vms.com [Coghlan], update README
|
||||
- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
|
||||
fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
|
||||
- Add FAQ entry and comments in deflate.c on uninitialized memory access
|
||||
- Add Solaris 9 make options in configure [Gilbert]
|
||||
- Allow strerror() usage in gzio.c for STDC
|
||||
- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
|
||||
- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
|
||||
- Use z_off_t for adler32_combine() and crc32_combine() lengths
|
||||
- Make adler32() much faster for small len
|
||||
- Use OS_CODE in deflate() default gzip header
|
||||
|
||||
Changes in 1.2.2.1 (31 October 2004)
|
||||
- Allow inflateSetDictionary() call for raw inflate
|
||||
- Fix inflate header crc check bug for file names and comments
|
||||
- Add deflateSetHeader() and gz_header structure for custom gzip headers
|
||||
- Add inflateGetheader() to retrieve gzip headers
|
||||
- Add crc32_combine() and adler32_combine() functions
|
||||
- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
|
||||
- Use zstreamp consistently in zlib.h (inflate_back functions)
|
||||
- Remove GUNZIP condition from definition of inflate_mode in inflate.h
|
||||
and in contrib/inflate86/inffast.S [Truta, Anderson]
|
||||
- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
|
||||
- Update projects/README.projects and projects/visualc6 [Truta]
|
||||
- Update win32/DLL_FAQ.txt [Truta]
|
||||
- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
|
||||
- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
|
||||
- Use a new algorithm for setting strm->data_type in trees.c [Truta]
|
||||
- Do not define an exit() prototype in zutil.c unless DEBUG defined
|
||||
- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
|
||||
- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
|
||||
- Fix Darwin build version identification [Peterson]
|
||||
|
||||
Changes in 1.2.2 (3 October 2004)
|
||||
- Update zlib.h comments on gzip in-memory processing
|
||||
- Set adler to 1 in inflateReset() to support Java test suite [Walles]
|
||||
- Add contrib/dotzlib [Ravn]
|
||||
- Update win32/DLL_FAQ.txt [Truta]
|
||||
- Update contrib/minizip [Vollant]
|
||||
- Move contrib/visual-basic.txt to old/ [Truta]
|
||||
- Fix assembler builds in projects/visualc6/ [Truta]
|
||||
|
||||
Changes in 1.2.1.2 (9 September 2004)
|
||||
- Update INDEX file
|
||||
- Fix trees.c to update strm->data_type (no one ever noticed!)
|
||||
- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
|
||||
- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
|
||||
- Add limited multitasking protection to DYNAMIC_CRC_TABLE
|
||||
- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
|
||||
- Don't declare strerror() under VMS [Mozilla]
|
||||
- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
|
||||
- Update contrib/ada [Anisimkov]
|
||||
- Update contrib/minizip [Vollant]
|
||||
- Fix configure to not hardcode directories for Darwin [Peterson]
|
||||
- Fix gzio.c to not return error on empty files [Brown]
|
||||
- Fix indentation; update version in contrib/delphi/ZLib.pas and
|
||||
contrib/pascal/zlibpas.pas [Truta]
|
||||
- Update mkasm.bat in contrib/masmx86 [Truta]
|
||||
- Update contrib/untgz [Truta]
|
||||
- Add projects/README.projects [Truta]
|
||||
- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
|
||||
- Update win32/DLL_FAQ.txt [Truta]
|
||||
- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
|
||||
- Remove an unnecessary assignment to curr in inftrees.c [Truta]
|
||||
- Add OS/2 to exe builds in configure [Poltorak]
|
||||
- Remove err dummy parameter in zlib.h [Kientzle]
|
||||
|
||||
Changes in 1.2.1.1 (9 January 2004)
|
||||
- Update email address in README
|
||||
- Several FAQ updates
|
||||
- Fix a big fat bug in inftrees.c that prevented decoding valid
|
||||
dynamic blocks with only literals and no distance codes --
|
||||
Thanks to "Hot Emu" for the bug report and sample file
|
||||
- Add a note to puff.c on no distance codes case.
|
||||
|
||||
Changes in 1.2.1 (17 November 2003)
|
||||
- Remove a tab in contrib/gzappend/gzappend.c
|
||||
- Update some interfaces in contrib for new zlib functions
|
||||
- Update zlib version number in some contrib entries
|
||||
- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
|
||||
- Support shared libraries on Hurd and KFreeBSD [Brown]
|
||||
- Fix error in NO_DIVIDE option of adler32.c
|
||||
|
||||
Changes in 1.2.0.8 (4 November 2003)
|
||||
- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
|
||||
- Add experimental NO_DIVIDE #define in adler32.c
|
||||
- Possibly faster on some processors (let me know if it is)
|
||||
- Correct Z_BLOCK to not return on first inflate call if no wrap
|
||||
- Fix strm->data_type on inflate() return to correctly indicate EOB
|
||||
- Add deflatePrime() function for appending in the middle of a byte
|
||||
- Add contrib/gzappend for an example of appending to a stream
|
||||
- Update win32/DLL_FAQ.txt [Truta]
|
||||
- Delete Turbo C comment in README [Truta]
|
||||
- Improve some indentation in zconf.h [Truta]
|
||||
- Fix infinite loop on bad input in configure script [Church]
|
||||
- Fix gzeof() for concatenated gzip files [Johnson]
|
||||
- Add example to contrib/visual-basic.txt [Michael B.]
|
||||
- Add -p to mkdir's in Makefile.in [vda]
|
||||
- Fix configure to properly detect presence or lack of printf functions
|
||||
- Add AS400 support [Monnerat]
|
||||
- Add a little Cygwin support [Wilson]
|
||||
|
||||
Changes in 1.2.0.7 (21 September 2003)
|
||||
- Correct some debug formats in contrib/infback9
|
||||
- Cast a type in a debug statement in trees.c
|
||||
- Change search and replace delimiter in configure from % to # [Beebe]
|
||||
- Update contrib/untgz to 0.2 with various fixes [Truta]
|
||||
- Add build support for Amiga [Nikl]
|
||||
- Remove some directories in old that have been updated to 1.2
|
||||
- Add dylib building for Mac OS X in configure and Makefile.in
|
||||
- Remove old distribution stuff from Makefile
|
||||
- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
|
||||
- Update links in README
|
||||
|
||||
Changes in 1.2.0.6 (13 September 2003)
|
||||
- Minor FAQ updates
|
||||
- Update contrib/minizip to 1.00 [Vollant]
|
||||
- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
|
||||
- Update POSTINC comment for 68060 [Nikl]
|
||||
- Add contrib/infback9 with deflate64 decoding (unsupported)
|
||||
- For MVS define NO_vsnprintf and undefine FAR [van Burik]
|
||||
- Add pragma for fdopen on MVS [van Burik]
|
||||
|
||||
Changes in 1.2.0.5 (8 September 2003)
|
||||
- Add OF to inflateBackEnd() declaration in zlib.h
|
||||
- Remember start when using gzdopen in the middle of a file
|
||||
- Use internal off_t counters in gz* functions to properly handle seeks
|
||||
- Perform more rigorous check for distance-too-far in inffast.c
|
||||
- Add Z_BLOCK flush option to return from inflate at block boundary
|
||||
- Set strm->data_type on return from inflate
|
||||
- Indicate bits unused, if at block boundary, and if in last block
|
||||
- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
|
||||
- Add condition so old NO_DEFLATE define still works for compatibility
|
||||
- FAQ update regarding the Windows DLL [Truta]
|
||||
- INDEX update: add qnx entry, remove aix entry [Truta]
|
||||
- Install zlib.3 into mandir [Wilson]
|
||||
- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
|
||||
- Adapt the zlib interface to the new DLL convention guidelines [Truta]
|
||||
- Introduce ZLIB_WINAPI macro to allow the export of functions using
|
||||
the WINAPI calling convention, for Visual Basic [Vollant, Truta]
|
||||
- Update msdos and win32 scripts and makefiles [Truta]
|
||||
- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
|
||||
- Add contrib/ada [Anisimkov]
|
||||
- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
|
||||
- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
|
||||
- Add contrib/masm686 [Truta]
|
||||
- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
|
||||
[Truta, Vollant]
|
||||
- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
|
||||
- Remove contrib/delphi2; add a new contrib/delphi [Truta]
|
||||
- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
|
||||
and fix some method prototypes [Truta]
|
||||
- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
|
||||
[Truta]
|
||||
- Avoid the use of backslash (\) in contrib/minizip [Vollant]
|
||||
- Fix file time handling in contrib/untgz; update makefiles [Truta]
|
||||
- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
|
||||
[Vollant]
|
||||
- Remove contrib/vstudio/vc15_16 [Vollant]
|
||||
- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
|
||||
- Update README.contrib [Truta]
|
||||
- Invert the assignment order of match_head and s->prev[...] in
|
||||
INSERT_STRING [Truta]
|
||||
- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
|
||||
[Truta]
|
||||
- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
|
||||
- Fix prototype of syncsearch in inflate.c [Truta]
|
||||
- Introduce ASMINF macro to be enabled when using an ASM implementation
|
||||
of inflate_fast [Truta]
|
||||
- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
|
||||
- Modify test_gzio in example.c to take a single file name as a
|
||||
parameter [Truta]
|
||||
- Exit the example.c program if gzopen fails [Truta]
|
||||
- Add type casts around strlen in example.c [Truta]
|
||||
- Remove casting to sizeof in minigzip.c; give a proper type
|
||||
to the variable compared with SUFFIX_LEN [Truta]
|
||||
- Update definitions of STDC and STDC99 in zconf.h [Truta]
|
||||
- Synchronize zconf.h with the new Windows DLL interface [Truta]
|
||||
- Use SYS16BIT instead of __32BIT__ to distinguish between
|
||||
16- and 32-bit platforms [Truta]
|
||||
- Use far memory allocators in small 16-bit memory models for
|
||||
Turbo C [Truta]
|
||||
- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
|
||||
zlibCompileFlags [Truta]
|
||||
- Cygwin has vsnprintf [Wilson]
|
||||
- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
|
||||
- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
|
||||
|
||||
Changes in 1.2.0.4 (10 August 2003)
|
||||
- Minor FAQ updates
|
||||
- Be more strict when checking inflateInit2's windowBits parameter
|
||||
- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
|
||||
- Add gzip wrapper option to deflateInit2 using windowBits
|
||||
- Add updated QNX rule in configure and qnx directory [Bonnefoy]
|
||||
- Make inflate distance-too-far checks more rigorous
|
||||
- Clean up FAR usage in inflate
|
||||
- Add casting to sizeof() in gzio.c and minigzip.c
|
||||
|
||||
Changes in 1.2.0.3 (19 July 2003)
|
||||
- Fix silly error in gzungetc() implementation [Vollant]
|
||||
- Update contrib/minizip and contrib/vstudio [Vollant]
|
||||
- Fix printf format in example.c
|
||||
- Correct cdecl support in zconf.in.h [Anisimkov]
|
||||
- Minor FAQ updates
|
||||
|
||||
Changes in 1.2.0.2 (13 July 2003)
|
||||
- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
|
||||
- Attempt to avoid warnings in crc32.c for pointer-int conversion
|
||||
- Add AIX to configure, remove aix directory [Bakker]
|
||||
- Add some casts to minigzip.c
|
||||
- Improve checking after insecure sprintf() or vsprintf() calls
|
||||
- Remove #elif's from crc32.c
|
||||
- Change leave label to inf_leave in inflate.c and infback.c to avoid
|
||||
library conflicts
|
||||
- Remove inflate gzip decoding by default--only enable gzip decoding by
|
||||
special request for stricter backward compatibility
|
||||
- Add zlibCompileFlags() function to return compilation information
|
||||
- More typecasting in deflate.c to avoid warnings
|
||||
- Remove leading underscore from _Capital #defines [Truta]
|
||||
- Fix configure to link shared library when testing
|
||||
- Add some Windows CE target adjustments [Mai]
|
||||
- Remove #define ZLIB_DLL in zconf.h [Vollant]
|
||||
- Add zlib.3 [Rodgers]
|
||||
- Update RFC URL in deflate.c and algorithm.txt [Mai]
|
||||
- Add zlib_dll_FAQ.txt to contrib [Truta]
|
||||
- Add UL to some constants [Truta]
|
||||
- Update minizip and vstudio [Vollant]
|
||||
- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
|
||||
- Expand use of NO_DUMMY_DECL to avoid all dummy structures
|
||||
- Added iostream3 to contrib [Schwardt]
|
||||
- Replace rewind() with fseek() for WinCE [Truta]
|
||||
- Improve setting of zlib format compression level flags
|
||||
- Report 0 for huffman and rle strategies and for level == 0 or 1
|
||||
- Report 2 only for level == 6
|
||||
- Only deal with 64K limit when necessary at compile time [Truta]
|
||||
- Allow TOO_FAR check to be turned off at compile time [Truta]
|
||||
- Add gzclearerr() function [Souza]
|
||||
- Add gzungetc() function
|
||||
|
||||
Changes in 1.2.0.1 (17 March 2003)
|
||||
- Add Z_RLE strategy for run-length encoding [Truta]
|
||||
- When Z_RLE requested, restrict matches to distance one
|
||||
- Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
|
||||
- Correct FASTEST compilation to allow level == 0
|
||||
- Clean up what gets compiled for FASTEST
|
||||
- Incorporate changes to zconf.in.h [Vollant]
|
||||
- Refine detection of Turbo C need for dummy returns
|
||||
- Refine ZLIB_DLL compilation
|
||||
- Include additional header file on VMS for off_t typedef
|
||||
- Try to use _vsnprintf where it supplants vsprintf [Vollant]
|
||||
- Add some casts in inffast.c
|
||||
- Enchance comments in zlib.h on what happens if gzprintf() tries to
|
||||
write more than 4095 bytes before compression
|
||||
- Remove unused state from inflateBackEnd()
|
||||
- Remove exit(0) from minigzip.c, example.c
|
||||
- Get rid of all those darn tabs
|
||||
- Add "check" target to Makefile.in that does the same thing as "test"
|
||||
- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
|
||||
- Update contrib/inflate86 [Anderson]
|
||||
- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
|
||||
- Add msdos and win32 directories with makefiles [Truta]
|
||||
- More additions and improvements to the FAQ
|
||||
|
||||
Changes in 1.2.0 (9 March 2003)
|
||||
- New and improved inflate code
|
||||
- About 20% faster
|
||||
- Does not allocate 32K window unless and until needed
|
||||
- Automatically detects and decompresses gzip streams
|
||||
- Raw inflate no longer needs an extra dummy byte at end
|
||||
- Added inflateBack functions using a callback interface--even faster
|
||||
than inflate, useful for file utilities (gzip, zip)
|
||||
- Added inflateCopy() function to record state for random access on
|
||||
externally generated deflate streams (e.g. in gzip files)
|
||||
- More readable code (I hope)
|
||||
- New and improved crc32()
|
||||
- About 50% faster, thanks to suggestions from Rodney Brown
|
||||
- Add deflateBound() and compressBound() functions
|
||||
- Fix memory leak in deflateInit2()
|
||||
- Permit setting dictionary for raw deflate (for parallel deflate)
|
||||
- Fix const declaration for gzwrite()
|
||||
- Check for some malloc() failures in gzio.c
|
||||
- Fix bug in gzopen() on single-byte file 0x1f
|
||||
- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
|
||||
and next buffer doesn't start with 0x8b
|
||||
- Fix uncompress() to return Z_DATA_ERROR on truncated input
|
||||
- Free memory at end of example.c
|
||||
- Remove MAX #define in trees.c (conflicted with some libraries)
|
||||
- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
|
||||
- Declare malloc() and free() in gzio.c if STDC not defined
|
||||
- Use malloc() instead of calloc() in zutil.c if int big enough
|
||||
- Define STDC for AIX
|
||||
- Add aix/ with approach for compiling shared library on AIX
|
||||
- Add HP-UX support for shared libraries in configure
|
||||
- Add OpenUNIX support for shared libraries in configure
|
||||
- Use $cc instead of gcc to build shared library
|
||||
- Make prefix directory if needed when installing
|
||||
- Correct Macintosh avoidance of typedef Byte in zconf.h
|
||||
- Correct Turbo C memory allocation when under Linux
|
||||
- Use libz.a instead of -lz in Makefile (assure use of compiled library)
|
||||
- Update configure to check for snprintf or vsnprintf functions and their
|
||||
return value, warn during make if using an insecure function
|
||||
- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
|
||||
is lost when library is used--resolution is to build new zconf.h
|
||||
- Documentation improvements (in zlib.h):
|
||||
- Document raw deflate and inflate
|
||||
- Update RFCs URL
|
||||
- Point out that zlib and gzip formats are different
|
||||
- Note that Z_BUF_ERROR is not fatal
|
||||
- Document string limit for gzprintf() and possible buffer overflow
|
||||
- Note requirement on avail_out when flushing
|
||||
- Note permitted values of flush parameter of inflate()
|
||||
- Add some FAQs (and even answers) to the FAQ
|
||||
- Add contrib/inflate86/ for x86 faster inflate
|
||||
- Add contrib/blast/ for PKWare Data Compression Library decompression
|
||||
- Add contrib/puff/ simple inflate for deflate format description
|
||||
|
||||
Changes in 1.1.4 (11 March 2002)
|
||||
- ZFREE was repeated on same allocation on some error conditions.
|
||||
@@ -10,7 +384,7 @@ Changes in 1.1.4 (11 March 2002)
|
||||
less than 32K.
|
||||
- force windowBits > 8 to avoid a bug in the encoder for a window size
|
||||
of 256 bytes. (A complete fix will be available in 1.1.5).
|
||||
|
||||
|
||||
Changes in 1.1.3 (9 July 1998)
|
||||
- fix "an inflate input buffer bug that shows up on rare but persistent
|
||||
occasions" (Mark)
|
||||
@@ -166,7 +540,7 @@ Changes in 1.0.7 (20 Jan 1998)
|
||||
Changes in 1.0.6 (19 Jan 1998)
|
||||
- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
|
||||
gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
|
||||
- Fix a deflate bug occuring only with compression level 0 (thanks to
|
||||
- Fix a deflate bug occurring only with compression level 0 (thanks to
|
||||
Andy Buckler for finding this one).
|
||||
- In minigzip, pass transparently also the first byte for .Z files.
|
||||
- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
|
||||
@@ -184,13 +558,13 @@ Changes in 1.0.6 (19 Jan 1998)
|
||||
- added Makefile.nt (thanks to Stephen Williams)
|
||||
- added the unsupported "contrib" directory:
|
||||
contrib/asm386/ by Gilles Vollant <info@winimage.com>
|
||||
386 asm code replacing longest_match().
|
||||
386 asm code replacing longest_match().
|
||||
contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
|
||||
A C++ I/O streams interface to the zlib gz* functions
|
||||
contrib/iostream2/ by Tyge L<>vset <Tyge.Lovset@cmr.no>
|
||||
Another C++ I/O streams interface
|
||||
Another C++ I/O streams interface
|
||||
contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
|
||||
A very simple tar.gz file extractor using zlib
|
||||
A very simple tar.gz file extractor using zlib
|
||||
contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
|
||||
How to use compress(), uncompress() and the gz* functions from VB.
|
||||
- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
|
||||
@@ -217,7 +591,7 @@ Changes in 1.0.6 (19 Jan 1998)
|
||||
- add NEED_DUMMY_RETURN for Borland
|
||||
- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
|
||||
- allow compilation with CC
|
||||
- defined STDC for OS/2 (David Charlap)
|
||||
- defined STDC for OS/2 (David Charlap)
|
||||
- limit external names to 8 chars for MVS (Thomas Lund)
|
||||
- in minigzip.c, use static buffers only for 16-bit systems
|
||||
- fix suffix check for "minigzip -d foo.gz"
|
||||
@@ -242,7 +616,7 @@ Changes in 1.0.5 (3 Jan 98)
|
||||
- Eliminate memory leaks on error conditions in inflate
|
||||
- Removed some vestigial code in inflate
|
||||
- Update web address in README
|
||||
|
||||
|
||||
Changes in 1.0.4 (24 Jul 96)
|
||||
- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
|
||||
bit, so the decompressor could decompress all the correct data but went
|
||||
|
||||
175
zlib/Makefile
175
zlib/Makefile
@@ -1,175 +0,0 @@
|
||||
# Makefile for zlib
|
||||
# Copyright (C) 1995-2002 Jean-loup Gailly.
|
||||
# For conditions of distribution and use, see copyright notice in zlib.h
|
||||
|
||||
# To compile and test, type:
|
||||
# ./configure; make test
|
||||
# The call of configure is optional if you don't have special requirements
|
||||
# If you wish to build zlib as a shared library, use: ./configure -s
|
||||
|
||||
# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
|
||||
# make install
|
||||
# To install in $HOME instead of /usr/local, use:
|
||||
# make install prefix=$HOME
|
||||
|
||||
CC=cc
|
||||
|
||||
CFLAGS=-O
|
||||
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
|
||||
#CFLAGS=-g -DDEBUG
|
||||
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
|
||||
# -Wstrict-prototypes -Wmissing-prototypes
|
||||
|
||||
LDFLAGS=-L. -lz
|
||||
LDSHARED=$(CC)
|
||||
CPP=$(CC) -E
|
||||
|
||||
VER=1.1.4
|
||||
LIBS=libz.a
|
||||
SHAREDLIB=libz.so
|
||||
|
||||
AR=ar rc
|
||||
RANLIB=ranlib
|
||||
TAR=tar
|
||||
SHELL=/bin/sh
|
||||
|
||||
prefix = /usr/local
|
||||
exec_prefix = ${prefix}
|
||||
libdir = ${exec_prefix}/lib
|
||||
includedir = ${prefix}/include
|
||||
|
||||
OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
|
||||
zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
|
||||
|
||||
OBJA =
|
||||
# to use the asm code: make OBJA=match.o
|
||||
|
||||
TEST_OBJS = example.o minigzip.o
|
||||
|
||||
DISTFILES = README FAQ INDEX ChangeLog configure Make*[a-z0-9] *.[ch] *.mms \
|
||||
algorithm.txt zlib.3 zlib.html \
|
||||
msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
|
||||
nt/Make*[a-z0-9] nt/zlib.dnt amiga/Make*.??? os2/M*.os2 os2/zlib.def \
|
||||
contrib/RE*.contrib contrib/*.txt contrib/asm386/*.asm contrib/asm386/*.c \
|
||||
contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/asm[56]86/*.?86 \
|
||||
contrib/asm[56]86/*.S contrib/iostream/*.cpp \
|
||||
contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \
|
||||
contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 \
|
||||
contrib/minizip/[CM]*[pe] contrib/minizip/*.[ch] contrib/minizip/*.[td]?? \
|
||||
contrib/delphi*/*.???
|
||||
|
||||
all: example minigzip
|
||||
|
||||
test: all
|
||||
@LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
|
||||
echo hello world | ./minigzip | ./minigzip -d || \
|
||||
echo ' *** minigzip test FAILED ***' ; \
|
||||
if ./example; then \
|
||||
echo ' *** zlib test OK ***'; \
|
||||
else \
|
||||
echo ' *** zlib test FAILED ***'; \
|
||||
fi
|
||||
|
||||
libz.a: $(OBJS) $(OBJA)
|
||||
$(AR) $@ $(OBJS) $(OBJA)
|
||||
-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
|
||||
|
||||
match.o: match.S
|
||||
$(CPP) match.S > _match.s
|
||||
$(CC) -c _match.s
|
||||
mv _match.o match.o
|
||||
rm -f _match.s
|
||||
|
||||
$(SHAREDLIB).$(VER): $(OBJS)
|
||||
$(LDSHARED) -o $@ $(OBJS)
|
||||
rm -f $(SHAREDLIB) $(SHAREDLIB).1
|
||||
ln -s $@ $(SHAREDLIB)
|
||||
ln -s $@ $(SHAREDLIB).1
|
||||
|
||||
example: example.o $(LIBS)
|
||||
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
|
||||
|
||||
minigzip: minigzip.o $(LIBS)
|
||||
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
|
||||
|
||||
install: $(LIBS)
|
||||
-@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi
|
||||
-@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi
|
||||
cp zlib.h zconf.h $(includedir)
|
||||
chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
|
||||
cp $(LIBS) $(libdir)
|
||||
cd $(libdir); chmod 755 $(LIBS)
|
||||
-@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
|
||||
cd $(libdir); if test -f $(SHAREDLIB).$(VER); then \
|
||||
rm -f $(SHAREDLIB) $(SHAREDLIB).1; \
|
||||
ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB); \
|
||||
ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB).1; \
|
||||
(ldconfig || true) >/dev/null 2>&1; \
|
||||
fi
|
||||
# The ranlib in install is needed on NeXTSTEP which checks file times
|
||||
# ldconfig is for Linux
|
||||
|
||||
uninstall:
|
||||
cd $(includedir); \
|
||||
v=$(VER); \
|
||||
if test -f zlib.h; then \
|
||||
v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`; \
|
||||
rm -f zlib.h zconf.h; \
|
||||
fi; \
|
||||
cd $(libdir); rm -f libz.a; \
|
||||
if test -f $(SHAREDLIB).$$v; then \
|
||||
rm -f $(SHAREDLIB).$$v $(SHAREDLIB) $(SHAREDLIB).1; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ example minigzip libz.a libz.so* foo.gz so_locations \
|
||||
_match.s maketree
|
||||
|
||||
distclean: clean
|
||||
|
||||
zip:
|
||||
mv Makefile Makefile~; cp -p Makefile.in Makefile
|
||||
rm -f test.c ztest*.c contrib/minizip/test.zip
|
||||
v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
|
||||
zip -ul9 zlib$$v $(DISTFILES)
|
||||
mv Makefile~ Makefile
|
||||
|
||||
dist:
|
||||
mv Makefile Makefile~; cp -p Makefile.in Makefile
|
||||
rm -f test.c ztest*.c contrib/minizip/test.zip
|
||||
d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
|
||||
rm -f $$d.tar.gz; \
|
||||
if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
|
||||
files=""; \
|
||||
for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
|
||||
cd ..; \
|
||||
GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
|
||||
if test ! -d $$d; then rm -f $$d; fi
|
||||
mv Makefile~ Makefile
|
||||
|
||||
tags:
|
||||
etags *.[ch]
|
||||
|
||||
depend:
|
||||
makedepend -- $(CFLAGS) -- *.[ch]
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
adler32.o: zlib.h zconf.h
|
||||
compress.o: zlib.h zconf.h
|
||||
crc32.o: zlib.h zconf.h
|
||||
deflate.o: deflate.h zutil.h zlib.h zconf.h
|
||||
example.o: zlib.h zconf.h
|
||||
gzio.o: zutil.h zlib.h zconf.h
|
||||
infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
|
||||
infcodes.o: zutil.h zlib.h zconf.h
|
||||
infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
|
||||
inffast.o: zutil.h zlib.h zconf.h inftrees.h
|
||||
inffast.o: infblock.h infcodes.h infutil.h inffast.h
|
||||
inflate.o: zutil.h zlib.h zconf.h infblock.h
|
||||
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
|
||||
infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
|
||||
minigzip.o: zlib.h zconf.h
|
||||
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
|
||||
uncompr.o: zlib.h zconf.h
|
||||
zutil.o: zutil.h zlib.h zconf.h
|
||||
130
zlib/README
130
zlib/README
@@ -1,110 +1,86 @@
|
||||
zlib 1.1.4 is a general purpose data compression library. All the code
|
||||
is thread safe. The data format used by the zlib library
|
||||
is described by RFCs (Request for Comments) 1950 to 1952 in the files
|
||||
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
|
||||
format) and rfc1952.txt (gzip format). These documents are also available in
|
||||
other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
|
||||
ZLIB DATA COMPRESSION LIBRARY
|
||||
|
||||
zlib 1.2.3 is a general purpose data compression library. All the code is
|
||||
thread safe. The data format used by the zlib library is described by RFCs
|
||||
(Request for Comments) 1950 to 1952 in the files
|
||||
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
|
||||
and rfc1952.txt (gzip format). These documents are also available in other
|
||||
formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
|
||||
|
||||
All functions of the compression library are documented in the file zlib.h
|
||||
(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
|
||||
example of the library is given in the file example.c which also tests that
|
||||
the library is working correctly. Another example is given in the file
|
||||
minigzip.c. The compression library itself is composed of all source files
|
||||
except example.c and minigzip.c.
|
||||
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
|
||||
of the library is given in the file example.c which also tests that the library
|
||||
is working correctly. Another example is given in the file minigzip.c. The
|
||||
compression library itself is composed of all source files except example.c and
|
||||
minigzip.c.
|
||||
|
||||
To compile all files and run the test program, follow the instructions
|
||||
given at the top of Makefile. In short "make test; make install"
|
||||
should work for most machines. For Unix: "./configure; make test; make install"
|
||||
For MSDOS, use one of the special makefiles such as Makefile.msc.
|
||||
For VMS, use Make_vms.com or descrip.mms.
|
||||
To compile all files and run the test program, follow the instructions given at
|
||||
the top of Makefile. In short "make test; make install" should work for most
|
||||
machines. For Unix: "./configure; make test; make install". For MSDOS, use one
|
||||
of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
|
||||
|
||||
Questions about zlib should be sent to <zlib@gzip.org>, or to
|
||||
Gilles Vollant <info@winimage.com> for the Windows DLL version.
|
||||
The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
|
||||
Before reporting a problem, please check this site to verify that
|
||||
you have the latest version of zlib; otherwise get the latest version and
|
||||
check whether the problem still exists or not.
|
||||
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
|
||||
<info@winimage.com> for the Windows DLL version. The zlib home page is
|
||||
http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
|
||||
please check this site to verify that you have the latest version of zlib;
|
||||
otherwise get the latest version and check whether the problem still exists or
|
||||
not.
|
||||
|
||||
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
|
||||
before asking for help.
|
||||
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
|
||||
for help.
|
||||
|
||||
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
||||
issue of Dr. Dobb's Journal; a copy of the article is available in
|
||||
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
|
||||
|
||||
The changes made in version 1.1.4 are documented in the file ChangeLog.
|
||||
The only changes made since 1.1.3 are bug corrections:
|
||||
|
||||
- ZFREE was repeated on same allocation on some error conditions.
|
||||
This creates a security problem described in
|
||||
http://www.zlib.org/advisory-2002-03-11.txt
|
||||
- Returned incorrect error (Z_MEM_ERROR) on some invalid data
|
||||
- Avoid accesses before window for invalid distances with inflate window
|
||||
less than 32K.
|
||||
- force windowBits > 8 to avoid a bug in the encoder for a window size
|
||||
of 256 bytes. (A complete fix will be available in 1.1.5).
|
||||
|
||||
The beta version 1.1.5beta includes many more changes. A new official
|
||||
version 1.1.5 will be released as soon as extensive testing has been
|
||||
completed on it.
|
||||
|
||||
The changes made in version 1.2.3 are documented in the file ChangeLog.
|
||||
|
||||
Unsupported third party contributions are provided in directory "contrib".
|
||||
|
||||
A Java implementation of zlib is available in the Java Development Kit
|
||||
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
|
||||
http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
|
||||
See the zlib home page http://www.zlib.org for details.
|
||||
|
||||
A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
|
||||
is in the CPAN (Comprehensive Perl Archive Network) sites
|
||||
A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
|
||||
CPAN (Comprehensive Perl Archive Network) sites
|
||||
http://www.cpan.org/modules/by-module/Compress/
|
||||
|
||||
A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
|
||||
is available in Python 1.5 and later versions, see
|
||||
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
|
||||
available in Python 1.5 and later versions, see
|
||||
http://www.python.org/doc/lib/module-zlib.html
|
||||
|
||||
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
|
||||
is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
|
||||
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
|
||||
availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
|
||||
|
||||
An experimental package to read and write files in .zip format,
|
||||
written on top of zlib by Gilles Vollant <info@winimage.com>, is
|
||||
available at http://www.winimage.com/zLibDll/unzip.html
|
||||
and also in the contrib/minizip directory of zlib.
|
||||
An experimental package to read and write files in .zip format, written on top
|
||||
of zlib by Gilles Vollant <info@winimage.com>, is available in the
|
||||
contrib/minizip directory of zlib.
|
||||
|
||||
|
||||
Notes for some targets:
|
||||
|
||||
- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
|
||||
and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
|
||||
The zlib DLL support was initially done by Alessandro Iacopetti and is
|
||||
now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
|
||||
home page at http://www.winimage.com/zLibDll
|
||||
- For Windows DLL versions, please see win32/DLL_FAQ.txt
|
||||
|
||||
From Visual Basic, you can call the DLL functions which do not take
|
||||
a structure as argument: compress, uncompress and all gz* functions.
|
||||
See contrib/visual-basic.txt for more information, or get
|
||||
http://www.tcfb.com/dowseware/cmp-z-it.zip
|
||||
- For 64-bit Irix, deflate.c must be compiled without any optimization. With
|
||||
-O, one libpng test fails. The test works in 32 bit mode (with the -n32
|
||||
compiler flag). The compiler bug has been reported to SGI.
|
||||
|
||||
- For 64-bit Irix, deflate.c must be compiled without any optimization.
|
||||
With -O, one libpng test fails. The test works in 32 bit mode (with
|
||||
the -n32 compiler flag). The compiler bug has been reported to SGI.
|
||||
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
|
||||
when compiled with cc.
|
||||
|
||||
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
|
||||
it works when compiled with cc.
|
||||
- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
|
||||
necessary to get gzprintf working correctly. This is done by configure.
|
||||
|
||||
- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
|
||||
is necessary to get gzprintf working correctly. This is done by configure.
|
||||
|
||||
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
|
||||
with other compilers. Use "make test" to check your compiler.
|
||||
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
|
||||
other compilers. Use "make test" to check your compiler.
|
||||
|
||||
- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
|
||||
|
||||
- For Turbo C the small model is supported only with reduced performance to
|
||||
avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
|
||||
- For PalmOs, see http://palmzlib.sourceforge.net/
|
||||
|
||||
- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
|
||||
Per Harald Myrvang <perm@stud.cs.uit.no>
|
||||
- When building a shared, i.e. dynamic library on Mac OS X, the library must be
|
||||
installed before testing (do "make install" before "make test"), since the
|
||||
library location is specified in the library.
|
||||
|
||||
|
||||
Acknowledgments:
|
||||
@@ -116,7 +92,7 @@ Acknowledgments:
|
||||
|
||||
Copyright notice:
|
||||
|
||||
(C) 1995-2002 Jean-loup Gailly and Mark Adler
|
||||
(C) 1995-2004 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -144,4 +120,6 @@ entirely written by Jean-loup Gailly and Mark Adler; it does not
|
||||
include third-party code.
|
||||
|
||||
If you redistribute modified sources, we would appreciate that you include
|
||||
in the file ChangeLog history information documenting your changes.
|
||||
in the file ChangeLog history information documenting your changes. Please
|
||||
read the FAQ for more information on the distribution of modified source
|
||||
versions.
|
||||
|
||||
147
zlib/adler32.c
147
zlib/adler32.c
@@ -1,48 +1,149 @@
|
||||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||
* Copyright (C) 1995-2002 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
#define BASE 65521L /* largest prime smaller than 65536 */
|
||||
#define BASE 65521UL /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
|
||||
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
|
||||
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
|
||||
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware */
|
||||
#ifdef NO_DIVIDE
|
||||
# define MOD(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
||||
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
||||
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
||||
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
||||
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
||||
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
||||
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
||||
if (a >= (BASE << 9)) a -= (BASE << 9); \
|
||||
if (a >= (BASE << 8)) a -= (BASE << 8); \
|
||||
if (a >= (BASE << 7)) a -= (BASE << 7); \
|
||||
if (a >= (BASE << 6)) a -= (BASE << 6); \
|
||||
if (a >= (BASE << 5)) a -= (BASE << 5); \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
# define MOD4(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#else
|
||||
# define MOD(a) a %= BASE
|
||||
# define MOD4(a) a %= BASE
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32(adler, buf, len)
|
||||
uLong adler;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
unsigned long s1 = adler & 0xffff;
|
||||
unsigned long s2 = (adler >> 16) & 0xffff;
|
||||
int k;
|
||||
unsigned long sum2;
|
||||
unsigned n;
|
||||
|
||||
if (buf == Z_NULL) return 1L;
|
||||
/* split Adler-32 into component sums */
|
||||
sum2 = (adler >> 16) & 0xffff;
|
||||
adler &= 0xffff;
|
||||
|
||||
while (len > 0) {
|
||||
k = len < NMAX ? len : NMAX;
|
||||
len -= k;
|
||||
while (k >= 16) {
|
||||
DO16(buf);
|
||||
buf += 16;
|
||||
k -= 16;
|
||||
}
|
||||
if (k != 0) do {
|
||||
s1 += *buf++;
|
||||
s2 += s1;
|
||||
} while (--k);
|
||||
s1 %= BASE;
|
||||
s2 %= BASE;
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
if (len == 1) {
|
||||
adler += buf[0];
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
sum2 += adler;
|
||||
if (sum2 >= BASE)
|
||||
sum2 -= BASE;
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
return (s2 << 16) | s1;
|
||||
|
||||
/* initial Adler-32 value (deferred check for len == 1 speed) */
|
||||
if (buf == Z_NULL)
|
||||
return 1L;
|
||||
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
if (len < 16) {
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
MOD4(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while (len >= NMAX) {
|
||||
len -= NMAX;
|
||||
n = NMAX / 16; /* NMAX is divisible by 16 */
|
||||
do {
|
||||
DO16(buf); /* 16 sums unrolled */
|
||||
buf += 16;
|
||||
} while (--n);
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if (len) { /* avoid modulos if none remaining */
|
||||
while (len >= 16) {
|
||||
len -= 16;
|
||||
DO16(buf);
|
||||
buf += 16;
|
||||
}
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* return recombined sums */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off_t len2;
|
||||
{
|
||||
unsigned long sum1;
|
||||
unsigned long sum2;
|
||||
unsigned rem;
|
||||
|
||||
/* the derivation of this formula is left as an exercise for the reader */
|
||||
rem = (unsigned)(len2 % BASE);
|
||||
sum1 = adler1 & 0xffff;
|
||||
sum2 = rem * sum1;
|
||||
MOD(sum2);
|
||||
sum1 += (adler2 & 0xffff) + BASE - 1;
|
||||
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
|
||||
if (sum1 > BASE) sum1 -= BASE;
|
||||
if (sum1 > BASE) sum1 -= BASE;
|
||||
if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
|
||||
if (sum2 > BASE) sum2 -= BASE;
|
||||
return sum1 | (sum2 << 16);
|
||||
}
|
||||
|
||||
79
zlib/compress.c
Normal file
79
zlib/compress.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/* compress.c -- compress a memory buffer
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
/* ===========================================================================
|
||||
Compresses the source buffer into the destination buffer. The level
|
||||
parameter has the same meaning as in deflateInit. sourceLen is the byte
|
||||
length of the source buffer. Upon entry, destLen is the total size of the
|
||||
destination buffer, which must be at least 0.1% larger than sourceLen plus
|
||||
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
|
||||
|
||||
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
|
||||
Z_STREAM_ERROR if the level parameter is invalid.
|
||||
*/
|
||||
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
int level;
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
#ifdef MAXSEG_64K
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
#endif
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = (uInt)*destLen;
|
||||
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
|
||||
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
stream.opaque = (voidpf)0;
|
||||
|
||||
err = deflateInit(&stream, level);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
err = deflate(&stream, Z_FINISH);
|
||||
if (err != Z_STREAM_END) {
|
||||
deflateEnd(&stream);
|
||||
return err == Z_OK ? Z_BUF_ERROR : err;
|
||||
}
|
||||
*destLen = stream.total_out;
|
||||
|
||||
err = deflateEnd(&stream);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
*/
|
||||
int ZEXPORT compress (dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
{
|
||||
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
If the default memLevel or windowBits for deflateInit() is changed, then
|
||||
this function needs to be updated.
|
||||
*/
|
||||
uLong ZEXPORT compressBound (sourceLen)
|
||||
uLong sourceLen;
|
||||
{
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
|
||||
}
|
||||
489
zlib/crc32.c
489
zlib/crc32.c
@@ -1,22 +1,84 @@
|
||||
/* crc32.c -- compute the CRC-32 of a data stream
|
||||
* Copyright (C) 1995-2002 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*
|
||||
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
|
||||
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
|
||||
* tables for updating the shift register in one step with three exclusive-ors
|
||||
* instead of four steps with four exclusive-ors. This results in about a
|
||||
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#include "zlib.h"
|
||||
/*
|
||||
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
|
||||
protection on the static variables used to control the first-use generation
|
||||
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
|
||||
first call get_crc_table() to initialize the tables before allowing more than
|
||||
one thread to use crc32().
|
||||
*/
|
||||
|
||||
#ifdef MAKECRCH
|
||||
# include <stdio.h>
|
||||
# ifndef DYNAMIC_CRC_TABLE
|
||||
# define DYNAMIC_CRC_TABLE
|
||||
# endif /* !DYNAMIC_CRC_TABLE */
|
||||
#endif /* MAKECRCH */
|
||||
|
||||
#include "zutil.h" /* for STDC and FAR definitions */
|
||||
|
||||
#define local static
|
||||
|
||||
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
|
||||
#ifndef NOBYFOUR
|
||||
# ifdef STDC /* need ANSI C limits.h to determine sizes */
|
||||
# include <limits.h>
|
||||
# define BYFOUR
|
||||
# if (UINT_MAX == 0xffffffffUL)
|
||||
typedef unsigned int u4;
|
||||
# else
|
||||
# if (ULONG_MAX == 0xffffffffUL)
|
||||
typedef unsigned long u4;
|
||||
# else
|
||||
# if (USHRT_MAX == 0xffffffffUL)
|
||||
typedef unsigned short u4;
|
||||
# else
|
||||
# undef BYFOUR /* can't find a four-byte integer type! */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif /* STDC */
|
||||
#endif /* !NOBYFOUR */
|
||||
|
||||
/* Definitions for doing the crc four data bytes at a time. */
|
||||
#ifdef BYFOUR
|
||||
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
|
||||
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
|
||||
local unsigned long crc32_little OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
local unsigned long crc32_big OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
# define TBLS 8
|
||||
#else
|
||||
# define TBLS 1
|
||||
#endif /* BYFOUR */
|
||||
|
||||
/* Local functions for crc concatenation */
|
||||
local unsigned long gf2_matrix_times OF((unsigned long *mat,
|
||||
unsigned long vec));
|
||||
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
|
||||
local int crc_table_empty = 1;
|
||||
local uLongf crc_table[256];
|
||||
local volatile int crc_table_empty = 1;
|
||||
local unsigned long FAR crc_table[TBLS][256];
|
||||
local void make_crc_table OF((void));
|
||||
|
||||
#ifdef MAKECRCH
|
||||
local void write_table OF((FILE *, const unsigned long FAR *));
|
||||
#endif /* MAKECRCH */
|
||||
/*
|
||||
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
|
||||
|
||||
Polynomials over GF(2) are represented in binary, one bit per coefficient,
|
||||
@@ -35,128 +97,327 @@ local void make_crc_table OF((void));
|
||||
out is a one). We start with the highest power (least significant bit) of
|
||||
q and repeat for all eight bits of q.
|
||||
|
||||
The table is simply the CRC of all possible eight bit values. This is all
|
||||
the information needed to generate CRC's on data a byte at a time for all
|
||||
combinations of CRC register values and incoming bytes.
|
||||
The first table is simply the CRC of all possible eight bit values. This is
|
||||
all the information needed to generate CRCs on data a byte at a time for all
|
||||
combinations of CRC register values and incoming bytes. The remaining tables
|
||||
allow for word-at-a-time CRC calculation for both big-endian and little-
|
||||
endian machines, where a word is four bytes.
|
||||
*/
|
||||
local void make_crc_table()
|
||||
{
|
||||
uLong c;
|
||||
int n, k;
|
||||
uLong poly; /* polynomial exclusive-or pattern */
|
||||
/* terms of polynomial defining this crc (except x^32): */
|
||||
static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
unsigned long c;
|
||||
int n, k;
|
||||
unsigned long poly; /* polynomial exclusive-or pattern */
|
||||
/* terms of polynomial defining this crc (except x^32): */
|
||||
static volatile int first = 1; /* flag to limit concurrent making */
|
||||
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320L) */
|
||||
poly = 0L;
|
||||
for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
|
||||
poly |= 1L << (31 - p[n]);
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
{
|
||||
c = (uLong)n;
|
||||
for (k = 0; k < 8; k++)
|
||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||
crc_table[n] = c;
|
||||
}
|
||||
crc_table_empty = 0;
|
||||
/* See if another task is already doing this (not thread-safe, but better
|
||||
than nothing -- significantly reduces duration of vulnerability in
|
||||
case the advice about DYNAMIC_CRC_TABLE is ignored) */
|
||||
if (first) {
|
||||
first = 0;
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
||||
poly = 0UL;
|
||||
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
|
||||
poly |= 1UL << (31 - p[n]);
|
||||
|
||||
/* generate a crc for every 8-bit value */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = (unsigned long)n;
|
||||
for (k = 0; k < 8; k++)
|
||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||
crc_table[0][n] = c;
|
||||
}
|
||||
|
||||
#ifdef BYFOUR
|
||||
/* generate crc for each value followed by one, two, and three zeros,
|
||||
and then the byte reversal of those as well as the first table */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = crc_table[0][n];
|
||||
crc_table[4][n] = REV(c);
|
||||
for (k = 1; k < 4; k++) {
|
||||
c = crc_table[0][c & 0xff] ^ (c >> 8);
|
||||
crc_table[k][n] = c;
|
||||
crc_table[k + 4][n] = REV(c);
|
||||
}
|
||||
}
|
||||
#endif /* BYFOUR */
|
||||
|
||||
crc_table_empty = 0;
|
||||
}
|
||||
else { /* not first */
|
||||
/* wait for the other guy to finish (not efficient, but rare) */
|
||||
while (crc_table_empty)
|
||||
;
|
||||
}
|
||||
|
||||
#ifdef MAKECRCH
|
||||
/* write out CRC tables to crc32.h */
|
||||
{
|
||||
FILE *out;
|
||||
|
||||
out = fopen("crc32.h", "w");
|
||||
if (out == NULL) return;
|
||||
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
|
||||
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
|
||||
fprintf(out, "local const unsigned long FAR ");
|
||||
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
|
||||
write_table(out, crc_table[0]);
|
||||
# ifdef BYFOUR
|
||||
fprintf(out, "#ifdef BYFOUR\n");
|
||||
for (k = 1; k < 8; k++) {
|
||||
fprintf(out, " },\n {\n");
|
||||
write_table(out, crc_table[k]);
|
||||
}
|
||||
fprintf(out, "#endif\n");
|
||||
# endif /* BYFOUR */
|
||||
fprintf(out, " }\n};\n");
|
||||
fclose(out);
|
||||
}
|
||||
#endif /* MAKECRCH */
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef MAKECRCH
|
||||
local void write_table(out, table)
|
||||
FILE *out;
|
||||
const unsigned long FAR *table;
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
|
||||
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
||||
}
|
||||
#endif /* MAKECRCH */
|
||||
|
||||
#else /* !DYNAMIC_CRC_TABLE */
|
||||
/* ========================================================================
|
||||
* Table of CRC-32's of all single-byte values (made by make_crc_table)
|
||||
* Tables of CRC-32s of all single-byte values, made by make_crc_table().
|
||||
*/
|
||||
local const uLongf crc_table[256] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
#endif
|
||||
#include "crc32.h"
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
|
||||
/* =========================================================================
|
||||
* This function can be used by asm versions of crc32()
|
||||
*/
|
||||
const uLongf * ZEXPORT get_crc_table()
|
||||
const unsigned long FAR * ZEXPORT get_crc_table()
|
||||
{
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty) make_crc_table();
|
||||
#endif
|
||||
return (const uLongf *)crc_table;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
|
||||
#define DO2(buf) DO1(buf); DO1(buf);
|
||||
#define DO4(buf) DO2(buf); DO2(buf);
|
||||
#define DO8(buf) DO4(buf); DO4(buf);
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT crc32(crc, buf, len)
|
||||
uLong crc;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
if (buf == Z_NULL) return 0L;
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty)
|
||||
make_crc_table();
|
||||
#endif
|
||||
crc = crc ^ 0xffffffffL;
|
||||
while (len >= 8)
|
||||
{
|
||||
DO8(buf);
|
||||
len -= 8;
|
||||
make_crc_table();
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
return (const unsigned long FAR *)crc_table;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
|
||||
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
|
||||
|
||||
/* ========================================================================= */
|
||||
unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
if (buf == Z_NULL) return 0UL;
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty)
|
||||
make_crc_table();
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
|
||||
#ifdef BYFOUR
|
||||
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
||||
u4 endian;
|
||||
|
||||
endian = 1;
|
||||
if (*((unsigned char *)(&endian)))
|
||||
return crc32_little(crc, buf, len);
|
||||
else
|
||||
return crc32_big(crc, buf, len);
|
||||
}
|
||||
#endif /* BYFOUR */
|
||||
crc = crc ^ 0xffffffffUL;
|
||||
while (len >= 8) {
|
||||
DO8;
|
||||
len -= 8;
|
||||
}
|
||||
if (len) do {
|
||||
DO1(buf);
|
||||
DO1;
|
||||
} while (--len);
|
||||
return crc ^ 0xffffffffL;
|
||||
return crc ^ 0xffffffffUL;
|
||||
}
|
||||
|
||||
#ifdef BYFOUR
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DOLIT4 c ^= *buf4++; \
|
||||
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
|
||||
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
|
||||
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
|
||||
|
||||
/* ========================================================================= */
|
||||
local unsigned long crc32_little(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
|
||||
c = (u4)crc;
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
while (len >= 32) {
|
||||
DOLIT32;
|
||||
len -= 32;
|
||||
}
|
||||
while (len >= 4) {
|
||||
DOLIT4;
|
||||
len -= 4;
|
||||
}
|
||||
buf = (const unsigned char FAR *)buf4;
|
||||
|
||||
if (len) do {
|
||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||
} while (--len);
|
||||
c = ~c;
|
||||
return (unsigned long)c;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DOBIG4 c ^= *++buf4; \
|
||||
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
|
||||
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
|
||||
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
|
||||
|
||||
/* ========================================================================= */
|
||||
local unsigned long crc32_big(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
|
||||
c = REV((u4)crc);
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
buf4--;
|
||||
while (len >= 32) {
|
||||
DOBIG32;
|
||||
len -= 32;
|
||||
}
|
||||
while (len >= 4) {
|
||||
DOBIG4;
|
||||
len -= 4;
|
||||
}
|
||||
buf4++;
|
||||
buf = (const unsigned char FAR *)buf4;
|
||||
|
||||
if (len) do {
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
} while (--len);
|
||||
c = ~c;
|
||||
return (unsigned long)(REV(c));
|
||||
}
|
||||
|
||||
#endif /* BYFOUR */
|
||||
|
||||
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
|
||||
|
||||
/* ========================================================================= */
|
||||
local unsigned long gf2_matrix_times(mat, vec)
|
||||
unsigned long *mat;
|
||||
unsigned long vec;
|
||||
{
|
||||
unsigned long sum;
|
||||
|
||||
sum = 0;
|
||||
while (vec) {
|
||||
if (vec & 1)
|
||||
sum ^= *mat;
|
||||
vec >>= 1;
|
||||
mat++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
local void gf2_matrix_square(square, mat)
|
||||
unsigned long *square;
|
||||
unsigned long *mat;
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < GF2_DIM; n++)
|
||||
square[n] = gf2_matrix_times(mat, mat[n]);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
|
||||
uLong crc1;
|
||||
uLong crc2;
|
||||
z_off_t len2;
|
||||
{
|
||||
int n;
|
||||
unsigned long row;
|
||||
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
|
||||
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
|
||||
|
||||
/* degenerate case */
|
||||
if (len2 == 0)
|
||||
return crc1;
|
||||
|
||||
/* put operator for one zero bit in odd */
|
||||
odd[0] = 0xedb88320L; /* CRC-32 polynomial */
|
||||
row = 1;
|
||||
for (n = 1; n < GF2_DIM; n++) {
|
||||
odd[n] = row;
|
||||
row <<= 1;
|
||||
}
|
||||
|
||||
/* put operator for two zero bits in even */
|
||||
gf2_matrix_square(even, odd);
|
||||
|
||||
/* put operator for four zero bits in odd */
|
||||
gf2_matrix_square(odd, even);
|
||||
|
||||
/* apply len2 zeros to crc1 (first square will put the operator for one
|
||||
zero byte, eight zero bits, in even) */
|
||||
do {
|
||||
/* apply zeros operator for this bit of len2 */
|
||||
gf2_matrix_square(even, odd);
|
||||
if (len2 & 1)
|
||||
crc1 = gf2_matrix_times(even, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
if (len2 == 0)
|
||||
break;
|
||||
|
||||
/* another iteration of the loop with odd and even swapped */
|
||||
gf2_matrix_square(odd, even);
|
||||
if (len2 & 1)
|
||||
crc1 = gf2_matrix_times(odd, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
} while (len2 != 0);
|
||||
|
||||
/* return combined crc */
|
||||
crc1 ^= crc2;
|
||||
return crc1;
|
||||
}
|
||||
|
||||
441
zlib/crc32.h
Normal file
441
zlib/crc32.h
Normal file
@@ -0,0 +1,441 @@
|
||||
/* crc32.h -- tables for rapid CRC calculation
|
||||
* Generated automatically by crc32.c
|
||||
*/
|
||||
|
||||
local const unsigned long FAR crc_table[TBLS][256] =
|
||||
{
|
||||
{
|
||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
|
||||
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
|
||||
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
|
||||
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
|
||||
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
|
||||
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
|
||||
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
|
||||
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
|
||||
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
|
||||
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
|
||||
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
|
||||
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
|
||||
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
|
||||
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
|
||||
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
|
||||
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
|
||||
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
|
||||
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
|
||||
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
|
||||
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
|
||||
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
|
||||
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
|
||||
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
|
||||
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
|
||||
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
|
||||
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
|
||||
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
|
||||
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
|
||||
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
|
||||
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
|
||||
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
|
||||
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
|
||||
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
|
||||
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
|
||||
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
|
||||
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
|
||||
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
|
||||
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
|
||||
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
|
||||
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
|
||||
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
|
||||
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
|
||||
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
|
||||
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
|
||||
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
|
||||
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
|
||||
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
|
||||
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
|
||||
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
|
||||
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
|
||||
0x2d02ef8dUL
|
||||
#ifdef BYFOUR
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
|
||||
0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
|
||||
0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
|
||||
0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
|
||||
0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
|
||||
0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
|
||||
0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
|
||||
0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
|
||||
0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
|
||||
0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
|
||||
0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
|
||||
0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
|
||||
0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
|
||||
0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
|
||||
0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
|
||||
0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
|
||||
0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
|
||||
0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
|
||||
0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
|
||||
0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
|
||||
0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
|
||||
0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
|
||||
0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
|
||||
0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
|
||||
0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
|
||||
0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
|
||||
0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
|
||||
0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
|
||||
0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
|
||||
0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
|
||||
0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
|
||||
0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
|
||||
0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
|
||||
0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
|
||||
0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
|
||||
0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
|
||||
0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
|
||||
0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
|
||||
0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
|
||||
0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
|
||||
0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
|
||||
0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
|
||||
0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
|
||||
0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
|
||||
0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
|
||||
0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
|
||||
0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
|
||||
0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
|
||||
0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
|
||||
0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
|
||||
0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
|
||||
0x9324fd72UL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
|
||||
0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
|
||||
0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
|
||||
0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
|
||||
0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
|
||||
0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
|
||||
0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
|
||||
0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
|
||||
0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
|
||||
0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
|
||||
0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
|
||||
0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
|
||||
0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
|
||||
0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
|
||||
0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
|
||||
0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
|
||||
0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
|
||||
0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
|
||||
0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
|
||||
0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
|
||||
0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
|
||||
0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
|
||||
0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
|
||||
0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
|
||||
0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
|
||||
0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
|
||||
0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
|
||||
0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
|
||||
0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
|
||||
0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
|
||||
0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
|
||||
0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
|
||||
0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
|
||||
0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
|
||||
0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
|
||||
0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
|
||||
0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
|
||||
0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
|
||||
0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
|
||||
0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
|
||||
0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
|
||||
0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
|
||||
0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
|
||||
0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
|
||||
0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
|
||||
0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
|
||||
0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
|
||||
0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
|
||||
0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
|
||||
0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
|
||||
0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
|
||||
0xbe9834edUL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
|
||||
0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
|
||||
0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
|
||||
0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
|
||||
0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
|
||||
0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
|
||||
0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
|
||||
0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
|
||||
0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
|
||||
0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
|
||||
0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
|
||||
0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
|
||||
0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
|
||||
0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
|
||||
0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
|
||||
0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
|
||||
0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
|
||||
0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
|
||||
0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
|
||||
0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
|
||||
0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
|
||||
0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
|
||||
0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
|
||||
0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
|
||||
0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
|
||||
0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
|
||||
0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
|
||||
0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
|
||||
0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
|
||||
0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
|
||||
0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
|
||||
0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
|
||||
0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
|
||||
0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
|
||||
0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
|
||||
0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
|
||||
0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
|
||||
0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
|
||||
0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
|
||||
0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
|
||||
0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
|
||||
0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
|
||||
0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
|
||||
0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
|
||||
0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
|
||||
0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
|
||||
0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
|
||||
0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
|
||||
0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
|
||||
0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
|
||||
0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
|
||||
0xde0506f1UL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
|
||||
0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
|
||||
0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
|
||||
0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
|
||||
0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
|
||||
0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
|
||||
0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
|
||||
0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
|
||||
0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
|
||||
0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
|
||||
0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
|
||||
0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
|
||||
0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
|
||||
0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
|
||||
0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
|
||||
0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
|
||||
0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
|
||||
0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
|
||||
0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
|
||||
0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
|
||||
0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
|
||||
0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
|
||||
0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
|
||||
0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
|
||||
0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
|
||||
0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
|
||||
0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
|
||||
0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
|
||||
0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
|
||||
0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
|
||||
0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
|
||||
0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
|
||||
0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
|
||||
0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
|
||||
0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
|
||||
0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
|
||||
0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
|
||||
0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
|
||||
0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
|
||||
0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
|
||||
0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
|
||||
0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
|
||||
0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
|
||||
0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
|
||||
0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
|
||||
0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
|
||||
0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
|
||||
0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
|
||||
0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
|
||||
0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
|
||||
0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
|
||||
0x8def022dUL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
|
||||
0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
|
||||
0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
|
||||
0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
|
||||
0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
|
||||
0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
|
||||
0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
|
||||
0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
|
||||
0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
|
||||
0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
|
||||
0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
|
||||
0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
|
||||
0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
|
||||
0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
|
||||
0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
|
||||
0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
|
||||
0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
|
||||
0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
|
||||
0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
|
||||
0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
|
||||
0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
|
||||
0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
|
||||
0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
|
||||
0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
|
||||
0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
|
||||
0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
|
||||
0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
|
||||
0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
|
||||
0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
|
||||
0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
|
||||
0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
|
||||
0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
|
||||
0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
|
||||
0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
|
||||
0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
|
||||
0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
|
||||
0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
|
||||
0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
|
||||
0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
|
||||
0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
|
||||
0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
|
||||
0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
|
||||
0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
|
||||
0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
|
||||
0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
|
||||
0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
|
||||
0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
|
||||
0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
|
||||
0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
|
||||
0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
|
||||
0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
|
||||
0x72fd2493UL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
|
||||
0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
|
||||
0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
|
||||
0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
|
||||
0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
|
||||
0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
|
||||
0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
|
||||
0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
|
||||
0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
|
||||
0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
|
||||
0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
|
||||
0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
|
||||
0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
|
||||
0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
|
||||
0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
|
||||
0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
|
||||
0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
|
||||
0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
|
||||
0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
|
||||
0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
|
||||
0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
|
||||
0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
|
||||
0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
|
||||
0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
|
||||
0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
|
||||
0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
|
||||
0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
|
||||
0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
|
||||
0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
|
||||
0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
|
||||
0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
|
||||
0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
|
||||
0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
|
||||
0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
|
||||
0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
|
||||
0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
|
||||
0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
|
||||
0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
|
||||
0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
|
||||
0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
|
||||
0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
|
||||
0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
|
||||
0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
|
||||
0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
|
||||
0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
|
||||
0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
|
||||
0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
|
||||
0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
|
||||
0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
|
||||
0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
|
||||
0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
|
||||
0xed3498beUL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
|
||||
0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
|
||||
0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
|
||||
0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
|
||||
0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
|
||||
0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
|
||||
0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
|
||||
0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
|
||||
0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
|
||||
0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
|
||||
0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
|
||||
0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
|
||||
0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
|
||||
0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
|
||||
0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
|
||||
0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
|
||||
0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
|
||||
0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
|
||||
0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
|
||||
0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
|
||||
0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
|
||||
0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
|
||||
0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
|
||||
0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
|
||||
0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
|
||||
0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
|
||||
0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
|
||||
0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
|
||||
0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
|
||||
0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
|
||||
0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
|
||||
0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
|
||||
0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
|
||||
0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
|
||||
0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
|
||||
0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
|
||||
0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
|
||||
0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
|
||||
0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
|
||||
0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
|
||||
0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
|
||||
0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
|
||||
0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
|
||||
0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
|
||||
0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
|
||||
0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
|
||||
0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
|
||||
0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
|
||||
0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
|
||||
0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
|
||||
0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
|
||||
0xf10605deUL
|
||||
#endif
|
||||
}
|
||||
};
|
||||
750
zlib/deflate.c
750
zlib/deflate.c
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user