mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 23:05:52 -04:00
Compare commits
4766 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16b49716d5 | ||
|
|
58faa1e8b9 | ||
|
|
9250e9ac23 | ||
|
|
3623d94fe7 | ||
|
|
cbc42b9c16 | ||
|
|
6ff5824c25 | ||
|
|
32de6b7cb4 | ||
|
|
bb853b3205 | ||
|
|
cce44865c1 | ||
|
|
1983198097 | ||
|
|
2a7355fb56 | ||
|
|
3da1dc4d18 | ||
|
|
abfb41e63e | ||
|
|
9d1cd2437c | ||
|
|
f8d2ecd223 | ||
|
|
453914e35b | ||
|
|
3f26e38f86 | ||
|
|
81d1ca0683 | ||
|
|
289ccbd02f | ||
|
|
85d3877be9 | ||
|
|
e203245d76 | ||
|
|
dfbcc4f7ec | ||
|
|
0bcb8b639a | ||
|
|
77f750f167 | ||
|
|
23afe20780 | ||
|
|
e12a6c087c | ||
|
|
6feb7d37df | ||
|
|
81ff413bb0 | ||
|
|
eac858085e | ||
|
|
2ac35b4507 | ||
|
|
3bc319766d | ||
|
|
a689fb1f5f | ||
|
|
b560a96b2c | ||
|
|
51e3c3da85 | ||
|
|
461086bbe7 | ||
|
|
00694610a6 | ||
|
|
8e3a6db842 | ||
|
|
8354cad53e | ||
|
|
317a0e8ca5 | ||
|
|
066ad8c719 | ||
|
|
ec4f644d2f | ||
|
|
4bf342c60f | ||
|
|
a2f733c664 | ||
|
|
3ea74eb388 | ||
|
|
962f8b9004 | ||
|
|
ae189e18de | ||
|
|
5b34561cf7 | ||
|
|
5546dab329 | ||
|
|
6128f56694 | ||
|
|
743f5a30d5 | ||
|
|
a955e93316 | ||
|
|
aca7dd3bff | ||
|
|
bc55aa04df | ||
|
|
f438d5abe0 | ||
|
|
6fe798392b | ||
|
|
6ceb9ea012 | ||
|
|
6900d35cce | ||
|
|
7cb0de6326 | ||
|
|
61e74afc42 | ||
|
|
0466e46b9f | ||
|
|
aa4c6db043 | ||
|
|
edb0d9c792 | ||
|
|
6ffd8f2169 | ||
|
|
ba43e88527 | ||
|
|
ff08acd4f2 | ||
|
|
03bb593f81 | ||
|
|
4c8eb5f951 | ||
|
|
f491d17352 | ||
|
|
288e64a79f | ||
|
|
0872dff60c | ||
|
|
3ce7a65c11 | ||
|
|
de8ec0b309 | ||
|
|
677c6e14cc | ||
|
|
7665ba5b36 | ||
|
|
adc600cbe2 | ||
|
|
43d6d0c5ba | ||
|
|
22a3ac0b55 | ||
|
|
1524c2e5c7 | ||
|
|
0dedfbce2c | ||
|
|
4cad402ea8 | ||
|
|
306d112730 | ||
|
|
371242e4e8 | ||
|
|
e1bfdf67f3 | ||
|
|
3fe686b577 | ||
|
|
783611707b | ||
|
|
cd909fde87 | ||
|
|
4dfe7c9f3e | ||
|
|
7fb4c08c24 | ||
|
|
8946cfc6f8 | ||
|
|
dfa5b49110 | ||
|
|
1bf6203616 | ||
|
|
a3f852bd78 | ||
|
|
72e7fb5b92 | ||
|
|
740551d657 | ||
|
|
a106ed78d5 | ||
|
|
bba31ddf12 | ||
|
|
31825a94b3 | ||
|
|
5dcef7c6dd | ||
|
|
72e0c45078 | ||
|
|
0593471e99 | ||
|
|
1b29458ea4 | ||
|
|
d3414a7d23 | ||
|
|
9e2e7a1b2d | ||
|
|
d34eaa8183 | ||
|
|
b4ea93c676 | ||
|
|
6df5d81ce2 | ||
|
|
0e3152febd | ||
|
|
e9398b1dc5 | ||
|
|
83792c1cbf | ||
|
|
32540aa091 | ||
|
|
836e0c5df4 | ||
|
|
2cd87086f0 | ||
|
|
eaa4e2d1ee | ||
|
|
e461cefbab | ||
|
|
18217a94c4 | ||
|
|
090ef59b29 | ||
|
|
708db6f772 | ||
|
|
63f9197611 | ||
|
|
f643330eb1 | ||
|
|
bc0d094d2a | ||
|
|
64dff88db9 | ||
|
|
637ebad048 | ||
|
|
487bf9290c | ||
|
|
bc58313bf7 | ||
|
|
de78297b61 | ||
|
|
9c7d755dfe | ||
|
|
60cc5d4b78 | ||
|
|
1220c93a99 | ||
|
|
7d7538d43c | ||
|
|
de94193353 | ||
|
|
05fce6582a | ||
|
|
62327b1281 | ||
|
|
99c9520ea7 | ||
|
|
01959d6387 | ||
|
|
807f3a44ba | ||
|
|
2791e0b542 | ||
|
|
d6a7ed99c1 | ||
|
|
4066d61a9d | ||
|
|
70d4a945f7 | ||
|
|
0488a14b99 | ||
|
|
a213d1cd6e | ||
|
|
fc2d6fabe7 | ||
|
|
a508e88fcf | ||
|
|
f0da824237 | ||
|
|
b74250037c | ||
|
|
f93094fa9f | ||
|
|
baf382d62e | ||
|
|
12505e02b1 | ||
|
|
d6df07392e | ||
|
|
d9ca1e4990 | ||
|
|
0ab8e166f4 | ||
|
|
1e9ee19a71 | ||
|
|
9bf065860f | ||
|
|
5b46454364 | ||
|
|
d4070db631 | ||
|
|
cb784f18ec | ||
|
|
2dc2070992 | ||
|
|
4442f8037b | ||
|
|
333e3a9ff0 | ||
|
|
94073d20e4 | ||
|
|
750ec9bcdc | ||
|
|
7fdba7aaf8 | ||
|
|
eec26089b1 | ||
|
|
76340ea44c | ||
|
|
7e1a9c4d79 | ||
|
|
16a9883649 | ||
|
|
bd7d36cc6c | ||
|
|
d42e7181d5 | ||
|
|
c03bb3d181 | ||
|
|
cee326436c | ||
|
|
0ae92567ed | ||
|
|
42f759ad9a | ||
|
|
e1ded58983 | ||
|
|
0bacaccee6 | ||
|
|
d46f8314b6 | ||
|
|
7cefbf106f | ||
|
|
f143b55ef1 | ||
|
|
ee51a745c1 | ||
|
|
0d34fbdf5a | ||
|
|
d51a3adb4f | ||
|
|
b55115ec6f | ||
|
|
f5e2b8f803 | ||
|
|
41c5ba641f | ||
|
|
0dfd2a64ec | ||
|
|
6686b93a7a | ||
|
|
9510fa9ab8 | ||
|
|
d74512eb05 | ||
|
|
1a2704512a | ||
|
|
a3b62ff4cf | ||
|
|
60ef397057 | ||
|
|
89e049ad7f | ||
|
|
036094d30e | ||
|
|
48b51d0004 | ||
|
|
7da17144fd | ||
|
|
cbdff74b44 | ||
|
|
37a729768b | ||
|
|
8dd6ea1f1e | ||
|
|
7c8f180900 | ||
|
|
3527677043 | ||
|
|
fd91c3b666 | ||
|
|
15df927ae2 | ||
|
|
8adceeb2b3 | ||
|
|
0c7fdf705e | ||
|
|
439d5d8929 | ||
|
|
de219101ed | ||
|
|
79853c30c0 | ||
|
|
953feeadd2 | ||
|
|
3417881d5c | ||
|
|
397fb1acd2 | ||
|
|
db0443cf90 | ||
|
|
d5bff8ffe2 | ||
|
|
a7d7f52ae0 | ||
|
|
847ddaf071 | ||
|
|
c4c5dc68b9 | ||
|
|
c4170cbaac | ||
|
|
de407c03d2 | ||
|
|
c1005fb256 | ||
|
|
70c4bfb770 | ||
|
|
a470b675af | ||
|
|
5561c14978 | ||
|
|
865efe9456 | ||
|
|
18749579b5 | ||
|
|
a05758fde6 | ||
|
|
fb0d4403f0 | ||
|
|
3fd0357f9f | ||
|
|
64fa23add9 | ||
|
|
0a77adee0b | ||
|
|
0a04a80d9f | ||
|
|
7ae666d2a7 | ||
|
|
fbf4c261f4 | ||
|
|
425747c2f3 | ||
|
|
03cd1ae4fa | ||
|
|
01580c794a | ||
|
|
a59a7b2423 | ||
|
|
5bfe006882 | ||
|
|
852585b1fc | ||
|
|
e2c1e482e0 | ||
|
|
4591bb2f66 | ||
|
|
810dc9fc2a | ||
|
|
d80f7d6cc3 | ||
|
|
e3bc529de9 | ||
|
|
820f7a7b57 | ||
|
|
a131954b7b | ||
|
|
f187ce36cc | ||
|
|
2fff0a4f28 | ||
|
|
cb0db58fb3 | ||
|
|
582aead623 | ||
|
|
d518e02243 | ||
|
|
b9cc2d4c86 | ||
|
|
ac30d22ae5 | ||
|
|
8bcd6a4aff | ||
|
|
58663df432 | ||
|
|
da7acc5e42 | ||
|
|
54d13604fa | ||
|
|
3ed84dbc98 | ||
|
|
0308092914 | ||
|
|
a13d3b3d77 | ||
|
|
813d5a25e3 | ||
|
|
591c224584 | ||
|
|
b223d96bf0 | ||
|
|
28b519c93b | ||
|
|
8686d3abba | ||
|
|
73b9b90a0b | ||
|
|
98ec67d786 | ||
|
|
0de5157564 | ||
|
|
78286a03d1 | ||
|
|
d699d815d6 | ||
|
|
e5e6d3c410 | ||
|
|
016ce71568 | ||
|
|
2792a83d58 | ||
|
|
0b67d5e396 | ||
|
|
d52aeae4e9 | ||
|
|
f7c3a25052 | ||
|
|
6da6b02bb7 | ||
|
|
da9b72b36c | ||
|
|
75a1a04847 | ||
|
|
eee2c77a93 | ||
|
|
7766e67321 | ||
|
|
4403b1332f | ||
|
|
c82711b34e | ||
|
|
b2e446d0cb | ||
|
|
3bd9f51917 | ||
|
|
86e90c58f4 | ||
|
|
e1fe1d55c4 | ||
|
|
57edc4808f | ||
|
|
69be312b5e | ||
|
|
4b4bcbe674 | ||
|
|
3f26945cb1 | ||
|
|
580cffdec9 | ||
|
|
58a1c1a218 | ||
|
|
53e6507e14 | ||
|
|
3feece5938 | ||
|
|
4ab6125214 | ||
|
|
49eb0c4a35 | ||
|
|
050e5334d8 | ||
|
|
bf4170ade8 | ||
|
|
6500e0769a | ||
|
|
aa3faf5f8c | ||
|
|
8030518dd0 | ||
|
|
e630fd1186 | ||
|
|
d3f5c628d7 | ||
|
|
8b6ebde1f3 | ||
|
|
1c99b1d956 | ||
|
|
575933e9d0 | ||
|
|
14013906ca | ||
|
|
d1b3118c16 | ||
|
|
8f30d21584 | ||
|
|
3f770ab0a5 | ||
|
|
743348e848 | ||
|
|
14ebc5b618 | ||
|
|
aef2b8ce41 | ||
|
|
9f5c16e51d | ||
|
|
8484ddd3d1 | ||
|
|
51b2ff03b3 | ||
|
|
96e051c86a | ||
|
|
55f767c5ca | ||
|
|
5ebe9a46d7 | ||
|
|
d64bda1c1e | ||
|
|
c6679e04f8 | ||
|
|
9cb20c605f | ||
|
|
ba342e22e7 | ||
|
|
29358819ca | ||
|
|
2a189350f2 | ||
|
|
020df16def | ||
|
|
2624e005e2 | ||
|
|
c9bf436e5b | ||
|
|
8b48c68285 | ||
|
|
aff4850053 | ||
|
|
b32fd63459 | ||
|
|
3b22184d4c | ||
|
|
929002a2d5 | ||
|
|
a64840a29d | ||
|
|
0f6b683c8e | ||
|
|
18070203c2 | ||
|
|
b3e41255a6 | ||
|
|
9dbb94a7e6 | ||
|
|
1c9eafdda0 | ||
|
|
cf0f454b8a | ||
|
|
d8c55a6e04 | ||
|
|
b320b7d6e5 | ||
|
|
54504b8e4f | ||
|
|
de32838ea2 | ||
|
|
ce571e64b6 | ||
|
|
9541770faf | ||
|
|
3be1d9beb2 | ||
|
|
292a5c2b72 | ||
|
|
e60c8b59fe | ||
|
|
130cdd0d90 | ||
|
|
db22e586da | ||
|
|
60c25caa64 | ||
|
|
c3541d30b6 | ||
|
|
86be7a0e64 | ||
|
|
47573508f4 | ||
|
|
d1fe65fc5e | ||
|
|
9fbec6e44c | ||
|
|
25082d1ef6 | ||
|
|
5deb19e4ea | ||
|
|
0b8a9bd69d | ||
|
|
7a3ce973c3 | ||
|
|
be8234cd59 | ||
|
|
d0f2bbb83e | ||
|
|
ef7441669b | ||
|
|
9a54a640f7 | ||
|
|
58a79f4b44 | ||
|
|
ae03e0e008 | ||
|
|
554dc122f2 | ||
|
|
8c934eba05 | ||
|
|
41ae04e09c | ||
|
|
9a7532e516 | ||
|
|
9b594a530f | ||
|
|
5d8dcd1edb | ||
|
|
afccb3d326 | ||
|
|
0d78a27893 | ||
|
|
05c36015f7 | ||
|
|
e34f43495c | ||
|
|
4256264991 | ||
|
|
fa5a06ad0c | ||
|
|
794f2cbab3 | ||
|
|
12e59929e2 | ||
|
|
fc4bb1230e | ||
|
|
a01e3b490e | ||
|
|
2b2a473831 | ||
|
|
4c4a296209 | ||
|
|
e89a0fc094 | ||
|
|
164faae84f | ||
|
|
de6ab501b6 | ||
|
|
4286ea6036 | ||
|
|
626b5ae839 | ||
|
|
92d021488e | ||
|
|
82b2a31a46 | ||
|
|
eeea1bbd72 | ||
|
|
aa3999d66c | ||
|
|
6e9ad2bb03 | ||
|
|
c5130bc123 | ||
|
|
f8e1fa6272 | ||
|
|
8e7f3107a4 | ||
|
|
c2dd3ec32c | ||
|
|
e9ad7bb1f8 | ||
|
|
b9107ee61e | ||
|
|
45426a7604 | ||
|
|
dc2a0923a2 | ||
|
|
ac32cdd7d4 | ||
|
|
6d952fdbe7 | ||
|
|
870cf55287 | ||
|
|
7d0fe4da70 | ||
|
|
763880ba81 | ||
|
|
2885270b52 | ||
|
|
0c2e8f9364 | ||
|
|
24079e988f | ||
|
|
8a68cad1f7 | ||
|
|
d03c0b1ed3 | ||
|
|
907e6a32a0 | ||
|
|
e4c598c830 | ||
|
|
ae598f3847 | ||
|
|
d85d029b92 | ||
|
|
d620b907e4 | ||
|
|
5692657757 | ||
|
|
c493b6b81d | ||
|
|
4e2a7e59e5 | ||
|
|
b82d8c9d1a | ||
|
|
75ea845904 | ||
|
|
ce795fcd75 | ||
|
|
aa381148a3 | ||
|
|
cece2e3f5e | ||
|
|
f397616e00 | ||
|
|
4351c039ad | ||
|
|
304d7b5817 | ||
|
|
9270e88d76 | ||
|
|
2907af472d | ||
|
|
8346c62a95 | ||
|
|
4655dcf218 | ||
|
|
f9185203ee | ||
|
|
84c11e85a4 | ||
|
|
6be8a8b14d | ||
|
|
ef9d3a152b | ||
|
|
fe16d9a67d | ||
|
|
23a0d1e200 | ||
|
|
a0f1ed55cd | ||
|
|
4dde3347fb | ||
|
|
44a97a34b1 | ||
|
|
281a141ea7 | ||
|
|
8e6b4ddbe8 | ||
|
|
9ccc8f8bbb | ||
|
|
2170667802 | ||
|
|
705132bcee | ||
|
|
0dd2310cac | ||
|
|
cbc63a09e8 | ||
|
|
a0a88e0ef3 | ||
|
|
d8a7290f86 | ||
|
|
3b8f819222 | ||
|
|
8b3e6fb985 | ||
|
|
d720569422 | ||
|
|
0a56ef128c | ||
|
|
0a9fbe17de | ||
|
|
d23cc156aa | ||
|
|
6f098b0f8c | ||
|
|
1ec57e4ddc | ||
|
|
20caffd2b3 | ||
|
|
df6350a8b8 | ||
|
|
7a7810aa2f | ||
|
|
41000dffc1 | ||
|
|
d8587b4690 | ||
|
|
e8bb37f567 | ||
|
|
ee1c00fea8 | ||
|
|
1b502f3ec2 | ||
|
|
44d7d045c7 | ||
|
|
1a2e41af94 | ||
|
|
accc091fe9 | ||
|
|
4b660bae92 | ||
|
|
2f1fb732d4 | ||
|
|
59924aa8cf | ||
|
|
b15fa9bd7b | ||
|
|
2c1aa2efac | ||
|
|
6e310d38fc | ||
|
|
3b83a22057 | ||
|
|
8e15bd87dd | ||
|
|
4a440e4be8 | ||
|
|
486ecd3d9c | ||
|
|
17cc4c383b | ||
|
|
c55fb5e1d6 | ||
|
|
8a21be11f0 | ||
|
|
ce827c3e50 | ||
|
|
2523d0cc14 | ||
|
|
18bd04018d | ||
|
|
4c3e9c09eb | ||
|
|
05a652d0b7 | ||
|
|
845ed84d70 | ||
|
|
049f8cbc8a | ||
|
|
0d5ebab1d6 | ||
|
|
dab0fb7cf0 | ||
|
|
62342430bf | ||
|
|
63070274f2 | ||
|
|
06886d36cf | ||
|
|
9ba4d44fa8 | ||
|
|
350242c5c1 | ||
|
|
181c9faf92 | ||
|
|
c8fa85b23b | ||
|
|
a61ec6b168 | ||
|
|
7b6c5c7794 | ||
|
|
b32d425451 | ||
|
|
134f97c9cc | ||
|
|
87755c6cea | ||
|
|
8f73c8a498 | ||
|
|
0cdb547f5c | ||
|
|
56017d3150 | ||
|
|
d960af72b2 | ||
|
|
fd2b6046cb | ||
|
|
a8e6e14869 | ||
|
|
307555eba3 | ||
|
|
261808dac1 | ||
|
|
5250c3bc20 | ||
|
|
9eaba7266c | ||
|
|
d510e82fc6 | ||
|
|
4e9c7fae8f | ||
|
|
3696674bc6 | ||
|
|
5e2d51ee06 | ||
|
|
d735fe2014 | ||
|
|
7e6c8ad653 | ||
|
|
407ea78a62 | ||
|
|
cb197514d9 | ||
|
|
a055dbdd88 | ||
|
|
5eb8bd4962 | ||
|
|
e129500c85 | ||
|
|
7fc2ca2551 | ||
|
|
83c32ca572 | ||
|
|
1a85a969a7 | ||
|
|
7f2591eaea | ||
|
|
eecc969e9b | ||
|
|
f8605c5b89 | ||
|
|
42d8ec616d | ||
|
|
7781241889 | ||
|
|
b5473dd4a9 | ||
|
|
4e0fa131fe | ||
|
|
17a1676976 | ||
|
|
b4d30300b9 | ||
|
|
e6f3a33c5e | ||
|
|
ce66f41791 | ||
|
|
8d10cbfcb1 | ||
|
|
e8d6fe6261 | ||
|
|
7f367bb1b4 | ||
|
|
df7ec1cf42 | ||
|
|
6437b817c0 | ||
|
|
d39d60a129 | ||
|
|
49c2407141 | ||
|
|
44ae54114a | ||
|
|
43eb865f9a | ||
|
|
789213909d | ||
|
|
46cd1ef6bc | ||
|
|
6e80613717 | ||
|
|
dc6fb11b41 | ||
|
|
4d13a2fe55 | ||
|
|
58cf354711 | ||
|
|
7a498f5b6c | ||
|
|
243e9a366d | ||
|
|
b53c202e45 | ||
|
|
aef68d7892 | ||
|
|
077e543b7d | ||
|
|
9784f01cbc | ||
|
|
bc40a30503 | ||
|
|
4079d6a684 | ||
|
|
df694f72ed | ||
|
|
11ef77b76a | ||
|
|
abd32c9585 | ||
|
|
01e293f1b5 | ||
|
|
8051aa5a34 | ||
|
|
46d68be3da | ||
|
|
bb499bd7a0 | ||
|
|
416cef36e9 | ||
|
|
1fb6a4018d | ||
|
|
fc4a695cdd | ||
|
|
83238ed0bb | ||
|
|
21cddef2b4 | ||
|
|
b3bf9b9df9 | ||
|
|
974e18191c | ||
|
|
09ca0d15d3 | ||
|
|
c43c66125e | ||
|
|
8b7a752024 | ||
|
|
2df20057e3 | ||
|
|
9556f156a9 | ||
|
|
aade88bfc2 | ||
|
|
3795dafd97 | ||
|
|
e4ed195bb7 | ||
|
|
faf980ffb5 | ||
|
|
b3ad9649bc | ||
|
|
d4d56eed8a | ||
|
|
3ce3cabe34 | ||
|
|
9411292489 | ||
|
|
b4de848d75 | ||
|
|
89cb47212e | ||
|
|
1049378d9c | ||
|
|
9ddc2b64da | ||
|
|
b3347e2a03 | ||
|
|
d8e8ef323a | ||
|
|
ea0f037930 | ||
|
|
08b7c3ed83 | ||
|
|
76181461f5 | ||
|
|
2c11e80e2e | ||
|
|
e366e5303f | ||
|
|
0a23e33630 | ||
|
|
8ab02ccd52 | ||
|
|
e0c572c5c6 | ||
|
|
315c2152d0 | ||
|
|
6d301fa3de | ||
|
|
af2dea6033 | ||
|
|
7fdb3bdab9 | ||
|
|
794d033981 | ||
|
|
45574a73c1 | ||
|
|
26e21efc5a | ||
|
|
433c6753a8 | ||
|
|
46b1361b41 | ||
|
|
9e7acc86c3 | ||
|
|
56c7ed9983 | ||
|
|
5dd14f0c33 | ||
|
|
2a147e9fcb | ||
|
|
7634fc8eb6 | ||
|
|
daa8d92094 | ||
|
|
adc2476fa2 | ||
|
|
34c3ca8f35 | ||
|
|
4f282b0b92 | ||
|
|
8b3e60523a | ||
|
|
1d891835e7 | ||
|
|
0b78944600 | ||
|
|
79daa59618 | ||
|
|
72de4140d5 | ||
|
|
94a4a125bc | ||
|
|
e982d59146 | ||
|
|
c78e4ea905 | ||
|
|
0b7bce2c7b | ||
|
|
87678cefd1 | ||
|
|
7c7462cd30 | ||
|
|
e34ad4e925 | ||
|
|
f303b749f2 | ||
|
|
91fd15b8b6 | ||
|
|
6e5b682273 | ||
|
|
902ee53ea4 | ||
|
|
c9f540f37d | ||
|
|
0479eb7601 | ||
|
|
459abd75f5 | ||
|
|
342bfb5e23 | ||
|
|
1fe0d14263 | ||
|
|
c8b823f9d8 | ||
|
|
45c37e737f | ||
|
|
41adbcec9f | ||
|
|
582831a447 | ||
|
|
312b68417f | ||
|
|
2206abf884 | ||
|
|
fcd613d6c7 | ||
|
|
8a3ddcfc81 | ||
|
|
c9604e2115 | ||
|
|
b583594ac7 | ||
|
|
36828daef1 | ||
|
|
8880d8ec5e | ||
|
|
56fc9f70d3 | ||
|
|
aacd188034 | ||
|
|
bb640d3221 | ||
|
|
0566dc54b1 | ||
|
|
aad635f766 | ||
|
|
a72f37bb67 | ||
|
|
93465f51bc | ||
|
|
26a7af26aa | ||
|
|
b791d6802b | ||
|
|
741597c2df | ||
|
|
37077bd339 | ||
|
|
ced4fd8993 | ||
|
|
eabc85ef5e | ||
|
|
5a18b34de3 | ||
|
|
56ac812359 | ||
|
|
e42fc158c9 | ||
|
|
886df221c1 | ||
|
|
fb01d1fb07 | ||
|
|
51ce67d599 | ||
|
|
a02348b5df | ||
|
|
28a5b78c6f | ||
|
|
7bbd60101e | ||
|
|
d239efa3ff | ||
|
|
269a8fb604 | ||
|
|
b1617a0825 | ||
|
|
806f530bcb | ||
|
|
7f0db4fd8e | ||
|
|
3a8fad7805 | ||
|
|
0c096e29aa | ||
|
|
6d56efa6ea | ||
|
|
97dde6b620 | ||
|
|
75d9697869 | ||
|
|
f35798a57e | ||
|
|
b8993a1ee9 | ||
|
|
951e826b75 | ||
|
|
d8d1389348 | ||
|
|
2970362338 | ||
|
|
7a2eca415b | ||
|
|
854411909b | ||
|
|
bb4e4d889f | ||
|
|
93f3fbf73e | ||
|
|
d252e47d09 | ||
|
|
db8f3f7350 | ||
|
|
85fd80ce10 | ||
|
|
a24d64bfaa | ||
|
|
33cc92a63a | ||
|
|
5e7f63f0bf | ||
|
|
8bd77e7098 | ||
|
|
13074c982b | ||
|
|
2171b9395b | ||
|
|
20bb1eb7ae | ||
|
|
7ee7bcd4e9 | ||
|
|
844810d609 | ||
|
|
67347196b1 | ||
|
|
e424e26128 | ||
|
|
ca7d17e41d | ||
|
|
6283e9ef43 | ||
|
|
7462c6ac39 | ||
|
|
f31850966f | ||
|
|
4ecf3e0671 | ||
|
|
60a986f504 | ||
|
|
0e9c3564c6 | ||
|
|
164cb66add | ||
|
|
0d9eba0312 | ||
|
|
d1f66d8d79 | ||
|
|
cc911409d6 | ||
|
|
a64f19e24b | ||
|
|
4337eeb754 | ||
|
|
928da42359 | ||
|
|
e717fa4d37 | ||
|
|
cc56eb2acc | ||
|
|
88e05f8489 | ||
|
|
9ec8583ef5 | ||
|
|
e9489cd6cb | ||
|
|
f1ca7c4429 | ||
|
|
adc4ebdd76 | ||
|
|
9a30c0cc3c | ||
|
|
47f43c023b | ||
|
|
5b385336b9 | ||
|
|
c3a2d95cfa | ||
|
|
6b19df680a | ||
|
|
fdf74bede0 | ||
|
|
876ad10ccc | ||
|
|
34a2b39165 | ||
|
|
276cc45571 | ||
|
|
311676ed21 | ||
|
|
4616867b0d | ||
|
|
8a5ae84efd | ||
|
|
59d2cd5a7f | ||
|
|
1c3e6e8b26 | ||
|
|
f2681d42ff | ||
|
|
774d1c367b | ||
|
|
1b8e0e876b | ||
|
|
1502f4f58f | ||
|
|
6db1db5488 | ||
|
|
09ad90537d | ||
|
|
da9aefa6b4 | ||
|
|
8ba802f3b4 | ||
|
|
e53f49d1af | ||
|
|
0917f581bc | ||
|
|
1fe2a3533f | ||
|
|
237e9a178f | ||
|
|
0668bfe077 | ||
|
|
214af6ad83 | ||
|
|
2551c47eb7 | ||
|
|
83d22fd7f9 | ||
|
|
325c243210 | ||
|
|
4e90cfbfed | ||
|
|
6fd2c27f38 | ||
|
|
19173d224a | ||
|
|
5b83829669 | ||
|
|
8cd3c6dccf | ||
|
|
29a89172f7 | ||
|
|
2089375179 | ||
|
|
f8949e7647 | ||
|
|
84ecaa0eca | ||
|
|
3f2d8d683a | ||
|
|
fd2598022c | ||
|
|
b05c58cce6 | ||
|
|
05805cd6b7 | ||
|
|
a165be754b | ||
|
|
af3172c148 | ||
|
|
487cb52615 | ||
|
|
9793bbb364 | ||
|
|
f6f74b93ef | ||
|
|
7568ff448a | ||
|
|
56158b7e04 | ||
|
|
798a9e4e74 | ||
|
|
c202b4fa96 | ||
|
|
1df02d13d3 | ||
|
|
73cb6738b3 | ||
|
|
ba8672dfab | ||
|
|
a5e0bf3579 | ||
|
|
99ba99c74c | ||
|
|
469ff84e29 | ||
|
|
b5daf5300f | ||
|
|
f5aeb6ff9b | ||
|
|
4c74d44dab | ||
|
|
4a86fbcda0 | ||
|
|
bc267e0f57 | ||
|
|
fc05137846 | ||
|
|
c085ece623 | ||
|
|
91f625cee0 | ||
|
|
27b067f87b | ||
|
|
987a546756 | ||
|
|
4d30f17671 | ||
|
|
d48810ba5b | ||
|
|
819bfe4599 | ||
|
|
d2f6e19262 | ||
|
|
e889e0c43b | ||
|
|
6e0bf4d840 | ||
|
|
83a8ca7b14 | ||
|
|
100200d0d2 | ||
|
|
f28bf7f401 | ||
|
|
e0fd68f5ce | ||
|
|
cc12c488aa | ||
|
|
99c3e591b2 | ||
|
|
1aefb7ef73 | ||
|
|
d7b6774d82 | ||
|
|
d4c5cb2b01 | ||
|
|
df476bfcff | ||
|
|
aa0e6b9977 | ||
|
|
1ba6468f1b | ||
|
|
f490102454 | ||
|
|
18f3cb6957 | ||
|
|
7abcfd85b7 | ||
|
|
6de417d9d4 | ||
|
|
ffe8feb265 | ||
|
|
c9b62cf375 | ||
|
|
7bc595785e | ||
|
|
022dec7aba | ||
|
|
ddaef70ced | ||
|
|
2357a51e09 | ||
|
|
24ded29ff6 | ||
|
|
ddff23a7f9 | ||
|
|
53936ef935 | ||
|
|
7f9bf6b710 | ||
|
|
cfdb27b0c1 | ||
|
|
fc3ca11040 | ||
|
|
d6c9c3319b | ||
|
|
8afaef4219 | ||
|
|
11faa893ca | ||
|
|
600b56b316 | ||
|
|
ee39281d14 | ||
|
|
0607c30700 | ||
|
|
492ad04277 | ||
|
|
1ed9018e69 | ||
|
|
ff0e15804f | ||
|
|
894e6299c1 | ||
|
|
c080190365 | ||
|
|
26f0e56587 | ||
|
|
b4e6aac985 | ||
|
|
7c21776e54 | ||
|
|
d724dd186e | ||
|
|
cbbd8e2e8b | ||
|
|
af6241f7ad | ||
|
|
852e763b89 | ||
|
|
0f71592015 | ||
|
|
e63d3a29e2 | ||
|
|
38cef641a5 | ||
|
|
6226396c4a | ||
|
|
89b47d43de | ||
|
|
d1c06c2180 | ||
|
|
800a4485f3 | ||
|
|
fede378577 | ||
|
|
3bc207b9dd | ||
|
|
ebac031925 | ||
|
|
3cbe640d3c | ||
|
|
4cb6197b21 | ||
|
|
d3d07a5e86 | ||
|
|
62ca38262f | ||
|
|
d62fb8894f | ||
|
|
fc29efc38d | ||
|
|
c4c9bb944b | ||
|
|
236adddc18 | ||
|
|
5b3aa8028b | ||
|
|
16e24c2043 | ||
|
|
7869953bbf | ||
|
|
d07edfc895 | ||
|
|
85b057cccf | ||
|
|
a2c473bb59 | ||
|
|
f587061a5b | ||
|
|
d9e92804a5 | ||
|
|
46e858a631 | ||
|
|
e0fe5231c2 | ||
|
|
698bc16e87 | ||
|
|
7b4f48650c | ||
|
|
a43ff267e9 | ||
|
|
717d04669a | ||
|
|
15dbffc215 | ||
|
|
0099e42332 | ||
|
|
1ed56a05c2 | ||
|
|
28fb6365d0 | ||
|
|
8365126b8d | ||
|
|
d770837ec0 | ||
|
|
59658acfec | ||
|
|
46f800e8c7 | ||
|
|
1c65a93d03 | ||
|
|
cae7885e2f | ||
|
|
eaa28e654f | ||
|
|
beef86d0dd | ||
|
|
2fe1feea75 | ||
|
|
0b52f94da7 | ||
|
|
f96bac8468 | ||
|
|
8444a7c00d | ||
|
|
c9d3bc3fca | ||
|
|
8340aa9670 | ||
|
|
3e2c0024d5 | ||
|
|
205393a2b5 | ||
|
|
5f0f2e0894 | ||
|
|
a5bb0902b4 | ||
|
|
d348d5fd5f | ||
|
|
21897ecbed | ||
|
|
01103e1870 | ||
|
|
2d8f9b1df0 | ||
|
|
68f1e7e594 | ||
|
|
87629cf2f6 | ||
|
|
e7f642cffe | ||
|
|
3e8fe565ed | ||
|
|
e96c7777d7 | ||
|
|
71daa07fb1 | ||
|
|
287bb276d5 | ||
|
|
ddc8110dea | ||
|
|
c0f4228d66 | ||
|
|
d6e6333a02 | ||
|
|
970ce063ee | ||
|
|
dd1f0da818 | ||
|
|
38a4bd432a | ||
|
|
3eabe6aa41 | ||
|
|
f2b7b64d86 | ||
|
|
b2057d38a9 | ||
|
|
964244b90d | ||
|
|
a7c1fa0049 | ||
|
|
42a28d9d3a | ||
|
|
19284e2ef8 | ||
|
|
2268defe66 | ||
|
|
643b018cfb | ||
|
|
e35ad79b1b | ||
|
|
da01d2e843 | ||
|
|
641dc0c51e | ||
|
|
69e2b4ee3a | ||
|
|
75a01a0734 | ||
|
|
b769ad6a3e | ||
|
|
6e59b97770 | ||
|
|
4da9fcd41d | ||
|
|
68ddbaf645 | ||
|
|
555a081fe2 | ||
|
|
513d3fd806 | ||
|
|
34aa616d41 | ||
|
|
ec8637f367 | ||
|
|
62a6b8df72 | ||
|
|
dd6f31f70f | ||
|
|
a5fd4b6e6e | ||
|
|
eca151d457 | ||
|
|
f859d3ded6 | ||
|
|
5288be3af7 | ||
|
|
83235dbc54 | ||
|
|
c78cb8f349 | ||
|
|
7210dbfd2a | ||
|
|
b6800a0b32 | ||
|
|
14eaa7a53b | ||
|
|
bc065415b0 | ||
|
|
9203c8d274 | ||
|
|
9468cf796d | ||
|
|
77d4c400c2 | ||
|
|
e3915dac76 | ||
|
|
78246d1a09 | ||
|
|
4bb319c6a6 | ||
|
|
293b11b8a5 | ||
|
|
8f42da0b50 | ||
|
|
a10186910d | ||
|
|
eb7715c1eb | ||
|
|
a7188cbf48 | ||
|
|
f7a2ac075f | ||
|
|
ce27f36d92 | ||
|
|
af5ed0f257 | ||
|
|
e6d05dcfca | ||
|
|
65b4e4b2a9 | ||
|
|
37adeae73e | ||
|
|
091b3459f6 | ||
|
|
85cdbb6be3 | ||
|
|
fcb1068f72 | ||
|
|
07ad305e8a | ||
|
|
bcfb738c93 | ||
|
|
b58f5e17ed | ||
|
|
87de82f2d0 | ||
|
|
87531e6302 | ||
|
|
eb67a6909b | ||
|
|
9217ce30e3 | ||
|
|
d52607ecd6 | ||
|
|
13e4914826 | ||
|
|
932fcfc1aa | ||
|
|
a2c770dc21 | ||
|
|
ba22c9e219 | ||
|
|
6a2456c501 | ||
|
|
ef3f14e6a7 | ||
|
|
9585b27678 | ||
|
|
5c77266d95 | ||
|
|
3db06222af | ||
|
|
aa6865d761 | ||
|
|
67b9b26ff3 | ||
|
|
b82ad9507f | ||
|
|
4d7c8e6b76 | ||
|
|
a685271de3 | ||
|
|
613c2d4431 | ||
|
|
225787a4a4 | ||
|
|
e107b6b122 | ||
|
|
5223b786ca | ||
|
|
3f0211b63a | ||
|
|
a6c6f8e650 | ||
|
|
ee6e80c753 | ||
|
|
ce72de30ce | ||
|
|
29bca53f9b | ||
|
|
dc2815c1fb | ||
|
|
3005a12bce | ||
|
|
fd913297fa | ||
|
|
90c98cdc39 | ||
|
|
b258ebf8ac | ||
|
|
97f0421523 | ||
|
|
ee8a733d6f | ||
|
|
20c7d7fd69 | ||
|
|
49ebb358ab | ||
|
|
1f41d42a91 | ||
|
|
813d2d101a | ||
|
|
86eb9f9595 | ||
|
|
18fa91296b | ||
|
|
8d3211447d | ||
|
|
805d8ac43d | ||
|
|
d26c7dfdb0 | ||
|
|
1e21cde315 | ||
|
|
c5d77e9659 | ||
|
|
2909586ede | ||
|
|
c5435b56bf | ||
|
|
2c386ff971 | ||
|
|
7f3b529367 | ||
|
|
6228239894 | ||
|
|
4da09a65f8 | ||
|
|
ab96610986 | ||
|
|
c8dccf8fb4 | ||
|
|
bdc12f41de | ||
|
|
2042c63251 | ||
|
|
6ec47d3d01 | ||
|
|
0c270e48af | ||
|
|
8aeac05d98 | ||
|
|
564dc9941e | ||
|
|
732b391720 | ||
|
|
879b6ad05c | ||
|
|
f153c9c943 | ||
|
|
1b411143e5 | ||
|
|
9456434688 | ||
|
|
268da8167a | ||
|
|
2213961e8f | ||
|
|
d100e733db | ||
|
|
15e4d40184 | ||
|
|
f7a76b9c45 | ||
|
|
84e1a34eaa | ||
|
|
41979f2518 | ||
|
|
4b1553e2d4 | ||
|
|
e516b69ef6 | ||
|
|
7df593f21f | ||
|
|
cac80887a6 | ||
|
|
45a143cd51 | ||
|
|
0379c8eca1 | ||
|
|
c9b16cdaba | ||
|
|
77943e69aa | ||
|
|
d620219dc4 | ||
|
|
c0685c05f8 | ||
|
|
b7386d23d4 | ||
|
|
17a4977bef | ||
|
|
4f9b139ab9 | ||
|
|
9f802c7294 | ||
|
|
6e1fa33f67 | ||
|
|
4021aa455b | ||
|
|
6ec0f6977d | ||
|
|
8c702798f6 | ||
|
|
2ad3c71777 | ||
|
|
05bd302ab6 | ||
|
|
2b4d51f2e9 | ||
|
|
ee279980cc | ||
|
|
4e42173508 | ||
|
|
b58bfb2f20 | ||
|
|
6bb82fe0a8 | ||
|
|
c73f2a3831 | ||
|
|
b1eca24226 | ||
|
|
58b7b3d668 | ||
|
|
ce055e863d | ||
|
|
53ec55a88e | ||
|
|
2cce75453c | ||
|
|
93204ccae2 | ||
|
|
57d617192b | ||
|
|
ea118be593 | ||
|
|
6a85ee9623 | ||
|
|
5851ac2dfe | ||
|
|
e844a4a8a8 | ||
|
|
1d8638ce86 | ||
|
|
4c17cdcb64 | ||
|
|
c291d05759 | ||
|
|
9520ce4b65 | ||
|
|
0485b451ea | ||
|
|
4efa11680a | ||
|
|
2f39f112c1 | ||
|
|
0438c59fd0 | ||
|
|
1aa343e89c | ||
|
|
5ed353a881 | ||
|
|
c126e66ebd | ||
|
|
97bcf138be | ||
|
|
37ce167996 | ||
|
|
88a7426843 | ||
|
|
a1f7c8e250 | ||
|
|
52d9a554d1 | ||
|
|
aabb50d4e3 | ||
|
|
03646b4910 | ||
|
|
11b02d927f | ||
|
|
5cefa088e2 | ||
|
|
2e4e03f196 | ||
|
|
ea4e8cf8a1 | ||
|
|
95def6d957 | ||
|
|
9970bed4d9 | ||
|
|
494d049ce1 | ||
|
|
6a385e3b7e | ||
|
|
71456d301f | ||
|
|
dbd697b578 | ||
|
|
5ca70927be | ||
|
|
2e52ba36cb | ||
|
|
fd78520dca | ||
|
|
3f655ca08d | ||
|
|
76edd33498 | ||
|
|
e5f35681e6 | ||
|
|
32b9011ae9 | ||
|
|
fdad5aad3f | ||
|
|
90ac152deb | ||
|
|
e9df0a6242 | ||
|
|
4cf94b8a01 | ||
|
|
a6fa5bdef3 | ||
|
|
8f61dfdbd4 | ||
|
|
ddf8c2b0b2 | ||
|
|
44ae628c59 | ||
|
|
44a7ba4587 | ||
|
|
44c4492acf | ||
|
|
609e6dda6b | ||
|
|
3f30927214 | ||
|
|
ae11e4ee2d | ||
|
|
b61665d5b6 | ||
|
|
38943d29d3 | ||
|
|
ff0284ddc4 | ||
|
|
3f65576881 | ||
|
|
3caf40356d | ||
|
|
26bbb6aa4b | ||
|
|
bf66c2da14 | ||
|
|
65f6b6b0ef | ||
|
|
983f647c7e | ||
|
|
14dfad3873 | ||
|
|
215465713b | ||
|
|
6be5ac61bd | ||
|
|
90c71caeb3 | ||
|
|
d46b5646c6 | ||
|
|
da564b51a1 | ||
|
|
f89617f7f2 | ||
|
|
0f8984ed78 | ||
|
|
306847ea67 | ||
|
|
d4eba300c9 | ||
|
|
dd589118d0 | ||
|
|
f92e15efd5 | ||
|
|
4f3c1df6c3 | ||
|
|
eb8f5c74e1 | ||
|
|
a960239f39 | ||
|
|
5621e5105a | ||
|
|
a1d2685b08 | ||
|
|
0f6b4909db | ||
|
|
b0ca7d2500 | ||
|
|
7ed6bc53b9 | ||
|
|
f57ab2f718 | ||
|
|
5ebb7935d2 | ||
|
|
c50a9076e1 | ||
|
|
d417c51669 | ||
|
|
5b934f5133 | ||
|
|
49ea69b3ff | ||
|
|
578219bed5 | ||
|
|
2e4a3d17b4 | ||
|
|
b4b24520f6 | ||
|
|
13710874ce | ||
|
|
7341ee2dfd | ||
|
|
e0cfd15bcc | ||
|
|
5a47354882 | ||
|
|
f5b532b144 | ||
|
|
c0dba635ba | ||
|
|
e1ac7791fe | ||
|
|
5b3f6a2730 | ||
|
|
f203266889 | ||
|
|
21914d8135 | ||
|
|
200aec7db4 | ||
|
|
a15c4b38b5 | ||
|
|
40e383765a | ||
|
|
5441088298 | ||
|
|
d0a6cdb62e | ||
|
|
19531e1f74 | ||
|
|
6f0805f564 | ||
|
|
6191429b50 | ||
|
|
89b76bac1f | ||
|
|
0758b2db30 | ||
|
|
74db1f1498 | ||
|
|
4f802c6637 | ||
|
|
33a04593ee | ||
|
|
6303f9a25f | ||
|
|
3932c42373 | ||
|
|
bc5df0f4e6 | ||
|
|
4b163f00c2 | ||
|
|
f07992739a | ||
|
|
c605c2cdbd | ||
|
|
1b42f628f4 | ||
|
|
5dafe360de | ||
|
|
6619d5fcc1 | ||
|
|
b960483e99 | ||
|
|
dd4a039515 | ||
|
|
229554084d | ||
|
|
4a1edb63dd | ||
|
|
3170b20967 | ||
|
|
d34cd639fc | ||
|
|
236df01b15 | ||
|
|
21cafc50cc | ||
|
|
de80679b67 | ||
|
|
27999abab4 | ||
|
|
82f37486a1 | ||
|
|
7820fa949f | ||
|
|
2ac9793064 | ||
|
|
a4453606cc | ||
|
|
71605b0f4d | ||
|
|
ba525f770c | ||
|
|
2509753fd3 | ||
|
|
5688c74d25 | ||
|
|
2ac081ff60 | ||
|
|
5d3e5f641d | ||
|
|
a0f29ed824 | ||
|
|
0b515981fc | ||
|
|
2e8259bb0b | ||
|
|
d274524317 | ||
|
|
71845bd2a0 | ||
|
|
bdd53557a8 | ||
|
|
d6ca255c21 | ||
|
|
2dc7b91dd2 | ||
|
|
288b12eefe | ||
|
|
f7d6dce6c8 | ||
|
|
48a481c4d0 | ||
|
|
8db8eacbdd | ||
|
|
e8e9e12c3a | ||
|
|
6e6daf5ac6 | ||
|
|
e73eed8563 | ||
|
|
da1319128a | ||
|
|
f2179fd370 | ||
|
|
969cdffbea | ||
|
|
3b7bcaaf34 | ||
|
|
4abe379c05 | ||
|
|
c980db5f08 | ||
|
|
c35d6e3522 | ||
|
|
044dc29307 | ||
|
|
7a4addaa74 | ||
|
|
f7e5068d94 | ||
|
|
67b8f3dfe7 | ||
|
|
95a44066da | ||
|
|
7909e65f83 | ||
|
|
f74a3d813b | ||
|
|
ac59386027 | ||
|
|
73a649b7cb | ||
|
|
9b49704959 | ||
|
|
ffbffc647b | ||
|
|
968061bb65 | ||
|
|
c47e3ee1b6 | ||
|
|
549a3efbb7 | ||
|
|
accf8d12bc | ||
|
|
0eeb9f5481 | ||
|
|
7b46e30fd4 | ||
|
|
35c8fd761f | ||
|
|
ba2d43d702 | ||
|
|
29349024c4 | ||
|
|
d108e04f38 | ||
|
|
d4d6646aae | ||
|
|
cf2d26656d | ||
|
|
7918f24405 | ||
|
|
9544261a45 | ||
|
|
354c9da60d | ||
|
|
626065702f | ||
|
|
9863bdbc93 | ||
|
|
83135e8f6a | ||
|
|
369233927c | ||
|
|
7e4b6b7bc4 | ||
|
|
a2dc4d687b | ||
|
|
a4431563e8 | ||
|
|
fbd91cae0c | ||
|
|
eb7a6e09cb | ||
|
|
9889a34bf2 | ||
|
|
8e1e60e98f | ||
|
|
f9998046a3 | ||
|
|
07bbf8703f | ||
|
|
77502cbade | ||
|
|
936fa865e1 | ||
|
|
2f188c8d96 | ||
|
|
83f5394810 | ||
|
|
24d677fc16 | ||
|
|
65a22a5ff7 | ||
|
|
a0f70237f5 | ||
|
|
4eff3051a0 | ||
|
|
e208631a5b | ||
|
|
b553a3dd20 | ||
|
|
e5f1a96ff8 | ||
|
|
eb7e7b2499 | ||
|
|
3caafdfd2f | ||
|
|
26ac181223 | ||
|
|
7fa60281bf | ||
|
|
73f2fa8189 | ||
|
|
75f162e46f | ||
|
|
1d2ca00703 | ||
|
|
4d91a5f8f4 | ||
|
|
61cb031ca4 | ||
|
|
ff0c27c926 | ||
|
|
d1d0a7051f | ||
|
|
444f9f7b04 | ||
|
|
411c04f06f | ||
|
|
5d935dce63 | ||
|
|
b88f6fe7e5 | ||
|
|
e6109f496c | ||
|
|
836ce36a4f | ||
|
|
35da2ec35a | ||
|
|
7b9598b2d5 | ||
|
|
4a4622bbe5 | ||
|
|
c9ec460807 | ||
|
|
79cd0c7fa4 | ||
|
|
de8c8b28c0 | ||
|
|
569e6f432b | ||
|
|
0d585188f9 | ||
|
|
34ca58d440 | ||
|
|
9c528e2935 | ||
|
|
2b967218eb | ||
|
|
6e058b4b60 | ||
|
|
b1e436ec17 | ||
|
|
4319cc56d8 | ||
|
|
952ae75138 | ||
|
|
4d745d3cf5 | ||
|
|
8798be8e63 | ||
|
|
42b06481c3 | ||
|
|
dbe287b701 | ||
|
|
8e3b627d07 | ||
|
|
809724d7e2 | ||
|
|
8e41b68e8f | ||
|
|
dc77edf218 | ||
|
|
65ba6af61b | ||
|
|
83d5e90054 | ||
|
|
e434f0ebfe | ||
|
|
a08979d564 | ||
|
|
252af65bb4 | ||
|
|
d048c2f225 | ||
|
|
9b9d5f89b3 | ||
|
|
e5bf3b5855 | ||
|
|
6755a7d742 | ||
|
|
5459e693a3 | ||
|
|
24108eb854 | ||
|
|
4635fb9995 | ||
|
|
9decb4d2ef | ||
|
|
b3b326016a | ||
|
|
4bde45f60e | ||
|
|
4fd842f98d | ||
|
|
f92f5b166e | ||
|
|
9b25ef35bd | ||
|
|
7c73536c25 | ||
|
|
33cbd577ad | ||
|
|
524eaa8245 | ||
|
|
9742b386b3 | ||
|
|
8b498b9f1a | ||
|
|
c04af69701 | ||
|
|
f87fb190b3 | ||
|
|
a21e72c3e6 | ||
|
|
1c4ffe64db | ||
|
|
abdcb21a7a | ||
|
|
f5ba7bfbb6 | ||
|
|
676e604135 | ||
|
|
3fac8ca8d1 | ||
|
|
33766a8daa | ||
|
|
e3d27df444 | ||
|
|
6aa27a7ce5 | ||
|
|
47cffb77de | ||
|
|
565a340b0a | ||
|
|
f45b64d8dd | ||
|
|
56ce72c447 | ||
|
|
898fab2577 | ||
|
|
0e5dd89866 | ||
|
|
79028af116 | ||
|
|
a572e12675 | ||
|
|
c8e8394615 | ||
|
|
8487f9cf29 | ||
|
|
d750be6ad8 | ||
|
|
0bb8616535 | ||
|
|
1faa1a6da9 | ||
|
|
b5ae4e25c2 | ||
|
|
3d0a159d96 | ||
|
|
8ea07c0030 | ||
|
|
59fd2a5e7d | ||
|
|
ae87c43452 | ||
|
|
f1599b9ef2 | ||
|
|
ee83e1bd4d | ||
|
|
7455467c17 | ||
|
|
19395697b9 | ||
|
|
7787579ad4 | ||
|
|
58a37ed34a | ||
|
|
fe8d61e5d5 | ||
|
|
87b0cc726b | ||
|
|
4504b2259f | ||
|
|
cf1b4969b9 | ||
|
|
434e77193c | ||
|
|
858d45f160 | ||
|
|
63186ec077 | ||
|
|
dfcb386569 | ||
|
|
d15f2ff0cf | ||
|
|
c395acd804 | ||
|
|
030820d5dc | ||
|
|
043ef55b22 | ||
|
|
a30dcbc0a8 | ||
|
|
02f0227e87 | ||
|
|
142a5e7b8b | ||
|
|
fdfc67406c | ||
|
|
fb7b9ddcb1 | ||
|
|
4ade505c7e | ||
|
|
1564cd5a87 | ||
|
|
33233b4900 | ||
|
|
d6b422a61c | ||
|
|
ff2001b91b | ||
|
|
d858b27400 | ||
|
|
1874f7e2e1 | ||
|
|
377d22ab9f | ||
|
|
4f3797c7e2 | ||
|
|
6b5a8f80fc | ||
|
|
bf10faa9dc | ||
|
|
548ca46fec | ||
|
|
e8c64ffdc7 | ||
|
|
0eb05245f1 | ||
|
|
0156c7842d | ||
|
|
1acb8f5119 | ||
|
|
76e754a0fd | ||
|
|
e7f905accb | ||
|
|
a9a8bc962c | ||
|
|
a6e7b97868 | ||
|
|
1befb74b13 | ||
|
|
8f3335a18c | ||
|
|
505c0579f7 | ||
|
|
a430691df1 | ||
|
|
332cf6df7c | ||
|
|
3f7afe7ec1 | ||
|
|
8fc4033ef0 | ||
|
|
ef35abb2b7 | ||
|
|
0b68d6b6f4 | ||
|
|
f1271537a4 | ||
|
|
b13505da1d | ||
|
|
7ea6ea98c8 | ||
|
|
d1798a2fda | ||
|
|
e911ff75d6 | ||
|
|
49f7162e7d | ||
|
|
3bb88b4388 | ||
|
|
b3fbe3ce35 | ||
|
|
9557eabaa7 | ||
|
|
acac1f5c6f | ||
|
|
3427355422 | ||
|
|
cbf626fd62 | ||
|
|
1c702303eb | ||
|
|
9a234269ed | ||
|
|
db9c9e2766 | ||
|
|
9439c0cb5a | ||
|
|
2ed790f354 | ||
|
|
486f8cd1ab | ||
|
|
875a13b42c | ||
|
|
719522b9bd | ||
|
|
753849fdbc | ||
|
|
bb25779de7 | ||
|
|
348d54d6d1 | ||
|
|
4471d9e570 | ||
|
|
19d4cac996 | ||
|
|
e4c877cf70 | ||
|
|
f14b3ef430 | ||
|
|
f3c93b1761 | ||
|
|
a72ba0cfac | ||
|
|
ba59bd68fc | ||
|
|
1c60d21947 | ||
|
|
473feecff3 | ||
|
|
351e23ad8e | ||
|
|
f31514adb7 | ||
|
|
2fcc265c2f | ||
|
|
b58e40332f | ||
|
|
a217c45359 | ||
|
|
764782662d | ||
|
|
4b24f4a2b5 | ||
|
|
c64ff141b8 | ||
|
|
1b896f8d1e | ||
|
|
01894cf01f | ||
|
|
16edf86595 | ||
|
|
1c53e5171c | ||
|
|
63d83e9477 | ||
|
|
5463453489 | ||
|
|
108133689d | ||
|
|
46ad63b7cf | ||
|
|
dbb20f6bc0 | ||
|
|
25c2a6ac0e | ||
|
|
161fba6903 | ||
|
|
55edf18c42 | ||
|
|
a0456b9c46 | ||
|
|
1a515b494b | ||
|
|
33cd9ad54b | ||
|
|
896f046f79 | ||
|
|
b9d5eea5c6 | ||
|
|
5275029d11 | ||
|
|
271aeaa49e | ||
|
|
91763a9c2f | ||
|
|
18438f0bac | ||
|
|
057f649fc9 | ||
|
|
88467ec444 | ||
|
|
1b897d50a9 | ||
|
|
d4a013edb7 | ||
|
|
545584cb9a | ||
|
|
e5abce8e0d | ||
|
|
3060ca8d42 | ||
|
|
ab14d01a0e | ||
|
|
987838fd2c | ||
|
|
6d4e718f5f | ||
|
|
1c3344a105 | ||
|
|
085e2fd588 | ||
|
|
f41152d393 | ||
|
|
d0c59b0e88 | ||
|
|
f49c837651 | ||
|
|
c12895089c | ||
|
|
27122338dc | ||
|
|
d762dfe94b | ||
|
|
c4750c2a07 | ||
|
|
3831f06319 | ||
|
|
be91bd81b8 | ||
|
|
2a40b503c0 | ||
|
|
ba2133d6ad | ||
|
|
4f47fec04d | ||
|
|
ab3d6c6025 | ||
|
|
121bfb2b4d | ||
|
|
100018b7cd | ||
|
|
1ff66d4c68 | ||
|
|
87a34ce56a | ||
|
|
04c722d5e0 | ||
|
|
7730114b30 | ||
|
|
7a2fa0c2d3 | ||
|
|
4eeaa16253 | ||
|
|
8dca155fca | ||
|
|
2a5df86299 | ||
|
|
3ea6e0e7a1 | ||
|
|
051ad69634 | ||
|
|
744e63fb2a | ||
|
|
cc7b86bf9b | ||
|
|
8c18ebe81d | ||
|
|
33689f4803 | ||
|
|
424d369179 | ||
|
|
d0221f1d2b | ||
|
|
3be97bf931 | ||
|
|
4afab31607 | ||
|
|
be21e29c35 | ||
|
|
c5b6e57a13 | ||
|
|
ca947dea3e | ||
|
|
2aea85ab54 | ||
|
|
05a41409b1 | ||
|
|
7a28d18448 | ||
|
|
1e05b590c4 | ||
|
|
ce5fddc3ed | ||
|
|
fd3f5af2aa | ||
|
|
dde5b77226 | ||
|
|
f845ef7dec | ||
|
|
9ae7a2cddb | ||
|
|
8a65e0ce00 | ||
|
|
98b1689dcb | ||
|
|
012d1a01f5 | ||
|
|
d9f46544a3 | ||
|
|
42c6b13901 | ||
|
|
f1482c3391 | ||
|
|
5bb7348509 | ||
|
|
4c9d5fef07 | ||
|
|
5607803376 | ||
|
|
76e0a49efe | ||
|
|
76a1013cc6 | ||
|
|
496c809f8c | ||
|
|
3ac830b9f9 | ||
|
|
f3d6d4800b | ||
|
|
8ef246e0b5 | ||
|
|
c7e6f84f89 | ||
|
|
fe04532ad2 | ||
|
|
e4b619b46d | ||
|
|
9ec3828b03 | ||
|
|
e0e3203156 | ||
|
|
edb977215b | ||
|
|
18233a170e | ||
|
|
283887d777 | ||
|
|
c2f0e4d965 | ||
|
|
8576397c3e | ||
|
|
c09af06d0c | ||
|
|
ded73ed90f | ||
|
|
f335eb1f83 | ||
|
|
7afa34fd27 | ||
|
|
1f56188f8c | ||
|
|
3162ea6f67 | ||
|
|
327c559aff | ||
|
|
99effefc81 | ||
|
|
e8dad39518 | ||
|
|
09a54c399c | ||
|
|
9586e59370 | ||
|
|
ce455b03e7 | ||
|
|
a39da29ac5 | ||
|
|
794a0b6c25 | ||
|
|
1b81f797a2 | ||
|
|
889ae39d7a | ||
|
|
5f4e991c70 | ||
|
|
c96f6eb584 | ||
|
|
e10664c5e8 | ||
|
|
99a957d3f4 | ||
|
|
658a63694b | ||
|
|
30e50494bb | ||
|
|
719985cb9c | ||
|
|
2d2414f39e | ||
|
|
edb4ba5fdb | ||
|
|
007996b40d | ||
|
|
dbd9ea3e5a | ||
|
|
2ef0340517 | ||
|
|
9d737ecb7a | ||
|
|
bd6edd3fa2 | ||
|
|
6eee13cf58 | ||
|
|
9602b5cfbd | ||
|
|
48ffc11e9c | ||
|
|
5a3e9ff608 | ||
|
|
aac5cab80b | ||
|
|
a3e18c763a | ||
|
|
403dbc1377 | ||
|
|
5b30412c68 | ||
|
|
d5833800a8 | ||
|
|
8d3a785fa5 | ||
|
|
3a5a7de6c9 | ||
|
|
c58c1dc446 | ||
|
|
eefe189e1d | ||
|
|
f05c801194 | ||
|
|
c905bf37f6 | ||
|
|
8cae71ebc3 | ||
|
|
14d776ff0c | ||
|
|
c7565dad84 | ||
|
|
b7cfb9e2c0 | ||
|
|
0d152437df | ||
|
|
6aef83c97d | ||
|
|
225aeca346 | ||
|
|
0a62f5f382 | ||
|
|
234844915e | ||
|
|
263d3bfb40 | ||
|
|
bf466c0f82 | ||
|
|
8b58407586 | ||
|
|
64119c792d | ||
|
|
8388e011ae | ||
|
|
0fddbd8a09 | ||
|
|
badb8c24b9 | ||
|
|
bfd3137246 | ||
|
|
6de0d06259 | ||
|
|
89d730a098 | ||
|
|
18979194cf | ||
|
|
aadc84d359 | ||
|
|
9d155ecd12 | ||
|
|
60af946576 | ||
|
|
ca0e8296bc | ||
|
|
c4a28da3ad | ||
|
|
20319fd9ed | ||
|
|
01d29d7b02 | ||
|
|
1183260426 | ||
|
|
07613def0a | ||
|
|
c2a608d9f1 | ||
|
|
49b86442ff | ||
|
|
4785cd43d1 | ||
|
|
e238c9977d | ||
|
|
b37b7c9949 | ||
|
|
f7d7fb381d | ||
|
|
3481bdf493 | ||
|
|
d365e22967 | ||
|
|
d02363609a | ||
|
|
1e1ca25343 | ||
|
|
a2ebbffca7 | ||
|
|
0395130c06 | ||
|
|
b8c167e804 | ||
|
|
17026f2741 | ||
|
|
112d728f48 | ||
|
|
96293cf991 | ||
|
|
f0fbf1d670 | ||
|
|
7a821d518b | ||
|
|
663b2857eb | ||
|
|
155d9206a4 | ||
|
|
6b2a3d5de6 | ||
|
|
82ad07c418 | ||
|
|
d144e43bb3 | ||
|
|
d2aee174e6 | ||
|
|
20f0d0f9b9 | ||
|
|
b675ba6f79 | ||
|
|
d1c178dd53 | ||
|
|
d619ff1376 | ||
|
|
db0f7613e1 | ||
|
|
45d8bfe09e | ||
|
|
d521e1c2a1 | ||
|
|
4ea4acf17b | ||
|
|
3a993aa4bf | ||
|
|
c7871d9892 | ||
|
|
482f48cca9 | ||
|
|
36e6594dce | ||
|
|
e17883827b | ||
|
|
37a4386d2c | ||
|
|
fd0a130c14 | ||
|
|
5e77efaf41 | ||
|
|
b0cacef14b | ||
|
|
b20830b338 | ||
|
|
c63625d41a | ||
|
|
7de7b49f6c | ||
|
|
d0d0e41fd2 | ||
|
|
2a28dd32fd | ||
|
|
65e83e097c | ||
|
|
4f37559232 | ||
|
|
604dbf6d94 | ||
|
|
53593085cf | ||
|
|
eb0144d79b | ||
|
|
54b0dfa0f7 | ||
|
|
264042760b | ||
|
|
1e999f9f1b | ||
|
|
f9b66bc464 | ||
|
|
60d465dbdd | ||
|
|
3ebdd3c7fc | ||
|
|
f0fa8c6df2 | ||
|
|
9d33e6f7cf | ||
|
|
4a19c3b254 | ||
|
|
4743f0f41b | ||
|
|
0abe148fd9 | ||
|
|
39411fa876 | ||
|
|
662fd70b54 | ||
|
|
cd87e2f59a | ||
|
|
2c70847654 | ||
|
|
eaf895e6ef | ||
|
|
149a78e33f | ||
|
|
88897638a9 | ||
|
|
c575f8ce87 | ||
|
|
5303941021 | ||
|
|
c0f1e57b51 | ||
|
|
ccdb23bb90 | ||
|
|
146c2c368c | ||
|
|
60cc01a6c6 | ||
|
|
f5761a342b | ||
|
|
caf8299e2e | ||
|
|
c6fadc0ee1 | ||
|
|
2dc3db2a3e | ||
|
|
771d0add8f | ||
|
|
e5e85283a9 | ||
|
|
21068d8e87 | ||
|
|
4d2ea5a838 | ||
|
|
9ba53f26a3 | ||
|
|
3aeedbfd11 | ||
|
|
989b0b8802 | ||
|
|
b2e4811db2 | ||
|
|
b467495cd0 | ||
|
|
3b8ed84245 | ||
|
|
3a72cc2929 | ||
|
|
c202424a03 | ||
|
|
083f75ee42 | ||
|
|
45760f5f05 | ||
|
|
116a4769c1 | ||
|
|
1e4f5f6342 | ||
|
|
a19d285ae3 | ||
|
|
564782ba95 | ||
|
|
2dc7b8bd0e | ||
|
|
e0930845ce | ||
|
|
cf81788366 | ||
|
|
89a0e3a927 | ||
|
|
a8facdc090 | ||
|
|
c5e29261f3 | ||
|
|
1acb2e15b4 | ||
|
|
06898c80d9 | ||
|
|
684576ff45 | ||
|
|
574a24a2ec | ||
|
|
9775d6ab66 | ||
|
|
2b916250d8 | ||
|
|
2955529bb4 | ||
|
|
d094b5eb3c | ||
|
|
bc93ee842f | ||
|
|
0c6d79528a | ||
|
|
556e03a3c9 | ||
|
|
e4887738bb | ||
|
|
0f5c1c193a | ||
|
|
ab6dcad61c | ||
|
|
b6855ddc9c | ||
|
|
0cbb958f34 | ||
|
|
418da6d952 | ||
|
|
51d133d686 | ||
|
|
cbb95d3d24 | ||
|
|
d9126a861f | ||
|
|
b4768a1397 | ||
|
|
47b032e97f | ||
|
|
50dfd5b4fe | ||
|
|
1de02c273d | ||
|
|
9ce7fc3887 | ||
|
|
dc1f7b9ea3 | ||
|
|
ee7cf95b13 | ||
|
|
492fc3536d | ||
|
|
5e61bdb4d5 | ||
|
|
f964ac5eee | ||
|
|
c55b39afad | ||
|
|
a27463a9a2 | ||
|
|
590eb6c02d | ||
|
|
0d7a6b4906 | ||
|
|
b4f0287197 | ||
|
|
8d6386809e | ||
|
|
230328a30a | ||
|
|
5819d6b14a | ||
|
|
7b4a40ed70 | ||
|
|
f210dcadf4 | ||
|
|
178a1d2048 | ||
|
|
a4b4e0770b | ||
|
|
2a6e35db31 | ||
|
|
e3794138d8 | ||
|
|
fdd10da6f7 | ||
|
|
5f12a07bff | ||
|
|
6a4a1d0cb0 | ||
|
|
434c40986d | ||
|
|
8ee6857702 | ||
|
|
721ddc903f | ||
|
|
154c345db0 | ||
|
|
25f637a334 | ||
|
|
2356d73bb4 | ||
|
|
4968423e71 | ||
|
|
99eba67585 | ||
|
|
5abe03d6e8 | ||
|
|
83078af5b0 | ||
|
|
185aa5b0e5 | ||
|
|
cabd60fdce | ||
|
|
10944395bf | ||
|
|
204f4f4d09 | ||
|
|
c9bce0b8f8 | ||
|
|
deee574b11 | ||
|
|
55410368e5 | ||
|
|
e4fdf1debe | ||
|
|
1580899c1d | ||
|
|
f863b76300 | ||
|
|
5e1ec06f09 | ||
|
|
36e2ea6068 | ||
|
|
f4164b73b4 | ||
|
|
9ef506a2b2 | ||
|
|
b1b54199ef | ||
|
|
33394b769d | ||
|
|
011e85a5e3 | ||
|
|
d5dcb6f775 | ||
|
|
0c25dedf31 | ||
|
|
6105464b79 | ||
|
|
4d51f0db79 | ||
|
|
ff530f04a0 | ||
|
|
e8b21fe406 | ||
|
|
71cb9df386 | ||
|
|
f97c2d4a9b | ||
|
|
b8a6dae038 | ||
|
|
969f7ed5b7 | ||
|
|
e825409a84 | ||
|
|
b8d29fd8e6 | ||
|
|
200f2d98db | ||
|
|
1a7f3d99c5 | ||
|
|
e80876700c | ||
|
|
ec55b4f2fb | ||
|
|
798cde474f | ||
|
|
558d482c47 | ||
|
|
418b6a2703 | ||
|
|
1ef5bf3cfd | ||
|
|
2a94207ad6 | ||
|
|
ddcba3f075 | ||
|
|
db3ae95cac | ||
|
|
1a05de2bff | ||
|
|
d9163a4cf5 | ||
|
|
44885a398f | ||
|
|
dfe1ed5e97 | ||
|
|
242f6052c2 | ||
|
|
519d55a950 | ||
|
|
b6008dc645 | ||
|
|
6f3684ffb5 | ||
|
|
615a5415c9 | ||
|
|
ba081be327 | ||
|
|
3e88414e4e | ||
|
|
0888952768 | ||
|
|
5dcd9a2b70 | ||
|
|
6ce9432d75 | ||
|
|
6c8507724b | ||
|
|
d04e95e968 | ||
|
|
b06050f9ad | ||
|
|
ad75d18d2e | ||
|
|
ed4b8da048 | ||
|
|
2cd421d809 | ||
|
|
ea0ea357f4 | ||
|
|
0480a946f5 | ||
|
|
67f8a41be5 | ||
|
|
5e1f082d0c | ||
|
|
a633351962 | ||
|
|
2edfe52230 | ||
|
|
acee1ad853 | ||
|
|
8f4ae68ca7 | ||
|
|
ff1b9344c9 | ||
|
|
a923437bc0 | ||
|
|
dde698c2e8 | ||
|
|
c2b47e31a5 | ||
|
|
4e0bf97716 | ||
|
|
174e51b5bf | ||
|
|
30cd7ec1cf | ||
|
|
48459ba15c | ||
|
|
48ecccce2d | ||
|
|
a739128df9 | ||
|
|
2c1775620a | ||
|
|
40f910c43a | ||
|
|
503114a782 | ||
|
|
71f9e4673e | ||
|
|
176e8e94c3 | ||
|
|
814b340c27 | ||
|
|
f167879035 | ||
|
|
4187572616 | ||
|
|
ff43d8b449 | ||
|
|
97bf86f8ee | ||
|
|
8c449e6285 | ||
|
|
29930a9fd2 | ||
|
|
c98ad3df96 | ||
|
|
9c3c30e5c7 | ||
|
|
b4a09b72ee | ||
|
|
5a3810b463 | ||
|
|
e8d97006e5 | ||
|
|
8adc22e362 | ||
|
|
dcebf78fe0 | ||
|
|
651c8510e8 | ||
|
|
1ed3f5ed61 | ||
|
|
70c81b0c07 | ||
|
|
47c1197534 | ||
|
|
fb41a3c669 | ||
|
|
2700069d5a | ||
|
|
044ccbaacf | ||
|
|
841d943651 | ||
|
|
04cd8789cb | ||
|
|
9578783a71 | ||
|
|
4cff5fa462 | ||
|
|
cc1b4f776a | ||
|
|
72d1b262ac | ||
|
|
6fb7cc38a2 | ||
|
|
8a7b8400e7 | ||
|
|
d2ab094dec | ||
|
|
ccd2966da9 | ||
|
|
6dc9b74bc6 | ||
|
|
04c841190f | ||
|
|
d20ce6e144 | ||
|
|
a7d461fccd | ||
|
|
4c5a2da65f | ||
|
|
caff33228e | ||
|
|
f38f6f80b7 | ||
|
|
e848e06618 | ||
|
|
eece5fe32c | ||
|
|
8590993185 | ||
|
|
b64ee91a41 | ||
|
|
d0133e6eba | ||
|
|
1925c3448c | ||
|
|
19b8587654 | ||
|
|
051f5df526 | ||
|
|
e525519509 | ||
|
|
4b90820d9f | ||
|
|
2873603ab5 | ||
|
|
ec52c3b9da | ||
|
|
10ae3406ee | ||
|
|
232658d9d3 | ||
|
|
c000002f46 | ||
|
|
2fedf3d596 | ||
|
|
887d745549 | ||
|
|
20f90d5e8a | ||
|
|
17bda2d109 | ||
|
|
b534351058 | ||
|
|
b3e4e7ef2e | ||
|
|
a3f6dbdf5c | ||
|
|
95ae5224b0 | ||
|
|
03dbc0b831 | ||
|
|
ffa8ab8eb5 | ||
|
|
a17e119d8b | ||
|
|
6bfc7b4d79 | ||
|
|
b3e8e7c79e | ||
|
|
bdd3a4fef5 | ||
|
|
a00f5a371e | ||
|
|
55c412630c | ||
|
|
778ee637ee | ||
|
|
80aff93b32 | ||
|
|
6721973e37 | ||
|
|
a2ed5801d3 | ||
|
|
15ce4b24fc | ||
|
|
c5260884d6 | ||
|
|
ea124cb324 | ||
|
|
13b597fa71 | ||
|
|
ecc7623e7f | ||
|
|
87c0f9d6b4 | ||
|
|
1cfcb8af11 | ||
|
|
56aaa4c44c | ||
|
|
4b6a7bd706 | ||
|
|
5bc933a285 | ||
|
|
01d124d9e2 | ||
|
|
58a06312a4 | ||
|
|
c2c8db9195 | ||
|
|
d1e6b0e225 | ||
|
|
8936367695 | ||
|
|
8517e9c10a | ||
|
|
fcecb70b1d | ||
|
|
582c1589f3 | ||
|
|
cb15269eb0 | ||
|
|
f47807900b | ||
|
|
40410a38bc | ||
|
|
6b54a688cf | ||
|
|
b59dc8d5ae | ||
|
|
45ba206a94 | ||
|
|
2220ec0a69 | ||
|
|
5fdbb87df8 | ||
|
|
f1c9bcd0fc | ||
|
|
3723548ded | ||
|
|
12ccc73ae7 | ||
|
|
ee8d9636d1 | ||
|
|
38de2866e5 | ||
|
|
bdac7621ee | ||
|
|
8ac4774675 | ||
|
|
229e1950ed | ||
|
|
93977bca10 | ||
|
|
c2a2147a5b | ||
|
|
73173af955 | ||
|
|
a2248aea2e | ||
|
|
a8167c6611 | ||
|
|
91f4b31fe1 | ||
|
|
cad8f6f980 | ||
|
|
d8bf7ea8e9 | ||
|
|
d8f28a663c | ||
|
|
2ae4126a9e | ||
|
|
6f1c2aab43 | ||
|
|
e71c1c26df | ||
|
|
b24498ec2c | ||
|
|
b2d4639543 | ||
|
|
d3ef985954 | ||
|
|
7c58c99184 | ||
|
|
ad77db8b71 | ||
|
|
e7c67065c0 | ||
|
|
0f78b81511 | ||
|
|
d051056f92 | ||
|
|
a4a38e8df0 | ||
|
|
60ef8ed128 | ||
|
|
8aa0dc7838 | ||
|
|
4177f09b83 | ||
|
|
acaadb55c1 | ||
|
|
b88c2e8ffe | ||
|
|
f4ea5f47dc | ||
|
|
62ae66d43b | ||
|
|
8641d28740 | ||
|
|
de3438407c | ||
|
|
434764269c | ||
|
|
ba212fe0b6 | ||
|
|
5f93b4d35e | ||
|
|
f8db4a8ab4 | ||
|
|
398612ba07 | ||
|
|
77b013afb5 | ||
|
|
08c0cd8a42 | ||
|
|
1c6e9dfabc | ||
|
|
0037bf23fc | ||
|
|
285edc9169 | ||
|
|
c4aa84ad50 | ||
|
|
b635bc92d1 | ||
|
|
146d2228cc | ||
|
|
b2501ccf12 | ||
|
|
e60bba3fbc | ||
|
|
e26cfccf16 | ||
|
|
74f80abce2 | ||
|
|
5899b8cf3e | ||
|
|
08e0a62956 | ||
|
|
2bd17a51ae | ||
|
|
c7b9ebb598 | ||
|
|
e3db43ffe5 | ||
|
|
f61ab01d96 | ||
|
|
ceca8ccac8 | ||
|
|
374c3e1278 | ||
|
|
e09d8a304c | ||
|
|
2a7d9fe9b8 | ||
|
|
e63aeb6d68 | ||
|
|
077d5d4ebc | ||
|
|
e2d774cdd7 | ||
|
|
415b598346 | ||
|
|
69627d66f8 | ||
|
|
ac98cd98e3 | ||
|
|
91d324b4ea | ||
|
|
89fb50263b | ||
|
|
e257c6c20b | ||
|
|
43eae40e45 | ||
|
|
920240a687 | ||
|
|
f8b9da1a2c | ||
|
|
3c987ee956 | ||
|
|
5c6d46329b | ||
|
|
8b3e964d14 | ||
|
|
91a93df049 | ||
|
|
19826af5f0 | ||
|
|
49f4cfdf39 | ||
|
|
b3222792ad | ||
|
|
0640710115 | ||
|
|
fa65989a8b | ||
|
|
4209f079dd | ||
|
|
a7704777ce | ||
|
|
7d51b8374d | ||
|
|
a27042b521 | ||
|
|
5b51c893c5 | ||
|
|
408e69396c | ||
|
|
954bbed84a | ||
|
|
7c329ec72c | ||
|
|
07a8a360a5 | ||
|
|
1618c9e6d1 | ||
|
|
ba0147ac42 | ||
|
|
9e88f057b4 | ||
|
|
f171bf5b8f | ||
|
|
1b1628b90a | ||
|
|
50cf25672e | ||
|
|
b316862831 | ||
|
|
38a4b9c297 | ||
|
|
a058cbc410 | ||
|
|
1ef7913497 | ||
|
|
88a16c8b4f | ||
|
|
8030b28ff8 | ||
|
|
1c598b1db8 | ||
|
|
6854bf69a8 | ||
|
|
293def601d | ||
|
|
651dc65efc | ||
|
|
c2b2bd6a93 | ||
|
|
e32a48d256 | ||
|
|
b5cf121d70 | ||
|
|
44c26bf2a1 | ||
|
|
cc8c5057fe | ||
|
|
b4c7c1ca99 | ||
|
|
16d3b31b2c | ||
|
|
89a8180c5e | ||
|
|
34f961bbf3 | ||
|
|
2384f9e1db | ||
|
|
48cce779a2 | ||
|
|
6820753732 | ||
|
|
fbbe9a016d | ||
|
|
c64ca7ef58 | ||
|
|
900cfcb584 | ||
|
|
beab3078d6 | ||
|
|
530a2199da | ||
|
|
d9bca0c32f | ||
|
|
d733de97f5 | ||
|
|
f06c11ed40 | ||
|
|
c638caa63e | ||
|
|
d775372a34 | ||
|
|
07affc3d93 | ||
|
|
f2ebbebead | ||
|
|
a695b379b5 | ||
|
|
88c2190a7c | ||
|
|
2dbf36ef55 | ||
|
|
cca9208697 | ||
|
|
aa37022ef7 | ||
|
|
85c417579f | ||
|
|
baed67efc4 | ||
|
|
c5b7aa1532 | ||
|
|
904e5af128 | ||
|
|
a41d110647 | ||
|
|
a92d6ff13c | ||
|
|
05278935a3 | ||
|
|
a56cdef9b1 | ||
|
|
e9357a2deb | ||
|
|
8d94d27af0 | ||
|
|
6f2a222c59 | ||
|
|
8470a515ef | ||
|
|
06982ac43b | ||
|
|
865c3b5f92 | ||
|
|
8c9e06d7b9 | ||
|
|
a9cc128308 | ||
|
|
ccb16b467b | ||
|
|
1e44aeb92a | ||
|
|
c897f7119a | ||
|
|
ee8e2b1547 | ||
|
|
5fa38cd679 | ||
|
|
65535b5482 | ||
|
|
439a198d02 | ||
|
|
f041b02557 | ||
|
|
4d8639eb2d | ||
|
|
519c8de16f | ||
|
|
7f20af4674 | ||
|
|
55d24e5fed | ||
|
|
81f654e396 | ||
|
|
8f1dc165e2 | ||
|
|
9a0cfff57f | ||
|
|
d749eb6896 | ||
|
|
6d59ac192b | ||
|
|
94d3725cf2 | ||
|
|
8840ec0f49 | ||
|
|
44a8e86d47 | ||
|
|
73abdda442 | ||
|
|
15b03ab1a8 | ||
|
|
dc5245679a | ||
|
|
60414e5bce | ||
|
|
af40c7d667 | ||
|
|
7eb2ecda0f | ||
|
|
6d12a859bc | ||
|
|
920071e242 | ||
|
|
2a24b4bd0c | ||
|
|
a753502200 | ||
|
|
8958fae362 | ||
|
|
e2d68210d7 | ||
|
|
99534debc8 | ||
|
|
5b98629747 | ||
|
|
42003f6af3 | ||
|
|
434573b226 | ||
|
|
d6081c829c | ||
|
|
58718881ef | ||
|
|
ac669e8b92 | ||
|
|
567f1566a9 | ||
|
|
59a5687105 | ||
|
|
7b13ff9704 | ||
|
|
5e7b826a4f | ||
|
|
cbc63b9b48 | ||
|
|
71a84cbab0 | ||
|
|
55e54e464b | ||
|
|
467688dc06 | ||
|
|
375d8f913b | ||
|
|
021849204a | ||
|
|
b635f2e964 | ||
|
|
1e2b96bbee | ||
|
|
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 | ||
|
|
2dfe1c37ad | ||
|
|
b9949780f4 | ||
|
|
5fe857d4be | ||
|
|
3d86c6b18f | ||
|
|
0f0b2e66b8 | ||
|
|
5d24ee71ad | ||
|
|
3a05c5d3ce | ||
|
|
89ec535af5 | ||
|
|
e96d7972c4 | ||
|
|
962a3f0b6e | ||
|
|
cbb5fa4f07 | ||
|
|
b57907efb2 | ||
|
|
26beb7861f | ||
|
|
6e8b9f1341 | ||
|
|
6efe94167f | ||
|
|
51cc96e469 | ||
|
|
bdedced84b | ||
|
|
f497ad722d | ||
|
|
339eb8943e | ||
|
|
c36864e40e | ||
|
|
af6155bb0e | ||
|
|
605fed4b46 | ||
|
|
ac40b74788 | ||
|
|
3e6ddb3738 | ||
|
|
9ac756c6ea | ||
|
|
3b0a30eba8 | ||
|
|
bac7259081 | ||
|
|
4d474ad513 | ||
|
|
e50e82ab40 | ||
|
|
4922175589 | ||
|
|
a289f89fbe | ||
|
|
ba64001df8 | ||
|
|
b225b089b8 | ||
|
|
557a35f55b | ||
|
|
1848fd6fa1 | ||
|
|
f2a4853c93 | ||
|
|
e65154085c | ||
|
|
e4676bb59b | ||
|
|
3b968014c9 | ||
|
|
21b9b93377 | ||
|
|
c4d1b2983d | ||
|
|
7d7a34aeb2 | ||
|
|
65c84700fc | ||
|
|
5a727522f0 | ||
|
|
1599754727 | ||
|
|
d90338cec6 | ||
|
|
d0e94abb40 | ||
|
|
d8c4d6de10 | ||
|
|
74ba98a51b | ||
|
|
c296031d9f | ||
|
|
81c453b16a | ||
|
|
4a34c6f176 | ||
|
|
9b3150bd2e | ||
|
|
6f2245c8fa | ||
|
|
0f9941dc5a | ||
|
|
060f31500b | ||
|
|
7c2a83c635 | ||
|
|
97e3c50cd9 | ||
|
|
b2360dabf6 | ||
|
|
723160280f | ||
|
|
fa92818af3 | ||
|
|
289a32167c | ||
|
|
95e107db96 | ||
|
|
513fd04d21 | ||
|
|
7a16e12207 | ||
|
|
de8252f67f | ||
|
|
98e4741463 | ||
|
|
028245a57b | ||
|
|
2765f2e4a7 | ||
|
|
79db59d1a7 | ||
|
|
c48cff9fbe | ||
|
|
f4b8e829e9 | ||
|
|
468d766819 | ||
|
|
f3ab64d3a8 | ||
|
|
a234bca4ef | ||
|
|
42e9c7eb56 | ||
|
|
9d19f8a5fe | ||
|
|
24e61cffe3 | ||
|
|
3556fe5d86 | ||
|
|
ee887d98f6 | ||
|
|
5c7b1feb4c | ||
|
|
3cd5301f40 | ||
|
|
d8169e6f6b | ||
|
|
c4833b024e | ||
|
|
2a5d5a8cc4 | ||
|
|
f7112154e9 | ||
|
|
f83051b2e3 | ||
|
|
2e42adb302 | ||
|
|
c09ebb8c04 | ||
|
|
042dc7360e | ||
|
|
7a6e294f7b | ||
|
|
97e786c331 | ||
|
|
8ee6adefe3 | ||
|
|
64c37826e4 | ||
|
|
2e8015e0da | ||
|
|
5b6281afcf | ||
|
|
e732fb0c4f | ||
|
|
b10917a426 | ||
|
|
7ae64260e0 | ||
|
|
f97f6bcd3a | ||
|
|
e86d98cbaa | ||
|
|
6afb90778b | ||
|
|
32c7f91a14 | ||
|
|
b28a27e9e9 | ||
|
|
15164c0aa9 | ||
|
|
bf011fedfc | ||
|
|
d7d11b7ebd | ||
|
|
9a929c8f68 | ||
|
|
298d8c0a9b | ||
|
|
a054570942 | ||
|
|
a0009fc30d | ||
|
|
beb51aa09e | ||
|
|
e8a96e275e | ||
|
|
11e758a430 | ||
|
|
d630f53e0d | ||
|
|
5918daf8a4 | ||
|
|
326bb56e40 | ||
|
|
f96154f44c | ||
|
|
45c5b903eb | ||
|
|
5037cf3adf | ||
|
|
180443af42 | ||
|
|
4f3f97fbde | ||
|
|
664cf3278a | ||
|
|
cd36049cd1 | ||
|
|
c2523a0541 | ||
|
|
92739a0aa7 | ||
|
|
cd908ef4ff | ||
|
|
ebd33e0cea | ||
|
|
5f2c5bf110 | ||
|
|
417099fa20 | ||
|
|
626bec8e84 | ||
|
|
a06e2b7cab | ||
|
|
3ae5367ff2 | ||
|
|
b4ef0bca47 | ||
|
|
4313d6f9c0 | ||
|
|
2a0dd9bd70 | ||
|
|
3eeac9bc7e | ||
|
|
67de72bd9b | ||
|
|
552a218468 | ||
|
|
d940151496 | ||
|
|
f5c7f4abe7 | ||
|
|
3ae6c1875d | ||
|
|
1ad6a7f611 | ||
|
|
89d26123ff | ||
|
|
46bffd98cb | ||
|
|
41b84ce012 | ||
|
|
de392f1e5c | ||
|
|
0455cd933d | ||
|
|
d9c0051fae | ||
|
|
126e7affb7 | ||
|
|
624d6be2a5 | ||
|
|
16f960feb5 | ||
|
|
e145d51ba6 | ||
|
|
dcbae65444 | ||
|
|
b4bf2b5a7e | ||
|
|
9baed7609c | ||
|
|
1c2efa1706 | ||
|
|
80a24d52d4 | ||
|
|
af9f56a09d | ||
|
|
ddd74b67be | ||
|
|
7b558d7f8b | ||
|
|
c87ae64a82 | ||
|
|
b9f0ca7274 | ||
|
|
c1759b9fa2 | ||
|
|
9c63d83d3d | ||
|
|
1ed91a04fe | ||
|
|
154cdaaa40 | ||
|
|
33c4b445ef | ||
|
|
53135fe89a | ||
|
|
083acd496d | ||
|
|
00348fd793 | ||
|
|
ddb6fc696b | ||
|
|
f7e48a5cb8 | ||
|
|
70352269ba | ||
|
|
0b94147928 | ||
|
|
da9f59264f | ||
|
|
96b7b48efa | ||
|
|
aea4bf2894 | ||
|
|
855ef72f3f | ||
|
|
98dc857b32 | ||
|
|
94af17a6eb | ||
|
|
00fd35482e | ||
|
|
cc3e0770bc | ||
|
|
e7f7064cc5 | ||
|
|
7b759fe0df | ||
|
|
254ee3baab | ||
|
|
f957e8fdf9 | ||
|
|
822012eea9 | ||
|
|
bb21ecac5b | ||
|
|
648859bda2 | ||
|
|
f328e0f3a8 | ||
|
|
6012eaa183 | ||
|
|
da2a6c1f1c | ||
|
|
0438f100ae | ||
|
|
b95ad9ac55 | ||
|
|
828a256123 | ||
|
|
ebf447ac81 | ||
|
|
124f349ea1 | ||
|
|
26718401fb | ||
|
|
f463e20753 | ||
|
|
1129070514 | ||
|
|
ac3f7b81f8 | ||
|
|
62f9573fb3 | ||
|
|
6d0e5d2e62 | ||
|
|
8b48bf1154 | ||
|
|
42be53201f | ||
|
|
c7791b8cb2 | ||
|
|
7e9059d60f | ||
|
|
f3ebe1a77e | ||
|
|
301fb56ce9 | ||
|
|
aa7a6e878b | ||
|
|
0a39837a62 | ||
|
|
b2e8a9b293 | ||
|
|
a98ad81760 | ||
|
|
ccc51c8331 | ||
|
|
ee171c6da9 | ||
|
|
d5609e969d | ||
|
|
927c806841 | ||
|
|
2da9dda1c0 | ||
|
|
3117bc16a5 | ||
|
|
717b04306a | ||
|
|
271220c542 | ||
|
|
566a874141 | ||
|
|
967866d4df | ||
|
|
1de3e99bc5 | ||
|
|
3e13004b6b | ||
|
|
2f03ce67d6 | ||
|
|
b9232d45eb | ||
|
|
6087ef2a84 | ||
|
|
1f1d368ad5 | ||
|
|
dd18526e5b | ||
|
|
4d53c4dd46 | ||
|
|
9e4a8d29b5 | ||
|
|
ef20efcbb6 | ||
|
|
c70e07d9ac | ||
|
|
b7d4d28bb3 | ||
|
|
9a6ed83f2c | ||
|
|
fd84673e54 | ||
|
|
57b12568e6 | ||
|
|
f9a9f54720 | ||
|
|
3019a9bafd | ||
|
|
278e3d4f6e | ||
|
|
9b9dd06894 | ||
|
|
1f7e29b99c | ||
|
|
c2f0e6e5e3 | ||
|
|
c2b11ba017 | ||
|
|
f75a53e71b | ||
|
|
054abde25f | ||
|
|
24cecf1365 | ||
|
|
821ff7f49a | ||
|
|
ff3d3c32d5 | ||
|
|
3b2ef5b11c | ||
|
|
0394e34a69 | ||
|
|
56efa56474 | ||
|
|
ed7e79553e | ||
|
|
dec71e94f3 | ||
|
|
ac4f91a5ee | ||
|
|
e957626347 | ||
|
|
b4875de45c | ||
|
|
2cfe44eee4 | ||
|
|
fad3dc421c | ||
|
|
22907b6bd9 | ||
|
|
3485ae8321 | ||
|
|
ca62acc3ca | ||
|
|
cdf236aaf5 | ||
|
|
9f2e3c3f52 | ||
|
|
ee1d11c495 | ||
|
|
669e76717c | ||
|
|
4e107712f3 | ||
|
|
85aa57a7dd | ||
|
|
58a14ed950 | ||
|
|
165e6d446c | ||
|
|
1c3e3679ef | ||
|
|
8a513e55b0 | ||
|
|
a314f7c155 | ||
|
|
9497b0d4e9 | ||
|
|
b694f8a245 | ||
|
|
afc65a5acf | ||
|
|
5f40615cd5 | ||
|
|
c6816b9444 | ||
|
|
46e99b09b9 | ||
|
|
af436313a0 | ||
|
|
d64e6f42b4 | ||
|
|
a00628b335 | ||
|
|
33ab4ad879 | ||
|
|
99eb41b25f | ||
|
|
e86ae6bc1f | ||
|
|
c3cbcfb8ef | ||
|
|
a1d23b5314 | ||
|
|
d4d4890d4e | ||
|
|
30e66e53de | ||
|
|
e224331729 | ||
|
|
70b54e4e43 | ||
|
|
9ba463435b | ||
|
|
05ee48661c | ||
|
|
aef9882581 | ||
|
|
78bcddcc6a | ||
|
|
68e169ab4d | ||
|
|
f62eaa24f1 | ||
|
|
d3e553b4bd | ||
|
|
3753975f48 | ||
|
|
2d81114b23 | ||
|
|
472135e0bc | ||
|
|
c60b7056b2 | ||
|
|
42ccb4c091 | ||
|
|
b31c92edcc | ||
|
|
08b018304f | ||
|
|
d19320fdf6 | ||
|
|
860236bf90 | ||
|
|
4d3abf1360 | ||
|
|
305666bf59 | ||
|
|
b03c719f04 | ||
|
|
62f27e3c02 | ||
|
|
4dc67d5e30 | ||
|
|
8ebdc9724e | ||
|
|
9e0582f9bf | ||
|
|
705de51a73 | ||
|
|
1a8e5c97eb | ||
|
|
55bb7fff14 | ||
|
|
662bdcd4ac | ||
|
|
fef101a548 | ||
|
|
18a11cfd48 | ||
|
|
0f80c3e886 | ||
|
|
f122383179 | ||
|
|
e6bc6f4232 | ||
|
|
ac1cb9380d | ||
|
|
40df65fdb4 | ||
|
|
cb2e1f18c2 | ||
|
|
0ecd03e396 | ||
|
|
e6f5ac116b | ||
|
|
051182cb75 | ||
|
|
574c250093 | ||
|
|
8dad7fc6ea | ||
|
|
b558728875 | ||
|
|
e777afad6f | ||
|
|
87703a1b1f | ||
|
|
981b202661 | ||
|
|
13725744fd | ||
|
|
363c3ece3a | ||
|
|
47780ddfef | ||
|
|
251f22b5d7 | ||
|
|
4e0fcd85ae | ||
|
|
59faec8b8b | ||
|
|
32cbfe7b17 | ||
|
|
f08ca43472 | ||
|
|
8eb6cf784b | ||
|
|
7433d73adc | ||
|
|
3221f451a0 | ||
|
|
9e4536748d | ||
|
|
ea67c71505 | ||
|
|
ea38b5af72 | ||
|
|
89d19eedef | ||
|
|
41b5b5e756 | ||
|
|
a3e1363aaa | ||
|
|
2217b30adf | ||
|
|
9ac2395bf0 | ||
|
|
9e2409ab22 | ||
|
|
8e6cf5d189 | ||
|
|
d17190df44 | ||
|
|
fbe5eeb831 | ||
|
|
ed9d969c4c | ||
|
|
7f2a1f651e | ||
|
|
bbbb44ee0f | ||
|
|
29fbd1eea6 | ||
|
|
33f839b319 | ||
|
|
bc83274ad6 | ||
|
|
38e3910b6f | ||
|
|
c26c51a7ee | ||
|
|
e9973668a4 | ||
|
|
4104c3bf52 | ||
|
|
b7c2481933 | ||
|
|
cfb691ac9a | ||
|
|
cb8240a291 | ||
|
|
352963ddc3 | ||
|
|
8c57732324 | ||
|
|
8a33c406b3 | ||
|
|
340bd68f59 | ||
|
|
8237f9305b | ||
|
|
5b1c1eefda | ||
|
|
6258626751 | ||
|
|
87fd439059 | ||
|
|
564ef546a9 | ||
|
|
94dcbf8367 | ||
|
|
1bad11c759 | ||
|
|
ba679d5194 | ||
|
|
e1ad7fe63d | ||
|
|
f18d87b6ed | ||
|
|
a6c15e9a38 | ||
|
|
64bba1465b | ||
|
|
638e106568 | ||
|
|
34e18ecd61 | ||
|
|
d4021b6d9b | ||
|
|
40b1393880 | ||
|
|
30688bf11b | ||
|
|
a7d7a805dc | ||
|
|
4a239e98f6 | ||
|
|
7b97c38898 | ||
|
|
1f35babc6b | ||
|
|
80ffc3de12 | ||
|
|
507b61d5a6 | ||
|
|
8db3106e0b | ||
|
|
1b1fef20b3 | ||
|
|
22c7c5fb0b | ||
|
|
13d00101e8 | ||
|
|
3e7934a5fb | ||
|
|
815193e89e | ||
|
|
4fd4b3d667 | ||
|
|
1526b8b17d | ||
|
|
732537212b | ||
|
|
4adbb5f246 | ||
|
|
30fa772457 | ||
|
|
ee03617b3d | ||
|
|
19cb6106d2 | ||
|
|
cd6bececc1 | ||
|
|
88b93c6159 | ||
|
|
b62fd39392 | ||
|
|
95306d9d50 | ||
|
|
3e870a6444 | ||
|
|
bf26aa2219 | ||
|
|
9981c27ef1 | ||
|
|
fe96018750 | ||
|
|
07c6ae7de8 | ||
|
|
e163683020 | ||
|
|
961103049b | ||
|
|
0254bd46ec | ||
|
|
8b806ed347 | ||
|
|
8e3ead09a3 | ||
|
|
8715db2cab | ||
|
|
50839b4bb0 | ||
|
|
e1f40891c7 | ||
|
|
042f470ef9 | ||
|
|
40cc28516d | ||
|
|
8174bc3506 | ||
|
|
9118a09c77 | ||
|
|
8324bd5c21 | ||
|
|
7f37167da5 | ||
|
|
227a9c41c1 | ||
|
|
6c3862fae3 | ||
|
|
1eec003a80 | ||
|
|
684d7582b6 | ||
|
|
f39b2060fe | ||
|
|
4f2ba7e056 | ||
|
|
1dcf3b4345 | ||
|
|
aa57d14ae7 | ||
|
|
3c54d8a3ad | ||
|
|
c0814b813f | ||
|
|
088aff1a48 | ||
|
|
d6707171e6 | ||
|
|
5c5e159892 | ||
|
|
6d7b3d52dc | ||
|
|
591b908fbf | ||
|
|
742be97ce4 | ||
|
|
1f30a674cd | ||
|
|
19bc826d8b | ||
|
|
c786a7aec5 | ||
|
|
8a8356b7db | ||
|
|
0d67e00af8 | ||
|
|
7448177753 | ||
|
|
90d151f423 | ||
|
|
9f7c5dabf8 | ||
|
|
a85a151430 | ||
|
|
5dd97ab999 | ||
|
|
8daa9925cc | ||
|
|
e844be4e7b | ||
|
|
88b218fa5c | ||
|
|
e66d70e34c | ||
|
|
9361f83933 | ||
|
|
3b2bebbf90 | ||
|
|
4f90eb433a | ||
|
|
b485e0c16c | ||
|
|
bc1fac9648 | ||
|
|
c78779cce3 | ||
|
|
702cd15cb0 | ||
|
|
1da05366ad | ||
|
|
2267efeac5 | ||
|
|
15954da08f | ||
|
|
b2dc7bad39 | ||
|
|
d4e0196346 | ||
|
|
2fc50f5a98 | ||
|
|
bd5b85dbc7 | ||
|
|
8a8324657e | ||
|
|
4bb0af79b7 | ||
|
|
e3bcd89319 | ||
|
|
87383697e8 | ||
|
|
e4b808989e | ||
|
|
59e52bf276 | ||
|
|
9b40e44ef4 | ||
|
|
e92f21d2f7 | ||
|
|
910e89b963 | ||
|
|
8a9cfb2459 | ||
|
|
41961db0bd | ||
|
|
e76518843d | ||
|
|
ef74f5d626 | ||
|
|
c557eb8cec | ||
|
|
0cc279e0d3 | ||
|
|
0cfdf22655 | ||
|
|
527a010f10 | ||
|
|
c8ca974634 | ||
|
|
3296f91bb0 | ||
|
|
e2124620eb | ||
|
|
69864a5ccf | ||
|
|
5b4e1f318d | ||
|
|
b78296cb0b | ||
|
|
06a1dbad61 | ||
|
|
93c31c1a6d | ||
|
|
a8ed495833 | ||
|
|
4a14ed068c | ||
|
|
dc0f24976d | ||
|
|
1e7098b5e3 | ||
|
|
2f24fb18c4 | ||
|
|
96a8ca6d98 | ||
|
|
37a5644576 | ||
|
|
a1cbe76e2c | ||
|
|
98bf61c80e | ||
|
|
01f439ec6e | ||
|
|
acc461c7da | ||
|
|
1585958497 | ||
|
|
7cacd47edd | ||
|
|
e461b9bed4 | ||
|
|
3723c04850 | ||
|
|
73273075c8 | ||
|
|
8e85be0a16 | ||
|
|
37802f40dc | ||
|
|
06b96ffa86 | ||
|
|
c4ed1487f9 | ||
|
|
e64ae6d766 | ||
|
|
5b4837552b | ||
|
|
d2004814f0 | ||
|
|
bf0c5bec45 | ||
|
|
0dd046d36f | ||
|
|
4f5b0756df | ||
|
|
fe1c19dcdf | ||
|
|
24b2096e86 | ||
|
|
86e97e178d | ||
|
|
905d906d69 | ||
|
|
abce74bb93 | ||
|
|
f5db099330 | ||
|
|
122d1771db | ||
|
|
8824e2cee4 | ||
|
|
8a6f3fead8 | ||
|
|
9c71f56a25 | ||
|
|
f924946eba | ||
|
|
32a5edf43f | ||
|
|
9a338344da | ||
|
|
df337831dc | ||
|
|
bb558f6791 | ||
|
|
22558cdd7e | ||
|
|
28c54e81c1 | ||
|
|
0dfffb88e1 | ||
|
|
ed243f8c29 | ||
|
|
a427e8938a | ||
|
|
cc25d29132 | ||
|
|
134f43385b | ||
|
|
a5a264842e | ||
|
|
eed47b6b9c | ||
|
|
3841a04e88 | ||
|
|
9eef8f0b73 | ||
|
|
c258230722 | ||
|
|
345e0988cb | ||
|
|
3671987f4d | ||
|
|
5aa7b20a3e | ||
|
|
68795c640b | ||
|
|
4f1f94d1de | ||
|
|
0f7e31f7d7 | ||
|
|
2f3cad893b | ||
|
|
e79666267d | ||
|
|
d91de04671 | ||
|
|
64b761c19a | ||
|
|
a1ac8edd66 | ||
|
|
1dca857b5b | ||
|
|
f8cd88dbd1 | ||
|
|
71903f601a | ||
|
|
719bc858b5 | ||
|
|
a6126d678b | ||
|
|
4875d6b64d | ||
|
|
54b4059856 | ||
|
|
38059f8e8e | ||
|
|
bb5f4e7285 | ||
|
|
448797a1e6 | ||
|
|
a261103ce0 | ||
|
|
7b82b5adb3 | ||
|
|
397a344364 | ||
|
|
bafa48759f | ||
|
|
46db185081 | ||
|
|
1412da7c32 | ||
|
|
d09e800a0e | ||
|
|
53b417e414 | ||
|
|
57dee64e82 | ||
|
|
fdc795015f | ||
|
|
3a5e9224d0 | ||
|
|
ebfd1a1cf7 | ||
|
|
dd667c2301 | ||
|
|
d727f0ff48 | ||
|
|
eb9b2e53c8 | ||
|
|
b6f06b8e8b | ||
|
|
0a68f869d7 | ||
|
|
3b2461cf2e | ||
|
|
346402ddbf | ||
|
|
44d60d5f83 | ||
|
|
f2ae9e8583 | ||
|
|
7c8e23bd9f | ||
|
|
0752721dc3 | ||
|
|
68a94ac30f | ||
|
|
ee3751c8d7 | ||
|
|
ec33e0e6bd | ||
|
|
31937d363b | ||
|
|
8982a89b24 | ||
|
|
0492fdfb2e | ||
|
|
14698a3a1a | ||
|
|
8c2ffaf095 | ||
|
|
afd72c78bd | ||
|
|
6bf822649b | ||
|
|
67dde16163 | ||
|
|
f1d5ba4005 | ||
|
|
794b0a037f | ||
|
|
c32edbe02e | ||
|
|
f3c3ed44e6 | ||
|
|
f805730493 | ||
|
|
2b1366635d | ||
|
|
42f23f479d | ||
|
|
62bf783f06 | ||
|
|
0b2901b72d | ||
|
|
faa82484a5 | ||
|
|
4ccfd96cfe | ||
|
|
408aa7b24c | ||
|
|
776b9d1c00 | ||
|
|
c93fad5ee0 | ||
|
|
19b2a5d9fd | ||
|
|
f1773e09ab | ||
|
|
462c51d9a1 | ||
|
|
2430e98412 | ||
|
|
78fc60cd29 | ||
|
|
864146de58 | ||
|
|
45478cc79b | ||
|
|
5454d22ad8 | ||
|
|
dc1488ae47 | ||
|
|
0121a8ecad | ||
|
|
7bc90b3066 | ||
|
|
bf39270e0c | ||
|
|
211bc43b6e | ||
|
|
91c5833bd0 | ||
|
|
8311f1c11e | ||
|
|
ae2836325f | ||
|
|
a897af2cde | ||
|
|
cc80022e84 | ||
|
|
5a016db9b6 | ||
|
|
92e1aeede7 | ||
|
|
f846a9bfe9 | ||
|
|
3db859e8b5 | ||
|
|
0eeb1cf83a | ||
|
|
5f238db203 | ||
|
|
422696201a | ||
|
|
58fef0ac38 | ||
|
|
25e1181466 | ||
|
|
5b5f7e3b59 | ||
|
|
dc3afaf6aa | ||
|
|
1164f67827 | ||
|
|
c83a2c8ec5 | ||
|
|
43d0f38b24 | ||
|
|
e95538ca2c | ||
|
|
25ff04417e | ||
|
|
63ecee4d1a | ||
|
|
4c8f6b6a06 | ||
|
|
2161111900 | ||
|
|
24b0922b0e | ||
|
|
186387301f | ||
|
|
1bd9db74ba | ||
|
|
df6933406f | ||
|
|
d679c8390a | ||
|
|
d4daa7b68c | ||
|
|
44d98d6166 | ||
|
|
b3708acf27 | ||
|
|
2c0fa6c5df | ||
|
|
57f74bd1c2 | ||
|
|
598c409e63 | ||
|
|
c6eb7fad68 | ||
|
|
c561edaa72 | ||
|
|
031fa9ad4d | ||
|
|
d622d4bf30 | ||
|
|
e32db5c9aa | ||
|
|
4a6c209a13 | ||
|
|
0d2aa5d9d7 | ||
|
|
e30b1fb8fd | ||
|
|
da1b6eeaf2 | ||
|
|
01b835c237 | ||
|
|
48e1c8c69d | ||
|
|
f06e708282 | ||
|
|
f0f7e760ae | ||
|
|
31b4d25d10 | ||
|
|
d41988232e | ||
|
|
880570f228 | ||
|
|
72a90c750a | ||
|
|
e1988bc744 | ||
|
|
d6a3e37b83 | ||
|
|
8261047b1e | ||
|
|
417b59997f | ||
|
|
4366d2c428 | ||
|
|
217cc3b045 | ||
|
|
757e0a5445 | ||
|
|
ddf6410130 | ||
|
|
7842418b7b | ||
|
|
9624b86426 | ||
|
|
201a2fe5ff | ||
|
|
ed032a88b8 | ||
|
|
ae76a74043 | ||
|
|
3359acb8cb | ||
|
|
a2b371cd52 | ||
|
|
dd69b3976a | ||
|
|
16e5de84da | ||
|
|
46fa602530 | ||
|
|
aa4d3b4cc0 | ||
|
|
73ed23495e | ||
|
|
c7d970f782 | ||
|
|
6dfd07d025 | ||
|
|
e7bf7c0161 | ||
|
|
f5a7b9e716 | ||
|
|
b951e023ec | ||
|
|
3ea9bbd632 | ||
|
|
aaca3daa27 | ||
|
|
a51b316824 | ||
|
|
928a00c474 | ||
|
|
fa13f396d5 | ||
|
|
3ab56a20ee | ||
|
|
649f874292 | ||
|
|
90fdd89a0b | ||
|
|
54e66f1d59 | ||
|
|
82471e68a8 | ||
|
|
20fb7b9175 | ||
|
|
859fdaad45 | ||
|
|
09ed309996 | ||
|
|
65e4cda059 | ||
|
|
7e037c4226 | ||
|
|
f636c38440 | ||
|
|
b98f040ef2 | ||
|
|
e57211c544 | ||
|
|
48a1ff0d45 | ||
|
|
032dcf74b0 | ||
|
|
51d4839861 | ||
|
|
9f125ea7c1 | ||
|
|
9bcb25958d | ||
|
|
866925bfb7 | ||
|
|
f8b3c05311 | ||
|
|
353f272434 | ||
|
|
3d54c6ec46 | ||
|
|
71e27c463d | ||
|
|
8c48382049 | ||
|
|
11781089d1 | ||
|
|
d97fd43a72 | ||
|
|
f5ea4b3b39 | ||
|
|
f227ffe4b9 | ||
|
|
027428eb1d | ||
|
|
15778afbdc | ||
|
|
d06f63287e | ||
|
|
1490812ab2 | ||
|
|
707415d4fc | ||
|
|
9cea6ef1b6 | ||
|
|
48ea74bf01 | ||
|
|
026deaf759 | ||
|
|
4c59971194 | ||
|
|
fd8571c2c9 | ||
|
|
dd096ae080 | ||
|
|
eb1accaa91 | ||
|
|
7e38410e47 | ||
|
|
d336388403 | ||
|
|
c207d7ec62 | ||
|
|
018b28328c | ||
|
|
0957a7463e | ||
|
|
c72f5bd9c4 | ||
|
|
0f57446da7 | ||
|
|
3a90ea0acd | ||
|
|
58af2f958c | ||
|
|
a8fd4161bb | ||
|
|
53f8519a38 | ||
|
|
eb162f3b0a | ||
|
|
4ce838e1f1 | ||
|
|
a36ffd3910 | ||
|
|
17b5b32f75 | ||
|
|
9b919d590a | ||
|
|
80264051d8 | ||
|
|
188fed9570 | ||
|
|
eae7165c79 | ||
|
|
54281fe733 | ||
|
|
2b2ea368aa | ||
|
|
67a28eb256 | ||
|
|
f5d96a6f80 | ||
|
|
44ac015598 | ||
|
|
89a9c0545e | ||
|
|
3b26bba0c4 | ||
|
|
2be2fb3ed3 | ||
|
|
e341588a8a | ||
|
|
c56595d749 | ||
|
|
ce0b384fa6 | ||
|
|
dfd7d541b0 | ||
|
|
ded4daf049 | ||
|
|
361428213b | ||
|
|
12a79db2f6 | ||
|
|
e8b155a3be | ||
|
|
716b46c550 | ||
|
|
9d954dca8c | ||
|
|
7162c65df7 | ||
|
|
bd9fca4708 | ||
|
|
14d496cc8b | ||
|
|
106a8ad918 | ||
|
|
44a82a175d | ||
|
|
99248631aa | ||
|
|
2836ee9b02 | ||
|
|
d82773ffe9 | ||
|
|
ec626b3f0e | ||
|
|
997d9ea67f | ||
|
|
aec6b9f86f | ||
|
|
d45898df80 | ||
|
|
b0da4b23a0 | ||
|
|
bf18b7ca67 | ||
|
|
cc17fbfe7d | ||
|
|
fa170b2e5a | ||
|
|
c61ba345f2 | ||
|
|
ae09fb1f91 | ||
|
|
70a2c84cd2 | ||
|
|
21524e3083 | ||
|
|
fbe2aba2e7 | ||
|
|
a41a1e8718 | ||
|
|
051547603a | ||
|
|
80a25bb880 | ||
|
|
0301b334c7 | ||
|
|
1492b4b2b2 | ||
|
|
5b7bcac260 | ||
|
|
7fcbf9e43e | ||
|
|
6c495e0da4 | ||
|
|
a06b419d42 | ||
|
|
a255c592e8 | ||
|
|
7aac6604c4 | ||
|
|
deb5bf1dff | ||
|
|
3dfe6e97a7 | ||
|
|
43bab4035b | ||
|
|
ef0c03ff70 | ||
|
|
ad54dcc827 | ||
|
|
c0ab28d1d9 | ||
|
|
5b2f48da27 | ||
|
|
132fcf36b2 | ||
|
|
4571df58c6 | ||
|
|
f6b384d41f | ||
|
|
c259892c3a | ||
|
|
b471329591 | ||
|
|
3add5835db | ||
|
|
cf510ad2c5 | ||
|
|
696a8d6191 | ||
|
|
01f8a1155f | ||
|
|
986aaaaa4b | ||
|
|
c96ee2310d | ||
|
|
76cb2a3a4f | ||
|
|
9bef934c76 | ||
|
|
85f14172dc | ||
|
|
4539c0d79f | ||
|
|
c3131af90a | ||
|
|
c2c14fa26e | ||
|
|
e49f61f5fc | ||
|
|
22f5bd5e35 | ||
|
|
7a1b73b983 | ||
|
|
0c56b1add7 | ||
|
|
1e60969646 | ||
|
|
ee29752217 | ||
|
|
e012f858d6 | ||
|
|
c3fad2e227 | ||
|
|
b7e8628c4b | ||
|
|
e4977b0b9f | ||
|
|
b127c1dc58 | ||
|
|
07bff66fb5 | ||
|
|
4a888ae6d4 | ||
|
|
a0a33ee506 | ||
|
|
98f8c9a5e5 | ||
|
|
1f69bec480 | ||
|
|
8f1b4f3642 | ||
|
|
ca39ebf9fb | ||
|
|
9fb0844100 | ||
|
|
bdf278f7a5 | ||
|
|
c8f2f8572f | ||
|
|
5d54f33962 | ||
|
|
ba449e444b | ||
|
|
87ba7282f6 | ||
|
|
7d1bfaf7be | ||
|
|
7d5acf1d44 | ||
|
|
3610c4583a | ||
|
|
41cfde6be3 | ||
|
|
34bde8d54a | ||
|
|
1ed55e3e3e | ||
|
|
f80a8520e8 | ||
|
|
740bab942d | ||
|
|
08b1b4860f | ||
|
|
18ea5dc0d7 | ||
|
|
3ac7f5d4c1 | ||
|
|
ad71500818 | ||
|
|
b2ad840a6b | ||
|
|
8db7cc2cff | ||
|
|
ac1541f4b7 | ||
|
|
09e2bbce8a | ||
|
|
73496a36a1 | ||
|
|
8303cc1021 | ||
|
|
ab759cd27b | ||
|
|
64444de582 | ||
|
|
e425fbe85d | ||
|
|
4f4b2f0927 | ||
|
|
da6eb9d123 | ||
|
|
1b15e07e99 | ||
|
|
e49d720081 | ||
|
|
3267d6a9ce | ||
|
|
3ba2c330e1 | ||
|
|
618c8a73db | ||
|
|
aa0ea373cd | ||
|
|
6c3fda83ba | ||
|
|
a3571c6cce | ||
|
|
6fcedb7dbe | ||
|
|
18882701d2 | ||
|
|
30c041f9ad | ||
|
|
be7cf82299 | ||
|
|
fde045cd77 | ||
|
|
183150b741 | ||
|
|
a2570930e8 | ||
|
|
fdb6716c0f | ||
|
|
a20a88d235 | ||
|
|
48d3ff94c9 | ||
|
|
a33857da09 | ||
|
|
13791b1eeb | ||
|
|
9a5e37fca8 | ||
|
|
3e976df0fb | ||
|
|
42afed9c1a | ||
|
|
37c36e2692 | ||
|
|
7fbc7031f4 | ||
|
|
9f004a9ea9 | ||
|
|
23f4587f2b | ||
|
|
4d8f5b0ae7 | ||
|
|
89389a29ef | ||
|
|
29fe3961ab | ||
|
|
4e8a085ac9 | ||
|
|
fb22c2774d | ||
|
|
7d059d4c37 | ||
|
|
9715c5899a | ||
|
|
cc07f21211 | ||
|
|
b4d1e854ef | ||
|
|
075aa18fd4 | ||
|
|
e0204f5621 | ||
|
|
a9ac4411e5 | ||
|
|
50b31539c2 | ||
|
|
56194bcd95 | ||
|
|
eb8ffa9040 | ||
|
|
a7a1cc2c75 | ||
|
|
ab217f7ffa | ||
|
|
a20c9893e4 | ||
|
|
3bb400ca14 | ||
|
|
cd6aa5b5c0 | ||
|
|
dc55d7bdab | ||
|
|
8b115ac8dc | ||
|
|
c94e4afbfa | ||
|
|
6566d205e2 | ||
|
|
e484f0cc04 | ||
|
|
bd397b8cba | ||
|
|
f8c8ef9eac | ||
|
|
72c19bb3de | ||
|
|
89f7eff382 | ||
|
|
b90a6d9ff6 | ||
|
|
584ba4ebae | ||
|
|
ba3db4795e | ||
|
|
59d73bf3d2 | ||
|
|
919ca3a3cc | ||
|
|
5886edfac2 | ||
|
|
d414962af4 | ||
|
|
8fb7db245a | ||
|
|
6f0fc27e33 | ||
|
|
9c54ad58f8 | ||
|
|
f55c2dfc03 | ||
|
|
675ef1aa3a | ||
|
|
ef57235623 | ||
|
|
d66d07e883 | ||
|
|
b92693daba | ||
|
|
58b1999e08 | ||
|
|
8e5f029e02 | ||
|
|
2d41264e9e | ||
|
|
82c6be7edf | ||
|
|
0219d4dfba | ||
|
|
391516da51 | ||
|
|
1d6b8f9ad2 | ||
|
|
10796f4b6e | ||
|
|
33ffd7c37d | ||
|
|
21d1e929a0 | ||
|
|
d0bc3520de | ||
|
|
9f18657889 | ||
|
|
c16d69b292 | ||
|
|
ebeacb36fb | ||
|
|
6558854dbe | ||
|
|
7d9d5d9478 | ||
|
|
630f548ff4 | ||
|
|
100b62bb69 | ||
|
|
e012b94f21 | ||
|
|
3104620cf0 | ||
|
|
ebdd24d6d0 | ||
|
|
7cd72c79ec | ||
|
|
84a6379565 | ||
|
|
0a5f12720e | ||
|
|
73f7af0e88 | ||
|
|
e5a96f0f54 | ||
|
|
d73e7f6edd | ||
|
|
61542c41de | ||
|
|
bd1a581bee | ||
|
|
6e8a1782ab | ||
|
|
96d910c770 | ||
|
|
7560c17adc | ||
|
|
9cd339eb39 | ||
|
|
f310029387 | ||
|
|
3ed8eb3f9c | ||
|
|
007351494d | ||
|
|
6dcb93208d | ||
|
|
84e1a698bf | ||
|
|
0d7638eafd | ||
|
|
86e2f445f7 | ||
|
|
093e816c37 | ||
|
|
1cb0a3edc6 | ||
|
|
06a5054273 | ||
|
|
acd0299243 | ||
|
|
dca68b0aad | ||
|
|
c3ea09906d | ||
|
|
bf4679e8a0 | ||
|
|
c4054610c8 | ||
|
|
f6c0d3d70b | ||
|
|
ef855d198e | ||
|
|
81b07870c8 | ||
|
|
bb6721dce6 | ||
|
|
446a2987cd | ||
|
|
4de2a17409 | ||
|
|
99d24f77ed | ||
|
|
c0422cea9f | ||
|
|
8b6ad0193d | ||
|
|
33eff8bfd6 | ||
|
|
65af3dab03 | ||
|
|
065a605270 | ||
|
|
a7260c4037 | ||
|
|
44cad59f2b | ||
|
|
c52461f911 | ||
|
|
7f459268d9 | ||
|
|
9eeb3b9c88 | ||
|
|
d1b31da71e | ||
|
|
89e540e638 | ||
|
|
fab65a5bc2 | ||
|
|
e7d13fe532 | ||
|
|
ecc81fce17 | ||
|
|
b4afd23c30 | ||
|
|
af1a3f9b6e | ||
|
|
820b6c9aa0 | ||
|
|
3cb22c204c | ||
|
|
7432ccf4ed | ||
|
|
6a48e792c1 | ||
|
|
9459290ae7 | ||
|
|
741d654495 | ||
|
|
d3e182af09 | ||
|
|
d9b4d267c7 | ||
|
|
58c5c24555 | ||
|
|
341c9a137f | ||
|
|
871446fc98 | ||
|
|
0abda1b176 | ||
|
|
394bcdb5e3 | ||
|
|
28deecca55 | ||
|
|
4db88e5b8f | ||
|
|
75b243a51d | ||
|
|
9bccfc429c | ||
|
|
077e59b769 | ||
|
|
007e3c0e9a | ||
|
|
e2bc412669 | ||
|
|
e344209582 | ||
|
|
e76ca1458c | ||
|
|
16cc9ca2c9 | ||
|
|
8c90957ff5 | ||
|
|
c0d8e84c9d | ||
|
|
b0ad542928 | ||
|
|
727b35f665 | ||
|
|
aa4343211f | ||
|
|
3611989355 | ||
|
|
3381b77d71 | ||
|
|
dce70db374 | ||
|
|
2adbcdc7ea | ||
|
|
7e5fa372cf | ||
|
|
6e45e1dd86 | ||
|
|
7f290d5c82 | ||
|
|
b6609cafae | ||
|
|
efa95a1842 | ||
|
|
51bd4f0f3a | ||
|
|
562b61695e | ||
|
|
98f51bfb56 | ||
|
|
73f0ce69e7 | ||
|
|
cf338ab1be | ||
|
|
66a9dc9639 | ||
|
|
8ed9d849dc | ||
|
|
5ebab6c10c | ||
|
|
e7a69008e6 | ||
|
|
73e015683c | ||
|
|
b462781fd0 | ||
|
|
93095cbe99 | ||
|
|
399371e7b5 | ||
|
|
d7142e2328 | ||
|
|
1f75bb1066 | ||
|
|
088adfacc1 | ||
|
|
da3478b2a7 | ||
|
|
5126ed1ef0 | ||
|
|
61fb21ad28 | ||
|
|
a3221d2ac1 | ||
|
|
2c713fcdfa | ||
|
|
afd8bdb907 | ||
|
|
efd5ee5786 | ||
|
|
510b4cd4d5 | ||
|
|
de584c658c | ||
|
|
6eb770bbcc | ||
|
|
c7e11bfdc0 | ||
|
|
94327ff0c2 | ||
|
|
4602eafa87 | ||
|
|
bb3edc3b47 | ||
|
|
c769702fe5 | ||
|
|
dbbab0c4d2 | ||
|
|
9b3318b0df | ||
|
|
0fac7fe8b8 | ||
|
|
b9f592fbf5 | ||
|
|
c7b1a56b3d | ||
|
|
3896bca4d8 | ||
|
|
9774cc3344 | ||
|
|
d3979b025d | ||
|
|
01966df4f7 | ||
|
|
f38bd4a072 | ||
|
|
b1df18d76f | ||
|
|
7daccb8e72 | ||
|
|
bb91a624f1 | ||
|
|
a04d77bcbc | ||
|
|
25bd99451c | ||
|
|
ed43d0a76d | ||
|
|
066a844c4e | ||
|
|
5e252dea4b | ||
|
|
d2a918b454 | ||
|
|
da38e779ea | ||
|
|
8186ae6bc0 | ||
|
|
e1f67417d7 | ||
|
|
fd322eef82 | ||
|
|
d3a4375f78 | ||
|
|
78112d305b | ||
|
|
f7c3ee9932 | ||
|
|
e7a392c77c | ||
|
|
887e553f05 | ||
|
|
beb227ddf1 | ||
|
|
84acca07ae | ||
|
|
cc1e997dcd | ||
|
|
a7026ba90a | ||
|
|
3a69fad0f6 | ||
|
|
40564811ee | ||
|
|
dcd08dc51c | ||
|
|
fdf57ede8c | ||
|
|
bd717af8ab | ||
|
|
c54f5170bf | ||
|
|
eae4e1f9f0 | ||
|
|
9c513d678d | ||
|
|
d16c245fc4 | ||
|
|
ec8290c897 | ||
|
|
b293a7f62c | ||
|
|
d67c8bdfc3 | ||
|
|
e2ccd3578c | ||
|
|
4e834af140 | ||
|
|
7e5614383d | ||
|
|
eb84a83b47 | ||
|
|
2c2898a388 | ||
|
|
1732b6c037 | ||
|
|
314f459161 | ||
|
|
83926d3cae | ||
|
|
6218c7bf42 | ||
|
|
566fce3237 | ||
|
|
373ef16010 | ||
|
|
ea76e76104 | ||
|
|
9fd62d1588 | ||
|
|
b7061c82b4 | ||
|
|
6fb812f747 | ||
|
|
40e8d11e64 | ||
|
|
73042aae5b | ||
|
|
e5ce3bcf2c | ||
|
|
c399d22a19 | ||
|
|
1ea087a794 | ||
|
|
00bdf89977 | ||
|
|
0bb4d17634 | ||
|
|
f9c6b3e7d6 | ||
|
|
9e5a5ddb4c | ||
|
|
8c0d6a8432 | ||
|
|
553f93758a | ||
|
|
a4a7e64c19 | ||
|
|
22832c30a0 | ||
|
|
1a21666286 | ||
|
|
4033b80b51 | ||
|
|
99218d821b | ||
|
|
e626b29e10 | ||
|
|
f89b936801 | ||
|
|
17f59e818d | ||
|
|
b5bd5542eb | ||
|
|
2e94e70e2b | ||
|
|
4e1f385711 | ||
|
|
716e73d483 | ||
|
|
5b36173d11 | ||
|
|
b2ef4f6134 | ||
|
|
c7be6dec11 | ||
|
|
bd1574b208 | ||
|
|
f376e67420 | ||
|
|
ef0bc0abff | ||
|
|
71e586304b | ||
|
|
3c74c3a358 | ||
|
|
edad5898f2 | ||
|
|
fa0c1939ed | ||
|
|
9a5ade185c | ||
|
|
f1dd0f27cb | ||
|
|
f9e5a0cde2 | ||
|
|
ead751c62b | ||
|
|
0058c58edd | ||
|
|
221ddb9456 | ||
|
|
65e2487096 | ||
|
|
0501f36390 | ||
|
|
96981b9cff | ||
|
|
f51e87f5ad | ||
|
|
cb213f1c1b | ||
|
|
c8d895de26 | ||
|
|
e51094b721 | ||
|
|
b03bded70b | ||
|
|
ee1df1ccae | ||
|
|
bc6ebcd248 | ||
|
|
ba582f753a | ||
|
|
cbd85b472e | ||
|
|
7a92ded39a | ||
|
|
831f05df51 | ||
|
|
0d94a6a66c | ||
|
|
3e35c34b6b | ||
|
|
03a9ca0a97 | ||
|
|
6f481bb0e0 | ||
|
|
f98cc5685d | ||
|
|
9135621ff9 | ||
|
|
8624daa7f8 | ||
|
|
3051c46dc3 | ||
|
|
e920830ec5 | ||
|
|
7892e5ac77 | ||
|
|
b0e9bafc78 | ||
|
|
44aa070770 | ||
|
|
97f9dcae6a | ||
|
|
8cbf495a57 | ||
|
|
c1b29492c5 | ||
|
|
669a31924e | ||
|
|
5e972dcf34 | ||
|
|
8fcdc444df | ||
|
|
619d21ffc9 | ||
|
|
d62bcc17f3 | ||
|
|
982e05bbd5 | ||
|
|
a3c8b36863 | ||
|
|
630e3c408b | ||
|
|
1082b52bd4 | ||
|
|
914f3066bb | ||
|
|
de91e75724 | ||
|
|
384431886a | ||
|
|
82b302d928 | ||
|
|
4ecc9e6b64 | ||
|
|
55e50d890b | ||
|
|
6e86c951d7 | ||
|
|
c41b52c487 | ||
|
|
5c6fc4a6a3 | ||
|
|
edecdad54d | ||
|
|
5291364f1d | ||
|
|
41cc97ae64 | ||
|
|
bf2b7ddfc5 | ||
|
|
eb0cbdaa90 | ||
|
|
0d0142e812 | ||
|
|
a43e21e05c | ||
|
|
4135d091a6 | ||
|
|
534407b1f4 | ||
|
|
18cc8c7ef1 | ||
|
|
58c9b4b7f6 | ||
|
|
cde719f49f | ||
|
|
38cab94d9a | ||
|
|
6ed6d7f5a8 | ||
|
|
e40a46de71 | ||
|
|
c5bf99a1c2 | ||
|
|
2c7d63c765 | ||
|
|
3dd22903ac | ||
|
|
d8d36af452 | ||
|
|
e610e50f9c | ||
|
|
935c64173f | ||
|
|
377dbd2075 | ||
|
|
93272700d2 | ||
|
|
d508258ad8 | ||
|
|
f57b2e6150 | ||
|
|
af45f9e27e | ||
|
|
4c4d61b046 | ||
|
|
7561c3e132 | ||
|
|
1514ad2a80 | ||
|
|
d8195637d4 | ||
|
|
c8d771a0fb | ||
|
|
9130776c4e | ||
|
|
9eac94a4dd | ||
|
|
6e06d2f31a | ||
|
|
6a6d21136a | ||
|
|
f28bd83346 | ||
|
|
96fb478eae | ||
|
|
8752b3fcd8 | ||
|
|
55ffed7e42 | ||
|
|
e00df64bae | ||
|
|
080ddf58ae | ||
|
|
4ce48a5bfd | ||
|
|
20bf7f847f | ||
|
|
b66d00853b | ||
|
|
8b602edda4 | ||
|
|
9f27cd8ca6 | ||
|
|
b084f9e092 | ||
|
|
4220e1098e | ||
|
|
c30468169a | ||
|
|
c0d9e8c76b | ||
|
|
90a973fe8a | ||
|
|
7f0feb4dd6 | ||
|
|
33a5432ea6 | ||
|
|
968ff560d2 | ||
|
|
cd59be1d5e | ||
|
|
8b2869c0d2 | ||
|
|
82a51ea53d | ||
|
|
20af605eba | ||
|
|
a6536635e3 | ||
|
|
adddd075eb | ||
|
|
a0c823b22b | ||
|
|
9fdb334e85 | ||
|
|
f89e890b87 | ||
|
|
1c666c3fcb | ||
|
|
2a383be0f1 | ||
|
|
ac1d2d3384 | ||
|
|
acfcfa7053 | ||
|
|
8ef81dd452 | ||
|
|
67340e9523 | ||
|
|
a7ceddae34 | ||
|
|
24e1569f8b | ||
|
|
de31639fff | ||
|
|
8b46340924 | ||
|
|
d008bcb5cd | ||
|
|
0484b5b0b7 | ||
|
|
f01b6368a5 | ||
|
|
40d38dc0be | ||
|
|
33a2361cc2 | ||
|
|
4124540d61 | ||
|
|
5f38126817 | ||
|
|
b05b3c9b48 | ||
|
|
a03a9f4efe | ||
|
|
3e55030372 | ||
|
|
273c0420d0 | ||
|
|
5774786fa5 | ||
|
|
1a9ec1fd1c | ||
|
|
b2aa573b1c | ||
|
|
63d0331991 | ||
|
|
bf6dcd1713 | ||
|
|
495723bb26 | ||
|
|
911cb0662c | ||
|
|
5387514eaf | ||
|
|
61414c83ce | ||
|
|
43a9d0e7c2 | ||
|
|
df5cd107a5 | ||
|
|
abca4eba67 | ||
|
|
96d3590a08 | ||
|
|
8429aa9e0e | ||
|
|
79d4053048 | ||
|
|
753b6b4692 | ||
|
|
f8f726449b | ||
|
|
357406ecb2 | ||
|
|
3915fd7583 | ||
|
|
9c5e91f848 | ||
|
|
af107f6c08 | ||
|
|
a3dbb20a0e | ||
|
|
a3779426b6 | ||
|
|
2f5ca63d92 | ||
|
|
0e1d98ae92 | ||
|
|
04575bcab5 | ||
|
|
71b291d71b | ||
|
|
decba3ae73 | ||
|
|
f8ed564c9f | ||
|
|
47ba39bef6 | ||
|
|
71f7051489 | ||
|
|
3c3791e8be | ||
|
|
c39d6514ab | ||
|
|
1cb6f3bf4d | ||
|
|
f09dc86ab6 | ||
|
|
f26ac1e8cb | ||
|
|
84a3efa0ab | ||
|
|
00ed4b5bf3 | ||
|
|
e2e053bbd7 | ||
|
|
f8b33ab379 | ||
|
|
5df1fcf245 | ||
|
|
b1ad6a3260 | ||
|
|
6442ccc606 | ||
|
|
b21813060c | ||
|
|
706c75307a | ||
|
|
2b284ee33d | ||
|
|
4cfa6156e3 | ||
|
|
c1e7217fcb | ||
|
|
4b2f6a7c37 | ||
|
|
a8726d2a06 | ||
|
|
b5ebe6d9c7 | ||
|
|
ef383c0d32 | ||
|
|
8dcf93356e | ||
|
|
ce5f2732e4 | ||
|
|
3e89da86df | ||
|
|
f5450e791d | ||
|
|
cb984e620e | ||
|
|
be92ac6c36 | ||
|
|
5dc6e9c9ca | ||
|
|
0b79c324ca | ||
|
|
f39b6638f6 | ||
|
|
a4b6f30579 | ||
|
|
7be73df4e7 | ||
|
|
14b61c63f0 | ||
|
|
75a64762c2 | ||
|
|
028fdddb49 | ||
|
|
f86b0f2e7b | ||
|
|
285fba0759 | ||
|
|
92b9eb978e | ||
|
|
1e82e2cea6 | ||
|
|
a7ed6ca618 | ||
|
|
b4b90120ff | ||
|
|
16f72adc49 | ||
|
|
3d06165389 | ||
|
|
fd4893155d | ||
|
|
67e78a8231 | ||
|
|
6b320e4045 | ||
|
|
7e5cb90983 | ||
|
|
8120a98f47 | ||
|
|
8f3f8eec08 | ||
|
|
386b93dc60 | ||
|
|
b3bc31102c | ||
|
|
0f1aa0d3e5 | ||
|
|
7a08ae31d2 | ||
|
|
304f127f56 | ||
|
|
c338460d66 | ||
|
|
48d704af52 | ||
|
|
ac7aa92290 | ||
|
|
0042f81894 | ||
|
|
2c836acb37 | ||
|
|
a1d8f29a3d | ||
|
|
a174e1ed0f | ||
|
|
530adb7625 | ||
|
|
cd3fe9fb03 | ||
|
|
a8edfd53d1 | ||
|
|
dbb665180c | ||
|
|
9d78ed31a7 | ||
|
|
89afe532d7 | ||
|
|
c67d13866b | ||
|
|
3b98b08c4d | ||
|
|
9c15534511 | ||
|
|
55afbb522c | ||
|
|
27ed20f7a0 | ||
|
|
f567e9b3d7 | ||
|
|
40ae4f93a0 | ||
|
|
7a27e9b599 | ||
|
|
62c9e6b3a5 | ||
|
|
cfeed4da95 | ||
|
|
4068d8617d | ||
|
|
421c2a2448 | ||
|
|
d1e7726460 | ||
|
|
0596df00b3 | ||
|
|
417c99f637 | ||
|
|
de0e225076 | ||
|
|
e0391f8149 | ||
|
|
7de2483fbd | ||
|
|
65d6212d03 | ||
|
|
4d4df3cd2b | ||
|
|
62125b10c9 | ||
|
|
81c3a3a86e | ||
|
|
61d35e1844 | ||
|
|
15f85b1f63 | ||
|
|
5bf63a11f4 | ||
|
|
97a67bdfa9 | ||
|
|
aa0b9ca174 | ||
|
|
b96efc2f67 | ||
|
|
be20dc3448 | ||
|
|
cb869c26d9 | ||
|
|
7cf8e8d05d | ||
|
|
54fd3e5020 | ||
|
|
3e4916822d | ||
|
|
7efdcf3218 | ||
|
|
9935066b70 | ||
|
|
6c2e5b56e4 | ||
|
|
2289bf64cc | ||
|
|
b1bf649cba | ||
|
|
8ee6eb7134 | ||
|
|
f98c60bfa8 | ||
|
|
a5c1113971 | ||
|
|
736f46d1d9 | ||
|
|
a8f7e4b835 | ||
|
|
9352b0649b | ||
|
|
a85906c756 | ||
|
|
8aa81e06e6 | ||
|
|
1f9ae80a3e | ||
|
|
71020fc3aa | ||
|
|
7b74bba15e | ||
|
|
e5fbaa713a | ||
|
|
6609a9f17e | ||
|
|
5204e853e1 | ||
|
|
01363a24e2 | ||
|
|
d49def4832 | ||
|
|
4836c3eece | ||
|
|
9f7b8c3b8f | ||
|
|
ade7292aee | ||
|
|
dbd8811b85 | ||
|
|
05118158f4 | ||
|
|
1df395f7c2 | ||
|
|
5fdf2e7063 | ||
|
|
6fe05820ff | ||
|
|
670d8abf80 | ||
|
|
b2bffbb2ca | ||
|
|
13a6d667d2 | ||
|
|
1be77f8336 | ||
|
|
187e9c24f1 | ||
|
|
eddeaf76f8 | ||
|
|
33e9d10d2a | ||
|
|
46f7dc3bf6 | ||
|
|
555b0e20f7 | ||
|
|
a57dfe710d | ||
|
|
53adbd7a3d | ||
|
|
17f033b725 | ||
|
|
cefed3e8dc | ||
|
|
84fa865c0c | ||
|
|
f05f993eb7 | ||
|
|
e90cdb8adf | ||
|
|
4250941710 | ||
|
|
a2687b64a2 | ||
|
|
c284f34a49 | ||
|
|
5f5be796b0 | ||
|
|
5cb374364b | ||
|
|
f15256e156 | ||
|
|
ce37eb2d83 | ||
|
|
0d6e308b51 | ||
|
|
b1dab2363a | ||
|
|
bd6abc4939 | ||
|
|
96eeda0324 | ||
|
|
4c4266d9c9 | ||
|
|
54e87b4b06 | ||
|
|
44e9e221f3 | ||
|
|
61dec11ae0 | ||
|
|
5009de7d2d | ||
|
|
67f3feebcb | ||
|
|
b22260749f | ||
|
|
06d76beb28 | ||
|
|
7af4227ac2 | ||
|
|
9312b7325e | ||
|
|
c6edb381f5 | ||
|
|
a1d55ad095 | ||
|
|
a289addd96 | ||
|
|
13c5b46361 | ||
|
|
f3af206d8d | ||
|
|
df0054ab13 | ||
|
|
0d162bd17c | ||
|
|
e1add89334 | ||
|
|
22d49dc429 | ||
|
|
1aa4caf318 | ||
|
|
306ffb8c71 | ||
|
|
0a98201164 | ||
|
|
e0870f1d7a | ||
|
|
1923b1fce4 | ||
|
|
5dc4003e63 | ||
|
|
37c817eb81 | ||
|
|
284d628a7c | ||
|
|
ff3184ca1e | ||
|
|
12865a9762 | ||
|
|
ea847c6232 | ||
|
|
b695f2423d | ||
|
|
c3e5e5851b | ||
|
|
4337c8f856 | ||
|
|
4c7e46079d | ||
|
|
72a6e63136 | ||
|
|
37101856a6 | ||
|
|
65fc84b32e | ||
|
|
45e08edb08 | ||
|
|
05b7bab8e1 | ||
|
|
904817552d | ||
|
|
6e195fe975 | ||
|
|
3eaf615f40 | ||
|
|
6156e72f85 | ||
|
|
73a4bdfd77 | ||
|
|
4844449a5d | ||
|
|
ae289aec1e | ||
|
|
9e4c32ea54 | ||
|
|
a5f9cff256 | ||
|
|
d01d15e096 | ||
|
|
a53426441b | ||
|
|
5d1966948e | ||
|
|
f673ea84b2 | ||
|
|
64f21c31bf | ||
|
|
520cf41711 | ||
|
|
d38fc30563 | ||
|
|
6dff599288 | ||
|
|
f746dda0a0 | ||
|
|
91a1e147ae | ||
|
|
40da904230 | ||
|
|
34fada3012 | ||
|
|
f91e01d9a5 | ||
|
|
3048b0a8ea | ||
|
|
d99b4ccf93 | ||
|
|
58811a0a38 | ||
|
|
cb290916be | ||
|
|
a2b0471f1d | ||
|
|
bb18e7550c | ||
|
|
db2b5cb75f | ||
|
|
fa8c787d8b | ||
|
|
ec40899bb9 | ||
|
|
b5accabaa7 | ||
|
|
4e308a9526 | ||
|
|
4d88810810 | ||
|
|
f321922214 | ||
|
|
cab13afe8d | ||
|
|
72fc7ec59b | ||
|
|
58743a87b8 | ||
|
|
54bf456e85 | ||
|
|
a24639bb36 | ||
|
|
3fef53645d | ||
|
|
882e689312 | ||
|
|
b0a93231cf | ||
|
|
0c819b76d6 | ||
|
|
ce58b1b479 | ||
|
|
a16d8f2b25 | ||
|
|
59187666b9 | ||
|
|
808c57c343 | ||
|
|
4af8fe4e78 | ||
|
|
4034cb3f71 | ||
|
|
6fc048f438 | ||
|
|
5d2a707139 | ||
|
|
81d2b0ef9d | ||
|
|
248ed45fc6 | ||
|
|
893c4cc056 | ||
|
|
a7725e6df9 | ||
|
|
368ad70e05 | ||
|
|
b7cee9498b | ||
|
|
72d45525d2 | ||
|
|
1fb8ec4b0d | ||
|
|
beb9368481 | ||
|
|
981555bddb | ||
|
|
9c7527085c | ||
|
|
eddd5d129e | ||
|
|
26f76b7912 | ||
|
|
32eda0961e | ||
|
|
66964002df | ||
|
|
57469f6c31 | ||
|
|
13c7bcbb2b | ||
|
|
d48c806560 | ||
|
|
ad1a09a509 | ||
|
|
d6631cf3a5 | ||
|
|
5a8543b8b8 | ||
|
|
19119cbd35 | ||
|
|
442743b83c | ||
|
|
419896af47 | ||
|
|
0569a1339d | ||
|
|
f1e3656ee2 | ||
|
|
a644fc3cc4 | ||
|
|
d17e1dd2da | ||
|
|
b9b15fb165 | ||
|
|
ef732c3b54 | ||
|
|
baa4212ae1 | ||
|
|
0be976ec0a | ||
|
|
f7f10340d6 | ||
|
|
68f9910d94 | ||
|
|
fb6e0ea120 | ||
|
|
97feb557ed | ||
|
|
dc8293ff73 | ||
|
|
785db4ced0 | ||
|
|
5562deb169 | ||
|
|
983b1ed321 | ||
|
|
548abf96ce | ||
|
|
f8ebdf9265 | ||
|
|
aa23c22004 | ||
|
|
1d5cda2265 | ||
|
|
fe70ad26d3 | ||
|
|
0a00748901 | ||
|
|
03979352b4 | ||
|
|
cb7fb45e42 | ||
|
|
92cc9dd7c2 | ||
|
|
88a7fb3edd | ||
|
|
728d092201 | ||
|
|
80707c983c | ||
|
|
5911fee567 | ||
|
|
a09f6f55da | ||
|
|
caf5cc9152 | ||
|
|
58422e8393 | ||
|
|
e8d3168e3a | ||
|
|
7b1a0c19b8 | ||
|
|
536492752b | ||
|
|
7c4f063b13 | ||
|
|
1a62c49d31 | ||
|
|
fea4db62bd | ||
|
|
4499c0eebd | ||
|
|
0c42946536 | ||
|
|
ab264c9e79 | ||
|
|
dd7fb70f6e | ||
|
|
30f337c9ef | ||
|
|
9d35271938 | ||
|
|
bbfb1d016b | ||
|
|
c4b4df4fb4 | ||
|
|
a6d89d18bf | ||
|
|
75bc860093 | ||
|
|
02a279a75f | ||
|
|
584c7bf76d | ||
|
|
c4cd2ca6bf | ||
|
|
1ef00d2072 | ||
|
|
4dd4c72790 | ||
|
|
6aae748ea7 | ||
|
|
aa953c3201 | ||
|
|
3f55bd5dad | ||
|
|
279b1c1ebb | ||
|
|
fa45cda1aa | ||
|
|
11dc274054 | ||
|
|
e7bef92205 | ||
|
|
4a1991d7c5 | ||
|
|
13aefa1365 | ||
|
|
addf0c4a1c | ||
|
|
25bfc8cea1 | ||
|
|
dfd5ba6ab7 | ||
|
|
393ba2214d | ||
|
|
f358487f8e | ||
|
|
a18381aca6 | ||
|
|
f6e54812b7 | ||
|
|
31e7451aa5 | ||
|
|
0e36d9da42 | ||
|
|
da9d12f5d9 | ||
|
|
a60e2dca6b | ||
|
|
86c4601e12 | ||
|
|
173f5bf8cf | ||
|
|
823edc686f | ||
|
|
a3a841073e | ||
|
|
57385128c3 | ||
|
|
2990e06f29 | ||
|
|
2ef2e822d1 | ||
|
|
b7736c797c | ||
|
|
9b9c8aaf4d | ||
|
|
b0fd253afc | ||
|
|
e028b9ff53 | ||
|
|
9c07d25345 | ||
|
|
7352b8736b | ||
|
|
5b540e86a4 | ||
|
|
6744b62ddd | ||
|
|
e90b8acec3 | ||
|
|
925c517f19 | ||
|
|
cc964a518c | ||
|
|
3309507dd3 | ||
|
|
5e7dbaca50 | ||
|
|
76c2194714 | ||
|
|
968c8030cf | ||
|
|
446e239e2c | ||
|
|
e7bc9b64a3 | ||
|
|
8018edd3aa | ||
|
|
64c3523a6f | ||
|
|
310c9f30f0 | ||
|
|
5c1b7bfd2a | ||
|
|
faf11086d8 | ||
|
|
52fa4d7893 | ||
|
|
de0551020b | ||
|
|
c1456d83a7 | ||
|
|
1cbbaea957 | ||
|
|
f6aeaa74d1 | ||
|
|
6839140eb5 | ||
|
|
915dd20705 | ||
|
|
c53217a2b8 | ||
|
|
b2ac00eb16 | ||
|
|
45ddbf6204 | ||
|
|
276877cf77 | ||
|
|
6b45fcf160 | ||
|
|
49c24eccd4 | ||
|
|
0d7d3763f2 | ||
|
|
241dc65eee | ||
|
|
860bdd4571 | ||
|
|
55bf051bbc | ||
|
|
423dba8ea1 | ||
|
|
517c7b4dee | ||
|
|
18ced14631 | ||
|
|
ce67256218 | ||
|
|
9e83fa99fe | ||
|
|
256a9e376c | ||
|
|
ef5075e092 | ||
|
|
65653a6596 | ||
|
|
d5a0b48379 | ||
|
|
314a74d731 | ||
|
|
90e22f4b51 | ||
|
|
ab304c268c | ||
|
|
16a3fec02d | ||
|
|
abb0b532f8 | ||
|
|
43cd760fc1 | ||
|
|
9af87151ec | ||
|
|
8dd99390f5 | ||
|
|
e636af6b23 | ||
|
|
e3217f1448 | ||
|
|
66b711633f | ||
|
|
f40f2fc8ce | ||
|
|
e6f9e388cf | ||
|
|
3c1e2ad956 | ||
|
|
e6d2799170 | ||
|
|
2cfbf4bc0e | ||
|
|
f7731f1fc2 | ||
|
|
7d3f8ae2df | ||
|
|
a60fdd63f4 | ||
|
|
3a7dec59bc | ||
|
|
880ae34190 | ||
|
|
d00daf1f3f | ||
|
|
17fadf7d40 | ||
|
|
06c28400fa | ||
|
|
6e35c72fdb | ||
|
|
e2d22fee53 | ||
|
|
1bca1de6cc | ||
|
|
e0ed4e4087 | ||
|
|
4a7319be12 | ||
|
|
55d5937dd6 | ||
|
|
63596e1c4a | ||
|
|
603e6b05c7 | ||
|
|
dfad66a838 | ||
|
|
58cadc8608 | ||
|
|
b11b50bcd0 | ||
|
|
a73de5f3ba | ||
|
|
84c3645cea | ||
|
|
2a88a8cd30 | ||
|
|
8a97fc2e1b | ||
|
|
7a2fd68b96 | ||
|
|
6a7cc46cb2 | ||
|
|
aa6dc37ccb | ||
|
|
ea42541fe0 | ||
|
|
b7b2741f3a | ||
|
|
eb61be192d | ||
|
|
9b9114e8cd | ||
|
|
857e38bb45 | ||
|
|
4ea812445d | ||
|
|
e80a765412 | ||
|
|
15089022d4 | ||
|
|
f69204adad | ||
|
|
459a83c9cc | ||
|
|
6464bdbe13 | ||
|
|
4f3e9a0fba | ||
|
|
8a9709dee5 | ||
|
|
daa598df11 | ||
|
|
d04e9c51b4 | ||
|
|
d89a3a313a | ||
|
|
350e4e4dec | ||
|
|
c95dcb3935 | ||
|
|
1e4f48d6c4 | ||
|
|
fb55e28d83 | ||
|
|
067669dac7 | ||
|
|
24c906d3f7 | ||
|
|
14820f635d | ||
|
|
59192f5650 | ||
|
|
365346ca30 | ||
|
|
d01350a881 | ||
|
|
38b02c13d0 | ||
|
|
b017ec4e13 | ||
|
|
2c873122b3 | ||
|
|
6969ebcfcf | ||
|
|
1dbb94cadf | ||
|
|
8a78bb963d | ||
|
|
6931c13800 | ||
|
|
e6e3f12ffc | ||
|
|
e2559dbedc | ||
|
|
1f3d6cdd86 | ||
|
|
4a7ee79d4d | ||
|
|
0c2ef5f42d | ||
|
|
ca20c7fd62 | ||
|
|
191e40da17 | ||
|
|
80ddadb7e8 | ||
|
|
31f3b68a97 | ||
|
|
d594399c6a | ||
|
|
d74a2e3ed5 | ||
|
|
d175d7e13e | ||
|
|
daa8ce838b | ||
|
|
b19fd07c02 | ||
|
|
47d6a60c2f | ||
|
|
980821ebab | ||
|
|
592f4696dc | ||
|
|
8a7846f97e | ||
|
|
87f18b6289 | ||
|
|
28063ba5b2 | ||
|
|
fe332038c6 | ||
|
|
3c0b1ebf78 | ||
|
|
f2fe4903c9 | ||
|
|
3151cbae89 | ||
|
|
3c30b99059 | ||
|
|
a7735ba085 | ||
|
|
d811b68901 | ||
|
|
1c8162a921 | ||
|
|
16417f8b9d | ||
|
|
b49d381d05 | ||
|
|
7da9a16d10 | ||
|
|
32f60a6e7b | ||
|
|
b7db090661 | ||
|
|
136c5c5ec3 | ||
|
|
85b80fbc73 | ||
|
|
16859cdbdc | ||
|
|
fc96552d26 | ||
|
|
15bb997d0a | ||
|
|
b6b42c892c | ||
|
|
5bb920003e | ||
|
|
37ff0e344d | ||
|
|
97d53f8c75 | ||
|
|
f2ac84c36d | ||
|
|
c21eeef5bc | ||
|
|
e11c425119 | ||
|
|
84229c7ac9 | ||
|
|
c9a59880f0 | ||
|
|
9a17dddbc5 | ||
|
|
277d99e8c9 | ||
|
|
2a1874cc82 | ||
|
|
d5c973ccb7 | ||
|
|
37f3ce61bb | ||
|
|
076f60eed0 | ||
|
|
20b2e9cef7 | ||
|
|
e37d8229f5 | ||
|
|
710faea9a4 | ||
|
|
70a6051cf1 | ||
|
|
7a1f46b6ac | ||
|
|
7ca9250db0 | ||
|
|
af7086c63f | ||
|
|
8808589277 | ||
|
|
6cd5096063 | ||
|
|
677cd34acd | ||
|
|
08c5385e65 | ||
|
|
d7bf70f196 | ||
|
|
6f3cff41dd | ||
|
|
5de45bcadc | ||
|
|
446ee5b110 | ||
|
|
d3e6fd3910 | ||
|
|
6813fa7eac | ||
|
|
0f5a04e3ff | ||
|
|
8801138b47 | ||
|
|
2473391971 | ||
|
|
7d6879328a | ||
|
|
900454132e | ||
|
|
92b8abfe80 | ||
|
|
52e628a861 | ||
|
|
4791825d49 | ||
|
|
d542c20c5f | ||
|
|
4762db4fc9 | ||
|
|
8645af1d8c | ||
|
|
429f98283f | ||
|
|
5be7fa93fc | ||
|
|
837cbad97f | ||
|
|
af1d91c562 | ||
|
|
908f5a9f9f | ||
|
|
9b74643315 | ||
|
|
986066873e | ||
|
|
9533e15a79 | ||
|
|
8dc74608a3 | ||
|
|
3e85237e5f | ||
|
|
9d0523ef4c | ||
|
|
4a7144ee7e | ||
|
|
c120ff37f5 | ||
|
|
83fd337d8e | ||
|
|
707c1a3085 | ||
|
|
8294b00c11 | ||
|
|
da2bcdd1c2 | ||
|
|
093acc5dad | ||
|
|
fd73b94d31 | ||
|
|
38499c1a49 | ||
|
|
170381c052 | ||
|
|
8113a033dd | ||
|
|
87cc45e136 | ||
|
|
f6b8d591f7 | ||
|
|
d31c09c872 | ||
|
|
337a1a86a7 | ||
|
|
b7dc46c0f6 | ||
|
|
ff57065957 | ||
|
|
0406a3a7a4 | ||
|
|
bc3b5b2558 | ||
|
|
d1cce1dd92 | ||
|
|
7bb7058e8d | ||
|
|
727fa3688f | ||
|
|
577ab12ce5 | ||
|
|
0f2ac85576 | ||
|
|
fab1f8898e | ||
|
|
f63d68be97 | ||
|
|
58665d23b4 | ||
|
|
195bd906a2 | ||
|
|
fc1ae6582f | ||
|
|
fc0257c9fd | ||
|
|
91c4da3fda | ||
|
|
990ff150ef | ||
|
|
e72b18a9bd | ||
|
|
bc63ae3f13 | ||
|
|
6e12886393 | ||
|
|
b5ca91ae4b | ||
|
|
89855e78ab | ||
|
|
e106de49c8 | ||
|
|
afbcc8f216 | ||
|
|
f177b7cca2 | ||
|
|
ea5164d181 | ||
|
|
ccdff3ebbf | ||
|
|
24d0fcde7f | ||
|
|
56014c8c0a | ||
|
|
7c2a9e766c | ||
|
|
bb24028f51 | ||
|
|
52d3e10613 | ||
|
|
67863f46e3 | ||
|
|
9c28e52628 | ||
|
|
1b2f167546 | ||
|
|
702d0c4529 | ||
|
|
51106bafc6 | ||
|
|
42d4edc067 | ||
|
|
fbc0bc4d53 | ||
|
|
1b2db7aecb | ||
|
|
1ce29566e7 | ||
|
|
3742bf3ac3 | ||
|
|
18d6b679af | ||
|
|
dbda5fbf06 | ||
|
|
2154309a54 | ||
|
|
afb6e9450d | ||
|
|
dfa3248380 | ||
|
|
2cda256088 | ||
|
|
d9c7edf63f | ||
|
|
a151343943 | ||
|
|
85ed0aa396 | ||
|
|
3019f95f37 | ||
|
|
5702bc12b3 | ||
|
|
b0d791bb35 | ||
|
|
3903928ca0 | ||
|
|
827c37f631 | ||
|
|
b45b059a3d | ||
|
|
f39281ae56 | ||
|
|
e2bea9eb8d | ||
|
|
931a979904 | ||
|
|
3fccfafd30 |
23
.cvsignore
23
.cvsignore
@@ -1,23 +0,0 @@
|
||||
ID
|
||||
Makefile
|
||||
autom4te.cache
|
||||
confdefs.h
|
||||
config.cache
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
conftest.c
|
||||
conftest.log
|
||||
dox
|
||||
getgroups
|
||||
gmon.out
|
||||
rsync
|
||||
shconfig
|
||||
testdir
|
||||
tests-dont-exist
|
||||
testtmp
|
||||
testtmp.*
|
||||
tls
|
||||
trimslash
|
||||
t_unsafe
|
||||
zlib/dummy
|
||||
48
.gitignore
vendored
Normal file
48
.gitignore
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
*.[oa]
|
||||
*~
|
||||
dummy
|
||||
ID
|
||||
Makefile
|
||||
Makefile.old
|
||||
configure.sh
|
||||
configure.sh.old
|
||||
config.cache
|
||||
config.h
|
||||
config.h.in
|
||||
config.h.in.old
|
||||
config.log
|
||||
config.status
|
||||
aclocal.m4
|
||||
/proto.h
|
||||
/proto.h-tstamp
|
||||
/rsync.1
|
||||
/rsyncd.conf.5
|
||||
/autom4te*.cache
|
||||
/confdefs.h
|
||||
/conftest*
|
||||
/dox
|
||||
/getgroups
|
||||
/gmon.out
|
||||
/rsync
|
||||
/rsync-ssl
|
||||
/stunnel-rsync
|
||||
/stunnel-rsyncd.conf
|
||||
/shconfig
|
||||
/testdir
|
||||
/tests-dont-exist
|
||||
/testtmp
|
||||
/tls
|
||||
/testrun
|
||||
/trimslash
|
||||
/t_unsafe
|
||||
/wildtest
|
||||
/getfsdev
|
||||
/rounding.h
|
||||
/doc/rsync.pdf
|
||||
/doc/rsync.ps
|
||||
/support/savetransfer
|
||||
/testsuite/chown-fake.test
|
||||
/testsuite/devices-fake.test
|
||||
/testsuite/xattrs-hlink.test
|
||||
/patches
|
||||
.deps
|
||||
19
.ignore
19
.ignore
@@ -1,19 +0,0 @@
|
||||
.#*
|
||||
*.log
|
||||
Makefile
|
||||
config.h
|
||||
*.o
|
||||
CVS
|
||||
.ignore
|
||||
.cvsignore
|
||||
*~
|
||||
rsync
|
||||
config.status
|
||||
config.cache
|
||||
TAGS
|
||||
config.log
|
||||
test
|
||||
*.gz
|
||||
rsync-*
|
||||
*.dvi
|
||||
*.aux
|
||||
849
COPYING
849
COPYING
@@ -1,285 +1,626 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
0. Definitions.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
1. Source Code.
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
14. Revised Versions of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
NO WARRANTY
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@@ -287,15 +628,15 @@ free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
@@ -304,36 +645,30 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
49
INSTALL
49
INSTALL
@@ -1,4 +1,4 @@
|
||||
To build and install rsync
|
||||
To build and install rsync:
|
||||
|
||||
$ ./configure
|
||||
$ make
|
||||
@@ -9,15 +9,39 @@ 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,
|
||||
and will be used it there is no popt library on your build host, or if
|
||||
cut-down copy of a recent release 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.
|
||||
|
||||
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.
|
||||
|
||||
MAKE COMPATIBILITY
|
||||
------------------
|
||||
|
||||
Note that Makefile.in has a rule that uses a wildcard in a prerequisite. If
|
||||
your make has a problem with this rule, you will see an error like this:
|
||||
|
||||
Don't know how to make ./*.c
|
||||
|
||||
You can change the "proto.h-tstamp" target in Makefile.in to list all the *.c
|
||||
filenames explicitly in order to avoid this issue.
|
||||
|
||||
RPM NOTES
|
||||
---------
|
||||
|
||||
Under packaging you will find .spec files for several distributions.
|
||||
The .spec file in packaging/lsb can be used for Linux systems that
|
||||
adhere to the Linux Standards Base (e.g., RedHat and others).
|
||||
|
||||
HP-UX NOTES
|
||||
-----------
|
||||
@@ -30,16 +54,21 @@ 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.
|
||||
|
||||
<http://www.ipv6.org/impl/mac.html> says that Apple do not support
|
||||
IPv6 yet. If your build fails, try again with --disable-ipv6.
|
||||
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 started to support
|
||||
IPv6 in 10.2 (Jaguar). If your build fails, try again after running
|
||||
configure with --disable-ipv6.
|
||||
|
||||
IBM AIX NOTES
|
||||
-------------
|
||||
|
||||
IBM AIX has a largefile problem with mkstemp. See IBM PR-51921.
|
||||
The workaround is to append the below to config.h
|
||||
#ifdef _LARGE_FILES
|
||||
#undef HAVE_SECURE_MKSTEMP
|
||||
#endif
|
||||
|
||||
254
Makefile.in
254
Makefile.in
@@ -2,7 +2,9 @@
|
||||
# Makefile
|
||||
|
||||
prefix=@prefix@
|
||||
datarootdir=@datarootdir@
|
||||
exec_prefix=@exec_prefix@
|
||||
stunnel4=@STUNNEL4@
|
||||
bindir=@bindir@
|
||||
mandir=@mandir@
|
||||
|
||||
@@ -12,42 +14,48 @@ CFLAGS=@CFLAGS@
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
EXEEXT=@EXEEXT@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
LIBOBJDIR=lib/
|
||||
|
||||
INSTALLCMD=@INSTALL@
|
||||
INSTALLMAN=@INSTALL@
|
||||
|
||||
srcdir=@srcdir@
|
||||
MKDIR_P=@MKDIR_P@
|
||||
VPATH=$(srcdir)
|
||||
SHELL=/bin/sh
|
||||
|
||||
VERSION=@VERSION@
|
||||
VERSION=@RSYNC_VERSION@
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
LIBOBJ=lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
|
||||
lib/permstring.o @LIBOBJS@
|
||||
ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
|
||||
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
|
||||
zlib/zutil.o zlib/adler32.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
|
||||
GENFILES=configure.sh aclocal.m4 config.h.in proto.h proto.h-tstamp rsync.1 rsyncd.conf.5
|
||||
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h itypes.h inums.h \
|
||||
lib/pool_alloc.h
|
||||
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o lib/md5.o \
|
||||
lib/permstring.o lib/pool_alloc.o lib/sysacls.o lib/sysxattrs.o @LIBOBJS@
|
||||
zlib_OBJS=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
|
||||
zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
|
||||
OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \
|
||||
util.o util2.o main.o checksum.o match.o syscall.o log.o backup.o delete.o
|
||||
OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o \
|
||||
fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
|
||||
OBJS3=progress.o pipe.o
|
||||
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
|
||||
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
|
||||
popt/popthelp.o popt/poptparse.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
|
||||
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
|
||||
|
||||
TLS_OBJ = tls.o syscall.o lib/permstring.o
|
||||
TLS_OBJ = tls.o syscall.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
|
||||
|
||||
# Programs we must have to run the test cases
|
||||
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) \
|
||||
trimslash$(EXEEXT) t_unsafe$(EXEEXT)
|
||||
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
|
||||
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
|
||||
|
||||
CHECK_SYMLINKS = testsuite/chown-fake.test testsuite/devices-fake.test testsuite/xattrs-hlink.test
|
||||
|
||||
# Objects for CHECK_PROGS to clean
|
||||
CHECK_OBJS=getgroups.o t_stub.o t_unsafe.o trimslash.o
|
||||
CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o
|
||||
|
||||
# note that the -I. is needed to handle config.h when using VPATH
|
||||
.c.o:
|
||||
@@ -55,63 +63,172 @@ CHECK_OBJS=getgroups.o t_stub.o t_unsafe.o trimslash.o
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
|
||||
@OBJ_RESTORE@
|
||||
|
||||
all: rsync$(EXEEXT)
|
||||
|
||||
man: rsync.1 rsyncd.conf.5
|
||||
all: Makefile rsync$(EXEEXT) rsync-ssl stunnel-rsync stunnel-rsyncd.conf @MAKE_MAN@
|
||||
|
||||
install: all
|
||||
-mkdir -p ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} ${STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
|
||||
-mkdir -p ${DESTDIR}${mandir}/man1
|
||||
-mkdir -p ${DESTDIR}${mandir}/man5
|
||||
${INSTALLMAN} -m 644 $(srcdir)/rsync.1 ${DESTDIR}${mandir}/man1
|
||||
${INSTALLMAN} -m 644 $(srcdir)/rsyncd.conf.5 ${DESTDIR}${mandir}/man5
|
||||
-${MKDIR_P} ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
|
||||
-${MKDIR_P} ${DESTDIR}${mandir}/man1
|
||||
-${MKDIR_P} ${DESTDIR}${mandir}/man5
|
||||
if test -f rsync.1; then ${INSTALLMAN} -m 644 rsync.1 ${DESTDIR}${mandir}/man1; fi
|
||||
if test -f rsyncd.conf.5; then ${INSTALLMAN} -m 644 rsyncd.conf.5 ${DESTDIR}${mandir}/man5; fi
|
||||
|
||||
install-ssl-client: rsync-ssl stunnel-rsync
|
||||
-${MKDIR_P} ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} -m 755 rsync-ssl ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} -m 755 stunnel-rsync ${DESTDIR}${bindir}
|
||||
|
||||
install-ssl-daemon: stunnel-rsyncd.conf
|
||||
-${MKDIR_P} ${DESTDIR}/etc/stunnel
|
||||
${INSTALLCMD} -m 644 stunnel-rsyncd.conf ${DESTDIR}/etc/stunnel/rsyncd.conf
|
||||
@if ! ls /etc/rsync-ssl/certs/server.* >/dev/null 2>/dev/null; then \
|
||||
echo "Note that you'll need to install the certificate used by /etc/stunnel/rsyncd.conf"; \
|
||||
fi
|
||||
|
||||
install-all: install install-ssl-client install-ssl-daemon
|
||||
|
||||
install-strip:
|
||||
$(MAKE) STRIP='-s' install
|
||||
$(MAKE) INSTALL_STRIP='-s' install
|
||||
|
||||
rsync$(EXEEXT): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
$(OBJS): config.h
|
||||
$(OBJS): $(HEADERS)
|
||||
$(CHECK_OBJS): $(HEADERS)
|
||||
|
||||
flist.o: rounding.h
|
||||
|
||||
rounding.h: rounding.c rsync.h
|
||||
@for r in 0 1 3; do \
|
||||
if $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o rounding -DEXTRA_ROUNDING=$$r -I. $(srcdir)/rounding.c >rounding.out 2>&1; then \
|
||||
echo "#define EXTRA_ROUNDING $$r" >rounding.h; \
|
||||
if test -f "$$HOME/build_farm/build_test.fns"; then \
|
||||
echo "EXTRA_ROUNDING is $$r" >&2; \
|
||||
fi; \
|
||||
break; \
|
||||
fi; \
|
||||
done
|
||||
@rm -f rounding
|
||||
@if test -f rounding.h; then : ; else \
|
||||
cat rounding.out 1>&2; \
|
||||
echo "Failed to create rounding.h!" 1>&2; \
|
||||
exit 1; \
|
||||
fi
|
||||
@rm -f rounding.out
|
||||
|
||||
tls$(EXEEXT): $(TLS_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
|
||||
|
||||
testrun$(EXEEXT): testrun.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ testrun.o
|
||||
|
||||
getgroups$(EXEEXT): getgroups.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getgroups.o $(LIBS)
|
||||
|
||||
TRIMSLASH_OBJ = trimslash.o syscall.o
|
||||
getfsdev$(EXEEXT): getfsdev.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getfsdev.o $(LIBS)
|
||||
|
||||
TRIMSLASH_OBJ = trimslash.o syscall.o lib/compat.o lib/snprintf.o
|
||||
trimslash$(EXEEXT): $(TRIMSLASH_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)
|
||||
|
||||
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o t_stub.o lib/compat.o lib/snprintf.o
|
||||
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/wildmatch.o
|
||||
t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
|
||||
|
||||
# I don't like these rules because CVS can skew the timestamps and
|
||||
# produce spurious warnings, and also make "make install" fail if the
|
||||
# source directory can no longer be found. Since we don't rebuild
|
||||
# automatically they're kind of lame anyhow.
|
||||
gen: conf proto.h man
|
||||
|
||||
#Makefile: Makefile.in configure config.status
|
||||
# echo "WARNING: You need to run ./config.status --recheck"
|
||||
gensend: gen
|
||||
rsync -aivzc $(GENFILES) $${SAMBA_HOST-samba.org}:/home/ftp/pub/rsync/generated-files/
|
||||
|
||||
# don't actually run autoconf, just issue a warning
|
||||
#configure: configure.in
|
||||
# echo "WARNING: you need to rerun autoconf"
|
||||
conf:
|
||||
cd $(srcdir) && $(MAKE) -f prepare-source.mak conf
|
||||
|
||||
$(srcdir)/rsync.1: $(srcdir)/rsync.yo
|
||||
yodl2man -o $(srcdir)/rsync.1 $(srcdir)/rsync.yo
|
||||
aclocal.m4: $(srcdir)/m4/*.m4
|
||||
aclocal -I $(srcdir)/m4
|
||||
|
||||
$(srcdir)/rsyncd.conf.5: $(srcdir)/rsyncd.conf.yo
|
||||
yodl2man -o $(srcdir)/rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
|
||||
configure.sh config.h.in: configure.ac aclocal.m4
|
||||
@if test -f configure.sh; then cp -p configure.sh configure.sh.old; else touch configure.sh.old; fi
|
||||
@if test -f config.h.in; then cp -p config.h.in config.h.in.old; else touch config.h.in.old; fi
|
||||
autoconf -o configure.sh
|
||||
autoheader && touch config.h.in
|
||||
@if diff configure.sh configure.sh.old >/dev/null 2>&1; then \
|
||||
echo "configure.sh is unchanged."; \
|
||||
rm configure.sh.old; \
|
||||
else \
|
||||
echo "configure.sh has CHANGED."; \
|
||||
fi
|
||||
@if diff config.h.in config.h.in.old >/dev/null 2>&1; then \
|
||||
echo "config.h.in is unchanged."; \
|
||||
rm config.h.in.old; \
|
||||
else \
|
||||
echo "config.h.in has CHANGED."; \
|
||||
fi
|
||||
@if test -f configure.sh.old -o -f config.h.in.old; then \
|
||||
if test "$(MAKECMDGOALS)" = reconfigure; then \
|
||||
echo 'Continuing with "make reconfigure".'; \
|
||||
else \
|
||||
echo 'You may need to run:'; \
|
||||
echo ' make reconfigure'; \
|
||||
exit 1; \
|
||||
fi \
|
||||
fi
|
||||
|
||||
proto:
|
||||
cat $(srcdir)/*.c $(srcdir)/lib/compat.c | awk -f $(srcdir)/mkproto.awk > $(srcdir)/proto.h
|
||||
reconfigure: configure.sh
|
||||
./config.status --recheck
|
||||
./config.status
|
||||
|
||||
Makefile: Makefile.in config.status configure.sh config.h.in
|
||||
@if test -f Makefile; then cp -p Makefile Makefile.old; else touch Makefile.old; fi
|
||||
@./config.status
|
||||
@if diff Makefile Makefile.old >/dev/null 2>&1; then \
|
||||
echo "Makefile is unchanged."; \
|
||||
rm Makefile.old; \
|
||||
else \
|
||||
if test "$(MAKECMDGOALS)" = reconfigure; then \
|
||||
echo 'Continuing with "make reconfigure".'; \
|
||||
else \
|
||||
echo "Makefile updated -- rerun your make command."; \
|
||||
exit 1; \
|
||||
fi \
|
||||
fi
|
||||
|
||||
rsync-ssl: $(srcdir)/rsync-ssl.in Makefile
|
||||
sed 's;\@bindir\@;$(bindir);g' <$(srcdir)/rsync-ssl.in >rsync-ssl
|
||||
@chmod +x rsync-ssl
|
||||
|
||||
stunnel-rsync: $(srcdir)/stunnel-rsync.in Makefile
|
||||
sed 's;\@stunnel4\@;$(stunnel4);g' <$(srcdir)/stunnel-rsync.in >stunnel-rsync
|
||||
@chmod +x stunnel-rsync
|
||||
|
||||
stunnel-rsyncd.conf: $(srcdir)/stunnel-rsyncd.conf.in Makefile
|
||||
sed 's;\@bindir\@;$(bindir);g' <$(srcdir)/stunnel-rsyncd.conf.in >stunnel-rsyncd.conf
|
||||
|
||||
proto: proto.h-tstamp
|
||||
|
||||
proto.h: proto.h-tstamp
|
||||
@if test -f proto.h; then :; else cp -p $(srcdir)/proto.h .; fi
|
||||
|
||||
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c config.h
|
||||
perl $(srcdir)/mkproto.pl $(srcdir)/*.c $(srcdir)/lib/compat.c
|
||||
|
||||
man: rsync.1 rsyncd.conf.5 man-copy
|
||||
|
||||
man-copy:
|
||||
@-if test -f rsync.1; then :; else echo 'Copying srcdir rsync.1'; cp -p $(srcdir)/rsync.1 .; fi
|
||||
@-if test -f rsyncd.conf.5; then :; else echo 'Copying srcdir rsyncd.conf.5'; cp -p $(srcdir)/rsyncd.conf.5 .; fi
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man -o rsync.1 $(srcdir)/rsync.yo
|
||||
-$(srcdir)/tweak_manpage rsync.1
|
||||
|
||||
rsyncd.conf.5: rsyncd.conf.yo
|
||||
yodl2man -o rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
|
||||
-$(srcdir)/tweak_manpage rsyncd.conf.5
|
||||
|
||||
clean: cleantests
|
||||
rm -f *~ $(OBJS) $(TLS_OBJ) $(CHECK_PROGS) $(CHECK_OBJS)
|
||||
rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) \
|
||||
rounding rounding.h *.old
|
||||
|
||||
cleantests:
|
||||
rm -rf ./testtmp*
|
||||
@@ -121,12 +238,15 @@ cleantests:
|
||||
# the source directory.
|
||||
distclean: clean
|
||||
rm -f Makefile config.h config.status
|
||||
rm -f rsync-ssl stunnel-rsync stunnel-rsyncd.conf
|
||||
rm -f lib/dummy popt/dummy zlib/dummy
|
||||
rm -f $(srcdir)/Makefile $(srcdir)/config.h $(srcdir)/config.status
|
||||
|
||||
rm -f $(srcdir)/lib/dummy $(srcdir)/popt/dummy $(srcdir)/zlib/dummy
|
||||
rm -f config.cache config.log
|
||||
rm -f $(srcdir)/config.cache $(srcdir)/config.log
|
||||
|
||||
rm -f shconfig $(srcdir)/shconfig
|
||||
rm -f $(GENFILES)
|
||||
rm -rf autom4te.cache
|
||||
|
||||
# this target is really just for my use. It only works on a limited
|
||||
# range of machines and is used to produce a list of potentially
|
||||
@@ -141,13 +261,9 @@ finddead:
|
||||
|
||||
test: check
|
||||
|
||||
|
||||
# There seems to be no standard way to specify some variables as
|
||||
# exported from a Makefile apart from listing them like this.
|
||||
|
||||
# TODO: Tests that depend on built test aide programs like tls need to
|
||||
# know where the build directory is.
|
||||
|
||||
# This depends on building rsync; if we need any helper programs it
|
||||
# should depend on them too.
|
||||
|
||||
@@ -155,14 +271,33 @@ test: check
|
||||
# catch Bash-isms earlier even if we're running on GNU. Of course, we
|
||||
# might lose in the future where POSIX diverges from old sh.
|
||||
|
||||
check: all $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin=`pwd`/rsync$(EXEEXT) srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh
|
||||
|
||||
check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=29
|
||||
|
||||
check30: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=30
|
||||
|
||||
wildtest.o: wildtest.c lib/wildmatch.c rsync.h config.h
|
||||
wildtest$(EXEEXT): wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@ $(LIBS)
|
||||
|
||||
testsuite/chown-fake.test:
|
||||
ln -s chown.test $(srcdir)/testsuite/chown-fake.test
|
||||
|
||||
testsuite/devices-fake.test:
|
||||
ln -s devices.test $(srcdir)/testsuite/devices-fake.test
|
||||
|
||||
testsuite/xattrs-hlink.test:
|
||||
ln -s xattrs.test $(srcdir)/testsuite/xattrs-hlink.test
|
||||
|
||||
# This does *not* depend on building or installing: you can use it to
|
||||
# check a version installed from a binary or some other source tree,
|
||||
# if you want.
|
||||
|
||||
installcheck: $(CHECK_PROGS)
|
||||
installcheck: $(CHECK_PROGS) $(CHECK_SYMLINKS)
|
||||
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin="$(bindir)/rsync$(EXEEXT)" srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
|
||||
# TODO: Add 'dist' target; need to know which files will be included
|
||||
@@ -172,21 +307,10 @@ installcheck: $(CHECK_PROGS)
|
||||
splint:
|
||||
splint +unixlib +gnuextensions -weak rsync.c
|
||||
|
||||
|
||||
rsync.dvi: doc/rsync.texinfo
|
||||
texi2dvi -o $@ $<
|
||||
|
||||
rsync.ps: rsync.dvi
|
||||
dvips -ta4 -o $@ $<
|
||||
|
||||
rsync.pdf: doc/rsync.texinfo
|
||||
texi2dvi -o $@ --pdf $<
|
||||
|
||||
|
||||
doxygen:
|
||||
cd $(srcdir) && rm dox/html/* && doxygen
|
||||
|
||||
# for maintainers only
|
||||
doxygen-upload:
|
||||
rsync -avzv $(srcdir)/dox/html/ --delete \
|
||||
samba.org:/home/httpd/html/rsync/doxygen/head/
|
||||
$${SAMBA_HOST-samba.org}:/home/httpd/html/rsync/doxygen/head/
|
||||
|
||||
128
NEWS
128
NEWS
@@ -1,91 +1,47 @@
|
||||
NEWS for rsync version 2.5.6, aka the dwd-between-jobs release
|
||||
Changes since version 2.5.5:
|
||||
NEWS for rsync 3.1.2 (21 Dec 2015)
|
||||
Protocol: 31 (unchanged)
|
||||
Changes since 3.1.1:
|
||||
|
||||
SECURITY FIXES:
|
||||
|
||||
- Make sure that all transferred files use only path names from inside the
|
||||
transfer. This makes it impossible for a malicious sender to try to make
|
||||
the receiver use an unsafe destination path for a transferred file, such
|
||||
as a just-sent symlink.
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- Change the checksum seed order in the per-block checksums. This prevents
|
||||
someone from trying to create checksum blocks that match in sum but not
|
||||
content.
|
||||
- Fixed a with the per-dir filter files (using -FF) that could trigger an
|
||||
assert failure.
|
||||
- Only skip set_modtime() on a transferred file if the time is exactly
|
||||
right.
|
||||
- Don't create an empty backup dir for a transferred file that doesn't
|
||||
exist yet.
|
||||
- Fixed a bug where --link-dest and --xattrs could cause rsync to exit if
|
||||
a filename had a matching dir of the same name in the alt-dest area.
|
||||
- Allow more than 32 group IDs per user in the daemon's gid=LIST config.
|
||||
- Fix the logging of %b & %c via --log-file (daemon logging was already
|
||||
correct, as was --out-format='%b/%c').
|
||||
- Fix erroneous acceptance of --info=5 & --debug=5 (an empty flag name is
|
||||
not valid).
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* The --delete-after option now implies --delete. (Wayne Davison)
|
||||
- Added "(DRY RUN)" info to the --debug=exit output line.
|
||||
- Use usleep() for our msleep() function if it is available.
|
||||
- Added a few extra long-option names to rrsync script, which will make
|
||||
BackupPC happier.
|
||||
- Made configure choose to use linux xattrs on netbsd (rather than not
|
||||
supporting xattrs).
|
||||
- Added -wo (write-only) option to rrsync support script.
|
||||
- Misc. manpage tweaks.
|
||||
|
||||
* The --suffix option can now be used with --backup-dir. (Michael
|
||||
Zimmerman)
|
||||
DEVELOPER RELATED:
|
||||
|
||||
* Combining "::" syntax with the -rsh/-e option now uses the
|
||||
specified remote-shell as a transport to talk to a (newly-spawned)
|
||||
server-daemon. This allows someone to use daemon features, such
|
||||
as modules, over a secure protocol, such as ssh. (JD Paul)
|
||||
|
||||
* The rsync:// syntax for daemon connections is now accepted in the
|
||||
destination field.
|
||||
|
||||
* If the file name given to --include-from or --exclude-from is "-",
|
||||
rsync will read from standard input. (J.W. Schultz)
|
||||
|
||||
* New option --link-dest which is like --compare-dest except that
|
||||
unchanged files are hard-linked in to the destination directory.
|
||||
(J.W. Schultz)
|
||||
|
||||
* Don't report an error if an excluded file disappears during an
|
||||
rsync run. (Eugene Chupriyanov and Bo Kersey)
|
||||
|
||||
* Added .svn to --cvs-exclude list to support subversion. (Jon
|
||||
Middleton)
|
||||
|
||||
* Properly support IPv6 addresses in the rsyncd.conf "hosts allow"
|
||||
and "hosts deny" fields. (Hideaki Yoshifuji)
|
||||
|
||||
* Changed exclude file handling to permit DOS or MAC style line
|
||||
terminations. (J.W. Schultz)
|
||||
|
||||
* Ignore errors from chmod when -p/-a/--preserve-perms is not set.
|
||||
(Dave Dykstra)
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix "forward name lookup failed" errors on AIX 4.3.3. (John
|
||||
L. Allen, Martin Pool)
|
||||
|
||||
* Generate each file's rolling-checksum data as we send it, not
|
||||
in a separate (memory-eating) pass before hand. This prevents
|
||||
timeout errors on really large files. (Stefan Nehlsen)
|
||||
|
||||
* Fix compilation on Tru64. (Albert Chin, Zoong Pham)
|
||||
|
||||
* Better handling of some client-server errors. (Martin Pool)
|
||||
|
||||
* Fixed a crash that would occur when sending a list of files that
|
||||
contains a duplicate name (if it sorts to the end of the file
|
||||
list) and using --delete. (Wayne Davison)
|
||||
|
||||
* Fixed the file-name duplicate-removal code when dealing with multiple
|
||||
dups in a row. (Wayne Davison)
|
||||
|
||||
* Fixed a bug that caused rsync to lose the exit status of its child
|
||||
processes and sometimes return an exit code of 0 instead of showing
|
||||
an error. (David R. Staples, Dave Dykstra)
|
||||
|
||||
* Fixed bug in --copy-unsafe-links that caused it to be completely
|
||||
broken. (Dave Dykstra)
|
||||
|
||||
* Prevent infinite recursion in cleanup code under certain circumstances.
|
||||
(Sviatoslav Sviridov and Marc Espie)
|
||||
|
||||
* Fixed a bug that prevented rsync from creating intervening directories
|
||||
when --relative-paths/-R is set. (Craig Barratt)
|
||||
|
||||
* Prevent "Connection reset by peer" messages from Cygwin. (Randy O'Meara)
|
||||
|
||||
INTERNAL:
|
||||
|
||||
* Many code cleanups and improved internal documentation. (Martin
|
||||
Pool, Nelson Beebe)
|
||||
|
||||
* Portability fixes. (Dave Dykstra and Wayne Davison)
|
||||
|
||||
* More test cases. (Martin Pool)
|
||||
|
||||
* Some test-case fixes. (Brian Poole, Wayne Davison)
|
||||
|
||||
* Updated included popt to the latest vendor drop, version 1.6.4.
|
||||
(Jos Backus)
|
||||
|
||||
* Updated config.guess and config.sub to latest versions; this
|
||||
means rsync should build on more platforms. (Paul Green)
|
||||
- Fixed a bug with the Makefile's use of INSTALL_STRIP.
|
||||
- Improve a test in the suite that could get an erroneous timestamp error.
|
||||
- Tweaks for newer versions of git in the packaging tools.
|
||||
- Improved the m4 generation rules and some autoconf idioms.
|
||||
|
||||
130
README
130
README
@@ -1,121 +1,135 @@
|
||||
WHAT IS RSYNC?
|
||||
--------------
|
||||
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
Rsync is a fast and extraordinarily versatile file copying tool for
|
||||
both remote and local files.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
Rsync uses a delta-transfer algorithm which provides a very fast method
|
||||
for bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
At first glance this may seem impossible because the calculation of
|
||||
diffs between two files normally requires local access to both
|
||||
files.
|
||||
sets of files are present at one of the ends of the link beforehand. At
|
||||
first glance this may seem impossible because the calculation of diffs
|
||||
between two files normally requires local access to both files.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
A technical report describing the rsync algorithm is included with this
|
||||
package.
|
||||
|
||||
|
||||
USAGE
|
||||
-----
|
||||
|
||||
Basically you use rsync just like rcp, but rsync has many additional
|
||||
options. To get a complete list of supported options type
|
||||
Basically you use rsync just like scp, but rsync has many additional
|
||||
options. To get a complete list of supported options type:
|
||||
|
||||
rsync --help
|
||||
rsync --help
|
||||
|
||||
and see the manual for more information.
|
||||
See the manpage for more detailed information.
|
||||
|
||||
|
||||
SETUP
|
||||
-----
|
||||
|
||||
Rsync normally uses rsh or ssh for communication. It does not need to
|
||||
be setuid and requires no special privileges for installation. You
|
||||
must, however, have a working rsh or ssh system. Using ssh is
|
||||
recommended for its security features.
|
||||
Rsync normally uses ssh or rsh for communication with remote systems.
|
||||
It does not need to be setuid and requires no special privileges for
|
||||
installation. You must, however, have a working ssh or rsh system.
|
||||
Using ssh is recommended for its security features.
|
||||
|
||||
Alternatively, rsync can run in `daemon' mode, listening on a socket.
|
||||
This is generally used for public file distribution, although
|
||||
authentication and access control are available.
|
||||
|
||||
To install rsync, first run the "configure" script. This will create a
|
||||
Makefile and config.h appropriate for your system. Then type
|
||||
"make".
|
||||
To install rsync, first run the "configure" script. This will create a
|
||||
Makefile and config.h appropriate for your system. Then type "make".
|
||||
|
||||
Note that on some systems you will have to force configure not to use
|
||||
gcc because gcc may not support some features (such as 64 bit file
|
||||
offsets) that your system may support. Set the environment variable CC
|
||||
offsets) that your system may support. Set the environment variable CC
|
||||
to the name of your native compiler before running configure in this
|
||||
case.
|
||||
case.
|
||||
|
||||
Once built put a copy of rsync in your search path on the local and
|
||||
remote systems (or use "make install"). That's it!
|
||||
remote systems (or use "make install"). That's it!
|
||||
|
||||
RSYNC SERVERS
|
||||
|
||||
RSYNC DAEMONS
|
||||
-------------
|
||||
|
||||
rsync can also talk to "rsync servers" which can provide anonymous or
|
||||
authenticated rsync. See the rsyncd.conf(5) man page for details on how
|
||||
to setup a rsync server. See the rsync(1) man page for info on how to
|
||||
connect to a rsync server.
|
||||
Rsync can also talk to "rsync daemons" which can provide anonymous or
|
||||
authenticated rsync. See the rsyncd.conf(5) man page for details on how
|
||||
to setup an rsync daemon. See the rsync(1) man page for info on how to
|
||||
connect to an rsync daemon.
|
||||
|
||||
|
||||
MAILING LIST
|
||||
------------
|
||||
WEB SITE
|
||||
--------
|
||||
|
||||
There is a mailing list for the discussion of rsync and its
|
||||
applications. It is open to anyone to join. I will announce new
|
||||
versions on this list.
|
||||
The main rsync web site is here:
|
||||
|
||||
To join the mailing list see the web page at http://lists.samba.org/
|
||||
http://rsync.samba.org/
|
||||
|
||||
To send mail to everyone on the list send it to rsync@samba.org
|
||||
You'll find a FAQ list, downloads, resources, HTML versions of the
|
||||
manpages, etc.
|
||||
|
||||
|
||||
MAILING LISTS
|
||||
-------------
|
||||
|
||||
There is a mailing list for the discussion of rsync and its applications
|
||||
that is open to anyone to join. New releases are announced on this
|
||||
list, and there is also an announcement-only mailing list for those that
|
||||
want official announcements. See the mailing-list page for full
|
||||
details:
|
||||
|
||||
http://rsync.samba.org/lists.html
|
||||
|
||||
|
||||
BUG REPORTS
|
||||
-----------
|
||||
|
||||
If you have web access then please look at
|
||||
To visit this web page for full the details on bug reporting:
|
||||
|
||||
http://rsync.samba.org
|
||||
http://rsync.samba.org/bugzilla.html
|
||||
|
||||
That page contains links to the current bug list, and information on
|
||||
how to report a bug well. You might also like to try searching the
|
||||
internet for the error message you've received, or looking in the
|
||||
mailing list archives at
|
||||
That page contains links to the current bug list, and information on how
|
||||
to report a bug well. You might also like to try searching the Internet
|
||||
for the error message you've received, or looking in the mailing list
|
||||
archives at:
|
||||
|
||||
http://mail-archive.com/rsync@lists.samba.org/
|
||||
http://mail-archive.com/rsync@lists.samba.org/
|
||||
|
||||
Please send bug reports to
|
||||
To send a bug report, follow the instructions on the bug-tracking
|
||||
page of the web site.
|
||||
|
||||
rsync@lists.samba.org
|
||||
Alternately, email your bug report to rsync@lists.samba.org .
|
||||
|
||||
|
||||
CVS TREE
|
||||
--------
|
||||
GIT REPOSITORY
|
||||
--------------
|
||||
|
||||
If you want to get the very latest version of rsync direct from the
|
||||
source code repository then you can use anonymous cvs. You will need a
|
||||
recent version of cvs then use the following commands:
|
||||
source code repository then you can use git:
|
||||
|
||||
cvs -d :pserver:cvs@pserver.samba.org:/cvsroot login
|
||||
Password: cvs
|
||||
git clone git://git.samba.org/rsync.git
|
||||
|
||||
cvs -d :pserver:cvs@pserver.samba.org:/cvsroot co rsync
|
||||
See the download page for full details on all the ways to grab the
|
||||
source, including nightly tar files, web-browsing of the git repository,
|
||||
etc.:
|
||||
|
||||
Look at the cvs documentation, or http://samba.org/cvs.html, for more
|
||||
details.
|
||||
http://rsync.samba.org/download.html
|
||||
|
||||
|
||||
COPYRIGHT
|
||||
---------
|
||||
|
||||
rsync was originally written by Andrew Tridgell and has been improved
|
||||
by many developers around the world. rsync may be used, modified and
|
||||
redistributed only under the terms of the GNU General Public License,
|
||||
found in the file COPYING in this distribution, or at
|
||||
Rsync was originally written by Andrew Tridgell and is currently
|
||||
maintained by Wayne Davison. It has been improved by many developers
|
||||
from around the world.
|
||||
|
||||
http://www.fsf.org/licenses/gpl.html
|
||||
Rsync may be used, modified and redistributed only under the terms of
|
||||
the GNU General Public License, found in the file COPYING in this
|
||||
distribution, or at:
|
||||
|
||||
http://www.fsf.org/licenses/gpl.html
|
||||
|
||||
|
||||
AVAILABILITY
|
||||
|
||||
177
access.c
177
access.c
@@ -1,49 +1,82 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
hosts allow/deny code for rsync
|
||||
|
||||
*/
|
||||
* Routines to authenticate access to a daemon (hosts allow/deny).
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2004-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
static int allow_forward_dns;
|
||||
|
||||
static int match_hostname(char *host, char *tok)
|
||||
extern const char undetermined_hostname[];
|
||||
|
||||
static int match_hostname(const char **host_ptr, const char *addr, const char *tok)
|
||||
{
|
||||
if (!host || !*host) return 0;
|
||||
return (fnmatch(tok, host, 0) == 0);
|
||||
struct hostent *hp;
|
||||
unsigned int i;
|
||||
const char *host = *host_ptr;
|
||||
|
||||
if (!host || !*host)
|
||||
return 0;
|
||||
|
||||
/* First check if the reverse-DNS-determined hostname matches. */
|
||||
if (iwildmatch(tok, host))
|
||||
return 1;
|
||||
|
||||
if (!allow_forward_dns)
|
||||
return 0;
|
||||
|
||||
/* Fail quietly if tok is an address or wildcarded entry, not a simple hostname. */
|
||||
if (!tok[strspn(tok, ".0123456789")] || tok[strcspn(tok, ":/*?[")])
|
||||
return 0;
|
||||
|
||||
/* Now try forward-DNS on the token (config-specified hostname) and see if the IP matches. */
|
||||
if (!(hp = gethostbyname(tok)))
|
||||
return 0;
|
||||
|
||||
for (i = 0; hp->h_addr_list[i] != NULL; i++) {
|
||||
if (strcmp(addr, inet_ntoa(*(struct in_addr*)(hp->h_addr_list[i]))) == 0) {
|
||||
/* If reverse lookups are off, we'll use the conf-specified
|
||||
* hostname in preference to UNDETERMINED. */
|
||||
if (host == undetermined_hostname) {
|
||||
if (!(*host_ptr = strdup(tok)))
|
||||
*host_ptr = undetermined_hostname;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int match_binary(char *b1, char *b2, char *mask, int addrlen)
|
||||
static int match_binary(const char *b1, const char *b2, const char *mask, int addrlen)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<addrlen; i++) {
|
||||
if ((b1[i]^b2[i])&mask[i]) {
|
||||
for (i = 0; i < addrlen; i++) {
|
||||
if ((b1[i] ^ b2[i]) & mask[i])
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void make_mask(char *mask, int plen, int addrlen) {
|
||||
static void make_mask(char *mask, int plen, int addrlen)
|
||||
{
|
||||
int w, b;
|
||||
|
||||
w = plen >> 3;
|
||||
@@ -59,7 +92,7 @@ static void make_mask(char *mask, int plen, int addrlen) {
|
||||
return;
|
||||
}
|
||||
|
||||
static int match_address(char *addr, char *tok)
|
||||
static int match_address(const char *addr, const char *tok)
|
||||
{
|
||||
char *p;
|
||||
struct addrinfo hints, *resa, *rest;
|
||||
@@ -74,10 +107,19 @@ static int match_address(char *addr, char *tok)
|
||||
char mask[16];
|
||||
char *a = NULL, *t = NULL;
|
||||
|
||||
if (!addr || !*addr) return 0;
|
||||
if (!addr || !*addr)
|
||||
return 0;
|
||||
|
||||
p = strchr(tok,'/');
|
||||
if (p) *p = 0;
|
||||
if (p)
|
||||
*p = '\0';
|
||||
|
||||
/* Fail quietly if tok is a hostname, not an address. */
|
||||
if (tok[strspn(tok, ".0123456789")] && strchr(tok, ':') == NULL) {
|
||||
if (p)
|
||||
*p = '/';
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
@@ -86,14 +128,18 @@ static int match_address(char *addr, char *tok)
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
#endif
|
||||
|
||||
gai = getaddrinfo(addr, NULL, &hints, &resa);
|
||||
if (gai) return 0;
|
||||
if (getaddrinfo(addr, NULL, &hints, &resa) != 0) {
|
||||
if (p)
|
||||
*p = '/';
|
||||
return 0;
|
||||
}
|
||||
|
||||
gai = getaddrinfo(tok, NULL, &hints, &rest);
|
||||
if (p)
|
||||
*p++ = '/';
|
||||
if (gai) {
|
||||
rprintf(FERROR,"malformed address %s\n", tok);
|
||||
if (gai != 0) {
|
||||
rprintf(FLOG, "error matching address %s: %s\n",
|
||||
tok, gai_strerror(gai));
|
||||
freeaddrinfo(resa);
|
||||
return 0;
|
||||
}
|
||||
@@ -136,7 +182,7 @@ static int match_address(char *addr, char *tok)
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
rprintf(FERROR,"unknown family %u\n", rest->ai_family);
|
||||
rprintf(FLOG, "unknown family %u\n", rest->ai_family);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
@@ -153,14 +199,14 @@ static int match_address(char *addr, char *tok)
|
||||
#ifdef HAVE_STRTOL
|
||||
bits = strtol(p, &ep, 10);
|
||||
if (!*p || *ep) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
rprintf(FLOG, "malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
for (pp = (unsigned char *)p; *pp; pp++) {
|
||||
if (!isascii(*pp) || !isdigit(*pp)) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
rprintf(FLOG, "malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
@@ -172,7 +218,7 @@ static int match_address(char *addr, char *tok)
|
||||
goto out;
|
||||
}
|
||||
if (bits < 0 || bits > (addrlen << 3)) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
rprintf(FLOG, "malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
@@ -186,24 +232,24 @@ static int match_address(char *addr, char *tok)
|
||||
|
||||
ret = match_binary(a, t, mask, addrlen);
|
||||
|
||||
out:
|
||||
out:
|
||||
freeaddrinfo(resa);
|
||||
freeaddrinfo(rest);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int access_match(char *list, char *addr, char *host)
|
||||
static int access_match(const char *list, const char *addr, const char **host_ptr)
|
||||
{
|
||||
char *tok;
|
||||
char *list2 = strdup(list);
|
||||
|
||||
if (!list2) out_of_memory("access_match");
|
||||
if (!list2)
|
||||
out_of_memory("access_match");
|
||||
|
||||
strlower(list2);
|
||||
if (host) strlower(host);
|
||||
|
||||
for (tok=strtok(list2," ,\t"); tok; tok=strtok(NULL," ,\t")) {
|
||||
if (match_hostname(host, tok) || match_address(addr, tok)) {
|
||||
for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
|
||||
if (match_hostname(host_ptr, addr, tok) || match_address(addr, tok)) {
|
||||
free(list2);
|
||||
return 1;
|
||||
}
|
||||
@@ -213,31 +259,32 @@ static int access_match(char *list, char *addr, char *host)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int allow_access(char *addr, char *host, char *allow_list, char *deny_list)
|
||||
int allow_access(const char *addr, const char **host_ptr, int i)
|
||||
{
|
||||
/* if theres no deny list and no allow list then allow access */
|
||||
if ((!deny_list || !*deny_list) && (!allow_list || !*allow_list))
|
||||
return 1;
|
||||
const char *allow_list = lp_hosts_allow(i);
|
||||
const char *deny_list = lp_hosts_deny(i);
|
||||
|
||||
/* if there is an allow list but no deny list then allow only hosts
|
||||
on the allow list */
|
||||
if (!deny_list || !*deny_list)
|
||||
return(access_match(allow_list, addr, host));
|
||||
if (allow_list && !*allow_list)
|
||||
allow_list = NULL;
|
||||
if (deny_list && !*deny_list)
|
||||
deny_list = NULL;
|
||||
|
||||
/* if theres a deny list but no allow list then allow
|
||||
all hosts not on the deny list */
|
||||
if (!allow_list || !*allow_list)
|
||||
return(!access_match(deny_list,addr,host));
|
||||
allow_forward_dns = lp_forward_lookup(i);
|
||||
|
||||
/* if there are both type of list then allow all hosts on the
|
||||
allow list */
|
||||
if (access_match(allow_list,addr,host))
|
||||
return 1;
|
||||
/* If we match an allow-list item, we always allow access. */
|
||||
if (allow_list) {
|
||||
if (access_match(allow_list, addr, host_ptr))
|
||||
return 1;
|
||||
/* For an allow-list w/o a deny-list, disallow non-matches. */
|
||||
if (!deny_list)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if there are both type of list and it's not on the allow then
|
||||
allow it if its not on the deny */
|
||||
if (access_match(deny_list,addr,host))
|
||||
/* If we match a deny-list item (and got past any allow-list
|
||||
* items), we always disallow access. */
|
||||
if (deny_list && access_match(deny_list, addr, host_ptr))
|
||||
return 0;
|
||||
|
||||
/* Allow all other access. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
11
acconfig.h
11
acconfig.h
@@ -1,11 +0,0 @@
|
||||
#undef ino_t
|
||||
#undef HAVE_CONNECT
|
||||
#undef HAVE_SHORT_INO_T
|
||||
#undef HAVE_GETOPT_LONG
|
||||
#undef REPLACE_INET_NTOA
|
||||
#undef REPLACE_INET_ATON
|
||||
#undef HAVE_GETTIMEOFDAY_TZ
|
||||
#undef ENABLE_IPV6
|
||||
#undef HAVE_SOCKADDR_LEN
|
||||
#undef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
#undef HAVE_SOCKETPAIR
|
||||
455
authenticate.c
455
authenticate.c
@@ -1,39 +1,41 @@
|
||||
/* -*- c-file-style: "linux"; -*-
|
||||
|
||||
Copyright (C) 1998-2000 by Andrew Tridgell
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Support rsync daemon authentication.
|
||||
*
|
||||
* Copyright (C) 1998-2000 Andrew Tridgell
|
||||
* Copyright (C) 2002-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
/* support rsync authentication */
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
|
||||
extern int read_only;
|
||||
extern char *password_file;
|
||||
|
||||
/***************************************************************************
|
||||
encode a buffer using base64 - simple and slow algorithm. null terminates
|
||||
the result.
|
||||
***************************************************************************/
|
||||
static void base64_encode(char *buf, int len, char *out)
|
||||
void base64_encode(const char *buf, int len, char *out, int pad)
|
||||
{
|
||||
char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
int bit_offset, byte_offset, idx, i;
|
||||
unsigned char *d = (unsigned char *)buf;
|
||||
const uchar *d = (const uchar *)buf;
|
||||
int bytes = (len*8 + 5)/6;
|
||||
|
||||
memset(out, 0, bytes+1);
|
||||
|
||||
for (i=0;i<bytes;i++) {
|
||||
for (i = 0; i < bytes; i++) {
|
||||
byte_offset = (i*6)/8;
|
||||
bit_offset = (i*6)%8;
|
||||
if (bit_offset < 3) {
|
||||
@@ -46,244 +48,327 @@ static void base64_encode(char *buf, int len, char *out)
|
||||
}
|
||||
out[i] = b64[idx];
|
||||
}
|
||||
|
||||
while (pad && (i % 4))
|
||||
out[i++] = '=';
|
||||
|
||||
out[i] = '\0';
|
||||
}
|
||||
|
||||
/* create a 16 byte challenge buffer */
|
||||
static void gen_challenge(char *addr, char *challenge)
|
||||
/* Generate a challenge buffer and return it base64-encoded. */
|
||||
static void gen_challenge(const char *addr, char *challenge)
|
||||
{
|
||||
char input[32];
|
||||
char digest[MAX_DIGEST_LEN];
|
||||
struct timeval tv;
|
||||
int len;
|
||||
|
||||
memset(input, 0, sizeof(input));
|
||||
memset(input, 0, sizeof input);
|
||||
|
||||
strlcpy((char *)input, addr, 17);
|
||||
strlcpy(input, addr, 17);
|
||||
sys_gettimeofday(&tv);
|
||||
SIVAL(input, 16, tv.tv_sec);
|
||||
SIVAL(input, 20, tv.tv_usec);
|
||||
SIVAL(input, 24, getpid());
|
||||
|
||||
sum_init();
|
||||
sum_update(input, sizeof(input));
|
||||
sum_end(challenge);
|
||||
sum_init(0);
|
||||
sum_update(input, sizeof input);
|
||||
len = sum_end(digest);
|
||||
|
||||
base64_encode(digest, len, challenge, 0);
|
||||
}
|
||||
|
||||
|
||||
/* return the secret for a user from the sercret file. maximum length
|
||||
is len. null terminate it */
|
||||
static int get_secret(int module, char *user, char *secret, int len)
|
||||
/* Generate an MD4 hash created from the combination of the password
|
||||
* and the challenge string and return it base64-encoded. */
|
||||
static void generate_hash(const char *in, const char *challenge, char *out)
|
||||
{
|
||||
char *fname = lp_secrets_file(module);
|
||||
int fd, found=0;
|
||||
char line[MAXPATHLEN];
|
||||
char *p, *pass=NULL;
|
||||
char buf[MAX_DIGEST_LEN];
|
||||
int len;
|
||||
|
||||
sum_init(0);
|
||||
sum_update(in, strlen(in));
|
||||
sum_update(challenge, strlen(challenge));
|
||||
len = sum_end(buf);
|
||||
|
||||
base64_encode(buf, len, out, 0);
|
||||
}
|
||||
|
||||
/* Return the secret for a user from the secret file, null terminated.
|
||||
* Maximum length is len (not counting the null). */
|
||||
static const char *check_secret(int module, const char *user, const char *group,
|
||||
const char *challenge, const char *pass)
|
||||
{
|
||||
char line[1024];
|
||||
char pass2[MAX_DIGEST_LEN*2];
|
||||
const char *fname = lp_secrets_file(module);
|
||||
STRUCT_STAT st;
|
||||
int ok = 1;
|
||||
extern int am_root;
|
||||
int user_len = strlen(user);
|
||||
int group_len = group ? strlen(group) : 0;
|
||||
char *err;
|
||||
FILE *fh;
|
||||
|
||||
if (!fname || !*fname) return 0;
|
||||
if (!fname || !*fname || (fh = fopen(fname, "r")) == NULL)
|
||||
return "no secrets file";
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) return 0;
|
||||
|
||||
if (do_stat(fname, &st) == -1) {
|
||||
rsyserr(FERROR, errno, "stat(%s)", fname);
|
||||
if (do_fstat(fileno(fh), &st) == -1) {
|
||||
rsyserr(FLOG, errno, "fstat(%s)", fname);
|
||||
ok = 0;
|
||||
} else if (lp_strict_modes(module)) {
|
||||
if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FERROR,"secrets file must not be other-accessible (see strict modes option)\n");
|
||||
rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
|
||||
ok = 0;
|
||||
} else if (am_root && (st.st_uid != 0)) {
|
||||
rprintf(FERROR,"secrets file must be owned by root when running as root (see strict modes)\n");
|
||||
} else if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
rprintf(FERROR,"continuing without secrets file\n");
|
||||
close(fd);
|
||||
return 0;
|
||||
fclose(fh);
|
||||
return "ignoring secrets file";
|
||||
}
|
||||
|
||||
while (!found) {
|
||||
int i = 0;
|
||||
memset(line, 0, sizeof line);
|
||||
while ((size_t) i < (sizeof(line)-1)) {
|
||||
if (read(fd, &line[i], 1) != 1) {
|
||||
memset(line, 0, sizeof(line));
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (line[i] == '\r') continue;
|
||||
if (line[i] == '\n') break;
|
||||
i++;
|
||||
if (*user == '#') {
|
||||
/* Reject attempt to match a comment. */
|
||||
fclose(fh);
|
||||
return "invalid username";
|
||||
}
|
||||
|
||||
/* Try to find a line that starts with the user (or @group) name and a ':'. */
|
||||
err = "secret not found";
|
||||
while ((user || group) && fgets(line, sizeof line, fh) != NULL) {
|
||||
const char **ptr, *s = strtok(line, "\n\r");
|
||||
int len;
|
||||
if (!s)
|
||||
continue;
|
||||
if (*s == '@') {
|
||||
ptr = &group;
|
||||
len = group_len;
|
||||
s++;
|
||||
} else {
|
||||
ptr = &user;
|
||||
len = user_len;
|
||||
}
|
||||
line[i] = 0;
|
||||
if (line[0] == '#') continue;
|
||||
p = strchr(line,':');
|
||||
if (!p) continue;
|
||||
*p = 0;
|
||||
if (strcmp(user, line)) continue;
|
||||
pass = p+1;
|
||||
found = 1;
|
||||
if (!*ptr || strncmp(s, *ptr, len) != 0 || s[len] != ':')
|
||||
continue;
|
||||
generate_hash(s+len+1, challenge, pass2);
|
||||
if (strcmp(pass, pass2) == 0) {
|
||||
err = NULL;
|
||||
break;
|
||||
}
|
||||
err = "password mismatch";
|
||||
*ptr = NULL; /* Don't look for name again. */
|
||||
}
|
||||
|
||||
close(fd);
|
||||
if (!found) return 0;
|
||||
fclose(fh);
|
||||
|
||||
strlcpy(secret, pass, len);
|
||||
return 1;
|
||||
memset(line, 0, sizeof line);
|
||||
memset(pass2, 0, sizeof pass2);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static char *getpassf(char *filename)
|
||||
static const char *getpassf(const char *filename)
|
||||
{
|
||||
char buffer[100];
|
||||
int fd=0;
|
||||
STRUCT_STAT st;
|
||||
int ok = 1;
|
||||
extern int am_root;
|
||||
char *envpw=getenv("RSYNC_PASSWORD");
|
||||
char buffer[512], *p;
|
||||
int n;
|
||||
|
||||
if (!filename) return NULL;
|
||||
|
||||
if ( (fd=open(filename,O_RDONLY)) == -1) {
|
||||
rsyserr(FERROR, errno, "could not open password file \"%s\"",filename);
|
||||
if (envpw) rprintf(FERROR,"falling back to RSYNC_PASSWORD environment variable.\n");
|
||||
if (!filename)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (do_stat(filename, &st) == -1) {
|
||||
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)) {
|
||||
rprintf(FERROR,"password file must be owned by root when running as root\n");
|
||||
ok = 0;
|
||||
}
|
||||
if (!ok) {
|
||||
rprintf(FERROR,"continuing without password file\n");
|
||||
if (envpw) rprintf(FERROR,"using RSYNC_PASSWORD environment variable.\n");
|
||||
|
||||
if (strcmp(filename, "-") == 0) {
|
||||
n = fgets(buffer, sizeof buffer, stdin) == NULL ? -1 : (int)strlen(buffer);
|
||||
} else {
|
||||
int fd;
|
||||
|
||||
if ((fd = open(filename,O_RDONLY)) < 0) {
|
||||
rsyserr(FERROR, errno, "could not open password file %s", filename);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
if (do_stat(filename, &st) == -1) {
|
||||
rsyserr(FERROR, errno, "stat(%s)", filename);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if ((st.st_mode & 06) != 0) {
|
||||
rprintf(FERROR, "ERROR: password file must not be other-accessible\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
if (MY_UID() == 0 && st.st_uid != 0) {
|
||||
rprintf(FERROR, "ERROR: password file must be owned by root when running as root\n");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
n = read(fd, buffer, sizeof buffer - 1);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (envpw) rprintf(FERROR,"RSYNC_PASSWORD environment variable ignored\n");
|
||||
if (n > 0) {
|
||||
buffer[n] = '\0';
|
||||
if ((p = strtok(buffer, "\n\r")) != NULL)
|
||||
return strdup(p);
|
||||
}
|
||||
|
||||
buffer[sizeof(buffer)-1]='\0';
|
||||
if (read(fd,buffer,sizeof(buffer)-1) > 0)
|
||||
{
|
||||
char *p = strtok(buffer,"\n\r");
|
||||
close(fd);
|
||||
if (p) p = strdup(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
rprintf(FERROR, "ERROR: failed to read a password from %s\n", filename);
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
/* generate a 16 byte hash from a password and challenge */
|
||||
static void generate_hash(char *in, char *challenge, char *out)
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
sum_init();
|
||||
sum_update(in, strlen(in));
|
||||
sum_update(challenge, strlen(challenge));
|
||||
sum_end(buf);
|
||||
|
||||
base64_encode(buf, 16, out);
|
||||
}
|
||||
|
||||
/* possible negotiate authentication with the client. Use "leader" to
|
||||
start off the auth if necessary
|
||||
|
||||
return NULL if authentication failed
|
||||
|
||||
return "" if anonymous access
|
||||
|
||||
otherwise return username
|
||||
*/
|
||||
char *auth_server(int f_in, int f_out, int module, char *addr, char *leader)
|
||||
/* Possibly negotiate authentication with the client. Use "leader" to
|
||||
* start off the auth if necessary.
|
||||
*
|
||||
* Return NULL if authentication failed. Return "" if anonymous access.
|
||||
* Otherwise return username.
|
||||
*/
|
||||
char *auth_server(int f_in, int f_out, int module, const char *host,
|
||||
const char *addr, const char *leader)
|
||||
{
|
||||
char *users = lp_auth_users(module);
|
||||
char challenge[16];
|
||||
char b64_challenge[30];
|
||||
char line[MAXPATHLEN];
|
||||
static char user[100];
|
||||
char secret[100];
|
||||
char pass[30];
|
||||
char pass2[30];
|
||||
char *tok;
|
||||
char challenge[MAX_DIGEST_LEN*2];
|
||||
char line[BIGPATHBUFLEN];
|
||||
char **auth_uid_groups = NULL;
|
||||
int auth_uid_groups_cnt = -1;
|
||||
const char *err = NULL;
|
||||
int group_match = -1;
|
||||
char *tok, *pass;
|
||||
char opt_ch = '\0';
|
||||
|
||||
/* if no auth list then allow anyone in! */
|
||||
if (!users || !*users) return "";
|
||||
if (!users || !*users)
|
||||
return "";
|
||||
|
||||
gen_challenge(addr, challenge);
|
||||
|
||||
base64_encode(challenge, 16, b64_challenge);
|
||||
|
||||
io_printf(f_out, "%s%s\n", leader, b64_challenge);
|
||||
io_printf(f_out, "%s%s\n", leader, challenge);
|
||||
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
if (!read_line_old(f_in, line, sizeof line, 0)
|
||||
|| (pass = strchr(line, ' ')) == NULL) {
|
||||
rprintf(FLOG, "auth failed on module %s from %s (%s): "
|
||||
"invalid challenge response\n",
|
||||
lp_name(module), host, addr);
|
||||
return NULL;
|
||||
}
|
||||
*pass++ = '\0';
|
||||
|
||||
memset(user, 0, sizeof(user));
|
||||
memset(pass, 0, sizeof(pass));
|
||||
if (!(users = strdup(users)))
|
||||
out_of_memory("auth_server");
|
||||
|
||||
if (sscanf(line,"%99s %29s", user, pass) != 2) {
|
||||
return NULL;
|
||||
for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
|
||||
char *opts;
|
||||
/* See if the user appended :deny, :ro, or :rw. */
|
||||
if ((opts = strchr(tok, ':')) != NULL) {
|
||||
*opts++ = '\0';
|
||||
opt_ch = isUpper(opts) ? toLower(opts) : *opts;
|
||||
if (opt_ch == 'r') { /* handle ro and rw */
|
||||
opt_ch = isUpper(opts+1) ? toLower(opts+1) : opts[1];
|
||||
if (opt_ch == 'o')
|
||||
opt_ch = 'r';
|
||||
else if (opt_ch != 'w')
|
||||
opt_ch = '\0';
|
||||
} else if (opt_ch != 'd') /* if it's not deny, ignore it */
|
||||
opt_ch = '\0';
|
||||
} else
|
||||
opt_ch = '\0';
|
||||
if (*tok != '@') {
|
||||
/* Match the username */
|
||||
if (wildmatch(tok, line))
|
||||
break;
|
||||
} else {
|
||||
#ifdef HAVE_GETGROUPLIST
|
||||
int j;
|
||||
/* See if authorizing user is a real user, and if so, see
|
||||
* if it is in a group that matches tok+1 wildmat. */
|
||||
if (auth_uid_groups_cnt < 0) {
|
||||
item_list gid_list = EMPTY_ITEM_LIST;
|
||||
uid_t auth_uid;
|
||||
if (!user_to_uid(line, &auth_uid, False)
|
||||
|| getallgroups(auth_uid, &gid_list) != NULL)
|
||||
auth_uid_groups_cnt = 0;
|
||||
else {
|
||||
gid_t *gid_array = gid_list.items;
|
||||
auth_uid_groups_cnt = gid_list.count;
|
||||
if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
|
||||
out_of_memory("auth_server");
|
||||
for (j = 0; j < auth_uid_groups_cnt; j++)
|
||||
auth_uid_groups[j] = gid_to_group(gid_array[j]);
|
||||
}
|
||||
}
|
||||
for (j = 0; j < auth_uid_groups_cnt; j++) {
|
||||
if (auth_uid_groups[j] && wildmatch(tok+1, auth_uid_groups[j])) {
|
||||
group_match = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (group_match >= 0)
|
||||
break;
|
||||
#else
|
||||
rprintf(FLOG, "your computer doesn't support getgrouplist(), so no @group authorization is possible.\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
users = strdup(users);
|
||||
if (!users) return NULL;
|
||||
|
||||
for (tok=strtok(users," ,\t"); tok; tok = strtok(NULL," ,\t")) {
|
||||
if (fnmatch(tok, user, 0) == 0) break;
|
||||
}
|
||||
free(users);
|
||||
|
||||
if (!tok) {
|
||||
return NULL;
|
||||
if (!tok)
|
||||
err = "no matching rule";
|
||||
else if (opt_ch == 'd')
|
||||
err = "denied by rule";
|
||||
else {
|
||||
char *group = group_match >= 0 ? auth_uid_groups[group_match] : NULL;
|
||||
err = check_secret(module, line, group, challenge, pass);
|
||||
}
|
||||
|
||||
memset(secret, 0, sizeof(secret));
|
||||
if (!get_secret(module, user, secret, sizeof(secret)-1)) {
|
||||
memset(secret, 0, sizeof(secret));
|
||||
|
||||
memset(challenge, 0, sizeof challenge);
|
||||
memset(pass, 0, strlen(pass));
|
||||
|
||||
if (auth_uid_groups) {
|
||||
int j;
|
||||
for (j = 0; j < auth_uid_groups_cnt; j++) {
|
||||
if (auth_uid_groups[j])
|
||||
free(auth_uid_groups[j]);
|
||||
}
|
||||
free(auth_uid_groups);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
rprintf(FLOG, "auth failed on module %s from %s (%s) for %s: %s\n",
|
||||
lp_name(module), host, addr, line, err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
generate_hash(secret, b64_challenge, pass2);
|
||||
memset(secret, 0, sizeof(secret));
|
||||
|
||||
if (strcmp(pass, pass2) == 0)
|
||||
return user;
|
||||
if (opt_ch == 'r')
|
||||
read_only = 1;
|
||||
else if (opt_ch == 'w')
|
||||
read_only = 0;
|
||||
|
||||
return NULL;
|
||||
return strdup(line);
|
||||
}
|
||||
|
||||
|
||||
void auth_client(int fd, char *user, char *challenge)
|
||||
void auth_client(int fd, const char *user, const char *challenge)
|
||||
{
|
||||
char *pass;
|
||||
char pass2[30];
|
||||
extern char *password_file;
|
||||
const char *pass;
|
||||
char pass2[MAX_DIGEST_LEN*2];
|
||||
|
||||
if (!user || !*user) return;
|
||||
if (!user || !*user)
|
||||
user = "nobody";
|
||||
|
||||
if (!(pass=getpassf(password_file)) && !(pass=getenv("RSYNC_PASSWORD"))) {
|
||||
if (!(pass = getpassf(password_file))
|
||||
&& !(pass = getenv("RSYNC_PASSWORD"))) {
|
||||
/* XXX: cyeoh says that getpass is deprecated, because
|
||||
it may return a truncated password on some systems,
|
||||
and it is not in the LSB. */
|
||||
* it may return a truncated password on some systems,
|
||||
* and it is not in the LSB.
|
||||
*
|
||||
* Andrew Klein says that getpassphrase() is present
|
||||
* on Solaris and reads up to 256 characters.
|
||||
*
|
||||
* OpenBSD has a readpassphrase() that might be more suitable.
|
||||
*/
|
||||
pass = getpass("Password: ");
|
||||
}
|
||||
|
||||
if (!pass || !*pass) {
|
||||
if (!pass)
|
||||
pass = "";
|
||||
}
|
||||
|
||||
generate_hash(pass, challenge, pass2);
|
||||
io_printf(fd, "%s %s\n", user, pass2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
625
backup.c
625
backup.c
@@ -1,297 +1,354 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1999
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* backup handling code */
|
||||
/*
|
||||
* Backup handling code.
|
||||
*
|
||||
* Copyright (C) 1999 Andrew Tridgell
|
||||
* Copyright (C) 2003-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int suffix_specified;
|
||||
extern int am_root;
|
||||
extern int preserve_acls;
|
||||
extern int preserve_xattrs;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_specials;
|
||||
extern int preserve_links;
|
||||
extern int safe_symlinks;
|
||||
extern int backup_dir_len;
|
||||
extern unsigned int backup_dir_remainder;
|
||||
extern char backup_dir_buf[MAXPATHLEN];
|
||||
extern char *backup_suffix;
|
||||
extern char *backup_dir;
|
||||
|
||||
|
||||
extern int am_root;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_links;
|
||||
extern int preserve_hard_links;
|
||||
|
||||
/* simple backup creates a backup with a suffix in the same directory */
|
||||
static int make_simple_backup(char *fname)
|
||||
/* Returns -1 on error, 0 on missing dir, and 1 on present dir. */
|
||||
static int validate_backup_dir(void)
|
||||
{
|
||||
char fnamebak[MAXPATHLEN];
|
||||
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
|
||||
rprintf(FERROR,"backup filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(fnamebak,sizeof(fnamebak),"%s%s",fname,backup_suffix);
|
||||
if (do_rename(fname,fnamebak) != 0) {
|
||||
/* cygwin (at least version b19) reports EINVAL */
|
||||
if (errno != ENOENT && errno != EINVAL) {
|
||||
rsyserr(FERROR, errno, "rename %s to backup %s", fname, fnamebak);
|
||||
return 0;
|
||||
}
|
||||
} else if (verbose > 1) {
|
||||
rprintf(FINFO,"backed up %s to %s\n",fname,fnamebak);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* recursively make a directory path */
|
||||
static int make_dir(char *name, int mask)
|
||||
{
|
||||
char newdir [MAXPATHLEN];
|
||||
char *p, *d;
|
||||
|
||||
/* copy pathname over, look for last '/' */
|
||||
for (p = d = newdir; *name; *d++ = *name++)
|
||||
if (*name == '/')
|
||||
p = d;
|
||||
if (p == newdir)
|
||||
return 0;
|
||||
*p = 0;
|
||||
|
||||
/* make the new directory, if that fails then make its parent */
|
||||
while (do_mkdir (newdir, mask) != 0)
|
||||
if ((errno != ENOENT) || !make_dir (newdir, mask))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
} /* make_dir */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Create a directory given an absolute path, perms based upon another directory
|
||||
path
|
||||
****************************************************************************/
|
||||
static int make_bak_dir(char *fname,char *bak_path)
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
STRUCT_STAT *st2;
|
||||
char fullpath[MAXPATHLEN];
|
||||
extern int orig_umask;
|
||||
char *p;
|
||||
char *q;
|
||||
|
||||
while(strncmp(bak_path,"./",2)==0) bak_path += 2;
|
||||
|
||||
if(bak_path[strlen(bak_path)-1]!='/') {
|
||||
snprintf(fullpath,sizeof(fullpath),"%s/",bak_path);
|
||||
} else {
|
||||
snprintf(fullpath,sizeof(fullpath),"%s",bak_path);
|
||||
}
|
||||
p=fullpath;
|
||||
q=&fullpath[strlen(fullpath)]; /* End of bak_path string */
|
||||
strcat(fullpath,fname);
|
||||
|
||||
/* Make the directories */
|
||||
while ((p=strchr(p,'/'))) {
|
||||
*p = 0;
|
||||
if(do_lstat(fullpath,&st)!=0) {
|
||||
do_mkdir(fullpath,0777 & ~orig_umask);
|
||||
if(p>q) {
|
||||
if(do_lstat(q,&st)!=0) {
|
||||
rprintf(FERROR,"make_bak_dir stat %s : %s\n",fullpath,strerror(errno));
|
||||
} else {
|
||||
st2=&st;
|
||||
set_modtime(fullpath,st2->st_mtime);
|
||||
if(do_lchown(fullpath,st2->st_uid,st2->st_gid)!=0) {
|
||||
rprintf(FERROR,"make_bak_dir chown %s : %s\n",fullpath,strerror(errno));
|
||||
};
|
||||
if(do_chmod(fullpath,st2->st_mode)!=0) {
|
||||
rprintf(FERROR,"make_bak_dir failed to set permissions on %s : %s\n",fullpath,strerror(errno));
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
*p = '/';
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* robustly move a file, creating new directory structures if necessary */
|
||||
static int robust_move(char *src, char *dst)
|
||||
{
|
||||
int keep_trying = 4;
|
||||
int keep_path_extfs = 0;
|
||||
int failed;
|
||||
|
||||
while (keep_trying) {
|
||||
if (keep_path_extfs) {
|
||||
failed = copy_file(src, dst, 0755);
|
||||
if (!failed) {
|
||||
do_unlink(src);
|
||||
}
|
||||
} else {
|
||||
failed = robust_rename (src, dst);
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
if (verbose > 2)
|
||||
rprintf (FERROR, "robust_move failed: %s(%d)\n",
|
||||
strerror (errno), errno);
|
||||
switch (errno) {
|
||||
/* external filesystem */
|
||||
case EXDEV:
|
||||
keep_path_extfs = 1;
|
||||
keep_trying--;
|
||||
break;
|
||||
/* no directory to write to */
|
||||
case ENOENT:
|
||||
make_dir (dst, 0755);
|
||||
keep_trying--;
|
||||
break;
|
||||
default:
|
||||
keep_trying = 0;
|
||||
} /* switch */
|
||||
} else
|
||||
keep_trying = 0;
|
||||
} /* while */
|
||||
return (!failed);
|
||||
} /* robust_move */
|
||||
|
||||
|
||||
/* if we have a backup_dir, then we get here from make_backup().
|
||||
We will move the file to be deleted into a parallel directory tree */
|
||||
static int keep_backup(char *fname)
|
||||
{
|
||||
|
||||
static int initialised;
|
||||
|
||||
char keep_name [MAXPATHLEN];
|
||||
STRUCT_STAT st;
|
||||
struct file_struct *file;
|
||||
|
||||
int kept=0;
|
||||
int ret_code;
|
||||
|
||||
if (!initialised) {
|
||||
if (backup_dir[strlen(backup_dir) - 1] == '/')
|
||||
backup_dir[strlen(backup_dir) - 1] = 0;
|
||||
if (verbose > 0)
|
||||
rprintf (FINFO, "backup_dir is %s\n", backup_dir);
|
||||
initialised = 1;
|
||||
if (do_lstat(backup_dir_buf, &st) < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
rsyserr(FERROR, errno, "backup lstat %s failed", backup_dir_buf);
|
||||
return -1;
|
||||
}
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
int flags = get_del_for_flag(st.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
|
||||
if (delete_item(backup_dir_buf, st.st_mode, flags) == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* return if no file to keep */
|
||||
#if SUPPORT_LINKS
|
||||
if (do_lstat (fname, &st)) return 1;
|
||||
#else
|
||||
if (do_stat (fname, &st)) return 1;
|
||||
#endif
|
||||
|
||||
file = make_file(-1, fname, NULL, 1);
|
||||
|
||||
/* the file could have disappeared */
|
||||
if (!file) return 1;
|
||||
|
||||
/* make a complete pathname for backup file */
|
||||
if (strlen(backup_dir) + strlen(fname) +
|
||||
(suffix_specified ? strlen(backup_suffix) : 0) > (MAXPATHLEN - 1)) {
|
||||
rprintf (FERROR, "keep_backup filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (suffix_specified) {
|
||||
snprintf(keep_name, sizeof (keep_name), "%s/%s%s", backup_dir, fname, backup_suffix);
|
||||
} else {
|
||||
snprintf(keep_name, sizeof (keep_name), "%s/%s", backup_dir, fname);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_MKNOD
|
||||
/* Check to see if this is a device file, or link */
|
||||
if(IS_DEVICE(file->mode)) {
|
||||
if(am_root && preserve_devices) {
|
||||
make_bak_dir(fname,backup_dir);
|
||||
if(do_mknod(keep_name,file->mode,file->rdev)!=0) {
|
||||
rprintf(FERROR,"mknod %s : %s\n",keep_name,strerror(errno));
|
||||
} else {
|
||||
if(verbose>2)
|
||||
rprintf(FINFO,"make_backup : DEVICE %s successful.\n",fname);
|
||||
};
|
||||
};
|
||||
kept=1;
|
||||
do_unlink(fname);
|
||||
};
|
||||
#endif
|
||||
|
||||
if(!kept && S_ISDIR(file->mode)) {
|
||||
/* make an empty directory */
|
||||
make_bak_dir(fname,backup_dir);
|
||||
do_mkdir(keep_name,file->mode);
|
||||
ret_code=do_rmdir(fname);
|
||||
if(verbose>2)
|
||||
rprintf(FINFO,"make_backup : RMDIR %s returns %i\n",fname,ret_code);
|
||||
kept=1;
|
||||
};
|
||||
|
||||
#if SUPPORT_LINKS
|
||||
if(!kept && preserve_links && S_ISLNK(file->mode)) {
|
||||
extern int safe_symlinks;
|
||||
if (safe_symlinks && unsafe_symlink(file->link, keep_name)) {
|
||||
if (verbose) {
|
||||
rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n",
|
||||
keep_name,file->link);
|
||||
}
|
||||
kept=1;
|
||||
}
|
||||
make_bak_dir(fname,backup_dir);
|
||||
if(do_symlink(file->link,keep_name) != 0) {
|
||||
rprintf(FERROR,"link %s -> %s : %s\n",keep_name,file->link,strerror(errno));
|
||||
};
|
||||
do_unlink(fname);
|
||||
kept=1;
|
||||
};
|
||||
#endif
|
||||
if(!kept && preserve_hard_links && check_hard_link(file)) {
|
||||
if(verbose > 1) rprintf(FINFO,"%s is a hard link\n",f_name(file));
|
||||
};
|
||||
|
||||
if(!kept && !S_ISREG(file->mode)) {
|
||||
rprintf(FINFO,"make_bak: skipping non-regular file %s\n",fname);
|
||||
}
|
||||
|
||||
/* move to keep tree if a file */
|
||||
if(!kept) {
|
||||
if (!robust_move (fname, keep_name))
|
||||
rprintf(FERROR, "keep_backup failed %s -> %s : %s\n",
|
||||
fname, keep_name, strerror(errno));
|
||||
};
|
||||
set_perms (keep_name, file, NULL, 0);
|
||||
free_file (file);
|
||||
free (file);
|
||||
|
||||
if (verbose > 1)
|
||||
rprintf (FINFO, "keep_backup %s -> %s\n", fname, keep_name);
|
||||
return 1;
|
||||
} /* keep_backup */
|
||||
|
||||
|
||||
/* main backup switch routine */
|
||||
int make_backup(char *fname)
|
||||
{
|
||||
if (backup_dir)
|
||||
return (keep_backup(fname));
|
||||
else
|
||||
return (make_simple_backup(fname));
|
||||
}
|
||||
|
||||
/* Create a backup path from the given fname, putting the result into
|
||||
* backup_dir_buf. Any new directories (compared to the prior backup
|
||||
* path) are ensured to exist as directories, replacing anything else
|
||||
* that may be in the way (e.g. a symlink). */
|
||||
static BOOL copy_valid_path(const char *fname)
|
||||
{
|
||||
const char *f;
|
||||
int val;
|
||||
BOOL ret = True;
|
||||
stat_x sx;
|
||||
char *b, *rel = backup_dir_buf + backup_dir_len, *name = rel;
|
||||
|
||||
for (f = fname, b = rel; *f && *f == *b; f++, b++) {
|
||||
if (*b == '/')
|
||||
name = b + 1;
|
||||
}
|
||||
|
||||
if (stringjoin(rel, backup_dir_remainder, fname, backup_suffix, NULL) >= backup_dir_remainder) {
|
||||
rprintf(FERROR, "backup filename too long\n");
|
||||
*name = '\0';
|
||||
return False;
|
||||
}
|
||||
|
||||
for ( ; ; name = b + 1) {
|
||||
if ((b = strchr(name, '/')) == NULL)
|
||||
return True;
|
||||
*b = '\0';
|
||||
|
||||
val = validate_backup_dir();
|
||||
if (val == 0)
|
||||
break;
|
||||
if (val < 0) {
|
||||
*name = '\0';
|
||||
return False;
|
||||
}
|
||||
|
||||
*b = '/';
|
||||
}
|
||||
|
||||
init_stat_x(&sx);
|
||||
|
||||
for ( ; b; name = b + 1, b = strchr(name, '/')) {
|
||||
*b = '\0';
|
||||
|
||||
while (do_mkdir(backup_dir_buf, ACCESSPERMS) < 0) {
|
||||
if (errno == EEXIST) {
|
||||
val = validate_backup_dir();
|
||||
if (val > 0)
|
||||
break;
|
||||
if (val == 0)
|
||||
continue;
|
||||
} else
|
||||
rsyserr(FERROR, errno, "backup mkdir %s failed", backup_dir_buf);
|
||||
*name = '\0';
|
||||
ret = False;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Try to transfer the directory settings of the actual dir
|
||||
* that the files are coming from. */
|
||||
if (x_stat(rel, &sx.st, NULL) < 0)
|
||||
rsyserr(FERROR, errno, "backup stat %s failed", full_fname(rel));
|
||||
else {
|
||||
struct file_struct *file;
|
||||
if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS)))
|
||||
continue;
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
get_acl(rel, &sx);
|
||||
cache_tmp_acl(file, &sx);
|
||||
free_acl(&sx);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
get_xattr(rel, &sx);
|
||||
cache_tmp_xattr(file, &sx);
|
||||
free_xattr(&sx);
|
||||
}
|
||||
#endif
|
||||
set_file_attrs(backup_dir_buf, file, NULL, NULL, 0);
|
||||
unmake_file(file);
|
||||
}
|
||||
|
||||
*b = '/';
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Make a complete pathname for backup file and verify any new path elements. */
|
||||
char *get_backup_name(const char *fname)
|
||||
{
|
||||
if (backup_dir) {
|
||||
static int initialized = 0;
|
||||
if (!initialized) {
|
||||
int ret;
|
||||
if (backup_dir_len > 1)
|
||||
backup_dir_buf[backup_dir_len-1] = '\0';
|
||||
ret = make_path(backup_dir_buf, 0);
|
||||
if (backup_dir_len > 1)
|
||||
backup_dir_buf[backup_dir_len-1] = '/';
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
initialized = 1;
|
||||
}
|
||||
/* copy fname into backup_dir_buf while validating the dirs. */
|
||||
if (copy_valid_path(fname))
|
||||
return backup_dir_buf;
|
||||
/* copy_valid_path() has printed an error message. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (stringjoin(backup_dir_buf, MAXPATHLEN, fname, backup_suffix, NULL) < MAXPATHLEN)
|
||||
return backup_dir_buf;
|
||||
|
||||
rprintf(FERROR, "backup filename too long\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Has same return codes as make_backup(). */
|
||||
static inline int link_or_rename(const char *from, const char *to,
|
||||
BOOL prefer_rename, STRUCT_STAT *stp)
|
||||
{
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
if (!prefer_rename) {
|
||||
#ifndef CAN_HARDLINK_SYMLINK
|
||||
if (S_ISLNK(stp->st_mode))
|
||||
return 0; /* Use copy code. */
|
||||
#endif
|
||||
#ifndef CAN_HARDLINK_SPECIAL
|
||||
if (IS_SPECIAL(stp->st_mode) || IS_DEVICE(stp->st_mode))
|
||||
return 0; /* Use copy code. */
|
||||
#endif
|
||||
if (do_link(from, to) == 0) {
|
||||
if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: HLINK %s successful.\n", from);
|
||||
return 2;
|
||||
}
|
||||
/* We prefer to rename a regular file rather than copy it. */
|
||||
if (!S_ISREG(stp->st_mode) || errno == EEXIST || errno == EISDIR)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (do_rename(from, to) == 0) {
|
||||
if (stp->st_nlink > 1 && !S_ISDIR(stp->st_mode)) {
|
||||
/* If someone has hard-linked the file into the backup
|
||||
* dir, rename() might return success but do nothing! */
|
||||
robust_unlink(from); /* Just in case... */
|
||||
}
|
||||
if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: RENAME %s successful.\n", from);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hard-link, rename, or copy an item to the backup name. Returns 0 for
|
||||
* failure, 1 if item was moved, 2 if item was duplicated or hard linked
|
||||
* into backup area, or 3 if item doesn't exist or isn't a regular file. */
|
||||
int make_backup(const char *fname, BOOL prefer_rename)
|
||||
{
|
||||
stat_x sx;
|
||||
struct file_struct *file;
|
||||
int save_preserve_xattrs;
|
||||
char *buf;
|
||||
int ret = 0;
|
||||
|
||||
init_stat_x(&sx);
|
||||
/* Return success if no file to keep. */
|
||||
if (x_lstat(fname, &sx.st, NULL) < 0)
|
||||
return 3;
|
||||
|
||||
if (!(buf = get_backup_name(fname)))
|
||||
return 0;
|
||||
|
||||
/* Try a hard-link or a rename first. Using rename is not atomic, but
|
||||
* is more efficient than forcing a copy for larger files when no hard-
|
||||
* linking is possible. */
|
||||
if ((ret = link_or_rename(fname, buf, prefer_rename, &sx.st)) != 0)
|
||||
goto success;
|
||||
if (errno == EEXIST || errno == EISDIR) {
|
||||
STRUCT_STAT bakst;
|
||||
if (do_lstat(buf, &bakst) == 0) {
|
||||
int flags = get_del_for_flag(bakst.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
|
||||
if (delete_item(buf, bakst.st_mode, flags) != 0)
|
||||
return 0;
|
||||
}
|
||||
if ((ret = link_or_rename(fname, buf, prefer_rename, &sx.st)) != 0)
|
||||
goto success;
|
||||
}
|
||||
|
||||
/* Fall back to making a copy. */
|
||||
if (!(file = make_file(fname, NULL, &sx.st, 0, NO_FILTERS)))
|
||||
return 3; /* the file could have disappeared */
|
||||
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
get_acl(fname, &sx);
|
||||
cache_tmp_acl(file, &sx);
|
||||
free_acl(&sx);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
get_xattr(fname, &sx);
|
||||
cache_tmp_xattr(file, &sx);
|
||||
free_xattr(&sx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check to see if this is a device file, or link */
|
||||
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|
||||
|| (preserve_specials && IS_SPECIAL(file->mode))) {
|
||||
if (do_mknod(buf, file->mode, sx.st.st_rdev) < 0)
|
||||
rsyserr(FERROR, errno, "mknod %s failed", full_fname(buf));
|
||||
else if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: DEVICE %s successful.\n", fname);
|
||||
ret = 2;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
if (!ret && preserve_links && S_ISLNK(file->mode)) {
|
||||
const char *sl = F_SYMLINK(file);
|
||||
if (safe_symlinks && unsafe_symlink(sl, fname)) {
|
||||
if (INFO_GTE(SYMSAFE, 1)) {
|
||||
rprintf(FINFO, "not backing up unsafe symlink \"%s\" -> \"%s\"\n",
|
||||
fname, sl);
|
||||
}
|
||||
ret = 2;
|
||||
} else {
|
||||
if (do_symlink(sl, buf) < 0)
|
||||
rsyserr(FERROR, errno, "link %s -> \"%s\"", full_fname(buf), sl);
|
||||
else if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: SYMLINK %s successful.\n", fname);
|
||||
ret = 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ret && !S_ISREG(file->mode)) {
|
||||
rprintf(FINFO, "make_bak: skipping non-regular file %s\n", fname);
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* Copy to backup tree if a file. */
|
||||
if (!ret) {
|
||||
if (copy_file(fname, buf, -1, file->mode) < 0) {
|
||||
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
|
||||
full_fname(fname), buf);
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if (DEBUG_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "make_backup: COPY %s successful.\n", fname);
|
||||
ret = 2;
|
||||
}
|
||||
|
||||
save_preserve_xattrs = preserve_xattrs;
|
||||
preserve_xattrs = 0;
|
||||
set_file_attrs(buf, file, NULL, fname, 0);
|
||||
preserve_xattrs = save_preserve_xattrs;
|
||||
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
|
||||
success:
|
||||
if (INFO_GTE(BACKUP, 1))
|
||||
rprintf(FINFO, "backed up %s to %s\n", fname, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
811
batch.c
811
batch.c
@@ -1,610 +1,283 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Weiss 1/1999
|
||||
Batch utilities for rsync.
|
||||
|
||||
*/
|
||||
/*
|
||||
* Support for the batch-file options.
|
||||
*
|
||||
* Copyright (C) 1999 Weiss
|
||||
* Copyright (C) 2004 Chris Shoemaker
|
||||
* Copyright (C) 2004-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include <zlib.h>
|
||||
#include <time.h>
|
||||
|
||||
extern char *batch_prefix;
|
||||
extern int eol_nulls;
|
||||
extern int recurse;
|
||||
extern int xfer_dirs;
|
||||
extern int preserve_links;
|
||||
extern int preserve_hard_links;
|
||||
extern int preserve_devices;
|
||||
extern int preserve_uid;
|
||||
extern int preserve_gid;
|
||||
extern int preserve_acls;
|
||||
extern int preserve_xattrs;
|
||||
extern int always_checksum;
|
||||
extern int do_compression;
|
||||
extern int inplace;
|
||||
extern int append_mode;
|
||||
extern int protocol_version;
|
||||
extern char *batch_name;
|
||||
#ifdef ICONV_OPTION
|
||||
extern char *iconv_opt;
|
||||
#endif
|
||||
|
||||
struct file_list *batch_flist;
|
||||
extern filter_rule_list filter_list;
|
||||
|
||||
static char rsync_flist_file[] = ".rsync_flist";
|
||||
static char rsync_csums_file[] = ".rsync_csums";
|
||||
static char rsync_delta_file[] = ".rsync_delta";
|
||||
static char rsync_argvs_file[] = ".rsync_argvs";
|
||||
int batch_stream_flags;
|
||||
|
||||
static int fdb;
|
||||
static int fdb_delta;
|
||||
static int fdb_open;
|
||||
static int fdb_close;
|
||||
static int tweaked_append;
|
||||
static int tweaked_append_verify;
|
||||
static int tweaked_iconv;
|
||||
|
||||
void write_batch_flist_file(char *buff, int bytes_to_write)
|
||||
static int *flag_ptr[] = {
|
||||
&recurse, /* 0 */
|
||||
&preserve_uid, /* 1 */
|
||||
&preserve_gid, /* 2 */
|
||||
&preserve_links, /* 3 */
|
||||
&preserve_devices, /* 4 */
|
||||
&preserve_hard_links, /* 5 */
|
||||
&always_checksum, /* 6 */
|
||||
&xfer_dirs, /* 7 (protocol 29) */
|
||||
&do_compression, /* 8 (protocol 29) */
|
||||
&tweaked_iconv, /* 9 (protocol 30) */
|
||||
&preserve_acls, /* 10 (protocol 30) */
|
||||
&preserve_xattrs, /* 11 (protocol 30) */
|
||||
&inplace, /* 12 (protocol 30) */
|
||||
&tweaked_append, /* 13 (protocol 30) */
|
||||
&tweaked_append_verify, /* 14 (protocol 30) */
|
||||
NULL
|
||||
};
|
||||
|
||||
static char *flag_name[] = {
|
||||
"--recurse (-r)",
|
||||
"--owner (-o)",
|
||||
"--group (-g)",
|
||||
"--links (-l)",
|
||||
"--devices (-D)",
|
||||
"--hard-links (-H)",
|
||||
"--checksum (-c)",
|
||||
"--dirs (-d)",
|
||||
"--compress (-z)",
|
||||
"--iconv",
|
||||
"--acls (-A)",
|
||||
"--xattrs (-X)",
|
||||
"--inplace",
|
||||
"--append",
|
||||
"--append-verify",
|
||||
NULL
|
||||
};
|
||||
|
||||
void write_stream_flags(int fd)
|
||||
{
|
||||
char filename[MAXPATHLEN];
|
||||
int i, flags;
|
||||
|
||||
if (fdb_open) {
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_flist_file, sizeof(filename));
|
||||
tweaked_append = append_mode == 1;
|
||||
tweaked_append_verify = append_mode == 2;
|
||||
#ifdef ICONV_OPTION
|
||||
tweaked_iconv = iconv_opt != NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Open batch flist file for writing;
|
||||
* create it if it doesn't exist
|
||||
*/
|
||||
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IREAD | S_IWRITE);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
fdb_open = 0;
|
||||
}
|
||||
|
||||
/* Write buffer to batch flist file */
|
||||
|
||||
if (write(fdb, buff, bytes_to_write) == -1) {
|
||||
rprintf(FERROR, "Batch file %s write error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
if (fdb_close) {
|
||||
close(fdb);
|
||||
/* Start the batch file with a bitmap of data-stream-affecting
|
||||
* flags. */
|
||||
for (i = 0, flags = 0; flag_ptr[i]; i++) {
|
||||
if (*flag_ptr[i])
|
||||
flags |= 1 << i;
|
||||
}
|
||||
write_int(fd, flags);
|
||||
}
|
||||
|
||||
void write_batch_flist_info(int flist_count, struct file_struct **fptr)
|
||||
void read_stream_flags(int fd)
|
||||
{
|
||||
batch_stream_flags = read_int(fd);
|
||||
}
|
||||
|
||||
void check_batch_flags(void)
|
||||
{
|
||||
int i;
|
||||
int bytes_to_write;
|
||||
|
||||
/* Write flist info to batch file */
|
||||
|
||||
bytes_to_write =
|
||||
sizeof(unsigned) +
|
||||
sizeof(time_t) +
|
||||
sizeof(OFF_T) +
|
||||
sizeof(mode_t) +
|
||||
sizeof(INO64_T) +
|
||||
sizeof(DEV64_T) +
|
||||
sizeof(DEV64_T) +
|
||||
sizeof(uid_t) +
|
||||
sizeof(gid_t);
|
||||
|
||||
fdb_open = 1;
|
||||
fdb_close = 0;
|
||||
|
||||
for (i = 0; i < flist_count; i++) {
|
||||
write_batch_flist_file((char *) fptr[i], bytes_to_write);
|
||||
write_char_bufs(fptr[i]->basename);
|
||||
write_char_bufs(fptr[i]->dirname);
|
||||
write_char_bufs(fptr[i]->basedir);
|
||||
write_char_bufs(fptr[i]->link);
|
||||
if (i == flist_count - 1) {
|
||||
fdb_close = 1;
|
||||
}
|
||||
write_char_bufs(fptr[i]->sum);
|
||||
}
|
||||
}
|
||||
|
||||
void write_char_bufs(char *buf)
|
||||
{
|
||||
/* Write the size of the string which will follow */
|
||||
|
||||
char b[4];
|
||||
|
||||
SIVAL(b, 0, buf != NULL ? strlen(buf) : 0);
|
||||
|
||||
write_batch_flist_file(b, sizeof(int));
|
||||
|
||||
/* Write the string if there is one */
|
||||
|
||||
if (buf != NULL) {
|
||||
write_batch_flist_file(buf, strlen(buf));
|
||||
}
|
||||
}
|
||||
|
||||
void write_batch_argvs_file(int argc, char *argv[])
|
||||
{
|
||||
int fdb;
|
||||
int i;
|
||||
char buff[256]; /* XXX */
|
||||
char buff2[MAXPATHLEN + 6];
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_argvs_file, sizeof(filename));
|
||||
|
||||
/*
|
||||
* Open batch argvs file for writing;
|
||||
* create it if it doesn't exist
|
||||
*/
|
||||
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IREAD | S_IWRITE | S_IEXEC);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
buff[0] = '\0';
|
||||
|
||||
/* Write argvs info to batch file */
|
||||
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (i == argc - 2) /* Skip source directory on cmdline */
|
||||
continue;
|
||||
/*
|
||||
* FIXME:
|
||||
* I think directly manipulating argv[] is probably bogus
|
||||
*/
|
||||
if (!strncmp(argv[i], "--write-batch",
|
||||
strlen("--write-batch"))) {
|
||||
/* Safer to change it here than script */
|
||||
/*
|
||||
* Change to --read-batch=prefix
|
||||
* to get ready for remote
|
||||
*/
|
||||
strlcat(buff, "--read-batch=", sizeof(buff));
|
||||
strlcat(buff, batch_prefix, sizeof(buff));
|
||||
} else
|
||||
if (i == argc - 1) {
|
||||
snprintf(buff2, sizeof(buff2), "${1:-%s}", argv[i]);
|
||||
strlcat(buff, buff2, sizeof(buff));
|
||||
}
|
||||
else {
|
||||
strlcat(buff, argv[i], sizeof(buff));
|
||||
}
|
||||
|
||||
if (i < (argc - 1)) {
|
||||
strlcat(buff, " ", sizeof(buff));
|
||||
}
|
||||
}
|
||||
strlcat(buff, "\n", sizeof(buff));
|
||||
if (!write(fdb, buff, strlen(buff))) {
|
||||
rprintf(FERROR, "Batch file %s write error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
close(fdb);
|
||||
}
|
||||
|
||||
struct file_list *create_flist_from_batch(void)
|
||||
{
|
||||
unsigned char flags;
|
||||
|
||||
fdb_open = 1;
|
||||
fdb_close = 0;
|
||||
|
||||
batch_flist = (struct file_list *) malloc(sizeof(batch_flist[0]));
|
||||
if (!batch_flist) {
|
||||
out_of_memory("create_flist_from_batch");
|
||||
}
|
||||
batch_flist->count = 0;
|
||||
batch_flist->malloced = 1000;
|
||||
batch_flist->files =
|
||||
(struct file_struct **) malloc(sizeof(batch_flist->files[0]) *
|
||||
batch_flist->malloced);
|
||||
if (!batch_flist->files) {
|
||||
out_of_memory("create_flist_from_batch");
|
||||
}
|
||||
|
||||
for (flags = read_batch_flags(); flags; flags = read_batch_flags()) {
|
||||
|
||||
int i = batch_flist->count;
|
||||
|
||||
if (i >= batch_flist->malloced) {
|
||||
if (batch_flist->malloced < 1000)
|
||||
batch_flist->malloced += 1000;
|
||||
else
|
||||
batch_flist->malloced *= 2;
|
||||
batch_flist->files =
|
||||
(struct file_struct **) realloc(batch_flist->
|
||||
files,
|
||||
sizeof
|
||||
(batch_flist->
|
||||
files[0]) *
|
||||
batch_flist->
|
||||
malloced);
|
||||
if (!batch_flist->files)
|
||||
out_of_memory("create_flist_from_batch");
|
||||
}
|
||||
read_batch_flist_info(&batch_flist->files[i]);
|
||||
batch_flist->files[i]->flags = flags;
|
||||
|
||||
batch_flist->count++;
|
||||
}
|
||||
|
||||
return batch_flist;
|
||||
}
|
||||
|
||||
int read_batch_flist_file(char *buff, int len)
|
||||
{
|
||||
int bytes_read;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_open) {
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_flist_file, sizeof(filename));
|
||||
|
||||
/* Open batch flist file for reading */
|
||||
fdb = do_open(filename, O_RDONLY, 0);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
fdb_open = 0;
|
||||
}
|
||||
|
||||
/* Read flist batch file */
|
||||
|
||||
switch (bytes_read = read(fdb, buff, len)) {
|
||||
case -1:
|
||||
rprintf(FERROR, "Batch file %s read error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
break;
|
||||
case 0: /* EOF */
|
||||
close(fdb);
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
unsigned char read_batch_flags(void)
|
||||
{
|
||||
int flags;
|
||||
|
||||
if (read_batch_flist_file((char *) &flags, 4)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void read_batch_flist_info(struct file_struct **fptr)
|
||||
{
|
||||
int int_str_len;
|
||||
char char_str_len[4];
|
||||
char buff[256];
|
||||
struct file_struct *file;
|
||||
|
||||
file = (struct file_struct *) malloc(sizeof(*file));
|
||||
if (!file)
|
||||
out_of_memory("read_batch_flist_info");
|
||||
memset((char *) file, 0, sizeof(*file));
|
||||
|
||||
*fptr = file;
|
||||
|
||||
/*
|
||||
* Keep these in sync with bytes_to_write assignment
|
||||
* in write_batch_flist_info()
|
||||
*/
|
||||
read_batch_flist_file((char *) &file->modtime, sizeof(time_t));
|
||||
read_batch_flist_file((char *) &file->length, sizeof(OFF_T));
|
||||
read_batch_flist_file((char *) &file->mode, sizeof(mode_t));
|
||||
read_batch_flist_file((char *) &file->inode, sizeof(INO64_T));
|
||||
read_batch_flist_file((char *) &file->dev, sizeof(DEV64_T));
|
||||
read_batch_flist_file((char *) &file->rdev, sizeof(DEV64_T));
|
||||
read_batch_flist_file((char *) &file->uid, sizeof(uid_t));
|
||||
read_batch_flist_file((char *) &file->gid, sizeof(gid_t));
|
||||
read_batch_flist_file(char_str_len, sizeof(char_str_len));
|
||||
int_str_len = IVAL(char_str_len, 0);
|
||||
if (int_str_len > 0) {
|
||||
read_batch_flist_file(buff, int_str_len);
|
||||
buff[int_str_len] = '\0';
|
||||
file->basename = strdup(buff);
|
||||
} else {
|
||||
file->basename = NULL;
|
||||
}
|
||||
|
||||
read_batch_flist_file(char_str_len, sizeof(char_str_len));
|
||||
int_str_len = IVAL(char_str_len, 0);
|
||||
if (int_str_len > 0) {
|
||||
read_batch_flist_file(buff, int_str_len);
|
||||
buff[int_str_len] = '\0';
|
||||
file[0].dirname = strdup(buff);
|
||||
} else {
|
||||
file[0].dirname = NULL;
|
||||
}
|
||||
|
||||
read_batch_flist_file(char_str_len, sizeof(char_str_len));
|
||||
int_str_len = IVAL(char_str_len, 0);
|
||||
if (int_str_len > 0) {
|
||||
read_batch_flist_file(buff, int_str_len);
|
||||
buff[int_str_len] = '\0';
|
||||
file[0].basedir = strdup(buff);
|
||||
} else {
|
||||
file[0].basedir = NULL;
|
||||
}
|
||||
|
||||
read_batch_flist_file(char_str_len, sizeof(char_str_len));
|
||||
int_str_len = IVAL(char_str_len, 0);
|
||||
if (int_str_len > 0) {
|
||||
read_batch_flist_file(buff, int_str_len);
|
||||
buff[int_str_len] = '\0';
|
||||
file[0].link = strdup(buff);
|
||||
} else {
|
||||
file[0].link = NULL;
|
||||
}
|
||||
|
||||
read_batch_flist_file(char_str_len, sizeof(char_str_len));
|
||||
int_str_len = IVAL(char_str_len, 0);
|
||||
if (int_str_len > 0) {
|
||||
read_batch_flist_file(buff, int_str_len);
|
||||
buff[int_str_len] = '\0';
|
||||
file[0].sum = strdup(buff);
|
||||
} else {
|
||||
file[0].sum = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void write_batch_csums_file(void *buff, int bytes_to_write)
|
||||
{
|
||||
static int fdb_open = 1;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_open) {
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_csums_file, sizeof(filename));
|
||||
|
||||
/*
|
||||
* Open batch csums file for writing;
|
||||
* create it if it doesn't exist
|
||||
*/
|
||||
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IREAD | S_IWRITE);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
fdb_open = 0;
|
||||
}
|
||||
|
||||
/* Write buffer to batch csums file */
|
||||
|
||||
if (write(fdb, buff, bytes_to_write) == -1) {
|
||||
rprintf(FERROR, "Batch file %s write error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
}
|
||||
|
||||
void close_batch_csums_file(void)
|
||||
{
|
||||
close(fdb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write csum info to batch file
|
||||
*
|
||||
* @todo This will break if s->count is ever larger than maxint. The
|
||||
* batch code should probably be changed to consistently use the
|
||||
* variable-length integer routines, which is probably a compatible
|
||||
* change.
|
||||
**/
|
||||
void write_batch_csum_info(int *flist_entry, int flist_count,
|
||||
struct sum_struct *s)
|
||||
{
|
||||
size_t i;
|
||||
int int_count;
|
||||
extern int csum_length;
|
||||
|
||||
fdb_open = 1;
|
||||
|
||||
write_batch_csums_file(flist_entry, sizeof(int));
|
||||
int_count = s ? (int) s->count : 0;
|
||||
write_batch_csums_file(&int_count, sizeof int_count);
|
||||
|
||||
if (s) {
|
||||
for (i = 0; i < s->count; i++) {
|
||||
write_batch_csums_file(&s->sums[i].sum1, sizeof(uint32));
|
||||
if ((*flist_entry == flist_count - 1)
|
||||
&& (i == s->count - 1)) {
|
||||
fdb_close = 1;
|
||||
if (protocol_version < 29)
|
||||
flag_ptr[7] = NULL;
|
||||
else if (protocol_version < 30)
|
||||
flag_ptr[9] = NULL;
|
||||
tweaked_append = append_mode == 1;
|
||||
tweaked_append_verify = append_mode == 2;
|
||||
#ifdef ICONV_OPTION
|
||||
tweaked_iconv = iconv_opt != NULL;
|
||||
#endif
|
||||
for (i = 0; flag_ptr[i]; i++) {
|
||||
int set = batch_stream_flags & (1 << i) ? 1 : 0;
|
||||
if (*flag_ptr[i] != set) {
|
||||
if (i == 9) {
|
||||
rprintf(FERROR,
|
||||
"%s specify the --iconv option to use this batch file.\n",
|
||||
set ? "Please" : "Do not");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
write_batch_csums_file(s->sums[i].sum2, csum_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int read_batch_csums_file(char *buff, int len)
|
||||
{
|
||||
static int fdb_open = 1;
|
||||
int bytes_read;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_open) {
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_csums_file, sizeof(filename));
|
||||
|
||||
/* Open batch flist file for reading */
|
||||
fdb = do_open(filename, O_RDONLY, 0);
|
||||
if (fdb == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
fdb_open = 0;
|
||||
}
|
||||
|
||||
/* Read csums batch file */
|
||||
|
||||
bytes_read = read(fdb, buff, len);
|
||||
|
||||
if (bytes_read == -1) {
|
||||
rprintf(FERROR, "Batch file %s read error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
void read_batch_csum_info(int flist_entry, struct sum_struct *s,
|
||||
int *checksums_match)
|
||||
{
|
||||
int i;
|
||||
int file_flist_entry;
|
||||
int file_chunk_ct;
|
||||
uint32 file_sum1;
|
||||
char file_sum2[SUM_LENGTH];
|
||||
extern int csum_length;
|
||||
|
||||
read_batch_csums_file((char *) &file_flist_entry, sizeof(int));
|
||||
if (file_flist_entry != flist_entry) {
|
||||
rprintf(FINFO, "file_flist_entry (%d) != flist_entry (%d)\n",
|
||||
file_flist_entry, flist_entry);
|
||||
close(fdb);
|
||||
exit_cleanup(1);
|
||||
|
||||
} else {
|
||||
read_batch_csums_file((char *) &file_chunk_ct,
|
||||
sizeof(int));
|
||||
*checksums_match = 1;
|
||||
for (i = 0; i < file_chunk_ct; i++) {
|
||||
|
||||
read_batch_csums_file((char *) &file_sum1,
|
||||
sizeof(uint32));
|
||||
read_batch_csums_file(file_sum2, csum_length);
|
||||
|
||||
if ((s->sums[i].sum1 != file_sum1) ||
|
||||
(memcmp(s->sums[i].sum2, file_sum2, csum_length)
|
||||
!= 0)) {
|
||||
*checksums_match = 0;
|
||||
if (INFO_GTE(MISC, 1)) {
|
||||
rprintf(FINFO,
|
||||
"%sing the %s option to match the batchfile.\n",
|
||||
set ? "Sett" : "Clear", flag_name[i]);
|
||||
}
|
||||
} /* end for */
|
||||
}
|
||||
}
|
||||
|
||||
void write_batch_delta_file(char *buff, int bytes_to_write)
|
||||
{
|
||||
static int fdb_delta_open = 1;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_delta_open) {
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_delta_file, sizeof(filename));
|
||||
|
||||
/*
|
||||
* Open batch delta file for writing;
|
||||
* create it if it doesn't exist
|
||||
*/
|
||||
fdb_delta = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IREAD | S_IWRITE);
|
||||
if (fdb_delta == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb_delta);
|
||||
exit_cleanup(1);
|
||||
*flag_ptr[i] = set;
|
||||
}
|
||||
fdb_delta_open = 0;
|
||||
}
|
||||
if (protocol_version < 29) {
|
||||
if (recurse)
|
||||
xfer_dirs |= 1;
|
||||
else if (xfer_dirs < 2)
|
||||
xfer_dirs = 0;
|
||||
}
|
||||
|
||||
/* Write buffer to batch delta file */
|
||||
if (tweaked_append)
|
||||
append_mode = 1;
|
||||
else if (tweaked_append_verify)
|
||||
append_mode = 2;
|
||||
}
|
||||
|
||||
if (write(fdb_delta, buff, bytes_to_write) == -1) {
|
||||
rprintf(FERROR, "Batch file %s write error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb_delta);
|
||||
exit_cleanup(1);
|
||||
static int write_arg(int fd, char *arg)
|
||||
{
|
||||
char *x, *s;
|
||||
int len, ret = 0;
|
||||
|
||||
if (*arg == '-' && (x = strchr(arg, '=')) != NULL) {
|
||||
if (write(fd, arg, x - arg + 1) != x - arg + 1)
|
||||
ret = -1;
|
||||
arg += x - arg + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void close_batch_delta_file(void)
|
||||
{
|
||||
close(fdb_delta);
|
||||
}
|
||||
|
||||
int read_batch_delta_file(char *buff, int len)
|
||||
{
|
||||
static int fdb_delta_open = 1;
|
||||
int bytes_read;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
if (fdb_delta_open) {
|
||||
/* Set up file extension */
|
||||
strlcpy(filename, batch_prefix, sizeof(filename));
|
||||
strlcat(filename, rsync_delta_file, sizeof(filename));
|
||||
|
||||
/* Open batch flist file for reading */
|
||||
fdb_delta = do_open(filename, O_RDONLY, 0);
|
||||
if (fdb_delta == -1) {
|
||||
rprintf(FERROR, "Batch file %s open error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb_delta);
|
||||
exit_cleanup(1);
|
||||
if (strpbrk(arg, " \"'&;|[]()$#!*?^\\") != NULL) {
|
||||
if (write(fd, "'", 1) != 1)
|
||||
ret = -1;
|
||||
for (s = arg; (x = strchr(s, '\'')) != NULL; s = x + 1) {
|
||||
if (write(fd, s, x - s + 1) != x - s + 1
|
||||
|| write(fd, "'", 1) != 1)
|
||||
ret = -1;
|
||||
}
|
||||
fdb_delta_open = 0;
|
||||
len = strlen(s);
|
||||
if (write(fd, s, len) != len
|
||||
|| write(fd, "'", 1) != 1)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read delta batch file */
|
||||
len = strlen(arg);
|
||||
if (write(fd, arg, len) != len)
|
||||
ret = -1;
|
||||
|
||||
bytes_read = read(fdb_delta, buff, len);
|
||||
|
||||
if (bytes_read == -1) {
|
||||
rprintf(FERROR, "Batch file %s read error: %s\n",
|
||||
filename, strerror(errno));
|
||||
close(fdb_delta);
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void show_flist(int index, struct file_struct **fptr)
|
||||
static void write_filter_rules(int fd)
|
||||
{
|
||||
/* for debugging show_flist(flist->count, flist->files * */
|
||||
filter_rule *ent;
|
||||
|
||||
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", fptr[i]->basename);
|
||||
if (fptr[i]->dirname)
|
||||
rprintf(FINFO, "flist->dirname=%s\n",
|
||||
fptr[i]->dirname);
|
||||
if (fptr[i]->basedir)
|
||||
rprintf(FINFO, "flist->basedir=%s\n",
|
||||
fptr[i]->basedir);
|
||||
write_sbuf(fd, " <<'#E#'\n");
|
||||
for (ent = filter_list.head; ent; ent = ent->next) {
|
||||
unsigned int plen;
|
||||
char *p = get_rule_prefix(ent, "- ", 0, &plen);
|
||||
write_buf(fd, p, plen);
|
||||
write_sbuf(fd, ent->pattern);
|
||||
if (ent->rflags & FILTRULE_DIRECTORY)
|
||||
write_byte(fd, '/');
|
||||
write_byte(fd, eol_nulls ? 0 : '\n');
|
||||
}
|
||||
if (eol_nulls)
|
||||
write_sbuf(fd, ";\n");
|
||||
write_sbuf(fd, "#E#");
|
||||
}
|
||||
|
||||
void show_argvs(int argc, char *argv[])
|
||||
/* This routine tries to write out an equivalent --read-batch command
|
||||
* given the user's --write-batch args. However, it doesn't really
|
||||
* understand most of the options, so it uses some overly simple
|
||||
* heuristics to munge the command line into something that will
|
||||
* (hopefully) work. */
|
||||
void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
|
||||
{
|
||||
/* for debugging * */
|
||||
int fd, i, len, err = 0;
|
||||
char *p, filename[MAXPATHLEN];
|
||||
|
||||
int i;
|
||||
rprintf(FINFO, "BATCH.C:show_argvs,argc=%d\n", argc);
|
||||
for (i = 0; i < argc; i++) {
|
||||
/* if (argv[i]) */
|
||||
rprintf(FINFO, "i=%d,argv[i]=%s\n", i, argv[i]);
|
||||
stringjoin(filename, sizeof filename,
|
||||
batch_name, ".sh", NULL);
|
||||
fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
if (fd < 0) {
|
||||
rsyserr(FERROR, errno, "Batch file %s open error",
|
||||
filename);
|
||||
exit_cleanup(RERR_FILESELECT);
|
||||
}
|
||||
|
||||
/* Write argvs info to BATCH.sh file */
|
||||
if (write_arg(fd, argv[0]) < 0)
|
||||
err = 1;
|
||||
if (filter_list.head) {
|
||||
if (protocol_version >= 29)
|
||||
write_sbuf(fd, " --filter=._-");
|
||||
else
|
||||
write_sbuf(fd, " --exclude-from=-");
|
||||
}
|
||||
for (i = 1; i < argc - file_arg_cnt; i++) {
|
||||
p = argv[i];
|
||||
if (strncmp(p, "--files-from", 12) == 0
|
||||
|| strncmp(p, "--filter", 8) == 0
|
||||
|| strncmp(p, "--include", 9) == 0
|
||||
|| strncmp(p, "--exclude", 9) == 0) {
|
||||
if (strchr(p, '=') == NULL)
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(p, "-f") == 0) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (write(fd, " ", 1) != 1)
|
||||
err = 1;
|
||||
if (strncmp(p, "--write-batch", len = 13) == 0
|
||||
|| strncmp(p, "--only-write-batch", len = 18) == 0) {
|
||||
if (write(fd, "--read-batch", 12) != 12)
|
||||
err = 1;
|
||||
if (p[len] == '=') {
|
||||
if (write(fd, "=", 1) != 1
|
||||
|| write_arg(fd, p + len + 1) < 0)
|
||||
err = 1;
|
||||
}
|
||||
} else {
|
||||
if (write_arg(fd, p) < 0)
|
||||
err = 1;
|
||||
}
|
||||
}
|
||||
if (!(p = check_for_hostspec(argv[argc - 1], &p, &i)))
|
||||
p = argv[argc - 1];
|
||||
if (write(fd, " ${1:-", 6) != 6
|
||||
|| write_arg(fd, p) < 0)
|
||||
err = 1;
|
||||
write_byte(fd, '}');
|
||||
if (filter_list.head)
|
||||
write_filter_rules(fd);
|
||||
if (write(fd, "\n", 1) != 1 || close(fd) < 0 || err) {
|
||||
rsyserr(FERROR, errno, "Batch file %s write error",
|
||||
filename);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
}
|
||||
|
||||
140
byteorder.h
140
byteorder.h
@@ -1,27 +1,29 @@
|
||||
/*
|
||||
simple byteorder handling
|
||||
Copyright (C) Andrew Tridgell 1992-1995
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Simple byteorder handling.
|
||||
*
|
||||
* Copyright (C) 1992-1995 Andrew Tridgell
|
||||
* Copyright (C) 2007-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#undef CAREFUL_ALIGNMENT
|
||||
#undef AVOID_BYTEORDER_INLINE
|
||||
|
||||
/* we know that the x86 can handle misalignment and has the "right"
|
||||
byteorder */
|
||||
#ifdef __i386__
|
||||
/* We know that the x86 can handle misalignment and has the same
|
||||
* byte order (LSB-first) as the 32-bit numbers we transmit. */
|
||||
#if defined __i386__ || defined __i486__ || defined __i586__ || defined __i686__ || __amd64
|
||||
#define CAREFUL_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
@@ -30,25 +32,93 @@
|
||||
#endif
|
||||
|
||||
#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
|
||||
#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
|
||||
#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
|
||||
|
||||
#define UVAL(buf,pos) ((uint32)CVAL(buf,pos))
|
||||
|
||||
#if CAREFUL_ALIGNMENT
|
||||
#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
|
||||
#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
|
||||
|
||||
#define PVAL(buf,pos) (UVAL(buf,pos)|UVAL(buf,(pos)+1)<<8)
|
||||
#define IVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+2)<<16)
|
||||
#define IVAL64(buf,pos) (IVAL(buf,pos)|(int64)IVAL(buf,(pos)+4)<<32)
|
||||
#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
|
||||
#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
|
||||
#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
|
||||
#else
|
||||
/* this handles things for architectures like the 386 that can handle
|
||||
alignment errors */
|
||||
/*
|
||||
WARNING: This section is dependent on the length of int32
|
||||
being correct. set CAREFUL_ALIGNMENT if it is not.
|
||||
*/
|
||||
#define SIVAL(buf,pos,val) SIVALX(buf,pos,(uint32)(val))
|
||||
#define SIVAL64(buf,pos,val) (SIVAL(buf,pos,val),SIVAL(buf,(pos)+4,(val)>>32))
|
||||
|
||||
#define IVALu(buf,pos) IVAL(buf,pos)
|
||||
#define SIVALu(buf,pos,val) SIVAL(buf,pos,val)
|
||||
|
||||
#else /* !CAREFUL_ALIGNMENT */
|
||||
|
||||
/* This handles things for architectures like the 386 that can handle alignment errors.
|
||||
* WARNING: This section is dependent on the length of an int32 (and thus a uint32)
|
||||
* being correct (4 bytes)! Set CAREFUL_ALIGNMENT if it is not. */
|
||||
|
||||
# ifdef AVOID_BYTEORDER_INLINE
|
||||
|
||||
#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
|
||||
#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
|
||||
#endif
|
||||
|
||||
#define IVALu(buf,pos) IVAL(buf,pos)
|
||||
#define SIVALu(buf,pos,val) SIVAL(buf,pos,val)
|
||||
|
||||
# else /* !AVOID_BYTEORDER_INLINE */
|
||||
|
||||
static inline uint32
|
||||
IVALu(const uchar *buf, int pos)
|
||||
{
|
||||
union {
|
||||
const uchar *b;
|
||||
const uint32 *num;
|
||||
} u;
|
||||
u.b = buf + pos;
|
||||
return *u.num;
|
||||
}
|
||||
|
||||
static inline void
|
||||
SIVALu(uchar *buf, int pos, uint32 val)
|
||||
{
|
||||
union {
|
||||
uchar *b;
|
||||
uint32 *num;
|
||||
} u;
|
||||
u.b = buf + pos;
|
||||
*u.num = val;
|
||||
}
|
||||
|
||||
static inline uint32
|
||||
IVAL(const char *buf, int pos)
|
||||
{
|
||||
return IVALu((uchar*)buf, pos);
|
||||
}
|
||||
|
||||
static inline void
|
||||
SIVAL(char *buf, int pos, uint32 val)
|
||||
{
|
||||
SIVALu((uchar*)buf, pos, val);
|
||||
}
|
||||
|
||||
static inline int64
|
||||
IVAL64(const char *buf, int pos)
|
||||
{
|
||||
union {
|
||||
const char *b;
|
||||
const int64 *num;
|
||||
} u;
|
||||
u.b = buf + pos;
|
||||
return *u.num;
|
||||
}
|
||||
|
||||
static inline void
|
||||
SIVAL64(char *buf, int pos, int64 val)
|
||||
{
|
||||
union {
|
||||
char *b;
|
||||
int64 *num;
|
||||
} u;
|
||||
u.b = buf + pos;
|
||||
*u.num = val;
|
||||
}
|
||||
|
||||
# endif /* !AVOID_BYTEORDER_INLINE */
|
||||
|
||||
#endif /* !CAREFUL_ALIGNMENT */
|
||||
|
||||
76
case_N.h
Normal file
76
case_N.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Allow an arbitrary sequence of case labels.
|
||||
*
|
||||
* Copyright (C) 2006-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
/* This is included multiple times, once for every segement in a switch statement.
|
||||
* This produces the next "case N:" statement in sequence. */
|
||||
|
||||
#if !defined CASE_N_STATE_0
|
||||
#define CASE_N_STATE_0
|
||||
case 0:
|
||||
#elif !defined CASE_N_STATE_1
|
||||
#define CASE_N_STATE_1
|
||||
case 1:
|
||||
#elif !defined CASE_N_STATE_2
|
||||
#define CASE_N_STATE_2
|
||||
case 2:
|
||||
#elif !defined CASE_N_STATE_3
|
||||
#define CASE_N_STATE_3
|
||||
case 3:
|
||||
#elif !defined CASE_N_STATE_4
|
||||
#define CASE_N_STATE_4
|
||||
case 4:
|
||||
#elif !defined CASE_N_STATE_5
|
||||
#define CASE_N_STATE_5
|
||||
case 5:
|
||||
#elif !defined CASE_N_STATE_6
|
||||
#define CASE_N_STATE_6
|
||||
case 6:
|
||||
#elif !defined CASE_N_STATE_7
|
||||
#define CASE_N_STATE_7
|
||||
case 7:
|
||||
#elif !defined CASE_N_STATE_8
|
||||
#define CASE_N_STATE_8
|
||||
case 8:
|
||||
#elif !defined CASE_N_STATE_9
|
||||
#define CASE_N_STATE_9
|
||||
case 9:
|
||||
#elif !defined CASE_N_STATE_10
|
||||
#define CASE_N_STATE_10
|
||||
case 10:
|
||||
#elif !defined CASE_N_STATE_11
|
||||
#define CASE_N_STATE_11
|
||||
case 11:
|
||||
#elif !defined CASE_N_STATE_12
|
||||
#define CASE_N_STATE_12
|
||||
case 12:
|
||||
#elif !defined CASE_N_STATE_13
|
||||
#define CASE_N_STATE_13
|
||||
case 13:
|
||||
#elif !defined CASE_N_STATE_14
|
||||
#define CASE_N_STATE_14
|
||||
case 14:
|
||||
#elif !defined CASE_N_STATE_15
|
||||
#define CASE_N_STATE_15
|
||||
case 15:
|
||||
#elif !defined CASE_N_STATE_16
|
||||
#define CASE_N_STATE_16
|
||||
case 16:
|
||||
#else
|
||||
#error Need to add more case statements!
|
||||
#endif
|
||||
276
checksum.c
276
checksum.c
@@ -1,46 +1,45 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Routines to support checksumming of bytes.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2004-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
int csum_length=2; /* initial value */
|
||||
|
||||
#define CSUM_CHUNK 64
|
||||
|
||||
int checksum_seed = 0;
|
||||
extern int remote_version;
|
||||
extern int checksum_seed;
|
||||
extern int protocol_version;
|
||||
extern int proper_seed_order;
|
||||
|
||||
/*
|
||||
a simple 32 bit checksum that can be upadted from either end
|
||||
(inspired by Mark Adler's Adler-32 checksum)
|
||||
*/
|
||||
uint32 get_checksum1(char *buf1,int len)
|
||||
uint32 get_checksum1(char *buf1, int32 len)
|
||||
{
|
||||
int i;
|
||||
int32 i;
|
||||
uint32 s1, s2;
|
||||
schar *buf = (schar *)buf1;
|
||||
|
||||
s1 = s2 = 0;
|
||||
for (i = 0; i < (len-4); i+=4) {
|
||||
s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] +
|
||||
s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] +
|
||||
10*CHAR_OFFSET;
|
||||
s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET);
|
||||
s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET);
|
||||
}
|
||||
for (; i < len; i++) {
|
||||
s1 += (buf[i]+CHAR_OFFSET); s2 += s1;
|
||||
@@ -49,95 +48,132 @@ uint32 get_checksum1(char *buf1,int len)
|
||||
}
|
||||
|
||||
|
||||
void get_checksum2(char *buf,int len,char *sum)
|
||||
void get_checksum2(char *buf, int32 len, char *sum)
|
||||
{
|
||||
int i;
|
||||
static char *buf1;
|
||||
static int len1;
|
||||
struct mdfour m;
|
||||
md_context m;
|
||||
|
||||
if (len > len1) {
|
||||
if (buf1) free(buf1);
|
||||
buf1 = (char *)malloc(len+4);
|
||||
len1 = len;
|
||||
if (!buf1) out_of_memory("get_checksum2");
|
||||
if (protocol_version >= 30) {
|
||||
uchar seedbuf[4];
|
||||
md5_begin(&m);
|
||||
if (proper_seed_order) {
|
||||
if (checksum_seed) {
|
||||
SIVALu(seedbuf, 0, checksum_seed);
|
||||
md5_update(&m, seedbuf, 4);
|
||||
}
|
||||
md5_update(&m, (uchar *)buf, len);
|
||||
} else {
|
||||
md5_update(&m, (uchar *)buf, len);
|
||||
if (checksum_seed) {
|
||||
SIVALu(seedbuf, 0, checksum_seed);
|
||||
md5_update(&m, seedbuf, 4);
|
||||
}
|
||||
}
|
||||
md5_result(&m, (uchar *)sum);
|
||||
} else {
|
||||
int32 i;
|
||||
static char *buf1;
|
||||
static int32 len1;
|
||||
|
||||
mdfour_begin(&m);
|
||||
|
||||
if (len > len1) {
|
||||
if (buf1)
|
||||
free(buf1);
|
||||
buf1 = new_array(char, len+4);
|
||||
len1 = len;
|
||||
if (!buf1)
|
||||
out_of_memory("get_checksum2");
|
||||
}
|
||||
|
||||
memcpy(buf1, buf, len);
|
||||
if (checksum_seed) {
|
||||
SIVAL(buf1,len,checksum_seed);
|
||||
len += 4;
|
||||
}
|
||||
|
||||
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK)
|
||||
mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK);
|
||||
|
||||
/*
|
||||
* Prior to version 27 an incorrect MD4 checksum was computed
|
||||
* by failing to call mdfour_tail() for block sizes that
|
||||
* are multiples of 64. This is fixed by calling mdfour_update()
|
||||
* even when there are no more bytes.
|
||||
*/
|
||||
if (len - i > 0 || protocol_version >= 27)
|
||||
mdfour_update(&m, (uchar *)(buf1+i), len-i);
|
||||
|
||||
mdfour_result(&m, (uchar *)sum);
|
||||
}
|
||||
|
||||
mdfour_begin(&m);
|
||||
|
||||
memcpy(buf1,buf,len);
|
||||
if (checksum_seed) {
|
||||
SIVAL(buf1,len,checksum_seed);
|
||||
len += 4;
|
||||
}
|
||||
|
||||
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
|
||||
mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK);
|
||||
}
|
||||
if (len - i > 0) {
|
||||
mdfour_update(&m, (uchar *)(buf1+i), (len-i));
|
||||
}
|
||||
|
||||
mdfour_result(&m, (uchar *)sum);
|
||||
}
|
||||
|
||||
|
||||
void file_checksum(char *fname,char *sum,OFF_T size)
|
||||
void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
|
||||
{
|
||||
OFF_T i;
|
||||
struct map_struct *buf;
|
||||
OFF_T i, len = st_p->st_size;
|
||||
md_context m;
|
||||
int32 remainder;
|
||||
int fd;
|
||||
OFF_T len = size;
|
||||
char tmpchunk[CSUM_CHUNK];
|
||||
struct mdfour m;
|
||||
|
||||
memset(sum,0,MD4_SUM_LENGTH);
|
||||
|
||||
|
||||
memset(sum, 0, MAX_DIGEST_LEN);
|
||||
|
||||
fd = do_open(fname, O_RDONLY, 0);
|
||||
if (fd == -1) return;
|
||||
|
||||
buf = map_file(fd,size);
|
||||
|
||||
mdfour_begin(&m);
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
|
||||
memcpy(tmpchunk, map_ptr(buf,i,CSUM_CHUNK), CSUM_CHUNK);
|
||||
mdfour_update(&m, (uchar *)tmpchunk, CSUM_CHUNK);
|
||||
buf = map_file(fd, len, MAX_MAP_SIZE, CSUM_CHUNK);
|
||||
|
||||
if (protocol_version >= 30) {
|
||||
md5_begin(&m);
|
||||
|
||||
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
|
||||
md5_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
|
||||
CSUM_CHUNK);
|
||||
}
|
||||
|
||||
remainder = (int32)(len - i);
|
||||
if (remainder > 0)
|
||||
md5_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
md5_result(&m, (uchar *)sum);
|
||||
} else {
|
||||
mdfour_begin(&m);
|
||||
|
||||
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
|
||||
mdfour_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
|
||||
CSUM_CHUNK);
|
||||
}
|
||||
|
||||
/* Prior to version 27 an incorrect MD4 checksum was computed
|
||||
* by failing to call mdfour_tail() for block sizes that
|
||||
* are multiples of 64. This is fixed by calling mdfour_update()
|
||||
* even when there are no more bytes. */
|
||||
remainder = (int32)(len - i);
|
||||
if (remainder > 0 || protocol_version >= 27)
|
||||
mdfour_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
|
||||
|
||||
mdfour_result(&m, (uchar *)sum);
|
||||
}
|
||||
|
||||
if (len - i > 0) {
|
||||
memcpy(tmpchunk, map_ptr(buf,i,len-i), len-i);
|
||||
mdfour_update(&m, (uchar *)tmpchunk, (len-i));
|
||||
}
|
||||
|
||||
mdfour_result(&m, (uchar *)sum);
|
||||
|
||||
close(fd);
|
||||
unmap_file(buf);
|
||||
}
|
||||
|
||||
static int32 sumresidue;
|
||||
static md_context md;
|
||||
|
||||
void checksum_init(void)
|
||||
{
|
||||
if (remote_version >= 14)
|
||||
csum_length = 2; /* adaptive */
|
||||
else
|
||||
csum_length = SUM_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int sumresidue;
|
||||
static char sumrbuf[CSUM_CHUNK];
|
||||
static struct mdfour md;
|
||||
|
||||
void sum_init(void)
|
||||
void sum_init(int seed)
|
||||
{
|
||||
char s[4];
|
||||
mdfour_begin(&md);
|
||||
sumresidue=0;
|
||||
SIVAL(s,0,checksum_seed);
|
||||
sum_update(s,4);
|
||||
|
||||
if (protocol_version >= 30)
|
||||
md5_begin(&md);
|
||||
else {
|
||||
mdfour_begin(&md);
|
||||
sumresidue = 0;
|
||||
SIVAL(s, 0, seed);
|
||||
sum_update(s, 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,41 +184,49 @@ void sum_init(void)
|
||||
* @todo Perhaps get rid of md and just pass in the address each time.
|
||||
* Very slightly clearer and slower.
|
||||
**/
|
||||
void sum_update(char *p, int len)
|
||||
void sum_update(const char *p, int32 len)
|
||||
{
|
||||
int i;
|
||||
if (protocol_version >= 30) {
|
||||
md5_update(&md, (uchar *)p, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (len + sumresidue < CSUM_CHUNK) {
|
||||
memcpy(sumrbuf+sumresidue, p, len);
|
||||
memcpy(md.buffer + sumresidue, p, len);
|
||||
sumresidue += len;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sumresidue) {
|
||||
i = MIN(CSUM_CHUNK-sumresidue,len);
|
||||
memcpy(sumrbuf+sumresidue,p,i);
|
||||
mdfour_update(&md, (uchar *)sumrbuf, (i+sumresidue));
|
||||
int32 i = CSUM_CHUNK - sumresidue;
|
||||
memcpy(md.buffer + sumresidue, p, i);
|
||||
mdfour_update(&md, (uchar *)md.buffer, CSUM_CHUNK);
|
||||
len -= i;
|
||||
p += i;
|
||||
}
|
||||
|
||||
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
|
||||
memcpy(sumrbuf,p+i,CSUM_CHUNK);
|
||||
mdfour_update(&md, (uchar *)sumrbuf, CSUM_CHUNK);
|
||||
while (len >= CSUM_CHUNK) {
|
||||
mdfour_update(&md, (uchar *)p, CSUM_CHUNK);
|
||||
len -= CSUM_CHUNK;
|
||||
p += CSUM_CHUNK;
|
||||
}
|
||||
|
||||
if (len - i > 0) {
|
||||
sumresidue = len-i;
|
||||
memcpy(sumrbuf,p+i,sumresidue);
|
||||
} else {
|
||||
sumresidue = 0;
|
||||
}
|
||||
sumresidue = len;
|
||||
if (sumresidue)
|
||||
memcpy(md.buffer, p, sumresidue);
|
||||
}
|
||||
|
||||
void sum_end(char *sum)
|
||||
int sum_end(char *sum)
|
||||
{
|
||||
if (sumresidue) {
|
||||
mdfour_update(&md, (uchar *)sumrbuf, sumresidue);
|
||||
if (protocol_version >= 30) {
|
||||
md5_result(&md, (uchar *)sum);
|
||||
return MD5_DIGEST_LEN;
|
||||
}
|
||||
|
||||
if (sumresidue || protocol_version >= 27)
|
||||
mdfour_update(&md, (uchar *)md.buffer, sumresidue);
|
||||
|
||||
mdfour_result(&md, (uchar *)sum);
|
||||
|
||||
return MD4_DIGEST_LEN;
|
||||
}
|
||||
|
||||
249
chmod.c
Normal file
249
chmod.c
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Implement the core of the --chmod option.
|
||||
*
|
||||
* Copyright (C) 2002 Scott Howard
|
||||
* Copyright (C) 2005-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.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 CHMOD_SET 4
|
||||
|
||||
#define STATE_ERROR 0
|
||||
#define STATE_1ST_HALF 1
|
||||
#define STATE_2ND_HALF 2
|
||||
#define STATE_OCTAL_NUM 3
|
||||
|
||||
/* Parse a chmod-style argument, and break it down into one or more AND/OR
|
||||
* pairs in a linked list. We return a pointer to new items on succcess
|
||||
* (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;
|
||||
case CHMOD_SET:
|
||||
curr_mode->ModeAND = 0;
|
||||
curr_mode->ModeOR = bits;
|
||||
break;
|
||||
}
|
||||
|
||||
curr_mode->flags = flags;
|
||||
|
||||
if (!*modestr)
|
||||
break;
|
||||
modestr++;
|
||||
|
||||
state = STATE_1ST_HALF;
|
||||
where = what = op = topoct = topbits = flags = 0;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case STATE_1ST_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:
|
||||
if (isDigit(modestr) && *modestr < '8' && !where) {
|
||||
op = CHMOD_SET;
|
||||
state = STATE_OCTAL_NUM;
|
||||
where = 1;
|
||||
what = *modestr - '0';
|
||||
} else
|
||||
state = STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case STATE_2ND_HALF:
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case STATE_OCTAL_NUM:
|
||||
if (isDigit(modestr) && *modestr < '8') {
|
||||
what = what*8 + *modestr - '0';
|
||||
if (what > CHMOD_BITS)
|
||||
state = STATE_ERROR;
|
||||
} else
|
||||
state = STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
modestr++;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
307
cleanup.c
307
cleanup.c
@@ -1,46 +1,64 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* End-of-run cleanup routines.
|
||||
*
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int dry_run;
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int am_receiver;
|
||||
extern int io_error;
|
||||
extern int keep_partial;
|
||||
extern int got_xfer_error;
|
||||
extern int protocol_version;
|
||||
extern int output_needs_newline;
|
||||
extern char *partial_dir;
|
||||
extern char *logfile_name;
|
||||
|
||||
BOOL shutting_down = False;
|
||||
BOOL flush_ok_after_signal = False;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
static struct sigaction sigact;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Close all open sockets and files, allowing a (somewhat) graceful
|
||||
* shutdown() of socket connections. This eliminates the abortive
|
||||
* TCP RST sent by a Winsock-based system when the close() occurs.
|
||||
**/
|
||||
void close_all()
|
||||
void close_all(void)
|
||||
{
|
||||
#ifdef SHUTDOWN_ALL_SOCKETS
|
||||
int max_fd;
|
||||
int fd;
|
||||
int ret;
|
||||
struct stat st;
|
||||
STRUCT_STAT st;
|
||||
|
||||
max_fd = sysconf(_SC_OPEN_MAX) - 1;
|
||||
for (fd = max_fd; fd >= 0; fd--) {
|
||||
ret = fstat(fd,&st);
|
||||
if (fstat(fd,&st) == 0) {
|
||||
if (is_a_socket(fd)) {
|
||||
if ((ret = do_fstat(fd, &st)) == 0) {
|
||||
if (is_a_socket(fd))
|
||||
ret = shutdown(fd, 2);
|
||||
}
|
||||
ret = close(fd);
|
||||
}
|
||||
}
|
||||
@@ -65,15 +83,13 @@ void close_all()
|
||||
* --partial is selected. We need to ensure that the partial file is
|
||||
* kept if any real data has been transferred.
|
||||
**/
|
||||
int cleanup_got_literal=0;
|
||||
int cleanup_got_literal = 0;
|
||||
|
||||
static char *cleanup_fname;
|
||||
static char *cleanup_new_fname;
|
||||
static const char *cleanup_fname;
|
||||
static const char *cleanup_new_fname;
|
||||
static struct file_struct *cleanup_file;
|
||||
static int cleanup_fd1, cleanup_fd2;
|
||||
static struct map_struct *cleanup_buf;
|
||||
static int cleanup_pid = 0;
|
||||
extern int io_error;
|
||||
static int cleanup_fd_r = -1, cleanup_fd_w = -1;
|
||||
static pid_t cleanup_pid = 0;
|
||||
|
||||
pid_t cleanup_child_pid = -1;
|
||||
|
||||
@@ -82,88 +98,197 @@ pid_t cleanup_child_pid = -1;
|
||||
*
|
||||
* @param code one of the RERR_* codes from errcode.h.
|
||||
**/
|
||||
void _exit_cleanup(int code, const char *file, int line)
|
||||
NORETURN void _exit_cleanup(int code, const char *file, int line)
|
||||
{
|
||||
int ocode = code;
|
||||
extern int keep_partial;
|
||||
extern int log_got_error;
|
||||
static int inside_cleanup = 0;
|
||||
static int switch_step = 0;
|
||||
static int exit_code = 0, exit_line = 0;
|
||||
static const char *exit_file = NULL;
|
||||
static int first_code = 0;
|
||||
|
||||
if (inside_cleanup > 10) {
|
||||
/* prevent the occasional infinite recursion */
|
||||
return;
|
||||
SIGACTION(SIGUSR1, SIG_IGN);
|
||||
SIGACTION(SIGUSR2, SIG_IGN);
|
||||
|
||||
if (!exit_code) { /* Preserve first error exit info when recursing. */
|
||||
exit_code = code;
|
||||
exit_file = file;
|
||||
exit_line = line < 0 ? -line : line;
|
||||
}
|
||||
inside_cleanup++;
|
||||
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
signal(SIGUSR2, SIG_IGN);
|
||||
/* If this is the exit at the end of the run, the server side
|
||||
* should not attempt to output a message (see log_exit()). */
|
||||
if (am_server && code == 0)
|
||||
am_server = 2;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
code, file, line);
|
||||
/* Some of our actions might cause a recursive call back here, so we
|
||||
* keep track of where we are in the cleanup and never repeat a step. */
|
||||
switch (switch_step) {
|
||||
#include "case_N.h" /* case 0: */
|
||||
switch_step++;
|
||||
|
||||
if (cleanup_child_pid != -1) {
|
||||
int status;
|
||||
if (waitpid(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) {
|
||||
status = WEXITSTATUS(status);
|
||||
if (status > code) code = status;
|
||||
first_code = code;
|
||||
|
||||
if (output_needs_newline) {
|
||||
fputc('\n', stdout);
|
||||
output_needs_newline = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cleanup_got_literal && cleanup_fname && keep_partial) {
|
||||
char *fname = cleanup_fname;
|
||||
cleanup_fname = NULL;
|
||||
if (cleanup_buf) unmap_file(cleanup_buf);
|
||||
if (cleanup_fd1 != -1) close(cleanup_fd1);
|
||||
if (cleanup_fd2 != -1) close(cleanup_fd2);
|
||||
finish_transfer(cleanup_new_fname, fname, cleanup_file);
|
||||
}
|
||||
io_flush();
|
||||
if (cleanup_fname)
|
||||
do_unlink(cleanup_fname);
|
||||
if (code) {
|
||||
kill_all(SIGUSR1);
|
||||
}
|
||||
if ((cleanup_pid != 0) && (cleanup_pid == (int) getpid())) {
|
||||
char *pidf = lp_pid_file();
|
||||
if (pidf && *pidf) {
|
||||
unlink(lp_pid_file());
|
||||
if (DEBUG_GTE(EXIT, 2)) {
|
||||
rprintf(FINFO,
|
||||
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
who_am_i(), code, file, line);
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (cleanup_child_pid != -1) {
|
||||
int status;
|
||||
int pid = wait_process(cleanup_child_pid, &status, WNOHANG);
|
||||
if (pid == cleanup_child_pid) {
|
||||
status = WEXITSTATUS(status);
|
||||
if (status > exit_code)
|
||||
exit_code = status;
|
||||
}
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (cleanup_got_literal && (cleanup_fname || cleanup_fd_w != -1)) {
|
||||
if (cleanup_fd_r != -1) {
|
||||
close(cleanup_fd_r);
|
||||
cleanup_fd_r = -1;
|
||||
}
|
||||
if (cleanup_fd_w != -1) {
|
||||
flush_write_file(cleanup_fd_w);
|
||||
close(cleanup_fd_w);
|
||||
cleanup_fd_w = -1;
|
||||
}
|
||||
if (cleanup_fname && cleanup_new_fname && keep_partial
|
||||
&& handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
|
||||
int tweak_modtime = 0;
|
||||
const char *fname = cleanup_fname;
|
||||
cleanup_fname = NULL;
|
||||
if (!partial_dir) {
|
||||
/* We don't want to leave a partial file with a modern time or it
|
||||
* could be skipped via --update. Setting the time to something
|
||||
* really old also helps it to stand out as unfinished in an ls. */
|
||||
tweak_modtime = 1;
|
||||
cleanup_file->modtime = 0;
|
||||
}
|
||||
finish_transfer(cleanup_new_fname, fname, NULL, NULL,
|
||||
cleanup_file, tweak_modtime, !partial_dir);
|
||||
}
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (flush_ok_after_signal) {
|
||||
flush_ok_after_signal = False;
|
||||
if (code == RERR_SIGNAL)
|
||||
io_flush(FULL_FLUSH);
|
||||
}
|
||||
if (!exit_code && !code)
|
||||
io_flush(FULL_FLUSH);
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (cleanup_fname)
|
||||
do_unlink(cleanup_fname);
|
||||
if (exit_code)
|
||||
kill_all(SIGUSR1);
|
||||
if (cleanup_pid && cleanup_pid == getpid()) {
|
||||
char *pidf = lp_pid_file();
|
||||
if (pidf && *pidf)
|
||||
unlink(lp_pid_file());
|
||||
}
|
||||
|
||||
if (exit_code == 0) {
|
||||
if (code)
|
||||
exit_code = code;
|
||||
if (io_error & IOERR_DEL_LIMIT)
|
||||
exit_code = RERR_DEL_LIMIT;
|
||||
if (io_error & IOERR_VANISHED)
|
||||
exit_code = RERR_VANISHED;
|
||||
if (io_error & IOERR_GENERAL || got_xfer_error)
|
||||
exit_code = RERR_PARTIAL;
|
||||
}
|
||||
|
||||
/* If line < 0, this exit is after a MSG_ERROR_EXIT event, so
|
||||
* we don't want to output a duplicate error. */
|
||||
if ((exit_code && line > 0)
|
||||
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1))))
|
||||
log_exit(exit_code, exit_file, exit_line);
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (DEBUG_GTE(EXIT, 1)) {
|
||||
rprintf(FINFO,
|
||||
"[%s] _exit_cleanup(code=%d, file=%s, line=%d): "
|
||||
"about to call exit(%d)%s\n",
|
||||
who_am_i(), first_code, exit_file, exit_line, exit_code,
|
||||
dry_run ? " (DRY RUN)" : "");
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (exit_code && exit_code != RERR_SOCKETIO && exit_code != RERR_STREAMIO && exit_code != RERR_SIGNAL1
|
||||
&& exit_code != RERR_TIMEOUT && !shutting_down && (protocol_version >= 31 || am_receiver)) {
|
||||
if (line > 0) {
|
||||
if (DEBUG_GTE(EXIT, 3)) {
|
||||
rprintf(FINFO, "[%s] sending MSG_ERROR_EXIT with exit_code %d\n",
|
||||
who_am_i(), exit_code);
|
||||
}
|
||||
send_msg_int(MSG_ERROR_EXIT, exit_code);
|
||||
}
|
||||
noop_io_until_death();
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
#include "case_N.h"
|
||||
switch_step++;
|
||||
|
||||
if (am_server && exit_code)
|
||||
msleep(100);
|
||||
close_all();
|
||||
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (code == 0 && (io_error || log_got_error)) {
|
||||
code = RERR_PARTIAL;
|
||||
}
|
||||
|
||||
if (code) log_exit(code, file, line);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n",
|
||||
ocode, file, line, code);
|
||||
|
||||
close_all();
|
||||
exit(code);
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
void cleanup_disable(void)
|
||||
{
|
||||
cleanup_fname = NULL;
|
||||
cleanup_fname = cleanup_new_fname = NULL;
|
||||
cleanup_fd_r = cleanup_fd_w = -1;
|
||||
cleanup_got_literal = 0;
|
||||
}
|
||||
|
||||
|
||||
void cleanup_set(char *fnametmp, char *fname, struct file_struct *file,
|
||||
struct map_struct *buf, int fd1, int fd2)
|
||||
void cleanup_set(const char *fnametmp, const char *fname, struct file_struct *file,
|
||||
int fd_r, int fd_w)
|
||||
{
|
||||
cleanup_fname = fnametmp;
|
||||
cleanup_new_fname = fname;
|
||||
cleanup_new_fname = fname; /* can be NULL on a partial-dir failure */
|
||||
cleanup_file = file;
|
||||
cleanup_buf = buf;
|
||||
cleanup_fd1 = fd1;
|
||||
cleanup_fd2 = fd2;
|
||||
cleanup_fd_r = fd_r;
|
||||
cleanup_fd_w = fd_w;
|
||||
}
|
||||
|
||||
void cleanup_set_pid(int pid)
|
||||
void cleanup_set_pid(pid_t pid)
|
||||
{
|
||||
cleanup_pid = pid;
|
||||
}
|
||||
|
||||
246
clientname.c
246
clientname.c
@@ -1,71 +1,64 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
rsync -- fast file replication program
|
||||
|
||||
Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file clientname.c
|
||||
*
|
||||
/*
|
||||
* Functions for looking up the remote name or addr of a socket.
|
||||
*
|
||||
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2002-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is now converted to use the new-style getaddrinfo()
|
||||
* interface, which supports IPv6 but is also supported on recent
|
||||
* IPv4-only machines. On systems that don't have that interface, we
|
||||
* emulate it using the KAME implementation.
|
||||
**/
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
static const char default_name[] = "UNKNOWN";
|
||||
extern int am_daemon;
|
||||
extern int am_server;
|
||||
|
||||
|
||||
/**
|
||||
* Return the IP addr of the client as a string
|
||||
* Return the IP addr of the client as a string
|
||||
**/
|
||||
char *client_addr(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t length = sizeof ss;
|
||||
char *ssh_client, *p;
|
||||
int len;
|
||||
static char addr_buf[100];
|
||||
static int initialised;
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t length = sizeof ss;
|
||||
|
||||
if (initialised) return addr_buf;
|
||||
if (initialised)
|
||||
return addr_buf;
|
||||
|
||||
initialised = 1;
|
||||
|
||||
if (am_server) {
|
||||
/* daemon over --rsh mode */
|
||||
strcpy(addr_buf, "0.0.0.0");
|
||||
if ((ssh_client = getenv("SSH_CLIENT")) != NULL) {
|
||||
/* truncate SSH_CLIENT to just IP address */
|
||||
p = strchr(ssh_client, ' ');
|
||||
if (p) {
|
||||
len = MIN((unsigned int) (p - ssh_client),
|
||||
sizeof(addr_buf) - 1);
|
||||
strncpy(addr_buf, ssh_client, len);
|
||||
*(addr_buf + len) = '\0';
|
||||
}
|
||||
if (am_server) { /* daemon over --rsh mode */
|
||||
char *env_str;
|
||||
strlcpy(addr_buf, "0.0.0.0", sizeof addr_buf);
|
||||
if ((env_str = getenv("REMOTE_HOST")) != NULL
|
||||
|| (env_str = getenv("SSH_CONNECTION")) != NULL
|
||||
|| (env_str = getenv("SSH_CLIENT")) != NULL
|
||||
|| (env_str = getenv("SSH2_CLIENT")) != NULL) {
|
||||
char *p;
|
||||
strlcpy(addr_buf, env_str, sizeof addr_buf);
|
||||
/* Truncate the value to just the IP address. */
|
||||
if ((p = strchr(addr_buf, ' ')) != NULL)
|
||||
*p = '\0';
|
||||
}
|
||||
} else {
|
||||
client_sockaddr(fd, &ss, &length);
|
||||
@@ -101,58 +94,61 @@ char *client_name(int fd)
|
||||
static char name_buf[100];
|
||||
static char port_buf[100];
|
||||
static int initialised;
|
||||
struct sockaddr_storage ss, *ssp;
|
||||
struct sockaddr_in sin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 sin6;
|
||||
#endif
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t ss_len;
|
||||
|
||||
if (initialised) return name_buf;
|
||||
if (initialised)
|
||||
return name_buf;
|
||||
|
||||
strcpy(name_buf, default_name);
|
||||
strlcpy(name_buf, default_name, sizeof name_buf);
|
||||
initialised = 1;
|
||||
|
||||
if (am_server) {
|
||||
/* daemon over --rsh mode */
|
||||
memset(&ss, 0, sizeof ss);
|
||||
|
||||
if (am_server) { /* daemon over --rsh mode */
|
||||
char *addr = client_addr(fd);
|
||||
#ifdef INET6
|
||||
int dots = 0;
|
||||
char *p;
|
||||
struct addrinfo hint, *answer;
|
||||
int err;
|
||||
|
||||
for (p = addr; *p && (dots <= 3); p++) {
|
||||
if (*p == '.')
|
||||
dots++;
|
||||
}
|
||||
if (dots > 3) {
|
||||
/* more than 4 parts to IP address, must be ipv6 */
|
||||
ssp = (struct sockaddr_storage *) &sin6;
|
||||
ss_len = sizeof sin6;
|
||||
memset(ssp, 0, ss_len);
|
||||
inet_pton(AF_INET6, addr, &sin6.sin6_addr);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
} else
|
||||
if (strcmp(addr, "0.0.0.0") == 0)
|
||||
return name_buf;
|
||||
|
||||
memset(&hint, 0, sizeof hint);
|
||||
|
||||
#ifdef AI_NUMERICHOST
|
||||
hint.ai_flags = AI_NUMERICHOST;
|
||||
#endif
|
||||
{
|
||||
ssp = (struct sockaddr_storage *) &sin;
|
||||
ss_len = sizeof sin;
|
||||
memset(ssp, 0, ss_len);
|
||||
inet_pton(AF_INET, addr, &sin.sin_addr);
|
||||
sin.sin_family = AF_INET;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if ((err = getaddrinfo(addr, NULL, &hint, &answer)) != 0) {
|
||||
rprintf(FLOG, "malformed address %s: %s\n",
|
||||
addr, gai_strerror(err));
|
||||
return name_buf;
|
||||
}
|
||||
|
||||
switch (answer->ai_family) {
|
||||
case AF_INET:
|
||||
ss_len = sizeof (struct sockaddr_in);
|
||||
memcpy(&ss, answer->ai_addr, ss_len);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
ss_len = sizeof (struct sockaddr_in6);
|
||||
memcpy(&ss, answer->ai_addr, ss_len);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
freeaddrinfo(answer);
|
||||
} else {
|
||||
ss_len = sizeof ss;
|
||||
ssp = &ss;
|
||||
|
||||
client_sockaddr(fd, &ss, &ss_len);
|
||||
|
||||
}
|
||||
|
||||
if (!lookup_name(fd, ssp, ss_len, name_buf, sizeof name_buf,
|
||||
port_buf, sizeof port_buf))
|
||||
check_name(fd, ssp, name_buf);
|
||||
if (lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf,
|
||||
port_buf, sizeof port_buf) == 0)
|
||||
check_name(fd, &ss, name_buf, sizeof name_buf);
|
||||
|
||||
return name_buf;
|
||||
}
|
||||
@@ -169,17 +165,16 @@ void client_sockaddr(int fd,
|
||||
struct sockaddr_storage *ss,
|
||||
socklen_t *ss_len)
|
||||
{
|
||||
memset(ss, 0, sizeof(*ss));
|
||||
memset(ss, 0, sizeof *ss);
|
||||
|
||||
if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
|
||||
/* FIXME: Can we really not continue? */
|
||||
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
|
||||
fd, strerror(errno));
|
||||
rsyserr(FLOG, errno, "getpeername on fd%d failed", fd);
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
if (get_sockaddr_family(ss) == AF_INET6 &&
|
||||
if (get_sockaddr_family(ss) == AF_INET6 &&
|
||||
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
|
||||
/* OK, so ss is in the IPv6 family, but it is really
|
||||
* an IPv4 address: something like
|
||||
@@ -190,12 +185,12 @@ void client_sockaddr(int fd,
|
||||
struct sockaddr_in6 sin6;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
memcpy(&sin6, ss, sizeof(sin6));
|
||||
memcpy(&sin6, ss, sizeof sin6);
|
||||
sin = (struct sockaddr_in *)ss;
|
||||
memset(sin, 0, sizeof(*sin));
|
||||
memset(sin, 0, sizeof *sin);
|
||||
sin->sin_family = AF_INET;
|
||||
*ss_len = sizeof(struct sockaddr_in);
|
||||
#ifdef HAVE_SOCKADDR_LEN
|
||||
*ss_len = sizeof (struct sockaddr_in);
|
||||
#ifdef HAVE_SOCKADDR_IN_LEN
|
||||
sin->sin_len = *ss_len;
|
||||
#endif
|
||||
sin->sin_port = sin6.sin6_port;
|
||||
@@ -204,8 +199,8 @@ void client_sockaddr(int fd,
|
||||
* (IN6_V4MAPPED_TO_SINADDR ?), but it does not seem
|
||||
* to be present in the Linux headers. */
|
||||
memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
|
||||
sizeof(sin->sin_addr));
|
||||
}
|
||||
sizeof sin->sin_addr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -217,21 +212,20 @@ void client_sockaddr(int fd,
|
||||
**/
|
||||
int lookup_name(int fd, const struct sockaddr_storage *ss,
|
||||
socklen_t ss_len,
|
||||
char *name_buf, size_t name_buf_len,
|
||||
char *port_buf, size_t port_buf_len)
|
||||
char *name_buf, size_t name_buf_size,
|
||||
char *port_buf, size_t port_buf_size)
|
||||
{
|
||||
int name_err;
|
||||
|
||||
|
||||
/* reverse lookup */
|
||||
name_err = getnameinfo((struct sockaddr *) ss, ss_len,
|
||||
name_buf, name_buf_len,
|
||||
port_buf, port_buf_len,
|
||||
name_buf, name_buf_size,
|
||||
port_buf, port_buf_size,
|
||||
NI_NAMEREQD | NI_NUMERICSERV);
|
||||
if (name_err != 0) {
|
||||
strcpy(name_buf, default_name);
|
||||
rprintf(FERROR, RSYNC_NAME ": name lookup failed for %s: %s\n",
|
||||
client_addr(fd),
|
||||
gai_strerror(name_err));
|
||||
strlcpy(name_buf, default_name, name_buf_size);
|
||||
rprintf(FLOG, "name lookup failed for %s: %s\n",
|
||||
client_addr(fd), gai_strerror(name_err));
|
||||
return name_err;
|
||||
}
|
||||
|
||||
@@ -250,10 +244,9 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
|
||||
{
|
||||
int ss_family = get_sockaddr_family(ss);
|
||||
const char fn[] = "compare_addrinfo_sockaddr";
|
||||
|
||||
|
||||
if (ai->ai_family != ss_family) {
|
||||
rprintf(FERROR,
|
||||
"%s: response family %d != %d\n",
|
||||
rprintf(FLOG, "%s: response family %d != %d\n",
|
||||
fn, ai->ai_family, ss_family);
|
||||
return 1;
|
||||
}
|
||||
@@ -264,21 +257,21 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
|
||||
|
||||
sin1 = (const struct sockaddr_in *) ss;
|
||||
sin2 = (const struct sockaddr_in *) ai->ai_addr;
|
||||
|
||||
|
||||
return memcmp(&sin1->sin_addr, &sin2->sin_addr,
|
||||
sizeof sin1->sin_addr);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
else if (ss_family == AF_INET6) {
|
||||
if (ss_family == AF_INET6) {
|
||||
const struct sockaddr_in6 *sin1, *sin2;
|
||||
|
||||
sin1 = (const struct sockaddr_in6 *) ss;
|
||||
sin2 = (const struct sockaddr_in6 *) ai->ai_addr;
|
||||
|
||||
if (ai->ai_addrlen < sizeof(struct sockaddr_in6)) {
|
||||
rprintf(FERROR,
|
||||
"%s: too short sockaddr_in6; length=%d\n",
|
||||
fn, ai->ai_addrlen);
|
||||
if (ai->ai_addrlen < sizeof (struct sockaddr_in6)) {
|
||||
rprintf(FLOG, "%s: too short sockaddr_in6; length=%d\n",
|
||||
fn, (int)ai->ai_addrlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -293,10 +286,9 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
|
||||
return 0;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
else {
|
||||
/* don't know */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* don't know */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -312,26 +304,24 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
|
||||
**/
|
||||
int check_name(int fd,
|
||||
const struct sockaddr_storage *ss,
|
||||
char *name_buf)
|
||||
char *name_buf, size_t name_buf_size)
|
||||
{
|
||||
struct addrinfo hints, *res, *res0;
|
||||
int error;
|
||||
int ss_family = get_sockaddr_family(ss);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = ss_family;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
error = getaddrinfo(name_buf, NULL, &hints, &res0);
|
||||
if (error) {
|
||||
rprintf(FERROR,
|
||||
RSYNC_NAME ": forward name lookup for %s failed: %s\n",
|
||||
rprintf(FLOG, "forward name lookup for %s failed: %s\n",
|
||||
name_buf, gai_strerror(error));
|
||||
strcpy(name_buf, default_name);
|
||||
strlcpy(name_buf, default_name, name_buf_size);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* 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) {
|
||||
@@ -342,23 +332,17 @@ int check_name(int fd,
|
||||
if (!res0) {
|
||||
/* We hit the end of the list without finding an
|
||||
* address that was the same as ss. */
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": no known address for \"%s\": "
|
||||
"spoofed address?\n",
|
||||
name_buf);
|
||||
strcpy(name_buf, default_name);
|
||||
rprintf(FLOG, "no known address for \"%s\": "
|
||||
"spoofed address?\n", name_buf);
|
||||
strlcpy(name_buf, default_name, name_buf_size);
|
||||
} else if (res == NULL) {
|
||||
/* We hit the end of the list without finding an
|
||||
* address that was the same as ss. */
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": %s is not a known address for \"%s\": "
|
||||
"spoofed address?\n",
|
||||
client_addr(fd),
|
||||
name_buf);
|
||||
strcpy(name_buf, default_name);
|
||||
rprintf(FLOG, "%s is not a known address for \"%s\": "
|
||||
"spoofed address?\n", client_addr(fd), name_buf);
|
||||
strlcpy(name_buf, default_name, name_buf_size);
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
1308
clientserver.c
1308
clientserver.c
File diff suppressed because it is too large
Load Diff
380
compat.c
380
compat.c
@@ -1,79 +1,341 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file compat.c
|
||||
*
|
||||
/*
|
||||
* Compatibility routines for older rsync protocol versions.
|
||||
**/
|
||||
*
|
||||
* Copyright (C) Andrew Tridgell 1996
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2004-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int am_server;
|
||||
int remote_protocol = 0;
|
||||
int file_extra_cnt = 0; /* count of file-list extras that everyone gets */
|
||||
int inc_recurse = 0;
|
||||
int compat_flags = 0;
|
||||
int use_safe_inc_flist = 0;
|
||||
int want_xattr_optim = 0;
|
||||
int proper_seed_order = 0;
|
||||
|
||||
extern int preserve_links;
|
||||
extern int preserve_perms;
|
||||
extern int preserve_devices;
|
||||
extern int am_server;
|
||||
extern int am_sender;
|
||||
extern int local_server;
|
||||
extern int inplace;
|
||||
extern int recurse;
|
||||
extern int use_qsort;
|
||||
extern int allow_inc_recurse;
|
||||
extern int preallocate_files;
|
||||
extern int append_mode;
|
||||
extern int fuzzy_basis;
|
||||
extern int read_batch;
|
||||
extern int delay_updates;
|
||||
extern int checksum_seed;
|
||||
extern int basis_dir_cnt;
|
||||
extern int prune_empty_dirs;
|
||||
extern int protocol_version;
|
||||
extern int protect_args;
|
||||
extern int preserve_uid;
|
||||
extern int preserve_gid;
|
||||
extern int preserve_times;
|
||||
extern int always_checksum;
|
||||
extern int checksum_seed;
|
||||
extern int preserve_acls;
|
||||
extern int preserve_xattrs;
|
||||
extern int need_messages_from_generator;
|
||||
extern int delete_mode, delete_before, delete_during, delete_after;
|
||||
extern char *shell_cmd;
|
||||
extern char *partial_dir;
|
||||
extern char *dest_option;
|
||||
extern char *files_from;
|
||||
extern char *filesfrom_host;
|
||||
extern filter_rule_list filter_list;
|
||||
extern int need_unsorted_flist;
|
||||
#ifdef ICONV_OPTION
|
||||
extern iconv_t ic_send, ic_recv;
|
||||
extern char *iconv_opt;
|
||||
#endif
|
||||
|
||||
/* These index values are for the file-list's extra-attribute array. */
|
||||
int uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
|
||||
|
||||
extern int remote_version;
|
||||
extern int verbose;
|
||||
int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
|
||||
int sender_symlink_iconv = 0; /* sender should convert symlink content */
|
||||
|
||||
extern int read_batch; /* dw */
|
||||
extern int write_batch; /* dw */
|
||||
#ifdef ICONV_OPTION
|
||||
int filesfrom_convert = 0;
|
||||
#endif
|
||||
|
||||
#define CF_INC_RECURSE (1<<0)
|
||||
#define CF_SYMLINK_TIMES (1<<1)
|
||||
#define CF_SYMLINK_ICONV (1<<2)
|
||||
#define CF_SAFE_FLIST (1<<3)
|
||||
#define CF_AVOID_XATTR_OPTIM (1<<4)
|
||||
#define CF_CHKSUM_SEED_FIX (1<<5)
|
||||
|
||||
static const char *client_info;
|
||||
|
||||
/* The server makes sure that if either side only supports a pre-release
|
||||
* version of a protocol, that both sides must speak a compatible version
|
||||
* of that protocol for it to be advertised as available. */
|
||||
static void check_sub_protocol(void)
|
||||
{
|
||||
char *dot;
|
||||
int their_protocol, their_sub;
|
||||
#if SUBPROTOCOL_VERSION != 0
|
||||
int our_sub = protocol_version < PROTOCOL_VERSION ? 0 : SUBPROTOCOL_VERSION;
|
||||
#else
|
||||
int our_sub = 0;
|
||||
#endif
|
||||
|
||||
/* client_info starts with VER.SUB string if client is a pre-release. */
|
||||
if (!(their_protocol = atoi(client_info))
|
||||
|| !(dot = strchr(client_info, '.'))
|
||||
|| !(their_sub = atoi(dot+1))) {
|
||||
#if SUBPROTOCOL_VERSION != 0
|
||||
if (our_sub)
|
||||
protocol_version--;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (their_protocol < protocol_version) {
|
||||
if (their_sub)
|
||||
protocol_version = their_protocol - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (their_protocol > protocol_version)
|
||||
their_sub = 0; /* 0 == final version of older protocol */
|
||||
if (their_sub != our_sub)
|
||||
protocol_version--;
|
||||
}
|
||||
|
||||
void set_allow_inc_recurse(void)
|
||||
{
|
||||
client_info = shell_cmd ? shell_cmd : "";
|
||||
|
||||
if (!recurse || use_qsort)
|
||||
allow_inc_recurse = 0;
|
||||
else if (!am_sender
|
||||
&& (delete_before || delete_after
|
||||
|| delay_updates || prune_empty_dirs))
|
||||
allow_inc_recurse = 0;
|
||||
else if (am_server && !local_server
|
||||
&& (strchr(client_info, 'i') == NULL))
|
||||
allow_inc_recurse = 0;
|
||||
}
|
||||
|
||||
void setup_protocol(int f_out,int f_in)
|
||||
{
|
||||
if (remote_version == 0) {
|
||||
if (am_server) {
|
||||
remote_version = read_int(f_in);
|
||||
write_int(f_out,PROTOCOL_VERSION);
|
||||
} else {
|
||||
write_int(f_out,PROTOCOL_VERSION);
|
||||
remote_version = read_int(f_in);
|
||||
}
|
||||
if (am_sender)
|
||||
file_extra_cnt += PTR_EXTRA_CNT;
|
||||
else
|
||||
file_extra_cnt++;
|
||||
if (preserve_uid)
|
||||
uid_ndx = ++file_extra_cnt;
|
||||
if (preserve_gid)
|
||||
gid_ndx = ++file_extra_cnt;
|
||||
if (preserve_acls && !am_sender)
|
||||
acls_ndx = ++file_extra_cnt;
|
||||
if (preserve_xattrs)
|
||||
xattrs_ndx = ++file_extra_cnt;
|
||||
|
||||
if (am_server)
|
||||
set_allow_inc_recurse();
|
||||
|
||||
if (remote_protocol == 0) {
|
||||
if (am_server && !local_server)
|
||||
check_sub_protocol();
|
||||
if (!read_batch)
|
||||
write_int(f_out, protocol_version);
|
||||
remote_protocol = read_int(f_in);
|
||||
if (protocol_version > remote_protocol)
|
||||
protocol_version = remote_protocol;
|
||||
}
|
||||
if (read_batch && remote_protocol > protocol_version) {
|
||||
rprintf(FERROR, "The protocol version in the batch file is too new (%d > %d).\n",
|
||||
remote_protocol, protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (remote_version < MIN_PROTOCOL_VERSION ||
|
||||
remote_version > MAX_PROTOCOL_VERSION) {
|
||||
rprintf(FERROR,"protocol version mismatch - is your shell clean?\n");
|
||||
if (DEBUG_GTE(PROTO, 1)) {
|
||||
rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
|
||||
am_server? "Server" : "Client", remote_protocol, protocol_version);
|
||||
}
|
||||
if (remote_protocol < MIN_PROTOCOL_VERSION
|
||||
|| remote_protocol > MAX_PROTOCOL_VERSION) {
|
||||
rprintf(FERROR,"protocol version mismatch -- is your shell clean?\n");
|
||||
rprintf(FERROR,"(see the rsync man page for an explanation)\n");
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
|
||||
if (remote_version >= 12) {
|
||||
if (am_server) {
|
||||
if (read_batch || write_batch) /* dw */
|
||||
checksum_seed = 32761;
|
||||
else
|
||||
checksum_seed = time(NULL);
|
||||
write_int(f_out,checksum_seed);
|
||||
} else {
|
||||
checksum_seed = read_int(f_in);
|
||||
}
|
||||
if (remote_protocol < OLD_PROTOCOL_VERSION) {
|
||||
rprintf(FINFO,"%s is very old version of rsync, upgrade recommended.\n",
|
||||
am_server? "Client" : "Server");
|
||||
}
|
||||
if (protocol_version < MIN_PROTOCOL_VERSION) {
|
||||
rprintf(FERROR, "--protocol must be at least %d on the %s.\n",
|
||||
MIN_PROTOCOL_VERSION, am_server? "Server" : "Client");
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if (protocol_version > PROTOCOL_VERSION) {
|
||||
rprintf(FERROR, "--protocol must be no more than %d on the %s.\n",
|
||||
PROTOCOL_VERSION, am_server? "Server" : "Client");
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if (read_batch)
|
||||
check_batch_flags();
|
||||
|
||||
#ifndef SUPPORT_PREALLOCATION
|
||||
if (preallocate_files && !am_sender) {
|
||||
rprintf(FERROR, "preallocation is not supported on this %s\n",
|
||||
am_server ? "Server" : "Client");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (protocol_version < 30) {
|
||||
if (append_mode == 1)
|
||||
append_mode = 2;
|
||||
if (preserve_acls && !local_server) {
|
||||
rprintf(FERROR,
|
||||
"--acls requires protocol 30 or higher"
|
||||
" (negotiated %d).\n",
|
||||
protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
if (preserve_xattrs && !local_server) {
|
||||
rprintf(FERROR,
|
||||
"--xattrs requires protocol 30 or higher"
|
||||
" (negotiated %d).\n",
|
||||
protocol_version);
|
||||
exit_cleanup(RERR_PROTOCOL);
|
||||
}
|
||||
}
|
||||
|
||||
checksum_init();
|
||||
}
|
||||
|
||||
if (delete_mode && !(delete_before+delete_during+delete_after)) {
|
||||
if (protocol_version < 30)
|
||||
delete_before = 1;
|
||||
else
|
||||
delete_during = 1;
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
} else if (protocol_version >= 30) {
|
||||
if (am_server) {
|
||||
compat_flags = allow_inc_recurse ? CF_INC_RECURSE : 0;
|
||||
#ifdef CAN_SET_SYMLINK_TIMES
|
||||
compat_flags |= CF_SYMLINK_TIMES;
|
||||
#endif
|
||||
#ifdef ICONV_OPTION
|
||||
compat_flags |= CF_SYMLINK_ICONV;
|
||||
#endif
|
||||
if (local_server || strchr(client_info, 'f') != NULL)
|
||||
compat_flags |= CF_SAFE_FLIST;
|
||||
if (local_server || strchr(client_info, 'x') != NULL)
|
||||
compat_flags |= CF_AVOID_XATTR_OPTIM;
|
||||
if (local_server || strchr(client_info, 'C') != NULL)
|
||||
compat_flags |= CF_CHKSUM_SEED_FIX;
|
||||
write_byte(f_out, compat_flags);
|
||||
} else
|
||||
compat_flags = read_byte(f_in);
|
||||
/* The inc_recurse var MUST be set to 0 or 1. */
|
||||
inc_recurse = compat_flags & CF_INC_RECURSE ? 1 : 0;
|
||||
want_xattr_optim = protocol_version >= 31 && !(compat_flags & CF_AVOID_XATTR_OPTIM);
|
||||
proper_seed_order = compat_flags & CF_CHKSUM_SEED_FIX ? 1 : 0;
|
||||
if (am_sender) {
|
||||
receiver_symlink_times = am_server
|
||||
? strchr(client_info, 'L') != NULL
|
||||
: !!(compat_flags & CF_SYMLINK_TIMES);
|
||||
}
|
||||
#ifdef CAN_SET_SYMLINK_TIMES
|
||||
else
|
||||
receiver_symlink_times = 1;
|
||||
#endif
|
||||
#ifdef ICONV_OPTION
|
||||
sender_symlink_iconv = iconv_opt && (am_server
|
||||
? local_server || strchr(client_info, 's') != NULL
|
||||
: !!(compat_flags & CF_SYMLINK_ICONV));
|
||||
#endif
|
||||
if (inc_recurse && !allow_inc_recurse) {
|
||||
/* This should only be able to happen in a batch. */
|
||||
fprintf(stderr,
|
||||
"Incompatible options specified for inc-recursive %s.\n",
|
||||
read_batch ? "batch file" : "connection");
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
use_safe_inc_flist = (compat_flags & CF_SAFE_FLIST) || protocol_version >= 31;
|
||||
need_messages_from_generator = 1;
|
||||
#ifdef CAN_SET_SYMLINK_TIMES
|
||||
} else if (!am_sender) {
|
||||
receiver_symlink_times = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (need_unsorted_flist && (!am_sender || inc_recurse))
|
||||
unsort_ndx = ++file_extra_cnt;
|
||||
|
||||
if (partial_dir && *partial_dir != '/' && (!am_server || local_server)) {
|
||||
int rflags = FILTRULE_NO_PREFIXES | FILTRULE_DIRECTORY;
|
||||
if (!am_sender || protocol_version >= 30)
|
||||
rflags |= FILTRULE_PERISHABLE;
|
||||
parse_filter_str(&filter_list, partial_dir, rule_template(rflags), 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef ICONV_OPTION
|
||||
if (protect_args && files_from) {
|
||||
if (am_sender)
|
||||
filesfrom_convert = filesfrom_host && ic_send != (iconv_t)-1;
|
||||
else
|
||||
filesfrom_convert = !filesfrom_host && ic_recv != (iconv_t)-1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (am_server) {
|
||||
if (!checksum_seed)
|
||||
checksum_seed = time(NULL) ^ (getpid() << 6);
|
||||
write_int(f_out, checksum_seed);
|
||||
} else {
|
||||
checksum_seed = read_int(f_in);
|
||||
}
|
||||
}
|
||||
|
||||
1187
config.guess
vendored
Executable file → Normal file
1187
config.guess
vendored
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
538
config.sub
vendored
Executable file → Normal file
538
config.sub
vendored
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
27
configure
vendored
Executable file
27
configure
vendored
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh -e
|
||||
# This configure script ensures that the configure.sh script exists, and
|
||||
# if not, it tries to fetch rsync's generated files or build them. We
|
||||
# then transfer control to the configure.sh script to do the real work.
|
||||
|
||||
dir=`dirname $0`
|
||||
realconfigure="$dir/configure.sh"
|
||||
|
||||
if test ! -f "$realconfigure"; then
|
||||
if test -f "$HOME/build_farm/build_test.fns"; then
|
||||
# Test the included popt
|
||||
set -- --with-included-popt "${@}"
|
||||
# Allow the build farm to grab latest files via rsync.
|
||||
actions='build fetch'
|
||||
else
|
||||
actions='build'
|
||||
fi
|
||||
if "$dir/prepare-source" $actions; then
|
||||
:
|
||||
else
|
||||
echo 'Failed to build configure.sh and/or config.h.in -- giving up.' >&2
|
||||
rm -f "$realconfigure"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$realconfigure" "${@}"
|
||||
1087
configure.ac
Normal file
1087
configure.ac
Normal file
File diff suppressed because it is too large
Load Diff
641
configure.in
641
configure.in
@@ -1,641 +0,0 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT()
|
||||
AC_CONFIG_SRCDIR([byteorder.h])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PREREQ(2.52)
|
||||
|
||||
RSYNC_VERSION=2.5.6
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
|
||||
|
||||
AC_DEFINE_UNQUOTED(RSYNC_VERSION, ["$RSYNC_VERSION"], [rsync release version])
|
||||
|
||||
LDFLAGS=${LDFLAGS-""}
|
||||
|
||||
AC_CANONICAL_TARGET([])
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_CC_STDC
|
||||
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
|
||||
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
|
||||
fi
|
||||
|
||||
# We must decide this before testing the compiler.
|
||||
|
||||
# Please allow this to default to yes, so that your users have more
|
||||
# chance of getting a useful stack trace if problems occur.
|
||||
|
||||
AC_MSG_CHECKING([whether to include debugging symbols])
|
||||
AC_ARG_ENABLE(debug,
|
||||
AC_HELP_STRING([--enable-debug],
|
||||
[including debugging symbols and features (default yes)]),
|
||||
[], [])
|
||||
|
||||
if test x"$enable_debug" = x"no"
|
||||
then
|
||||
AC_MSG_RESULT(no)
|
||||
CFLAGS=${CFLAGS-"-O"}
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
# leave CFLAGS alone; AC_PROG_CC will try to include -g if it can
|
||||
dnl AC_DEFINE(DEBUG, 1, [Define to turn on debugging code that may slow normal operation])
|
||||
dnl CFLAGS=${CFLAGS-"-g"}
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
AC_ARG_ENABLE(profile,
|
||||
AC_HELP_STRING([--enable-profile],
|
||||
[turn on CPU profiling (default no)],
|
||||
[], []))
|
||||
if test x"$enable_profile" = xyes
|
||||
then
|
||||
CFLAGS="$CFLAGS -pg"
|
||||
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
|
||||
CFLAGS="$CFLAGS -DMAINTAINER_MODE"
|
||||
fi
|
||||
|
||||
|
||||
# This is needed for our included version of popt. Kind of silly, but
|
||||
# I don't want our version too far out of sync.
|
||||
CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
|
||||
|
||||
# If GCC, turn on warnings.
|
||||
if test "x$GCC" = "xyes"
|
||||
then
|
||||
CFLAGS="$CFLAGS -Wall -W"
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(included-popt,
|
||||
[ --with-included-popt use bundled popt library, not from system])
|
||||
|
||||
AC_ARG_WITH(rsync-path,
|
||||
[ --with-rsync-path=PATH set default --rsync-path to PATH (default: \"rsync\")],
|
||||
[ RSYNC_PATH="$with_rsync_path" ],
|
||||
[ RSYNC_PATH="rsync" ])
|
||||
|
||||
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [location of rsync on remote machine])
|
||||
|
||||
AC_ARG_WITH(rsh,
|
||||
AC_HELP_STRING([--with-rsh=CMD], [set rsh command to CMD (default: \"remsh\" or \"rsh\")]))
|
||||
|
||||
AC_CHECK_PROG(HAVE_REMSH, remsh, 1, 0)
|
||||
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [remote shell is remsh not rsh])
|
||||
|
||||
if test x"$with_rsh" != x
|
||||
then
|
||||
RSYNC_RSH="$with_rsh"
|
||||
elif test x"$HAVE_REMSH" = x1
|
||||
then
|
||||
RSYNC_RSH="remsh"
|
||||
else
|
||||
RSYNC_RSH="rsh"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
|
||||
|
||||
# arrgh. libc in the current debian stable screws up the largefile
|
||||
# stuff, getting byte range locking wrong
|
||||
AC_CACHE_CHECK([for broken largefile support],rsync_cv_HAVE_BROKEN_LARGEFILE,[
|
||||
AC_TRY_RUN([
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct flock lock;
|
||||
int status;
|
||||
int fd = open("conftest.dat", O_CREAT|O_RDWR, 0600);
|
||||
lock.l_type = F_WRLCK;
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 1;
|
||||
lock.l_pid = 0;
|
||||
|
||||
fcntl(fd,F_SETLK,&lock);
|
||||
if (fork() == 0) {
|
||||
lock.l_start = 1;
|
||||
exit(fcntl(fd,F_SETLK,&lock) == 0);
|
||||
}
|
||||
wait(&status);
|
||||
unlink("conftest.dat");
|
||||
exit(WEXITSTATUS(status));
|
||||
}
|
||||
],
|
||||
rsync_cv_HAVE_BROKEN_LARGEFILE=yes,rsync_cv_HAVE_BROKEN_LARGEFILE=no,rsync_cv_HAVE_BROKEN_LARGEFILE=cross)])
|
||||
if test x"$rsync_cv_HAVE_BROKEN_LARGEFILE" != x"yes"; then
|
||||
AC_SYS_LARGEFILE
|
||||
fi
|
||||
|
||||
ipv6type=unknown
|
||||
ipv6lib=none
|
||||
ipv6trylibc=yes
|
||||
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
AC_HELP_STRING([--disable-ipv6], [don't even try to use IPv6]))
|
||||
|
||||
if test "x$enable_ipv6" != xno
|
||||
then
|
||||
AC_MSG_CHECKING([ipv6 stack type])
|
||||
for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
|
||||
case $i in
|
||||
inria)
|
||||
# http://www.kame.net/
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include <netinet/in.h>
|
||||
#ifdef IPV6_INRIA_VERSION
|
||||
yes
|
||||
#endif],
|
||||
[ipv6type=$i;
|
||||
AC_DEFINE(INET6, 1, [true if you have IPv6])
|
||||
])
|
||||
;;
|
||||
kame)
|
||||
# http://www.kame.net/
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include <netinet/in.h>
|
||||
#ifdef __KAME__
|
||||
yes
|
||||
#endif],
|
||||
[ipv6type=$i;
|
||||
AC_DEFINE(INET6, 1, [true if you have IPv6])])
|
||||
;;
|
||||
linux-glibc)
|
||||
# http://www.v6.linux.or.jp/
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include <features.h>
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
|
||||
yes
|
||||
#endif],
|
||||
[ipv6type=$i;
|
||||
AC_DEFINE(INET6, 1, [true if you have IPv6])])
|
||||
;;
|
||||
linux-inet6)
|
||||
# http://www.v6.linux.or.jp/
|
||||
if test -d /usr/inet6 -o -f /usr/inet6/lib/libinet6.a; then
|
||||
ipv6type=$i
|
||||
ipv6lib=inet6
|
||||
ipv6libdir=/usr/inet6/lib
|
||||
ipv6trylibc=yes;
|
||||
AC_DEFINE(INET6, 1, [true if you have IPv6])
|
||||
CFLAGS="-I/usr/inet6/include $CFLAGS"
|
||||
fi
|
||||
;;
|
||||
toshiba)
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include <sys/param.h>
|
||||
#ifdef _TOSHIBA_INET6
|
||||
yes
|
||||
#endif],
|
||||
[ipv6type=$i;
|
||||
ipv6lib=inet6;
|
||||
ipv6libdir=/usr/local/v6/lib;
|
||||
AC_DEFINE(INET6, 1, [true if you have IPv6])])
|
||||
;;
|
||||
v6d)
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include </usr/local/v6/include/sys/v6config.h>
|
||||
#ifdef __V6D__
|
||||
yes
|
||||
#endif],
|
||||
[ipv6type=$i;
|
||||
ipv6lib=v6;
|
||||
ipv6libdir=/usr/local/v6/lib;
|
||||
AC_DEFINE(INET6, 1, [true if you have IPv6])])
|
||||
;;
|
||||
zeta)
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include <sys/param.h>
|
||||
#ifdef _ZETA_MINAMI_INET6
|
||||
yes
|
||||
#endif],
|
||||
[ipv6type=$i;
|
||||
ipv6lib=inet6;
|
||||
ipv6libdir=/usr/local/v6/lib;
|
||||
AC_DEFINE(INET6, 1, [true if you have IPv6])])
|
||||
;;
|
||||
esac
|
||||
if test "$ipv6type" != "unknown"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
AC_MSG_RESULT($ipv6type)
|
||||
|
||||
AC_SEARCH_LIBS(getaddrinfo, inet6)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to call shutdown on all sockets])
|
||||
case $host_os in
|
||||
*cygwin* ) AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(SHUTDOWN_ALL_SOCKETS, 1,
|
||||
[Define if sockets need to be shutdown])
|
||||
;;
|
||||
* ) AC_MSG_RESULT(no);;
|
||||
esac
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_TIME
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h unistd.h utime.h grp.h)
|
||||
AC_CHECK_HEADERS(compat.h sys/param.h ctype.h sys/wait.h sys/ioctl.h)
|
||||
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h sys/un.h)
|
||||
AC_CHECK_HEADERS(glob.h mcheck.h sys/sysctl.h arpa/inet.h arpa/nameser.h)
|
||||
AC_CHECK_HEADERS(netdb.h)
|
||||
AC_CHECK_HEADERS(malloc.h)
|
||||
AC_CHECK_HEADERS(float.h)
|
||||
|
||||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
AC_CHECK_SIZEOF(short)
|
||||
|
||||
AC_C_INLINE
|
||||
|
||||
AC_TYPE_SIGNAL
|
||||
AC_TYPE_UID_T
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_GETGROUPS
|
||||
AC_CHECK_MEMBERS([struct stat.st_rdev])
|
||||
|
||||
AC_CHECK_TYPE([ino_t], [unsigned])
|
||||
TYPE_SOCKLEN_T
|
||||
|
||||
AC_CACHE_CHECK([for errno in errno.h],rsync_cv_errno, [
|
||||
AC_TRY_COMPILE([#include <errno.h>],[int i = errno],
|
||||
rsync_cv_errno=yes,rsync_cv_have_errno_decl=no)])
|
||||
if test x"$rsync_cv_errno" = x"yes"; then
|
||||
AC_DEFINE(HAVE_ERRNO_DECL, 1, [ ])
|
||||
fi
|
||||
|
||||
# The following test taken from the cvs sources
|
||||
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
|
||||
# These need checks to be before checks for any other functions that
|
||||
# might be in the same libraries.
|
||||
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
|
||||
# libsocket.so which has a bad implementation of gethostbyname (it
|
||||
# only looks in /etc/hosts), so we only look for -lsocket if we need
|
||||
# it.
|
||||
AC_CHECK_FUNCS(connect)
|
||||
if test x"$ac_cv_func_connect" = x"no"; then
|
||||
case "$LIBS" in
|
||||
*-lnsl*) ;;
|
||||
*) AC_CHECK_LIB(nsl_s, printf) ;;
|
||||
esac
|
||||
case "$LIBS" in
|
||||
*-lnsl*) ;;
|
||||
*) AC_CHECK_LIB(nsl, printf) ;;
|
||||
esac
|
||||
case "$LIBS" in
|
||||
*-lsocket*) ;;
|
||||
*) AC_CHECK_LIB(socket, connect) ;;
|
||||
esac
|
||||
case "$LIBS" in
|
||||
*-linet*) ;;
|
||||
*) AC_CHECK_LIB(inet, connect) ;;
|
||||
esac
|
||||
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
|
||||
dnl has been cached.
|
||||
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
|
||||
test x"$ac_cv_lib_inet_connect" = x"yes"; then
|
||||
# ac_cv_func_connect=yes
|
||||
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
|
||||
AC_DEFINE(HAVE_CONNECT, 1, [ ])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(resolv, inet_ntop)
|
||||
|
||||
dnl AC_MSG_NOTICE([Looking in libraries: $LIBS])
|
||||
|
||||
AC_CHECK_FUNCS(inet_ntop, , AC_LIBOBJ(lib/inet_ntop))
|
||||
AC_CHECK_FUNCS(inet_pton, , AC_LIBOBJ(lib/inet_pton))
|
||||
|
||||
# Irix 6.5 has getaddrinfo but not the corresponding defines, so use
|
||||
# builtin getaddrinfo if one of the defines don't exist
|
||||
AC_CACHE_CHECK([whether defines needed by getaddrinfo exist],
|
||||
rsync_cv_HAVE_GETADDR_DEFINES,[
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#ifdef AI_PASSIVE
|
||||
yes
|
||||
#endif],
|
||||
rsync_cv_HAVE_GETADDR_DEFINES=yes,
|
||||
rsync_cv_HAVE_GETADDR_DEFINES=no)])
|
||||
if test x"$rsync_cv_HAVE_GETADDR_DEFINES" = x"yes"; then
|
||||
# Tru64 UNIX has getaddrinfo() but has it renamed in libc as
|
||||
# something else so we must include <netdb.h> to get the
|
||||
# redefinition.
|
||||
AC_CHECK_FUNCS(getaddrinfo, ,
|
||||
[AC_MSG_CHECKING([for getaddrinfo by including <netdb.h>])
|
||||
AC_TRY_LINK([#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>],[getaddrinfo(NULL, NULL, NULL, NULL);],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_GETADDRINFO, 1,
|
||||
[Define if you have the `getaddrinfo' function.])],
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_LIBOBJ(lib/getaddrinfo)])])
|
||||
AC_CHECK_FUNCS(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
|
||||
else
|
||||
AC_LIBOBJ(lib/getaddrinfo)
|
||||
AC_LIBOBJ(lib/getnameinfo)
|
||||
fi
|
||||
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr.sa_len],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(struct sockaddr_storage)
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <sys/socket.h>],
|
||||
[struct sockaddr_storage x;],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1,
|
||||
[Define if you have strct sockaddr_storage.] ),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_scope_id],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_IN6_SCOPE_ID) ],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
])
|
||||
|
||||
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
|
||||
#
|
||||
AC_CHECK_FUNCS(strcasecmp)
|
||||
if test x"$ac_cv_func_strcasecmp" = x"no"; then
|
||||
AC_CHECK_LIB(resolv, strcasecmp)
|
||||
fi
|
||||
|
||||
dnl At the moment we don't test for a broken memcmp(), because all we
|
||||
dnl need to do is test for equality, not comparison, and it seems that
|
||||
dnl every platform has a memcmp that can do at least that.
|
||||
dnl AC_FUNC_MEMCMP
|
||||
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_FUNC_ALLOCA
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod mkfifo)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
|
||||
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy strtol mtrace mallinfo setgroups)
|
||||
|
||||
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
main() {
|
||||
int fd[2];
|
||||
exit((socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1);
|
||||
}],
|
||||
rsync_cv_HAVE_SOCKETPAIR=yes,rsync_cv_HAVE_SOCKETPAIR=no,rsync_cv_HAVE_SOCKETPAIR=cross)])
|
||||
if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
|
||||
AC_DEFINE(HAVE_SOCKETPAIR, 1, [ ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for working fnmatch],rsync_cv_HAVE_FNMATCH,[
|
||||
AC_TRY_RUN([#include <fnmatch.h>
|
||||
main() { exit((fnmatch("*.o", "x.o", FNM_PATHNAME) == 0 &&
|
||||
fnmatch("a/b/*", "a/b/c/d", FNM_PATHNAME) != 0) ? 0: 1); }],
|
||||
rsync_cv_HAVE_FNMATCH=yes,rsync_cv_HAVE_FNMATCH=no,rsync_cv_HAVE_FNMATCH=cross)])
|
||||
if test x"$rsync_cv_HAVE_FNMATCH" = x"yes"; then
|
||||
AC_DEFINE(HAVE_FNMATCH, 1, [ ])
|
||||
fi
|
||||
|
||||
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
|
||||
AC_MSG_RESULT($srcdir/popt)
|
||||
BUILD_POPT='$(popt_OBJS)'
|
||||
CFLAGS="$CFLAGS -I$srcdir/popt"
|
||||
if test x"$ALLOCA" != x
|
||||
then
|
||||
# this can be removed when/if we add an included alloca.c;
|
||||
# see autoconf documentation on AC_FUNC_ALLOCA
|
||||
AC_MSG_WARN([included libpopt will use malloc, not alloca (which wastes a small amount of memory)])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for long long],rsync_cv_HAVE_LONGLONG,[
|
||||
AC_TRY_RUN([#include <stdio.h>
|
||||
main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }],
|
||||
rsync_cv_HAVE_LONGLONG=yes,rsync_cv_HAVE_LONGLONG=no,rsync_cv_HAVE_LONGLONG=cross)])
|
||||
if test x"$rsync_cv_HAVE_LONGLONG" = x"yes"; then
|
||||
AC_DEFINE(HAVE_LONGLONG, 1, [ ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for off64_t],rsync_cv_HAVE_OFF64_T,[
|
||||
AC_TRY_RUN([#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
|
||||
rsync_cv_HAVE_OFF64_T=yes,rsync_cv_HAVE_OFF64_T=no,rsync_cv_HAVE_OFF64_T=cross)])
|
||||
if test x"$rsync_cv_HAVE_OFF64_T" = x"yes"; then
|
||||
AC_DEFINE(HAVE_OFF64_T, 1, [ ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for short ino_t],rsync_cv_HAVE_SHORT_INO_T,[
|
||||
AC_TRY_RUN([#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
main() { if (sizeof(ino_t) < sizeof(unsigned int)) return 0; return 1; }],
|
||||
rsync_cv_HAVE_SHORT_INO_T=yes,rsync_cv_HAVE_SHORT_INO_T=no,rsync_cv_HAVE_SHORT_INO_T=cross)])
|
||||
if test x"$rsync_cv_HAVE_SHORT_INO_T" = x"yes"; then
|
||||
AC_DEFINE(HAVE_SHORT_INO_T, 1, [ ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for unsigned char],rsync_cv_HAVE_UNSIGNED_CHAR,[
|
||||
AC_TRY_RUN([#include <stdio.h>
|
||||
main() { char c; c=250; exit((c > 0)?0:1); }],
|
||||
rsync_cv_HAVE_UNSIGNED_CHAR=yes,rsync_cv_HAVE_UNSIGNED_CHAR=no,rsync_cv_HAVE_UNSIGNED_CHAR=cross)])
|
||||
if test x"$rsync_cv_HAVE_UNSIGNED_CHAR" = x"yes"; then
|
||||
AC_DEFINE(HAVE_UNSIGNED_CHAR, 1, [ ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for broken readdir],rsync_cv_HAVE_BROKEN_READDIR,[
|
||||
AC_TRY_RUN([#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
main() { struct dirent *di; DIR *d = opendir("."); di = readdir(d);
|
||||
if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 &&
|
||||
di->d_name[0] == 0) exit(0); exit(1);} ],
|
||||
rsync_cv_HAVE_BROKEN_READDIR=yes,rsync_cv_HAVE_BROKEN_READDIR=no,rsync_cv_HAVE_BROKEN_READDIR=cross)])
|
||||
if test x"$rsync_cv_HAVE_BROKEN_READDIR" = x"yes"; then
|
||||
AC_DEFINE(HAVE_BROKEN_READDIR, 1, [ ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for utimbuf],rsync_cv_HAVE_UTIMBUF,[
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <utime.h>],
|
||||
[struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));],
|
||||
rsync_cv_HAVE_UTIMBUF=yes,rsync_cv_HAVE_UTIMBUF=no,rsync_cv_HAVE_UTIMBUF=cross)])
|
||||
if test x"$rsync_cv_HAVE_UTIMBUF" = x"yes"; then
|
||||
AC_DEFINE(HAVE_UTIMBUF, 1, [ ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([if gettimeofday takes tz argument],rsync_cv_HAVE_GETTIMEOFDAY_TZ,[
|
||||
AC_TRY_RUN([
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}],
|
||||
rsync_cv_HAVE_GETTIMEOFDAY_TZ=yes,rsync_cv_HAVE_GETTIMEOFDAY_TZ=no,rsync_cv_HAVE_GETTIMEOFDAY_TZ=cross)])
|
||||
if test x"$rsync_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then
|
||||
AC_DEFINE(HAVE_GETTIMEOFDAY_TZ, 1, [ ])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for C99 vsnprintf],rsync_cv_HAVE_C99_VSNPRINTF,[
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
void foo(const char *format, ...) {
|
||||
va_list ap;
|
||||
int len;
|
||||
char buf[5];
|
||||
|
||||
va_start(ap, format);
|
||||
len = vsnprintf(0, 0, format, ap);
|
||||
va_end(ap);
|
||||
if (len != 5) exit(1);
|
||||
|
||||
if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
main() { foo("hello"); }
|
||||
],
|
||||
rsync_cv_HAVE_C99_VSNPRINTF=yes,rsync_cv_HAVE_C99_VSNPRINTF=no,rsync_cv_HAVE_C99_VSNPRINTF=cross)])
|
||||
if test x"$rsync_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
|
||||
AC_DEFINE(HAVE_C99_VSNPRINTF, 1, [ ])
|
||||
fi
|
||||
|
||||
|
||||
AC_CACHE_CHECK([for secure mkstemp],rsync_cv_HAVE_SECURE_MKSTEMP,[
|
||||
AC_TRY_RUN([#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
main() {
|
||||
struct stat st;
|
||||
char tpl[20]="/tmp/test.XXXXXX";
|
||||
int fd = mkstemp(tpl);
|
||||
if (fd == -1) exit(1);
|
||||
unlink(tpl);
|
||||
if (fstat(fd, &st) != 0) exit(1);
|
||||
if ((st.st_mode & 0777) != 0600) exit(1);
|
||||
exit(0);
|
||||
}],
|
||||
rsync_cv_HAVE_SECURE_MKSTEMP=yes,
|
||||
rsync_cv_HAVE_SECURE_MKSTEMP=no,
|
||||
rsync_cv_HAVE_SECURE_MKSTEMP=cross)])
|
||||
if test x"$rsync_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then
|
||||
AC_DEFINE(HAVE_SECURE_MKSTEMP, 1, [ ])
|
||||
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, [ ])
|
||||
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, [ ])
|
||||
fi
|
||||
|
||||
#
|
||||
# The following test was mostly taken from the tcl/tk plus patches
|
||||
#
|
||||
AC_CACHE_CHECK([whether -c -o works],rsync_cv_DASHC_WORKS_WITH_DASHO,[
|
||||
rm -rf conftest*
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
int main() { return 0; }
|
||||
EOF
|
||||
${CC-cc} -c -o conftest..o conftest.$ac_ext
|
||||
if test -f conftest..o; then
|
||||
rsync_cv_DASHC_WORKS_WITH_DASHO=yes
|
||||
else
|
||||
rsync_cv_DASHC_WORKS_WITH_DASHO=no
|
||||
fi
|
||||
rm -rf conftest*
|
||||
])
|
||||
if test x"$rsync_cv_DASHC_WORKS_WITH_DASHO" = x"yes"; then
|
||||
OBJ_SAVE="#"
|
||||
OBJ_RESTORE="#"
|
||||
CC_SHOBJ_FLAG='-o $@'
|
||||
else
|
||||
OBJ_SAVE=' @b=`basename $@ .o`;rm -f $$b.o.sav;if test -f $$b.o; then mv $$b.o $$b.o.sav;fi;'
|
||||
OBJ_RESTORE=' @b=`basename $@ .o`;if test "$$b.o" != "$@"; then mv $$b.o $@; if test -f $$b.o.sav; then mv $$b.o.sav $$b.o; fi; fi'
|
||||
CC_SHOBJ_FLAG=""
|
||||
fi
|
||||
|
||||
AC_SUBST(OBJ_SAVE)
|
||||
AC_SUBST(OBJ_RESTORE)
|
||||
AC_SUBST(CC_SHOBJ_FLAG)
|
||||
AC_SUBST(BUILD_POPT)
|
||||
|
||||
AC_CONFIG_FILES([Makefile lib/dummy zlib/dummy popt/dummy shconfig])
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_RESULT()
|
||||
AC_MSG_RESULT([ rsync ${RSYNC_VERSION} configuration successful])
|
||||
AC_MSG_RESULT()
|
||||
67
connection.c
67
connection.c
@@ -1,49 +1,46 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Support the max connections option.
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
/* support the max connections option */
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
simple routine to do connection counting
|
||||
****************************************************************************/
|
||||
int claim_connection(char *fname,int max_connections)
|
||||
/* A simple routine to do connection counting. This returns 1 on success
|
||||
* and 0 on failure, with errno also being set if the open() failed (errno
|
||||
* will be 0 if the lock request failed). */
|
||||
int claim_connection(char *fname, int max_connections)
|
||||
{
|
||||
int fd, i;
|
||||
|
||||
if (max_connections <= 0)
|
||||
if (max_connections == 0)
|
||||
return 1;
|
||||
|
||||
fd = open(fname,O_RDWR|O_CREAT, 0600);
|
||||
|
||||
if (fd == -1) {
|
||||
if ((fd = open(fname, O_RDWR|O_CREAT, 0600)) < 0)
|
||||
return 0;
|
||||
|
||||
/* Find a free spot. */
|
||||
for (i = 0; i < max_connections; i++) {
|
||||
if (lock_range(fd, i*4, 4))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* find a free spot */
|
||||
for (i=0;i<max_connections;i++) {
|
||||
if (lock_range(fd, i*4, 4)) return 1;
|
||||
}
|
||||
|
||||
/* only interested in open failures */
|
||||
errno = 0;
|
||||
|
||||
close(fd);
|
||||
|
||||
/* A lock failure needs to return an errno of 0. */
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,21 +3,22 @@ basically a summary of clientserver.c and authenticate.c.
|
||||
|
||||
-- Martin Pool <mbp@samba.org>
|
||||
|
||||
$Id$
|
||||
|
||||
|
||||
|
||||
|
||||
This is the protocol used for rsync --daemon; i.e. connections to port
|
||||
873 rather than invocations over a remote shell.
|
||||
|
||||
When the server accepts a connection, it prints a greeting
|
||||
|
||||
@RSYNCD: <version>
|
||||
@RSYNCD: <version>.<subprotocol>
|
||||
|
||||
where <version> is the numeric version; currently 24. It follows this
|
||||
with a free text message-of-the-day. It expects to see a similar
|
||||
greeting back from the client.
|
||||
where <version> is the numeric version (see PROTOCOL_VERSION in rsync.h)
|
||||
'.' is a literal period, and <subprotocol> is the numeric subprotocol
|
||||
version (see SUBPROTOCOL_VERSION -- it will be 0 for final releases).
|
||||
Protocols prior to 30 only output <version> alone. The daemon expects
|
||||
to see a similar greeting back from the client. For protocols prior to
|
||||
30, an absent ".<subprotocol>" value is assumed to be 0. For protocol
|
||||
30, an absent value is a fatal error. The daemon then follows this line
|
||||
with a free-format text message-of-the-day (if any is defined).
|
||||
|
||||
The server is now in the connected state. The client can either send
|
||||
the command
|
||||
@@ -75,8 +76,13 @@ stay tuned (or write it yourself!).
|
||||
------------
|
||||
Protocol version changes
|
||||
|
||||
25 (2001-08-20, 2.4.7pre2)
|
||||
30 (2007-10-04, 3.0.0pre1)
|
||||
|
||||
Send an explicit "@RSYNC EXIT" command at the end of the
|
||||
module listing. We never intentionally end the transmission
|
||||
by just closing the socket anymore.
|
||||
The use of a ".<subprotocol>" number was added to
|
||||
@RSYNCD: <version>.<subprotocol>
|
||||
|
||||
25 (2001-08-20, 2.4.7pre2)
|
||||
|
||||
Send an explicit "@RSYNC EXIT" command at the end of the
|
||||
module listing. We never intentionally end the transmission
|
||||
by just closing the socket anymore.
|
||||
|
||||
240
delete.c
Normal file
240
delete.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Deletion routines used in rsync.
|
||||
*
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int am_root;
|
||||
extern int make_backups;
|
||||
extern int max_delete;
|
||||
extern char *backup_dir;
|
||||
extern char *backup_suffix;
|
||||
extern int backup_suffix_len;
|
||||
extern struct stats stats;
|
||||
|
||||
int ignore_perishable = 0;
|
||||
int non_perishable_cnt = 0;
|
||||
int skipped_deletes = 0;
|
||||
|
||||
static inline int is_backup_file(char *fn)
|
||||
{
|
||||
int k = strlen(fn) - backup_suffix_len;
|
||||
return k > 0 && strcmp(fn+k, backup_suffix) == 0;
|
||||
}
|
||||
|
||||
/* The directory is about to be deleted: if DEL_RECURSE is given, delete all
|
||||
* its contents, otherwise just checks for content. Returns DR_SUCCESS or
|
||||
* DR_NOT_EMPTY. Note that fname must point to a MAXPATHLEN buffer! (The
|
||||
* buffer is used for recursion, but returned unchanged.)
|
||||
*/
|
||||
static enum delret delete_dir_contents(char *fname, uint16 flags)
|
||||
{
|
||||
struct file_list *dirlist;
|
||||
enum delret ret;
|
||||
unsigned remainder;
|
||||
void *save_filters;
|
||||
int j, dlen;
|
||||
char *p;
|
||||
|
||||
if (DEBUG_GTE(DEL, 3)) {
|
||||
rprintf(FINFO, "delete_dir_contents(%s) flags=%d\n",
|
||||
fname, flags);
|
||||
}
|
||||
|
||||
dlen = strlen(fname);
|
||||
save_filters = push_local_filters(fname, dlen);
|
||||
|
||||
non_perishable_cnt = 0;
|
||||
dirlist = get_dirlist(fname, dlen, 0);
|
||||
ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS;
|
||||
|
||||
if (!dirlist->used)
|
||||
goto done;
|
||||
|
||||
if (!(flags & DEL_RECURSE)) {
|
||||
ret = DR_NOT_EMPTY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p = fname + dlen;
|
||||
if (dlen != 1 || *fname != '/')
|
||||
*p++ = '/';
|
||||
remainder = MAXPATHLEN - (p - fname);
|
||||
|
||||
/* We do our own recursion, so make delete_item() non-recursive. */
|
||||
flags = (flags & ~(DEL_RECURSE|DEL_MAKE_ROOM|DEL_NO_UID_WRITE))
|
||||
| DEL_DIR_IS_EMPTY;
|
||||
|
||||
for (j = dirlist->used; j--; ) {
|
||||
struct file_struct *fp = dirlist->files[j];
|
||||
|
||||
if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) {
|
||||
if (DEBUG_GTE(DEL, 1)) {
|
||||
rprintf(FINFO,
|
||||
"mount point, %s, pins parent directory\n",
|
||||
f_name(fp, NULL));
|
||||
}
|
||||
ret = DR_NOT_EMPTY;
|
||||
continue;
|
||||
}
|
||||
|
||||
strlcpy(p, fp->basename, remainder);
|
||||
if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
|
||||
do_chmod(fname, fp->mode | S_IWUSR);
|
||||
/* Save stack by recursing to ourself directly. */
|
||||
if (S_ISDIR(fp->mode)) {
|
||||
if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS)
|
||||
ret = DR_NOT_EMPTY;
|
||||
}
|
||||
if (delete_item(fname, fp->mode, flags) != DR_SUCCESS)
|
||||
ret = DR_NOT_EMPTY;
|
||||
}
|
||||
|
||||
fname[dlen] = '\0';
|
||||
|
||||
done:
|
||||
flist_free(dirlist);
|
||||
pop_local_filters(save_filters);
|
||||
|
||||
if (ret == DR_NOT_EMPTY) {
|
||||
rprintf(FINFO, "cannot delete non-empty directory: %s\n",
|
||||
fname);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Delete a file or directory. If DEL_RECURSE is set in the flags, this will
|
||||
* delete recursively.
|
||||
*
|
||||
* Note that fbuf must point to a MAXPATHLEN buffer if the mode indicates it's
|
||||
* a directory! (The buffer is used for recursion, but returned unchanged.)
|
||||
*/
|
||||
enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
|
||||
{
|
||||
enum delret ret;
|
||||
char *what;
|
||||
int ok;
|
||||
|
||||
if (DEBUG_GTE(DEL, 2)) {
|
||||
rprintf(FINFO, "delete_item(%s) mode=%o flags=%d\n",
|
||||
fbuf, (int)mode, (int)flags);
|
||||
}
|
||||
|
||||
if (flags & DEL_NO_UID_WRITE)
|
||||
do_chmod(fbuf, mode | S_IWUSR);
|
||||
|
||||
if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
|
||||
/* This only happens on the first call to delete_item() since
|
||||
* delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */
|
||||
ignore_perishable = 1;
|
||||
/* If DEL_RECURSE is not set, this just reports emptiness. */
|
||||
ret = delete_dir_contents(fbuf, flags);
|
||||
ignore_perishable = 0;
|
||||
if (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT)
|
||||
goto check_ret;
|
||||
/* OK: try to delete the directory. */
|
||||
}
|
||||
|
||||
if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && stats.deleted_files >= max_delete) {
|
||||
skipped_deletes++;
|
||||
return DR_AT_LIMIT;
|
||||
}
|
||||
|
||||
if (S_ISDIR(mode)) {
|
||||
what = "rmdir";
|
||||
ok = do_rmdir(fbuf) == 0;
|
||||
} else {
|
||||
if (make_backups > 0 && !(flags & DEL_FOR_BACKUP) && (backup_dir || !is_backup_file(fbuf))) {
|
||||
what = "make_backup";
|
||||
ok = make_backup(fbuf, True);
|
||||
if (ok == 2) {
|
||||
what = "unlink";
|
||||
ok = robust_unlink(fbuf) == 0;
|
||||
}
|
||||
} else {
|
||||
what = "unlink";
|
||||
ok = robust_unlink(fbuf) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (!(flags & DEL_MAKE_ROOM)) {
|
||||
log_delete(fbuf, mode);
|
||||
stats.deleted_files++;
|
||||
if (S_ISREG(mode)) {
|
||||
/* Nothing more to count */
|
||||
} else if (S_ISDIR(mode))
|
||||
stats.deleted_dirs++;
|
||||
#ifdef SUPPORT_LINKS
|
||||
else if (S_ISLNK(mode))
|
||||
stats.deleted_symlinks++;
|
||||
#endif
|
||||
else if (IS_DEVICE(mode))
|
||||
stats.deleted_symlinks++;
|
||||
else
|
||||
stats.deleted_specials++;
|
||||
}
|
||||
ret = DR_SUCCESS;
|
||||
} else {
|
||||
if (S_ISDIR(mode) && errno == ENOTEMPTY) {
|
||||
rprintf(FINFO, "cannot delete non-empty directory: %s\n",
|
||||
fbuf);
|
||||
ret = DR_NOT_EMPTY;
|
||||
} else if (errno != ENOENT) {
|
||||
rsyserr(FERROR_XFER, errno, "delete_file: %s(%s) failed",
|
||||
what, fbuf);
|
||||
ret = DR_FAILURE;
|
||||
} else
|
||||
ret = DR_SUCCESS;
|
||||
}
|
||||
|
||||
check_ret:
|
||||
if (ret != DR_SUCCESS && flags & DEL_MAKE_ROOM) {
|
||||
const char *desc;
|
||||
switch (flags & DEL_MAKE_ROOM) {
|
||||
case DEL_FOR_FILE: desc = "regular file"; break;
|
||||
case DEL_FOR_DIR: desc = "directory"; break;
|
||||
case DEL_FOR_SYMLINK: desc = "symlink"; break;
|
||||
case DEL_FOR_DEVICE: desc = "device file"; break;
|
||||
case DEL_FOR_SPECIAL: desc = "special file"; break;
|
||||
default: exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */
|
||||
}
|
||||
rprintf(FERROR_XFER, "could not make way for %s %s: %s\n",
|
||||
flags & DEL_FOR_BACKUP ? "backup" : "new",
|
||||
desc, fbuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16 get_del_for_flag(uint16 mode)
|
||||
{
|
||||
if (S_ISREG(mode))
|
||||
return DEL_FOR_FILE;
|
||||
if (S_ISDIR(mode))
|
||||
return DEL_FOR_DIR;
|
||||
if (S_ISLNK(mode))
|
||||
return DEL_FOR_SYMLINK;
|
||||
if (IS_DEVICE(mode))
|
||||
return DEL_FOR_DEVICE;
|
||||
if (IS_SPECIAL(mode))
|
||||
return DEL_FOR_SPECIAL;
|
||||
exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
rsync.pdf
|
||||
rsync.ps
|
||||
51
errcode.h
51
errcode.h
@@ -1,32 +1,31 @@
|
||||
/* -*- c-file-style: "linux"; -*-
|
||||
|
||||
Copyright (C) 1998-2000 by Andrew Tridgell
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* error codes returned by rsync. If you change these, please also update the
|
||||
* string mappings in log.c
|
||||
* Error codes returned by rsync.
|
||||
*
|
||||
* Copyright (C) 1998-2000 Andrew Tridgell
|
||||
* Copyright (C) 2003-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
/* If you change these, please also update the string mappings in log.c and
|
||||
* the EXIT VALUES in rsync.yo. */
|
||||
|
||||
#define RERR_OK 0
|
||||
#define RERR_SYNTAX 1 /* syntax or usage error */
|
||||
#define RERR_PROTOCOL 2 /* protocol incompatibility */
|
||||
#define RERR_FILESELECT 3 /* errors selecting input/output files, dirs */
|
||||
#define RERR_UNSUPPORTED 4 /* requested action not supported */
|
||||
#define RERR_UNSUPPORTED 4 /* requested action not supported */
|
||||
#define RERR_STARTCLIENT 5 /* error starting client-server protocol */
|
||||
|
||||
#define RERR_SOCKETIO 10 /* error in socket IO */
|
||||
@@ -34,13 +33,19 @@
|
||||
#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 */
|
||||
#define RERR_VANISHED 24 /* file(s) vanished on sender side */
|
||||
#define RERR_DEL_LIMIT 25 /* skipped some deletes due to --max-delete */
|
||||
|
||||
#define RERR_TIMEOUT 30 /* timeout in data send/receive */
|
||||
#define RERR_CONTIMEOUT 35 /* timeout waiting for daemon connection */
|
||||
|
||||
/* Although it doesn't seem to be specified anywhere,
|
||||
* ssh and the shell seem to return these values:
|
||||
|
||||
333
fileio.c
333
fileio.c
@@ -1,89 +1,160 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
File IO utilities used in rsync
|
||||
*/
|
||||
#include "rsync.h"
|
||||
* File IO utilities used in rsync.
|
||||
*
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2004-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
|
||||
#ifndef ENODATA
|
||||
#define ENODATA EAGAIN
|
||||
#endif
|
||||
|
||||
/* We want all reads to be aligned on 1K boundries. */
|
||||
#define ALIGN_BOUNDRY 1024
|
||||
/* How far past the boundary is an offset? */
|
||||
#define ALIGNED_OVERSHOOT(oft) ((oft) & (ALIGN_BOUNDRY-1))
|
||||
/* Round up a length to the next boundary */
|
||||
#define ALIGNED_LENGTH(len) ((((len) - 1) | (ALIGN_BOUNDRY-1)) + 1)
|
||||
|
||||
static char last_byte;
|
||||
static int last_sparse;
|
||||
extern int sparse_files;
|
||||
|
||||
int sparse_end(int f)
|
||||
static OFF_T sparse_seek = 0;
|
||||
|
||||
int sparse_end(int f, OFF_T size)
|
||||
{
|
||||
if (last_sparse) {
|
||||
do_lseek(f,-1,SEEK_CUR);
|
||||
return (write(f,&last_byte,1) == 1 ? 0 : -1);
|
||||
int ret;
|
||||
|
||||
if (!sparse_seek)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_FTRUNCATE
|
||||
ret = do_ftruncate(f, size);
|
||||
#else
|
||||
if (do_lseek(f, sparse_seek-1, SEEK_CUR) != size-1)
|
||||
ret = -1;
|
||||
else {
|
||||
do {
|
||||
ret = write(f, "", 1);
|
||||
} while (ret < 0 && errno == EINTR);
|
||||
|
||||
ret = ret <= 0 ? -1 : 0;
|
||||
}
|
||||
last_sparse = 0;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
sparse_seek = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int write_sparse(int f,char *buf,size_t len)
|
||||
static int write_sparse(int f, char *buf, int len)
|
||||
{
|
||||
size_t l1=0, l2=0;
|
||||
int l1 = 0, l2 = 0;
|
||||
int ret;
|
||||
|
||||
for (l1=0;l1<len && buf[l1]==0;l1++) ;
|
||||
for (l2=0;l2<(len-l1) && buf[len-(l2+1)]==0;l2++) ;
|
||||
for (l1 = 0; l1 < len && buf[l1] == 0; l1++) {}
|
||||
for (l2 = 0; l2 < len-l1 && buf[len-(l2+1)] == 0; l2++) {}
|
||||
|
||||
last_byte = buf[len-1];
|
||||
sparse_seek += l1;
|
||||
|
||||
if (l1 == len || l2 > 0)
|
||||
last_sparse=1;
|
||||
|
||||
if (l1 > 0) {
|
||||
do_lseek(f,l1,SEEK_CUR);
|
||||
}
|
||||
|
||||
if (l1 == len)
|
||||
if (l1 == len)
|
||||
return len;
|
||||
|
||||
ret = write(f, buf + l1, len - (l1+l2));
|
||||
if (ret == -1 || ret == 0)
|
||||
return ret;
|
||||
else if (ret != (int) (len - (l1+l2)))
|
||||
return (l1+ret);
|
||||
if (sparse_seek)
|
||||
do_lseek(f, sparse_seek, SEEK_CUR);
|
||||
sparse_seek = l2;
|
||||
|
||||
while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) {
|
||||
if (ret < 0 && errno == EINTR)
|
||||
continue;
|
||||
sparse_seek = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret != (int)(len - (l1+l2))) {
|
||||
sparse_seek = 0;
|
||||
return l1+ret;
|
||||
}
|
||||
|
||||
if (l2 > 0)
|
||||
do_lseek(f,l2,SEEK_CUR);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static char *wf_writeBuf;
|
||||
static size_t wf_writeBufSize;
|
||||
static size_t wf_writeBufCnt;
|
||||
|
||||
int write_file(int f,char *buf,size_t len)
|
||||
int flush_write_file(int f)
|
||||
{
|
||||
int ret = 0;
|
||||
char *bp = wf_writeBuf;
|
||||
|
||||
while (wf_writeBufCnt > 0) {
|
||||
if ((ret = write(f, bp, wf_writeBufCnt)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return ret;
|
||||
}
|
||||
wf_writeBufCnt -= ret;
|
||||
bp += ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* write_file does not allow incomplete writes. It loops internally
|
||||
* until len bytes are written or errno is set.
|
||||
*/
|
||||
int write_file(int f, char *buf, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!sparse_files) {
|
||||
return write(f,buf,len);
|
||||
}
|
||||
|
||||
while (len>0) {
|
||||
int len1 = MIN(len, SPARSE_WRITE_SIZE);
|
||||
int r1 = write_sparse(f, buf, len1);
|
||||
while (len > 0) {
|
||||
int r1;
|
||||
if (sparse_files > 0) {
|
||||
int len1 = MIN(len, SPARSE_WRITE_SIZE);
|
||||
r1 = write_sparse(f, buf, len1);
|
||||
} else {
|
||||
if (!wf_writeBuf) {
|
||||
wf_writeBufSize = WRITE_SIZE * 8;
|
||||
wf_writeBufCnt = 0;
|
||||
wf_writeBuf = new_array(char, wf_writeBufSize);
|
||||
if (!wf_writeBuf)
|
||||
out_of_memory("write_file");
|
||||
}
|
||||
r1 = (int)MIN((size_t)len, wf_writeBufSize - wf_writeBufCnt);
|
||||
if (r1) {
|
||||
memcpy(wf_writeBuf + wf_writeBufCnt, buf, r1);
|
||||
wf_writeBufCnt += r1;
|
||||
}
|
||||
if (wf_writeBufCnt == wf_writeBufSize) {
|
||||
if (flush_write_file(f) < 0)
|
||||
return -1;
|
||||
if (!r1 && len)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (r1 <= 0) {
|
||||
if (ret > 0) return ret;
|
||||
if (ret > 0)
|
||||
return ret;
|
||||
return r1;
|
||||
}
|
||||
len -= r1;
|
||||
@@ -94,80 +165,68 @@ int write_file(int f,char *buf,size_t len)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* this provides functionality somewhat similar to mmap() but using
|
||||
read(). It gives sliding window access to a file. mmap() is not
|
||||
used because of the possibility of another program (such as a
|
||||
mailer) truncating the file thus giving us a SIGBUS */
|
||||
struct map_struct *map_file(int fd,OFF_T len)
|
||||
/* This provides functionality somewhat similar to mmap() but using read().
|
||||
* It gives sliding window access to a file. mmap() is not used because of
|
||||
* the possibility of another program (such as a mailer) truncating the
|
||||
* file thus giving us a SIGBUS. */
|
||||
struct map_struct *map_file(int fd, OFF_T len, int32 read_size, int32 blk_size)
|
||||
{
|
||||
struct map_struct *map;
|
||||
map = (struct map_struct *)malloc(sizeof(*map));
|
||||
if (!map) out_of_memory("map_file");
|
||||
|
||||
if (!(map = new0(struct map_struct)))
|
||||
out_of_memory("map_file");
|
||||
|
||||
if (blk_size && (read_size % blk_size))
|
||||
read_size += blk_size - (read_size % blk_size);
|
||||
|
||||
map->fd = fd;
|
||||
map->file_size = len;
|
||||
map->p = NULL;
|
||||
map->p_size = 0;
|
||||
map->p_offset = 0;
|
||||
map->p_fd_offset = 0;
|
||||
map->p_len = 0;
|
||||
map->def_window_size = ALIGNED_LENGTH(read_size);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
/* slide the read window in the file */
|
||||
char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
|
||||
{
|
||||
int nread;
|
||||
OFF_T window_start, read_start;
|
||||
int window_size, read_size, read_offset;
|
||||
int32 window_size, read_size, read_offset, align_fudge;
|
||||
|
||||
if (len == 0) {
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* can't go beyond the end of file */
|
||||
if (len > (map->file_size - offset)) {
|
||||
len = map->file_size - offset;
|
||||
if (len < 0) {
|
||||
rprintf(FERROR, "invalid len passed to map_ptr: %ld\n",
|
||||
(long)len);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
|
||||
/* in most cases the region will already be available */
|
||||
if (offset >= map->p_offset &&
|
||||
offset+len <= map->p_offset+map->p_len) {
|
||||
return (map->p + (offset - map->p_offset));
|
||||
}
|
||||
|
||||
if (offset >= map->p_offset && offset+len <= map->p_offset+map->p_len)
|
||||
return map->p + (offset - map->p_offset);
|
||||
|
||||
/* nope, we are going to have to do a read. Work out our desired window */
|
||||
if (offset > 2*CHUNK_SIZE) {
|
||||
window_start = offset - 2*CHUNK_SIZE;
|
||||
window_start &= ~((OFF_T)(CHUNK_SIZE-1)); /* assumes power of 2 */
|
||||
} else {
|
||||
window_start = 0;
|
||||
}
|
||||
window_size = MAX_MAP_SIZE;
|
||||
if (window_start + window_size > map->file_size) {
|
||||
window_size = map->file_size - window_start;
|
||||
}
|
||||
if (offset + len > window_start + window_size) {
|
||||
window_size = (offset+len) - window_start;
|
||||
}
|
||||
align_fudge = (int32)ALIGNED_OVERSHOOT(offset);
|
||||
window_start = offset - align_fudge;
|
||||
window_size = map->def_window_size;
|
||||
if (window_start + window_size > map->file_size)
|
||||
window_size = (int32)(map->file_size - window_start);
|
||||
if (window_size < len + align_fudge)
|
||||
window_size = ALIGNED_LENGTH(len + align_fudge);
|
||||
|
||||
/* make sure we have allocated enough memory for the window */
|
||||
if (window_size > map->p_size) {
|
||||
map->p = (char *)Realloc(map->p, window_size);
|
||||
if (!map->p) out_of_memory("map_ptr");
|
||||
map->p = realloc_array(map->p, char, window_size);
|
||||
if (!map->p)
|
||||
out_of_memory("map_ptr");
|
||||
map->p_size = window_size;
|
||||
}
|
||||
|
||||
/* now try to avoid re-reading any bytes by reusing any bytes from the previous
|
||||
buffer. */
|
||||
if (window_start >= map->p_offset &&
|
||||
window_start < map->p_offset + map->p_len &&
|
||||
window_start + window_size >= map->p_offset + map->p_len) {
|
||||
/* Now try to avoid re-reading any bytes by reusing any bytes from the previous buffer. */
|
||||
if (window_start >= map->p_offset && window_start < map->p_offset + map->p_len
|
||||
&& window_start + window_size >= map->p_offset + map->p_len) {
|
||||
read_start = map->p_offset + map->p_len;
|
||||
read_offset = read_start - window_start;
|
||||
read_offset = (int32)(read_start - window_start);
|
||||
read_size = window_size - read_offset;
|
||||
memmove(map->p, map->p + (map->p_len - read_offset), read_offset);
|
||||
} else {
|
||||
@@ -177,39 +236,53 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
}
|
||||
|
||||
if (read_size <= 0) {
|
||||
rprintf(FINFO,"Warning: unexpected read size of %d in map_ptr\n", read_size);
|
||||
} else {
|
||||
if (map->p_fd_offset != read_start) {
|
||||
if (do_lseek(map->fd,read_start,SEEK_SET) != read_start) {
|
||||
rprintf(FERROR,"lseek failed in map_ptr\n");
|
||||
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;
|
||||
/* 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;
|
||||
rprintf(FERROR, "invalid read_size of %ld in map_ptr\n",
|
||||
(long)read_size);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
|
||||
if (map->p_fd_offset != read_start) {
|
||||
OFF_T ret = do_lseek(map->fd, read_start, SEEK_SET);
|
||||
if (ret != read_start) {
|
||||
rsyserr(FERROR, errno, "lseek returned %s, not %s",
|
||||
big_num(ret), big_num(read_start));
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
map->p_fd_offset = read_start;
|
||||
}
|
||||
map->p_offset = window_start;
|
||||
map->p_len = window_size;
|
||||
|
||||
return map->p + (offset - map->p_offset);
|
||||
|
||||
while (read_size > 0) {
|
||||
int32 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 + align_fudge;
|
||||
}
|
||||
|
||||
|
||||
void unmap_file(struct map_struct *map)
|
||||
int unmap_file(struct map_struct *map)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (map->p) {
|
||||
free(map->p);
|
||||
map->p = NULL;
|
||||
}
|
||||
memset(map, 0, sizeof(*map));
|
||||
ret = map->status;
|
||||
memset(map, 0, sizeof map[0]);
|
||||
free(map);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
2618
generator.c
2618
generator.c
File diff suppressed because it is too large
Load Diff
23
getfsdev.c
Normal file
23
getfsdev.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "rsync.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
STRUCT_STAT st;
|
||||
int ret;
|
||||
|
||||
while (--argc > 0) {
|
||||
#ifdef USE_STAT64_FUNCS
|
||||
ret = stat64(*++argv, &st);
|
||||
#else
|
||||
ret = stat(*++argv, &st);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Unable to stat `%s'\n", *argv);
|
||||
exit(1);
|
||||
}
|
||||
printf("%ld/%ld\n", (long)major(st.st_dev),
|
||||
(long)minor(st.st_dev));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
71
getgroups.c
71
getgroups.c
@@ -1,49 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* Print out the gids of all groups for the current user. This is like
|
||||
* `id -G` on Linux, but it's too hard to find a portable equivalent.
|
||||
*
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2003-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* it under the terms of the GNU General Public License version 3 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file getgroups.c
|
||||
*
|
||||
* Print out the gids of all groups for the current user. This is
|
||||
* like `id -G` on Linux, but it's too hard to find a portable
|
||||
* equivalent.
|
||||
**/
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#ifndef NGROUPS
|
||||
/* It ought to be defined, but just in case. */
|
||||
# define NGROUPS 32
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int
|
||||
main(UNUSED(int argc), UNUSED(char *argv[]))
|
||||
{
|
||||
int n, i;
|
||||
gid_t list[NGROUPS];
|
||||
gid_t *list;
|
||||
gid_t gid = MY_GID();
|
||||
int gid_in_list = 0;
|
||||
|
||||
if ((n = getgroups(NGROUPS, list)) == -1) {
|
||||
#ifdef HAVE_GETGROUPS
|
||||
if ((n = getgroups(0, NULL)) < 0) {
|
||||
perror("getgroups");
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
n = 0;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
printf("%u ", list[i]);
|
||||
list = (gid_t*)malloc(sizeof (gid_t) * (n + 1));
|
||||
if (!list) {
|
||||
fprintf(stderr, "out of memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETGROUPS
|
||||
if (n > 0)
|
||||
n = getgroups(n, list);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
printf("%lu ", (unsigned long)list[i]);
|
||||
if (list[i] == gid)
|
||||
gid_in_list = 1;
|
||||
}
|
||||
/* The default gid might not be in the list on some systems. */
|
||||
if (!gid_in_list)
|
||||
printf("%lu", (unsigned long)gid);
|
||||
printf("\n");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
172
hashtable.c
Normal file
172
hashtable.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Routines to provide a memory-efficient hashtable.
|
||||
*
|
||||
* Copyright (C) 2007-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#define HASH_LOAD_LIMIT(size) ((size)*3/4)
|
||||
|
||||
struct hashtable *hashtable_create(int size, int key64)
|
||||
{
|
||||
int req = size;
|
||||
struct hashtable *tbl;
|
||||
int node_size = key64 ? sizeof (struct ht_int64_node)
|
||||
: sizeof (struct ht_int32_node);
|
||||
|
||||
/* Pick a power of 2 that can hold the requested size. */
|
||||
if (size & (size-1) || size < 16) {
|
||||
size = 16;
|
||||
while (size < req)
|
||||
size *= 2;
|
||||
}
|
||||
|
||||
if (!(tbl = new(struct hashtable))
|
||||
|| !(tbl->nodes = new_array0(char, size * node_size)))
|
||||
out_of_memory("hashtable_create");
|
||||
tbl->size = size;
|
||||
tbl->entries = 0;
|
||||
tbl->node_size = node_size;
|
||||
tbl->key64 = key64 ? 1 : 0;
|
||||
|
||||
if (DEBUG_GTE(HASH, 1)) {
|
||||
char buf[32];
|
||||
if (req != size)
|
||||
snprintf(buf, sizeof buf, "req: %d, ", req);
|
||||
else
|
||||
*buf = '\0';
|
||||
rprintf(FINFO, "[%s] created hashtable %lx (%ssize: %d, keys: %d-bit)\n",
|
||||
who_am_i(), (long)tbl, buf, size, key64 ? 64 : 32);
|
||||
}
|
||||
|
||||
return tbl;
|
||||
}
|
||||
|
||||
void hashtable_destroy(struct hashtable *tbl)
|
||||
{
|
||||
if (DEBUG_GTE(HASH, 1)) {
|
||||
rprintf(FINFO, "[%s] destroyed hashtable %lx (size: %d, keys: %d-bit)\n",
|
||||
who_am_i(), (long)tbl, tbl->size, tbl->key64 ? 64 : 32);
|
||||
}
|
||||
free(tbl->nodes);
|
||||
free(tbl);
|
||||
}
|
||||
|
||||
/* This returns the node for the indicated key, either newly created or
|
||||
* already existing. Returns NULL if not allocating and not found. */
|
||||
void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
|
||||
{
|
||||
int key64 = tbl->key64;
|
||||
struct ht_int32_node *node;
|
||||
uint32 ndx;
|
||||
|
||||
if (key64 ? key == 0 : (int32)key == 0) {
|
||||
rprintf(FERROR, "Internal hashtable error: illegal key supplied!\n");
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
|
||||
if (allocate_if_missing && tbl->entries > HASH_LOAD_LIMIT(tbl->size)) {
|
||||
void *old_nodes = tbl->nodes;
|
||||
int size = tbl->size * 2;
|
||||
int i;
|
||||
|
||||
if (!(tbl->nodes = new_array0(char, size * tbl->node_size)))
|
||||
out_of_memory("hashtable_node");
|
||||
tbl->size = size;
|
||||
tbl->entries = 0;
|
||||
|
||||
if (DEBUG_GTE(HASH, 1)) {
|
||||
rprintf(FINFO, "[%s] growing hashtable %lx (size: %d, keys: %d-bit)\n",
|
||||
who_am_i(), (long)tbl, size, key64 ? 64 : 32);
|
||||
}
|
||||
|
||||
for (i = size / 2; i-- > 0; ) {
|
||||
struct ht_int32_node *move_node = HT_NODE(tbl, old_nodes, i);
|
||||
int64 move_key = HT_KEY(move_node, key64);
|
||||
if (move_key == 0)
|
||||
continue;
|
||||
node = hashtable_find(tbl, move_key, 1);
|
||||
node->data = move_node->data;
|
||||
}
|
||||
|
||||
free(old_nodes);
|
||||
}
|
||||
|
||||
if (!key64) {
|
||||
/* Based on Jenkins One-at-a-time hash. */
|
||||
uchar buf[4], *keyp = buf;
|
||||
int i;
|
||||
|
||||
SIVALu(buf, 0, key);
|
||||
for (ndx = 0, i = 0; i < 4; i++) {
|
||||
ndx += keyp[i];
|
||||
ndx += (ndx << 10);
|
||||
ndx ^= (ndx >> 6);
|
||||
}
|
||||
ndx += (ndx << 3);
|
||||
ndx ^= (ndx >> 11);
|
||||
ndx += (ndx << 15);
|
||||
} else {
|
||||
/* Based on Jenkins hashword() from lookup3.c. */
|
||||
uint32 a, b, c;
|
||||
|
||||
/* Set up the internal state */
|
||||
a = b = c = 0xdeadbeef + (8 << 2);
|
||||
|
||||
#define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k))))
|
||||
#if SIZEOF_INT64 >= 8
|
||||
b += (uint32)(key >> 32);
|
||||
#endif
|
||||
a += (uint32)key;
|
||||
c ^= b; c -= rot(b, 14);
|
||||
a ^= c; a -= rot(c, 11);
|
||||
b ^= a; b -= rot(a, 25);
|
||||
c ^= b; c -= rot(b, 16);
|
||||
a ^= c; a -= rot(c, 4);
|
||||
b ^= a; b -= rot(a, 14);
|
||||
c ^= b; c -= rot(b, 24);
|
||||
#undef rot
|
||||
ndx = c;
|
||||
}
|
||||
|
||||
/* If it already exists, return the node. If we're not
|
||||
* allocating, return NULL if the key is not found. */
|
||||
while (1) {
|
||||
int64 nkey;
|
||||
|
||||
ndx &= tbl->size - 1;
|
||||
node = HT_NODE(tbl, tbl->nodes, ndx);
|
||||
nkey = HT_KEY(node, key64);
|
||||
|
||||
if (nkey == key)
|
||||
return node;
|
||||
if (nkey == 0) {
|
||||
if (!allocate_if_missing)
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
ndx++;
|
||||
}
|
||||
|
||||
/* Take over this empty spot and then return the node. */
|
||||
if (key64)
|
||||
((struct ht_int64_node*)node)->key = key;
|
||||
else
|
||||
node->key = (int32)key;
|
||||
tbl->entries++;
|
||||
return node;
|
||||
}
|
||||
679
hlink.c
679
hlink.c
@@ -1,186 +1,571 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Routines to support hard-linking.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2004-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
#include "ifuncs.h"
|
||||
|
||||
extern int dry_run;
|
||||
extern int verbose;
|
||||
extern int list_only;
|
||||
extern int am_sender;
|
||||
extern int inc_recurse;
|
||||
extern int do_xfers;
|
||||
extern int link_dest;
|
||||
extern int preserve_acls;
|
||||
extern int preserve_xattrs;
|
||||
extern int protocol_version;
|
||||
extern int remove_source_files;
|
||||
extern int stdout_format_has_i;
|
||||
extern int maybe_ATTRS_REPORT;
|
||||
extern int unsort_ndx;
|
||||
extern char *basis_dir[MAX_BASIS_DIRS+1];
|
||||
extern struct file_list *cur_flist;
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
static int hlink_compare(struct file_struct *f1, struct file_struct *f2)
|
||||
#ifdef SUPPORT_HARD_LINKS
|
||||
|
||||
/* Starting with protocol 30, we use a simple hashtable on the sending side
|
||||
* for hashing the st_dev and st_ino info. The receiving side gets told
|
||||
* (via flags and a "group index") which items are hard-linked together, so
|
||||
* we can avoid the pool of dev+inode data. For incremental recursion mode,
|
||||
* the receiver will use a ndx hash to remember old pathnames. */
|
||||
|
||||
static struct hashtable *dev_tbl;
|
||||
|
||||
static struct hashtable *prior_hlinks;
|
||||
|
||||
static struct file_list *hlink_flist;
|
||||
|
||||
void init_hard_links(void)
|
||||
{
|
||||
if (!S_ISREG(f1->mode) && !S_ISREG(f2->mode))
|
||||
return 0;
|
||||
if (!S_ISREG(f1->mode))
|
||||
return -1;
|
||||
if (!S_ISREG(f2->mode))
|
||||
return 1;
|
||||
|
||||
if (f1->dev != f2->dev)
|
||||
return (int) (f1->dev > f2->dev ? 1 : -1);
|
||||
|
||||
if (f1->inode != f2->inode)
|
||||
return (int) (f1->inode > f2->inode ? 1 : -1);
|
||||
|
||||
return file_compare(&f1, &f2);
|
||||
if (am_sender || protocol_version < 30)
|
||||
dev_tbl = hashtable_create(16, 1);
|
||||
else if (inc_recurse)
|
||||
prior_hlinks = hashtable_create(1024, 0);
|
||||
}
|
||||
|
||||
|
||||
static struct file_struct *hlink_list;
|
||||
static int hlink_count;
|
||||
#endif
|
||||
|
||||
void init_hard_links(struct file_list *flist)
|
||||
struct ht_int64_node *idev_find(int64 dev, int64 ino)
|
||||
{
|
||||
static struct ht_int64_node *dev_node = NULL;
|
||||
struct hashtable *tbl;
|
||||
|
||||
/* Note that some OSes have a dev == 0, so increment to avoid storing a 0. */
|
||||
if (!dev_node || dev_node->key != dev+1) {
|
||||
/* We keep a separate hash table of inodes for every device. */
|
||||
dev_node = hashtable_find(dev_tbl, dev+1, 1);
|
||||
if (!(tbl = dev_node->data)) {
|
||||
tbl = dev_node->data = hashtable_create(512, 1);
|
||||
if (DEBUG_GTE(HLINK, 3)) {
|
||||
rprintf(FINFO,
|
||||
"[%s] created hashtable for dev %s\n",
|
||||
who_am_i(), big_num(dev));
|
||||
}
|
||||
}
|
||||
} else
|
||||
tbl = dev_node->data;
|
||||
|
||||
return hashtable_find(tbl, ino, 1);
|
||||
}
|
||||
|
||||
void idev_destroy(void)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int i;
|
||||
if (flist->count < 2)
|
||||
return;
|
||||
|
||||
if (hlink_list)
|
||||
free(hlink_list);
|
||||
for (i = 0; i < dev_tbl->size; i++) {
|
||||
struct ht_int32_node *node = HT_NODE(dev_tbl, dev_tbl->nodes, i);
|
||||
if (node->data)
|
||||
hashtable_destroy(node->data);
|
||||
}
|
||||
|
||||
if (!(hlink_list =
|
||||
(struct file_struct *) malloc(sizeof(hlink_list[0]) *
|
||||
flist->count)))
|
||||
out_of_memory("init_hard_links");
|
||||
|
||||
for (i = 0; i < flist->count; i++)
|
||||
memcpy(&hlink_list[i], flist->files[i],
|
||||
sizeof(hlink_list[0]));
|
||||
|
||||
qsort(hlink_list, flist->count,
|
||||
sizeof(hlink_list[0]), (int (*)()) hlink_compare);
|
||||
|
||||
hlink_count = flist->count;
|
||||
#endif
|
||||
hashtable_destroy(dev_tbl);
|
||||
}
|
||||
|
||||
/* check if a file should be skipped because it is the same as an
|
||||
earlier hard link */
|
||||
int check_hard_link(struct file_struct *file)
|
||||
static int hlink_compare_gnum(int *int1, int *int2)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int low = 0, high = hlink_count - 1;
|
||||
int ret = 0;
|
||||
struct file_struct *f1 = hlink_flist->sorted[*int1];
|
||||
struct file_struct *f2 = hlink_flist->sorted[*int2];
|
||||
int32 gnum1 = F_HL_GNUM(f1);
|
||||
int32 gnum2 = F_HL_GNUM(f2);
|
||||
|
||||
if (!hlink_list || !S_ISREG(file->mode))
|
||||
if (gnum1 != gnum2)
|
||||
return gnum1 > gnum2 ? 1 : -1;
|
||||
|
||||
return *int1 > *int2 ? 1 : -1;
|
||||
}
|
||||
|
||||
static void match_gnums(int32 *ndx_list, int ndx_count)
|
||||
{
|
||||
int32 from, prev;
|
||||
struct file_struct *file, *file_next;
|
||||
struct ht_int32_node *node = NULL;
|
||||
int32 gnum, gnum_next;
|
||||
|
||||
qsort(ndx_list, ndx_count, sizeof ndx_list[0],
|
||||
(int (*)()) hlink_compare_gnum);
|
||||
|
||||
for (from = 0; from < ndx_count; from++) {
|
||||
file = hlink_flist->sorted[ndx_list[from]];
|
||||
gnum = F_HL_GNUM(file);
|
||||
if (inc_recurse) {
|
||||
node = hashtable_find(prior_hlinks, gnum, 1);
|
||||
if (!node->data) {
|
||||
if (!(node->data = new_array0(char, 5)))
|
||||
out_of_memory("match_gnums");
|
||||
assert(gnum >= hlink_flist->ndx_start);
|
||||
file->flags |= FLAG_HLINK_FIRST;
|
||||
prev = -1;
|
||||
} else if (CVAL(node->data, 0) == 0) {
|
||||
struct file_list *flist;
|
||||
prev = IVAL(node->data, 1);
|
||||
flist = flist_for_ndx(prev, NULL);
|
||||
if (flist)
|
||||
flist->files[prev - flist->ndx_start]->flags &= ~FLAG_HLINK_LAST;
|
||||
else {
|
||||
/* We skipped all prior files in this
|
||||
* group, so mark this as a "first". */
|
||||
file->flags |= FLAG_HLINK_FIRST;
|
||||
prev = -1;
|
||||
}
|
||||
} else
|
||||
prev = -1;
|
||||
} else {
|
||||
file->flags |= FLAG_HLINK_FIRST;
|
||||
prev = -1;
|
||||
}
|
||||
for ( ; from < ndx_count-1; file = file_next, gnum = gnum_next, from++) { /*SHARED ITERATOR*/
|
||||
file_next = hlink_flist->sorted[ndx_list[from+1]];
|
||||
gnum_next = F_HL_GNUM(file_next);
|
||||
if (gnum != gnum_next)
|
||||
break;
|
||||
F_HL_PREV(file) = prev;
|
||||
/* The linked list uses over-the-wire ndx values. */
|
||||
if (unsort_ndx)
|
||||
prev = F_NDX(file);
|
||||
else
|
||||
prev = ndx_list[from] + hlink_flist->ndx_start;
|
||||
}
|
||||
if (prev < 0 && !inc_recurse) {
|
||||
/* Disable hard-link bit and set DONE so that
|
||||
* HLINK_BUMP()-dependent values are unaffected. */
|
||||
file->flags &= ~(FLAG_HLINKED | FLAG_HLINK_FIRST);
|
||||
file->flags |= FLAG_HLINK_DONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
file->flags |= FLAG_HLINK_LAST;
|
||||
F_HL_PREV(file) = prev;
|
||||
if (inc_recurse && CVAL(node->data, 0) == 0) {
|
||||
if (unsort_ndx)
|
||||
prev = F_NDX(file);
|
||||
else
|
||||
prev = ndx_list[from] + hlink_flist->ndx_start;
|
||||
SIVAL(node->data, 1, prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Analyze the hard-links in the file-list by creating a list of all the
|
||||
* items that have hlink data, sorting them, and matching up identical
|
||||
* values into clusters. These will be a single linked list from last
|
||||
* to first when we're done. */
|
||||
void match_hard_links(struct file_list *flist)
|
||||
{
|
||||
if (!list_only && flist->used) {
|
||||
int i, ndx_count = 0;
|
||||
int32 *ndx_list;
|
||||
|
||||
if (!(ndx_list = new_array(int32, flist->used)))
|
||||
out_of_memory("match_hard_links");
|
||||
|
||||
for (i = 0; i < flist->used; i++) {
|
||||
if (F_IS_HLINKED(flist->sorted[i]))
|
||||
ndx_list[ndx_count++] = i;
|
||||
}
|
||||
|
||||
hlink_flist = flist;
|
||||
|
||||
if (ndx_count)
|
||||
match_gnums(ndx_list, ndx_count);
|
||||
|
||||
free(ndx_list);
|
||||
}
|
||||
if (protocol_version < 30)
|
||||
idev_destroy();
|
||||
}
|
||||
|
||||
static int maybe_hard_link(struct file_struct *file, int ndx,
|
||||
char *fname, int statret, stat_x *sxp,
|
||||
const char *oldname, STRUCT_STAT *old_stp,
|
||||
const char *realname, int itemizing, enum logcode code)
|
||||
{
|
||||
if (statret == 0) {
|
||||
if (sxp->st.st_dev == old_stp->st_dev
|
||||
&& sxp->st.st_ino == old_stp->st_ino) {
|
||||
if (itemizing) {
|
||||
itemize(fname, file, ndx, statret, sxp,
|
||||
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
|
||||
0, "");
|
||||
}
|
||||
if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
|
||||
rprintf(FCLIENT, "%s is uptodate\n", fname);
|
||||
file->flags |= FLAG_HLINK_DONE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (atomic_create(file, fname, NULL, oldname, MAKEDEV(0, 0), sxp, statret == 0 ? DEL_FOR_FILE : 0)) {
|
||||
if (itemizing) {
|
||||
itemize(fname, file, ndx, statret, sxp,
|
||||
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
|
||||
realname);
|
||||
}
|
||||
if (code != FNONE && INFO_GTE(NAME, 1))
|
||||
rprintf(code, "%s => %s\n", fname, realname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (low != high) {
|
||||
int mid = (low + high) / 2;
|
||||
ret = hlink_compare(&hlink_list[mid], file);
|
||||
if (ret == 0) {
|
||||
low = mid;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Figure out if a prior entry is still there or if we just have a
|
||||
* cached name for it. */
|
||||
static char *check_prior(struct file_struct *file, int gnum,
|
||||
int *prev_ndx_p, struct file_list **flist_p)
|
||||
{
|
||||
struct file_struct *fp;
|
||||
struct ht_int32_node *node;
|
||||
int prev_ndx = F_HL_PREV(file);
|
||||
|
||||
while (1) {
|
||||
struct file_list *flist;
|
||||
if (prev_ndx < 0
|
||||
|| (flist = flist_for_ndx(prev_ndx, NULL)) == NULL)
|
||||
break;
|
||||
fp = flist->files[prev_ndx - flist->ndx_start];
|
||||
if (!(fp->flags & FLAG_SKIP_HLINK)) {
|
||||
*prev_ndx_p = prev_ndx;
|
||||
*flist_p = flist;
|
||||
return NULL;
|
||||
}
|
||||
if (ret > 0)
|
||||
high = mid;
|
||||
else
|
||||
low = mid + 1;
|
||||
F_HL_PREV(file) = prev_ndx = F_HL_PREV(fp);
|
||||
}
|
||||
|
||||
/* XXX: To me this looks kind of dodgy -- why do we use [low]
|
||||
* here and [low-1] below? -- mbp */
|
||||
if (hlink_compare(&hlink_list[low], file) != 0)
|
||||
if (inc_recurse
|
||||
&& (node = hashtable_find(prior_hlinks, gnum, 0)) != NULL) {
|
||||
assert(node->data != NULL);
|
||||
if (CVAL(node->data, 0) != 0) {
|
||||
*prev_ndx_p = -1;
|
||||
*flist_p = NULL;
|
||||
return node->data;
|
||||
}
|
||||
/* The prior file must have been skipped. */
|
||||
F_HL_PREV(file) = -1;
|
||||
}
|
||||
|
||||
*prev_ndx_p = -1;
|
||||
*flist_p = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Only called if FLAG_HLINKED is set and FLAG_HLINK_FIRST is not. Returns:
|
||||
* 0 = process the file, 1 = skip the file, -1 = error occurred. */
|
||||
int hard_link_check(struct file_struct *file, int ndx, char *fname,
|
||||
int statret, stat_x *sxp, int itemizing,
|
||||
enum logcode code)
|
||||
{
|
||||
STRUCT_STAT prev_st;
|
||||
char namebuf[MAXPATHLEN], altbuf[MAXPATHLEN];
|
||||
char *realname, *prev_name;
|
||||
struct file_list *flist;
|
||||
int gnum = inc_recurse ? F_HL_GNUM(file) : -1;
|
||||
int prev_ndx;
|
||||
|
||||
prev_name = realname = check_prior(file, gnum, &prev_ndx, &flist);
|
||||
|
||||
if (!prev_name) {
|
||||
struct file_struct *prev_file;
|
||||
|
||||
if (!flist) {
|
||||
/* The previous file was skipped, so this one is
|
||||
* treated as if it were the first in its group. */
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): virtual first\n",
|
||||
ndx, f_name(file, NULL), gnum);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
prev_file = flist->files[prev_ndx - flist->ndx_start];
|
||||
|
||||
/* Is the previous link not complete yet? */
|
||||
if (!(prev_file->flags & FLAG_HLINK_DONE)) {
|
||||
/* Is the previous link being transferred? */
|
||||
if (prev_file->flags & FLAG_FILE_SENT) {
|
||||
/* Add ourselves to the list of files that will
|
||||
* be updated when the transfer completes, and
|
||||
* mark ourself as waiting for the transfer. */
|
||||
F_HL_PREV(file) = F_HL_PREV(prev_file);
|
||||
F_HL_PREV(prev_file) = ndx;
|
||||
file->flags |= FLAG_FILE_SENT;
|
||||
cur_flist->in_progress++;
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): waiting for %d\n",
|
||||
ndx, f_name(file, NULL), gnum, F_HL_PREV(file));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): looking for a leader\n",
|
||||
ndx, f_name(file, NULL), gnum);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* There is a finished file to link with! */
|
||||
if (!(prev_file->flags & FLAG_HLINK_FIRST)) {
|
||||
/* The previous previous is FIRST when prev is not. */
|
||||
prev_name = realname = check_prior(prev_file, gnum, &prev_ndx, &flist);
|
||||
/* Update our previous pointer to point to the FIRST. */
|
||||
F_HL_PREV(file) = prev_ndx;
|
||||
}
|
||||
|
||||
if (!prev_name) {
|
||||
int alt_dest;
|
||||
|
||||
assert(flist != NULL);
|
||||
prev_file = flist->files[prev_ndx - flist->ndx_start];
|
||||
/* F_HL_PREV() is alt_dest value when DONE && FIRST. */
|
||||
alt_dest = F_HL_PREV(prev_file);
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): found flist match (alt %d)\n",
|
||||
ndx, f_name(file, NULL), gnum, alt_dest);
|
||||
}
|
||||
|
||||
if (alt_dest >= 0 && dry_run) {
|
||||
pathjoin(namebuf, MAXPATHLEN, basis_dir[alt_dest],
|
||||
f_name(prev_file, NULL));
|
||||
prev_name = namebuf;
|
||||
realname = f_name(prev_file, altbuf);
|
||||
} else {
|
||||
prev_name = f_name(prev_file, namebuf);
|
||||
realname = prev_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(HLINK, 2)) {
|
||||
rprintf(FINFO, "hlink for %d (%s,%d): leader is %d (%s)\n",
|
||||
ndx, f_name(file, NULL), gnum, prev_ndx, prev_name);
|
||||
}
|
||||
|
||||
if (link_stat(prev_name, &prev_st, 0) < 0) {
|
||||
if (!dry_run || errno != ENOENT) {
|
||||
rsyserr(FERROR_XFER, errno, "stat %s failed", full_fname(prev_name));
|
||||
return -1;
|
||||
}
|
||||
/* A new hard-link will get a new dev & inode, so approximate
|
||||
* those values in dry-run mode by zeroing them. */
|
||||
memset(&prev_st, 0, sizeof prev_st);
|
||||
}
|
||||
|
||||
if (statret < 0 && basis_dir[0] != NULL) {
|
||||
/* If we match an alt-dest item, we don't output this as a change. */
|
||||
char cmpbuf[MAXPATHLEN];
|
||||
stat_x alt_sx;
|
||||
int j = 0;
|
||||
init_stat_x(&alt_sx);
|
||||
do {
|
||||
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
|
||||
if (link_stat(cmpbuf, &alt_sx.st, 0) < 0)
|
||||
continue;
|
||||
if (link_dest) {
|
||||
if (prev_st.st_dev != alt_sx.st.st_dev
|
||||
|| prev_st.st_ino != alt_sx.st.st_ino)
|
||||
continue;
|
||||
statret = 1;
|
||||
if (stdout_format_has_i == 0
|
||||
|| (!INFO_GTE(NAME, 2) && stdout_format_has_i < 2)) {
|
||||
itemizing = 0;
|
||||
code = FNONE;
|
||||
if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
|
||||
rprintf(FCLIENT, "%s is uptodate\n", fname);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!unchanged_file(cmpbuf, file, &alt_sx.st))
|
||||
continue;
|
||||
statret = 1;
|
||||
if (unchanged_attrs(cmpbuf, file, &alt_sx))
|
||||
break;
|
||||
} while (basis_dir[++j] != NULL);
|
||||
if (statret == 1) {
|
||||
sxp->st = alt_sx.st;
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
free_acl(sxp);
|
||||
if (!ACL_READY(alt_sx))
|
||||
get_acl(cmpbuf, sxp);
|
||||
else {
|
||||
sxp->acc_acl = alt_sx.acc_acl;
|
||||
sxp->def_acl = alt_sx.def_acl;
|
||||
alt_sx.acc_acl = alt_sx.def_acl = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
free_xattr(sxp);
|
||||
if (!XATTR_READY(alt_sx))
|
||||
get_xattr(cmpbuf, sxp);
|
||||
else {
|
||||
sxp->xattr = alt_sx.xattr;
|
||||
alt_sx.xattr = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
free_stat_x(&alt_sx);
|
||||
}
|
||||
|
||||
if (maybe_hard_link(file, ndx, fname, statret, sxp, prev_name, &prev_st,
|
||||
realname, itemizing, code) < 0)
|
||||
return -1;
|
||||
|
||||
if (remove_source_files == 1 && do_xfers)
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int hard_link_one(struct file_struct *file, const char *fname,
|
||||
const char *oldname, int terse)
|
||||
{
|
||||
if (do_link(oldname, fname) < 0) {
|
||||
enum logcode code;
|
||||
if (terse) {
|
||||
if (!INFO_GTE(NAME, 1))
|
||||
return 0;
|
||||
code = FINFO;
|
||||
} else
|
||||
code = FERROR_XFER;
|
||||
rsyserr(code, errno, "link %s => %s failed",
|
||||
full_fname(fname), oldname);
|
||||
return 0;
|
||||
|
||||
if (low > 0 &&
|
||||
S_ISREG(hlink_list[low - 1].mode) &&
|
||||
file->dev == hlink_list[low - 1].dev &&
|
||||
file->inode == hlink_list[low - 1].inode) {
|
||||
if (verbose >= 2) {
|
||||
rprintf(FINFO, "check_hard_link: \"%s\" is a hard link to file %d, \"%s\"\n",
|
||||
f_name(file), low-1, f_name(&hlink_list[low-1]));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
file->flags |= FLAG_HLINK_DONE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#if SUPPORT_HARD_LINKS
|
||||
static void hard_link_one(int i)
|
||||
void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
|
||||
STRUCT_STAT *stp, int itemizing, enum logcode code,
|
||||
int alt_dest)
|
||||
{
|
||||
STRUCT_STAT st1, st2;
|
||||
stat_x prev_sx;
|
||||
STRUCT_STAT st;
|
||||
char prev_name[MAXPATHLEN], alt_name[MAXPATHLEN];
|
||||
const char *our_name;
|
||||
struct file_list *flist;
|
||||
int prev_statret, ndx, prev_ndx = F_HL_PREV(file);
|
||||
|
||||
if (link_stat(f_name(&hlink_list[i - 1]), &st1) != 0)
|
||||
return;
|
||||
|
||||
if (link_stat(f_name(&hlink_list[i]), &st2) != 0) {
|
||||
if (do_link
|
||||
(f_name(&hlink_list[i - 1]),
|
||||
f_name(&hlink_list[i])) != 0) {
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO, "link %s => %s : %s\n",
|
||||
f_name(&hlink_list[i]),
|
||||
f_name(&hlink_list[i - 1]),
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino)
|
||||
return;
|
||||
|
||||
if (robust_unlink(f_name(&hlink_list[i])) != 0 ||
|
||||
do_link(f_name(&hlink_list[i - 1]),
|
||||
f_name(&hlink_list[i])) != 0) {
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO, "link %s => %s : %s\n",
|
||||
f_name(&hlink_list[i]),
|
||||
f_name(&hlink_list[i - 1]),
|
||||
strerror(errno));
|
||||
if (stp == NULL && prev_ndx >= 0) {
|
||||
if (link_stat(fname, &st, 0) < 0 && !dry_run) {
|
||||
rsyserr(FERROR_XFER, errno, "stat %s failed",
|
||||
full_fname(fname));
|
||||
return;
|
||||
}
|
||||
stp = &st;
|
||||
}
|
||||
|
||||
/* FIRST combined with DONE means we were the first to get done. */
|
||||
file->flags |= FLAG_HLINK_FIRST | FLAG_HLINK_DONE;
|
||||
F_HL_PREV(file) = alt_dest;
|
||||
if (alt_dest >= 0 && dry_run) {
|
||||
pathjoin(alt_name, MAXPATHLEN, basis_dir[alt_dest],
|
||||
f_name(file, NULL));
|
||||
our_name = alt_name;
|
||||
} else
|
||||
our_name = fname;
|
||||
|
||||
init_stat_x(&prev_sx);
|
||||
|
||||
while ((ndx = prev_ndx) >= 0) {
|
||||
int val;
|
||||
flist = flist_for_ndx(ndx, "finish_hard_link");
|
||||
file = flist->files[ndx - flist->ndx_start];
|
||||
file->flags = (file->flags & ~FLAG_HLINK_FIRST) | FLAG_HLINK_DONE;
|
||||
prev_ndx = F_HL_PREV(file);
|
||||
F_HL_PREV(file) = fin_ndx;
|
||||
prev_statret = link_stat(f_name(file, prev_name), &prev_sx.st, 0);
|
||||
val = maybe_hard_link(file, ndx, prev_name, prev_statret, &prev_sx,
|
||||
our_name, stp, fname, itemizing, code);
|
||||
flist->in_progress--;
|
||||
free_stat_x(&prev_sx);
|
||||
if (val < 0)
|
||||
continue;
|
||||
if (remove_source_files == 1 && do_xfers)
|
||||
send_msg_int(MSG_SUCCESS, ndx);
|
||||
}
|
||||
|
||||
if (inc_recurse) {
|
||||
int gnum = F_HL_GNUM(file);
|
||||
struct ht_int32_node *node = hashtable_find(prior_hlinks, gnum, 0);
|
||||
if (node == NULL) {
|
||||
rprintf(FERROR, "Unable to find a hlink node for %d (%s)\n", gnum, f_name(file, prev_name));
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
if (node->data == NULL) {
|
||||
rprintf(FERROR, "Hlink node data for %d is NULL (%s)\n", gnum, f_name(file, prev_name));
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
if (CVAL(node->data, 0) != 0) {
|
||||
rprintf(FERROR, "Hlink node data for %d already has path=%s (%s)\n",
|
||||
gnum, (char*)node->data, f_name(file, prev_name));
|
||||
exit_cleanup(RERR_MESSAGEIO);
|
||||
}
|
||||
free(node->data);
|
||||
if (!(node->data = strdup(our_name)))
|
||||
out_of_memory("finish_hard_link");
|
||||
}
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO, "%s => %s\n",
|
||||
f_name(&hlink_list[i]),
|
||||
f_name(&hlink_list[i - 1]));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create any hard links in the global hlink_list. They were put
|
||||
* there by running init_hard_links on the filelist.
|
||||
**/
|
||||
void do_hard_links(void)
|
||||
int skip_hard_link(struct file_struct *file, struct file_list **flist_p)
|
||||
{
|
||||
#if SUPPORT_HARD_LINKS
|
||||
int i;
|
||||
struct file_list *flist;
|
||||
int prev_ndx;
|
||||
|
||||
if (!hlink_list)
|
||||
return;
|
||||
file->flags |= FLAG_SKIP_HLINK;
|
||||
if (!(file->flags & FLAG_HLINK_LAST))
|
||||
return -1;
|
||||
|
||||
for (i = 1; i < hlink_count; i++) {
|
||||
if (S_ISREG(hlink_list[i].mode) &&
|
||||
S_ISREG(hlink_list[i - 1].mode) &&
|
||||
hlink_list[i].basename && hlink_list[i - 1].basename &&
|
||||
hlink_list[i].dev == hlink_list[i - 1].dev &&
|
||||
hlink_list[i].inode == hlink_list[i - 1].inode) {
|
||||
hard_link_one(i);
|
||||
}
|
||||
check_prior(file, F_HL_GNUM(file), &prev_ndx, &flist);
|
||||
if (prev_ndx >= 0) {
|
||||
file = flist->files[prev_ndx - flist->ndx_start];
|
||||
if (file->flags & (FLAG_HLINK_DONE|FLAG_FILE_SENT))
|
||||
return -1;
|
||||
file->flags |= FLAG_HLINK_LAST;
|
||||
*flist_p = flist;
|
||||
}
|
||||
#endif
|
||||
|
||||
return prev_ndx;
|
||||
}
|
||||
#endif
|
||||
|
||||
106
ifuncs.h
Normal file
106
ifuncs.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2007-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
alloc_xbuf(xbuf *xb, size_t sz)
|
||||
{
|
||||
if (!(xb->buf = new_array(char, sz)))
|
||||
out_of_memory("alloc_xbuf");
|
||||
xb->size = sz;
|
||||
xb->len = xb->pos = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
realloc_xbuf(xbuf *xb, size_t sz)
|
||||
{
|
||||
char *bf = realloc_array(xb->buf, char, sz);
|
||||
if (!bf)
|
||||
out_of_memory("realloc_xbuf");
|
||||
xb->buf = bf;
|
||||
xb->size = sz;
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_xbuf(xbuf *xb)
|
||||
{
|
||||
if (xb->buf)
|
||||
free(xb->buf);
|
||||
memset(xb, 0, sizeof (xbuf));
|
||||
}
|
||||
|
||||
static inline int
|
||||
to_wire_mode(mode_t mode)
|
||||
{
|
||||
#ifdef SUPPORT_LINKS
|
||||
#if _S_IFLNK != 0120000
|
||||
if (S_ISLNK(mode))
|
||||
return (mode & ~(_S_IFMT)) | 0120000;
|
||||
#endif
|
||||
#endif
|
||||
return mode;
|
||||
}
|
||||
|
||||
static inline mode_t
|
||||
from_wire_mode(int mode)
|
||||
{
|
||||
#if _S_IFLNK != 0120000
|
||||
if ((mode & (_S_IFMT)) == 0120000)
|
||||
return (mode & ~(_S_IFMT)) | _S_IFLNK;
|
||||
#endif
|
||||
return mode;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
d_name(struct dirent *di)
|
||||
{
|
||||
#ifdef HAVE_BROKEN_READDIR
|
||||
return (di->d_name - 2);
|
||||
#else
|
||||
return di->d_name;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
init_stat_x(stat_x *sx_p)
|
||||
{
|
||||
#ifdef SUPPORT_ACLS
|
||||
sx_p->acc_acl = sx_p->def_acl = NULL;
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
sx_p->xattr = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
free_stat_x(stat_x *sx_p)
|
||||
{
|
||||
#ifdef SUPPORT_ACLS
|
||||
{
|
||||
extern int preserve_acls;
|
||||
if (preserve_acls)
|
||||
free_acl(sx_p);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
{
|
||||
extern int preserve_xattrs;
|
||||
if (preserve_xattrs)
|
||||
free_xattr(sx_p);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
57
inums.h
Normal file
57
inums.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2008-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
static inline char *
|
||||
big_num(int64 num)
|
||||
{
|
||||
return do_big_num(num, 0, NULL);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
comma_num(int64 num)
|
||||
{
|
||||
extern int human_readable;
|
||||
return do_big_num(num, human_readable != 0, NULL);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
human_num(int64 num)
|
||||
{
|
||||
extern int human_readable;
|
||||
return do_big_num(num, human_readable, NULL);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
big_dnum(double dnum, int decimal_digits)
|
||||
{
|
||||
return do_big_dnum(dnum, 0, decimal_digits);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
comma_dnum(double dnum, int decimal_digits)
|
||||
{
|
||||
extern int human_readable;
|
||||
return do_big_dnum(dnum, human_readable != 0, decimal_digits);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
human_dnum(double dnum, int decimal_digits)
|
||||
{
|
||||
extern int human_readable;
|
||||
return do_big_dnum(dnum, human_readable, decimal_digits);
|
||||
}
|
||||
52
io.h
Normal file
52
io.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
extern int protocol_version;
|
||||
|
||||
static inline int32
|
||||
read_varint30(int f)
|
||||
{
|
||||
if (protocol_version < 30)
|
||||
return read_int(f);
|
||||
return read_varint(f);
|
||||
}
|
||||
|
||||
static inline int64
|
||||
read_varlong30(int f, uchar min_bytes)
|
||||
{
|
||||
if (protocol_version < 30)
|
||||
return read_longint(f);
|
||||
return read_varlong(f, min_bytes);
|
||||
}
|
||||
|
||||
static inline void
|
||||
write_varint30(int f, int32 x)
|
||||
{
|
||||
if (protocol_version < 30)
|
||||
write_int(f, x);
|
||||
else
|
||||
write_varint(f, x);
|
||||
}
|
||||
|
||||
static inline void
|
||||
write_varlong30(int f, int64 x, uchar min_bytes)
|
||||
{
|
||||
if (protocol_version < 30)
|
||||
write_longint(f, x);
|
||||
else
|
||||
write_varlong(f, x, min_bytes);
|
||||
}
|
||||
59
itypes.h
Normal file
59
itypes.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Inline functions for rsync.
|
||||
*
|
||||
* Copyright (C) 2007-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
static inline int
|
||||
isDigit(const char *ptr)
|
||||
{
|
||||
return isdigit(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isPrint(const char *ptr)
|
||||
{
|
||||
return isprint(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isSpace(const char *ptr)
|
||||
{
|
||||
return isspace(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isLower(const char *ptr)
|
||||
{
|
||||
return islower(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
isUpper(const char *ptr)
|
||||
{
|
||||
return isupper(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
toLower(const char *ptr)
|
||||
{
|
||||
return tolower(*(unsigned char *)ptr);
|
||||
}
|
||||
|
||||
static inline int
|
||||
toUpper(const char *ptr)
|
||||
{
|
||||
return toupper(*(unsigned char *)ptr);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
.cvsignore
|
||||
Makefile
|
||||
a
|
||||
b
|
||||
config.cache
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
dist.tar.gz
|
||||
dummy
|
||||
rsync
|
||||
rsync-0.1
|
||||
rsync-0.1
|
||||
rsync-0.1
|
||||
rsync-0.1.tar.gz
|
||||
rsync-0.2
|
||||
rsync-0.2
|
||||
rsync-0.2.tar.gz
|
||||
rsync-0.3
|
||||
rsync-0.3
|
||||
rsync-0.3.tar.gz
|
||||
rsync-0.4
|
||||
rsync-0.4
|
||||
rsync-0.4.tar.gz
|
||||
rsync-0.5
|
||||
rsync-0.5
|
||||
rsync-0.5
|
||||
rsync-0.5
|
||||
rsync-0.5
|
||||
rsync-0.5
|
||||
rsync-0.5
|
||||
rsync-0.5
|
||||
rsync-0.5.tar.gz
|
||||
rsync-0.6
|
||||
rsync-0.7
|
||||
rsync-0.7
|
||||
rsync-0.8
|
||||
rsync-0.8
|
||||
rsync-0.8
|
||||
rsync-0.8
|
||||
rsync-ERSION
|
||||
rsync.aux
|
||||
rsync.dvi
|
||||
rsync.log
|
||||
tech_report.aux
|
||||
tech_report.dvi
|
||||
tech_report.log
|
||||
tech_report.ps
|
||||
test
|
||||
180
lib/addrinfo.h
Normal file
180
lib/addrinfo.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
PostgreSQL Database Management System
|
||||
(formerly known as Postgres, then as Postgres95)
|
||||
|
||||
Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group
|
||||
|
||||
Portions Copyright (c) 1994, The Regents of the University of California
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose, without fee, and without a written agreement
|
||||
is hereby granted, provided that the above copyright notice and this paragraph
|
||||
and the following two paragraphs appear in all copies.
|
||||
|
||||
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
|
||||
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
|
||||
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
|
||||
EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS
|
||||
TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* getaddrinfo.h
|
||||
* Support getaddrinfo() on platforms that don't have it.
|
||||
*
|
||||
* Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO,
|
||||
* whether or not the library routine getaddrinfo() can be found. This
|
||||
* policy is needed because on some platforms a manually installed libbind.a
|
||||
* may provide getaddrinfo(), yet the system headers may not provide the
|
||||
* struct definitions needed to call it. To avoid conflict with the libbind
|
||||
* definition in such cases, we rename our routines to pg_xxx() via macros.
|
||||
*
|
||||
* This code will also work on platforms where struct addrinfo is defined
|
||||
* in the system headers but no getaddrinfo() can be located.
|
||||
*
|
||||
* Copyright (c) 2003-2007, PostgreSQL Global Development Group
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ADDRINFO_H
|
||||
#define ADDRINFO_H
|
||||
|
||||
|
||||
/* Various macros that ought to be in <netdb.h>, but might not be */
|
||||
|
||||
#ifndef EAI_FAIL
|
||||
#define EAI_BADFLAGS (-1)
|
||||
#define EAI_NONAME (-2)
|
||||
#define EAI_AGAIN (-3)
|
||||
#define EAI_FAIL (-4)
|
||||
#define EAI_FAMILY (-6)
|
||||
#define EAI_SOCKTYPE (-7)
|
||||
#define EAI_SERVICE (-8)
|
||||
#define EAI_MEMORY (-10)
|
||||
#define EAI_SYSTEM (-11)
|
||||
#endif /* !EAI_FAIL */
|
||||
|
||||
#ifndef AI_PASSIVE
|
||||
#define AI_PASSIVE 0x0001
|
||||
#endif
|
||||
|
||||
#ifndef AI_NUMERICHOST
|
||||
/*
|
||||
* some platforms don't support AI_NUMERICHOST; define as zero if using
|
||||
* the system version of getaddrinfo...
|
||||
*/
|
||||
#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
|
||||
#define AI_NUMERICHOST 0
|
||||
#else
|
||||
#define AI_NUMERICHOST 0x0004
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AI_CANONNAME
|
||||
#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
|
||||
#define AI_CANONNAME 0
|
||||
#else
|
||||
#define AI_CANONNAME 0x0008
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AI_NUMERICSERV
|
||||
#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
|
||||
#define AI_NUMERICSERV 0
|
||||
#else
|
||||
#define AI_NUMERICSERV 0x0010
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NI_NUMERICHOST
|
||||
#define NI_NUMERICHOST 1
|
||||
#endif
|
||||
|
||||
#ifndef NI_NUMERICSERV
|
||||
#define NI_NUMERICSERV 2
|
||||
#endif
|
||||
|
||||
#ifndef NI_NOFQDN
|
||||
#define NI_NOFQDN 4
|
||||
#endif
|
||||
|
||||
#ifndef NI_NAMEREQD
|
||||
#define NI_NAMEREQD 8
|
||||
#endif
|
||||
|
||||
#ifndef NI_DGRAM
|
||||
#define NI_DGRAM 16
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
#endif
|
||||
|
||||
#ifndef NI_MAXSERV
|
||||
#define NI_MAXSERV 32
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ADDRINFO
|
||||
struct addrinfo
|
||||
{
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
size_t ai_addrlen;
|
||||
struct sockaddr *ai_addr;
|
||||
char *ai_canonname;
|
||||
struct addrinfo *ai_next;
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_ADDRINFO */
|
||||
|
||||
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
struct sockaddr_storage {
|
||||
unsigned short ss_family;
|
||||
unsigned long ss_align;
|
||||
char ss_padding[128 - sizeof (unsigned long)];
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
|
||||
/* Rename private copies per comments above */
|
||||
#ifdef getaddrinfo
|
||||
#undef getaddrinfo
|
||||
#endif
|
||||
#define getaddrinfo pg_getaddrinfo
|
||||
|
||||
#ifdef freeaddrinfo
|
||||
#undef freeaddrinfo
|
||||
#endif
|
||||
#define freeaddrinfo pg_freeaddrinfo
|
||||
|
||||
#ifdef gai_strerror
|
||||
#undef gai_strerror
|
||||
#endif
|
||||
#define gai_strerror pg_gai_strerror
|
||||
|
||||
#ifdef getnameinfo
|
||||
#undef getnameinfo
|
||||
#endif
|
||||
#define getnameinfo pg_getnameinfo
|
||||
|
||||
extern int getaddrinfo(const char *node, const char *service,
|
||||
const struct addrinfo * hints, struct addrinfo ** res);
|
||||
extern void freeaddrinfo(struct addrinfo * res);
|
||||
extern const char *gai_strerror(int errcode);
|
||||
extern int getnameinfo(const struct sockaddr * sa, socklen_t salen,
|
||||
char *node, size_t nodelen,
|
||||
char *service, size_t servicelen, int flags);
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
|
||||
#endif /* ADDRINFO_H */
|
||||
244
lib/compat.c
244
lib/compat.c
@@ -1,42 +1,37 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file compat.c
|
||||
/*
|
||||
* Reimplementations of standard functions for platforms that don't have them.
|
||||
*
|
||||
* Reimplementations of standard functions for platforms that don't
|
||||
* have them.
|
||||
**/
|
||||
|
||||
|
||||
* Copyright (C) 1998 Andrew Tridgell
|
||||
* Copyright (C) 2002 Martin Pool
|
||||
* Copyright (C) 2004-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "itypes.h"
|
||||
|
||||
static char number_separator;
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
char *strdup(char *s)
|
||||
{
|
||||
int l = strlen(s) + 1;
|
||||
char *ret = (char *)malloc(l);
|
||||
if (ret)
|
||||
strcpy(ret,s);
|
||||
return ret;
|
||||
int len = strlen(s) + 1;
|
||||
char *ret = (char *)malloc(len);
|
||||
if (ret)
|
||||
memcpy(ret, s, len);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -86,7 +81,7 @@
|
||||
/**
|
||||
* Find the first ocurrence in @p s of any character in @p accept.
|
||||
*
|
||||
* Derived from glibc
|
||||
* Derived from glibc
|
||||
**/
|
||||
char *strpbrk(const char *s, const char *accept)
|
||||
{
|
||||
@@ -105,7 +100,7 @@
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/**
|
||||
* Like strncpy but does not 0 fill the buffer and always null
|
||||
* Like strncpy but does not 0 fill the buffer and always null
|
||||
* terminates.
|
||||
*
|
||||
* @param bufsize is the size of the destination buffer.
|
||||
@@ -116,17 +111,19 @@
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
size_t ret = len;
|
||||
if (bufsize <= 0) return 0;
|
||||
if (len >= bufsize) len = bufsize-1;
|
||||
memcpy(d, s, len);
|
||||
d[len] = 0;
|
||||
if (bufsize > 0) {
|
||||
if (len >= bufsize)
|
||||
len = bufsize-1;
|
||||
memcpy(d, s, len);
|
||||
d[len] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/**
|
||||
* Like strncat() but does not 0 fill the buffer and always null
|
||||
* Like strncat() but does not 0 fill the buffer and always null
|
||||
* terminates.
|
||||
*
|
||||
* @param bufsize length of the buffer, which should be one more than
|
||||
@@ -138,10 +135,9 @@
|
||||
size_t len2 = strlen(s);
|
||||
size_t ret = len1 + len2;
|
||||
|
||||
if (len1+len2 >= bufsize) {
|
||||
len2 = bufsize - (len1+1);
|
||||
}
|
||||
if (len2 > 0) {
|
||||
if (len1 < bufsize - 1) {
|
||||
if (len2 >= bufsize - len1)
|
||||
len2 = bufsize - len1 - 1;
|
||||
memcpy(d+len1, s, len2);
|
||||
d[len1+len2] = 0;
|
||||
}
|
||||
@@ -149,55 +145,131 @@
|
||||
}
|
||||
#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];
|
||||
#if 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)
|
||||
{
|
||||
#if HAVE_GETTIMEOFDAY_TZ
|
||||
#ifdef HAVE_GETTIMEOFDAY_TZ
|
||||
return gettimeofday(tv, NULL);
|
||||
#else
|
||||
return gettimeofday(tv);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define HUMANIFY(mult) \
|
||||
do { \
|
||||
if (num >= mult || num <= -mult) { \
|
||||
double dnum = (double)num / mult; \
|
||||
char units; \
|
||||
if (num < 0) \
|
||||
dnum = -dnum; \
|
||||
if (dnum < mult) \
|
||||
units = 'K'; \
|
||||
else if ((dnum /= mult) < mult) \
|
||||
units = 'M'; \
|
||||
else if ((dnum /= mult) < mult) \
|
||||
units = 'G'; \
|
||||
else { \
|
||||
dnum /= mult; \
|
||||
units = 'T'; \
|
||||
} \
|
||||
if (num < 0) \
|
||||
dnum = -dnum; \
|
||||
snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units); \
|
||||
return bufs[n]; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Return the int64 number as a string. If the human_flag arg is non-zero,
|
||||
* we may output the number in K, M, G, or T units. If we don't add a unit
|
||||
* suffix, we will append the fract string, if it is non-NULL. We can
|
||||
* return up to 4 buffers at a time. */
|
||||
char *do_big_num(int64 num, int human_flag, const char *fract)
|
||||
{
|
||||
static char bufs[4][128]; /* more than enough room */
|
||||
static unsigned int n;
|
||||
char *s;
|
||||
int len, negated;
|
||||
|
||||
if (human_flag && !number_separator) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof buf, "%f", 3.14);
|
||||
if (strchr(buf, '.') != NULL)
|
||||
number_separator = ',';
|
||||
else
|
||||
number_separator = '.';
|
||||
}
|
||||
|
||||
n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
|
||||
|
||||
if (human_flag > 1) {
|
||||
if (human_flag == 2)
|
||||
HUMANIFY(1000);
|
||||
else
|
||||
HUMANIFY(1024);
|
||||
}
|
||||
|
||||
s = bufs[n] + sizeof bufs[0] - 1;
|
||||
if (fract) {
|
||||
len = strlen(fract);
|
||||
s -= len;
|
||||
strlcpy(s, fract, len + 1);
|
||||
} else
|
||||
*s = '\0';
|
||||
|
||||
len = 0;
|
||||
|
||||
if (!num)
|
||||
*--s = '0';
|
||||
if (num < 0) {
|
||||
/* A maximum-size negated number can't fit as a positive,
|
||||
* so do one digit in negated form to start us off. */
|
||||
*--s = (char)(-(num % 10)) + '0';
|
||||
num = -(num / 10);
|
||||
len++;
|
||||
negated = 1;
|
||||
} else
|
||||
negated = 0;
|
||||
|
||||
while (num) {
|
||||
if (human_flag) {
|
||||
if (len == 3) {
|
||||
*--s = number_separator;
|
||||
len = 1;
|
||||
} else
|
||||
len++;
|
||||
}
|
||||
*--s = (char)(num % 10) + '0';
|
||||
num /= 10;
|
||||
}
|
||||
|
||||
if (negated)
|
||||
*--s = '-';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return the double number as a string. If the human_flag option is > 1,
|
||||
* we may output the number in K, M, G, or T units. The buffer we use for
|
||||
* our result is either a single static buffer defined here, or a buffer
|
||||
* we get from do_big_num(). */
|
||||
char *do_big_dnum(double dnum, int human_flag, int decimal_digits)
|
||||
{
|
||||
static char tmp_buf[128];
|
||||
#if SIZEOF_INT64 >= 8
|
||||
char *fract;
|
||||
|
||||
snprintf(tmp_buf, sizeof tmp_buf, "%.*f", decimal_digits, dnum);
|
||||
|
||||
if (!human_flag || (dnum < 1000.0 && dnum > -1000.0))
|
||||
return tmp_buf;
|
||||
|
||||
for (fract = tmp_buf+1; isDigit(fract); fract++) {}
|
||||
|
||||
return do_big_num((int64)dnum, human_flag, fract);
|
||||
#else
|
||||
/* A big number might lose digits converting to a too-short int64,
|
||||
* so let's just return the raw double conversion. */
|
||||
snprintf(tmp_buf, sizeof tmp_buf, "%.*f", decimal_digits, dnum);
|
||||
return tmp_buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
482
lib/fnmatch.c
482
lib/fnmatch.c
@@ -1,482 +0,0 @@
|
||||
#include "../rsync.h"
|
||||
#ifndef HAVE_FNMATCH
|
||||
|
||||
/* ----- THE FOLLOWING UP TO 'END' is glibc-2.1.2 posix/fnmatch.c
|
||||
except for the parts with '#if 0' */
|
||||
|
||||
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if 0 /* header files included better by ../rsync.h */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* Enable GNU extensions in fnmatch.h. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if HAVE_STRING_H || defined _LIBC
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if defined STDC_HEADERS || defined _LIBC
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#endif /* 0 */
|
||||
/* For platform which support the ISO C amendement 1 functionality we
|
||||
support user defined character classes. */
|
||||
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
|
||||
# include <wchar.h>
|
||||
# include <wctype.h>
|
||||
#endif
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if 1
|
||||
|
||||
# if defined STDC_HEADERS || !defined isascii
|
||||
# define ISASCII(c) 1
|
||||
# else
|
||||
# define ISASCII(c) isascii(c)
|
||||
# endif
|
||||
|
||||
#ifdef isblank
|
||||
# define ISBLANK(c) (ISASCII (c) && isblank (c))
|
||||
#else
|
||||
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
|
||||
#endif
|
||||
#ifdef isgraph
|
||||
# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
|
||||
#else
|
||||
# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
|
||||
#endif
|
||||
|
||||
#define ISPRINT(c) (ISASCII (c) && isprint (c))
|
||||
#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
|
||||
#define ISALNUM(c) (ISASCII (c) && isalnum (c))
|
||||
#define ISALPHA(c) (ISASCII (c) && isalpha (c))
|
||||
#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
|
||||
#define ISLOWER(c) (ISASCII (c) && islower (c))
|
||||
#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
|
||||
#define ISSPACE(c) (ISASCII (c) && isspace (c))
|
||||
#define ISUPPER(c) (ISASCII (c) && isupper (c))
|
||||
#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
|
||||
|
||||
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* The GNU C library provides support for user-defined character classes
|
||||
and the functions from ISO C amendement 1. */
|
||||
# ifdef CHARCLASS_NAME_MAX
|
||||
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
|
||||
# else
|
||||
/* This shouldn't happen but some implementation might still have this
|
||||
problem. Use a reasonable default value. */
|
||||
# define CHAR_CLASS_MAX_LENGTH 256
|
||||
# endif
|
||||
|
||||
# ifdef _LIBC
|
||||
# define IS_CHAR_CLASS(string) __wctype (string)
|
||||
# else
|
||||
# define IS_CHAR_CLASS(string) wctype (string)
|
||||
# endif
|
||||
# else
|
||||
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
|
||||
|
||||
# define IS_CHAR_CLASS(string) \
|
||||
(STREQ (string, "alpha") || STREQ (string, "upper") \
|
||||
|| STREQ (string, "lower") || STREQ (string, "digit") \
|
||||
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|
||||
|| STREQ (string, "space") || STREQ (string, "print") \
|
||||
|| STREQ (string, "punct") || STREQ (string, "graph") \
|
||||
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
|
||||
# endif
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
# if !defined _LIBC && !defined getenv
|
||||
extern char *getenv ();
|
||||
# endif
|
||||
|
||||
# ifndef errno
|
||||
extern int errno;
|
||||
# endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
static int
|
||||
#ifdef _LIBC
|
||||
internal_function
|
||||
#endif
|
||||
internal_fnmatch (const char *pattern, const char *string,
|
||||
int no_leading_period, int flags)
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register unsigned char c;
|
||||
|
||||
/* Note that this evaluates C many times. */
|
||||
# ifdef _LIBC
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
|
||||
# else
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
|
||||
# endif
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
{
|
||||
c = *p++;
|
||||
if (c == '\0')
|
||||
/* Trailing \ loses. */
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD ((unsigned char) *n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++)
|
||||
{
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* A slash does not match a wildcard under FNM_FILE_NAME. */
|
||||
return FNM_NOMATCH;
|
||||
else if (c == '?')
|
||||
{
|
||||
/* A ? needs to match one character. */
|
||||
if (*n == '\0')
|
||||
/* There isn't another character; no match. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
/* One character of the string is consumed in matching
|
||||
this ? wildcard, so *??? won't match if there are
|
||||
less than three characters. */
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\0')
|
||||
/* The wildcard(s) is/are the last element of the pattern.
|
||||
If the name is a file name and contains another slash
|
||||
this does mean it cannot match. */
|
||||
return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
|
||||
? FNM_NOMATCH : 0);
|
||||
else
|
||||
{
|
||||
const char *endp;
|
||||
|
||||
#if 0
|
||||
endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
|
||||
#else
|
||||
/* replace call to internal glibc function with equivalent */
|
||||
if (!(flags & FNM_FILE_NAME) || ((endp = strchr(n, '/')) == NULL))
|
||||
endp = n + strlen(n);
|
||||
#endif
|
||||
|
||||
if (c == '[')
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
for (--p; n < endp; ++n)
|
||||
if (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2)
|
||||
== 0)
|
||||
return 0;
|
||||
}
|
||||
else if (c == '/' && (flags & FNM_FILE_NAME))
|
||||
{
|
||||
while (*n != '\0' && *n != '/')
|
||||
++n;
|
||||
if (*n == '/'
|
||||
&& (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
|
||||
flags) == 0))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
if (c == '\\' && !(flags & FNM_NOESCAPE))
|
||||
c = *p;
|
||||
c = FOLD (c);
|
||||
for (--p; n < endp; ++n)
|
||||
if (FOLD ((unsigned char) *n) == c
|
||||
&& (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2) == 0))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we come here no match is possible with the wildcard. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
case '[':
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
static int posixly_correct;
|
||||
register int not;
|
||||
char cold;
|
||||
|
||||
if (posixly_correct == 0)
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
|
||||
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '.' && no_leading_period && (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* `/' cannot be matched. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
|
||||
if (not)
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
unsigned char fn = FOLD ((unsigned char) *n);
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD ((unsigned char) *p);
|
||||
++p;
|
||||
|
||||
if (c == fn)
|
||||
goto matched;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
/* Leave room for the null. */
|
||||
char str[CHAR_CLASS_MAX_LENGTH + 1];
|
||||
size_t c1 = 0;
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wctype_t wt;
|
||||
# endif
|
||||
const char *startp = p;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (c1 == CHAR_CLASS_MAX_LENGTH)
|
||||
/* The name is too long and therefore the pattern
|
||||
is ill-formed. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *++p;
|
||||
if (c == ':' && p[1] == ']')
|
||||
{
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
if (c < 'a' || c >= 'z')
|
||||
{
|
||||
/* This cannot possibly be a character class name.
|
||||
Match it as a normal range. */
|
||||
p = startp;
|
||||
c = '[';
|
||||
goto normal_bracket;
|
||||
}
|
||||
str[c1++] = c;
|
||||
}
|
||||
str[c1] = '\0';
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wt = IS_CHAR_CLASS (str);
|
||||
if (wt == 0)
|
||||
/* Invalid character class name. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (__iswctype (__btowc ((unsigned char) *n), wt))
|
||||
goto matched;
|
||||
# else
|
||||
if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
|
||||
|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
|
||||
|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
|
||||
|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
|
||||
|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
|
||||
|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
|
||||
|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
|
||||
|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
|
||||
|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
|
||||
|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
|
||||
|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
|
||||
|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
|
||||
goto matched;
|
||||
# endif
|
||||
}
|
||||
else if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
{
|
||||
normal_bracket:
|
||||
if (FOLD (c) == fn)
|
||||
goto matched;
|
||||
|
||||
cold = c;
|
||||
c = *p++;
|
||||
|
||||
if (c == '-' && *p != ']')
|
||||
{
|
||||
/* It is a range. */
|
||||
unsigned char cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (cold <= fn && fn <= FOLD (cend))
|
||||
goto matched;
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == ']')
|
||||
break;
|
||||
}
|
||||
|
||||
if (!not)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
matched:
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
while (c != ']')
|
||||
{
|
||||
if (c == '\0')
|
||||
/* [... (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
do
|
||||
if (*++p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
while (*p != ':' || p[1] == ']');
|
||||
p += 2;
|
||||
c = *p;
|
||||
}
|
||||
}
|
||||
if (not)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != FOLD ((unsigned char) *n))
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (*n == '\0')
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == '/')
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return FNM_NOMATCH;
|
||||
|
||||
# undef FOLD
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fnmatch (pattern, string, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int flags;
|
||||
{
|
||||
return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
/* ----- END glibc-2.1.2 posix/fnmatch.c */
|
||||
|
||||
#else /* HAVE_FNMATCH */
|
||||
void fnmatch_dummy(void) {}
|
||||
#endif
|
||||
@@ -1,88 +0,0 @@
|
||||
/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _FNMATCH_H
|
||||
#define _FNMATCH_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
|
||||
# if !defined __GLIBC__ || !defined __P
|
||||
# undef __P
|
||||
# define __P(protos) protos
|
||||
# endif
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# undef __P
|
||||
# define __P(protos) ()
|
||||
/* We can get away without defining `const' here only because in this file
|
||||
it is used only inside the prototype for `fnmatch', which is elided in
|
||||
non-ANSI C where `const' is problematical. */
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#ifndef const
|
||||
# if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||
# define __const const
|
||||
# else
|
||||
# define __const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* We #undef these before defining them because some losing systems
|
||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
||||
#undef FNM_PATHNAME
|
||||
#undef FNM_NOESCAPE
|
||||
#undef FNM_PERIOD
|
||||
|
||||
/* Bits set in the FLAGS argument to `fnmatch'. */
|
||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
||||
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
||||
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
||||
|
||||
#ifndef FNM_FILE_NAME
|
||||
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
||||
#endif
|
||||
#ifndef FNM_LEADING_DIR
|
||||
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
||||
#endif
|
||||
#ifndef FNM_CASEFOLD
|
||||
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#endif
|
||||
|
||||
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
/* This value is returned if the implementation does not support
|
||||
`fnmatch'. Since this is not the case here it will never be
|
||||
returned but the conformance test suites still require the symbol
|
||||
to be defined. */
|
||||
#ifdef _XOPEN_SOURCE
|
||||
# define FNM_NOSYS (-1)
|
||||
#endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN,
|
||||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int fnmatch __P ((__const char *__pattern, __const char *__string,
|
||||
int __flags));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* fnmatch.h */
|
||||
504
lib/getaddrinfo.c
Normal file
504
lib/getaddrinfo.c
Normal file
@@ -0,0 +1,504 @@
|
||||
/*
|
||||
PostgreSQL Database Management System
|
||||
(formerly known as Postgres, then as Postgres95)
|
||||
|
||||
Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group
|
||||
|
||||
Portions Copyright (c) 1994, The Regents of the University of California
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose, without fee, and without a written agreement
|
||||
is hereby granted, provided that the above copyright notice and this paragraph
|
||||
and the following two paragraphs appear in all copies.
|
||||
|
||||
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
|
||||
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
|
||||
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
|
||||
EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS
|
||||
TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* getaddrinfo.c
|
||||
* Support getaddrinfo() on platforms that don't have it.
|
||||
*
|
||||
* We also supply getnameinfo() here, assuming that the platform will have
|
||||
* it if and only if it has getaddrinfo(). If this proves false on some
|
||||
* platform, we'll need to split this file and provide a separate configure
|
||||
* test for getnameinfo().
|
||||
*
|
||||
* Copyright (c) 2003-2007, PostgreSQL Global Development Group
|
||||
*
|
||||
* Copyright (C) 2007 Jeremy Allison.
|
||||
* Modified to return multiple IPv4 addresses for Samba.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#ifndef SMB_MALLOC
|
||||
#define SMB_MALLOC(s) malloc(s)
|
||||
#endif
|
||||
|
||||
#ifndef SMB_STRDUP
|
||||
#define SMB_STRDUP(s) strdup(s)
|
||||
#endif
|
||||
|
||||
#ifndef HOST_NAME_MAX
|
||||
#define HOST_NAME_MAX 255
|
||||
#endif
|
||||
|
||||
static int check_hostent_err(struct hostent *hp)
|
||||
{
|
||||
#ifndef INET6
|
||||
extern int h_errno;
|
||||
#endif
|
||||
if (!hp) {
|
||||
switch (h_errno) {
|
||||
case HOST_NOT_FOUND:
|
||||
case NO_DATA:
|
||||
return EAI_NONAME;
|
||||
case TRY_AGAIN:
|
||||
return EAI_AGAIN;
|
||||
case NO_RECOVERY:
|
||||
default:
|
||||
return EAI_FAIL;
|
||||
}
|
||||
}
|
||||
if (!hp->h_name || hp->h_addrtype != AF_INET) {
|
||||
return EAI_FAIL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *canon_name_from_hostent(struct hostent *hp,
|
||||
int *perr)
|
||||
{
|
||||
char *ret = NULL;
|
||||
|
||||
*perr = check_hostent_err(hp);
|
||||
if (*perr) {
|
||||
return NULL;
|
||||
}
|
||||
ret = SMB_STRDUP(hp->h_name);
|
||||
if (!ret) {
|
||||
*perr = EAI_MEMORY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *get_my_canon_name(int *perr)
|
||||
{
|
||||
char name[HOST_NAME_MAX+1];
|
||||
|
||||
if (gethostname(name, HOST_NAME_MAX) == -1) {
|
||||
*perr = EAI_FAIL;
|
||||
return NULL;
|
||||
}
|
||||
/* Ensure null termination. */
|
||||
name[HOST_NAME_MAX] = '\0';
|
||||
return canon_name_from_hostent(gethostbyname(name), perr);
|
||||
}
|
||||
|
||||
static char *get_canon_name_from_addr(struct in_addr ip,
|
||||
int *perr)
|
||||
{
|
||||
return canon_name_from_hostent(
|
||||
gethostbyaddr((void *)&ip, sizeof ip, AF_INET),
|
||||
perr);
|
||||
}
|
||||
|
||||
static struct addrinfo *alloc_entry(const struct addrinfo *hints,
|
||||
struct in_addr ip,
|
||||
unsigned short port)
|
||||
{
|
||||
struct sockaddr_in *psin = NULL;
|
||||
struct addrinfo *ai = SMB_MALLOC(sizeof(*ai));
|
||||
|
||||
if (!ai) {
|
||||
return NULL;
|
||||
}
|
||||
memset(ai, '\0', sizeof(*ai));
|
||||
|
||||
psin = SMB_MALLOC(sizeof(*psin));
|
||||
if (!psin) {
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(psin, '\0', sizeof(*psin));
|
||||
|
||||
psin->sin_family = AF_INET;
|
||||
psin->sin_port = htons(port);
|
||||
psin->sin_addr = ip;
|
||||
|
||||
ai->ai_flags = 0;
|
||||
ai->ai_family = AF_INET;
|
||||
ai->ai_socktype = hints->ai_socktype;
|
||||
ai->ai_protocol = hints->ai_protocol;
|
||||
ai->ai_addrlen = sizeof(*psin);
|
||||
ai->ai_addr = (struct sockaddr *) psin;
|
||||
ai->ai_canonname = NULL;
|
||||
ai->ai_next = NULL;
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
/*
|
||||
* get address info for a single ipv4 address.
|
||||
*
|
||||
* Bugs: - servname can only be a number, not text.
|
||||
*/
|
||||
|
||||
static int getaddr_info_single_addr(const char *service,
|
||||
uint32 addr,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
|
||||
struct addrinfo *ai = NULL;
|
||||
struct in_addr ip;
|
||||
unsigned short port = 0;
|
||||
|
||||
if (service) {
|
||||
port = (unsigned short)atoi(service);
|
||||
}
|
||||
ip.s_addr = htonl(addr);
|
||||
|
||||
ai = alloc_entry(hints, ip, port);
|
||||
if (!ai) {
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
/* If we're asked for the canonical name,
|
||||
* make sure it returns correctly. */
|
||||
if (!(hints->ai_flags & AI_NUMERICSERV) &&
|
||||
hints->ai_flags & AI_CANONNAME) {
|
||||
int err;
|
||||
if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) {
|
||||
ai->ai_canonname = get_my_canon_name(&err);
|
||||
} else {
|
||||
ai->ai_canonname =
|
||||
get_canon_name_from_addr(ip,&err);
|
||||
}
|
||||
if (ai->ai_canonname == NULL) {
|
||||
freeaddrinfo(ai);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
*res = ai;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get address info for multiple ipv4 addresses.
|
||||
*
|
||||
* Bugs: - servname can only be a number, not text.
|
||||
*/
|
||||
|
||||
static int getaddr_info_name(const char *node,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
struct addrinfo *listp = NULL, *prevp = NULL;
|
||||
char **pptr = NULL;
|
||||
int err;
|
||||
struct hostent *hp = NULL;
|
||||
unsigned short port = 0;
|
||||
|
||||
if (service) {
|
||||
port = (unsigned short)atoi(service);
|
||||
}
|
||||
|
||||
hp = gethostbyname(node);
|
||||
err = check_hostent_err(hp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
for(pptr = hp->h_addr_list; *pptr; pptr++) {
|
||||
struct in_addr ip = *(struct in_addr *)*pptr;
|
||||
struct addrinfo *ai = alloc_entry(hints, ip, port);
|
||||
|
||||
if (!ai) {
|
||||
freeaddrinfo(listp);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
if (!listp) {
|
||||
listp = ai;
|
||||
prevp = ai;
|
||||
ai->ai_canonname = SMB_STRDUP(hp->h_name);
|
||||
if (!ai->ai_canonname) {
|
||||
freeaddrinfo(listp);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
} else {
|
||||
prevp->ai_next = ai;
|
||||
prevp = ai;
|
||||
}
|
||||
}
|
||||
*res = listp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get address info for ipv4 sockets.
|
||||
*
|
||||
* Bugs: - servname can only be a number, not text.
|
||||
*/
|
||||
|
||||
int getaddrinfo(const char *node,
|
||||
const char *service,
|
||||
const struct addrinfo * hintp,
|
||||
struct addrinfo ** res)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
|
||||
/* Setup the hints struct. */
|
||||
if (hintp == NULL) {
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
} else {
|
||||
memcpy(&hints, hintp, sizeof(hints));
|
||||
}
|
||||
|
||||
if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) {
|
||||
return EAI_FAMILY;
|
||||
}
|
||||
|
||||
if (hints.ai_socktype == 0) {
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
}
|
||||
|
||||
if (!node && !service) {
|
||||
return EAI_NONAME;
|
||||
}
|
||||
|
||||
if (node) {
|
||||
if (node[0] == '\0') {
|
||||
return getaddr_info_single_addr(service,
|
||||
INADDR_ANY,
|
||||
&hints,
|
||||
res);
|
||||
} else if (hints.ai_flags & AI_NUMERICHOST) {
|
||||
struct in_addr ip;
|
||||
if (inet_pton(AF_INET, node, &ip) <= 0)
|
||||
return EAI_FAIL;
|
||||
return getaddr_info_single_addr(service,
|
||||
ntohl(ip.s_addr),
|
||||
&hints,
|
||||
res);
|
||||
} else {
|
||||
return getaddr_info_name(node,
|
||||
service,
|
||||
&hints,
|
||||
res);
|
||||
}
|
||||
} else if (hints.ai_flags & AI_PASSIVE) {
|
||||
return getaddr_info_single_addr(service,
|
||||
INADDR_ANY,
|
||||
&hints,
|
||||
res);
|
||||
}
|
||||
return getaddr_info_single_addr(service,
|
||||
INADDR_LOOPBACK,
|
||||
&hints,
|
||||
res);
|
||||
}
|
||||
|
||||
|
||||
void freeaddrinfo(struct addrinfo *res)
|
||||
{
|
||||
struct addrinfo *next = NULL;
|
||||
|
||||
for (;res; res = next) {
|
||||
next = res->ai_next;
|
||||
if (res->ai_canonname) {
|
||||
free(res->ai_canonname);
|
||||
}
|
||||
if (res->ai_addr) {
|
||||
free(res->ai_addr);
|
||||
}
|
||||
free(res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *gai_strerror(int errcode)
|
||||
{
|
||||
#ifdef HAVE_HSTRERROR
|
||||
int hcode;
|
||||
|
||||
switch (errcode)
|
||||
{
|
||||
case EAI_NONAME:
|
||||
hcode = HOST_NOT_FOUND;
|
||||
break;
|
||||
case EAI_AGAIN:
|
||||
hcode = TRY_AGAIN;
|
||||
break;
|
||||
case EAI_FAIL:
|
||||
default:
|
||||
hcode = NO_RECOVERY;
|
||||
break;
|
||||
}
|
||||
|
||||
return hstrerror(hcode);
|
||||
#else /* !HAVE_HSTRERROR */
|
||||
|
||||
switch (errcode)
|
||||
{
|
||||
case EAI_NONAME:
|
||||
return "Unknown host";
|
||||
case EAI_AGAIN:
|
||||
return "Host name lookup failure";
|
||||
#ifdef EAI_BADFLAGS
|
||||
case EAI_BADFLAGS:
|
||||
return "Invalid argument";
|
||||
#endif
|
||||
#ifdef EAI_FAMILY
|
||||
case EAI_FAMILY:
|
||||
return "Address family not supported";
|
||||
#endif
|
||||
#ifdef EAI_MEMORY
|
||||
case EAI_MEMORY:
|
||||
return "Not enough memory";
|
||||
#endif
|
||||
#ifdef EAI_NODATA
|
||||
case EAI_NODATA:
|
||||
return "No host data of that type was found";
|
||||
#endif
|
||||
#ifdef EAI_SERVICE
|
||||
case EAI_SERVICE:
|
||||
return "Class type not found";
|
||||
#endif
|
||||
#ifdef EAI_SOCKTYPE
|
||||
case EAI_SOCKTYPE:
|
||||
return "Socket type not supported";
|
||||
#endif
|
||||
default:
|
||||
return "Unknown server error";
|
||||
}
|
||||
#endif /* HAVE_HSTRERROR */
|
||||
}
|
||||
|
||||
static int gethostnameinfo(const struct sockaddr *sa,
|
||||
char *node,
|
||||
size_t nodelen,
|
||||
int flags)
|
||||
{
|
||||
int ret = -1;
|
||||
char *p = NULL;
|
||||
|
||||
if (!(flags & NI_NUMERICHOST)) {
|
||||
struct hostent *hp = gethostbyaddr(
|
||||
(void *)&((struct sockaddr_in *)sa)->sin_addr,
|
||||
sizeof (struct in_addr),
|
||||
sa->sa_family);
|
||||
ret = check_hostent_err(hp);
|
||||
if (ret == 0) {
|
||||
/* Name looked up successfully. */
|
||||
ret = snprintf(node, nodelen, "%s", hp->h_name);
|
||||
if (ret < 0 || (size_t)ret >= nodelen) {
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
if (flags & NI_NOFQDN) {
|
||||
p = strchr(node,'.');
|
||||
if (p) {
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flags & NI_NAMEREQD) {
|
||||
/* If we require a name and didn't get one,
|
||||
* automatically fail. */
|
||||
return ret;
|
||||
}
|
||||
/* Otherwise just fall into the numeric host code... */
|
||||
}
|
||||
p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);
|
||||
ret = snprintf(node, nodelen, "%s", p);
|
||||
if (ret < 0 || (size_t)ret >= nodelen) {
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getservicenameinfo(const struct sockaddr *sa,
|
||||
char *service,
|
||||
size_t servicelen,
|
||||
int flags)
|
||||
{
|
||||
int ret = -1;
|
||||
int port = ntohs(((struct sockaddr_in *)sa)->sin_port);
|
||||
|
||||
if (!(flags & NI_NUMERICSERV)) {
|
||||
struct servent *se = getservbyport(
|
||||
port,
|
||||
(flags & NI_DGRAM) ? "udp" : "tcp");
|
||||
if (se && se->s_name) {
|
||||
/* Service name looked up successfully. */
|
||||
ret = snprintf(service, servicelen, "%s", se->s_name);
|
||||
if (ret < 0 || (size_t)ret >= servicelen) {
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* Otherwise just fall into the numeric service code... */
|
||||
}
|
||||
ret = snprintf(service, servicelen, "%d", port);
|
||||
if (ret < 0 || (size_t)ret >= servicelen) {
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an ipv4 address to a hostname.
|
||||
*
|
||||
* Bugs: - No IPv6 support.
|
||||
*/
|
||||
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
||||
char *node, size_t nodelen,
|
||||
char *service, size_t servicelen, int flags)
|
||||
{
|
||||
|
||||
/* Invalid arguments. */
|
||||
if (sa == NULL || (node == NULL && service == NULL)) {
|
||||
return EAI_FAIL;
|
||||
}
|
||||
|
||||
if (sa->sa_family != AF_INET) {
|
||||
return EAI_FAIL;
|
||||
}
|
||||
|
||||
if (salen < (socklen_t)sizeof (struct sockaddr_in)) {
|
||||
return EAI_FAIL;
|
||||
}
|
||||
|
||||
if (node) {
|
||||
int ret = gethostnameinfo(sa, node, nodelen, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (service) {
|
||||
return getservicenameinfo(sa, service, servicelen, flags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
72
lib/getpass.c
Normal file
72
lib/getpass.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* An implementation of getpass for systems that lack one.
|
||||
*
|
||||
* Copyright (C) 2013 Roman Donchenko
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
char *getpass(const char *prompt)
|
||||
{
|
||||
static char password[256];
|
||||
|
||||
BOOL tty_changed = False, read_success;
|
||||
struct termios tty_old, tty_new;
|
||||
FILE *in = stdin, *out = stderr;
|
||||
FILE *tty = fopen("/dev/tty", "w+");
|
||||
|
||||
if (tty)
|
||||
in = out = tty;
|
||||
|
||||
if (tcgetattr(fileno(in), &tty_old) == 0) {
|
||||
tty_new = tty_old;
|
||||
tty_new.c_lflag &= ~(ECHO | ISIG);
|
||||
|
||||
if (tcsetattr(fileno(in), TCSAFLUSH, &tty_new) == 0)
|
||||
tty_changed = True;
|
||||
}
|
||||
|
||||
if (!tty_changed)
|
||||
fputs("(WARNING: will be visible) ", out);
|
||||
fputs(prompt, out);
|
||||
fflush(out);
|
||||
|
||||
read_success = fgets(password, sizeof password, in) != NULL;
|
||||
|
||||
/* Print the newline that hasn't been echoed. */
|
||||
fputc('\n', out);
|
||||
|
||||
if (tty_changed)
|
||||
tcsetattr(fileno(in), TCSAFLUSH, &tty_old);
|
||||
|
||||
if (tty)
|
||||
fclose(tty);
|
||||
|
||||
if (read_success) {
|
||||
/* Remove the trailing newline. */
|
||||
size_t password_len = strlen(password);
|
||||
if (password_len && password[password_len - 1] == '\n')
|
||||
password[password_len - 1] = '\0';
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -75,13 +75,14 @@ inet_ntop4(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
static const char *fmt = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
size_t len;
|
||||
|
||||
if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
|
||||
{
|
||||
len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]);
|
||||
if (len >= size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
memcpy(dst, tmp, len + 1);
|
||||
|
||||
return (dst);
|
||||
}
|
||||
@@ -106,7 +107,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
int i, inc;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
@@ -157,13 +158,14 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp,
|
||||
sizeof tmp - (tp - tmp)))
|
||||
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += sprintf(tp, "%x", words[i]);
|
||||
inc = snprintf(tp, 5, "%x", words[i]);
|
||||
assert(inc < 5);
|
||||
tp += inc;
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
@@ -178,7 +180,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
memcpy(dst, tmp, tp - tmp);
|
||||
return (dst);
|
||||
}
|
||||
#endif /* AF_INET6 */
|
||||
|
||||
304
lib/md5.c
Normal file
304
lib/md5.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* RFC 1321 compliant MD5 implementation
|
||||
*
|
||||
* Copyright (C) 2001-2003 Christophe Devine
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
void md5_begin(md_context *ctx)
|
||||
{
|
||||
ctx->A = 0x67452301;
|
||||
ctx->B = 0xEFCDAB89;
|
||||
ctx->C = 0x98BADCFE;
|
||||
ctx->D = 0x10325476;
|
||||
|
||||
ctx->totalN = ctx->totalN2 = 0;
|
||||
}
|
||||
|
||||
static void md5_process(md_context *ctx, const uchar data[CSUM_CHUNK])
|
||||
{
|
||||
uint32 X[16], A, B, C, D;
|
||||
|
||||
A = ctx->A;
|
||||
B = ctx->B;
|
||||
C = ctx->C;
|
||||
D = ctx->D;
|
||||
|
||||
X[0] = IVALu(data, 0);
|
||||
X[1] = IVALu(data, 4);
|
||||
X[2] = IVALu(data, 8);
|
||||
X[3] = IVALu(data, 12);
|
||||
X[4] = IVALu(data, 16);
|
||||
X[5] = IVALu(data, 20);
|
||||
X[6] = IVALu(data, 24);
|
||||
X[7] = IVALu(data, 28);
|
||||
X[8] = IVALu(data, 32);
|
||||
X[9] = IVALu(data, 36);
|
||||
X[10] = IVALu(data, 40);
|
||||
X[11] = IVALu(data, 44);
|
||||
X[12] = IVALu(data, 48);
|
||||
X[13] = IVALu(data, 52);
|
||||
X[14] = IVALu(data, 56);
|
||||
X[15] = IVALu(data, 60);
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define P(a,b,c,d,k,s,t) a += F(b,c,d) + X[k] + t, a = S(a,s) + b
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
P(A, B, C, D, 0, 7, 0xD76AA478);
|
||||
P(D, A, B, C, 1, 12, 0xE8C7B756);
|
||||
P(C, D, A, B, 2, 17, 0x242070DB);
|
||||
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
|
||||
P(A, B, C, D, 4, 7, 0xF57C0FAF);
|
||||
P(D, A, B, C, 5, 12, 0x4787C62A);
|
||||
P(C, D, A, B, 6, 17, 0xA8304613);
|
||||
P(B, C, D, A, 7, 22, 0xFD469501);
|
||||
P(A, B, C, D, 8, 7, 0x698098D8);
|
||||
P(D, A, B, C, 9, 12, 0x8B44F7AF);
|
||||
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
|
||||
P(B, C, D, A, 11, 22, 0x895CD7BE);
|
||||
P(A, B, C, D, 12, 7, 0x6B901122);
|
||||
P(D, A, B, C, 13, 12, 0xFD987193);
|
||||
P(C, D, A, B, 14, 17, 0xA679438E);
|
||||
P(B, C, D, A, 15, 22, 0x49B40821);
|
||||
|
||||
#undef F
|
||||
#define F(x,y,z) (y ^ (z & (x ^ y)))
|
||||
|
||||
P(A, B, C, D, 1, 5, 0xF61E2562);
|
||||
P(D, A, B, C, 6, 9, 0xC040B340);
|
||||
P(C, D, A, B, 11, 14, 0x265E5A51);
|
||||
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
|
||||
P(A, B, C, D, 5, 5, 0xD62F105D);
|
||||
P(D, A, B, C, 10, 9, 0x02441453);
|
||||
P(C, D, A, B, 15, 14, 0xD8A1E681);
|
||||
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
|
||||
P(A, B, C, D, 9, 5, 0x21E1CDE6);
|
||||
P(D, A, B, C, 14, 9, 0xC33707D6);
|
||||
P(C, D, A, B, 3, 14, 0xF4D50D87);
|
||||
P(B, C, D, A, 8, 20, 0x455A14ED);
|
||||
P(A, B, C, D, 13, 5, 0xA9E3E905);
|
||||
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
|
||||
P(C, D, A, B, 7, 14, 0x676F02D9);
|
||||
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
|
||||
|
||||
#undef F
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
|
||||
P(A, B, C, D, 5, 4, 0xFFFA3942);
|
||||
P(D, A, B, C, 8, 11, 0x8771F681);
|
||||
P(C, D, A, B, 11, 16, 0x6D9D6122);
|
||||
P(B, C, D, A, 14, 23, 0xFDE5380C);
|
||||
P(A, B, C, D, 1, 4, 0xA4BEEA44);
|
||||
P(D, A, B, C, 4, 11, 0x4BDECFA9);
|
||||
P(C, D, A, B, 7, 16, 0xF6BB4B60);
|
||||
P(B, C, D, A, 10, 23, 0xBEBFBC70);
|
||||
P(A, B, C, D, 13, 4, 0x289B7EC6);
|
||||
P(D, A, B, C, 0, 11, 0xEAA127FA);
|
||||
P(C, D, A, B, 3, 16, 0xD4EF3085);
|
||||
P(B, C, D, A, 6, 23, 0x04881D05);
|
||||
P(A, B, C, D, 9, 4, 0xD9D4D039);
|
||||
P(D, A, B, C, 12, 11, 0xE6DB99E5);
|
||||
P(C, D, A, B, 15, 16, 0x1FA27CF8);
|
||||
P(B, C, D, A, 2, 23, 0xC4AC5665);
|
||||
|
||||
#undef F
|
||||
#define F(x,y,z) (y ^ (x | ~z))
|
||||
|
||||
P(A, B, C, D, 0, 6, 0xF4292244);
|
||||
P(D, A, B, C, 7, 10, 0x432AFF97);
|
||||
P(C, D, A, B, 14, 15, 0xAB9423A7);
|
||||
P(B, C, D, A, 5, 21, 0xFC93A039);
|
||||
P(A, B, C, D, 12, 6, 0x655B59C3);
|
||||
P(D, A, B, C, 3, 10, 0x8F0CCC92);
|
||||
P(C, D, A, B, 10, 15, 0xFFEFF47D);
|
||||
P(B, C, D, A, 1, 21, 0x85845DD1);
|
||||
P(A, B, C, D, 8, 6, 0x6FA87E4F);
|
||||
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
|
||||
P(C, D, A, B, 6, 15, 0xA3014314);
|
||||
P(B, C, D, A, 13, 21, 0x4E0811A1);
|
||||
P(A, B, C, D, 4, 6, 0xF7537E82);
|
||||
P(D, A, B, C, 11, 10, 0xBD3AF235);
|
||||
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
|
||||
P(B, C, D, A, 9, 21, 0xEB86D391);
|
||||
|
||||
#undef F
|
||||
|
||||
ctx->A += A;
|
||||
ctx->B += B;
|
||||
ctx->C += C;
|
||||
ctx->D += D;
|
||||
}
|
||||
|
||||
void md5_update(md_context *ctx, const uchar *input, uint32 length)
|
||||
{
|
||||
uint32 left, fill;
|
||||
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
left = ctx->totalN & 0x3F;
|
||||
fill = CSUM_CHUNK - left;
|
||||
|
||||
ctx->totalN += length;
|
||||
ctx->totalN &= 0xFFFFFFFF;
|
||||
|
||||
if (ctx->totalN < length)
|
||||
ctx->totalN2++;
|
||||
|
||||
if (left && length >= fill) {
|
||||
memcpy(ctx->buffer + left, input, fill);
|
||||
md5_process(ctx, ctx->buffer);
|
||||
length -= fill;
|
||||
input += fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (length >= CSUM_CHUNK) {
|
||||
md5_process(ctx, input);
|
||||
length -= CSUM_CHUNK;
|
||||
input += CSUM_CHUNK;
|
||||
}
|
||||
|
||||
if (length)
|
||||
memcpy(ctx->buffer + left, input, length);
|
||||
}
|
||||
|
||||
static uchar md5_padding[CSUM_CHUNK] = { 0x80 };
|
||||
|
||||
void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN])
|
||||
{
|
||||
uint32 last, padn;
|
||||
uint32 high, low;
|
||||
uchar msglen[8];
|
||||
|
||||
high = (ctx->totalN >> 29)
|
||||
| (ctx->totalN2 << 3);
|
||||
low = (ctx->totalN << 3);
|
||||
|
||||
SIVALu(msglen, 0, low);
|
||||
SIVALu(msglen, 4, high);
|
||||
|
||||
last = ctx->totalN & 0x3F;
|
||||
padn = last < 56 ? 56 - last : 120 - last;
|
||||
|
||||
md5_update(ctx, md5_padding, padn);
|
||||
md5_update(ctx, msglen, 8);
|
||||
|
||||
SIVALu(digest, 0, ctx->A);
|
||||
SIVALu(digest, 4, ctx->B);
|
||||
SIVALu(digest, 8, ctx->C);
|
||||
SIVALu(digest, 12, ctx->D);
|
||||
}
|
||||
|
||||
void get_md5(uchar *out, const uchar *input, int n)
|
||||
{
|
||||
md_context ctx;
|
||||
md5_begin(&ctx);
|
||||
md5_update(&ctx, input, n);
|
||||
md5_result(&ctx, out);
|
||||
}
|
||||
|
||||
#ifdef TEST_MD5
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* those are the standard RFC 1321 test vectors
|
||||
*/
|
||||
|
||||
static struct {
|
||||
char *str, *md5;
|
||||
} tests[] = {
|
||||
{ "",
|
||||
"d41d8cd98f00b204e9800998ecf8427e" },
|
||||
{ "a",
|
||||
"0cc175b9c0f1b6a831c399e269772661" },
|
||||
{ "abc",
|
||||
"900150983cd24fb0d6963f7d28e17f72" },
|
||||
{ "message digest",
|
||||
"f96b697d7cb7938d525a2f31aaf161d0" },
|
||||
{ "abcdefghijklmnopqrstuvwxyz",
|
||||
"c3fcd3d76192e4007dfb496cca67e13b" },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"d174ab98d277d9f5a5611c2c9f419d9f" },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
"57edf4a22be3c955ac49da2e2107b67a" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f;
|
||||
int i, j;
|
||||
char output[33];
|
||||
md_context ctx;
|
||||
uchar buf[1000];
|
||||
uchar md5sum[MD5_DIGEST_LEN];
|
||||
|
||||
if (argc < 2) {
|
||||
printf("\nMD5 Validation Tests:\n\n");
|
||||
|
||||
for (i = 0; tests[i].str; i++) {
|
||||
char *str = tests[i].str;
|
||||
char *chk = tests[i].md5;
|
||||
|
||||
printf(" Test %d ", i + 1);
|
||||
|
||||
get_md5(md5sum, str, strlen(str));
|
||||
|
||||
for (j = 0; j < MD5_DIGEST_LEN; j++)
|
||||
sprintf(output + j * 2, "%02x", md5sum[j]);
|
||||
|
||||
if (memcmp(output, chk, 32)) {
|
||||
printf("failed!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("passed.\n");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (--argc) {
|
||||
if (!(f = fopen(*++argv, "rb"))) {
|
||||
perror("fopen");
|
||||
return 1;
|
||||
}
|
||||
|
||||
md5_begin(&ctx);
|
||||
|
||||
while ((i = fread(buf, 1, sizeof buf, f)) > 0)
|
||||
md5_update(&ctx, buf, i);
|
||||
|
||||
md5_result(&ctx, md5sum);
|
||||
|
||||
for (j = 0; j < MD5_DIGEST_LEN; j++)
|
||||
printf("%02x", md5sum[j]);
|
||||
|
||||
printf(" %s\n", *argv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
226
lib/mdfour.c
226
lib/mdfour.c
@@ -1,32 +1,32 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
a implementation of MD4 designed for use in the SMB authentication protocol
|
||||
Copyright (C) Andrew Tridgell 1997-1998.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
* Unix SMB/Netbios implementation.
|
||||
* Version 1.9.
|
||||
* An implementation of MD4 designed for use in the SMB authentication protocol.
|
||||
*
|
||||
* Copyright (C) 1997-1998 Andrew Tridgell
|
||||
* Copyright (C) 2005-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/* NOTE: This code makes no attempt to be fast!
|
||||
*
|
||||
* It assumes that a int is at least 32 bits long. */
|
||||
|
||||
It assumes that a int is at least 32 bits long
|
||||
*/
|
||||
|
||||
static struct mdfour *m;
|
||||
static md_context *m;
|
||||
|
||||
#define MASK32 (0xffffffff)
|
||||
|
||||
@@ -48,32 +48,31 @@ static void mdfour64(uint32 *M)
|
||||
A = m->A; B = m->B; C = m->C; D = m->D;
|
||||
AA = A; BB = B; CC = C; DD = D;
|
||||
|
||||
ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
|
||||
ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
|
||||
ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
|
||||
ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
|
||||
ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
|
||||
ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
|
||||
ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
|
||||
ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
|
||||
ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
|
||||
ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
|
||||
ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
|
||||
ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
|
||||
|
||||
|
||||
ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
|
||||
ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
|
||||
ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);
|
||||
ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
|
||||
ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
|
||||
ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
|
||||
ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
|
||||
ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
|
||||
ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
|
||||
ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
|
||||
ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
|
||||
ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
|
||||
|
||||
ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
|
||||
ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
|
||||
ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
|
||||
ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
|
||||
ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
|
||||
ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
|
||||
ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
|
||||
ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
|
||||
ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
|
||||
ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
|
||||
ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
|
||||
|
||||
A += AA; B += BB;
|
||||
@@ -85,16 +84,17 @@ static void mdfour64(uint32 *M)
|
||||
m->A = A; m->B = B; m->C = C; m->D = D;
|
||||
}
|
||||
|
||||
static void copy64(uint32 *M, unsigned char *in)
|
||||
static void copy64(uint32 *M, const uchar *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<16;i++)
|
||||
M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
|
||||
(in[i*4+1]<<8) | (in[i*4+0]<<0);
|
||||
for (i = 0; i < MD4_DIGEST_LEN; i++) {
|
||||
M[i] = (in[i*4+3] << 24) | (in[i*4+2] << 16)
|
||||
| (in[i*4+1] << 8) | (in[i*4+0] << 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void copy4(unsigned char *out,uint32 x)
|
||||
static void copy4(uchar *out,uint32 x)
|
||||
{
|
||||
out[0] = x&0xFF;
|
||||
out[1] = (x>>8)&0xFF;
|
||||
@@ -102,36 +102,57 @@ static void copy4(unsigned char *out,uint32 x)
|
||||
out[3] = (x>>24)&0xFF;
|
||||
}
|
||||
|
||||
void mdfour_begin(struct mdfour *md)
|
||||
void mdfour_begin(md_context *md)
|
||||
{
|
||||
md->A = 0x67452301;
|
||||
md->B = 0xefcdab89;
|
||||
md->C = 0x98badcfe;
|
||||
md->D = 0x10325476;
|
||||
md->totalN = 0;
|
||||
md->totalN2 = 0;
|
||||
}
|
||||
|
||||
|
||||
static void mdfour_tail(unsigned char *in, int n)
|
||||
static void mdfour_tail(const uchar *in, uint32 length)
|
||||
{
|
||||
unsigned char buf[128];
|
||||
uchar buf[128];
|
||||
uint32 M[16];
|
||||
uint32 b;
|
||||
extern int protocol_version;
|
||||
|
||||
m->totalN += n;
|
||||
|
||||
b = m->totalN * 8;
|
||||
/*
|
||||
* Count total number of bits, modulo 2^64
|
||||
*/
|
||||
m->totalN += length << 3;
|
||||
if (m->totalN < (length << 3))
|
||||
m->totalN2++;
|
||||
m->totalN2 += length >> 29;
|
||||
|
||||
memset(buf, 0, 128);
|
||||
if (n) memcpy(buf, in, n);
|
||||
buf[n] = 0x80;
|
||||
if (length)
|
||||
memcpy(buf, in, length);
|
||||
buf[length] = 0x80;
|
||||
|
||||
if (n <= 55) {
|
||||
copy4(buf+56, b);
|
||||
if (length <= 55) {
|
||||
copy4(buf+56, m->totalN);
|
||||
/*
|
||||
* Prior to protocol version 27 only the number of bits
|
||||
* modulo 2^32 was included. MD4 requires the number
|
||||
* of bits modulo 2^64, which was fixed starting with
|
||||
* protocol version 27.
|
||||
*/
|
||||
if (protocol_version >= 27)
|
||||
copy4(buf+60, m->totalN2);
|
||||
copy64(M, buf);
|
||||
mdfour64(M);
|
||||
} else {
|
||||
copy4(buf+120, b);
|
||||
copy4(buf+120, m->totalN);
|
||||
/*
|
||||
* Prior to protocol version 27 only the number of bits
|
||||
* modulo 2^32 was included. MD4 requires the number
|
||||
* of bits modulo 2^64, which was fixed starting with
|
||||
* protocol version 27.
|
||||
*/
|
||||
if (protocol_version >= 27)
|
||||
copy4(buf+124, m->totalN2);
|
||||
copy64(M, buf);
|
||||
mdfour64(M);
|
||||
copy64(M, buf+64);
|
||||
@@ -139,51 +160,55 @@ static void mdfour_tail(unsigned char *in, int n)
|
||||
}
|
||||
}
|
||||
|
||||
void mdfour_update(struct mdfour *md, unsigned char *in, int n)
|
||||
void mdfour_update(md_context *md, const uchar *in, uint32 length)
|
||||
{
|
||||
uint32 M[16];
|
||||
|
||||
if (n == 0) mdfour_tail(in, n);
|
||||
|
||||
m = md;
|
||||
|
||||
while (n >= 64) {
|
||||
if (length == 0)
|
||||
mdfour_tail(in, length);
|
||||
|
||||
while (length >= 64) {
|
||||
copy64(M, in);
|
||||
mdfour64(M);
|
||||
in += 64;
|
||||
n -= 64;
|
||||
m->totalN += 64;
|
||||
length -= 64;
|
||||
m->totalN += 64 << 3;
|
||||
if (m->totalN < 64 << 3)
|
||||
m->totalN2++;
|
||||
}
|
||||
|
||||
if (n) mdfour_tail(in, n);
|
||||
if (length)
|
||||
mdfour_tail(in, length);
|
||||
}
|
||||
|
||||
|
||||
void mdfour_result(struct mdfour *md, unsigned char *out)
|
||||
void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN])
|
||||
{
|
||||
m = md;
|
||||
|
||||
copy4(out, m->A);
|
||||
copy4(out+4, m->B);
|
||||
copy4(out+8, m->C);
|
||||
copy4(out+12, m->D);
|
||||
copy4(digest, m->A);
|
||||
copy4(digest+4, m->B);
|
||||
copy4(digest+8, m->C);
|
||||
copy4(digest+12, m->D);
|
||||
}
|
||||
|
||||
|
||||
void mdfour(unsigned char *out, unsigned char *in, int n)
|
||||
void mdfour(uchar digest[MD4_DIGEST_LEN], uchar *in, int length)
|
||||
{
|
||||
struct mdfour md;
|
||||
md_context md;
|
||||
mdfour_begin(&md);
|
||||
mdfour_update(&md, in, n);
|
||||
mdfour_result(&md, out);
|
||||
mdfour_update(&md, in, length);
|
||||
mdfour_result(&md, digest);
|
||||
}
|
||||
|
||||
#ifdef TEST_MDFOUR
|
||||
int protocol_version = 28;
|
||||
|
||||
static void file_checksum1(char *fname)
|
||||
{
|
||||
int fd, i;
|
||||
struct mdfour md;
|
||||
unsigned char buf[64*1024], sum[16];
|
||||
int fd, i, was_multiple_of_64 = 1;
|
||||
md_context md;
|
||||
uchar buf[64*1024], sum[MD4_DIGEST_LEN];
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) {
|
||||
@@ -194,63 +219,28 @@ static void file_checksum1(char *fname)
|
||||
mdfour_begin(&md);
|
||||
|
||||
while (1) {
|
||||
int n = read(fd, buf, sizeof(buf));
|
||||
if (n <= 0) break;
|
||||
int n = read(fd, buf, sizeof buf);
|
||||
if (n <= 0)
|
||||
break;
|
||||
was_multiple_of_64 = !(n % 64);
|
||||
mdfour_update(&md, buf, n);
|
||||
}
|
||||
if (was_multiple_of_64 && protocol_version >= 27)
|
||||
mdfour_update(&md, buf, 0);
|
||||
|
||||
close(fd);
|
||||
|
||||
mdfour_result(&md, sum);
|
||||
|
||||
for (i=0;i<16;i++)
|
||||
for (i = 0; i < MD4_DIGEST_LEN; i++)
|
||||
printf("%02X", sum[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#if 0
|
||||
#include "../md4.h"
|
||||
|
||||
static void file_checksum2(char *fname)
|
||||
{
|
||||
int fd, i;
|
||||
MDstruct md;
|
||||
unsigned char buf[64], sum[16];
|
||||
|
||||
fd = open(fname,O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("fname");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
MDbegin(&md);
|
||||
|
||||
while (1) {
|
||||
int n = read(fd, buf, sizeof(buf));
|
||||
if (n <= 0) break;
|
||||
MDupdate(&md, buf, n*8);
|
||||
}
|
||||
|
||||
if (!md.done) {
|
||||
MDupdate(&md, buf, 0);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
memcpy(sum, md.buffer, 16);
|
||||
|
||||
for (i=0;i<16;i++)
|
||||
printf("%02X", sum[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
file_checksum1(argv[1]);
|
||||
#if 0
|
||||
file_checksum2(argv[1]);
|
||||
#endif
|
||||
while (--argc)
|
||||
file_checksum1(*++argv);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
34
lib/mdfour.h
34
lib/mdfour.h
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
a implementation of MD4 designed for use in the SMB authentication protocol
|
||||
Copyright (C) Andrew Tridgell 1997-1998.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
struct mdfour {
|
||||
uint32 A, B, C, D;
|
||||
uint32 totalN;
|
||||
};
|
||||
|
||||
void mdfour_begin(struct mdfour *md);
|
||||
void mdfour_update(struct mdfour *md, unsigned char *in, int n);
|
||||
void mdfour_result(struct mdfour *md, unsigned char *out);
|
||||
void mdfour(unsigned char *out, unsigned char *in, int n);
|
||||
|
||||
|
||||
|
||||
|
||||
26
lib/mdigest.h
Normal file
26
lib/mdigest.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* The include file for both the MD4 and MD5 routines. */
|
||||
|
||||
#define MD4_DIGEST_LEN 16
|
||||
#define MD5_DIGEST_LEN 16
|
||||
#define MAX_DIGEST_LEN MD5_DIGEST_LEN
|
||||
|
||||
#define CSUM_CHUNK 64
|
||||
|
||||
typedef struct {
|
||||
uint32 A, B, C, D;
|
||||
uint32 totalN; /* bit count, lower 32 bits */
|
||||
uint32 totalN2; /* bit count, upper 32 bits */
|
||||
uchar buffer[CSUM_CHUNK];
|
||||
} md_context;
|
||||
|
||||
void mdfour_begin(md_context *md);
|
||||
void mdfour_update(md_context *md, const uchar *in, uint32 length);
|
||||
void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN]);
|
||||
|
||||
void get_mdfour(uchar digest[MD4_DIGEST_LEN], const uchar *in, int length);
|
||||
|
||||
void md5_begin(md_context *ctx);
|
||||
void md5_update(md_context *ctx, const uchar *input, uint32 length);
|
||||
void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN]);
|
||||
|
||||
void get_md5(uchar digest[MD5_DIGEST_LEN], const uchar *input, int n);
|
||||
@@ -1,41 +1,39 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* A single utility routine.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2003-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/**
|
||||
* Produce a string representation of Unix mode bits like that used by
|
||||
* ls(1).
|
||||
*
|
||||
* @param buf buffer of at least 11 characters
|
||||
**/
|
||||
void permstring(char *perms,
|
||||
int mode)
|
||||
/* Produce a string representation of Unix mode bits like that used by ls(1).
|
||||
* The "buf" buffer must be at least 11 characters. */
|
||||
void permstring(char *perms, mode_t mode)
|
||||
{
|
||||
static const char *perm_map = "rwxrwxrwx";
|
||||
int i;
|
||||
|
||||
strcpy(perms, "----------");
|
||||
|
||||
for (i=0;i<9;i++) {
|
||||
if (mode & (1<<i)) perms[9-i] = perm_map[8-i];
|
||||
strlcpy(perms, "----------", 11);
|
||||
|
||||
for (i = 0; i < 9; i++) {
|
||||
if (mode & (1 << i))
|
||||
perms[9-i] = perm_map[8-i];
|
||||
}
|
||||
|
||||
/* Handle setuid/sticky bits. You might think the indices are
|
||||
@@ -46,18 +44,22 @@ void permstring(char *perms,
|
||||
|
||||
if (mode & S_ISGID)
|
||||
perms[6] = (mode & S_IXGRP) ? 's' : 'S';
|
||||
|
||||
|
||||
#ifdef S_ISVTX
|
||||
if (mode & S_ISVTX)
|
||||
perms[9] = (mode & S_IXOTH) ? 't' : 'T';
|
||||
#endif
|
||||
|
||||
if (S_ISLNK(mode)) perms[0] = 'l';
|
||||
if (S_ISDIR(mode)) perms[0] = 'd';
|
||||
if (S_ISBLK(mode)) perms[0] = 'b';
|
||||
if (S_ISCHR(mode)) perms[0] = 'c';
|
||||
if (S_ISSOCK(mode)) perms[0] = 's';
|
||||
if (S_ISFIFO(mode)) perms[0] = 'p';
|
||||
}
|
||||
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
perms[0] = 'd';
|
||||
else if (S_ISLNK(mode))
|
||||
perms[0] = 'l';
|
||||
else if (S_ISBLK(mode))
|
||||
perms[0] = 'b';
|
||||
else if (S_ISCHR(mode))
|
||||
perms[0] = 'c';
|
||||
else if (S_ISSOCK(mode))
|
||||
perms[0] = 's';
|
||||
else if (S_ISFIFO(mode))
|
||||
perms[0] = 'p';
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#define PERMSTRING_SIZE 11
|
||||
|
||||
void permstring(char *perms, int mode);
|
||||
void permstring(char *perms, mode_t mode);
|
||||
|
||||
268
lib/pool_alloc.3
Normal file
268
lib/pool_alloc.3
Normal file
@@ -0,0 +1,268 @@
|
||||
.ds d \-\^\-
|
||||
.ds o \fR[\fP
|
||||
.ds c \fR]\fP
|
||||
.ds | \fR|\fP
|
||||
.de D
|
||||
\\.B \*d\\$1
|
||||
..
|
||||
.de DI
|
||||
\\.BI \*d\\$1 \\$2
|
||||
..
|
||||
.de DR
|
||||
\\.BR \*d\\$1 \\$2
|
||||
..
|
||||
.de Di
|
||||
\\.BI \*d\\$1 " \\$2"
|
||||
..
|
||||
.de Db
|
||||
\\.B \*d\\$1 " \\$2"
|
||||
..
|
||||
.de Df
|
||||
\\.B \*d\*ono\*c\\$1
|
||||
..
|
||||
.de See
|
||||
See \fB\\$1\fP for details.
|
||||
..
|
||||
.de SeeIn
|
||||
See \fB\\$1\fP in \fB\\$2\fP for details.
|
||||
..
|
||||
.TH POOL_ALLOC 3
|
||||
.SH NAME
|
||||
pool_alloc, pool_free, pool_free_old, pool_talloc, pool_tfree, pool_create, pool_destroy, pool_boundary
|
||||
\- Allocate and free memory in managed allocation pools.
|
||||
.SH SYNOPSIS
|
||||
.B #include "pool_alloc.h"
|
||||
|
||||
\fBstruct alloc_pool *pool_create(size_t \fIsize\fB, size_t \fIquantum\fB, void (*\fIbomb\fB)(char *), int \fIflags\fB);
|
||||
|
||||
\fBvoid pool_destroy(struct alloc_pool *\fIpool\fB);
|
||||
|
||||
\fBvoid *pool_alloc(struct alloc_pool *\fIpool\fB, size_t \fIsize\fB, char *\fImsg\fB);
|
||||
|
||||
\fBvoid pool_free(struct alloc_pool *\fIpool\fB, size_t \fIsize\fB, void *\fIaddr\fB);
|
||||
|
||||
\fBvoid pool_free_old(struct alloc_pool *\fIpool\fB, void *\fIaddr\fB);
|
||||
|
||||
\fBvoid *pool_talloc(struct alloc_pool *\fIpool\fB, \fItype\fB), int \fIcount\fB, char *\fImsg\fB);
|
||||
|
||||
\fBvoid pool_tfree(struct alloc_pool *\fIpool\fB, \fItype\fB, int \fIcount\fB, void *\fIaddr\fB);
|
||||
|
||||
\fBvoid pool_boundary(struct alloc_pool *\fIpool\fB, sise_t \fIsize\fB);
|
||||
.SH DESCRIPTION
|
||||
.P
|
||||
The pool allocation routines use
|
||||
.B malloc()
|
||||
for underlying memory management.
|
||||
What allocation pools do is cause memory within a given pool
|
||||
to be allocated in large contiguous blocks
|
||||
(called extents) that will be reusable when freed. Unlike
|
||||
.BR malloc() ,
|
||||
the allocations are not managed individually.
|
||||
Instead, each extent tracks the total free memory within the
|
||||
extent. Each extent can either be used to allocate memory
|
||||
or to manage the freeing of memory within that extent.
|
||||
When an extent has less free memory than a given
|
||||
allocation request, the current extent ceases to be used
|
||||
for allocation. See also the
|
||||
.B pool_boundary()
|
||||
function.
|
||||
.P
|
||||
This form of memory management is suited to large numbers of small
|
||||
related allocations that are held for a while
|
||||
and then freed as a group.
|
||||
Because the
|
||||
underlying allocations are done in large contiguous extents,
|
||||
when an extent is freed, it can release a large enough
|
||||
contiguous block of memory to allow the memory to be returned
|
||||
to the OS for use by whatever program needs it.
|
||||
You can allocate from one or more memory pools and/or
|
||||
.B malloc()
|
||||
all at the same time without interfering with how pools work.
|
||||
.P
|
||||
.B pool_create()
|
||||
Creates an allocation pool for subsequent calls to the pool
|
||||
allocation functions.
|
||||
When an extent is created for allocations it will be
|
||||
.I size
|
||||
bytes.
|
||||
Allocations from the pool have their sizes rounded up to a
|
||||
multiple of
|
||||
.I quantum
|
||||
bytes in length.
|
||||
Specifying
|
||||
.B 0
|
||||
for
|
||||
.I quantum
|
||||
will produce a quantum that should meet maximal alignment
|
||||
on most platforms.
|
||||
Unless
|
||||
.B POOL_NO_QALIGN
|
||||
is set in the
|
||||
.IR flags ,
|
||||
allocations will be aligned to addresses that are a
|
||||
multiple of
|
||||
.IR quantum .
|
||||
A
|
||||
.B NULL
|
||||
may be specified for the
|
||||
.I bomb
|
||||
function pointer if it is not needed. (See the
|
||||
.B pool_alloc()
|
||||
function for how it is used.)
|
||||
If
|
||||
.B POOL_CLEAR
|
||||
is set in the
|
||||
.IR flags ,
|
||||
all allocations from the pool will be initialized to zeros.
|
||||
If either
|
||||
.B POOL_PREPEND
|
||||
or
|
||||
.B POOL_INTERN
|
||||
is specified in the
|
||||
.IR flags ,
|
||||
each extent's data structure will be allocated at the start of the
|
||||
.IR size -length
|
||||
buffer (rather than as a separate, non-pool allocation), with the
|
||||
former extending the
|
||||
.I size
|
||||
to hold the structure, and the latter subtracting the structure's
|
||||
length from the indicated
|
||||
.IR size .
|
||||
.P
|
||||
.B pool_destroy()
|
||||
destroys an allocation
|
||||
.I pool
|
||||
and frees all its associated memory.
|
||||
.P
|
||||
.B pool_alloc()
|
||||
allocates
|
||||
.I size
|
||||
bytes from the specified
|
||||
.IR pool .
|
||||
If
|
||||
.I size
|
||||
is
|
||||
.BR 0 ,
|
||||
.I quantum
|
||||
bytes will be allocated.
|
||||
If the pool has been created without
|
||||
.BR POOL_NO_QALIGN ,
|
||||
every chunk of memory that is returned will be suitably aligned.
|
||||
You can use this with the default
|
||||
.I quantum
|
||||
size to ensure that all memory can store a variable of any type.
|
||||
If the requested memory cannot be allocated, the
|
||||
.I bomb()
|
||||
function will be called with
|
||||
.I msg
|
||||
as its sole argument (if the function was defined at the time
|
||||
the pool was created), and then a
|
||||
.B NULL
|
||||
address is returned (assuming that the bomb function didn't exit).
|
||||
.P
|
||||
.B pool_free()
|
||||
frees
|
||||
.I size
|
||||
bytes pointed to by an
|
||||
.I addr
|
||||
that was previously allocated in the specified
|
||||
.IR pool .
|
||||
If
|
||||
.I size
|
||||
is
|
||||
.BR 0 ,
|
||||
.I quantum
|
||||
bytes will be freed.
|
||||
The memory freed within an extent will not be reusable until
|
||||
all of the memory in that extent has been freed with one
|
||||
exception: the most recent pool allocation may be freed back
|
||||
into the pool prior to making any further allocations.
|
||||
If enough free calls are made to indicate that an extent has no
|
||||
remaining allocated objects (as computed by the total freed size for
|
||||
an extent), its memory will be completely freed back to the system.
|
||||
If
|
||||
.I addr
|
||||
is
|
||||
.BR NULL ,
|
||||
no memory will be freed, but subsequent allocations will come
|
||||
from a new extent.
|
||||
.P
|
||||
.B pool_free_old()
|
||||
takes a boundary
|
||||
.I addr
|
||||
value that was returned by
|
||||
.B pool_boundary()
|
||||
and frees up any extents in the
|
||||
.I pool
|
||||
that have data allocated from that point backward in time.
|
||||
NOTE: you must NOT mix calls to both
|
||||
.B pool_free
|
||||
and
|
||||
.B pool_free_old
|
||||
on the same pool!
|
||||
.P
|
||||
.B pool_boundary()
|
||||
asks for a boundary value that can be sent to
|
||||
.B pool_free_old()
|
||||
at a later time to free up all memory allocated prior to a particular
|
||||
moment in time.
|
||||
If the extent that holds the boundary point has allocations from after the
|
||||
boundary point, it will not be freed until a future
|
||||
.B pool_free_old()
|
||||
call encompasses the entirety of the extent's data.
|
||||
If
|
||||
.I len
|
||||
is non-zero, the call will also check if the active extent has at least
|
||||
that much free memory available in it, and if not, it will mark the
|
||||
extent as inactive, forcing a new extent to be used for future allocations.
|
||||
(You can specify -1 for
|
||||
.I len
|
||||
if you want to force a new extent to start.)
|
||||
.P
|
||||
.B pool_talloc()
|
||||
is a macro that takes a
|
||||
.I type
|
||||
and a
|
||||
.I count
|
||||
instead of a
|
||||
.IR size .
|
||||
It casts the return value to the correct pointer type.
|
||||
.P
|
||||
.B pool_tfree
|
||||
is a macro that calls
|
||||
.B pool_free
|
||||
on memory that was allocated by
|
||||
.BR pool_talloc() .
|
||||
.SH RETURN VALUE
|
||||
.B pool_create()
|
||||
returns a pointer to
|
||||
.BR "struct alloc_pool" .
|
||||
.P
|
||||
.B pool_alloc()
|
||||
and
|
||||
.B pool_talloc()
|
||||
return pointers to the allocated memory,
|
||||
or NULL if the request fails.
|
||||
The return type of
|
||||
.B pool_alloc()
|
||||
will normally require casting to the desired type but
|
||||
.B pool_talloc()
|
||||
will returns a pointer of the requested
|
||||
.IR type .
|
||||
.P
|
||||
.B pool_boundary()
|
||||
returns a pointer that should only be used in a call to
|
||||
.BR pool_free_old() .
|
||||
.P
|
||||
.BR pool_free() ,
|
||||
.BR pool_free_old() ,
|
||||
.B pool_tfree()
|
||||
and
|
||||
.B pool_destroy()
|
||||
return no value.
|
||||
.SH SEE ALSO
|
||||
.nf
|
||||
malloc(3)
|
||||
.SH AUTHOR
|
||||
pool_alloc was created by J.W. Schultz of Pegasystems Technologies.
|
||||
.SH BUGS AND ISSUES
|
||||
376
lib/pool_alloc.c
Normal file
376
lib/pool_alloc.c
Normal file
@@ -0,0 +1,376 @@
|
||||
#include "rsync.h"
|
||||
|
||||
#define POOL_DEF_EXTENT (32 * 1024)
|
||||
|
||||
#define POOL_QALIGN_P2 (1<<16) /* power-of-2 qalign */
|
||||
|
||||
struct alloc_pool
|
||||
{
|
||||
size_t size; /* extent size */
|
||||
size_t quantum; /* allocation quantum */
|
||||
struct pool_extent *extents; /* top extent is "live" */
|
||||
void (*bomb)(); /* function to call if
|
||||
* malloc fails */
|
||||
int flags;
|
||||
|
||||
/* statistical data */
|
||||
unsigned long e_created; /* extents created */
|
||||
unsigned long e_freed; /* extents destroyed */
|
||||
int64 n_allocated; /* calls to alloc */
|
||||
int64 n_freed; /* calls to free */
|
||||
int64 b_allocated; /* cum. bytes allocated */
|
||||
int64 b_freed; /* cum. bytes freed */
|
||||
};
|
||||
|
||||
struct pool_extent
|
||||
{
|
||||
struct pool_extent *next;
|
||||
void *start; /* starting address */
|
||||
size_t free; /* free bytecount */
|
||||
size_t bound; /* trapped free bytes */
|
||||
};
|
||||
|
||||
struct align_test {
|
||||
uchar foo;
|
||||
union {
|
||||
int64 i;
|
||||
void *p;
|
||||
} bar;
|
||||
};
|
||||
|
||||
#define MINALIGN offsetof(struct align_test, bar)
|
||||
|
||||
/* Temporarily cast a void* var into a char* var when adding an offset (to
|
||||
* keep some compilers from complaining about the pointer arithmetic). */
|
||||
#define PTR_ADD(b,o) ( (void*) ((char*)(b) + (o)) )
|
||||
|
||||
alloc_pool_t
|
||||
pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags)
|
||||
{
|
||||
struct alloc_pool *pool;
|
||||
|
||||
if (!(pool = new0(struct alloc_pool)))
|
||||
return NULL;
|
||||
|
||||
if ((MINALIGN & (MINALIGN - 1)) != 0) {
|
||||
if (bomb)
|
||||
(*bomb)("Compiler error: MINALIGN is not a power of 2\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!size)
|
||||
size = POOL_DEF_EXTENT;
|
||||
if (!quantum)
|
||||
quantum = MINALIGN;
|
||||
|
||||
if (flags & POOL_INTERN) {
|
||||
if (size <= sizeof (struct pool_extent))
|
||||
size = quantum;
|
||||
else
|
||||
size -= sizeof (struct pool_extent);
|
||||
flags |= POOL_PREPEND;
|
||||
}
|
||||
|
||||
if (quantum <= 1)
|
||||
flags = (flags | POOL_NO_QALIGN) & ~POOL_QALIGN_P2;
|
||||
else if (!(flags & POOL_NO_QALIGN)) {
|
||||
if (size % quantum)
|
||||
size += quantum - size % quantum;
|
||||
/* If quantum is a power of 2, we'll avoid using modulus. */
|
||||
if (!(quantum & (quantum - 1)))
|
||||
flags |= POOL_QALIGN_P2;
|
||||
}
|
||||
|
||||
pool->size = size;
|
||||
pool->quantum = quantum;
|
||||
pool->bomb = bomb;
|
||||
pool->flags = flags;
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
void
|
||||
pool_destroy(alloc_pool_t p)
|
||||
{
|
||||
struct alloc_pool *pool = (struct alloc_pool *) p;
|
||||
struct pool_extent *cur, *next;
|
||||
|
||||
if (!pool)
|
||||
return;
|
||||
|
||||
for (cur = pool->extents; cur; cur = next) {
|
||||
next = cur->next;
|
||||
if (pool->flags & POOL_PREPEND)
|
||||
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
|
||||
else {
|
||||
free(cur->start);
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
free(pool);
|
||||
}
|
||||
|
||||
void *
|
||||
pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg)
|
||||
{
|
||||
struct alloc_pool *pool = (struct alloc_pool *) p;
|
||||
if (!pool)
|
||||
return NULL;
|
||||
|
||||
if (!len)
|
||||
len = pool->quantum;
|
||||
else if (pool->flags & POOL_QALIGN_P2) {
|
||||
if (len & (pool->quantum - 1))
|
||||
len += pool->quantum - (len & (pool->quantum - 1));
|
||||
} else if (!(pool->flags & POOL_NO_QALIGN)) {
|
||||
if (len % pool->quantum)
|
||||
len += pool->quantum - len % pool->quantum;
|
||||
}
|
||||
|
||||
if (len > pool->size)
|
||||
goto bomb_out;
|
||||
|
||||
if (!pool->extents || len > pool->extents->free) {
|
||||
void *start;
|
||||
size_t asize;
|
||||
struct pool_extent *ext;
|
||||
|
||||
asize = pool->size;
|
||||
if (pool->flags & POOL_PREPEND)
|
||||
asize += sizeof (struct pool_extent);
|
||||
|
||||
if (!(start = new_array(char, asize)))
|
||||
goto bomb_out;
|
||||
|
||||
if (pool->flags & POOL_CLEAR)
|
||||
memset(start, 0, asize);
|
||||
|
||||
if (pool->flags & POOL_PREPEND) {
|
||||
ext = start;
|
||||
start = PTR_ADD(start, sizeof (struct pool_extent));
|
||||
} else if (!(ext = new(struct pool_extent)))
|
||||
goto bomb_out;
|
||||
ext->start = start;
|
||||
ext->free = pool->size;
|
||||
ext->bound = 0;
|
||||
ext->next = pool->extents;
|
||||
pool->extents = ext;
|
||||
|
||||
pool->e_created++;
|
||||
}
|
||||
|
||||
pool->n_allocated++;
|
||||
pool->b_allocated += len;
|
||||
|
||||
pool->extents->free -= len;
|
||||
|
||||
return PTR_ADD(pool->extents->start, pool->extents->free);
|
||||
|
||||
bomb_out:
|
||||
if (pool->bomb)
|
||||
(*pool->bomb)(bomb_msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This function allows you to declare memory in the pool that you are done
|
||||
* using. If you free all the memory in a pool's extent, that extent will
|
||||
* be freed. */
|
||||
void
|
||||
pool_free(alloc_pool_t p, size_t len, void *addr)
|
||||
{
|
||||
struct alloc_pool *pool = (struct alloc_pool *)p;
|
||||
struct pool_extent *cur, *prev;
|
||||
|
||||
if (!pool)
|
||||
return;
|
||||
|
||||
if (!addr) {
|
||||
/* A NULL addr starts a fresh extent for new allocations. */
|
||||
if ((cur = pool->extents) != NULL && cur->free != pool->size) {
|
||||
cur->bound += cur->free;
|
||||
cur->free = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
len = pool->quantum;
|
||||
else if (pool->flags & POOL_QALIGN_P2) {
|
||||
if (len & (pool->quantum - 1))
|
||||
len += pool->quantum - (len & (pool->quantum - 1));
|
||||
} else if (!(pool->flags & POOL_NO_QALIGN)) {
|
||||
if (len % pool->quantum)
|
||||
len += pool->quantum - len % pool->quantum;
|
||||
}
|
||||
|
||||
pool->n_freed++;
|
||||
pool->b_freed += len;
|
||||
|
||||
for (prev = NULL, cur = pool->extents; cur; prev = cur, cur = cur->next) {
|
||||
if (addr >= cur->start
|
||||
&& addr < PTR_ADD(cur->start, pool->size))
|
||||
break;
|
||||
}
|
||||
if (!cur)
|
||||
return;
|
||||
|
||||
if (!prev) {
|
||||
/* The "live" extent is kept ready for more allocations. */
|
||||
if (cur->free + cur->bound + len >= pool->size) {
|
||||
if (pool->flags & POOL_CLEAR) {
|
||||
memset(PTR_ADD(cur->start, cur->free), 0,
|
||||
pool->size - cur->free);
|
||||
}
|
||||
cur->free = pool->size;
|
||||
cur->bound = 0;
|
||||
} else if (addr == PTR_ADD(cur->start, cur->free)) {
|
||||
if (pool->flags & POOL_CLEAR)
|
||||
memset(addr, 0, len);
|
||||
cur->free += len;
|
||||
} else
|
||||
cur->bound += len;
|
||||
} else {
|
||||
cur->bound += len;
|
||||
|
||||
if (cur->free + cur->bound >= pool->size) {
|
||||
prev->next = cur->next;
|
||||
if (pool->flags & POOL_PREPEND)
|
||||
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
|
||||
else {
|
||||
free(cur->start);
|
||||
free(cur);
|
||||
}
|
||||
pool->e_freed++;
|
||||
} else if (prev != pool->extents) {
|
||||
/* Move the extent to be the first non-live extent. */
|
||||
prev->next = cur->next;
|
||||
cur->next = pool->extents->next;
|
||||
pool->extents->next = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This allows you to declare that the given address marks the edge of some
|
||||
* pool memory that is no longer needed. Any extents that hold only data
|
||||
* older than the boundary address are freed. NOTE: You MUST NOT USE BOTH
|
||||
* pool_free() and pool_free_old() on the same pool!! */
|
||||
void
|
||||
pool_free_old(alloc_pool_t p, void *addr)
|
||||
{
|
||||
struct alloc_pool *pool = (struct alloc_pool *)p;
|
||||
struct pool_extent *cur, *prev, *next;
|
||||
|
||||
if (!pool || !addr)
|
||||
return;
|
||||
|
||||
for (prev = NULL, cur = pool->extents; cur; prev = cur, cur = cur->next) {
|
||||
if (addr >= cur->start
|
||||
&& addr < PTR_ADD(cur->start, pool->size))
|
||||
break;
|
||||
}
|
||||
if (!cur)
|
||||
return;
|
||||
|
||||
if (addr == PTR_ADD(cur->start, cur->free)) {
|
||||
if (prev) {
|
||||
prev->next = NULL;
|
||||
next = cur;
|
||||
} else {
|
||||
/* The most recent live extent can just be reset. */
|
||||
if (pool->flags & POOL_CLEAR)
|
||||
memset(addr, 0, pool->size - cur->free);
|
||||
cur->free = pool->size;
|
||||
cur->bound = 0;
|
||||
next = cur->next;
|
||||
cur->next = NULL;
|
||||
}
|
||||
} else {
|
||||
next = cur->next;
|
||||
cur->next = NULL;
|
||||
}
|
||||
|
||||
while ((cur = next) != NULL) {
|
||||
next = cur->next;
|
||||
if (pool->flags & POOL_PREPEND)
|
||||
free(PTR_ADD(cur->start, -sizeof (struct pool_extent)));
|
||||
else {
|
||||
free(cur->start);
|
||||
free(cur);
|
||||
}
|
||||
pool->e_freed++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the current extent doesn't have "len" free space in it, mark it as full
|
||||
* so that the next alloc will start a new extent. If len is (size_t)-1, this
|
||||
* bump will always occur. The function returns a boundary address that can
|
||||
* be used with pool_free_old(), or a NULL if no memory is allocated. */
|
||||
void *
|
||||
pool_boundary(alloc_pool_t p, size_t len)
|
||||
{
|
||||
struct alloc_pool *pool = (struct alloc_pool *)p;
|
||||
struct pool_extent *cur;
|
||||
|
||||
if (!pool || !pool->extents)
|
||||
return NULL;
|
||||
|
||||
cur = pool->extents;
|
||||
|
||||
if (cur->free < len) {
|
||||
cur->bound += cur->free;
|
||||
cur->free = 0;
|
||||
}
|
||||
|
||||
return PTR_ADD(cur->start, cur->free);
|
||||
}
|
||||
|
||||
#define FDPRINT(label, value) \
|
||||
do { \
|
||||
int len = snprintf(buf, sizeof buf, label, value); \
|
||||
if (write(fd, buf, len) != len) \
|
||||
ret = -1; \
|
||||
} while (0)
|
||||
|
||||
#define FDEXTSTAT(ext) \
|
||||
do { \
|
||||
int len = snprintf(buf, sizeof buf, " %12ld %5ld\n", \
|
||||
(long)ext->free, (long)ext->bound); \
|
||||
if (write(fd, buf, len) != len) \
|
||||
ret = -1; \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
pool_stats(alloc_pool_t p, int fd, int summarize)
|
||||
{
|
||||
struct alloc_pool *pool = (struct alloc_pool *) p;
|
||||
struct pool_extent *cur;
|
||||
char buf[BUFSIZ];
|
||||
int ret = 0;
|
||||
|
||||
if (!pool)
|
||||
return ret;
|
||||
|
||||
FDPRINT(" Extent size: %12ld\n", (long) pool->size);
|
||||
FDPRINT(" Alloc quantum: %12ld\n", (long) pool->quantum);
|
||||
FDPRINT(" Extents created: %12ld\n", pool->e_created);
|
||||
FDPRINT(" Extents freed: %12ld\n", pool->e_freed);
|
||||
FDPRINT(" Alloc count: %12.0f\n", (double) pool->n_allocated);
|
||||
FDPRINT(" Free Count: %12.0f\n", (double) pool->n_freed);
|
||||
FDPRINT(" Bytes allocated: %12.0f\n", (double) pool->b_allocated);
|
||||
FDPRINT(" Bytes freed: %12.0f\n", (double) pool->b_freed);
|
||||
|
||||
if (summarize)
|
||||
return ret;
|
||||
|
||||
if (!pool->extents)
|
||||
return ret;
|
||||
|
||||
if (write(fd, "\n", 1) != 1)
|
||||
ret = -1;
|
||||
|
||||
for (cur = pool->extents; cur; cur = cur->next)
|
||||
FDEXTSTAT(cur);
|
||||
|
||||
return ret;
|
||||
}
|
||||
21
lib/pool_alloc.h
Normal file
21
lib/pool_alloc.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#define POOL_CLEAR (1<<0) /* zero fill allocations */
|
||||
#define POOL_NO_QALIGN (1<<1) /* don't align data to quanta */
|
||||
#define POOL_INTERN (1<<2) /* Allocate extent structures */
|
||||
#define POOL_PREPEND (1<<3) /* or prepend to extent data */
|
||||
|
||||
typedef void *alloc_pool_t;
|
||||
|
||||
alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags);
|
||||
void pool_destroy(alloc_pool_t pool);
|
||||
void *pool_alloc(alloc_pool_t pool, size_t size, const char *bomb_msg);
|
||||
void pool_free(alloc_pool_t pool, size_t size, void *addr);
|
||||
void pool_free_old(alloc_pool_t pool, void *addr);
|
||||
void *pool_boundary(alloc_pool_t pool, size_t size);
|
||||
|
||||
#define pool_talloc(pool, type, count, bomb_msg) \
|
||||
((type *)pool_alloc(pool, sizeof(type) * count, bomb_msg))
|
||||
|
||||
#define pool_tfree(pool, type, count, addr) \
|
||||
(pool_free(pool, sizeof(type) * count, addr))
|
||||
1027
lib/snprintf.c
1027
lib/snprintf.c
File diff suppressed because it is too large
Load Diff
2796
lib/sysacls.c
Normal file
2796
lib/sysacls.c
Normal file
File diff suppressed because it is too large
Load Diff
305
lib/sysacls.h
Normal file
305
lib/sysacls.h
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Unix SMB/Netbios implementation.
|
||||
* Version 2.2.x
|
||||
* Portable SMB ACL interface
|
||||
* Copyright (C) Jeremy Allison 2000
|
||||
* Copyright (C) 2007-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#ifdef SUPPORT_ACLS
|
||||
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#ifdef HAVE_ACL_LIBACL_H
|
||||
#include <acl/libacl.h>
|
||||
#endif
|
||||
|
||||
#define SMB_MALLOC(cnt) new_array(char, cnt)
|
||||
#define SMB_MALLOC_P(obj) new_array(obj, 1)
|
||||
#define SMB_MALLOC_ARRAY(obj, cnt) new_array(obj, cnt)
|
||||
#define SMB_REALLOC(mem, cnt) realloc_array(mem, char, cnt)
|
||||
#define slprintf snprintf
|
||||
|
||||
#if defined HAVE_POSIX_ACLS /*-----------------------------------------------*/
|
||||
|
||||
/* This is an identity mapping (just remove the SMB_). */
|
||||
|
||||
#define SMB_ACL_TAG_T acl_tag_t
|
||||
#define SMB_ACL_TYPE_T acl_type_t
|
||||
|
||||
/* Types of ACLs. */
|
||||
#define SMB_ACL_USER ACL_USER
|
||||
#define SMB_ACL_USER_OBJ ACL_USER_OBJ
|
||||
#define SMB_ACL_GROUP ACL_GROUP
|
||||
#define SMB_ACL_GROUP_OBJ ACL_GROUP_OBJ
|
||||
#define SMB_ACL_OTHER ACL_OTHER
|
||||
#define SMB_ACL_MASK ACL_MASK
|
||||
|
||||
#define SMB_ACL_T acl_t
|
||||
|
||||
#define SMB_ACL_ENTRY_T acl_entry_t
|
||||
|
||||
#define SMB_ACL_FIRST_ENTRY ACL_FIRST_ENTRY
|
||||
#define SMB_ACL_NEXT_ENTRY ACL_NEXT_ENTRY
|
||||
|
||||
#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS
|
||||
#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
|
||||
|
||||
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
|
||||
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
|
||||
|
||||
#define SMB_ACL_NEED_SORT
|
||||
|
||||
#elif defined HAVE_TRU64_ACLS /*---------------------------------------------*/
|
||||
|
||||
/* This is for DEC/Compaq Tru64 UNIX */
|
||||
|
||||
#define SMB_ACL_TAG_T acl_tag_t
|
||||
#define SMB_ACL_TYPE_T acl_type_t
|
||||
|
||||
/* Types of ACLs. */
|
||||
#define SMB_ACL_USER ACL_USER
|
||||
#define SMB_ACL_USER_OBJ ACL_USER_OBJ
|
||||
#define SMB_ACL_GROUP ACL_GROUP
|
||||
#define SMB_ACL_GROUP_OBJ ACL_GROUP_OBJ
|
||||
#define SMB_ACL_OTHER ACL_OTHER
|
||||
#define SMB_ACL_MASK ACL_MASK
|
||||
|
||||
#define SMB_ACL_T acl_t
|
||||
|
||||
#define SMB_ACL_ENTRY_T acl_entry_t
|
||||
|
||||
#define SMB_ACL_FIRST_ENTRY 0
|
||||
#define SMB_ACL_NEXT_ENTRY 1
|
||||
|
||||
#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS
|
||||
#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
|
||||
|
||||
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
|
||||
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
|
||||
|
||||
#define SMB_ACL_NEED_SORT
|
||||
|
||||
#elif defined HAVE_UNIXWARE_ACLS || defined HAVE_SOLARIS_ACLS /*-------------*/
|
||||
|
||||
/* Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
|
||||
* Modified by Toomas Soome <tsoome@ut.ee> for Solaris. */
|
||||
|
||||
/* SVR4.2 ES/MP ACLs */
|
||||
typedef int SMB_ACL_TAG_T;
|
||||
typedef int SMB_ACL_TYPE_T;
|
||||
|
||||
/* Types of ACLs. */
|
||||
#define SMB_ACL_USER USER
|
||||
#define SMB_ACL_USER_OBJ USER_OBJ
|
||||
#define SMB_ACL_GROUP GROUP
|
||||
#define SMB_ACL_GROUP_OBJ GROUP_OBJ
|
||||
#define SMB_ACL_OTHER OTHER_OBJ
|
||||
#define SMB_ACL_MASK CLASS_OBJ
|
||||
|
||||
typedef struct SMB_ACL_T {
|
||||
int size;
|
||||
int count;
|
||||
int next;
|
||||
struct acl acl[1];
|
||||
} *SMB_ACL_T;
|
||||
|
||||
typedef struct acl *SMB_ACL_ENTRY_T;
|
||||
|
||||
#define SMB_ACL_FIRST_ENTRY 0
|
||||
#define SMB_ACL_NEXT_ENTRY 1
|
||||
|
||||
#define SMB_ACL_TYPE_ACCESS 0
|
||||
#define SMB_ACL_TYPE_DEFAULT 1
|
||||
|
||||
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
|
||||
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
|
||||
|
||||
#define SMB_ACL_NEED_SORT
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#define SMB_ACL_LOSES_SPECIAL_MODE_BITS
|
||||
#endif
|
||||
|
||||
#elif defined HAVE_HPUX_ACLS /*----------------------------------------------*/
|
||||
|
||||
/* Based on the Solaris & UnixWare code. */
|
||||
|
||||
#undef GROUP
|
||||
#include <sys/aclv.h>
|
||||
|
||||
/* SVR4.2 ES/MP ACLs */
|
||||
typedef int SMB_ACL_TAG_T;
|
||||
typedef int SMB_ACL_TYPE_T;
|
||||
|
||||
/* Types of ACLs. */
|
||||
#define SMB_ACL_USER USER
|
||||
#define SMB_ACL_USER_OBJ USER_OBJ
|
||||
#define SMB_ACL_GROUP GROUP
|
||||
#define SMB_ACL_GROUP_OBJ GROUP_OBJ
|
||||
#define SMB_ACL_OTHER OTHER_OBJ
|
||||
#define SMB_ACL_MASK CLASS_OBJ
|
||||
|
||||
typedef struct SMB_ACL_T {
|
||||
int size;
|
||||
int count;
|
||||
int next;
|
||||
struct acl acl[1];
|
||||
} *SMB_ACL_T;
|
||||
|
||||
typedef struct acl *SMB_ACL_ENTRY_T;
|
||||
|
||||
#define SMB_ACL_FIRST_ENTRY 0
|
||||
#define SMB_ACL_NEXT_ENTRY 1
|
||||
|
||||
#define SMB_ACL_TYPE_ACCESS 0
|
||||
#define SMB_ACL_TYPE_DEFAULT 1
|
||||
|
||||
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
|
||||
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
|
||||
|
||||
#define SMB_ACL_NEED_SORT
|
||||
|
||||
#elif defined HAVE_IRIX_ACLS /*----------------------------------------------*/
|
||||
|
||||
/* IRIX ACLs */
|
||||
|
||||
#define SMB_ACL_TAG_T acl_tag_t
|
||||
#define SMB_ACL_TYPE_T acl_type_t
|
||||
|
||||
/* Types of ACLs. */
|
||||
#define SMB_ACL_USER ACL_USER
|
||||
#define SMB_ACL_USER_OBJ ACL_USER_OBJ
|
||||
#define SMB_ACL_GROUP ACL_GROUP
|
||||
#define SMB_ACL_GROUP_OBJ ACL_GROUP_OBJ
|
||||
#define SMB_ACL_OTHER ACL_OTHER_OBJ
|
||||
#define SMB_ACL_MASK ACL_MASK
|
||||
|
||||
typedef struct SMB_ACL_T {
|
||||
int next;
|
||||
BOOL freeaclp;
|
||||
struct acl *aclp;
|
||||
} *SMB_ACL_T;
|
||||
|
||||
#define SMB_ACL_ENTRY_T acl_entry_t
|
||||
|
||||
#define SMB_ACL_FIRST_ENTRY 0
|
||||
#define SMB_ACL_NEXT_ENTRY 1
|
||||
|
||||
#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS
|
||||
#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
|
||||
|
||||
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
|
||||
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
|
||||
|
||||
#define SMB_ACL_NEED_SORT
|
||||
|
||||
#elif defined HAVE_AIX_ACLS /*-----------------------------------------------*/
|
||||
|
||||
/* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
|
||||
|
||||
#include "/usr/include/acl.h"
|
||||
|
||||
struct acl_entry_link{
|
||||
struct acl_entry_link *prevp;
|
||||
struct new_acl_entry *entryp;
|
||||
struct acl_entry_link *nextp;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct new_acl_entry{
|
||||
unsigned short ace_len;
|
||||
unsigned short ace_type;
|
||||
unsigned int ace_access;
|
||||
struct ace_id ace_id[1];
|
||||
};
|
||||
|
||||
#define SMB_ACL_ENTRY_T struct new_acl_entry*
|
||||
#define SMB_ACL_T struct acl_entry_link*
|
||||
|
||||
#define SMB_ACL_TAG_T unsigned short
|
||||
#define SMB_ACL_TYPE_T int
|
||||
|
||||
/* Types of ACLs. */
|
||||
#define SMB_ACL_USER ACEID_USER
|
||||
#define SMB_ACL_USER_OBJ 3
|
||||
#define SMB_ACL_GROUP ACEID_GROUP
|
||||
#define SMB_ACL_GROUP_OBJ 4
|
||||
#define SMB_ACL_OTHER 5
|
||||
#define SMB_ACL_MASK 6
|
||||
|
||||
#define SMB_ACL_FIRST_ENTRY 1
|
||||
#define SMB_ACL_NEXT_ENTRY 2
|
||||
|
||||
#define SMB_ACL_TYPE_ACCESS 0
|
||||
#define SMB_ACL_TYPE_DEFAULT 1
|
||||
|
||||
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
|
||||
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
|
||||
|
||||
#define SMB_ACL_NEED_SORT
|
||||
|
||||
#elif defined(HAVE_OSX_ACLS) /*----------------------------------------------*/
|
||||
|
||||
/* Special handling for OS X ACLs */
|
||||
|
||||
#define SMB_ACL_TAG_T acl_tag_t
|
||||
#define SMB_ACL_TYPE_T acl_type_t
|
||||
|
||||
#define SMB_ACL_T acl_t
|
||||
|
||||
#define SMB_ACL_ENTRY_T acl_entry_t
|
||||
|
||||
#define SMB_ACL_USER 1
|
||||
#define SMB_ACL_GROUP 2
|
||||
|
||||
#define SMB_ACL_FIRST_ENTRY ACL_FIRST_ENTRY
|
||||
#define SMB_ACL_NEXT_ENTRY ACL_NEXT_ENTRY
|
||||
|
||||
#define SMB_ACL_TYPE_ACCESS ACL_TYPE_EXTENDED
|
||||
#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
|
||||
|
||||
#define SMB_ACL_VALID_NAME_BITS ((1<<25)-1)
|
||||
#define SMB_ACL_VALID_OBJ_BITS 0
|
||||
|
||||
/*#undef SMB_ACL_NEED_SORT*/
|
||||
|
||||
#else /*---------------------------------------------------------------------*/
|
||||
|
||||
/* Unknown platform. */
|
||||
|
||||
#error Cannot handle ACLs on this platform!
|
||||
|
||||
#endif
|
||||
|
||||
int sys_acl_get_entry(SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
|
||||
int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
|
||||
int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p);
|
||||
SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type);
|
||||
SMB_ACL_T sys_acl_get_fd(int fd);
|
||||
SMB_ACL_T sys_acl_init(int count);
|
||||
int sys_acl_create_entry(SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
|
||||
int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype, uint32 bits, id_t u_g_id);
|
||||
int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits);
|
||||
int sys_acl_valid(SMB_ACL_T theacl);
|
||||
int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
|
||||
int sys_acl_set_fd(int fd, SMB_ACL_T theacl);
|
||||
int sys_acl_delete_def_file(const char *name);
|
||||
int sys_acl_free_acl(SMB_ACL_T the_acl);
|
||||
int no_acl_syscall_error(int err);
|
||||
|
||||
#endif /* SUPPORT_ACLS */
|
||||
300
lib/sysxattrs.c
Normal file
300
lib/sysxattrs.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Extended attribute support for rsync.
|
||||
*
|
||||
* Copyright (C) 2004 Red Hat, Inc.
|
||||
* Copyright (C) 2003-2015 Wayne Davison
|
||||
* Written by Jay Fenlason.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "sysxattrs.h"
|
||||
|
||||
#ifdef SUPPORT_XATTRS
|
||||
|
||||
#ifdef HAVE_OSX_XATTRS
|
||||
#define GETXATTR_FETCH_LIMIT (64*1024*1024)
|
||||
#endif
|
||||
|
||||
#if defined HAVE_LINUX_XATTRS
|
||||
|
||||
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
|
||||
{
|
||||
return lgetxattr(path, name, value, size);
|
||||
}
|
||||
|
||||
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
|
||||
{
|
||||
return fgetxattr(filedes, name, value, size);
|
||||
}
|
||||
|
||||
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
|
||||
{
|
||||
return lsetxattr(path, name, value, size, 0);
|
||||
}
|
||||
|
||||
int sys_lremovexattr(const char *path, const char *name)
|
||||
{
|
||||
return lremovexattr(path, name);
|
||||
}
|
||||
|
||||
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
|
||||
{
|
||||
return llistxattr(path, list, size);
|
||||
}
|
||||
|
||||
#elif HAVE_OSX_XATTRS
|
||||
|
||||
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
|
||||
{
|
||||
ssize_t len = getxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
|
||||
|
||||
/* If we're retrieving data, handle resource forks > 64MB specially */
|
||||
if (value != NULL && len == GETXATTR_FETCH_LIMIT && (size_t)len < size) {
|
||||
/* getxattr will only return 64MB of data at a time, need to call again with a new offset */
|
||||
u_int32_t offset = len;
|
||||
size_t data_retrieved = len;
|
||||
while (data_retrieved < size) {
|
||||
len = getxattr(path, name, value + offset, size - data_retrieved, offset, XATTR_NOFOLLOW);
|
||||
if (len <= 0)
|
||||
break;
|
||||
data_retrieved += len;
|
||||
offset += (u_int32_t)len;
|
||||
}
|
||||
len = data_retrieved;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
|
||||
{
|
||||
return fgetxattr(filedes, name, value, size, 0, 0);
|
||||
}
|
||||
|
||||
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
|
||||
{
|
||||
return setxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
|
||||
}
|
||||
|
||||
int sys_lremovexattr(const char *path, const char *name)
|
||||
{
|
||||
return removexattr(path, name, XATTR_NOFOLLOW);
|
||||
}
|
||||
|
||||
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
|
||||
{
|
||||
return listxattr(path, list, size, XATTR_NOFOLLOW);
|
||||
}
|
||||
|
||||
#elif HAVE_FREEBSD_XATTRS
|
||||
|
||||
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
|
||||
{
|
||||
return extattr_get_link(path, EXTATTR_NAMESPACE_USER, name, value, size);
|
||||
}
|
||||
|
||||
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
|
||||
{
|
||||
return extattr_get_fd(filedes, EXTATTR_NAMESPACE_USER, name, value, size);
|
||||
}
|
||||
|
||||
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
|
||||
{
|
||||
return extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, value, size);
|
||||
}
|
||||
|
||||
int sys_lremovexattr(const char *path, const char *name)
|
||||
{
|
||||
return extattr_delete_link(path, EXTATTR_NAMESPACE_USER, name);
|
||||
}
|
||||
|
||||
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
|
||||
{
|
||||
unsigned char keylen;
|
||||
ssize_t off, len = extattr_list_link(path, EXTATTR_NAMESPACE_USER, list, size);
|
||||
|
||||
if (len <= 0 || (size_t)len > size)
|
||||
return len;
|
||||
|
||||
/* FreeBSD puts a single-byte length before each string, with no '\0'
|
||||
* terminator. We need to change this into a series of null-terminted
|
||||
* strings. Since the size is the same, we can simply transform the
|
||||
* output in place. */
|
||||
for (off = 0; off < len; off += keylen + 1) {
|
||||
keylen = ((unsigned char*)list)[off];
|
||||
if (off + keylen >= len) {
|
||||
/* Should be impossible, but kernel bugs happen! */
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
memmove(list+off, list+off+1, keylen);
|
||||
list[off+keylen] = '\0';
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#elif HAVE_SOLARIS_XATTRS
|
||||
|
||||
static ssize_t read_xattr(int attrfd, void *buf, size_t buflen)
|
||||
{
|
||||
STRUCT_STAT sb;
|
||||
ssize_t ret;
|
||||
|
||||
if (fstat(attrfd, &sb) < 0)
|
||||
ret = -1;
|
||||
else if (sb.st_size > SSIZE_MAX) {
|
||||
errno = ERANGE;
|
||||
ret = -1;
|
||||
} else if (buflen == 0)
|
||||
ret = sb.st_size;
|
||||
else if (sb.st_size > buflen) {
|
||||
errno = ERANGE;
|
||||
ret = -1;
|
||||
} else {
|
||||
size_t bufpos;
|
||||
for (bufpos = 0; bufpos < sb.st_size; ) {
|
||||
ssize_t cnt = read(attrfd, buf + bufpos, sb.st_size - bufpos);
|
||||
if (cnt <= 0) {
|
||||
if (cnt < 0 && errno == EINTR)
|
||||
continue;
|
||||
bufpos = -1;
|
||||
break;
|
||||
}
|
||||
bufpos += cnt;
|
||||
}
|
||||
ret = bufpos;
|
||||
}
|
||||
|
||||
close(attrfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
|
||||
{
|
||||
int attrfd;
|
||||
|
||||
if ((attrfd = attropen(path, name, O_RDONLY)) < 0) {
|
||||
errno = ENOATTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read_xattr(attrfd, value, size);
|
||||
}
|
||||
|
||||
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
|
||||
{
|
||||
int attrfd;
|
||||
|
||||
if ((attrfd = openat(filedes, name, O_RDONLY|O_XATTR, 0)) < 0) {
|
||||
errno = ENOATTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read_xattr(attrfd, value, size);
|
||||
}
|
||||
|
||||
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
|
||||
{
|
||||
int attrfd;
|
||||
size_t bufpos;
|
||||
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
|
||||
|
||||
if ((attrfd = attropen(path, name, O_CREAT|O_TRUNC|O_WRONLY, mode)) < 0)
|
||||
return -1;
|
||||
|
||||
for (bufpos = 0; bufpos < size; ) {
|
||||
ssize_t cnt = write(attrfd, value+bufpos, size);
|
||||
if (cnt <= 0) {
|
||||
if (cnt < 0 && errno == EINTR)
|
||||
continue;
|
||||
bufpos = -1;
|
||||
break;
|
||||
}
|
||||
bufpos += cnt;
|
||||
}
|
||||
|
||||
close(attrfd);
|
||||
|
||||
return bufpos > 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
int sys_lremovexattr(const char *path, const char *name)
|
||||
{
|
||||
int attrdirfd;
|
||||
int ret;
|
||||
|
||||
if ((attrdirfd = attropen(path, ".", O_RDONLY)) < 0)
|
||||
return -1;
|
||||
|
||||
ret = unlinkat(attrdirfd, name, 0);
|
||||
|
||||
close(attrdirfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
|
||||
{
|
||||
int attrdirfd;
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
ssize_t ret = 0;
|
||||
|
||||
if ((attrdirfd = attropen(path, ".", O_RDONLY)) < 0) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((dirp = fdopendir(attrdirfd)) == NULL) {
|
||||
close(attrdirfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((dp = readdir(dirp))) {
|
||||
int len = strlen(dp->d_name);
|
||||
|
||||
if (dp->d_name[0] == '.' && (len == 1 || (len == 2 && dp->d_name[1] == '.')))
|
||||
continue;
|
||||
if (len == 11 && dp->d_name[0] == 'S' && strncmp(dp->d_name, "SUNWattr_r", 10) == 0
|
||||
&& (dp->d_name[10] == 'o' || dp->d_name[10] == 'w'))
|
||||
continue;
|
||||
|
||||
if ((ret += len+1) > size) {
|
||||
if (size == 0)
|
||||
continue;
|
||||
ret = -1;
|
||||
errno = ERANGE;
|
||||
break;
|
||||
}
|
||||
memcpy(list, dp->d_name, len+1);
|
||||
list += len+1;
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
close(attrdirfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error You need to create xattr compatibility functions.
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SUPPORT_XATTRS */
|
||||
26
lib/sysxattrs.h
Normal file
26
lib/sysxattrs.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifdef SUPPORT_XATTRS
|
||||
|
||||
#if defined HAVE_ATTR_XATTR_H
|
||||
#include <attr/xattr.h>
|
||||
#elif defined HAVE_SYS_XATTR_H
|
||||
#include <sys/xattr.h>
|
||||
#elif defined HAVE_SYS_EXTATTR_H
|
||||
#include <sys/extattr.h>
|
||||
#endif
|
||||
|
||||
/* Linux 2.4 does not define this as a distinct errno value: */
|
||||
#ifndef ENOATTR
|
||||
#define ENOATTR ENODATA
|
||||
#endif
|
||||
|
||||
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size);
|
||||
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size);
|
||||
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size);
|
||||
int sys_lremovexattr(const char *path, const char *name);
|
||||
ssize_t sys_llistxattr(const char *path, char *list, size_t size);
|
||||
|
||||
#else
|
||||
|
||||
/* No xattrs available */
|
||||
|
||||
#endif
|
||||
368
lib/wildmatch.c
Normal file
368
lib/wildmatch.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
** Do shell-style pattern matching for ?, \, [], and * characters.
|
||||
** It is 8bit clean.
|
||||
**
|
||||
** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
|
||||
** Rich $alz is now <rsalz@bbn.com>.
|
||||
**
|
||||
** Modified by Wayne Davison to special-case '/' matching, to make '**'
|
||||
** work differently than '*', and to fix the character-class code.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/* What character marks an inverted character class? */
|
||||
#define NEGATE_CLASS '!'
|
||||
#define NEGATE_CLASS2 '^'
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define ABORT_ALL -1
|
||||
#define ABORT_TO_STARSTAR -2
|
||||
|
||||
#define CC_EQ(class, len, litmatch) ((len) == sizeof (litmatch)-1 \
|
||||
&& *(class) == *(litmatch) \
|
||||
&& strncmp((char*)class, litmatch, len) == 0)
|
||||
|
||||
#if defined STDC_HEADERS || !defined isascii
|
||||
# define ISASCII(c) 1
|
||||
#else
|
||||
# define ISASCII(c) isascii(c)
|
||||
#endif
|
||||
|
||||
#ifdef isblank
|
||||
# define ISBLANK(c) (ISASCII(c) && isblank(c))
|
||||
#else
|
||||
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
|
||||
#endif
|
||||
|
||||
#ifdef isgraph
|
||||
# define ISGRAPH(c) (ISASCII(c) && isgraph(c))
|
||||
#else
|
||||
# define ISGRAPH(c) (ISASCII(c) && isprint(c) && !isspace(c))
|
||||
#endif
|
||||
|
||||
#define ISPRINT(c) (ISASCII(c) && isprint(c))
|
||||
#define ISDIGIT(c) (ISASCII(c) && isdigit(c))
|
||||
#define ISALNUM(c) (ISASCII(c) && isalnum(c))
|
||||
#define ISALPHA(c) (ISASCII(c) && isalpha(c))
|
||||
#define ISCNTRL(c) (ISASCII(c) && iscntrl(c))
|
||||
#define ISLOWER(c) (ISASCII(c) && islower(c))
|
||||
#define ISPUNCT(c) (ISASCII(c) && ispunct(c))
|
||||
#define ISSPACE(c) (ISASCII(c) && isspace(c))
|
||||
#define ISUPPER(c) (ISASCII(c) && isupper(c))
|
||||
#define ISXDIGIT(c) (ISASCII(c) && isxdigit(c))
|
||||
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
int wildmatch_iteration_count;
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
uchar p_ch;
|
||||
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
wildmatch_iteration_count++;
|
||||
#endif
|
||||
|
||||
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. */
|
||||
p_ch = *++p;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (t_ch != p_ch)
|
||||
return FALSE;
|
||||
continue;
|
||||
case '?':
|
||||
/* Match anything but '/'. */
|
||||
if (t_ch == '/')
|
||||
return FALSE;
|
||||
continue;
|
||||
case '*':
|
||||
if (*++p == '*') {
|
||||
while (*++p == '*') {}
|
||||
special = TRUE;
|
||||
} else
|
||||
special = FALSE;
|
||||
if (*p == '\0') {
|
||||
/* Trailing "**" matches everything. Trailing "*" matches
|
||||
* only if there are no more slash characters. */
|
||||
if (!special) {
|
||||
do {
|
||||
if (strchr((char*)text, '/') != NULL)
|
||||
return FALSE;
|
||||
} while ((text = *a++) != NULL);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
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 && t_ch == '/')
|
||||
return ABORT_TO_STARSTAR;
|
||||
t_ch = *++text;
|
||||
}
|
||||
return ABORT_ALL;
|
||||
case '[':
|
||||
p_ch = *++p;
|
||||
#ifdef NEGATE_CLASS2
|
||||
if (p_ch == NEGATE_CLASS2)
|
||||
p_ch = NEGATE_CLASS;
|
||||
#endif
|
||||
/* Assign literal TRUE/FALSE because of "matched" comparison. */
|
||||
special = p_ch == NEGATE_CLASS? TRUE : FALSE;
|
||||
if (special) {
|
||||
/* Inverted character class. */
|
||||
p_ch = *++p;
|
||||
}
|
||||
prev_ch = 0;
|
||||
matched = FALSE;
|
||||
do {
|
||||
if (!p_ch)
|
||||
return ABORT_ALL;
|
||||
if (p_ch == '\\') {
|
||||
p_ch = *++p;
|
||||
if (!p_ch)
|
||||
return ABORT_ALL;
|
||||
if (t_ch == p_ch)
|
||||
matched = TRUE;
|
||||
} 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 (t_ch <= p_ch && t_ch >= prev_ch)
|
||||
matched = TRUE;
|
||||
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; (p_ch = *p) && p_ch != ']'; p++) {} /*SHARED ITERATOR*/
|
||||
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;
|
||||
p_ch = '[';
|
||||
if (t_ch == p_ch)
|
||||
matched = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (CC_EQ(s,i, "alnum")) {
|
||||
if (ISALNUM(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "alpha")) {
|
||||
if (ISALPHA(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "blank")) {
|
||||
if (ISBLANK(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "cntrl")) {
|
||||
if (ISCNTRL(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "digit")) {
|
||||
if (ISDIGIT(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "graph")) {
|
||||
if (ISGRAPH(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "lower")) {
|
||||
if (ISLOWER(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "print")) {
|
||||
if (ISPRINT(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "punct")) {
|
||||
if (ISPUNCT(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "space")) {
|
||||
if (ISSPACE(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "upper")) {
|
||||
if (ISUPPER(t_ch))
|
||||
matched = TRUE;
|
||||
} else if (CC_EQ(s,i, "xdigit")) {
|
||||
if (ISXDIGIT(t_ch))
|
||||
matched = TRUE;
|
||||
} else /* malformed [:class:] string */
|
||||
return ABORT_ALL;
|
||||
p_ch = 0; /* This makes "prev_ch" get set to 0. */
|
||||
} else if (t_ch == p_ch)
|
||||
matched = TRUE;
|
||||
} while (prev_ch = p_ch, (p_ch = *++p) != ']');
|
||||
if (matched == special || t_ch == '/')
|
||||
return FALSE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if (*text)
|
||||
return FALSE;
|
||||
} while ((text = *a++) != NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* 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 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;
|
||||
}
|
||||
6
lib/wildmatch.h
Normal file
6
lib/wildmatch.h
Normal file
@@ -0,0 +1,6 @@
|
||||
/* wildmatch.h */
|
||||
|
||||
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);
|
||||
1230
loadparm.c
1230
loadparm.c
File diff suppressed because it is too large
Load Diff
22
m4/have_type.m4
Normal file
22
m4/have_type.m4
Normal file
@@ -0,0 +1,22 @@
|
||||
dnl AC_HAVE_TYPE(TYPE,INCLUDES)
|
||||
AC_DEFUN([AC_HAVE_TYPE], [
|
||||
AC_REQUIRE([AC_HEADER_STDC])
|
||||
cv=`echo "$1" | sed 'y%./+- %__p__%'`
|
||||
AC_MSG_CHECKING(for $1)
|
||||
AC_CACHE_VAL([ac_cv_type_$cv],
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
AC_INCLUDES_DEFAULT
|
||||
$2]],
|
||||
[[$1 foo;]])],
|
||||
[eval "ac_cv_type_$cv=yes"],
|
||||
[eval "ac_cv_type_$cv=no"]))dnl
|
||||
ac_foo=`eval echo \\$ac_cv_type_$cv`
|
||||
AC_MSG_RESULT($ac_foo)
|
||||
if test "$ac_foo" = yes; then
|
||||
ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
|
||||
if false; then
|
||||
AC_CHECK_TYPES($1)
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED($ac_tr_hdr, 1, [Define if you have type `$1'])
|
||||
fi
|
||||
])
|
||||
@@ -1,27 +1,3 @@
|
||||
dnl AC_VALIDATE_CACHE_SYSTEM_TYPE[(cmd)]
|
||||
dnl if the cache file is inconsistent with the current host,
|
||||
dnl target and build system types, execute CMD or print a default
|
||||
dnl error message.
|
||||
AC_DEFUN(AC_VALIDATE_CACHE_SYSTEM_TYPE, [
|
||||
AC_REQUIRE([AC_CANONICAL_SYSTEM])
|
||||
AC_MSG_CHECKING([config.cache system type])
|
||||
if { test x"${ac_cv_host_system_type+set}" = x"set" &&
|
||||
test x"$ac_cv_host_system_type" != x"$host"; } ||
|
||||
{ test x"${ac_cv_build_system_type+set}" = x"set" &&
|
||||
test x"$ac_cv_build_system_type" != x"$build"; } ||
|
||||
{ test x"${ac_cv_target_system_type+set}" = x"set" &&
|
||||
test x"$ac_cv_target_system_type" != x"$target"; }; then
|
||||
AC_MSG_RESULT([different])
|
||||
ifelse($#, 1, [$1],
|
||||
[AC_MSG_ERROR(["you must remove config.cache and restart configure"])])
|
||||
else
|
||||
AC_MSG_RESULT([same])
|
||||
fi
|
||||
ac_cv_host_system_type="$host"
|
||||
ac_cv_build_system_type="$build"
|
||||
ac_cv_target_system_type="$target"
|
||||
])
|
||||
|
||||
dnl Check for socklen_t: historically on BSD it is an int, and in
|
||||
dnl POSIX 1g it is a type of its own, but some platforms use different
|
||||
dnl types for the argument to getsockopt, getpeername, etc. So we
|
||||
@@ -67,5 +43,3 @@ AC_DEFUN([TYPE_SOCKLEN_T],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/socket.h>])
|
||||
])
|
||||
|
||||
|
||||
23
m4/validate_cache_system_type.m4
Normal file
23
m4/validate_cache_system_type.m4
Normal file
@@ -0,0 +1,23 @@
|
||||
dnl AC_VALIDATE_CACHE_SYSTEM_TYPE[(cmd)]
|
||||
dnl if the cache file is inconsistent with the current host,
|
||||
dnl target and build system types, execute CMD or print a default
|
||||
dnl error message.
|
||||
AC_DEFUN([AC_VALIDATE_CACHE_SYSTEM_TYPE], [
|
||||
AC_REQUIRE([AC_CANONICAL_SYSTEM])
|
||||
AC_MSG_CHECKING([config.cache system type])
|
||||
if { test x"${ac_cv_host_system_type+set}" = x"set" &&
|
||||
test x"$ac_cv_host_system_type" != x"$host"; } ||
|
||||
{ test x"${ac_cv_build_system_type+set}" = x"set" &&
|
||||
test x"$ac_cv_build_system_type" != x"$build"; } ||
|
||||
{ test x"${ac_cv_target_system_type+set}" = x"set" &&
|
||||
test x"$ac_cv_target_system_type" != x"$target"; }; then
|
||||
AC_MSG_RESULT([different])
|
||||
ifelse($#, 1, [$1],
|
||||
[AC_MSG_ERROR(["you must remove config.cache and restart configure"])])
|
||||
else
|
||||
AC_MSG_RESULT([same])
|
||||
fi
|
||||
ac_cv_host_system_type="$host"
|
||||
ac_cv_build_system_type="$build"
|
||||
ac_cv_target_system_type="$target"
|
||||
])
|
||||
504
match.c
504
match.c
@@ -1,97 +1,97 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Block matching used by the file-transfer code.
|
||||
*
|
||||
* Copyright (C) 1996 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2003-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "inums.h"
|
||||
|
||||
extern int csum_length;
|
||||
extern int checksum_seed;
|
||||
extern int append_mode;
|
||||
extern int checksum_len;
|
||||
|
||||
extern int verbose;
|
||||
extern int am_server;
|
||||
|
||||
extern int remote_version;
|
||||
|
||||
typedef unsigned short tag;
|
||||
|
||||
#define TABLESIZE (1<<16)
|
||||
#define NULL_TAG (-1)
|
||||
int updating_basis_file;
|
||||
char sender_file_sum[MAX_DIGEST_LEN];
|
||||
|
||||
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;
|
||||
int i;
|
||||
};
|
||||
#define TRADITIONAL_TABLESIZE (1<<16)
|
||||
|
||||
static struct target *targets;
|
||||
static uint32 tablesize;
|
||||
static int32 *hash_table;
|
||||
|
||||
static int *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);
|
||||
}
|
||||
#define SUM2HASH2(s1,s2) (((s1) + (s2)) & 0xFFFF)
|
||||
#define SUM2HASH(sum) SUM2HASH2((sum)&0xFFFF,(sum)>>16)
|
||||
|
||||
#define BIG_SUM2HASH(sum) ((sum)%tablesize)
|
||||
|
||||
static void build_hash_table(struct sum_struct *s)
|
||||
{
|
||||
int i;
|
||||
static uint32 alloc_size;
|
||||
int32 i;
|
||||
|
||||
if (!tag_table)
|
||||
tag_table = (int *)malloc(sizeof(tag_table[0])*TABLESIZE);
|
||||
/* Dynamically calculate the hash table size so that the hash load
|
||||
* for big files is about 80%. A number greater than the traditional
|
||||
* size must be odd or s2 will not be able to span the entire set. */
|
||||
tablesize = (uint32)(s->count/8) * 10 + 11;
|
||||
if (tablesize < TRADITIONAL_TABLESIZE)
|
||||
tablesize = TRADITIONAL_TABLESIZE;
|
||||
if (tablesize > alloc_size || tablesize < alloc_size - 16*1024) {
|
||||
if (hash_table)
|
||||
free(hash_table);
|
||||
hash_table = new_array(int32, tablesize);
|
||||
if (!hash_table)
|
||||
out_of_memory("build_hash_table");
|
||||
alloc_size = tablesize;
|
||||
}
|
||||
|
||||
targets = (struct target *)malloc(sizeof(targets[0])*s->count);
|
||||
if (!tag_table || !targets)
|
||||
out_of_memory("build_hash_table");
|
||||
memset(hash_table, 0xFF, tablesize * sizeof hash_table[0]);
|
||||
|
||||
for (i=0;i<(int) s->count;i++) {
|
||||
targets[i].i = i;
|
||||
targets[i].t = gettag(s->sums[i].sum1);
|
||||
}
|
||||
|
||||
qsort(targets,s->count,sizeof(targets[0]),(int (*)())compare_targets);
|
||||
|
||||
for (i=0;i<TABLESIZE;i++)
|
||||
tag_table[i] = NULL_TAG;
|
||||
|
||||
for (i=s->count-1;i>=0;i--) {
|
||||
tag_table[targets[i].t] = i;
|
||||
}
|
||||
if (tablesize == TRADITIONAL_TABLESIZE) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < s->count; i++) {
|
||||
uint32 t = BIG_SUM2HASH(s->sums[i].sum1);
|
||||
s->sums[i].chain = hash_table[t];
|
||||
hash_table[t] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static OFF_T last_match;
|
||||
|
||||
|
||||
/**
|
||||
* Transmit a literal and/or match token.
|
||||
/* Transmit a literal and/or match token.
|
||||
*
|
||||
* This delightfully-named function is called either when we find a
|
||||
* match and need to transmit all the unmatched data leading up to it,
|
||||
@@ -99,161 +99,235 @@ static OFF_T last_match;
|
||||
* transmit it. As a result of this second case, it is called even if
|
||||
* we have not matched at all!
|
||||
*
|
||||
* @param i If >0, the number of a matched token. If 0, indicates we
|
||||
* have only literal data.
|
||||
**/
|
||||
static void matched(int f,struct sum_struct *s,struct map_struct *buf,
|
||||
OFF_T offset,int i)
|
||||
* If i >= 0, the number of a matched token. If < 0, indicates we have
|
||||
* only literal data. A -1 will send a 0-token-int too, and a -2 sends
|
||||
* only literal data, w/o any token-int. */
|
||||
static void matched(int f, struct sum_struct *s, struct map_struct *buf,
|
||||
OFF_T offset, int32 i)
|
||||
{
|
||||
OFF_T n = offset - last_match;
|
||||
OFF_T j;
|
||||
int32 n = (int32)(offset - last_match); /* max value: block_size (int32) */
|
||||
int32 j;
|
||||
|
||||
if (verbose > 2 && i >= 0)
|
||||
rprintf(FINFO,"match at %.0f last_match=%.0f j=%d len=%d n=%.0f\n",
|
||||
(double)offset,(double)last_match,i,s->sums[i].len,(double)n);
|
||||
if (DEBUG_GTE(DELTASUM, 2) && i >= 0) {
|
||||
rprintf(FINFO,
|
||||
"match at %s last_match=%s j=%d len=%ld n=%ld\n",
|
||||
big_num(offset), big_num(last_match), i,
|
||||
(long)s->sums[i].len, (long)n);
|
||||
}
|
||||
|
||||
send_token(f,i,buf,last_match,n,i<0?0:s->sums[i].len);
|
||||
send_token(f, i, buf, last_match, n, i < 0 ? 0 : s->sums[i].len);
|
||||
data_transfer += n;
|
||||
|
||||
if (i >= 0) {
|
||||
stats.matched_data += s->sums[i].len;
|
||||
n += s->sums[i].len;
|
||||
}
|
||||
|
||||
for (j=0;j<n;j+=CHUNK_SIZE) {
|
||||
int n1 = MIN(CHUNK_SIZE,n-j);
|
||||
sum_update(map_ptr(buf,last_match+j,n1),n1);
|
||||
}
|
||||
|
||||
for (j = 0; j < n; j += CHUNK_SIZE) {
|
||||
int32 n1 = MIN(CHUNK_SIZE, n - j);
|
||||
sum_update(map_ptr(buf, last_match + j, n1), n1);
|
||||
}
|
||||
|
||||
if (i >= 0)
|
||||
last_match = offset + s->sums[i].len;
|
||||
else
|
||||
last_match = offset;
|
||||
|
||||
if (buf) {
|
||||
if (buf && INFO_GTE(PROGRESS, 1))
|
||||
show_progress(last_match, buf->file_size);
|
||||
|
||||
if (i == -1) end_progress(buf->file_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void hash_search(int f,struct sum_struct *s,
|
||||
struct map_struct *buf,OFF_T len)
|
||||
struct map_struct *buf, OFF_T len)
|
||||
{
|
||||
OFF_T offset, end;
|
||||
int j,k, last_i;
|
||||
OFF_T offset, aligned_offset, end;
|
||||
int32 k, want_i, aligned_i, backup;
|
||||
char sum2[SUM_LENGTH];
|
||||
uint32 s1, s2, sum;
|
||||
uint32 s1, s2, sum;
|
||||
int more;
|
||||
schar *map;
|
||||
|
||||
/* last_i is used to encourage adjacent matches, allowing the RLL coding of the
|
||||
output to work more efficiently */
|
||||
last_i = -1;
|
||||
/* want_i is used to encourage adjacent matches, allowing the RLL
|
||||
* coding of the output to work more efficiently. */
|
||||
want_i = 0;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"hash search b=%ld len=%.0f\n",
|
||||
(long) s->n, (double)len);
|
||||
if (DEBUG_GTE(DELTASUM, 2)) {
|
||||
rprintf(FINFO, "hash search b=%ld len=%s\n",
|
||||
(long)s->blength, big_num(len));
|
||||
}
|
||||
|
||||
k = (int32)MIN(len, (OFF_T)s->blength);
|
||||
|
||||
map = (schar *)map_ptr(buf, 0, k);
|
||||
|
||||
/* cast is to make s->n signed; it should always be reasonably
|
||||
* small */
|
||||
k = MIN(len, (OFF_T) s->n);
|
||||
|
||||
map = (schar *)map_ptr(buf,0,k);
|
||||
|
||||
sum = get_checksum1((char *)map, k);
|
||||
s1 = sum & 0xFFFF;
|
||||
s2 = sum >> 16;
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO, "sum=%.8x k=%d\n", sum, k);
|
||||
|
||||
offset = 0;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 3))
|
||||
rprintf(FINFO, "sum=%.8x k=%ld\n", sum, (long)k);
|
||||
|
||||
offset = aligned_offset = aligned_i = 0;
|
||||
|
||||
end = len + 1 - s->sums[s->count-1].len;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO, "hash search s->n=%ld len=%.0f count=%ld\n",
|
||||
(long) s->n, (double) len, (long) s->count);
|
||||
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 3)) {
|
||||
rprintf(FINFO, "hash search s->blength=%ld len=%s count=%s\n",
|
||||
(long)s->blength, big_num(len), big_num(s->count));
|
||||
}
|
||||
|
||||
do {
|
||||
tag t = gettag2(s1,s2);
|
||||
int done_csum2 = 0;
|
||||
|
||||
j = tag_table[t];
|
||||
if (verbose > 4)
|
||||
rprintf(FINFO,"offset=%.0f sum=%08x\n",(double)offset,sum);
|
||||
|
||||
if (j == NULL_TAG) {
|
||||
goto null_tag;
|
||||
uint32 hash_entry;
|
||||
int32 i, *prev;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 4)) {
|
||||
rprintf(FINFO, "offset=%s sum=%04x%04x\n",
|
||||
big_num(offset), s2 & 0xFFFF, s1 & 0xFFFF);
|
||||
}
|
||||
|
||||
sum = (s1 & 0xffff) | (s2 << 16);
|
||||
tag_hits++;
|
||||
for (; j < (int) s->count && targets[j].t == t; j++) {
|
||||
int l, i = targets[j].i;
|
||||
|
||||
if (sum != s->sums[i].sum1) continue;
|
||||
|
||||
/* also make sure the two blocks are the same length */
|
||||
l = MIN(s->n,len-offset);
|
||||
if (l != s->sums[i].len) continue;
|
||||
if (tablesize == TRADITIONAL_TABLESIZE) {
|
||||
hash_entry = SUM2HASH2(s1,s2);
|
||||
if ((i = hash_table[hash_entry]) < 0)
|
||||
goto null_hash;
|
||||
sum = (s1 & 0xffff) | (s2 << 16);
|
||||
} else {
|
||||
sum = (s1 & 0xffff) | (s2 << 16);
|
||||
hash_entry = BIG_SUM2HASH(sum);
|
||||
if ((i = hash_table[hash_entry]) < 0)
|
||||
goto null_hash;
|
||||
}
|
||||
prev = &hash_table[hash_entry];
|
||||
|
||||
hash_hits++;
|
||||
do {
|
||||
int32 l;
|
||||
|
||||
/* When updating in-place, the chunk's offset must be
|
||||
* either >= our offset or identical data at that offset.
|
||||
* Remove any bypassed entries that we can never use. */
|
||||
if (updating_basis_file && s->sums[i].offset < offset
|
||||
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET)) {
|
||||
*prev = s->sums[i].chain;
|
||||
continue;
|
||||
}
|
||||
prev = &s->sums[i].chain;
|
||||
|
||||
if (sum != s->sums[i].sum1)
|
||||
continue;
|
||||
|
||||
/* also make sure the two blocks are the same length */
|
||||
l = (int32)MIN((OFF_T)s->blength, len-offset);
|
||||
if (l != s->sums[i].len)
|
||||
continue;
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 3)) {
|
||||
rprintf(FINFO,
|
||||
"potential match at %s i=%ld sum=%08x\n",
|
||||
big_num(offset), (long)i, sum);
|
||||
}
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"potential match at %.0f target=%d %d sum=%08x\n",
|
||||
(double)offset,j,i,sum);
|
||||
|
||||
if (!done_csum2) {
|
||||
map = (schar *)map_ptr(buf,offset,l);
|
||||
get_checksum2((char *)map,l,sum2);
|
||||
done_csum2 = 1;
|
||||
}
|
||||
|
||||
if (memcmp(sum2,s->sums[i].sum2,csum_length) != 0) {
|
||||
|
||||
if (memcmp(sum2,s->sums[i].sum2,s->s2length) != 0) {
|
||||
false_alarms++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we've found a match, but now check to see
|
||||
if last_i can hint at a better match */
|
||||
for (j++; j < (int) s->count && targets[j].t == t; j++) {
|
||||
int i2 = targets[j].i;
|
||||
if (i2 == last_i + 1) {
|
||||
if (sum != s->sums[i2].sum1) break;
|
||||
if (memcmp(sum2,s->sums[i2].sum2,csum_length) != 0) break;
|
||||
/* we've found an adjacent match - the RLL coder
|
||||
will be happy */
|
||||
i = i2;
|
||||
break;
|
||||
/* When updating in-place, the best possible match is
|
||||
* one with an identical offset, so we prefer that over
|
||||
* the adjacent want_i optimization. */
|
||||
if (updating_basis_file) {
|
||||
/* All the generator's chunks start at blength boundaries. */
|
||||
while (aligned_offset < offset) {
|
||||
aligned_offset += s->blength;
|
||||
aligned_i++;
|
||||
}
|
||||
if ((offset == aligned_offset
|
||||
|| (sum == 0 && l == s->blength && aligned_offset + l <= len))
|
||||
&& aligned_i < s->count) {
|
||||
if (i != aligned_i) {
|
||||
if (sum != s->sums[aligned_i].sum1
|
||||
|| l != s->sums[aligned_i].len
|
||||
|| memcmp(sum2, s->sums[aligned_i].sum2, s->s2length) != 0)
|
||||
goto check_want_i;
|
||||
i = aligned_i;
|
||||
}
|
||||
if (offset != aligned_offset) {
|
||||
/* We've matched some zeros in a spot that is also zeros
|
||||
* further along in the basis file, if we find zeros ahead
|
||||
* in the sender's file, we'll output enough literal data
|
||||
* to re-align with the basis file, and get back to seeking
|
||||
* instead of writing. */
|
||||
backup = (int32)(aligned_offset - last_match);
|
||||
if (backup < 0)
|
||||
backup = 0;
|
||||
map = (schar *)map_ptr(buf, aligned_offset - backup, l + backup)
|
||||
+ backup;
|
||||
sum = get_checksum1((char *)map, l);
|
||||
if (sum != s->sums[i].sum1)
|
||||
goto check_want_i;
|
||||
get_checksum2((char *)map, l, sum2);
|
||||
if (memcmp(sum2, s->sums[i].sum2, s->s2length) != 0)
|
||||
goto check_want_i;
|
||||
/* OK, we have a re-alignment match. Bump the offset
|
||||
* forward to the new match point. */
|
||||
offset = aligned_offset;
|
||||
}
|
||||
/* This identical chunk is in the same spot in the old and new file. */
|
||||
s->sums[i].flags |= SUMFLG_SAME_OFFSET;
|
||||
want_i = i;
|
||||
}
|
||||
}
|
||||
|
||||
last_i = i;
|
||||
|
||||
check_want_i:
|
||||
/* we've found a match, but now check to see
|
||||
* if want_i can hint at a better match. */
|
||||
if (i != want_i && want_i < s->count
|
||||
&& (!updating_basis_file || s->sums[want_i].offset >= offset
|
||||
|| s->sums[want_i].flags & SUMFLG_SAME_OFFSET)
|
||||
&& sum == s->sums[want_i].sum1
|
||||
&& memcmp(sum2, s->sums[want_i].sum2, s->s2length) == 0) {
|
||||
/* we've found an adjacent match - the RLL coder
|
||||
* will be happy */
|
||||
i = want_i;
|
||||
}
|
||||
want_i = i + 1;
|
||||
|
||||
matched(f,s,buf,offset,i);
|
||||
offset += s->sums[i].len - 1;
|
||||
k = MIN((len-offset), s->n);
|
||||
map = (schar *)map_ptr(buf,offset,k);
|
||||
k = (int32)MIN((OFF_T)s->blength, len-offset);
|
||||
map = (schar *)map_ptr(buf, offset, k);
|
||||
sum = get_checksum1((char *)map, k);
|
||||
s1 = sum & 0xFFFF;
|
||||
s2 = sum >> 16;
|
||||
matches++;
|
||||
break;
|
||||
}
|
||||
|
||||
null_tag:
|
||||
} while ((i = s->sums[i].chain) >= 0);
|
||||
|
||||
null_hash:
|
||||
backup = (int32)(offset - last_match);
|
||||
/* We sometimes read 1 byte prior to last_match... */
|
||||
if (backup < 0)
|
||||
backup = 0;
|
||||
|
||||
/* Trim off the first byte from the checksum */
|
||||
map = (schar *)map_ptr(buf,offset,k+1);
|
||||
more = offset + k < len;
|
||||
map = (schar *)map_ptr(buf, offset - backup, k + more + backup)
|
||||
+ backup;
|
||||
s1 -= map[0] + CHAR_OFFSET;
|
||||
s2 -= k * (map[0]+CHAR_OFFSET);
|
||||
|
||||
|
||||
/* Add on the next byte (if there is one) to the checksum */
|
||||
if (k < (len-offset)) {
|
||||
s1 += (map[k]+CHAR_OFFSET);
|
||||
if (more) {
|
||||
s1 += map[k] + CHAR_OFFSET;
|
||||
s2 += s1;
|
||||
} else {
|
||||
} else
|
||||
--k;
|
||||
}
|
||||
|
||||
/* By matching early we avoid re-reading the
|
||||
data 3 times in the case where a token
|
||||
@@ -261,15 +335,12 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
match. The 3 reads are caused by the
|
||||
running match, the checksum update and the
|
||||
literal send. */
|
||||
if (offset > last_match &&
|
||||
offset-last_match >= CHUNK_SIZE+s->n &&
|
||||
(end-offset > CHUNK_SIZE)) {
|
||||
matched(f,s,buf,offset - s->n, -2);
|
||||
}
|
||||
if (backup >= s->blength+CHUNK_SIZE && end-offset > CHUNK_SIZE)
|
||||
matched(f, s, buf, offset - s->blength, -2);
|
||||
} while (++offset < end);
|
||||
|
||||
matched(f,s,buf,len,-1);
|
||||
map_ptr(buf,len-1,1);
|
||||
|
||||
matched(f, s, buf, len, -1);
|
||||
map_ptr(buf, len-1, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -289,57 +360,77 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
**/
|
||||
void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
{
|
||||
char file_sum[MD4_SUM_LENGTH];
|
||||
extern int write_batch; /* dw */
|
||||
|
||||
last_match = 0;
|
||||
false_alarms = 0;
|
||||
tag_hits = 0;
|
||||
matches=0;
|
||||
data_transfer=0;
|
||||
hash_hits = 0;
|
||||
matches = 0;
|
||||
data_transfer = 0;
|
||||
|
||||
sum_init();
|
||||
sum_init(checksum_seed);
|
||||
|
||||
if (len > 0 && s->count>0) {
|
||||
if (append_mode > 0) {
|
||||
if (append_mode == 2) {
|
||||
OFF_T j = 0;
|
||||
for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
|
||||
if (buf && INFO_GTE(PROGRESS, 1))
|
||||
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 n = (int32)(s->flength - last_match);
|
||||
if (buf && INFO_GTE(PROGRESS, 1))
|
||||
show_progress(last_match, buf->file_size);
|
||||
sum_update(map_ptr(buf, last_match, n), n);
|
||||
}
|
||||
}
|
||||
last_match = s->flength;
|
||||
s->count = 0;
|
||||
}
|
||||
|
||||
if (len > 0 && s->count > 0) {
|
||||
build_hash_table(s);
|
||||
|
||||
if (verbose > 2)
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2))
|
||||
rprintf(FINFO,"built hash table\n");
|
||||
|
||||
hash_search(f,s,buf,len);
|
||||
|
||||
if (verbose > 2)
|
||||
|
||||
hash_search(f, s, buf, len);
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2))
|
||||
rprintf(FINFO,"done hash search\n");
|
||||
} else {
|
||||
OFF_T j;
|
||||
/* by doing this in pieces we avoid too many seeks */
|
||||
for (j=0;j<(len-CHUNK_SIZE);j+=CHUNK_SIZE) {
|
||||
int n1 = MIN(CHUNK_SIZE,(len-CHUNK_SIZE)-j);
|
||||
matched(f,s,buf,j+n1,-2);
|
||||
}
|
||||
matched(f,s,buf,len,-1);
|
||||
for (j = last_match + CHUNK_SIZE; j < len; j += CHUNK_SIZE)
|
||||
matched(f, s, buf, j, -2);
|
||||
matched(f, s, buf, len, -1);
|
||||
}
|
||||
|
||||
sum_end(file_sum);
|
||||
if (sum_end(sender_file_sum) != checksum_len)
|
||||
overflow_exit("checksum_len"); /* Impossible... */
|
||||
|
||||
if (remote_version >= 14) {
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"sending file_sum\n");
|
||||
write_buf(f,file_sum,MD4_SUM_LENGTH);
|
||||
if (write_batch) /* dw */
|
||||
write_batch_delta_file(file_sum, MD4_SUM_LENGTH);
|
||||
/* If we had a read error, send a bad checksum. We use all bits
|
||||
* off as long as the checksum doesn't happen to be that, in
|
||||
* which case we turn the last 0 bit into a 1. */
|
||||
if (buf && buf->status != 0) {
|
||||
int i;
|
||||
for (i = 0; i < checksum_len && sender_file_sum[i] == 0; i++) {}
|
||||
memset(sender_file_sum, 0, checksum_len);
|
||||
if (i == checksum_len)
|
||||
sender_file_sum[i-1]++;
|
||||
}
|
||||
|
||||
if (targets) {
|
||||
free(targets);
|
||||
targets=NULL;
|
||||
if (DEBUG_GTE(DELTASUM, 2))
|
||||
rprintf(FINFO,"sending file_sum\n");
|
||||
write_buf(f, sender_file_sum, checksum_len);
|
||||
|
||||
if (DEBUG_GTE(DELTASUM, 2)) {
|
||||
rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
|
||||
false_alarms, hash_hits, matches);
|
||||
}
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO, "false_alarms=%d tag_hits=%d matches=%d\n",
|
||||
false_alarms, tag_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;
|
||||
@@ -347,12 +438,11 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
|
||||
void match_report(void)
|
||||
{
|
||||
if (verbose <= 1)
|
||||
if (!DEBUG_GTE(DELTASUM, 1))
|
||||
return;
|
||||
|
||||
rprintf(FINFO,
|
||||
"total: matches=%d tag_hits=%d false_alarms=%d data=%.0f\n",
|
||||
total_matches,total_tag_hits,
|
||||
total_false_alarms,
|
||||
(double)stats.literal_data);
|
||||
"total: matches=%d hash_hits=%d false_alarms=%d data=%s\n",
|
||||
total_matches, total_hash_hits, total_false_alarms,
|
||||
big_num(stats.literal_data));
|
||||
}
|
||||
|
||||
76
mkproto.awk
76
mkproto.awk
@@ -1,76 +0,0 @@
|
||||
# generate prototypes for Samba C code
|
||||
# tridge, June 1996
|
||||
|
||||
BEGIN {
|
||||
inheader=0;
|
||||
print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */"
|
||||
print ""
|
||||
}
|
||||
|
||||
{
|
||||
if (inheader) {
|
||||
if (match($0,"[)][ \t]*$")) {
|
||||
inheader = 0;
|
||||
printf "%s;\n",$0;
|
||||
} else {
|
||||
printf "%s\n",$0;
|
||||
}
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
/^FN_LOCAL_BOOL/ {
|
||||
split($0,a,"[,()]")
|
||||
printf "BOOL %s(int );\n", a[2]
|
||||
}
|
||||
|
||||
/^FN_LOCAL_STRING/ {
|
||||
split($0,a,"[,()]")
|
||||
printf "char *%s(int );\n", a[2]
|
||||
}
|
||||
|
||||
/^FN_LOCAL_INT/ {
|
||||
split($0,a,"[,()]")
|
||||
printf "int %s(int );\n", a[2]
|
||||
}
|
||||
|
||||
/^FN_LOCAL_CHAR/ {
|
||||
split($0,a,"[,()]")
|
||||
printf "char %s(int );\n", a[2]
|
||||
}
|
||||
|
||||
/^FN_GLOBAL_BOOL/ {
|
||||
split($0,a,"[,()]")
|
||||
printf "BOOL %s(void);\n", a[2]
|
||||
}
|
||||
|
||||
/^FN_GLOBAL_STRING/ {
|
||||
split($0,a,"[,()]")
|
||||
printf "char *%s(void);\n", a[2]
|
||||
}
|
||||
|
||||
/^FN_GLOBAL_INT/ {
|
||||
split($0,a,"[,()]")
|
||||
printf "int %s(void);\n", a[2]
|
||||
}
|
||||
|
||||
/^static|^extern/ || !/^[a-zA-Z]/ || /[;]/ {
|
||||
next;
|
||||
}
|
||||
|
||||
!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time/ {
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
/[(].*[)][ \t]*$/ {
|
||||
printf "%s;\n",$0;
|
||||
next;
|
||||
}
|
||||
|
||||
/[(]/ {
|
||||
inheader=1;
|
||||
printf "%s\n",$0;
|
||||
next;
|
||||
}
|
||||
|
||||
48
mkproto.pl
Normal file
48
mkproto.pl
Normal file
@@ -0,0 +1,48 @@
|
||||
# generate prototypes for rsync
|
||||
|
||||
$old_protos = '';
|
||||
if (open(IN, 'proto.h')) {
|
||||
$old_protos = join('', <IN>);
|
||||
close IN;
|
||||
}
|
||||
|
||||
%FN_MAP = (
|
||||
BOOL => 'BOOL ',
|
||||
CHAR => 'char ',
|
||||
INTEGER => 'int ',
|
||||
STRING => 'char *',
|
||||
);
|
||||
|
||||
$inheader = 0;
|
||||
$protos = qq|/* This file is automatically generated with "make proto". DO NOT EDIT */\n\n|;
|
||||
|
||||
while (<>) {
|
||||
if ($inheader) {
|
||||
if (/[)][ \t]*$/) {
|
||||
$inheader = 0;
|
||||
s/$/;/;
|
||||
}
|
||||
$protos .= $_;
|
||||
} elsif (/^FN_(LOCAL|GLOBAL)_([^(]+)\(([^,()]+)/) {
|
||||
$ret = $FN_MAP{$2};
|
||||
$func = $3;
|
||||
$arg = $1 eq 'LOCAL' ? 'int module_id' : 'void';
|
||||
$protos .= "$ret$func($arg);\n";
|
||||
} elsif (/^static|^extern/ || /[;]/ || !/^[A-Za-z][A-Za-z0-9_]* /) {
|
||||
;
|
||||
} elsif (/[(].*[)][ \t]*$/) {
|
||||
s/$/;/;
|
||||
$protos .= $_;
|
||||
} elsif (/[(]/) {
|
||||
$inheader = 1;
|
||||
$protos .= $_;
|
||||
}
|
||||
}
|
||||
|
||||
if ($old_protos ne $protos) {
|
||||
open(OUT, '>proto.h') or die $!;
|
||||
print OUT $protos;
|
||||
close OUT;
|
||||
}
|
||||
|
||||
open(OUT, '>proto.h-tstamp') and close OUT;
|
||||
6
packaging/bin/gpg
Executable file
6
packaging/bin/gpg
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh -e
|
||||
# This script gets git to run gpg with a --passphrase-file option.
|
||||
|
||||
PATH=`echo $PATH | sed 's/^[^:]*://'`
|
||||
|
||||
gpg --batch --passphrase-file=$GPG_PASSFILE "${@}"
|
||||
180
packaging/branch-from-patch
Executable file
180
packaging/branch-from-patch
Executable file
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
||||
&Getopt::Long::Configure('bundling');
|
||||
&usage if !&GetOptions(
|
||||
'branch|b=s' => \( my $master_branch = 'master' ),
|
||||
'skip-check' => \( my $skip_branch_check ),
|
||||
'delete' => \( my $delete_local_branches ),
|
||||
'help|h' => \( my $help_opt ),
|
||||
);
|
||||
&usage if $help_opt;
|
||||
|
||||
require 'packaging/git-status.pl';
|
||||
check_git_state($master_branch, !$skip_branch_check, 1);
|
||||
|
||||
my %local_branch;
|
||||
open PIPE, '-|', 'git branch -l' or die "Unable to fork: $!\n";
|
||||
while (<PIPE>) {
|
||||
if (m# patch/\Q$master_branch\E/(.*)#o) {
|
||||
$local_branch{$1} = 1;
|
||||
}
|
||||
}
|
||||
close PIPE;
|
||||
|
||||
if ($delete_local_branches) {
|
||||
foreach my $name (sort keys %local_branch) {
|
||||
my $branch = "patch/$master_branch/$name";
|
||||
system 'git', 'branch', '-D', $branch and exit 1;
|
||||
}
|
||||
%local_branch = ( );
|
||||
}
|
||||
|
||||
my @patch_list;
|
||||
foreach (@ARGV) {
|
||||
if (!-f $_) {
|
||||
die "File not found: $_\n";
|
||||
}
|
||||
die "Filename is not a .diff file: $_\n" unless /\.diff$/;
|
||||
push @patch_list, $_;
|
||||
}
|
||||
|
||||
exit unless @patch_list;
|
||||
|
||||
my(%scanned, %created, %info);
|
||||
|
||||
foreach my $patch (@patch_list) {
|
||||
my($where, $name) = $patch =~ m{^(.*?)([^/]+)\.diff$};
|
||||
next if $scanned{$name}++;
|
||||
|
||||
open IN, '<', $patch or die "Unable to open $patch: $!\n";
|
||||
|
||||
my $info = '';
|
||||
my $commit;
|
||||
while (<IN>) {
|
||||
if (m#^based-on: (\S+)#) {
|
||||
$commit = $1;
|
||||
last;
|
||||
}
|
||||
last if m#^index .*\.\..* \d#;
|
||||
last if m#^diff --git #;
|
||||
last if m#^--- (old|a)/#;
|
||||
$info .= $_;
|
||||
}
|
||||
close IN;
|
||||
|
||||
$info =~ s/\s+\Z/\n/;
|
||||
|
||||
my $parent = $master_branch;
|
||||
my @patches = $info =~ m#patch -p1 <patches/(\S+)\.diff#g;
|
||||
if (@patches) {
|
||||
if ($patches[-1] eq $name) {
|
||||
pop @patches;
|
||||
} else {
|
||||
warn "No identity patch line in $patch\n";
|
||||
}
|
||||
if (@patches) {
|
||||
$parent = pop @patches;
|
||||
if (!$scanned{$parent}) {
|
||||
unless (-f "$where$parent.diff") {
|
||||
die "Unknown parent of $patch: $parent\n";
|
||||
}
|
||||
# Add parent to @patch_list so that we will look for the
|
||||
# parent's parent. Any duplicates will just be ignored.
|
||||
push @patch_list, "$where$parent.diff";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn "No patch lines found in $patch\n";
|
||||
}
|
||||
|
||||
$info{$name} = [ $parent, $info, $commit ];
|
||||
}
|
||||
|
||||
foreach my $patch (@patch_list) {
|
||||
create_branch($patch);
|
||||
}
|
||||
|
||||
system 'git', 'checkout', $master_branch and exit 1;
|
||||
|
||||
exit;
|
||||
|
||||
sub create_branch
|
||||
{
|
||||
my($patch) = @_;
|
||||
my($where, $name) = $patch =~ m{^(.*?)([^/]+)\.diff$};
|
||||
|
||||
return if $created{$name}++;
|
||||
|
||||
my $ref = $info{$name};
|
||||
my($parent, $info, $commit) = @$ref;
|
||||
|
||||
my $parent_branch;
|
||||
if ($parent eq $master_branch) {
|
||||
$parent_branch = $master_branch;
|
||||
$parent_branch = $commit if defined $commit;
|
||||
} else {
|
||||
create_branch("$where/$parent.diff");
|
||||
$parent_branch = "patch/$master_branch/$parent";
|
||||
}
|
||||
|
||||
my $branch = "patch/$master_branch/$name";
|
||||
print "\n", '=' x 64, "\nProcessing $branch ($parent_branch)\n";
|
||||
|
||||
if ($local_branch{$name}) {
|
||||
system 'git', 'branch', '-D', $branch and exit 1;
|
||||
}
|
||||
|
||||
system 'git', 'checkout', '-b', $branch, $parent_branch and exit 1;
|
||||
|
||||
open OUT, '>', "PATCH.$name" or die $!;
|
||||
print OUT $info;
|
||||
close OUT;
|
||||
system 'git', 'add', "PATCH.$name" and exit 1;
|
||||
|
||||
open IN, '<', $patch or die "Unable to open $patch: $!\n";
|
||||
$_ = join('', <IN>);
|
||||
close IN;
|
||||
|
||||
open PIPE, '|-', 'patch -p1' or die $!;
|
||||
print PIPE $_;
|
||||
close PIPE;
|
||||
|
||||
system 'rm -f *.orig */*.orig';
|
||||
|
||||
while (m#\nnew file mode (\d+)\s+--- /dev/null\s+\Q+++\E b/(.*)#g) {
|
||||
chmod oct($1), $2;
|
||||
system 'git', 'add', $2;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
system 'git status';
|
||||
print 'Press Enter to commit, Ctrl-C to abort, or type a wild-name to add a new file: ';
|
||||
$_ = <STDIN>;
|
||||
last if /^$/;
|
||||
chomp;
|
||||
system "git add $_";
|
||||
}
|
||||
|
||||
while (system 'git', 'commit', '-a', '-m', "Creating branch from $name.diff.") {
|
||||
exit 1 if system '/bin/zsh';
|
||||
}
|
||||
}
|
||||
|
||||
sub usage
|
||||
{
|
||||
die <<EOT;
|
||||
Usage branch-from-patch [OPTIONS] patches/DIFF...
|
||||
|
||||
Options:
|
||||
-b, --branch=BRANCH Create branches relative to BRANCH if no "based-on"
|
||||
header was found in the patch file.
|
||||
--skip-check Skip the check that ensures starting with a clean branch.
|
||||
--delete Delete all the local patch/BASE/* branches, not just the ones
|
||||
that are being recreated.
|
||||
-h, --help Output this help message.
|
||||
EOT
|
||||
}
|
||||
83
packaging/cull_options
Executable file
83
packaging/cull_options
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/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;
|
||||
our %short_with_num;
|
||||
our %long_opt = ( # These include some extra long-args that BackupPC uses:
|
||||
'block-size' => 1,
|
||||
'daemon' => -1,
|
||||
'debug' => 1,
|
||||
'fake-super' => 0,
|
||||
'fuzzy' => 0,
|
||||
'group' => 0,
|
||||
'hard-links' => 0,
|
||||
'ignore-times' => 0,
|
||||
'info' => 1,
|
||||
'links' => 0,
|
||||
'log-file' => 3,
|
||||
'one-file-system' => 0,
|
||||
'owner' => 0,
|
||||
'perms' => 0,
|
||||
'recursive' => 0,
|
||||
'times' => 0,
|
||||
);
|
||||
our $last_long_opt;
|
||||
|
||||
open(IN, '../options.c') or die "Unable to open ../options.c: $!\n";
|
||||
|
||||
while (<IN>) {
|
||||
if (/\Qargstr[x++]\E = '([^.ie])'/) {
|
||||
$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 unless exists $long_opt{$1};
|
||||
} 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 = 's';
|
||||
|
||||
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-|min-)/;
|
||||
$val = 3 if $opt eq 'files-from';
|
||||
$val = '$ro ? -1 : ' . $val if $opt =~ /^remove-/;
|
||||
print " '$opt' => $val,\n";
|
||||
}
|
||||
|
||||
print ");\n\n";
|
||||
51
packaging/git-status.pl
Normal file
51
packaging/git-status.pl
Normal file
@@ -0,0 +1,51 @@
|
||||
# Do some git-status checking for the current dir and (optionally)
|
||||
# the patches dir.
|
||||
|
||||
sub check_git_state
|
||||
{
|
||||
my($master_branch, $fatal_unless_clean, $check_patches_dir) = @_;
|
||||
|
||||
my($cur_branch) = check_git_status($fatal_unless_clean);
|
||||
(my $branch = $cur_branch) =~ s{^patch/([^/]+)/[^/]+$}{$1}; # change patch/BRANCH/PATCH_NAME into BRANCH
|
||||
if ($branch ne $master_branch) {
|
||||
print "The checkout is not on the $master_branch branch.\n";
|
||||
exit 1 if $master_branch ne 'master';
|
||||
print "Do you want me to continue with --branch=$branch? [n] ";
|
||||
$_ = <STDIN>;
|
||||
exit 1 unless /^y/i;
|
||||
$_[0] = $master_branch = $branch; # Updates caller's $master_branch too.
|
||||
}
|
||||
|
||||
if ($check_patches_dir && -d 'patches/.git') {
|
||||
($branch) = check_git_status($fatal_unless_clean, 'patches');
|
||||
if ($branch ne $master_branch) {
|
||||
print "The *patches* checkout is on branch $branch, not branch $master_branch.\n";
|
||||
print "Do you want to change it to branch $master_branch? [n] ";
|
||||
$_ = <STDIN>;
|
||||
exit 1 unless /^y/i;
|
||||
system "cd patches && git checkout '$master_branch'";
|
||||
}
|
||||
}
|
||||
|
||||
return $cur_branch;
|
||||
}
|
||||
|
||||
sub check_git_status
|
||||
{
|
||||
my($fatal_unless_clean, $subdir) = @_;
|
||||
$subdir = '.' unless defined $subdir;
|
||||
my $status = `cd '$subdir' && git status`;
|
||||
my $is_clean = $status =~ /\nnothing to commit.+working directory clean/;
|
||||
my($cur_branch) = $status =~ /^(?:# )?On branch (.+)\n/;
|
||||
if ($fatal_unless_clean && !$is_clean) {
|
||||
if ($subdir eq '.') {
|
||||
$subdir = '';
|
||||
} else {
|
||||
$subdir = " *$subdir*";
|
||||
}
|
||||
die "The$subdir checkout is not clean:\n", $status;
|
||||
}
|
||||
($cur_branch, $is_clean, $status);
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,84 +1,99 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Summary: A fast, versatile, remote (and local) file-copying tool
|
||||
Name: rsync
|
||||
Version: 2.5.6
|
||||
Version: 3.1.2
|
||||
%define fullversion %{version}
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.6.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
%define srcdir src
|
||||
Group: Applications/Internet
|
||||
License: GPL
|
||||
Source0: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-%{fullversion}.tar.gz
|
||||
#Source1: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-patches-%{fullversion}.tar.gz
|
||||
URL: http://rsync.samba.org/
|
||||
|
||||
Prefix: %{_prefix}
|
||||
BuildRoot: /var/tmp/%{name}-root
|
||||
|
||||
%package ssl-client
|
||||
Summary: Provides rsync-ssl
|
||||
Group: Applications/Internet
|
||||
Requires: rsync, stunnel >= 4
|
||||
|
||||
%package ssl-daemon
|
||||
Summary: An stunnel config file to support ssl rsync daemon connections.
|
||||
Group: Applications/Internet
|
||||
Requires: rsync, stunnel >= 4
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
Rsync is a fast and extraordinarily versatile file copying tool. It can
|
||||
copy locally, to/from another host over any remote shell, or to/from a
|
||||
remote rsync daemon. It offers a large number of options that control
|
||||
every aspect of its behavior and permit very flexible specification of the
|
||||
set of files to be copied. It is famous for its delta-transfer algorithm,
|
||||
which reduces the amount of data sent over the network by sending only the
|
||||
differences between the source files and the existing files in the
|
||||
destination. Rsync is widely used for backups and mirroring and as an
|
||||
improved copy command for everyday use.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
%description ssl-client
|
||||
Provides the rsync-ssl script that makes use of stunnel 4 to open an ssl
|
||||
connection to an rsync daemon (on port 874). This setup does NOT require
|
||||
any local stunnel daemon to be running to connect to the remote ssl rsyncd.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
|
||||
Changed target paths to be Linux Standards Base compliant
|
||||
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
%description ssl-daemon
|
||||
Provides a config file for stunnel that will (if you start your stunnel
|
||||
service) cause stunnel to listen for ssl rsync-daemon connections and run
|
||||
"rsync --daemon" to handle them.
|
||||
|
||||
%prep
|
||||
%setup
|
||||
# Choose one -- setup source only, or setup source + rsync-patches:
|
||||
%setup -q -n rsync-%{fullversion}
|
||||
#%setup -q -b1 -n rsync-%{fullversion}
|
||||
|
||||
# If you you used "%setup -q -b1 ...", choose the patches you wish to apply:
|
||||
#patch -p1 <patches/acls.diff
|
||||
#patch -p1 <patches/xattrs.diff
|
||||
#patch -p1 <patches/remote-option.diff
|
||||
#patch -p1 <patches/db.diff
|
||||
|
||||
# Avoid extra perl dependencies for scripts going into doc dir.
|
||||
chmod -x support/*
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr --mandir=/usr/share/man
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
#./prepare-source
|
||||
%configure
|
||||
|
||||
make
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
|
||||
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make install install-ssl-client install-ssl-daemon DESTDIR=$RPM_BUILD_ROOT
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d $RPM_BUILD_ROOT/etc/rsync-ssl/certs
|
||||
install -m 644 packaging/lsb/rsync.xinetd $RPM_BUILD_ROOT/etc/xinetd.d/rsync
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/share/man/man1/rsync.1
|
||||
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
%defattr(-,root,root)
|
||||
%doc COPYING NEWS OLDNEWS README support/ tech_report.tex
|
||||
%config(noreplace) /etc/xinetd.d/rsync
|
||||
%{_prefix}/bin/rsync
|
||||
%{_mandir}/man1/rsync.1*
|
||||
%{_mandir}/man5/rsyncd.conf.5*
|
||||
|
||||
%files ssl-client
|
||||
%{_prefix}/bin/rsync-ssl
|
||||
%{_prefix}/bin/stunnel-rsync
|
||||
|
||||
%files ssl-daemon
|
||||
%config(noreplace) /etc/stunnel/rsyncd.conf
|
||||
%dir /etc/rsync-ssl/certs
|
||||
|
||||
%changelog
|
||||
* Mon Dec 21 2015 Wayne Davison <wayned@samba.org>
|
||||
Released 3.1.2.
|
||||
|
||||
* Fri Mar 21 2008 Wayne Davison <wayned@samba.org>
|
||||
Added installation of /etc/xinetd.d/rsync file and some commented-out
|
||||
lines that demonstrate how to use the rsync-patches tar file.
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: PVERSION
|
||||
Release: PRELEASE
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
|
||||
Changed target paths to be Linux Standards Base compliant
|
||||
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr --mandir=/usr/share/man
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
|
||||
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/share/man/man1/rsync.1
|
||||
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
13
packaging/lsb/rsync.xinetd
Normal file
13
packaging/lsb/rsync.xinetd
Normal file
@@ -0,0 +1,13 @@
|
||||
# default: off
|
||||
# description: The rsync server is a good addition to an ftp server, as it
|
||||
# allows crc checksumming etc.
|
||||
service rsync
|
||||
{
|
||||
disable = yes
|
||||
socket_type = stream
|
||||
wait = no
|
||||
user = root
|
||||
server = /usr/bin/rsync
|
||||
server_args = --daemon
|
||||
log_on_failure += USERID
|
||||
}
|
||||
174
packaging/nightly-rsync
Executable file
174
packaging/nightly-rsync
Executable file
@@ -0,0 +1,174 @@
|
||||
#!/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
|
||||
# git checkout of rsync (feel free to use your normal rsync build dir as
|
||||
# long as it doesn't have any uncommitted 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;
|
||||
|
||||
# Where the local copy of /home/ftp/pub/rsync/dev/nightly should be updated.
|
||||
our $dest = $ENV{HOME} . '/samba-rsync-ftp/dev/nightly';
|
||||
our $samba_host = $ENV{SAMBA_HOST} || 'samba.org';
|
||||
our $nightly_symlink = "$dest/rsync-HEAD.tar.gz";
|
||||
|
||||
our($make_tar, $upload, $help_opt);
|
||||
&Getopt::Long::Configure('bundling');
|
||||
&usage if !&GetOptions(
|
||||
'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;
|
||||
our $gen_target = $upload ? 'gensend' : 'gen';
|
||||
|
||||
die "$dest does not exist\n" unless -d $dest;
|
||||
die "There is no .git dir in the current directory.\n" unless -d '.git';
|
||||
die "There is no rsync checkout in the current directory.\n" unless -f 'rsyncd.conf.yo';
|
||||
|
||||
if ($make_tar) {
|
||||
open(IN, '-|', 'git status') or die $!;
|
||||
my $status = join('', <IN>);
|
||||
close IN;
|
||||
die "The checkout is not clean:\n", $status unless $status =~ /\nnothing to commit.+working directory clean/;
|
||||
die "The checkout is not on the master branch.\n" unless $status =~ /^(?:# )?On branch master\n/;
|
||||
system "make $gen_target" and die "make $gen_target failed!\n";
|
||||
|
||||
my @extra_files;
|
||||
open(IN, '<', 'Makefile.in') or die "Couldn't open Makefile.in: $!\n";
|
||||
while (<IN>) {
|
||||
if (s/^GENFILES=//) {
|
||||
while (s/\\$//) {
|
||||
$_ .= <IN>;
|
||||
}
|
||||
@extra_files = split(' ', $_);
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
|
||||
my $confversion;
|
||||
open(IN, '<', 'configure.ac') or die "Unable to open configure.ac: $!\n";
|
||||
while (<IN>) {
|
||||
if (/^AC_INIT\(\[rsync\],\s*\[(\d.+?)\]/) {
|
||||
$confversion = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
die "Unable to find AC_INIT with version in configure.ac\n" unless defined $confversion;
|
||||
|
||||
open(IN, '<', 'OLDNEWS') or die "Unable to open OLDNEWS: $!\n";
|
||||
$_ = <IN>;
|
||||
my($lastversion) = /(\d+\.\d+\.\d+)/;
|
||||
my $last_protocol_version;
|
||||
while (<IN>) {
|
||||
if (my($ver,$pdate,$pver) = /^\s+\S\S\s\S\S\S\s\d\d\d\d\s+(\d+\.\d+\.\d+)\s+(\d\d \w\w\w \d\d\d\d\s+)?(\d+)$/) {
|
||||
$last_protocol_version = $pver if $ver eq $lastversion;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
die "Unable to determine protocol_version for $lastversion.\n" unless defined $last_protocol_version;
|
||||
|
||||
my($protocol_version,$subprotocol_version);
|
||||
open(IN, '<', 'rsync.h') or die "Unable to open rsync.h: $!\n";
|
||||
while (<IN>) {
|
||||
if (/^#define\s+PROTOCOL_VERSION\s+(\d+)/) {
|
||||
$protocol_version = $1;
|
||||
} elsif (/^#define\s+SUBPROTOCOL_VERSION\s+(\d+)/) {
|
||||
$subprotocol_version = $1;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
die "Unable to determine the current PROTOCOL_VERSION.\n" unless defined $protocol_version;
|
||||
die "Unable to determine the current SUBPROTOCOL_VERSION.\n" unless defined $subprotocol_version;
|
||||
|
||||
if ($confversion =~ /dev|pre/) {
|
||||
if ($last_protocol_version ne $protocol_version) {
|
||||
if ($subprotocol_version == 0) {
|
||||
die "SUBPROTOCOL_VERSION must not be 0 for a non-final release with a changed PROTOCOL_VERSION.\n";
|
||||
}
|
||||
} else {
|
||||
if ($subprotocol_version != 0) {
|
||||
die "SUBPROTOCOL_VERSION must be 0 when the PROTOCOL_VERSION hasn't changed from the last release.\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($subprotocol_version != 0) {
|
||||
die "SUBPROTOCOL_VERSION must be 0 for a final release.\n";
|
||||
}
|
||||
}
|
||||
|
||||
print "Creating $name.tar.gz\n";
|
||||
system "rsync -a @extra_files $name/";
|
||||
system "git archive --format=tar --prefix=$name/ HEAD | tar xf -";
|
||||
system "support/git-set-file-times --prefix=$name/";
|
||||
system "fakeroot tar czf $dest/$name.tar.gz $name; rm -rf $name";
|
||||
|
||||
unlink($nightly_symlink);
|
||||
symlink("$name.tar.gz", $nightly_symlink);
|
||||
}
|
||||
|
||||
foreach my $fn (qw( rsync.yo rsyncd.conf.yo )) {
|
||||
my $yo_tmp = "$dest/$fn";
|
||||
(my $html_fn = "$dest/$fn") =~ s/\.yo/.html/;
|
||||
|
||||
open(IN, '<', $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, '>', $yo_tmp) or die $!;
|
||||
print OUT $_;
|
||||
close OUT;
|
||||
|
||||
system 'yodl2html', '-o', $html_fn, $yo_tmp;
|
||||
|
||||
unlink($yo_tmp);
|
||||
}
|
||||
|
||||
chdir($dest) or die $!;
|
||||
|
||||
my $cnt = 0;
|
||||
open(PIPE, '-|', 'ls -1t rsync-HEAD-*') or die $!;
|
||||
while (<PIPE>) {
|
||||
chomp;
|
||||
next if $cnt++ < 10;
|
||||
unlink($_);
|
||||
}
|
||||
close PIPE;
|
||||
|
||||
system 'ls -ltr';
|
||||
|
||||
if ($upload) {
|
||||
my $opt = '';
|
||||
if (defined $ENV{RSYNC_PARTIAL_DIR}) {
|
||||
$opt = " -f 'R $ENV{RSYNC_PARTIAL_DIR}'";
|
||||
}
|
||||
system "rsync$opt -aviHP --delete-after . $samba_host\:/home/ftp/pub/rsync/dev/nightly";
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
sub usage
|
||||
{
|
||||
die <<EOT;
|
||||
Usage: nightly-rsync [OPTIONS]
|
||||
|
||||
-t, --make-tar create a new tar file in $dest
|
||||
-u, --upload upload the revised nightly dir to samba.org
|
||||
-h, --help display this help
|
||||
EOT
|
||||
}
|
||||
242
packaging/patch-update
Executable file
242
packaging/patch-update
Executable file
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/perl
|
||||
# This script is used to turn one or more of the "patch/BASE/*" branches
|
||||
# into one or more diffs in the "patches" directory. Pass the option
|
||||
# --gen if you want generated files in the diffs. Pass the name of
|
||||
# one or more diffs if you want to just update a subset of all the
|
||||
# diffs.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
||||
my $patches_dir = 'patches';
|
||||
my $tmp_dir = "patches.$$";
|
||||
my $make_gen_cmd = 'make -f prepare-source.mak conf && ./config.status && make gen';
|
||||
|
||||
&Getopt::Long::Configure('bundling');
|
||||
&usage if !&GetOptions(
|
||||
'branch|b=s' => \( my $master_branch = 'master' ),
|
||||
'skip-check' => \( my $skip_branch_check ),
|
||||
'shell|s' => \( my $launch_shell ),
|
||||
'gen:s' => \( my $incl_generated_files ),
|
||||
'help|h' => \( my $help_opt ),
|
||||
);
|
||||
&usage if $help_opt;
|
||||
|
||||
$ENV{GIT_MERGE_AUTOEDIT} = 'no';
|
||||
|
||||
if (defined $incl_generated_files) {
|
||||
$patches_dir = $incl_generated_files if $incl_generated_files ne '';
|
||||
$incl_generated_files = 1;
|
||||
}
|
||||
|
||||
die "No '$patches_dir' directory was found.\n" unless -d $patches_dir;
|
||||
die "No '.git' directory present in the current dir.\n" unless -d '.git';
|
||||
|
||||
require 'packaging/git-status.pl';
|
||||
my $starting_branch = check_git_state($master_branch, !$skip_branch_check, 1);
|
||||
|
||||
my $master_commit;
|
||||
open PIPE, '-|', "git log -1 --no-color $master_branch" or die $!;
|
||||
while (<PIPE>) {
|
||||
if (/^commit (\S+)/) {
|
||||
$master_commit = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close PIPE;
|
||||
die "Unable to determine commit hash for master branch: $master_branch\n" unless defined $master_commit;
|
||||
|
||||
if ($incl_generated_files) {
|
||||
my @extra_files = get_extra_files();
|
||||
die "'$tmp_dir' must not exist in the current directory.\n" if -e $tmp_dir;
|
||||
mkdir($tmp_dir, 0700) or die "Unable to mkdir($tmp_dir): $!\n";
|
||||
system "$make_gen_cmd && rsync -a @extra_files $tmp_dir/master/" and exit 1;
|
||||
}
|
||||
our $last_touch = time;
|
||||
|
||||
my %patches;
|
||||
|
||||
# Start by finding all patches so that we can load all possible parents.
|
||||
open(PIPE, '-|', 'git', 'branch', '-l') or die $!;
|
||||
while (<PIPE>) {
|
||||
if (m# patch/\Q$master_branch\E/(.*)#o) {
|
||||
$patches{$1} = 1;
|
||||
}
|
||||
}
|
||||
close PIPE;
|
||||
|
||||
my @patches = sort keys %patches;
|
||||
|
||||
my(%parent, %description);
|
||||
foreach my $patch (@patches) {
|
||||
my $branch = "patch/$master_branch/$patch";
|
||||
my $desc = '';
|
||||
open(PIPE, '-|', 'git', 'diff', '-U1000', "$master_branch...$branch", '--', "PATCH.$patch") or die $!;
|
||||
while (<PIPE>) {
|
||||
last if /^@@ /;
|
||||
}
|
||||
while (<PIPE>) {
|
||||
next unless s/^[ +]//;
|
||||
if (m#patch -p1 <patches/(\S+)\.diff# && $1 ne $patch) {
|
||||
my $parent = $parent{$patch} = $1;
|
||||
if (!$patches{$parent}) {
|
||||
die "Parent of $patch is not a local branch: $parent\n";
|
||||
}
|
||||
}
|
||||
$desc .= $_;
|
||||
}
|
||||
close PIPE;
|
||||
$description{$patch} = $desc;
|
||||
}
|
||||
|
||||
if (@ARGV) {
|
||||
# Limit the list of patches to actually process based on @ARGV.
|
||||
@patches = ( );
|
||||
foreach (@ARGV) {
|
||||
s{^patch(es)?/} {};
|
||||
s{\.diff$} {};
|
||||
if (!$patches{$_}) {
|
||||
die "Local branch not available for patch: $_\n";
|
||||
}
|
||||
push(@patches, $_);
|
||||
}
|
||||
}
|
||||
|
||||
my %completed;
|
||||
foreach my $patch (@patches) {
|
||||
next if $completed{$patch}++;
|
||||
last unless update_patch($patch);
|
||||
}
|
||||
|
||||
if ($incl_generated_files) {
|
||||
system "rm -rf $tmp_dir";
|
||||
}
|
||||
|
||||
sleep 1 while $last_touch >= time;
|
||||
system "git checkout $starting_branch" and exit 1;
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
sub update_patch
|
||||
{
|
||||
my($patch) = @_;
|
||||
|
||||
my $parent = $parent{$patch};
|
||||
my $based_on;
|
||||
if (defined $parent) {
|
||||
unless ($completed{$parent}++) {
|
||||
update_patch($parent);
|
||||
}
|
||||
$based_on = $parent = "patch/$master_branch/$parent";
|
||||
} else {
|
||||
$parent = $master_branch;
|
||||
$based_on = $master_commit;
|
||||
}
|
||||
|
||||
print "======== $patch ========\n";
|
||||
|
||||
sleep 1 while $incl_generated_files && $last_touch >= time;
|
||||
system "git checkout patch/$master_branch/$patch" and return 0;
|
||||
|
||||
my $ok = system("git merge $based_on") == 0;
|
||||
if (!$ok || $launch_shell) {
|
||||
my($parent_dir) = $parent =~ m{([^/]+)$};
|
||||
print qq|"git merge $based_on" incomplete -- please fix.\n| if !$ok;
|
||||
$ENV{PS1} = "[$parent_dir] $patch: ";
|
||||
while (1) {
|
||||
if (system($ENV{SHELL}) != 0) {
|
||||
print "Abort? [n/y] ";
|
||||
$_ = <STDIN>;
|
||||
next unless /^y/i;
|
||||
return 0;
|
||||
}
|
||||
my($cur_branch, $is_clean, $status) = check_git_status(0);
|
||||
last if $is_clean;
|
||||
print $status;
|
||||
}
|
||||
}
|
||||
|
||||
open(OUT, '>', "$patches_dir/$patch.diff") or die $!;
|
||||
print OUT $description{$patch}, "\nbased-on: $based_on\n";
|
||||
|
||||
my @extra_files;
|
||||
if ($incl_generated_files) {
|
||||
@extra_files = get_extra_files();
|
||||
system "$make_gen_cmd && rsync -a @extra_files $tmp_dir/$patch/" and exit 1;
|
||||
}
|
||||
$last_touch = time;
|
||||
|
||||
open(PIPE, '-|', 'git', 'diff', $based_on) or die $!;
|
||||
DIFF: while (<PIPE>) {
|
||||
while (m{^diff --git a/PATCH}) {
|
||||
while (<PIPE>) {
|
||||
last if m{^diff --git a/};
|
||||
}
|
||||
last DIFF if !defined $_;
|
||||
}
|
||||
next if /^index /;
|
||||
print OUT $_;
|
||||
}
|
||||
close PIPE;
|
||||
|
||||
if ($incl_generated_files) {
|
||||
my $parent_dir;
|
||||
if ($parent eq $master_branch) {
|
||||
$parent_dir = 'master';
|
||||
} else {
|
||||
($parent_dir) = $parent =~ m{([^/]+)$};
|
||||
}
|
||||
open(PIPE, '-|', 'diff', '-Nurp', "$tmp_dir/$parent_dir", "$tmp_dir/$patch") or die $!;
|
||||
while (<PIPE>) {
|
||||
s#^(diff -Nurp) $tmp_dir/[^/]+/(.*?) $tmp_dir/[^/]+/(.*)#$1 a/$2 b/$3#o;
|
||||
s#^\Q---\E $tmp_dir/[^/]+/([^\t]+)\t.*#--- a/$1#o;
|
||||
s#^\Q+++\E $tmp_dir/[^/]+/([^\t]+)\t.*#+++ b/$1#o;
|
||||
print OUT $_;
|
||||
}
|
||||
close PIPE;
|
||||
unlink @extra_files;
|
||||
}
|
||||
|
||||
close OUT;
|
||||
|
||||
1;
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
sub get_extra_files
|
||||
{
|
||||
my @extras;
|
||||
|
||||
open(IN, '<', 'Makefile.in') or die "Couldn't open Makefile.in: $!\n";
|
||||
while (<IN>) {
|
||||
if (s/^GENFILES=//) {
|
||||
while (s/\\$//) {
|
||||
$_ .= <IN>;
|
||||
}
|
||||
@extras = split(' ', $_);
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
|
||||
return @extras;
|
||||
}
|
||||
|
||||
sub usage
|
||||
{
|
||||
die <<EOT;
|
||||
Usage: patch-update [OPTIONS] [patches/DIFF...]
|
||||
|
||||
Options:
|
||||
-b, --branch=BRANCH The master branch to merge into the patch/BASE/* branches.
|
||||
--gen[=DIR] Include generated files. Optional destination DIR
|
||||
arg overrides the default of using the "patches" dir.
|
||||
--skip-check Skip the check that ensures starting with a clean branch.
|
||||
-s, --shell Launch a shell for every patch/BASE/* branch updated, not
|
||||
just when a conflict occurs.
|
||||
-h, --help Output this help message.
|
||||
EOT
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.5.6
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.6.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/man/man1
|
||||
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/man/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/man/man1/rsync.1
|
||||
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
@@ -1,81 +0,0 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: PVERSION
|
||||
Release: PRELEASE
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/man/man1
|
||||
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/man/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/man/man1/rsync.1
|
||||
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
@@ -1,81 +0,0 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.5.6
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.6.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
|
||||
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/man/man1/rsync.1*
|
||||
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
@@ -1,81 +0,0 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: PVERSION
|
||||
Release: PRELEASE
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
%description
|
||||
rsync is a replacement for rcp that has many more features.
|
||||
|
||||
rsync uses the "rsync algorithm" which provides a very fast method for
|
||||
bringing remote files into sync. It does this by sending just the
|
||||
differences in the files across the link, without requiring that both
|
||||
sets of files are present at one of the ends of the link beforehand.
|
||||
|
||||
A technical report describing the rsync algorithm is included with
|
||||
this package.
|
||||
|
||||
%changelog
|
||||
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
|
||||
quoted RPM_OPT_FLAGS for the sake of robustness
|
||||
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
|
||||
|
||||
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
|
||||
Upgraded to Rsync 2.0.6
|
||||
-new feature anonymous rsync
|
||||
|
||||
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Upgrade to rsync version 1.7.2.
|
||||
|
||||
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
|
||||
|
||||
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
|
||||
Changes from 1.6.3-2 packaging: added latex and dvips commands
|
||||
to create tech_report.ps.
|
||||
|
||||
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
|
||||
|
||||
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
|
||||
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
|
||||
showing no packager nor signature but giving
|
||||
"Source RPM: rsync-1.6.3-1.src.rpm".
|
||||
|
||||
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
|
||||
to '%build', removed '%prefix'.
|
||||
|
||||
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
|
||||
|
||||
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
|
||||
previous package(s).)
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
./configure --prefix=/usr
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
strip rsync
|
||||
|
||||
%install
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
|
||||
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
|
||||
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
|
||||
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%attr(-,root,root) /usr/bin/rsync
|
||||
%attr(-,root,root) /usr/man/man1/rsync.1*
|
||||
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
|
||||
%attr(-,root,root) %doc tech_report.tex
|
||||
%attr(-,root,root) %doc README
|
||||
%attr(-,root,root) %doc COPYING
|
||||
421
packaging/release-rsync
Executable file
421
packaging/release-rsync
Executable file
@@ -0,0 +1,421 @@
|
||||
#!/usr/bin/perl
|
||||
# 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. When the script is done,
|
||||
# the git repository in the current directory will be updated, and the local
|
||||
# ~/samba-rsync-ftp dir will be ready to be rsynced to samba.org.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Cwd;
|
||||
use Getopt::Long;
|
||||
use Term::ReadKey;
|
||||
use Date::Format;
|
||||
|
||||
my $dest = $ENV{HOME} . '/samba-rsync-ftp';
|
||||
my $passfile = $ENV{HOME} . '/.rsyncpass';
|
||||
my $path = $ENV{PATH};
|
||||
my $make_gen_cmd = 'make -f prepare-source.mak conf && ./config.status && make gen';
|
||||
|
||||
&Getopt::Long::Configure('bundling');
|
||||
&usage if !&GetOptions(
|
||||
'branch|b=s' => \( my $master_branch = 'master' ),
|
||||
'help|h' => \( my $help_opt ),
|
||||
);
|
||||
&usage if $help_opt;
|
||||
|
||||
my $now = time;
|
||||
my $cl_today = time2str('* %a %b %d %Y', $now);
|
||||
my $year = time2str('%Y', $now);
|
||||
my $ztoday = time2str('%d %b %Y', $now);
|
||||
(my $today = $ztoday) =~ s/^0//;
|
||||
|
||||
my $curdir = Cwd::cwd;
|
||||
|
||||
END {
|
||||
unlink($passfile);
|
||||
}
|
||||
|
||||
my @extra_files;
|
||||
open(IN, '<', 'Makefile.in') or die "Couldn't open Makefile.in: $!\n";
|
||||
while (<IN>) {
|
||||
if (s/^GENFILES=//) {
|
||||
while (s/\\$//) {
|
||||
$_ .= <IN>;
|
||||
}
|
||||
@extra_files = split(' ', $_);
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
|
||||
my $break = <<EOT;
|
||||
==========================================================================
|
||||
EOT
|
||||
|
||||
print $break, <<EOT, $break, "\n";
|
||||
== This will release a new version of rsync onto an unsuspecting world. ==
|
||||
EOT
|
||||
|
||||
die "$dest does not exist\n" unless -d $dest;
|
||||
die "There is no .git dir in the current directory.\n" unless -d '.git';
|
||||
die "'a' must not exist in the current directory.\n" if -e 'a';
|
||||
die "'b' must not exist in the current directory.\n" if -e 'b';
|
||||
|
||||
require 'packaging/git-status.pl';
|
||||
check_git_state($master_branch, 1, 1);
|
||||
|
||||
my $confversion;
|
||||
open(IN, '<', 'configure.ac') or die $!;
|
||||
while (<IN>) {
|
||||
if (/^AC_INIT\(\[rsync\],\s*\[(\d.+?)\]/) {
|
||||
$confversion = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
die "Unable to find AC_INIT with version in configure.ac\n" unless defined $confversion;
|
||||
|
||||
open(IN, '<', 'OLDNEWS') or die $!;
|
||||
$_ = <IN>;
|
||||
my($lastversion) = /(\d+\.\d+\.\d+)/;
|
||||
my($last_protocol_version, %pdate);
|
||||
while (<IN>) {
|
||||
if (my($ver,$pdate,$pver) = /^\s+\S\S\s\S\S\S\s\d\d\d\d\s+(\d+\.\d+\.\d+)\s+(\d\d \w\w\w \d\d\d\d\s+)?(\d+)$/) {
|
||||
$pdate{$ver} = $pdate if defined $pdate;
|
||||
$last_protocol_version = $pver if $ver eq $lastversion;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
die "Unable to determine protocol_version for $lastversion.\n" unless defined $last_protocol_version;
|
||||
|
||||
my $protocol_version;
|
||||
open(IN, '<', 'rsync.h') or die $!;
|
||||
while (<IN>) {
|
||||
if (/^#define\s+PROTOCOL_VERSION\s+(\d+)/) {
|
||||
$protocol_version = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close IN;
|
||||
die "Unable to determine the current PROTOCOL_VERSION.\n" unless defined $protocol_version;
|
||||
|
||||
my $version = $confversion;
|
||||
$version =~ s/dev/pre1/ || $version =~ s/pre(\d+)/ 'pre' . ($1 + 1) /e;
|
||||
|
||||
print "Please enter the version number of this release: [$version] ";
|
||||
chomp($_ = <STDIN>);
|
||||
if ($_ eq '.') {
|
||||
$version =~ s/pre\d+//;
|
||||
} elsif ($_ ne '') {
|
||||
$version = $_;
|
||||
}
|
||||
die "Invalid version: `$version'\n" unless $version =~ /^[\d.]+(pre\d+)?$/;
|
||||
|
||||
if (`git tag -l v$version` ne '') {
|
||||
print "Tag v$version already exists.\n\nDelete tag or quit? [q/del] ";
|
||||
$_ = <STDIN>;
|
||||
exit 1 unless /^del/i;
|
||||
system "git tag -d v$version";
|
||||
}
|
||||
|
||||
if ($version =~ s/[-.]*pre[-.]*/pre/ && $confversion !~ /dev$/) {
|
||||
$lastversion = $confversion;
|
||||
}
|
||||
|
||||
print "Enter the previous version to produce a patch against: [$lastversion] ";
|
||||
chomp($_ = <STDIN>);
|
||||
$lastversion = $_ if $_ ne '';
|
||||
$lastversion =~ s/[-.]*pre[-.]*/pre/;
|
||||
|
||||
my $pre = $version =~ /(pre\d+)/ ? $1 : '';
|
||||
|
||||
my $release = $pre ? '0.1' : '1';
|
||||
print "Please enter the RPM release number of this release: [$release] ";
|
||||
chomp($_ = <STDIN>);
|
||||
$release = $_ if $_ ne '';
|
||||
$release .= ".$pre" if $pre;
|
||||
|
||||
(my $finalversion = $version) =~ s/pre\d+//;
|
||||
my($proto_changed,$proto_change_date);
|
||||
if ($protocol_version eq $last_protocol_version) {
|
||||
$proto_changed = 'unchanged';
|
||||
$proto_change_date = "\t\t";
|
||||
} else {
|
||||
$proto_changed = 'changed';
|
||||
if (!defined($proto_change_date = $pdate{$finalversion})) {
|
||||
while (1) {
|
||||
print "On what date did the protocol change to $protocol_version get checked in? (dd Mmm yyyy) ";
|
||||
chomp($_ = <STDIN>);
|
||||
last if /^\d\d \w\w\w \d\d\d\d$/;
|
||||
}
|
||||
$proto_change_date = "$_\t";
|
||||
}
|
||||
}
|
||||
|
||||
my($srcdir,$srcdiffdir,$lastsrcdir,$skipping);
|
||||
if ($lastversion =~ /pre/) {
|
||||
if (!$pre) {
|
||||
die "You should not diff a release version against a pre-release version.\n";
|
||||
}
|
||||
$srcdir = $srcdiffdir = $lastsrcdir = 'src-previews';
|
||||
$skipping = ' ** SKIPPING **';
|
||||
} elsif ($pre) {
|
||||
$srcdir = $srcdiffdir = 'src-previews';
|
||||
$lastsrcdir = 'src';
|
||||
$skipping = ' ** SKIPPING **';
|
||||
} else {
|
||||
$srcdir = $lastsrcdir = 'src';
|
||||
$srcdiffdir = 'src-diffs';
|
||||
$skipping = '';
|
||||
}
|
||||
|
||||
print "\n", $break, <<EOT;
|
||||
\$version is "$version"
|
||||
\$lastversion is "$lastversion"
|
||||
\$dest is "$dest"
|
||||
\$curdir is "$curdir"
|
||||
\$srcdir is "$srcdir"
|
||||
\$srcdiffdir is "$srcdiffdir"
|
||||
\$lastsrcdir is "$lastsrcdir"
|
||||
\$release is "$release"
|
||||
|
||||
About to:
|
||||
- tweak SUBPROTOCOL_VERSION in rsync.h, if needed
|
||||
- tweak the version in configure.ac and the spec files
|
||||
- tweak NEWS and OLDNEWS to ensure header values are correct
|
||||
- tweak the date in the *.yo files and generate the manpages
|
||||
- generate configure.sh, config.h.in, and proto.h
|
||||
- page through the differences
|
||||
|
||||
EOT
|
||||
print "<Press Enter to continue> ";
|
||||
$_ = <STDIN>;
|
||||
|
||||
my %specvars = ( 'Version:' => $finalversion, 'Release:' => $release,
|
||||
'%define fullversion' => "\%{version}$pre", 'Released' => "$version.",
|
||||
'%define srcdir' => $srcdir );
|
||||
my @tweak_files = ( glob('packaging/*.spec'), glob('packaging/*/*.spec'), glob('*.yo'),
|
||||
qw( configure.ac rsync.h NEWS OLDNEWS options.c ) );
|
||||
|
||||
foreach my $fn (@tweak_files) {
|
||||
open(IN, '<', $fn) or die $!;
|
||||
undef $/; $_ = <IN>; $/ = "\n";
|
||||
close IN;
|
||||
if ($fn =~ /configure/) {
|
||||
s/^(AC_INIT\(\[rsync\],\s*\[)\d.+?(\])/$1$version$2/m
|
||||
or die "Unable to update AC_INIT with version in $fn\n";
|
||||
} elsif ($fn =~ /\.spec/) {
|
||||
while (my($str, $val) = each %specvars) {
|
||||
s/^\Q$str\E .*/$str $val/m
|
||||
or die "Unable to update $str in $fn\n";
|
||||
}
|
||||
s/^\* \w\w\w \w\w\w \d\d \d\d\d\d (.*)/$cl_today $1/m
|
||||
or die "Unable to update ChangeLog header in $fn\n";
|
||||
} elsif ($fn =~ /\.yo/) {
|
||||
s/^(manpage\([^)]+\)\(\d+\)\()[^)]+(\).*)/$1$today$2/m
|
||||
or die "Unable to update date in manpage() header in $fn\n";
|
||||
s/^(This man ?page is current for version) \S+ (of rsync)/$1 $version $2/m
|
||||
or die "Unable to update current version info in $fn\n";
|
||||
} elsif ($fn eq 'rsync.h') {
|
||||
s{(#define\s+SUBPROTOCOL_VERSION)\s+(\d+)}
|
||||
{ $1 . ' ' . get_subprotocol_version($2) }e
|
||||
or die "Unable to find SUBPROTOCOL_VERSION define in $fn\n";
|
||||
} elsif ($fn eq 'NEWS') {
|
||||
s{^(NEWS for rsync \Q$finalversion\E )(\(UNRELEASED\))\s*(\nProtocol: )(\d+) (\([^)]+\))\n}
|
||||
{ $1 . ($pre ? $2 : "($today)") . "$3$protocol_version ($proto_changed)\n" }ei
|
||||
or die "The first 2 lines of $fn are not in the right format. They must be:\n"
|
||||
. "NEWS for rsync $finalversion (UNRELEASED)\n"
|
||||
. "Protocol: $protocol_version ($proto_changed)\n";
|
||||
} elsif ($fn eq 'OLDNEWS') {
|
||||
s{^(\t\S\S\s\S\S\S\s\d\d\d\d)(\t\Q$finalversion\E\t).*}
|
||||
{ ($pre ? $1 : "\t$ztoday") . $2 . $proto_change_date . $protocol_version }em
|
||||
or die "Unable to find \"?? ??? $year\t$finalversion\" line in $fn\n";
|
||||
} elsif ($fn eq 'options.c') {
|
||||
if (s/(Copyright \(C\) 2002-)(\d+)( Wayne Davison)/$1$year$3/
|
||||
&& $2 ne $year) {
|
||||
die "Copyright comments need to be updated to $year in all files!\n";
|
||||
}
|
||||
# Adjust the year in the --version output.
|
||||
s/(rprintf\(f, "Copyright \(C\) 1996-)(\d+)/$1$year/
|
||||
or die "Unable to find Copyright string in --version output of $fn\n";
|
||||
next if $2 eq $year;
|
||||
} else {
|
||||
die "Unrecognized file in \@tweak_files: $fn\n";
|
||||
}
|
||||
open(OUT, '>', $fn) or die $!;
|
||||
print OUT $_;
|
||||
close OUT;
|
||||
}
|
||||
|
||||
print $break;
|
||||
system "git diff --color | less -p '^diff .*'";
|
||||
|
||||
my $srctar_name = "rsync-$version.tar.gz";
|
||||
my $pattar_name = "rsync-patches-$version.tar.gz";
|
||||
my $diff_name = "rsync-$lastversion-$version.diffs.gz";
|
||||
my $srctar_file = "$dest/$srcdir/$srctar_name";
|
||||
my $pattar_file = "$dest/$srcdir/$pattar_name";
|
||||
my $diff_file = "$dest/$srcdiffdir/$diff_name";
|
||||
my $news_file = "$dest/$srcdir/rsync-$version-NEWS";
|
||||
my $lasttar_file = "$dest/$lastsrcdir/rsync-$lastversion.tar.gz";
|
||||
|
||||
print $break, <<EOT;
|
||||
|
||||
About to:
|
||||
- commit all version changes
|
||||
- merge the $master_branch branch into the patch/$master_branch/* branches
|
||||
- update the files in the "patches" dir and OPTIONALLY
|
||||
(if you type 'y') to launch a shell for each patch
|
||||
|
||||
EOT
|
||||
print "<Press Enter OR 'y' to continue> ";
|
||||
my $ans = <STDIN>;
|
||||
|
||||
system "git commit -a -m 'Preparing for release of $version'" and exit 1;
|
||||
|
||||
print "Updating files in \"patches\" dir ...\n";
|
||||
system "packaging/patch-update --branch=$master_branch";
|
||||
|
||||
if ($ans =~ /^y/i) {
|
||||
print "\nVisiting all \"patch/$master_branch/*\" branches ...\n";
|
||||
system "packaging/patch-update --branch=$master_branch --skip-check --shell";
|
||||
}
|
||||
|
||||
if (-d 'patches/.git') {
|
||||
system "cd patches && git commit -a -m 'The patches for $version.'" and exit 1;
|
||||
}
|
||||
|
||||
print $break, <<EOT;
|
||||
|
||||
About to:
|
||||
- create signed tag for this release: v$version
|
||||
- create release diffs, "$diff_name"
|
||||
- create release tar, "$srctar_name"
|
||||
- generate rsync-$version/patches/* files
|
||||
- create patches tar, "$pattar_name"
|
||||
- update top-level README, *NEWS, TODO, and ChangeLog
|
||||
- update top-level rsync*.html manpages
|
||||
- gpg-sign the release files
|
||||
- update hard-linked top-level release files$skipping
|
||||
|
||||
EOT
|
||||
print "<Press Enter to continue> ";
|
||||
$_ = <STDIN>;
|
||||
|
||||
# We want to use our passphrase-providing "gpg" script, so modify the PATH.
|
||||
$ENV{PATH} = "$curdir/packaging/bin:$path";
|
||||
|
||||
my $passphrase;
|
||||
while (1) {
|
||||
ReadMode('noecho');
|
||||
print "\nEnter your GPG pass-phrase: ";
|
||||
chomp($passphrase = <STDIN>);
|
||||
ReadMode(0);
|
||||
print "\n";
|
||||
|
||||
# Briefly create a temp file with the passphrase for git's tagging use.
|
||||
my $oldmask = umask 077;
|
||||
unlink($passfile);
|
||||
open(OUT, '>', $passfile) or die $!;
|
||||
print OUT $passphrase, "\n";
|
||||
close OUT;
|
||||
umask $oldmask;
|
||||
$ENV{'GPG_PASSFILE'} = $passfile;
|
||||
|
||||
$_ = `git tag -s -m 'Version $version.' v$version 2>&1`;
|
||||
print $_;
|
||||
next if /bad passphrase/;
|
||||
exit 1 if /failed/;
|
||||
|
||||
if (-d 'patches/.git') {
|
||||
$_ = `cd patches && git tag -s -m 'Version $version.' v$version 2>&1`;
|
||||
print $_;
|
||||
exit 1 if /bad passphrase|failed/;
|
||||
}
|
||||
|
||||
unlink($passfile);
|
||||
last;
|
||||
}
|
||||
|
||||
$ENV{PATH} = $path;
|
||||
|
||||
# Extract the generated files from the old tar.
|
||||
@_ = @extra_files;
|
||||
map { s#^#rsync-$lastversion/# } @_;
|
||||
system "tar xzf $lasttar_file @_";
|
||||
rename("rsync-$lastversion", 'a');
|
||||
|
||||
print "Creating $diff_file ...\n";
|
||||
system "$make_gen_cmd && rsync -a @extra_files b/" and exit 1;
|
||||
my $sed_script = 's:^((---|\+\+\+) [ab]/[^\t]+)\t.*:\1:';
|
||||
system "(git diff v$lastversion v$version; diff -upN a b | sed -r '$sed_script') | gzip -9 >$diff_file";
|
||||
system "rm -rf a";
|
||||
rename('b', "rsync-$version");
|
||||
|
||||
print "Creating $srctar_file ...\n";
|
||||
system "git archive --format=tar --prefix=rsync-$version/ v$version | tar xf -";
|
||||
system "support/git-set-file-times --prefix=rsync-$version/";
|
||||
system "fakeroot tar czf $srctar_file rsync-$version; rm -rf rsync-$version";
|
||||
|
||||
print "Updating files in \"rsync-$version/patches\" dir ...\n";
|
||||
mkdir("rsync-$version", 0755);
|
||||
mkdir("rsync-$version/patches", 0755);
|
||||
system "packaging/patch-update --skip-check --branch=$master_branch --gen=rsync-$version/patches";
|
||||
|
||||
print "Creating $pattar_file ...\n";
|
||||
system "fakeroot tar chzf $pattar_file rsync-$version/patches; rm -rf rsync-$version";
|
||||
|
||||
print "Updating the other files in $dest ...\n";
|
||||
system "rsync -a README NEWS OLDNEWS TODO $dest";
|
||||
unlink($news_file);
|
||||
link("$dest/NEWS", $news_file);
|
||||
system "git log --name-status | gzip -9 >$dest/ChangeLog.gz";
|
||||
|
||||
system "yodl2html -o $dest/rsync.html rsync.yo";
|
||||
system "yodl2html -o $dest/rsyncd.conf.html rsyncd.conf.yo";
|
||||
|
||||
foreach my $fn ($srctar_file, $pattar_file, $diff_file) {
|
||||
unlink("$fn.asc");
|
||||
open(GPG, '|-', "gpg --batch --passphrase-fd=0 -ba $fn") or die $!;
|
||||
print GPG $passphrase, "\n";
|
||||
close GPG;
|
||||
}
|
||||
|
||||
if (!$pre) {
|
||||
system "rm $dest/rsync-*.gz $dest/rsync-*.asc $dest/rsync-*-NEWS $dest/src-previews/rsync-*diffs.gz*";
|
||||
|
||||
foreach my $fn ($srctar_file, "$srctar_file.asc",
|
||||
$pattar_file, "$pattar_file.asc",
|
||||
$diff_file, "$diff_file.asc", $news_file) {
|
||||
(my $top_fn = $fn) =~ s#/src(-\w+)?/#/#;
|
||||
link($fn, $top_fn);
|
||||
}
|
||||
}
|
||||
|
||||
print $break, <<'EOT';
|
||||
|
||||
Local changes are done. When you're satisfied, push the git repository
|
||||
and rsync the release files. Remember to announce the release on *BOTH*
|
||||
rsync-announce@lists.samba.org and rsync@lists.samba.org (and the web)!
|
||||
EOT
|
||||
|
||||
exit;
|
||||
|
||||
sub get_subprotocol_version
|
||||
{
|
||||
my($subver) = @_;
|
||||
if ($pre && $proto_changed eq 'changed') {
|
||||
return $subver == 0 ? 1 : $subver;
|
||||
}
|
||||
0;
|
||||
}
|
||||
|
||||
sub usage
|
||||
{
|
||||
die <<EOT;
|
||||
Usage: release-rsync [OPTIONS]
|
||||
|
||||
-b, --branch=BRANCH The branch to release (default: master)
|
||||
-h, --help Display this help message
|
||||
EOT
|
||||
}
|
||||
9
packaging/systemd/rsync.service
Normal file
9
packaging/systemd/rsync.service
Normal file
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=fast remote file copy program daemon
|
||||
ConditionPathExists=/etc/rsyncd.conf
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/rsync --daemon --no-detach
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
83
packaging/var-checker
Executable file
83
packaging/var-checker
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/perl
|
||||
# This script checks the *.c files for extraneous "extern" variables,
|
||||
# for vars that are defined but not used, and for inconsistent array
|
||||
# sizes. Run it from inside the main rsync directory.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my %add_syscall_c = map { $_ => 1 } qw( t_stub.c t_unsafe.c tls.c trimslash.c );
|
||||
my %add_compat_c = map { $_ => 1 } qw( t_stub.c tls.c trimslash.c wildtest.c );
|
||||
my %add_util_c = map { $_ => 1 } qw( t_stub.c t_unsafe.c );
|
||||
my %sizes;
|
||||
|
||||
open(IN, '<', 'syscall.c') or die $!;
|
||||
undef $/; my $syscall_c = <IN>; $/ = "\n";
|
||||
close IN;
|
||||
$syscall_c =~ s/^extern\s.*//mg;
|
||||
|
||||
open(IN, '<', 'lib/compat.c') or die $!;
|
||||
undef $/; my $compat_c = <IN>; $/ = "\n";
|
||||
close IN;
|
||||
$compat_c =~ s/^extern\s.*//mg;
|
||||
|
||||
open(IN, '<', 'util.c') or die $!;
|
||||
undef $/; my $util_c = <IN>; $/ = "\n";
|
||||
close IN;
|
||||
$util_c =~ s/^extern\s.*//mg;
|
||||
|
||||
my @files = glob('*.c');
|
||||
|
||||
foreach my $fn (@files) {
|
||||
open(IN, '<', $fn) or die $!;
|
||||
undef $/; $_ = <IN>; $/ = "\n";
|
||||
close IN;
|
||||
|
||||
my @vars = /^(?!(?:extern|enum)\s)([a-zA-Z]\S*\s+.*);/mg;
|
||||
my @externs = /^extern\s+(.*);/mg;
|
||||
|
||||
$_ .= $syscall_c if $add_syscall_c{$fn};
|
||||
$_ .= $compat_c if $add_compat_c{$fn};
|
||||
$_ .= $util_c if $add_util_c{$fn};
|
||||
s/INFO_GTE/info_levels/g;
|
||||
s/DEBUG_GTE/debug_levels/g;
|
||||
|
||||
check_vars($fn, 'var', @vars);
|
||||
check_vars($fn, 'extern', @externs);
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
# The file's contents are in $_.
|
||||
sub check_vars
|
||||
{
|
||||
my $fn = shift;
|
||||
my $type = shift;
|
||||
|
||||
foreach my $line (@_) {
|
||||
$line =~ s/\s*\{.*\}//;
|
||||
$line =~ s/\s*\(.*\)//;
|
||||
foreach my $item (split(/\s*,\s*/, $line)) {
|
||||
$item =~ s/\s*=.*//;
|
||||
my $sz = $item =~ s/(\[.*?\])// ? $1 : '';
|
||||
my($var) = $item =~ /([^*\s]+)$/;
|
||||
if (!defined $var) {
|
||||
print "Bogus match? ($item)\n";
|
||||
next;
|
||||
}
|
||||
if ($sz) {
|
||||
if (defined $sizes{$var}) {
|
||||
if ($sizes{$var} ne $sz) {
|
||||
print $fn, ' has inconsistent size for "', $var,
|
||||
"\": $sizes{$var} vs $sz\n";
|
||||
}
|
||||
} else {
|
||||
$sizes{$var} = $sz;
|
||||
}
|
||||
}
|
||||
my @matches = /(?<!\sstruct )\b(\Q$var\E)(?!\w)/g;
|
||||
push(@matches, /(\QSIGACTION(\E)/g) if $var eq 'sigact';
|
||||
print $fn, " has extraneous $type: \"", $var, "\"\n" if @matches == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
204
params.c
204
params.c
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
This modules is based on the params.c module from Samba, written by Karl Auer
|
||||
and much modifed by Christopher Hertel.
|
||||
/* This modules is based on the params.c module from Samba, written by Karl Auer
|
||||
and much modifed by Christopher Hertel. */
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
@@ -12,11 +12,11 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* Module name: params
|
||||
*
|
||||
@@ -74,6 +74,8 @@
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "ifuncs.h"
|
||||
#include "itypes.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
* Constants...
|
||||
@@ -92,6 +94,8 @@
|
||||
|
||||
static char *bufr = NULL;
|
||||
static int bSize = 0;
|
||||
static BOOL (*the_sfunc)(char *);
|
||||
static BOOL (*the_pfunc)(char *, char *);
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
* Functions...
|
||||
@@ -164,7 +168,7 @@ static int Continuation( char *line, int pos )
|
||||
*/
|
||||
{
|
||||
pos--;
|
||||
while( (pos >= 0) && isspace(((unsigned char *)line)[pos]) )
|
||||
while( pos >= 0 && isSpace(line + pos) )
|
||||
pos--;
|
||||
|
||||
return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
|
||||
@@ -207,10 +211,10 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
|
||||
if( i > (bSize - 2) )
|
||||
{
|
||||
bSize += BUFR_INC;
|
||||
bufr = Realloc( bufr, bSize );
|
||||
bufr = realloc_array( bufr, char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FERROR, "%s Memory re-allocation failure.", func);
|
||||
rprintf(FLOG, "%s Memory re-allocation failure.", func);
|
||||
return( False );
|
||||
}
|
||||
}
|
||||
@@ -222,7 +226,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
|
||||
bufr[end] = '\0';
|
||||
if( 0 == end ) /* Don't allow an empty name. */
|
||||
{
|
||||
rprintf(FERROR, "%s Empty section name in configuration file.\n", func );
|
||||
rprintf(FLOG, "%s Empty section name in config file.\n", func );
|
||||
return( False );
|
||||
}
|
||||
if( !sfunc( bufr ) ) /* Got a valid name. Deal with it. */
|
||||
@@ -235,7 +239,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
|
||||
if( i < 0 )
|
||||
{
|
||||
bufr[end] = '\0';
|
||||
rprintf(FERROR, "%s Badly formed line in configuration file: %s\n",
|
||||
rprintf(FLOG, "%s Badly formed line in config file: %s\n",
|
||||
func, bufr );
|
||||
return( False );
|
||||
}
|
||||
@@ -260,7 +264,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
|
||||
}
|
||||
|
||||
/* We arrive here if we've met the EOF before the closing bracket. */
|
||||
rprintf(FERROR, "%s Unexpected EOF in the configuration file: %s\n", func, bufr );
|
||||
rprintf(FLOG, "%s Unexpected EOF in the config file: %s\n", func, bufr );
|
||||
return( False );
|
||||
} /* Section */
|
||||
|
||||
@@ -301,10 +305,10 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
if( i > (bSize - 2) ) /* Ensure there's space for next char. */
|
||||
{
|
||||
bSize += BUFR_INC;
|
||||
bufr = Realloc( bufr, bSize );
|
||||
bufr = realloc_array( bufr, char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
|
||||
rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
|
||||
return( False );
|
||||
}
|
||||
}
|
||||
@@ -314,13 +318,12 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
case '=': /* Equal sign marks end of param name. */
|
||||
if( 0 == end ) /* Don't allow an empty name. */
|
||||
{
|
||||
rprintf(FERROR, "%s Invalid parameter name in config. file.\n", func );
|
||||
rprintf(FLOG, "%s Invalid parameter name in config file.\n", func );
|
||||
return( False );
|
||||
}
|
||||
bufr[end++] = '\0'; /* Mark end of string & advance. */
|
||||
i = end; /* New string starts here. */
|
||||
vstart = end; /* New string is parameter value. */
|
||||
bufr[i] = '\0'; /* New string is nul, for now. */
|
||||
i = vstart = end; /* New string starts here. */
|
||||
c = EatWhitespace(InFile);
|
||||
break;
|
||||
|
||||
case '\n': /* Find continuation char, else error. */
|
||||
@@ -328,7 +331,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
if( i < 0 )
|
||||
{
|
||||
bufr[end] = '\0';
|
||||
rprintf(FERROR, "%s Ignoring badly formed line in configuration file: %s\n",
|
||||
rprintf(FLOG, "%s Ignoring badly formed line in config file: %s\n",
|
||||
func, bufr );
|
||||
return( True );
|
||||
}
|
||||
@@ -339,9 +342,22 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
case '\0': /* Shouldn't have EOF within param name. */
|
||||
case EOF:
|
||||
bufr[i] = '\0';
|
||||
rprintf(FERROR, "%s Unexpected end-of-file at: %s\n", func, bufr );
|
||||
rprintf(FLOG, "%s Unexpected end-of-file at: %s\n", func, bufr );
|
||||
return( True );
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
/* A directive divides at the first space or tab. */
|
||||
if (*bufr == '&') {
|
||||
bufr[end++] = '\0';
|
||||
i = vstart = end;
|
||||
c = EatWhitespace(InFile);
|
||||
if (c == '=')
|
||||
c = EatWhitespace(InFile);
|
||||
break;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
|
||||
default:
|
||||
if( isspace( c ) ) /* One ' ' per whitespace region. */
|
||||
{
|
||||
@@ -359,17 +375,16 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
}
|
||||
|
||||
/* Now parse the value. */
|
||||
c = EatWhitespace( InFile ); /* Again, trim leading whitespace. */
|
||||
while( (EOF !=c) && (c > 0) )
|
||||
{
|
||||
|
||||
if( i > (bSize - 2) ) /* Make sure there's enough room. */
|
||||
{
|
||||
bSize += BUFR_INC;
|
||||
bufr = Realloc( bufr, bSize );
|
||||
bufr = realloc_array( bufr, char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
|
||||
rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
|
||||
return( False );
|
||||
}
|
||||
}
|
||||
@@ -386,7 +401,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
c = 0;
|
||||
else
|
||||
{
|
||||
for( end = i; (end >= 0) && isspace(((unsigned char *) bufr)[end]); end-- )
|
||||
for( end = i; end >= 0 && isSpace(bufr + end); end-- )
|
||||
;
|
||||
c = getc( InFile );
|
||||
}
|
||||
@@ -405,7 +420,88 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
return( pfunc( bufr, &bufr[vstart] ) ); /* Pass name & value to pfunc(). */
|
||||
} /* Parameter */
|
||||
|
||||
static BOOL Parse( FILE *InFile,
|
||||
static int name_cmp(const void *n1, const void *n2)
|
||||
{
|
||||
return strcmp(*(char * const *)n1, *(char * const *)n2);
|
||||
}
|
||||
|
||||
static int include_config(char *include, int manage_globals)
|
||||
{
|
||||
STRUCT_STAT sb;
|
||||
char *match = manage_globals ? "*.conf" : "*.inc";
|
||||
int ret;
|
||||
|
||||
if (do_stat(include, &sb) < 0) {
|
||||
rsyserr(FLOG, errno, "unable to stat config file \"%s\"", include);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (S_ISREG(sb.st_mode)) {
|
||||
if (manage_globals && the_sfunc)
|
||||
the_sfunc("]push");
|
||||
ret = pm_process(include, the_sfunc, the_pfunc);
|
||||
if (manage_globals && the_sfunc)
|
||||
the_sfunc("]pop");
|
||||
} else if (S_ISDIR(sb.st_mode)) {
|
||||
char buf[MAXPATHLEN], **bpp;
|
||||
item_list conf_list;
|
||||
struct dirent *di;
|
||||
size_t j;
|
||||
DIR *d;
|
||||
|
||||
if (!(d = opendir(include))) {
|
||||
rsyserr(FLOG, errno, "unable to open config dir \"%s\"", include);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&conf_list, 0, sizeof conf_list);
|
||||
|
||||
while ((di = readdir(d)) != NULL) {
|
||||
char *dname = d_name(di);
|
||||
if (!wildmatch(match, dname))
|
||||
continue;
|
||||
bpp = EXPAND_ITEM_LIST(&conf_list, char *, 32);
|
||||
pathjoin(buf, sizeof buf, include, dname);
|
||||
*bpp = strdup(buf);
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
if (!(bpp = conf_list.items))
|
||||
return 1;
|
||||
|
||||
if (conf_list.count > 1)
|
||||
qsort(bpp, conf_list.count, sizeof (char *), name_cmp);
|
||||
|
||||
for (j = 0, ret = 1; j < conf_list.count; j++) {
|
||||
if (manage_globals && the_sfunc)
|
||||
the_sfunc(j == 0 ? "]push" : "]reset");
|
||||
if ((ret = pm_process(bpp[j], the_sfunc, the_pfunc)) != 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (manage_globals && the_sfunc)
|
||||
the_sfunc("]pop");
|
||||
|
||||
for (j = 0; j < conf_list.count; j++)
|
||||
free(bpp[j]);
|
||||
free(bpp);
|
||||
} else
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int parse_directives(char *name, char *val)
|
||||
{
|
||||
if (strcasecmp(name, "&include") == 0)
|
||||
return include_config(val, 1);
|
||||
if (strcasecmp(name, "&merge") == 0)
|
||||
return include_config(val, 0);
|
||||
rprintf(FLOG, "Unknown directive: %s.\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Parse( FILE *InFile,
|
||||
BOOL (*sfunc)(char *),
|
||||
BOOL (*pfunc)(char *, char *) )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
@@ -417,7 +513,8 @@ static BOOL Parse( FILE *InFile,
|
||||
* pfunc - Function to be called when a parameter is scanned.
|
||||
* See Parameter().
|
||||
*
|
||||
* Output: True if the file was successfully scanned, else False.
|
||||
* Output: 1 if the file was successfully scanned, 2 if the file was
|
||||
* scanned until a section header with no section function, else 0.
|
||||
*
|
||||
* Notes: The input can be viewed in terms of 'lines'. There are four
|
||||
* types of lines:
|
||||
@@ -426,7 +523,7 @@ static BOOL Parse( FILE *InFile,
|
||||
* The remainder of the line is ignored.
|
||||
* Section - First non-whitespace character is a '['.
|
||||
* Parameter - The default case.
|
||||
*
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
{
|
||||
@@ -447,29 +544,39 @@ static BOOL Parse( FILE *InFile,
|
||||
break;
|
||||
|
||||
case '[': /* Section Header. */
|
||||
if (!sfunc) return True;
|
||||
if( !Section( InFile, sfunc ) )
|
||||
return( False );
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
if (!sfunc)
|
||||
return 2;
|
||||
if( !Section( InFile, sfunc ) )
|
||||
return 0;
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
case '\\': /* Bogus backslash. */
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
case '&': /* Handle directives */
|
||||
the_sfunc = sfunc;
|
||||
the_pfunc = pfunc;
|
||||
c = Parameter( InFile, parse_directives, c );
|
||||
if (c != 1)
|
||||
return c;
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
default: /* Parameter line. */
|
||||
if( !Parameter( InFile, pfunc, c ) )
|
||||
return( False );
|
||||
return 0;
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return( True );
|
||||
return 1;
|
||||
} /* Parse */
|
||||
|
||||
static FILE *OpenConfFile( char *FileName )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
* Open a configuration file.
|
||||
* Open a config file.
|
||||
*
|
||||
* Input: FileName - The pathname of the config file to be opened.
|
||||
*
|
||||
@@ -484,21 +591,21 @@ static FILE *OpenConfFile( char *FileName )
|
||||
|
||||
if( NULL == FileName || 0 == *FileName )
|
||||
{
|
||||
rprintf(FERROR,"%s No configuration filename specified.\n", func);
|
||||
rprintf(FLOG, "%s No config filename specified.\n", func);
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
OpenedFile = fopen( FileName, "r" );
|
||||
if( NULL == OpenedFile )
|
||||
{
|
||||
rprintf(FERROR,"rsync: unable to open configuration file \"%s\": %s\n",
|
||||
FileName, strerror(errno));
|
||||
rsyserr(FLOG, errno, "unable to open config file \"%s\"",
|
||||
FileName);
|
||||
}
|
||||
|
||||
return( OpenedFile );
|
||||
} /* OpenConfFile */
|
||||
|
||||
BOOL pm_process( char *FileName,
|
||||
int pm_process( char *FileName,
|
||||
BOOL (*sfunc)(char *),
|
||||
BOOL (*pfunc)(char *, char *) )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
@@ -510,7 +617,8 @@ BOOL pm_process( char *FileName,
|
||||
* pfunc - A pointer to a function that will be called when
|
||||
* a parameter name and value are discovered.
|
||||
*
|
||||
* Output: TRUE if the file was successfully parsed, else FALSE.
|
||||
* Output: 1 if the file was successfully parsed, 2 if parsing ended at a
|
||||
* section header w/o a section function, else 0.
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
@@ -530,10 +638,10 @@ BOOL pm_process( char *FileName,
|
||||
else /* If we don't have a buffer */
|
||||
{ /* allocate one, then parse, */
|
||||
bSize = BUFR_INC; /* then free. */
|
||||
bufr = (char *)malloc( bSize );
|
||||
bufr = new_array( char, bSize );
|
||||
if( NULL == bufr )
|
||||
{
|
||||
rprintf(FERROR,"%s memory allocation failure.\n", func);
|
||||
rprintf(FLOG, "%s memory allocation failure.\n", func);
|
||||
fclose(InFile);
|
||||
return( False );
|
||||
}
|
||||
@@ -547,11 +655,11 @@ BOOL pm_process( char *FileName,
|
||||
|
||||
if( !result ) /* Generic failure. */
|
||||
{
|
||||
rprintf(FERROR,"%s Failed. Error returned from params.c:parse().\n", func);
|
||||
return( False );
|
||||
rprintf(FLOG, "%s Failed. Error returned from params.c:parse().\n", func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return( True ); /* Generic success. */
|
||||
return result;
|
||||
} /* pm_process */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
128
pipe.c
128
pipe.c
@@ -1,31 +1,42 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
/*
|
||||
* Routines used to setup various kinds of inter-process pipes.
|
||||
*
|
||||
* Copyright (C) 1996-2000 Andrew Tridgell
|
||||
* Copyright (C) 1996 Paul Mackerras
|
||||
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2004-2015 Wayne Davison
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, visit the http://fsf.org website.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
extern int blocking_io;
|
||||
extern int filesfrom_fd;
|
||||
extern int munge_symlinks;
|
||||
extern char *logfile_name;
|
||||
extern int remote_option_cnt;
|
||||
extern const char **remote_options;
|
||||
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
|
||||
*
|
||||
* This is derived from CVS code
|
||||
*
|
||||
* Note that in the child STDIN is set to blocking and STDOUT
|
||||
* is set to non-blocking. This is necessary as rsh relies on stdin being blocking
|
||||
* and ssh relies on stdout being non-blocking
|
||||
@@ -39,51 +50,43 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
|
||||
pid_t pid;
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
extern int blocking_io;
|
||||
|
||||
if (verbose >= 2) {
|
||||
print_child_argv(command);
|
||||
}
|
||||
|
||||
if (DEBUG_GTE(CMD, 1))
|
||||
print_child_argv("opening connection using:", command);
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
|
||||
rprintf(FERROR, "pipe: %s\n", strerror(errno));
|
||||
rsyserr(FERROR, errno, "pipe");
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
|
||||
pid = do_fork();
|
||||
if (pid == -1) {
|
||||
rprintf(FERROR, "fork: %s\n", strerror(errno));
|
||||
rsyserr(FERROR, errno, "fork");
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
extern int orig_umask;
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
|
||||
rprintf(FERROR, "Failed to dup/close : %s\n",
|
||||
strerror(errno));
|
||||
rsyserr(FERROR, errno, "Failed to dup/close");
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
if (to_child_pipe[0] != STDIN_FILENO)
|
||||
close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO)
|
||||
close(from_child_pipe[1]);
|
||||
umask(orig_umask);
|
||||
set_blocking(STDIN_FILENO);
|
||||
if (blocking_io) {
|
||||
if (blocking_io > 0)
|
||||
set_blocking(STDOUT_FILENO);
|
||||
}
|
||||
execvp(command[0], command);
|
||||
rprintf(FERROR, "Failed to exec %s : %s\n",
|
||||
command[0], strerror(errno));
|
||||
rsyserr(FERROR, errno, "Failed to exec %s", command[0]);
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
|
||||
rprintf(FERROR, "Failed to close : %s\n", strerror(errno));
|
||||
rsyserr(FERROR, errno, "Failed to close");
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
@@ -93,56 +96,85 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
|
||||
return pid;
|
||||
}
|
||||
|
||||
pid_t local_child(int argc, char **argv,int *f_in,int *f_out,
|
||||
/* This function forks a child which calls child_main(). First,
|
||||
* however, it has to establish communication paths to and from the
|
||||
* newborn child. It creates two socket pairs -- one for writing to
|
||||
* the child (from the parent) and one for reading from the child
|
||||
* (writing to the parent). Since that's four socket ends, each
|
||||
* process has to close the two ends it doesn't need. The remaining
|
||||
* two socket ends are retained for reading and writing. In the
|
||||
* child, the STDIN and STDOUT file descriptors refer to these
|
||||
* sockets. In the parent, the function arguments f_in and f_out are
|
||||
* set to refer to these sockets. */
|
||||
pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
|
||||
int (*child_main)(int, char*[]))
|
||||
{
|
||||
pid_t pid;
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
extern int read_batch; /* dw */
|
||||
|
||||
/* 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) {
|
||||
rprintf(FERROR,"pipe: %s\n",strerror(errno));
|
||||
rsyserr(FERROR, errno, "pipe");
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
|
||||
pid = do_fork();
|
||||
if (pid == -1) {
|
||||
rprintf(FERROR,"fork: %s\n",strerror(errno));
|
||||
rsyserr(FERROR, errno, "fork");
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
am_sender = 0;
|
||||
am_server = 1;
|
||||
filesfrom_fd = -1;
|
||||
munge_symlinks = 0; /* Each side needs its own option. */
|
||||
chmod_modes = NULL; /* Let the sending side handle this. */
|
||||
|
||||
am_sender = read_batch ? 0 : !am_sender;
|
||||
am_server = 1;
|
||||
/* Let the client side handle this. */
|
||||
if (logfile_name) {
|
||||
logfile_name = NULL;
|
||||
logfile_close();
|
||||
}
|
||||
|
||||
if (remote_option_cnt) {
|
||||
int rc = remote_option_cnt + 1;
|
||||
const char **rv = remote_options;
|
||||
if (!parse_arguments(&rc, &rv)) {
|
||||
option_error();
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
}
|
||||
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
|
||||
rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
|
||||
rsyserr(FERROR, errno, "Failed to dup/close");
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
|
||||
if (to_child_pipe[0] != STDIN_FILENO)
|
||||
close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO)
|
||||
close(from_child_pipe[1]);
|
||||
#ifdef ICONV_CONST
|
||||
setup_iconv();
|
||||
#endif
|
||||
child_main(argc, argv);
|
||||
}
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 ||
|
||||
close(to_child_pipe[0]) < 0) {
|
||||
rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
|
||||
rsyserr(FERROR, errno, "Failed to close");
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
*f_in = from_child_pipe[0];
|
||||
*f_out = to_child_pipe[1];
|
||||
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
ID
|
||||
Makefile
|
||||
config.cache
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
dummy
|
||||
rsync
|
||||
zlib/dummy
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user